[
  {
    "path": ".config/dotnet-tools.json",
    "content": "{\n  \"version\": 1,\n  \"isRoot\": true,\n  \"tools\": {\n    \"signclient\": {\n      \"version\": \"1.2.17\",\n      \"commands\": [\n        \"SignClient\"\n      ]\n    },\n    \"dotnet-ef\": {\n      \"version\": \"3.1.0\",\n      \"commands\": [\n        \"dotnet-ef\"\n      ]\n    }\n  }\n}"
  },
  {
    "path": ".editorconfig",
    "content": "root=true\n# Remove the line below if you want to inherit .editorconfig settings from higher directories\n\n# C# files\n[*.cs]\n\n#### Core EditorConfig Options ####\n\n# Indentation and spacing\nindent_size=4\nindent_style=space\ntab_width=4\n\n# New line preferences\nend_of_line=crlf\ninsert_final_newline=false\n\n#### .NET Coding Conventions ####\n\n# this. and Me. preferences\ndotnet_style_qualification_for_event=false:warning\ndotnet_style_qualification_for_field=false:warning\ndotnet_style_qualification_for_method=false:warning\ndotnet_style_qualification_for_property=false:warning\n\n# Language keywords vs BCL types preferences\ndotnet_style_predefined_type_for_locals_parameters_members=true:silent\ndotnet_style_predefined_type_for_member_access=true:silent\n\n# Parentheses preferences\ndotnet_style_parentheses_in_arithmetic_binary_operators=always_for_clarity:silent\ndotnet_style_parentheses_in_other_binary_operators=always_for_clarity:silent\ndotnet_style_parentheses_in_other_operators=never_if_unnecessary:silent\ndotnet_style_parentheses_in_relational_binary_operators=always_for_clarity:silent\n\n# Modifier preferences\ndotnet_style_require_accessibility_modifiers=for_non_interface_members:silent\n\n# Expression-level preferences\ncsharp_style_deconstructed_variable_declaration=true:suggestion\ncsharp_style_inlined_variable_declaration=true:suggestion\ncsharp_style_throw_expression=true:suggestion\ndotnet_style_coalesce_expression=true:suggestion\ndotnet_style_collection_initializer=true:suggestion\ndotnet_style_explicit_tuple_names=true:suggestion\ndotnet_style_null_propagation=true:suggestion\ndotnet_style_object_initializer=true:suggestion\ndotnet_style_prefer_auto_properties=true:silent\ndotnet_style_prefer_compound_assignment=true:suggestion\ndotnet_style_prefer_conditional_expression_over_assignment=true:silent\ndotnet_style_prefer_conditional_expression_over_return=true:silent\ndotnet_style_prefer_inferred_anonymous_type_member_names=true:suggestion\ndotnet_style_prefer_inferred_tuple_names=true:suggestion\ndotnet_style_prefer_is_null_check_over_reference_equality_method=true:suggestion\n\n# Field preferences\ndotnet_style_readonly_field=true:suggestion\n\n# Parameter preferences\ndotnet_code_quality_unused_parameters=all:suggestion\n\n#### C# Coding Conventions ####\n\n# var preferences\ncsharp_style_var_elsewhere=false:silent\ncsharp_style_var_for_built_in_types=false:silent\ncsharp_style_var_when_type_is_apparent=false:silent\n\n# Expression-bodied members\ncsharp_style_expression_bodied_accessors=true:silent\ncsharp_style_expression_bodied_constructors=false:silent\ncsharp_style_expression_bodied_indexers=true:silent\ncsharp_style_expression_bodied_lambdas=true:silent\ncsharp_style_expression_bodied_local_functions=false:silent\ncsharp_style_expression_bodied_methods=false:silent\ncsharp_style_expression_bodied_operators=false:silent\ncsharp_style_expression_bodied_properties=true:silent\n\n# Pattern matching preferences\ncsharp_style_pattern_matching_over_as_with_null_check=true:suggestion\ncsharp_style_pattern_matching_over_is_with_cast_check=true:suggestion\n\n# Null-checking preferences\ncsharp_style_conditional_delegate_call=true:suggestion\n\n# Modifier preferences\ncsharp_preferred_modifier_order=public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async\n\n# Code-block preferences\ncsharp_prefer_braces=true:silent\n\n# Expression-level preferences\ncsharp_prefer_simple_default_expression=true:suggestion\ncsharp_style_pattern_local_over_anonymous_function=true:suggestion\ncsharp_style_prefer_index_operator=true:suggestion\ncsharp_style_prefer_range_operator=true:suggestion\ncsharp_style_unused_value_assignment_preference=discard_variable:suggestion\ncsharp_style_unused_value_expression_statement_preference=discard_variable:silent\n\n#### C# Formatting Rules ####\n\n# New line preferences\ncsharp_new_line_before_catch=true\ncsharp_new_line_before_else=true\ncsharp_new_line_before_finally=true\ncsharp_new_line_before_members_in_anonymous_types=true\ncsharp_new_line_before_members_in_object_initializers=true\ncsharp_new_line_before_open_brace=all\ncsharp_new_line_between_query_expression_clauses=true\n\n# Indentation preferences\ncsharp_indent_block_contents=true\ncsharp_indent_braces=false\ncsharp_indent_case_contents=true\ncsharp_indent_case_contents_when_block=true\ncsharp_indent_labels=one_less_than_current\ncsharp_indent_switch_labels=true\n\n# Space preferences\ncsharp_space_after_cast=false\ncsharp_space_after_colon_in_inheritance_clause=true\ncsharp_space_after_comma=true\ncsharp_space_after_dot=false\ncsharp_space_after_keywords_in_control_flow_statements=true\ncsharp_space_after_semicolon_in_for_statement=true\ncsharp_space_around_binary_operators=before_and_after\ncsharp_space_around_declaration_statements=false\ncsharp_space_before_colon_in_inheritance_clause=true\ncsharp_space_before_comma=false\ncsharp_space_before_dot=false\ncsharp_space_before_open_square_brackets=false\ncsharp_space_before_semicolon_in_for_statement=false\ncsharp_space_between_empty_square_brackets=false\ncsharp_space_between_method_call_empty_parameter_list_parentheses=false\ncsharp_space_between_method_call_name_and_opening_parenthesis=false\ncsharp_space_between_method_call_parameter_list_parentheses=false\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses=false\ncsharp_space_between_method_declaration_name_and_open_parenthesis=false\ncsharp_space_between_method_declaration_parameter_list_parentheses=false\ncsharp_space_between_parentheses=false\ncsharp_space_between_square_brackets=false\n\n# Wrapping preferences\ncsharp_preserve_single_line_blocks=true\ncsharp_preserve_single_line_statements=true\n\n\n[*]\ncharset=utf-8\nend_of_line=lf\ntrim_trailing_whitespace=false\ninsert_final_newline=false\nindent_style=space\nindent_size=4\n\n# Microsoft .NET properties\ncsharp_indent_braces=false\ncsharp_indent_switch_labels=true\ncsharp_new_line_before_catch=true\ncsharp_new_line_before_else=true\ncsharp_new_line_before_finally=true\ncsharp_new_line_before_members_in_object_initializers=false\ncsharp_new_line_before_open_brace=all\ncsharp_new_line_between_query_expression_clauses=true\ncsharp_preferred_modifier_order=public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion\ncsharp_preserve_single_line_blocks=true\ncsharp_space_after_cast=true\ncsharp_space_after_colon_in_inheritance_clause=true\ncsharp_space_after_comma=true\ncsharp_space_after_dot=false\ncsharp_space_after_keywords_in_control_flow_statements=true\ncsharp_space_after_semicolon_in_for_statement=true\ncsharp_space_around_binary_operators=before_and_after\ncsharp_space_before_colon_in_inheritance_clause=true\ncsharp_space_before_comma=false\ncsharp_space_before_dot=false\ncsharp_space_before_open_square_brackets=false\ncsharp_space_before_semicolon_in_for_statement=false\ncsharp_space_between_empty_square_brackets=false\ncsharp_space_between_method_call_empty_parameter_list_parentheses=false\ncsharp_space_between_method_call_name_and_opening_parenthesis=false\ncsharp_space_between_method_call_parameter_list_parentheses=false\ncsharp_space_between_method_declaration_empty_parameter_list_parentheses=false\ncsharp_space_between_method_declaration_name_and_open_parenthesis=false\ncsharp_space_between_method_declaration_parameter_list_parentheses=false\ncsharp_space_between_parentheses=false\ncsharp_space_between_square_brackets=false\ncsharp_style_var_elsewhere=true:suggestion\ncsharp_style_var_for_built_in_types=true:suggestion\ncsharp_style_var_when_type_is_apparent=true:suggestion\ncsharp_using_directive_placement=outside_namespace:silent\ndotnet_naming_rule.constants_rule.severity=warning\ndotnet_naming_rule.constants_rule.style=upper_camel_case_style\ndotnet_naming_rule.constants_rule.symbols=constants_symbols\ndotnet_naming_rule.event_rule.severity=warning\ndotnet_naming_rule.event_rule.style=upper_camel_case_style\ndotnet_naming_rule.event_rule.symbols=event_symbols\ndotnet_naming_rule.interfaces_rule.severity=warning\ndotnet_naming_rule.interfaces_rule.style=i_upper_camel_case_style\ndotnet_naming_rule.interfaces_rule.symbols=interfaces_symbols\ndotnet_naming_rule.locals_rule.severity=warning\ndotnet_naming_rule.locals_rule.style=lower_camel_case_style_1\ndotnet_naming_rule.locals_rule.symbols=locals_symbols\ndotnet_naming_rule.local_constants_rule.severity=warning\ndotnet_naming_rule.local_constants_rule.style=lower_camel_case_style_1\ndotnet_naming_rule.local_constants_rule.symbols=local_constants_symbols\ndotnet_naming_rule.local_functions_rule.severity=warning\ndotnet_naming_rule.local_functions_rule.style=upper_camel_case_style\ndotnet_naming_rule.local_functions_rule.symbols=local_functions_symbols\ndotnet_naming_rule.method_rule.severity=warning\ndotnet_naming_rule.method_rule.style=upper_camel_case_style\ndotnet_naming_rule.method_rule.symbols=method_symbols\ndotnet_naming_rule.parameters_rule.severity=warning\ndotnet_naming_rule.parameters_rule.style=lower_camel_case_style_1\ndotnet_naming_rule.parameters_rule.symbols=parameters_symbols\ndotnet_naming_rule.private_constants_rule.severity=warning\ndotnet_naming_rule.private_constants_rule.style=upper_camel_case_style\ndotnet_naming_rule.private_constants_rule.symbols=private_constants_symbols\ndotnet_naming_rule.private_instance_fields_rule.severity=warning\ndotnet_naming_rule.private_instance_fields_rule.style=lower_camel_case_style\ndotnet_naming_rule.private_instance_fields_rule.symbols=private_instance_fields_symbols\ndotnet_naming_rule.private_static_fields_rule.severity=warning\ndotnet_naming_rule.private_static_fields_rule.style=lower_camel_case_style\ndotnet_naming_rule.private_static_fields_rule.symbols=private_static_fields_symbols\ndotnet_naming_rule.private_static_readonly_rule.severity=warning\ndotnet_naming_rule.private_static_readonly_rule.style=upper_camel_case_style\ndotnet_naming_rule.private_static_readonly_rule.symbols=private_static_readonly_symbols\ndotnet_naming_rule.property_rule.severity=warning\ndotnet_naming_rule.property_rule.style=upper_camel_case_style\ndotnet_naming_rule.property_rule.symbols=property_symbols\ndotnet_naming_rule.public_fields_rule.severity=warning\ndotnet_naming_rule.public_fields_rule.style=upper_camel_case_style\ndotnet_naming_rule.public_fields_rule.symbols=public_fields_symbols\ndotnet_naming_rule.static_readonly_rule.severity=warning\ndotnet_naming_rule.static_readonly_rule.style=upper_camel_case_style\ndotnet_naming_rule.static_readonly_rule.symbols=static_readonly_symbols\ndotnet_naming_rule.types_and_namespaces_rule.severity=warning\ndotnet_naming_rule.types_and_namespaces_rule.style=upper_camel_case_style\ndotnet_naming_rule.types_and_namespaces_rule.symbols=types_and_namespaces_symbols\ndotnet_naming_rule.type_parameters_rule.severity=warning\ndotnet_naming_rule.type_parameters_rule.style=t_upper_camel_case_style\ndotnet_naming_rule.type_parameters_rule.symbols=type_parameters_symbols\ndotnet_naming_style.i_upper_camel_case_style.capitalization=pascal_case\ndotnet_naming_style.i_upper_camel_case_style.required_prefix=I\ndotnet_naming_style.lower_camel_case_style.capitalization=camel_case\ndotnet_naming_style.lower_camel_case_style.required_prefix=_\ndotnet_naming_style.lower_camel_case_style_1.capitalization=camel_case\ndotnet_naming_style.t_upper_camel_case_style.capitalization=pascal_case\ndotnet_naming_style.t_upper_camel_case_style.required_prefix=T\ndotnet_naming_style.upper_camel_case_style.capitalization=pascal_case\ndotnet_naming_symbols.constants_symbols.applicable_accessibilities=public,internal,protected,protected_internal,private_protected\ndotnet_naming_symbols.constants_symbols.applicable_kinds=field\ndotnet_naming_symbols.constants_symbols.required_modifiers=const\ndotnet_naming_symbols.event_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.event_symbols.applicable_kinds=event\ndotnet_naming_symbols.interfaces_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.interfaces_symbols.applicable_kinds=interface\ndotnet_naming_symbols.locals_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.locals_symbols.applicable_kinds=local\ndotnet_naming_symbols.local_constants_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.local_constants_symbols.applicable_kinds=local\ndotnet_naming_symbols.local_constants_symbols.required_modifiers=const\ndotnet_naming_symbols.local_functions_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.local_functions_symbols.applicable_kinds=local_function\ndotnet_naming_symbols.method_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.method_symbols.applicable_kinds=method\ndotnet_naming_symbols.parameters_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.parameters_symbols.applicable_kinds=parameter\ndotnet_naming_symbols.private_constants_symbols.applicable_accessibilities=private\ndotnet_naming_symbols.private_constants_symbols.applicable_kinds=field\ndotnet_naming_symbols.private_constants_symbols.required_modifiers=const\ndotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities=private\ndotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds=field\ndotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities=private\ndotnet_naming_symbols.private_static_fields_symbols.applicable_kinds=field\ndotnet_naming_symbols.private_static_fields_symbols.required_modifiers=static\ndotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities=private\ndotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds=field\ndotnet_naming_symbols.private_static_readonly_symbols.required_modifiers=static,readonly\ndotnet_naming_symbols.property_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.property_symbols.applicable_kinds=property\ndotnet_naming_symbols.public_fields_symbols.applicable_accessibilities=public,internal,protected,protected_internal,private_protected\ndotnet_naming_symbols.public_fields_symbols.applicable_kinds=field\ndotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities=public,internal,protected,protected_internal,private_protected\ndotnet_naming_symbols.static_readonly_symbols.applicable_kinds=field\ndotnet_naming_symbols.static_readonly_symbols.required_modifiers=static,readonly\ndotnet_naming_symbols.types_and_namespaces_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.types_and_namespaces_symbols.applicable_kinds=namespace,class,struct,enum,delegate\ndotnet_naming_symbols.type_parameters_symbols.applicable_accessibilities=*\ndotnet_naming_symbols.type_parameters_symbols.applicable_kinds=type_parameter\ndotnet_style_parentheses_in_arithmetic_binary_operators=never_if_unnecessary:none\ndotnet_style_parentheses_in_other_binary_operators=never_if_unnecessary:none\ndotnet_style_parentheses_in_relational_binary_operators=never_if_unnecessary:none\ndotnet_style_predefined_type_for_locals_parameters_members=true:suggestion\ndotnet_style_predefined_type_for_member_access=true:suggestion\ndotnet_style_qualification_for_event=false:suggestion\ndotnet_style_qualification_for_field=false:suggestion\ndotnet_style_qualification_for_method=false:suggestion\ndotnet_style_qualification_for_property=false:suggestion\ndotnet_style_require_accessibility_modifiers=for_non_interface_members:suggestion\n\n# ReSharper properties\nresharper_accessor_owner_body=expression_body\nresharper_alignment_tab_fill_style=use_spaces\nresharper_align_first_arg_by_paren=false\nresharper_align_linq_query=false\nresharper_align_multiline_array_and_object_initializer=false\nresharper_align_multiline_array_initializer=true\nresharper_align_multiline_binary_expressions_chain=true\nresharper_align_multiline_calls_chain=false\nresharper_align_multiline_extends_list=false\nresharper_align_multiline_for_stmt=false\nresharper_align_multiline_implements_list=true\nresharper_align_multiline_switch_expression=false\nresharper_align_multline_type_parameter_constrains=false\nresharper_align_multline_type_parameter_list=false\nresharper_align_tuple_components=false\nresharper_allow_alias=true\nresharper_allow_comment_after_lbrace=false\nresharper_always_use_end_of_line_brace_style=false\nresharper_apply_auto_detected_rules=true\nresharper_apply_on_completion=false\nresharper_arguments_anonymous_function=positional\nresharper_arguments_literal=positional\nresharper_arguments_named=positional\nresharper_arguments_other=positional\nresharper_arguments_skip_single=false\nresharper_arguments_string_literal=positional\nresharper_attribute_style=do_not_touch\nresharper_autodetect_indent_settings=true\nresharper_blank_lines_after_block_statements=1\nresharper_blank_lines_after_case=0\nresharper_blank_lines_after_control_transfer_statements=0\nresharper_blank_lines_after_imports=1\nresharper_blank_lines_after_multiline_statements=0\nresharper_blank_lines_after_options=1\nresharper_blank_lines_after_start_comment=1\nresharper_blank_lines_after_using_list=1\nresharper_blank_lines_around_auto_property=1\nresharper_blank_lines_around_block_case_section=0\nresharper_blank_lines_around_field=1\nresharper_blank_lines_around_global_attribute=0\nresharper_blank_lines_around_invocable=1\nresharper_blank_lines_around_local_method=1\nresharper_blank_lines_around_multiline_case_section=0\nresharper_blank_lines_around_namespace=1\nresharper_blank_lines_around_property=1\nresharper_blank_lines_around_razor_functions=1\nresharper_blank_lines_around_razor_helpers=1\nresharper_blank_lines_around_razor_sections=1\nresharper_blank_lines_around_region=1\nresharper_blank_lines_around_single_line_auto_property=0\nresharper_blank_lines_around_single_line_field=0\nresharper_blank_lines_around_single_line_invocable=0\nresharper_blank_lines_around_single_line_local_method=0\nresharper_blank_lines_around_single_line_property=0\nresharper_blank_lines_around_type=1\nresharper_blank_lines_before_block_statements=0\nresharper_blank_lines_before_case=0\nresharper_blank_lines_before_control_transfer_statements=0\nresharper_blank_lines_before_multiline_statements=0\nresharper_blank_lines_before_single_line_comment=0\nresharper_blank_lines_between_using_groups=0\nresharper_blank_lines_inside_namespace=0\nresharper_blank_lines_inside_region=1\nresharper_blank_lines_inside_type=0\nresharper_blank_line_after_pi=true\nresharper_braces_for_dowhile=required\nresharper_braces_for_fixed=required\nresharper_braces_for_for=not_required\nresharper_braces_for_foreach=not_required\nresharper_braces_for_ifelse=not_required_for_both\nresharper_braces_for_lock=required\nresharper_braces_for_using=required\nresharper_braces_for_while=not_required\nresharper_braces_redundant=true\nresharper_can_use_global_alias=true\nresharper_constructor_or_destructor_body=block_body\nresharper_continuous_indent_multiplier=1\nresharper_csharp_align_multiline_argument=false\nresharper_csharp_align_multiline_expression=false\nresharper_csharp_align_multiline_parameter=false\nresharper_csharp_align_multiple_declaration=false\nresharper_csharp_max_line_length=120\nresharper_csharp_naming_rule.enum_member=AaBb\nresharper_csharp_naming_rule.method_property_event=AaBb\nresharper_csharp_naming_rule.other=AaBb\nresharper_csharp_prefer_qualified_reference=false\nresharper_csharp_wrap_lines=true\nresharper_default_exception_variable_name=e\nresharper_delete_quotes_from_solid_values=false\nresharper_disable_blank_line_changes=false\nresharper_disable_formatter=false\nresharper_disable_indenter=false\nresharper_disable_int_align=false\nresharper_disable_line_break_changes=false\nresharper_disable_line_break_removal=false\nresharper_disable_space_changes=false\nresharper_empty_block_style=multiline\nresharper_enable_wrapping=false\nresharper_enforce_line_ending_style=false\nresharper_event_handler_pattern_long=$object$On$event$\nresharper_event_handler_pattern_short=On$event$\nresharper_extra_spaces=remove_all\nresharper_force_attribute_style=separate\nresharper_force_chop_compound_do_expression=false\nresharper_force_chop_compound_if_expression=false\nresharper_force_chop_compound_while_expression=false\nresharper_format_leading_spaces_decl=false\nresharper_html_attribute_indent=align_by_first_attribute\nresharper_html_linebreak_before_elements=body,div,p,form,h1,h2,h3\nresharper_html_max_blank_lines_between_tags=2\nresharper_html_max_line_length=120\nresharper_html_pi_attribute_style=on_single_line\nresharper_html_space_before_self_closing=false\nresharper_html_wrap_lines=true\nresharper_ignore_space_preservation=false\nresharper_include_prefix_comment_in_indent=false\nresharper_indent_anonymous_method_block=false\nresharper_indent_case_from_select=true\nresharper_indent_child_elements=OneIndent\nresharper_indent_inside_namespace=true\nresharper_indent_invocation_pars=inside\nresharper_indent_method_decl_pars=inside\nresharper_indent_nested_fixed_stmt=false\nresharper_indent_nested_foreach_stmt=false\nresharper_indent_nested_for_stmt=false\nresharper_indent_nested_lock_stmt=false\nresharper_indent_nested_usings_stmt=false\nresharper_indent_nested_while_stmt=false\nresharper_indent_pars=inside\nresharper_indent_preprocessor_if=no_indent\nresharper_indent_preprocessor_other=no_indent\nresharper_indent_preprocessor_region=usual_indent\nresharper_indent_statement_pars=inside\nresharper_indent_text=OneIndent\nresharper_indent_typearg_angles=inside\nresharper_indent_typeparam_angles=inside\nresharper_indent_type_constraints=true\nresharper_instance_members_qualify_declared_in=this_class, base_class\nresharper_int_align=false\nresharper_keep_blank_lines_in_code=2\nresharper_keep_blank_lines_in_declarations=2\nresharper_keep_existing_attribute_arrangement=false\nresharper_keep_existing_declaration_block_arrangement=false\nresharper_keep_existing_declaration_parens_arrangement=true\nresharper_keep_existing_embedded_arrangement=true\nresharper_keep_existing_embedded_block_arrangement=false\nresharper_keep_existing_enum_arrangement=false\nresharper_keep_existing_expr_member_arrangement=true\nresharper_keep_existing_invocation_parens_arrangement=true\nresharper_keep_existing_switch_expression_arrangement=true\nresharper_keep_nontrivial_alias=true\nresharper_keep_user_linebreaks=true\nresharper_keep_user_wrapping=true\nresharper_linebreaks_around_razor_statements=true\nresharper_linebreaks_inside_tags_for_elements_longer_than=2147483647\nresharper_linebreaks_inside_tags_for_elements_with_child_elements=true\nresharper_linebreaks_inside_tags_for_multiline_elements=true\nresharper_linebreak_before_all_elements=false\nresharper_linebreak_before_multiline_elements=true\nresharper_linebreak_before_singleline_elements=false\nresharper_local_function_body=block_body\nresharper_max_array_initializer_elements_on_line=10000\nresharper_max_attribute_length_for_same_line=38\nresharper_max_enum_members_on_line=3\nresharper_max_formal_parameters_on_line=10000\nresharper_max_initializer_elements_on_line=4\nresharper_max_invocation_arguments_on_line=10000\nresharper_method_or_operator_body=block_body\nresharper_nested_ternary_style=autodetect\nresharper_new_line_before_while=false\nresharper_normalize_tag_names=false\nresharper_no_indent_inside_elements=html,body,thead,tbody,tfoot\nresharper_no_indent_inside_if_element_longer_than=200\nresharper_old_engine=false\nresharper_outdent_binary_ops=false\nresharper_outdent_commas=false\nresharper_outdent_dots=false\nresharper_outdent_ternary_ops=false\nresharper_parentheses_non_obvious_operations=none, shift, bitwise_and, bitwise_exclusive_or, bitwise_inclusive_or, bitwise\nresharper_parentheses_redundancy_style=remove_if_not_clarifies_precedence\nresharper_pi_attributes_indent=align_by_first_attribute\nresharper_place_accessorholder_attribute_on_same_line=if_owner_is_single_line\nresharper_place_accessor_attribute_on_same_line=if_owner_is_single_line\nresharper_place_comments_at_first_column=false\nresharper_place_constructor_initializer_on_same_line=true\nresharper_place_event_attribute_on_same_line=false\nresharper_place_expr_accessor_on_single_line=if_owner_is_single_line\nresharper_place_expr_method_on_single_line=if_owner_is_single_line\nresharper_place_expr_property_on_single_line=if_owner_is_single_line\nresharper_place_field_attribute_on_same_line=true\nresharper_place_linq_into_on_new_line=true\nresharper_place_method_attribute_on_same_line=false\nresharper_place_property_attribute_on_same_line=false\nresharper_place_simple_case_statement_on_same_line=false\nresharper_place_simple_embedded_statement_on_same_line=if_owner_is_single_line\nresharper_place_simple_initializer_on_single_line=true\nresharper_place_simple_switch_expression_on_single_line=false\nresharper_place_type_attribute_on_same_line=false\nresharper_place_type_constraints_on_same_line=true\nresharper_prefer_explicit_discard_declaration=false\nresharper_prefer_separate_deconstructed_variables_declaration=false\nresharper_preserve_spaces_inside_tags=pre,textarea\nresharper_qualified_using_at_nested_scope=false\nresharper_quote_style=doublequoted\nresharper_razor_prefer_qualified_reference=true\nresharper_remove_blank_lines_near_braces=false\nresharper_remove_blank_lines_near_braces_in_code=true\nresharper_remove_blank_lines_near_braces_in_declarations=true\nresharper_remove_this_qualifier=true\nresharper_resx_attribute_indent=single_indent\nresharper_resx_linebreak_before_elements=\nresharper_resx_max_blank_lines_between_tags=0\nresharper_resx_max_line_length=2147483647\nresharper_resx_pi_attribute_style=do_not_touch\nresharper_resx_space_before_self_closing=false\nresharper_resx_wrap_lines=false\nresharper_resx_wrap_tags_and_pi=false\nresharper_resx_wrap_text=false\nresharper_show_autodetect_configure_formatting_tip=true\nresharper_sort_attributes=false\nresharper_sort_class_selectors=false\nresharper_sort_usings=true\nresharper_sort_usings_lowercase_first=false\nresharper_sort_usings_with_system_first=true\nresharper_spaces_around_eq_in_attribute=false\nresharper_spaces_around_eq_in_pi_attribute=false\nresharper_spaces_inside_tags=false\nresharper_space_after_attributes=true\nresharper_space_after_attribute_target_colon=true\nresharper_space_after_colon=true\nresharper_space_after_colon_in_case=true\nresharper_space_after_comma=true\nresharper_space_after_last_attribute=false\nresharper_space_after_last_pi_attribute=false\nresharper_space_after_operator_keyword=true\nresharper_space_after_triple_slash=true\nresharper_space_after_type_parameter_constraint_colon=true\nresharper_space_after_unary_operator=false\nresharper_space_around_additive_op=true\nresharper_space_around_alias_eq=true\nresharper_space_around_assignment_op=true\nresharper_space_around_lambda_arrow=true\nresharper_space_around_member_access_operator=false\nresharper_space_around_relational_op=true\nresharper_space_around_shift_op=true\nresharper_space_around_stmt_colon=true\nresharper_space_around_ternary_operator=true\nresharper_space_before_array_rank_parentheses=false\nresharper_space_before_attribute_target_colon=false\nresharper_space_before_checked_parentheses=false\nresharper_space_before_colon=false\nresharper_space_before_colon_in_case=false\nresharper_space_before_comma=false\nresharper_space_before_default_parentheses=false\nresharper_space_before_empty_invocation_parentheses=false\nresharper_space_before_empty_method_parentheses=false\nresharper_space_before_invocation_parentheses=false\nresharper_space_before_label_colon=false\nresharper_space_before_method_parentheses=false\nresharper_space_before_nameof_parentheses=false\nresharper_space_before_nullable_mark=false\nresharper_space_before_pointer_asterik_declaration=false\nresharper_space_before_semicolon=false\nresharper_space_before_singleline_accessorholder=true\nresharper_space_before_sizeof_parentheses=false\nresharper_space_before_trailing_comment=true\nresharper_space_before_typeof_parentheses=false\nresharper_space_before_type_argument_angle=false\nresharper_space_before_type_parameter_angle=false\nresharper_space_before_type_parameter_constraint_colon=true\nresharper_space_before_type_parameter_parentheses=true\nresharper_space_between_accessors_in_singleline_property=true\nresharper_space_between_attribute_sections=true\nresharper_space_between_keyword_and_expression=true\nresharper_space_between_keyword_and_type=true\nresharper_space_in_singleline_accessorholder=true\nresharper_space_in_singleline_anonymous_method=true\nresharper_space_in_singleline_method=true\nresharper_space_near_postfix_and_prefix_op=false\nresharper_space_within_array_initialization_braces=false\nresharper_space_within_array_rank_empty_parentheses=false\nresharper_space_within_array_rank_parentheses=false\nresharper_space_within_attribute_angles=false\nresharper_space_within_checked_parentheses=false\nresharper_space_within_default_parentheses=false\nresharper_space_within_empty_braces=true\nresharper_space_within_empty_invocation_parentheses=false\nresharper_space_within_empty_method_parentheses=false\nresharper_space_within_expression_parentheses=false\nresharper_space_within_invocation_parentheses=false\nresharper_space_within_method_parentheses=false\nresharper_space_within_nameof_parentheses=false\nresharper_space_within_single_line_array_initializer_braces=true\nresharper_space_within_sizeof_parentheses=false\nresharper_space_within_tuple_parentheses=false\nresharper_space_within_typeof_parentheses=false\nresharper_space_within_type_argument_angles=false\nresharper_space_within_type_parameter_angles=false\nresharper_space_within_type_parameter_parentheses=false\nresharper_special_else_if_treatment=true\nresharper_static_members_qualify_members=none\nresharper_static_members_qualify_with=do_not_change, declared_type\nresharper_stick_comment=true\nresharper_support_vs_event_naming_pattern=true\nresharper_trailing_comma_in_multiline_lists=false\nresharper_trailing_comma_in_singleline_lists=false\nresharper_use_continuous_indent_inside_initializer_braces=true\nresharper_use_continuous_indent_inside_parens=true\nresharper_use_heuristics_for_body_style=true\nresharper_use_indents_from_main_language_in_file=true\nresharper_use_indent_from_previous_element=true\nresharper_use_indent_from_vs=false\nresharper_use_roslyn_logic_for_evident_types=false\nresharper_vb_align_multiline_argument=true\nresharper_vb_align_multiline_expression=true\nresharper_vb_align_multiline_parameter=true\nresharper_vb_align_multiple_declaration=true\nresharper_vb_max_line_length=120\nresharper_vb_place_field_attribute_on_same_line=true\nresharper_vb_place_method_attribute_on_same_line=false\nresharper_vb_place_type_attribute_on_same_line=false\nresharper_vb_prefer_qualified_reference=false\nresharper_vb_space_around_multiplicative_op=false\nresharper_vb_wrap_lines=true\nresharper_wrap_after_declaration_lpar=false\nresharper_wrap_after_dot_in_method_calls=false\nresharper_wrap_after_invocation_lpar=false\nresharper_wrap_arguments_style=wrap_if_long\nresharper_wrap_around_elements=true\nresharper_wrap_array_initializer_style=wrap_if_long\nresharper_wrap_before_arrow_with_expressions=false\nresharper_wrap_before_binary_opsign=false\nresharper_wrap_before_comma=false\nresharper_wrap_before_declaration_lpar=false\nresharper_wrap_before_declaration_rpar=false\nresharper_wrap_before_extends_colon=false\nresharper_wrap_before_first_type_parameter_constraint=false\nresharper_wrap_before_invocation_lpar=false\nresharper_wrap_before_invocation_rpar=false\nresharper_wrap_before_linq_expression=false\nresharper_wrap_before_ternary_opsigns=true\nresharper_wrap_before_type_parameter_langle=false\nresharper_wrap_chained_binary_expressions=wrap_if_long\nresharper_wrap_chained_method_calls=wrap_if_long\nresharper_wrap_enum_declaration=chop_always\nresharper_wrap_extends_list_style=wrap_if_long\nresharper_wrap_for_stmt_header_style=chop_if_long\nresharper_wrap_multiple_declaration_style=chop_if_long\nresharper_wrap_multiple_type_parameter_constraints_style=chop_if_long\nresharper_wrap_object_and_collection_initializer_style=chop_if_long\nresharper_wrap_parameters_style=wrap_if_long\nresharper_wrap_switch_expression=chop_always\nresharper_wrap_ternary_expr_style=chop_if_long\nresharper_wrap_verbatim_interpolated_strings=no_wrap\nresharper_xmldoc_attribute_indent=single_indent\nresharper_xmldoc_linebreak_before_elements=summary,remarks,example,returns,param,typeparam,value,para\nresharper_xmldoc_max_blank_lines_between_tags=0\nresharper_xmldoc_max_line_length=120\nresharper_xmldoc_pi_attribute_style=do_not_touch\nresharper_xmldoc_space_before_self_closing=true\nresharper_xmldoc_wrap_lines=true\nresharper_xmldoc_wrap_tags_and_pi=true\nresharper_xmldoc_wrap_text=true\nresharper_xml_attribute_indent=align_by_first_attribute\nresharper_xml_linebreak_before_elements=\nresharper_xml_max_blank_lines_between_tags=2\nresharper_xml_max_line_length=120\nresharper_xml_pi_attribute_style=do_not_touch\nresharper_xml_space_before_self_closing=true\nresharper_xml_wrap_lines=true\nresharper_xml_wrap_tags_and_pi=true\nresharper_xml_wrap_text=false\n\n# ReSharper inspection severities\nresharper_abstract_class_constructor_can_be_made_protected_highlighting=hint\nresharper_access_rights_in_text_highlighting=warning\nresharper_access_to_disposed_closure_highlighting=warning\nresharper_access_to_for_each_variable_in_closure_highlighting=warning\nresharper_access_to_modified_closure_highlighting=warning\nresharper_access_to_static_member_via_derived_type_highlighting=warning\nresharper_address_of_marshal_by_ref_object_highlighting=warning\nresharper_amd_dependency_path_problem_highlighting=none\nresharper_angular_html_banana_highlighting=warning\nresharper_annotate_can_be_null_parameter_highlighting=none\nresharper_annotate_can_be_null_type_member_highlighting=none\nresharper_annotate_not_null_parameter_highlighting=none\nresharper_annotate_not_null_type_member_highlighting=none\nresharper_annotation_conflict_in_hierarchy_highlighting=warning\nresharper_annotation_redundancy_at_value_type_highlighting=warning\nresharper_annotation_redundancy_in_hierarchy_highlighting=warning\nresharper_arguments_style_anonymous_function_highlighting=hint\nresharper_arguments_style_literal_highlighting=hint\nresharper_arguments_style_named_expression_highlighting=hint\nresharper_arguments_style_other_highlighting=hint\nresharper_arguments_style_string_literal_highlighting=hint\nresharper_arrange_accessor_owner_body_highlighting=suggestion\nresharper_arrange_attributes_highlighting=none\nresharper_arrange_constructor_or_destructor_body_highlighting=none\nresharper_arrange_local_function_body_highlighting=none\nresharper_arrange_method_or_operator_body_highlighting=none\nresharper_arrange_redundant_parentheses_highlighting=hint\nresharper_arrange_static_member_qualifier_highlighting=hint\nresharper_arrange_this_qualifier_highlighting=hint\nresharper_arrange_trailing_comma_in_multiline_lists_highlighting=hint\nresharper_arrange_trailing_comma_in_singleline_lists_highlighting=hint\nresharper_arrange_type_member_modifiers_highlighting=hint\nresharper_arrange_type_modifiers_highlighting=hint\nresharper_arrange_var_keywords_in_deconstructing_declaration_highlighting=suggestion\nresharper_asp0000_highlighting=warning\nresharper_asp0001_highlighting=warning\nresharper_asp_content_placeholder_not_resolved_highlighting=error\nresharper_asp_custom_page_parser_filter_type_highlighting=warning\nresharper_asp_dead_code_highlighting=warning\nresharper_asp_entity_highlighting=warning\nresharper_asp_image_highlighting=warning\nresharper_asp_invalid_control_type_highlighting=error\nresharper_asp_not_resolved_highlighting=error\nresharper_asp_ods_method_reference_resolve_error_highlighting=error\nresharper_asp_resolve_warning_highlighting=warning\nresharper_asp_skin_not_resolved_highlighting=error\nresharper_asp_tag_attribute_with_optional_value_highlighting=warning\nresharper_asp_theme_not_resolved_highlighting=error\nresharper_asp_unused_register_directive_highlighting_highlighting=warning\nresharper_asp_warning_highlighting=warning\nresharper_assigned_value_is_never_used_highlighting=warning\nresharper_assigned_value_wont_be_assigned_to_corresponding_field_highlighting=warning\nresharper_assignment_in_conditional_expression_highlighting=warning\nresharper_assignment_in_condition_expression_highlighting=warning\nresharper_assignment_is_fully_discarded_highlighting=warning\nresharper_assign_null_to_not_null_attribute_highlighting=warning\nresharper_assign_to_constant_highlighting=error\nresharper_assign_to_implicit_global_in_function_scope_highlighting=warning\nresharper_asxx_path_error_highlighting=warning\nresharper_async_iterator_invocation_without_await_foreach_highlighting=warning\nresharper_auto_property_can_be_made_get_only_global_highlighting=suggestion\nresharper_auto_property_can_be_made_get_only_local_highlighting=suggestion\nresharper_bad_attribute_brackets_spaces_highlighting=none\nresharper_bad_braces_spaces_highlighting=none\nresharper_bad_child_statement_indent_highlighting=warning\nresharper_bad_colon_spaces_highlighting=none\nresharper_bad_comma_spaces_highlighting=none\nresharper_bad_control_braces_indent_highlighting=suggestion\nresharper_bad_control_braces_line_breaks_highlighting=none\nresharper_bad_declaration_braces_indent_highlighting=none\nresharper_bad_declaration_braces_line_breaks_highlighting=none\nresharper_bad_empty_braces_line_breaks_highlighting=none\nresharper_bad_expression_braces_indent_highlighting=none\nresharper_bad_expression_braces_line_breaks_highlighting=none\nresharper_bad_generic_brackets_spaces_highlighting=none\nresharper_bad_indent_highlighting=none\nresharper_bad_linq_line_breaks_highlighting=none\nresharper_bad_list_line_breaks_highlighting=none\nresharper_bad_member_access_spaces_highlighting=none\nresharper_bad_namespace_braces_indent_highlighting=none\nresharper_bad_parens_line_breaks_highlighting=none\nresharper_bad_parens_spaces_highlighting=none\nresharper_bad_preprocessor_indent_highlighting=none\nresharper_bad_semicolon_spaces_highlighting=none\nresharper_bad_spaces_after_keyword_highlighting=none\nresharper_bad_square_brackets_spaces_highlighting=none\nresharper_bad_switch_braces_indent_highlighting=none\nresharper_bad_symbol_spaces_highlighting=none\nresharper_base_member_has_params_highlighting=warning\nresharper_base_method_call_with_default_parameter_highlighting=warning\nresharper_base_object_equals_is_object_equals_highlighting=warning\nresharper_base_object_get_hash_code_call_in_get_hash_code_highlighting=warning\nresharper_bitwise_operator_on_enum_without_flags_highlighting=warning\nresharper_bl0001_highlighting=error\nresharper_bl0002_highlighting=warning\nresharper_bl0003_highlighting=warning\nresharper_bl0004_highlighting=error\nresharper_bl0005_highlighting=warning\nresharper_bl0006_highlighting=warning\nresharper_block_scope_redeclaration_highlighting=error\nresharper_built_in_type_reference_style_for_member_access_highlighting=hint\nresharper_built_in_type_reference_style_highlighting=hint\nresharper_by_ref_argument_is_volatile_field_highlighting=warning\nresharper_caller_callee_using_error_highlighting=error\nresharper_caller_callee_using_highlighting=warning\nresharper_cannot_apply_equality_operator_to_type_highlighting=warning\nresharper_center_tag_is_obsolete_highlighting=warning\nresharper_check_for_reference_equality_instead_1_highlighting=suggestion\nresharper_check_for_reference_equality_instead_2_highlighting=suggestion\nresharper_check_for_reference_equality_instead_3_highlighting=suggestion\nresharper_check_for_reference_equality_instead_4_highlighting=suggestion\nresharper_check_namespace_highlighting=warning\nresharper_class_cannot_be_instantiated_highlighting=warning\nresharper_class_can_be_sealed_global_highlighting=none\nresharper_class_can_be_sealed_local_highlighting=none\nresharper_class_never_instantiated_global_highlighting=suggestion\nresharper_class_never_instantiated_local_highlighting=suggestion\nresharper_class_with_virtual_members_never_inherited_global_highlighting=suggestion\nresharper_class_with_virtual_members_never_inherited_local_highlighting=suggestion\nresharper_clear_attribute_is_obsolete_all_highlighting=warning\nresharper_clear_attribute_is_obsolete_highlighting=warning\nresharper_closure_on_modified_variable_highlighting=warning\nresharper_coerced_equals_using_highlighting=warning\nresharper_coerced_equals_using_with_null_undefined_highlighting=none\nresharper_collection_never_queried_global_highlighting=warning\nresharper_collection_never_queried_local_highlighting=warning\nresharper_collection_never_updated_global_highlighting=warning\nresharper_collection_never_updated_local_highlighting=warning\nresharper_comma_not_valid_here_highlighting=error\nresharper_comment_typo_highlighting=suggestion\nresharper_compare_non_constrained_generic_with_null_highlighting=none\nresharper_compare_of_floats_by_equality_operator_highlighting=warning\nresharper_conditional_ternary_equal_branch_highlighting=warning\nresharper_condition_is_always_const_highlighting=warning\nresharper_condition_is_always_true_or_false_highlighting=warning\nresharper_confusing_char_as_integer_in_constructor_highlighting=warning\nresharper_constant_conditional_access_qualifier_highlighting=warning\nresharper_constant_null_coalescing_condition_highlighting=warning\nresharper_constructor_call_not_used_highlighting=warning\nresharper_constructor_initializer_loop_highlighting=warning\nresharper_container_annotation_redundancy_highlighting=warning\nresharper_context_value_is_provided_highlighting=none\nresharper_contract_annotation_not_parsed_highlighting=warning\nresharper_convert_closure_to_method_group_highlighting=suggestion\nresharper_convert_conditional_ternary_expression_to_switch_expression_highlighting=hint\nresharper_convert_if_do_to_while_highlighting=suggestion\nresharper_convert_if_statement_to_conditional_ternary_expression_highlighting=suggestion\nresharper_convert_if_statement_to_null_coalescing_assignment_highlighting=suggestion\nresharper_convert_if_statement_to_null_coalescing_expression_highlighting=suggestion\nresharper_convert_if_statement_to_return_statement_highlighting=hint\nresharper_convert_if_statement_to_switch_expression_highlighting=hint\nresharper_convert_if_statement_to_switch_statement_highlighting=hint\nresharper_convert_if_to_or_expression_highlighting=suggestion\nresharper_convert_nullable_to_short_form_highlighting=suggestion\nresharper_convert_switch_statement_to_switch_expression_highlighting=hint\nresharper_convert_to_auto_property_highlighting=suggestion\nresharper_convert_to_auto_property_when_possible_highlighting=hint\nresharper_convert_to_auto_property_with_private_setter_highlighting=hint\nresharper_convert_to_compound_assignment_highlighting=hint\nresharper_convert_to_constant_global_highlighting=hint\nresharper_convert_to_constant_local_highlighting=hint\nresharper_convert_to_lambda_expression_highlighting=suggestion\nresharper_convert_to_lambda_expression_when_possible_highlighting=none\nresharper_convert_to_local_function_highlighting=suggestion\nresharper_convert_to_null_coalescing_compound_assignment_highlighting=suggestion\nresharper_convert_to_static_class_highlighting=suggestion\nresharper_convert_to_using_declaration_highlighting=suggestion\nresharper_convert_to_vb_auto_property_highlighting=suggestion\nresharper_convert_to_vb_auto_property_when_possible_highlighting=hint\nresharper_convert_to_vb_auto_property_with_private_setter_highlighting=hint\nresharper_co_variant_array_conversion_highlighting=warning\nresharper_create_specialized_overload_highlighting=hint\nresharper_css_browser_compatibility_highlighting=warning\nresharper_css_caniuse_feature_requires_prefix_highlighting=hint\nresharper_css_caniuse_unsupported_feature_highlighting=hint\nresharper_css_not_resolved_highlighting=error\nresharper_css_obsolete_highlighting=hint\nresharper_css_property_does_not_override_vendor_property_highlighting=warning\nresharper_cyclic_reference_comment_highlighting=none\nresharper_c_sharp_warnings_cs0078_highlighting=warning\nresharper_c_sharp_warnings_cs0108_cs0114_highlighting=warning\nresharper_c_sharp_warnings_cs0109_highlighting=warning\nresharper_c_sharp_warnings_cs0162_highlighting=warning\nresharper_c_sharp_warnings_cs0183_highlighting=warning\nresharper_c_sharp_warnings_cs0184_highlighting=warning\nresharper_c_sharp_warnings_cs0197_highlighting=warning\nresharper_c_sharp_warnings_cs0252_cs0253_highlighting=warning\nresharper_c_sharp_warnings_cs0420_highlighting=warning\nresharper_c_sharp_warnings_cs0465_highlighting=warning\nresharper_c_sharp_warnings_cs0469_highlighting=warning\nresharper_c_sharp_warnings_cs0612_highlighting=warning\nresharper_c_sharp_warnings_cs0618_highlighting=warning\nresharper_c_sharp_warnings_cs0628_highlighting=warning\nresharper_c_sharp_warnings_cs0642_highlighting=warning\nresharper_c_sharp_warnings_cs0657_highlighting=warning\nresharper_c_sharp_warnings_cs0658_highlighting=warning\nresharper_c_sharp_warnings_cs0659_highlighting=warning\nresharper_c_sharp_warnings_cs0660_cs0661_highlighting=warning\nresharper_c_sharp_warnings_cs0665_highlighting=warning\nresharper_c_sharp_warnings_cs0672_highlighting=warning\nresharper_c_sharp_warnings_cs0693_highlighting=warning\nresharper_c_sharp_warnings_cs1030_highlighting=warning\nresharper_c_sharp_warnings_cs1058_highlighting=warning\nresharper_c_sharp_warnings_cs1066_highlighting=warning\nresharper_c_sharp_warnings_cs1522_highlighting=warning\nresharper_c_sharp_warnings_cs1570_highlighting=warning\nresharper_c_sharp_warnings_cs1571_highlighting=warning\nresharper_c_sharp_warnings_cs1572_highlighting=warning\nresharper_c_sharp_warnings_cs1573_highlighting=warning\nresharper_c_sharp_warnings_cs1574_cs1584_cs1581_cs1580_highlighting=warning\nresharper_c_sharp_warnings_cs1574_highlighting=warning\nresharper_c_sharp_warnings_cs1580_highlighting=warning\nresharper_c_sharp_warnings_cs1584_highlighting=warning\nresharper_c_sharp_warnings_cs1587_highlighting=warning\nresharper_c_sharp_warnings_cs1589_highlighting=warning\nresharper_c_sharp_warnings_cs1590_highlighting=warning\nresharper_c_sharp_warnings_cs1591_highlighting=warning\nresharper_c_sharp_warnings_cs1592_highlighting=warning\nresharper_c_sharp_warnings_cs1710_highlighting=warning\nresharper_c_sharp_warnings_cs1711_highlighting=warning\nresharper_c_sharp_warnings_cs1712_highlighting=warning\nresharper_c_sharp_warnings_cs1717_highlighting=warning\nresharper_c_sharp_warnings_cs1723_highlighting=warning\nresharper_c_sharp_warnings_cs1911_highlighting=warning\nresharper_c_sharp_warnings_cs1957_highlighting=warning\nresharper_c_sharp_warnings_cs1981_highlighting=warning\nresharper_c_sharp_warnings_cs1998_highlighting=warning\nresharper_c_sharp_warnings_cs4014_highlighting=warning\nresharper_c_sharp_warnings_cs7095_highlighting=warning\nresharper_c_sharp_warnings_cs8094_highlighting=warning\nresharper_c_sharp_warnings_cs8123_highlighting=warning\nresharper_c_sharp_warnings_cs8383_highlighting=warning\nresharper_c_sharp_warnings_cs8416_highlighting=warning\nresharper_c_sharp_warnings_cs8417_highlighting=warning\nresharper_c_sharp_warnings_cs8425_highlighting=warning\nresharper_c_sharp_warnings_cs8509_highlighting=warning\nresharper_c_sharp_warnings_cs8597_highlighting=warning\nresharper_c_sharp_warnings_cs8600_highlighting=warning\nresharper_c_sharp_warnings_cs8601_highlighting=warning\nresharper_c_sharp_warnings_cs8602_highlighting=warning\nresharper_c_sharp_warnings_cs8603_highlighting=warning\nresharper_c_sharp_warnings_cs8604_highlighting=warning\nresharper_c_sharp_warnings_cs8605_highlighting=warning\nresharper_c_sharp_warnings_cs8606_highlighting=warning\nresharper_c_sharp_warnings_cs8608_highlighting=warning\nresharper_c_sharp_warnings_cs8609_highlighting=warning\nresharper_c_sharp_warnings_cs8610_highlighting=warning\nresharper_c_sharp_warnings_cs8611_highlighting=warning\nresharper_c_sharp_warnings_cs8612_highlighting=warning\nresharper_c_sharp_warnings_cs8613_highlighting=warning\nresharper_c_sharp_warnings_cs8614_highlighting=warning\nresharper_c_sharp_warnings_cs8615_highlighting=warning\nresharper_c_sharp_warnings_cs8616_highlighting=warning\nresharper_c_sharp_warnings_cs8617_highlighting=warning\nresharper_c_sharp_warnings_cs8618_highlighting=warning\nresharper_c_sharp_warnings_cs8619_highlighting=warning\nresharper_c_sharp_warnings_cs8620_highlighting=warning\nresharper_c_sharp_warnings_cs8621_highlighting=warning\nresharper_c_sharp_warnings_cs8622_highlighting=warning\nresharper_c_sharp_warnings_cs8624_highlighting=warning\nresharper_c_sharp_warnings_cs8625_highlighting=warning\nresharper_c_sharp_warnings_cs8629_highlighting=warning\nresharper_c_sharp_warnings_cs8631_highlighting=warning\nresharper_c_sharp_warnings_cs8632_highlighting=warning\nresharper_c_sharp_warnings_cs8633_highlighting=warning\nresharper_c_sharp_warnings_cs8634_highlighting=warning\nresharper_c_sharp_warnings_cs8643_highlighting=warning\nresharper_c_sharp_warnings_cs8644_highlighting=warning\nresharper_c_sharp_warnings_cs8645_highlighting=warning\nresharper_c_sharp_warnings_cs8656_highlighting=warning\nresharper_c_sharp_warnings_cs8667_highlighting=warning\nresharper_c_sharp_warnings_cs8714_highlighting=warning\nresharper_c_sharp_warnings_wme006_highlighting=warning\nresharper_declaration_hides_highlighting=hint\nresharper_declaration_is_empty_highlighting=warning\nresharper_declaration_visibility_error_highlighting=error\nresharper_default_value_attribute_for_optional_parameter_highlighting=warning\nresharper_delegate_subtraction_highlighting=warning\nresharper_deleting_non_qualified_reference_highlighting=error\nresharper_dl_tag_contains_non_dt_or_dd_elements_highlighting=hint\nresharper_double_colons_expected_highlighting=error\nresharper_double_colons_preferred_highlighting=suggestion\nresharper_double_negation_of_boolean_highlighting=warning\nresharper_double_negation_operator_highlighting=suggestion\nresharper_duplicate_identifier_error_highlighting=error\nresharper_duplicate_reference_comment_highlighting=warning\nresharper_duplicate_resource_highlighting=warning\nresharper_duplicating_local_declaration_highlighting=warning\nresharper_duplicating_parameter_declaration_error_highlighting=error\nresharper_duplicating_property_declaration_error_highlighting=error\nresharper_duplicating_property_declaration_highlighting=warning\nresharper_duplicating_switch_label_highlighting=warning\nresharper_dynamic_shift_right_op_is_not_int_highlighting=warning\nresharper_ef1001_highlighting=warning\nresharper_elided_trailing_element_highlighting=warning\nresharper_empty_constructor_highlighting=warning\nresharper_empty_destructor_highlighting=warning\nresharper_empty_embedded_statement_highlighting=warning\nresharper_empty_for_statement_highlighting=warning\nresharper_empty_general_catch_clause_highlighting=warning\nresharper_empty_namespace_highlighting=warning\nresharper_empty_object_property_declaration_highlighting=error\nresharper_empty_return_value_for_type_annotated_function_highlighting=warning\nresharper_empty_statement_highlighting=warning\nresharper_empty_title_tag_highlighting=hint\nresharper_enc0001_highlighting=info\nresharper_enc0002_highlighting=info\nresharper_enc0003_highlighting=info\nresharper_enc0004_highlighting=info\nresharper_enc0005_highlighting=info\nresharper_enc0006_highlighting=info\nresharper_enc0007_highlighting=info\nresharper_enc0008_highlighting=info\nresharper_enc0009_highlighting=info\nresharper_enc0010_highlighting=info\nresharper_enc0011_highlighting=info\nresharper_enc0012_highlighting=info\nresharper_enc0013_highlighting=info\nresharper_enc0014_highlighting=info\nresharper_enc0015_highlighting=info\nresharper_enc0016_highlighting=info\nresharper_enc0017_highlighting=info\nresharper_enc0018_highlighting=info\nresharper_enc0019_highlighting=info\nresharper_enc0020_highlighting=info\nresharper_enc0021_highlighting=info\nresharper_enc0023_highlighting=info\nresharper_enc0024_highlighting=info\nresharper_enc0025_highlighting=info\nresharper_enc0026_highlighting=info\nresharper_enc0028_highlighting=info\nresharper_enc0029_highlighting=info\nresharper_enc0030_highlighting=info\nresharper_enc0031_highlighting=info\nresharper_enc0032_highlighting=info\nresharper_enc0033_highlighting=info\nresharper_enc0034_highlighting=info\nresharper_enc0035_highlighting=info\nresharper_enc0036_highlighting=info\nresharper_enc0037_highlighting=info\nresharper_enc0038_highlighting=info\nresharper_enc0039_highlighting=info\nresharper_enc0040_highlighting=info\nresharper_enc0041_highlighting=info\nresharper_enc0044_highlighting=info\nresharper_enc0045_highlighting=info\nresharper_enc0046_highlighting=info\nresharper_enc0047_highlighting=info\nresharper_enc0048_highlighting=info\nresharper_enc0049_highlighting=info\nresharper_enc0050_highlighting=info\nresharper_enc0051_highlighting=info\nresharper_enc0052_highlighting=info\nresharper_enc0053_highlighting=info\nresharper_enc0054_highlighting=info\nresharper_enc0055_highlighting=info\nresharper_enc0056_highlighting=info\nresharper_enc0057_highlighting=info\nresharper_enc0058_highlighting=info\nresharper_enc0059_highlighting=info\nresharper_enc0060_highlighting=info\nresharper_enc0061_highlighting=info\nresharper_enc0062_highlighting=info\nresharper_enc0063_highlighting=info\nresharper_enc0064_highlighting=info\nresharper_enc0065_highlighting=info\nresharper_enc0066_highlighting=info\nresharper_enc0067_highlighting=info\nresharper_enc0068_highlighting=info\nresharper_enc0069_highlighting=info\nresharper_enc0070_highlighting=info\nresharper_enc0071_highlighting=info\nresharper_enc0072_highlighting=info\nresharper_enc0073_highlighting=info\nresharper_enc0074_highlighting=info\nresharper_enc0075_highlighting=info\nresharper_enc0076_highlighting=info\nresharper_enc0080_highlighting=info\nresharper_enc0081_highlighting=info\nresharper_enc0082_highlighting=info\nresharper_enc0083_highlighting=info\nresharper_enc0084_highlighting=info\nresharper_enc0085_highlighting=info\nresharper_enc0086_highlighting=info\nresharper_enc1001_highlighting=info\nresharper_enc1002_highlighting=info\nresharper_enc1003_highlighting=info\nresharper_enc1004_highlighting=info\nresharper_enforce_do_while_statement_braces_highlighting=none\nresharper_enforce_fixed_statement_braces_highlighting=none\nresharper_enforce_foreach_statement_braces_highlighting=none\nresharper_enforce_for_statement_braces_highlighting=none\nresharper_enforce_if_statement_braces_highlighting=none\nresharper_enforce_lock_statement_braces_highlighting=none\nresharper_enforce_using_statement_braces_highlighting=none\nresharper_enforce_while_statement_braces_highlighting=none\nresharper_enumerable_sum_in_explicit_unchecked_context_highlighting=warning\nresharper_enum_underlying_type_is_int_highlighting=warning\nresharper_equal_expression_comparison_highlighting=warning\nresharper_error_in_xml_doc_reference_highlighting=error\nresharper_es6_feature_highlighting=error\nresharper_es7_feature_highlighting=error\nresharper_escaped_keyword_highlighting=warning\nresharper_eval_arguments_name_error_highlighting=error\nresharper_event_never_invoked_global_highlighting=suggestion\nresharper_event_never_invoked_highlighting=warning\nresharper_event_never_subscribed_to_global_highlighting=suggestion\nresharper_event_never_subscribed_to_local_highlighting=suggestion\nresharper_event_unsubscription_via_anonymous_delegate_highlighting=warning\nresharper_experimental_feature_highlighting=error\nresharper_explicit_caller_info_argument_highlighting=warning\nresharper_expression_is_always_const_highlighting=warning\nresharper_expression_is_always_null_highlighting=warning\nresharper_field_can_be_made_read_only_global_highlighting=suggestion\nresharper_field_can_be_made_read_only_local_highlighting=suggestion\nresharper_foreach_can_be_converted_to_query_using_another_get_enumerator_highlighting=hint\nresharper_foreach_can_be_partly_converted_to_query_using_another_get_enumerator_highlighting=hint\nresharper_format_string_placeholders_mismatch_highlighting=warning\nresharper_format_string_problem_highlighting=warning\nresharper_for_can_be_converted_to_foreach_highlighting=suggestion\nresharper_for_statement_condition_is_true_highlighting=warning\nresharper_functions_used_before_declared_highlighting=none\nresharper_function_complexity_overflow_highlighting=none\nresharper_function_never_returns_highlighting=warning\nresharper_function_parameter_named_arguments_highlighting=warning\nresharper_function_recursive_on_all_paths_highlighting=warning\nresharper_function_used_out_of_scope_highlighting=warning\nresharper_gc_suppress_finalize_for_type_without_destructor_highlighting=warning\nresharper_generic_enumerator_not_disposed_highlighting=warning\nresharper_heuristically_unreachable_code_highlighting=warning\nresharper_heuristic_unreachable_code_highlighting=warning\nresharper_hex_color_value_with_alpha_highlighting=error\nresharper_html_attributes_quotes_highlighting=hint\nresharper_html_attribute_not_resolved_highlighting=warning\nresharper_html_attribute_value_not_resolved_highlighting=warning\nresharper_html_dead_code_highlighting=warning\nresharper_html_event_not_resolved_highlighting=warning\nresharper_html_id_duplication_highlighting=warning\nresharper_html_id_not_resolved_highlighting=warning\nresharper_html_obsolete_highlighting=warning\nresharper_html_path_error_highlighting=warning\nresharper_html_tag_not_closed_highlighting=error\nresharper_html_tag_not_resolved_highlighting=warning\nresharper_html_tag_should_be_self_closed_highlighting=warning\nresharper_html_tag_should_not_be_self_closed_highlighting=warning\nresharper_html_warning_highlighting=warning\nresharper_identifier_typo_highlighting=suggestion\nresharper_ignored_directive_highlighting=warning\nresharper_implicit_any_error_highlighting=error\nresharper_implicit_any_type_warning_highlighting=warning\nresharper_import_keyword_not_with_invocation_highlighting=error\nresharper_inactive_preprocessor_branch_highlighting=warning\nresharper_inconsistently_synchronized_field_highlighting=warning\nresharper_inconsistent_function_returns_highlighting=warning\nresharper_inconsistent_naming_highlighting=warning\nresharper_incorrect_blank_lines_near_braces_highlighting=none\nresharper_incorrect_operand_in_type_of_comparison_highlighting=warning\nresharper_incorrect_triple_slash_location_highlighting=warning\nresharper_indexing_by_invalid_range_highlighting=warning\nresharper_inheritdoc_consider_usage_highlighting=none\nresharper_inheritdoc_invalid_usage_highlighting=warning\nresharper_inline_out_variable_declaration_highlighting=suggestion\nresharper_internal_or_private_member_not_documented_highlighting=none\nresharper_interpolated_string_expression_is_not_i_formattable_highlighting=warning\nresharper_introduce_optional_parameters_global_highlighting=suggestion\nresharper_introduce_optional_parameters_local_highlighting=suggestion\nresharper_introduce_variable_to_apply_guard_highlighting=hint\nresharper_int_division_by_zero_highlighting=warning\nresharper_int_relational_or_equality_expression_always_same_value_highlighting=warning\nresharper_int_variable_overflow_highlighting=warning\nresharper_int_variable_overflow_in_checked_context_highlighting=warning\nresharper_int_variable_overflow_in_unchecked_context_highlighting=warning\nresharper_invalid_attribute_value_highlighting=warning\nresharper_invalid_json_syntax_highlighting=error\nresharper_invalid_task_element_highlighting=none\nresharper_invalid_value_highlighting=error\nresharper_invalid_value_type_highlighting=warning\nresharper_invalid_xml_doc_comment_highlighting=warning\nresharper_invert_condition_1_highlighting=hint\nresharper_invert_if_highlighting=hint\nresharper_invocation_is_skipped_highlighting=hint\nresharper_invocation_of_non_function_highlighting=warning\nresharper_invoked_expression_maybe_non_function_highlighting=warning\nresharper_invoke_as_extension_method_highlighting=suggestion\nresharper_is_expression_always_false_highlighting=warning\nresharper_is_expression_always_of_type_highlighting=warning\nresharper_is_expression_always_true_highlighting=warning\nresharper_iterator_method_result_is_ignored_highlighting=warning\nresharper_iterator_never_returns_highlighting=warning\nresharper_join_declaration_and_initializer_highlighting=suggestion\nresharper_join_declaration_and_initializer_js_highlighting=suggestion\nresharper_join_null_check_with_usage_highlighting=suggestion\nresharper_join_null_check_with_usage_when_possible_highlighting=none\nresharper_json_validation_failed_highlighting=error\nresharper_js_path_not_found_highlighting=error\nresharper_js_unreachable_code_highlighting=warning\nresharper_jump_must_be_in_loop_highlighting=warning\nresharper_label_or_semicolon_expected_highlighting=error\nresharper_less_specific_overload_than_main_signature_highlighting=warning\nresharper_lexical_declaration_needs_block_highlighting=error\nresharper_localizable_element_highlighting=warning\nresharper_local_function_can_be_made_static_highlighting=hint\nresharper_local_function_redefined_later_highlighting=warning\nresharper_local_name_captured_only_highlighting=warning\nresharper_local_variable_hides_member_highlighting=warning\nresharper_long_literal_ending_lower_l_highlighting=warning\nresharper_loop_can_be_converted_to_query_highlighting=hint\nresharper_loop_can_be_partly_converted_to_query_highlighting=none\nresharper_loop_variable_is_never_changed_inside_loop_highlighting=warning\nresharper_l_value_is_expected_highlighting=error\nresharper_markup_attribute_typo_highlighting=suggestion\nresharper_markup_text_typo_highlighting=suggestion\nresharper_meaningless_default_parameter_value_highlighting=warning\nresharper_member_can_be_internal_highlighting=none\nresharper_member_can_be_made_static_global_highlighting=hint\nresharper_member_can_be_made_static_local_highlighting=hint\nresharper_member_can_be_private_global_highlighting=suggestion\nresharper_member_can_be_private_local_highlighting=suggestion\nresharper_member_can_be_protected_global_highlighting=suggestion\nresharper_member_can_be_protected_local_highlighting=suggestion\nresharper_member_hides_static_from_outer_class_highlighting=warning\nresharper_member_initializer_value_ignored_highlighting=warning\nresharper_merge_cast_with_type_check_highlighting=suggestion\nresharper_merge_conditional_expression_highlighting=suggestion\nresharper_merge_conditional_expression_when_possible_highlighting=none\nresharper_merge_sequential_checks_highlighting=suggestion\nresharper_merge_sequential_checks_when_possible_highlighting=none\nresharper_method_has_async_overload_highlighting=suggestion\nresharper_method_has_async_overload_with_cancellation_highlighting=suggestion\nresharper_method_overload_with_optional_parameter_highlighting=warning\nresharper_method_supports_cancellation_highlighting=suggestion\nresharper_missing_alt_attribute_in_img_tag_highlighting=hint\nresharper_missing_attribute_highlighting=warning\nresharper_missing_blank_lines_highlighting=none\nresharper_missing_body_tag_highlighting=warning\nresharper_missing_has_own_property_in_foreach_highlighting=warning\nresharper_missing_head_and_body_tags_highlighting=warning\nresharper_missing_head_tag_highlighting=warning\nresharper_missing_indent_highlighting=none\nresharper_missing_linebreak_highlighting=none\nresharper_missing_space_highlighting=none\nresharper_missing_title_tag_highlighting=hint\nresharper_misuse_of_owner_function_this_highlighting=warning\nresharper_more_specific_foreach_variable_type_available_highlighting=suggestion\nresharper_more_specific_signature_after_less_specific_highlighting=warning\nresharper_multiple_declarations_in_foreach_highlighting=error\nresharper_multiple_nullable_attributes_usage_highlighting=warning\nresharper_multiple_order_by_highlighting=warning\nresharper_multiple_output_tags_highlighting=warning\nresharper_multiple_resolve_candidates_in_text_highlighting=warning\nresharper_multiple_spaces_highlighting=none\nresharper_multiple_statements_on_one_line_highlighting=none\nresharper_multiple_type_members_on_one_line_highlighting=none\nresharper_must_use_return_value_highlighting=warning\nresharper_mvc1000_highlighting=warning\nresharper_mvc1001_highlighting=warning\nresharper_mvc1002_highlighting=warning\nresharper_mvc1003_highlighting=warning\nresharper_mvc1004_highlighting=warning\nresharper_mvc1005_highlighting=warning\nresharper_mvc1006_highlighting=error\nresharper_mvc_action_not_resolved_highlighting=error\nresharper_mvc_area_not_resolved_highlighting=error\nresharper_mvc_controller_not_resolved_highlighting=error\nresharper_mvc_invalid_model_type_highlighting=error\nresharper_mvc_masterpage_not_resolved_highlighting=error\nresharper_mvc_partial_view_not_resolved_highlighting=error\nresharper_mvc_template_not_resolved_highlighting=error\nresharper_mvc_view_component_not_resolved_highlighting=error\nresharper_mvc_view_component_view_not_resolved_highlighting=error\nresharper_mvc_view_not_resolved_highlighting=error\nresharper_native_type_prototype_extending_highlighting=warning\nresharper_native_type_prototype_overwriting_highlighting=warning\nresharper_negative_equality_expression_highlighting=suggestion\nresharper_negative_index_highlighting=warning\nresharper_nested_string_interpolation_highlighting=suggestion\nresharper_non_assigned_constant_highlighting=error\nresharper_non_constant_equality_expression_has_constant_result_highlighting=warning\nresharper_non_readonly_member_in_get_hash_code_highlighting=warning\nresharper_non_volatile_field_in_double_check_locking_highlighting=warning\nresharper_not_accessed_field_compiler_highlighting=warning\nresharper_not_accessed_field_global_highlighting=suggestion\nresharper_not_accessed_field_local_highlighting=warning\nresharper_not_accessed_variable_compiler_highlighting=warning\nresharper_not_accessed_variable_highlighting=warning\nresharper_not_all_paths_return_value_highlighting=warning\nresharper_not_assigned_out_parameter_highlighting=warning\nresharper_not_declared_in_parent_culture_highlighting=warning\nresharper_not_null_member_is_not_initialized_highlighting=warning\nresharper_not_observable_annotation_redundancy_highlighting=warning\nresharper_not_overridden_in_specific_culture_highlighting=warning\nresharper_not_resolved_highlighting=warning\nresharper_not_resolved_in_text_highlighting=warning\nresharper_no_support_for_vb_highlighting=warning\nresharper_n_unit_async_method_must_be_task_highlighting=warning\nresharper_n_unit_incorrect_argument_type_highlighting=warning\nresharper_n_unit_incorrect_expected_result_type_highlighting=warning\nresharper_n_unit_method_with_parameters_and_test_attribute_highlighting=warning\nresharper_n_unit_missing_arguments_in_test_case_attribute_highlighting=warning\nresharper_n_unit_non_public_method_with_test_attribute_highlighting=warning\nresharper_n_unit_redundant_argument_instead_of_expected_result_highlighting=warning\nresharper_n_unit_redundant_argument_in_test_case_attribute_highlighting=warning\nresharper_n_unit_redundant_expected_result_in_test_case_attribute_highlighting=warning\nresharper_n_unit_test_case_attribute_requires_expected_result_highlighting=warning\nresharper_n_unit_test_case_result_property_duplicates_expected_result_highlighting=warning\nresharper_n_unit_test_case_result_property_is_obsolete_highlighting=warning\nresharper_n_unit_test_case_source_cannot_be_resolved_highlighting=warning\nresharper_n_unit_test_case_source_must_be_field_property_method_highlighting=warning\nresharper_n_unit_test_case_source_must_be_static_highlighting=warning\nresharper_n_unit_test_case_source_should_implement_i_enumerable_highlighting=warning\nresharper_object_creation_as_statement_highlighting=warning\nresharper_object_destructuring_without_parentheses_highlighting=error\nresharper_object_literals_are_not_comma_free_highlighting=error\nresharper_obsolete_element_error_highlighting=error\nresharper_obsolete_element_highlighting=warning\nresharper_octal_literals_not_allowed_error_highlighting=error\nresharper_ol_tag_contains_non_li_elements_highlighting=hint\nresharper_one_way_operation_contract_with_return_type_highlighting=warning\nresharper_operation_contract_without_service_contract_highlighting=warning\nresharper_operator_is_can_be_used_highlighting=warning\nresharper_optional_parameter_hierarchy_mismatch_highlighting=warning\nresharper_optional_parameter_ref_out_highlighting=warning\nresharper_other_tags_inside_script1_highlighting=error\nresharper_other_tags_inside_script2_highlighting=error\nresharper_other_tags_inside_unclosed_script_highlighting=error\nresharper_outdent_is_off_prev_level_highlighting=none\nresharper_output_tag_required_highlighting=warning\nresharper_overridden_with_empty_value_highlighting=warning\nresharper_overridden_with_same_value_highlighting=suggestion\nresharper_parameter_doesnt_make_any_sense_highlighting=warning\nresharper_parameter_hides_member_highlighting=warning\nresharper_parameter_only_used_for_precondition_check_global_highlighting=suggestion\nresharper_parameter_only_used_for_precondition_check_local_highlighting=warning\nresharper_parameter_type_can_be_enumerable_global_highlighting=hint\nresharper_parameter_type_can_be_enumerable_local_highlighting=hint\nresharper_parameter_value_is_not_used_highlighting=warning\nresharper_partial_method_parameter_name_mismatch_highlighting=warning\nresharper_partial_method_with_single_part_highlighting=warning\nresharper_partial_type_with_single_part_highlighting=warning\nresharper_path_not_resolved_highlighting=error\nresharper_pattern_always_matches_highlighting=warning\nresharper_pattern_always_of_type_highlighting=warning\nresharper_pattern_never_matches_highlighting=warning\nresharper_polymorphic_field_like_event_invocation_highlighting=warning\nresharper_possible_infinite_inheritance_highlighting=warning\nresharper_possible_intended_rethrow_highlighting=warning\nresharper_possible_interface_member_ambiguity_highlighting=warning\nresharper_possible_invalid_cast_exception_highlighting=warning\nresharper_possible_invalid_cast_exception_in_foreach_loop_highlighting=warning\nresharper_possible_invalid_operation_exception_highlighting=warning\nresharper_possible_loss_of_fraction_highlighting=warning\nresharper_possible_mistaken_argument_highlighting=warning\nresharper_possible_mistaken_call_to_get_type_1_highlighting=warning\nresharper_possible_mistaken_call_to_get_type_2_highlighting=warning\nresharper_possible_multiple_enumeration_highlighting=warning\nresharper_possible_multiple_write_access_in_double_check_locking_highlighting=warning\nresharper_possible_null_reference_exception_highlighting=warning\nresharper_possible_struct_member_modification_of_non_variable_struct_highlighting=warning\nresharper_possible_unintended_linear_search_in_set_highlighting=warning\nresharper_possible_unintended_queryable_as_enumerable_highlighting=suggestion\nresharper_possible_unintended_reference_comparison_highlighting=warning\nresharper_possible_write_to_me_highlighting=warning\nresharper_possibly_impure_method_call_on_readonly_variable_highlighting=warning\nresharper_possibly_incorrectly_broken_statement_highlighting=warning\nresharper_possibly_missing_indexer_initializer_comma_highlighting=warning\nresharper_possibly_mistaken_use_of_interpolated_string_insert_highlighting=warning\nresharper_possibly_mistaken_use_of_params_method_highlighting=warning\nresharper_possibly_unassigned_property_highlighting=hint\nresharper_private_field_can_be_converted_to_local_variable_highlighting=warning\nresharper_private_variable_can_be_made_readonly_highlighting=hint\nresharper_property_getter_cannot_have_parameters_highlighting=error\nresharper_property_not_resolved_highlighting=error\nresharper_property_setter_must_have_single_parameter_highlighting=error\nresharper_public_constructor_in_abstract_class_highlighting=suggestion\nresharper_pure_attribute_on_void_method_highlighting=warning\nresharper_qualified_expression_is_null_highlighting=warning\nresharper_qualified_expression_maybe_null_highlighting=warning\nresharper_razor_layout_not_resolved_highlighting=error\nresharper_razor_section_not_resolved_highlighting=error\nresharper_read_access_in_double_check_locking_highlighting=warning\nresharper_redundant_abstract_modifier_highlighting=warning\nresharper_redundant_anonymous_type_property_name_highlighting=warning\nresharper_redundant_argument_default_value_highlighting=warning\nresharper_redundant_array_creation_expression_highlighting=hint\nresharper_redundant_array_lower_bound_specification_highlighting=warning\nresharper_redundant_assignment_highlighting=warning\nresharper_redundant_attribute_parentheses_highlighting=hint\nresharper_redundant_attribute_usage_property_highlighting=suggestion\nresharper_redundant_base_constructor_call_highlighting=warning\nresharper_redundant_base_qualifier_highlighting=warning\nresharper_redundant_blank_lines_highlighting=none\nresharper_redundant_block_highlighting=warning\nresharper_redundant_bool_compare_highlighting=warning\nresharper_redundant_case_label_highlighting=warning\nresharper_redundant_cast_0_highlighting=warning\nresharper_redundant_cast_highlighting=warning\nresharper_redundant_catch_clause_highlighting=warning\nresharper_redundant_check_before_assignment_highlighting=warning\nresharper_redundant_collection_initializer_element_braces_highlighting=hint\nresharper_redundant_comparison_with_boolean_highlighting=warning\nresharper_redundant_css_hack_highlighting=warning\nresharper_redundant_declaration_semicolon_highlighting=hint\nresharper_redundant_default_member_initializer_highlighting=warning\nresharper_redundant_delegate_creation_highlighting=warning\nresharper_redundant_disable_warning_comment_highlighting=warning\nresharper_redundant_discarded_pattern_highlighting=suggestion\nresharper_redundant_discard_designation_highlighting=suggestion\nresharper_redundant_else_block_highlighting=warning\nresharper_redundant_empty_case_else_highlighting=warning\nresharper_redundant_empty_constructor_highlighting=warning\nresharper_redundant_empty_finally_block_highlighting=warning\nresharper_redundant_empty_object_creation_argument_list_highlighting=hint\nresharper_redundant_empty_object_or_collection_initializer_highlighting=warning\nresharper_redundant_empty_switch_section_highlighting=warning\nresharper_redundant_enumerable_cast_call_highlighting=warning\nresharper_redundant_explicit_array_creation_highlighting=warning\nresharper_redundant_explicit_array_size_highlighting=warning\nresharper_redundant_explicit_nullable_creation_highlighting=warning\nresharper_redundant_explicit_params_array_creation_highlighting=suggestion\nresharper_redundant_explicit_tuple_component_name_highlighting=warning\nresharper_redundant_extends_list_entry_highlighting=warning\nresharper_redundant_fixed_pointer_declaration_highlighting=suggestion\nresharper_redundant_highlighting=warning\nresharper_redundant_if_else_block_highlighting=hint\nresharper_redundant_if_statement_then_keyword_highlighting=none\nresharper_redundant_immediate_delegate_invocation_highlighting=suggestion\nresharper_redundant_include_highlighting=warning\nresharper_redundant_intermediate_variable_highlighting=hint\nresharper_redundant_iterator_keyword_highlighting=warning\nresharper_redundant_jump_statement_highlighting=warning\nresharper_redundant_lambda_parameter_type_highlighting=warning\nresharper_redundant_lambda_signature_parentheses_highlighting=hint\nresharper_redundant_linebreak_highlighting=none\nresharper_redundant_local_class_name_highlighting=hint\nresharper_redundant_local_function_name_highlighting=hint\nresharper_redundant_logical_conditional_expression_operand_highlighting=warning\nresharper_redundant_me_qualifier_highlighting=warning\nresharper_redundant_my_base_qualifier_highlighting=warning\nresharper_redundant_my_class_qualifier_highlighting=warning\nresharper_redundant_name_qualifier_highlighting=warning\nresharper_redundant_not_null_constraint_highlighting=warning\nresharper_redundant_nullable_annotation_on_reference_type_constraint_highlighting=warning\nresharper_redundant_nullable_annotation_on_type_constraint_has_non_nullable_base_type_highlighting=warning\nresharper_redundant_nullable_annotation_on_type_constraint_has_non_nullable_type_kind_highlighting=warning\nresharper_redundant_nullable_type_mark_highlighting=warning\nresharper_redundant_overflow_checking_context_highlighting=warning\nresharper_redundant_overload_global_highlighting=suggestion\nresharper_redundant_overload_local_highlighting=suggestion\nresharper_redundant_overridden_member_highlighting=warning\nresharper_redundant_params_highlighting=warning\nresharper_redundant_parentheses_highlighting=none\nresharper_redundant_parent_type_declaration_highlighting=warning\nresharper_redundant_property_parentheses_highlighting=hint\nresharper_redundant_property_pattern_clause_highlighting=suggestion\nresharper_redundant_qualifier_highlighting=warning\nresharper_redundant_query_order_by_ascending_keyword_highlighting=hint\nresharper_redundant_range_bound_highlighting=suggestion\nresharper_redundant_readonly_modifier_highlighting=suggestion\nresharper_redundant_setter_value_parameter_declaration_highlighting=hint\nresharper_redundant_space_highlighting=none\nresharper_redundant_string_format_call_highlighting=warning\nresharper_redundant_string_interpolation_highlighting=suggestion\nresharper_redundant_string_to_char_array_call_highlighting=warning\nresharper_redundant_string_type_highlighting=suggestion\nresharper_redundant_ternary_expression_highlighting=warning\nresharper_redundant_to_string_call_for_value_type_highlighting=hint\nresharper_redundant_to_string_call_highlighting=warning\nresharper_redundant_type_arguments_of_method_highlighting=warning\nresharper_redundant_type_cast_highlighting=warning\nresharper_redundant_type_cast_structural_highlighting=warning\nresharper_redundant_type_specification_in_default_expression_highlighting=suggestion\nresharper_redundant_units_highlighting=warning\nresharper_redundant_unsafe_context_highlighting=warning\nresharper_redundant_using_directive_highlighting=warning\nresharper_redundant_variable_type_specification_highlighting=hint\nresharper_redundant_verbatim_prefix_highlighting=suggestion\nresharper_redundant_verbatim_string_prefix_highlighting=suggestion\nresharper_reference_equals_with_value_type_highlighting=warning\nresharper_reg_exp_inspections_highlighting=warning\nresharper_remove_constructor_invocation_highlighting=none\nresharper_remove_redundant_braces_highlighting=none\nresharper_remove_redundant_or_statement_false_highlighting=suggestion\nresharper_remove_redundant_or_statement_true_highlighting=suggestion\nresharper_remove_to_list_1_highlighting=suggestion\nresharper_remove_to_list_2_highlighting=suggestion\nresharper_replace_indicing_with_array_destructuring_highlighting=hint\nresharper_replace_indicing_with_short_hand_properties_after_destructuring_highlighting=hint\nresharper_replace_undefined_checking_series_with_object_destructuring_highlighting=hint\nresharper_replace_with_destructuring_swap_highlighting=hint\nresharper_replace_with_first_or_default_1_highlighting=suggestion\nresharper_replace_with_first_or_default_2_highlighting=suggestion\nresharper_replace_with_first_or_default_3_highlighting=suggestion\nresharper_replace_with_first_or_default_4_highlighting=suggestion\nresharper_replace_with_last_or_default_1_highlighting=suggestion\nresharper_replace_with_last_or_default_2_highlighting=suggestion\nresharper_replace_with_last_or_default_3_highlighting=suggestion\nresharper_replace_with_last_or_default_4_highlighting=suggestion\nresharper_replace_with_of_type_1_highlighting=suggestion\nresharper_replace_with_of_type_2_highlighting=suggestion\nresharper_replace_with_of_type_3_highlighting=suggestion\nresharper_replace_with_of_type_any_1_highlighting=suggestion\nresharper_replace_with_of_type_any_2_highlighting=suggestion\nresharper_replace_with_of_type_count_1_highlighting=suggestion\nresharper_replace_with_of_type_count_2_highlighting=suggestion\nresharper_replace_with_of_type_first_1_highlighting=suggestion\nresharper_replace_with_of_type_first_2_highlighting=suggestion\nresharper_replace_with_of_type_first_or_default_1_highlighting=suggestion\nresharper_replace_with_of_type_first_or_default_2_highlighting=suggestion\nresharper_replace_with_of_type_last_1_highlighting=suggestion\nresharper_replace_with_of_type_last_2_highlighting=suggestion\nresharper_replace_with_of_type_last_or_default_1_highlighting=suggestion\nresharper_replace_with_of_type_last_or_default_2_highlighting=suggestion\nresharper_replace_with_of_type_long_count_highlighting=suggestion\nresharper_replace_with_of_type_single_1_highlighting=suggestion\nresharper_replace_with_of_type_single_2_highlighting=suggestion\nresharper_replace_with_of_type_single_or_default_1_highlighting=suggestion\nresharper_replace_with_of_type_single_or_default_2_highlighting=suggestion\nresharper_replace_with_of_type_where_highlighting=suggestion\nresharper_replace_with_simple_assignment_false_highlighting=suggestion\nresharper_replace_with_simple_assignment_true_highlighting=suggestion\nresharper_replace_with_single_assignment_false_highlighting=suggestion\nresharper_replace_with_single_assignment_true_highlighting=suggestion\nresharper_replace_with_single_call_to_any_highlighting=suggestion\nresharper_replace_with_single_call_to_count_highlighting=suggestion\nresharper_replace_with_single_call_to_first_highlighting=suggestion\nresharper_replace_with_single_call_to_first_or_default_highlighting=suggestion\nresharper_replace_with_single_call_to_last_highlighting=suggestion\nresharper_replace_with_single_call_to_last_or_default_highlighting=suggestion\nresharper_replace_with_single_call_to_single_highlighting=suggestion\nresharper_replace_with_single_call_to_single_or_default_highlighting=suggestion\nresharper_replace_with_single_or_default_1_highlighting=suggestion\nresharper_replace_with_single_or_default_2_highlighting=suggestion\nresharper_replace_with_single_or_default_3_highlighting=suggestion\nresharper_replace_with_single_or_default_4_highlighting=suggestion\nresharper_replace_with_string_is_null_or_empty_highlighting=suggestion\nresharper_required_base_types_conflict_highlighting=warning\nresharper_required_base_types_direct_conflict_highlighting=warning\nresharper_required_base_types_is_not_inherited_highlighting=warning\nresharper_requires_fallback_color_highlighting=warning\nresharper_resource_item_not_resolved_highlighting=error\nresharper_resource_not_resolved_highlighting=error\nresharper_resx_not_resolved_highlighting=warning\nresharper_return_from_global_scopet_with_value_highlighting=warning\nresharper_return_type_can_be_enumerable_global_highlighting=hint\nresharper_return_type_can_be_enumerable_local_highlighting=hint\nresharper_return_value_of_pure_method_is_not_used_highlighting=warning\nresharper_safe_cast_is_used_as_type_check_highlighting=suggestion\nresharper_same_imports_with_different_name_highlighting=warning\nresharper_same_variable_assignment_highlighting=warning\nresharper_script_tag_has_both_src_and_content_attributes_highlighting=error\nresharper_script_tag_with_content_before_includes_highlighting=hint\nresharper_sealed_member_in_sealed_class_highlighting=warning\nresharper_sensitive_data_api_usage_tag_highlighting=warning\nresharper_separate_control_transfer_statement_highlighting=none\nresharper_service_contract_without_operations_highlighting=warning\nresharper_shift_expression_real_shift_count_is_zero_highlighting=warning\nresharper_shift_expression_result_equals_zero_highlighting=warning\nresharper_shift_expression_right_operand_not_equal_real_count_highlighting=warning\nresharper_shift_expression_zero_left_operand_highlighting=warning\nresharper_similar_anonymous_type_nearby_highlighting=hint\nresharper_similar_expressions_comparison_highlighting=warning\nresharper_simplify_conditional_operator_highlighting=suggestion\nresharper_simplify_conditional_ternary_expression_highlighting=suggestion\nresharper_simplify_i_if_highlighting=suggestion\nresharper_simplify_linq_expression_highlighting=suggestion\nresharper_specify_a_culture_in_string_conversion_explicitly_highlighting=warning\nresharper_specify_string_comparison_highlighting=hint\nresharper_specify_variable_type_explicitly_highlighting=hint\nresharper_stack_alloc_inside_loop_highlighting=warning\nresharper_statement_termination_highlighting=warning\nresharper_static_member_initializer_referes_to_member_below_highlighting=warning\nresharper_static_member_in_generic_type_highlighting=warning\nresharper_static_problem_in_text_highlighting=warning\nresharper_string_compare_is_culture_specific_1_highlighting=warning\nresharper_string_compare_is_culture_specific_2_highlighting=warning\nresharper_string_compare_is_culture_specific_3_highlighting=warning\nresharper_string_compare_is_culture_specific_4_highlighting=warning\nresharper_string_compare_is_culture_specific_5_highlighting=warning\nresharper_string_compare_is_culture_specific_6_highlighting=warning\nresharper_string_compare_to_is_culture_specific_highlighting=warning\nresharper_string_concatenation_to_template_string_highlighting=hint\nresharper_string_ends_with_is_culture_specific_highlighting=none\nresharper_string_index_of_is_culture_specific_1_highlighting=warning\nresharper_string_index_of_is_culture_specific_2_highlighting=warning\nresharper_string_index_of_is_culture_specific_3_highlighting=warning\nresharper_string_last_index_of_is_culture_specific_1_highlighting=warning\nresharper_string_last_index_of_is_culture_specific_2_highlighting=warning\nresharper_string_last_index_of_is_culture_specific_3_highlighting=warning\nresharper_string_literal_as_interpolation_argument_highlighting=suggestion\nresharper_string_literal_typo_highlighting=suggestion\nresharper_string_literal_wrong_quotes_highlighting=hint\nresharper_string_starts_with_is_culture_specific_highlighting=none\nresharper_struct_can_be_made_read_only_highlighting=suggestion\nresharper_struct_member_can_be_made_read_only_highlighting=none\nresharper_suggest_base_type_for_parameter_highlighting=hint\nresharper_suggest_discard_declaration_var_style_highlighting=hint\nresharper_suggest_var_or_type_built_in_types_highlighting=hint\nresharper_suggest_var_or_type_deconstruction_declarations_highlighting=hint\nresharper_suggest_var_or_type_elsewhere_highlighting=hint\nresharper_suggest_var_or_type_simple_types_highlighting=hint\nresharper_super_call_prohibits_this_highlighting=error\nresharper_suspicious_instanceof_check_highlighting=warning\nresharper_suspicious_lambda_block_highlighting=warning\nresharper_suspicious_this_usage_highlighting=warning\nresharper_suspicious_typeof_check_highlighting=warning\nresharper_suspicious_type_conversion_global_highlighting=warning\nresharper_switch_expression_handles_some_known_enum_values_with_exception_in_default_highlighting=hint\nresharper_switch_statement_for_enum_misses_default_section_highlighting=hint\nresharper_switch_statement_handles_some_known_enum_values_with_default_highlighting=hint\nresharper_switch_statement_missing_some_enum_cases_no_default_highlighting=hint\nresharper_symbol_from_not_copied_locally_reference_used_warning_highlighting=warning\nresharper_syntax_is_not_allowed_highlighting=warning\nresharper_tabs_and_spaces_mismatch_highlighting=none\nresharper_tabs_are_disallowed_highlighting=none\nresharper_tabs_outside_indent_highlighting=none\nresharper_tail_recursive_call_highlighting=hint\nresharper_tasks_not_loaded_highlighting=warning\nresharper_ternary_can_be_replaced_by_its_condition_highlighting=warning\nresharper_this_in_global_context_highlighting=warning\nresharper_thread_static_at_instance_field_highlighting=warning\nresharper_thread_static_field_has_initializer_highlighting=warning\nresharper_throw_must_be_followed_by_expression_highlighting=error\nresharper_too_wide_local_variable_scope_highlighting=suggestion\nresharper_tree_node_enumerable_can_be_used_tag_highlighting=none\nresharper_try_cast_always_succeeds_highlighting=suggestion\nresharper_try_statements_can_be_merged_highlighting=hint\nresharper_ts_not_resolved_highlighting=error\nresharper_ts_resolved_from_inaccessible_module_highlighting=error\nresharper_type_guard_doesnt_affect_anything_highlighting=warning\nresharper_type_guard_produces_never_type_highlighting=warning\nresharper_type_parameter_can_be_variant_highlighting=suggestion\nresharper_type_parameter_hides_type_param_from_outer_scope_highlighting=warning\nresharper_ul_tag_contains_non_li_elements_highlighting=hint\nresharper_unassigned_field_compiler_highlighting=warning\nresharper_unassigned_field_global_highlighting=suggestion\nresharper_unassigned_field_local_highlighting=warning\nresharper_unassigned_get_only_auto_property_highlighting=warning\nresharper_unassigned_readonly_field_compiler_highlighting=warning\nresharper_unassigned_readonly_field_highlighting=warning\nresharper_unclosed_script_highlighting=error\nresharper_undeclared_global_variable_using_highlighting=warning\nresharper_unexpected_attribute_highlighting=warning\nresharper_unexpected_directive_highlighting=warning\nresharper_unexpected_value_highlighting=error\nresharper_unknown_css_class_highlighting=warning\nresharper_unknown_css_variable_highlighting=warning\nresharper_unknown_css_vendor_extension_highlighting=hint\nresharper_unknown_item_group_highlighting=warning\nresharper_unknown_metadata_highlighting=warning\nresharper_unknown_output_parameter_highlighting=warning\nresharper_unknown_property_highlighting=warning\nresharper_unknown_target_highlighting=warning\nresharper_unknown_task_attribute_highlighting=warning\nresharper_unknown_task_highlighting=warning\nresharper_unnecessary_whitespace_highlighting=none\nresharper_unreachable_code_highlighting=warning\nresharper_unreachable_switch_arm_due_to_integer_analysis_highlighting=warning\nresharper_unreachable_switch_case_due_to_integer_analysis_highlighting=warning\nresharper_unresolved_assembly_highlighting=warning\nresharper_unresolved_include_highlighting=warning\nresharper_unsafe_comma_in_object_properties_list_highlighting=warning\nresharper_unsupported_required_base_type_highlighting=warning\nresharper_unused_anonymous_method_signature_highlighting=warning\nresharper_unused_auto_property_accessor_global_highlighting=warning\nresharper_unused_auto_property_accessor_local_highlighting=warning\nresharper_unused_field_compiler_highlighting=warning\nresharper_unused_import_clause_highlighting=warning\nresharper_unused_inherited_parameter_highlighting=hint\nresharper_unused_label_highlighting=warning\nresharper_unused_locals_highlighting=warning\nresharper_unused_local_function_compiler_highlighting=warning\nresharper_unused_local_function_highlighting=warning\nresharper_unused_local_function_parameter_highlighting=warning\nresharper_unused_local_function_return_value_highlighting=warning\nresharper_unused_local_import_highlighting=warning\nresharper_unused_member_global_highlighting=suggestion\nresharper_unused_member_hierarchy_global_highlighting=suggestion\nresharper_unused_member_hierarchy_local_highlighting=warning\nresharper_unused_member_in_super_global_highlighting=suggestion\nresharper_unused_member_in_super_local_highlighting=warning\nresharper_unused_member_local_highlighting=warning\nresharper_unused_method_return_value_global_highlighting=suggestion\nresharper_unused_method_return_value_local_highlighting=warning\nresharper_unused_parameter_global_highlighting=suggestion\nresharper_unused_parameter_highlighting=warning\nresharper_unused_parameter_in_partial_method_highlighting=warning\nresharper_unused_parameter_local_highlighting=warning\nresharper_unused_property_highlighting=warning\nresharper_unused_tuple_component_in_return_value_highlighting=warning\nresharper_unused_type_global_highlighting=suggestion\nresharper_unused_type_local_highlighting=warning\nresharper_unused_type_parameter_highlighting=warning\nresharper_unused_variable_compiler_highlighting=warning\nresharper_unused_variable_highlighting=warning\nresharper_usage_of_definitely_unassigned_value_highlighting=warning\nresharper_usage_of_possibly_unassigned_value_highlighting=warning\nresharper_useless_binary_operation_highlighting=warning\nresharper_use_array_creation_expression_1_highlighting=suggestion\nresharper_use_array_creation_expression_2_highlighting=suggestion\nresharper_use_as_instead_of_type_cast_highlighting=hint\nresharper_use_await_using_highlighting=suggestion\nresharper_use_cancellation_token_for_i_async_enumerable_highlighting=suggestion\nresharper_use_collection_count_property_highlighting=suggestion\nresharper_use_deconstruction_highlighting=hint\nresharper_use_deconstruction_on_parameter_highlighting=hint\nresharper_use_format_specifier_in_format_string_highlighting=suggestion\nresharper_use_format_specifier_in_interpolation_highlighting=suggestion\nresharper_use_implicitly_typed_variable_evident_highlighting=hint\nresharper_use_implicitly_typed_variable_highlighting=none\nresharper_use_implicit_by_val_modifier_highlighting=hint\nresharper_use_indexed_property_highlighting=suggestion\nresharper_use_index_from_end_expression_highlighting=suggestion\nresharper_use_is_operator_1_highlighting=suggestion\nresharper_use_is_operator_2_highlighting=suggestion\nresharper_use_method_any_0_highlighting=suggestion\nresharper_use_method_any_1_highlighting=suggestion\nresharper_use_method_any_2_highlighting=suggestion\nresharper_use_method_any_3_highlighting=suggestion\nresharper_use_method_any_4_highlighting=suggestion\nresharper_use_method_is_instance_of_type_highlighting=suggestion\nresharper_use_nameof_expression_highlighting=suggestion\nresharper_use_name_of_instead_of_type_of_highlighting=suggestion\nresharper_use_negated_pattern_matching_highlighting=hint\nresharper_use_null_propagation_highlighting=suggestion\nresharper_use_null_propagation_when_possible_highlighting=none\nresharper_use_object_or_collection_initializer_highlighting=suggestion\nresharper_use_of_implicit_global_in_function_scope_highlighting=warning\nresharper_use_of_possibly_unassigned_property_highlighting=warning\nresharper_use_pattern_matching_highlighting=suggestion\nresharper_use_string_interpolation_highlighting=suggestion\nresharper_use_switch_case_pattern_variable_highlighting=suggestion\nresharper_use_verbatim_string_highlighting=hint\nresharper_using_of_reserved_word_error_highlighting=error\nresharper_using_of_reserved_word_highlighting=warning\nresharper_value_parameter_not_used_highlighting=warning\nresharper_value_should_have_units_highlighting=error\nresharper_variable_can_be_made_const_highlighting=hint\nresharper_variable_can_be_made_let_highlighting=hint\nresharper_variable_can_be_moved_to_inner_block_highlighting=hint\nresharper_variable_hides_outer_variable_highlighting=warning\nresharper_variable_used_before_declared_highlighting=warning\nresharper_variable_used_in_inner_scope_before_declared_highlighting=warning\nresharper_variable_used_out_of_scope_highlighting=warning\nresharper_vb_check_for_reference_equality_instead_1_highlighting=suggestion\nresharper_vb_check_for_reference_equality_instead_2_highlighting=suggestion\nresharper_vb_possible_mistaken_argument_highlighting=warning\nresharper_vb_possible_mistaken_call_to_get_type_1_highlighting=warning\nresharper_vb_possible_mistaken_call_to_get_type_2_highlighting=warning\nresharper_vb_remove_to_list_1_highlighting=suggestion\nresharper_vb_remove_to_list_2_highlighting=suggestion\nresharper_vb_replace_with_first_or_default_highlighting=suggestion\nresharper_vb_replace_with_last_or_default_highlighting=suggestion\nresharper_vb_replace_with_of_type_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_any_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_any_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_count_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_count_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_first_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_first_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_first_or_default_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_first_or_default_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_last_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_last_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_last_or_default_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_last_or_default_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_single_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_single_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_single_or_default_1_highlighting=suggestion\nresharper_vb_replace_with_of_type_single_or_default_2_highlighting=suggestion\nresharper_vb_replace_with_of_type_where_highlighting=suggestion\nresharper_vb_replace_with_single_assignment_1_highlighting=suggestion\nresharper_vb_replace_with_single_assignment_2_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_any_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_count_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_first_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_first_or_default_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_last_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_last_or_default_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_single_highlighting=suggestion\nresharper_vb_replace_with_single_call_to_single_or_default_highlighting=suggestion\nresharper_vb_replace_with_single_or_default_highlighting=suggestion\nresharper_vb_simplify_linq_expression_10_highlighting=hint\nresharper_vb_simplify_linq_expression_1_highlighting=suggestion\nresharper_vb_simplify_linq_expression_2_highlighting=suggestion\nresharper_vb_simplify_linq_expression_3_highlighting=suggestion\nresharper_vb_simplify_linq_expression_4_highlighting=suggestion\nresharper_vb_simplify_linq_expression_5_highlighting=suggestion\nresharper_vb_simplify_linq_expression_6_highlighting=suggestion\nresharper_vb_simplify_linq_expression_7_highlighting=hint\nresharper_vb_simplify_linq_expression_8_highlighting=hint\nresharper_vb_simplify_linq_expression_9_highlighting=hint\nresharper_vb_string_compare_is_culture_specific_1_highlighting=warning\nresharper_vb_string_compare_is_culture_specific_2_highlighting=warning\nresharper_vb_string_compare_is_culture_specific_3_highlighting=warning\nresharper_vb_string_compare_is_culture_specific_4_highlighting=warning\nresharper_vb_string_compare_is_culture_specific_5_highlighting=warning\nresharper_vb_string_compare_is_culture_specific_6_highlighting=warning\nresharper_vb_string_compare_to_is_culture_specific_highlighting=warning\nresharper_vb_string_ends_with_is_culture_specific_highlighting=none\nresharper_vb_string_index_of_is_culture_specific_1_highlighting=warning\nresharper_vb_string_index_of_is_culture_specific_2_highlighting=warning\nresharper_vb_string_index_of_is_culture_specific_3_highlighting=warning\nresharper_vb_string_last_index_of_is_culture_specific_1_highlighting=warning\nresharper_vb_string_last_index_of_is_culture_specific_2_highlighting=warning\nresharper_vb_string_last_index_of_is_culture_specific_3_highlighting=warning\nresharper_vb_string_starts_with_is_culture_specific_highlighting=none\nresharper_vb_unreachable_code_highlighting=warning\nresharper_vb_use_array_creation_expression_1_highlighting=suggestion\nresharper_vb_use_array_creation_expression_2_highlighting=suggestion\nresharper_vb_use_first_instead_highlighting=warning\nresharper_vb_use_method_any_1_highlighting=suggestion\nresharper_vb_use_method_any_2_highlighting=suggestion\nresharper_vb_use_method_any_3_highlighting=suggestion\nresharper_vb_use_method_any_4_highlighting=suggestion\nresharper_vb_use_method_any_5_highlighting=suggestion\nresharper_vb_use_method_is_instance_of_type_highlighting=suggestion\nresharper_vb_use_type_of_is_operator_1_highlighting=suggestion\nresharper_vb_use_type_of_is_operator_2_highlighting=suggestion\nresharper_vb_warnings_bc400005_highlighting=warning\nresharper_vb_warnings_bc40000_highlighting=warning\nresharper_vb_warnings_bc40008_highlighting=warning\nresharper_vb_warnings_bc40056_highlighting=warning\nresharper_vb_warnings_bc42016_highlighting=warning\nresharper_vb_warnings_bc42025_highlighting=warning\nresharper_vb_warnings_bc42104_highlighting=warning\nresharper_vb_warnings_bc42105_bc42106_bc42107_highlighting=warning\nresharper_vb_warnings_bc42304_highlighting=warning\nresharper_vb_warnings_bc42309_highlighting=warning\nresharper_vb_warnings_bc42322_highlighting=warning\nresharper_vb_warnings_bc42349_highlighting=warning\nresharper_vb_warnings_bc42353_bc42354_bc42355_highlighting=warning\nresharper_vb_warnings_bc42356_highlighting=warning\nresharper_vb_warnings_bc42358_highlighting=warning\nresharper_vb_warnings_wme006_highlighting=warning\nresharper_virtual_member_call_in_constructor_highlighting=warning\nresharper_virtual_member_never_overridden_global_highlighting=suggestion\nresharper_virtual_member_never_overridden_local_highlighting=suggestion\nresharper_void_method_with_must_use_return_value_attribute_highlighting=warning\nresharper_web_config_module_not_resolved_highlighting=warning\nresharper_web_config_module_qualification_resolve_highlighting=warning\nresharper_web_config_redundant_add_namespace_tag_highlighting=warning\nresharper_web_config_redundant_location_tag_highlighting=warning\nresharper_web_config_tag_prefix_redundand_highlighting=warning\nresharper_web_config_type_not_resolved_highlighting=warning\nresharper_web_config_unused_add_tag_highlighting=warning\nresharper_web_config_unused_element_due_to_config_source_attribute_highlighting=warning\nresharper_web_config_unused_remove_or_clear_tag_highlighting=warning\nresharper_web_config_web_config_path_warning_highlighting=warning\nresharper_web_config_wrong_module_highlighting=warning\nresharper_web_ignored_path_highlighting=none\nresharper_web_mapped_path_highlighting=hint\nresharper_with_statement_using_error_highlighting=error\nresharper_wrong_expression_statement_highlighting=warning\nresharper_wrong_indent_size_highlighting=none\nresharper_wrong_metadata_use_highlighting=none\nresharper_wrong_public_modifier_specification_highlighting=hint\nresharper_wrong_require_relative_path_highlighting=hint\nresharper_xaml_binding_without_context_not_resolved_highlighting=hint\nresharper_xaml_binding_with_context_not_resolved_highlighting=warning\nresharper_xaml_constructor_warning_highlighting=warning\nresharper_xaml_dependency_property_resolve_error_highlighting=warning\nresharper_xaml_duplicate_style_setter_highlighting=warning\nresharper_xaml_dynamic_resource_error_highlighting=error\nresharper_xaml_element_name_reference_not_resolved_highlighting=error\nresharper_xaml_ignored_path_highlighting_highlighting=none\nresharper_xaml_index_out_of_grid_definition_highlighting=warning\nresharper_xaml_invalid_member_type_highlighting=error\nresharper_xaml_invalid_resource_target_type_highlighting=error\nresharper_xaml_invalid_resource_type_highlighting=error\nresharper_xaml_invalid_type_highlighting=error\nresharper_xaml_language_level_highlighting=error\nresharper_xaml_mapped_path_highlighting_highlighting=hint\nresharper_xaml_missing_grid_index_highlighting=warning\nresharper_xaml_path_error_highlighting=warning\nresharper_xaml_redundant_attached_property_highlighting=warning\nresharper_xaml_redundant_collection_property_highlighting=warning\nresharper_xaml_redundant_freeze_attribute_highlighting=warning\nresharper_xaml_redundant_grid_definitions_highlighting=warning\nresharper_xaml_redundant_grid_span_highlighting=warning\nresharper_xaml_redundant_modifiers_attribute_highlighting=warning\nresharper_xaml_redundant_namespace_alias_highlighting=warning\nresharper_xaml_redundant_name_attribute_highlighting=warning\nresharper_xaml_redundant_property_type_qualifier_highlighting=warning\nresharper_xaml_redundant_resource_highlighting=warning\nresharper_xaml_redundant_styled_value_highlighting=warning\nresharper_xaml_redundant_xamarin_forms_class_declaration_highlighting=warning\nresharper_xaml_routed_event_resolve_error_highlighting=warning\nresharper_xaml_static_resource_not_resolved_highlighting=warning\nresharper_xaml_style_invalid_target_type_highlighting=error\nresharper_xaml_unexpected_text_token_highlighting=error\nresharper_xaml_xaml_duplicate_device_family_type_view_highlighting_highlighting=error\nresharper_xaml_xaml_mismatched_device_family_view_clr_name_highlighting_highlighting=warning\nresharper_xaml_xaml_relative_source_default_mode_warning_highlighting_highlighting=warning\nresharper_xaml_xaml_unknown_device_family_type_highlighting_highlighting=warning\nresharper_xaml_xaml_xamarin_forms_data_type_and_binding_context_type_mismatched_highlighting_highlighting=warning\nresharper_xaml_x_key_attribute_disallowed_highlighting=error\nresharper_xml_doc_comment_syntax_problem_highlighting=warning\nresharper_xunit_xunit_test_with_console_output_highlighting=warning\nresharper_x_unit1000_highlighting=error\nresharper_x_unit1001_highlighting=error\nresharper_x_unit1002_highlighting=error\nresharper_x_unit1003_highlighting=error\nresharper_x_unit1004_highlighting=hint\nresharper_x_unit1005_highlighting=warning\nresharper_x_unit1006_highlighting=warning\nresharper_x_unit1007_highlighting=error\nresharper_x_unit1008_highlighting=warning\nresharper_x_unit1009_highlighting=error\nresharper_x_unit1010_highlighting=error\nresharper_x_unit1011_highlighting=error\nresharper_x_unit1012_highlighting=warning\nresharper_x_unit1013_highlighting=warning\nresharper_x_unit1014_highlighting=warning\nresharper_x_unit1015_highlighting=error\nresharper_x_unit1016_highlighting=error\nresharper_x_unit1017_highlighting=error\nresharper_x_unit1018_highlighting=error\nresharper_x_unit1019_highlighting=error\nresharper_x_unit1020_highlighting=error\nresharper_x_unit1021_highlighting=warning\nresharper_x_unit1022_highlighting=error\nresharper_x_unit1023_highlighting=error\nresharper_x_unit1024_highlighting=error\nresharper_x_unit1025_highlighting=warning\nresharper_x_unit1026_highlighting=warning\nresharper_x_unit2000_highlighting=warning\nresharper_x_unit2001_highlighting=none\nresharper_x_unit2002_highlighting=warning\nresharper_x_unit2003_highlighting=warning\nresharper_x_unit2004_highlighting=warning\nresharper_x_unit2005_highlighting=warning\nresharper_x_unit2006_highlighting=warning\nresharper_x_unit2007_highlighting=warning\nresharper_x_unit2008_highlighting=warning\nresharper_x_unit2009_highlighting=warning\nresharper_x_unit2010_highlighting=warning\nresharper_x_unit2011_highlighting=warning\nresharper_x_unit2012_highlighting=warning\nresharper_x_unit2013_highlighting=warning\nresharper_x_unit2014_highlighting=error\nresharper_x_unit2015_highlighting=warning\nresharper_x_unit2016_highlighting=error\nresharper_x_unit2017_highlighting=warning\nresharper_x_unit2018_highlighting=warning\nresharper_x_unit2019_highlighting=none\nresharper_x_unit3000_highlighting=error\nresharper_x_unit3001_highlighting=error\n\n[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]\nindent_style=space\nindent_size=2\n\n[*.scss]\nindent_style=space\nindent_size=2\n\n[*.js.map]\nindent_style=space\nindent_size=2\n\n[*.{appxmanifest,asax,ascx,aspx,build,cs,cshtml,dtd,master,nuspec,razor,resw,resx,skin,vb,xaml,xamlx,xoml,xsd}]\nindent_style=space\nindent_size=4\ntab_width=4\n"
  },
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# How to contribute\n\nThe easiest way to contribute is to open an issue and start a discussion. \nThen we can decide if and how a feature or a change could be implemented and if you should submit a pull requests with code changes.\n\nAlso read this first: [Being a good open source citizen](https://hackernoon.com/being-a-good-open-source-citizen-9060d0ab9732#.x3hocgw85)\n\n## Found an issue or a bug?\nPlease start a discussion on the [core repo issue tracker](https://github.com/alexhiggins732/IdentityServer4/issues).\n\n## Filing issues\nThe best way to get your bug fixed is to be as detailed as you can be about the problem.\nProviding a minimal project with steps to reproduce the problem is ideal.\nHere are questions you can answer before you file a bug to make sure you're not missing any important information.\n\n1. Did you read the [documentation](https://identityserver8.readthedocs.io/en/latest/)?\n2. Did you include the snippet of broken code in the issue?\n3. What are the *EXACT* steps to reproduce this problem?\n4. Did you enable [logging](https://identityserver8.readthedocs.io/en/latest/topics/logging.html)?\n\nGitHub supports [markdown](http://github.github.com/github-flavored-markdown/), so when filing bugs make sure you check the formatting before clicking submit.\n\n## Contributing code and content\nYou will need to sign a contributor license agreement (CLA) before submitting your pull request. The first time you submit a PR, a bot will take you through that process.\n\nPlease make sure to include tests, that cover the changes/additions you made to the code base.\n\nMake sure you can build the code. Familiarize yourself with the project workflow and our coding conventions. If you don't know what a pull request is read this article: https://help.github.com/articles/using-pull-requests.\n\nBefore submitting a feature or substantial code contribution please discuss it with the team and ensure it follows the product roadmap. Here's a list of blog posts that are worth reading before doing a pull request:\n\n* [Open Source Contribution Etiquette](http://tirania.org/blog/archive/2010/Dec-31.html) by Miguel de Icaza\n* [Don't \"Push\" Your Pull Requests](http://www.igvita.com/2011/12/19/dont-push-your-pull-requests/) by Ilya Grigorik.\n* [10 tips for better Pull Requests](http://blog.ploeh.dk/2015/01/15/10-tips-for-better-pull-requests/) by Mark Seemann\n* [How to write the perfect pull request](https://github.com/blog/1943-how-to-write-the-perfect-pull-request) by GitHub\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: alexhiggins732\npatreon: alexhiggins732\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: https://www.paypal.me/alexhiggins732\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/Question.md",
    "content": "<!--\n  ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️\nQuestions are community supported only and the authors/maintainers may or may not have time to reply. If you or your company would like commercial support, please see [here](https://identityserver8.readthedocs.io/en/latest/intro/support.html#commercial-support) for more information.\n  ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️\n-->\n\n---\nname: Question\nabout: Ask a question.\ntitle: ''\nlabels: question\nassignees: skoruba\n\n---\n\n### Question\n\n\n### Minimal working example\n\n```csharp\n   // <code goes here>\n```\n\n### Relevant parts of the log file\n\n```\n   <log goes here>\n```\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug report\n\n\n---\n\n### Describe the bug\nA clear and concise description of what the bug is.\n\n### To Reproduce\nSteps to reproduce the behavior:\n\n### Relevant parts of the log file\n\n```\n<log goes here>\n```\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\n\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\nlabels: bug report\n---\n\n**We can only help you if you are on the latest version.**\n\nPlease only use the issue tracker for bug reports and/or feature requests. For general security questions, or free or commercial support options do __not__ use the issue tracker and instead see [here](http://identityserver8.readthedocs.io/en/latest/intro/support.html) for more details.\n\nFor bug reports,  include the relevant log files related to your issue. See here how to enable [logging](https://identityserver8.readthedocs.io/en/latest/topics/logging.html). Delete this line once you have.\n\nFinally, please keep the issue concise and to the point. If you paste in more code than the text for the issue you are reporting then we will most likely not read it. \n\n### Issue / Steps to reproduce the problem\n\n\n\n### Relevant parts of the log file\n\n```\n<log goes here>\n```"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file\n\nversion: 2\nupdates:\n  - package-ecosystem: \"nuget\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"daily\"\n    open-pull-requests-limit: 25\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL\"\n\non:\n  push:\n    branches: [ \"master\", \"develop\", \"release/*\" ]\n    paths-ignore:\n    - '**/README.md'\n    - '**/docs'\n    - '.github/**'\n    - \"docs/**\"\n    - \".git/*\"\n    - \".vs/*\"\n    - \".config/*\"\n    - \".github/*\"\n    - \"Directory.Build.props\"\n    - \"Directory.Build.targets\"\n    - \"Directory.Build.props\"\n    - \"docker-compose.yml\"\n    - \"docker-compose.override.yml\"\n    - \"docker-compose.vs.debug.yml\"\n    - \"docker-compose.vs.release.yml\"\n    - \"docker-compose.dcrpoj\"\n    - \"**/*.sln\"\n    - \"global.json\"\n    - \"IdentityServer8.DotNet.ruleset\"\n    - \"LICENSCE\"\n    - \"version.json\"\n    - \"Nuget.config\"\n    - \"SECURITY.md\"\n    - \"SPONSORS.md\"\n    - \"README.md\"\n    - \"samples\"\n    - \"nuget\"\n  pull_request:\n    branches: [ \"master\", \"develop\", \"release/*\" ]\n\n  schedule:\n    - cron: '23 4 * * 1'\n\njobs:\n  analyze:\n    name: Analyze\n    # Runner size impacts CodeQL analysis time. To learn more, please see:\n    #   - https://gh.io/recommended-hardware-resources-for-running-codeql\n    #   - https://gh.io/supported-runners-and-hardware-resources\n    #   - https://gh.io/using-larger-runners\n    # Consider using larger runners for possible analysis time improvements.\n    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}\n    timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}\n    permissions:\n      # required for all workflows\n      security-events: write\n\n      # only required for workflows in private repositories\n      actions: read\n      contents: read\n\n    strategy:\n      fail-fast: false\n      matrix:\n        language: [ 'csharp', 'javascript-typescript' ]\n        # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]\n        # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both\n        # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both\n        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v4\n\n    # Initializes the CodeQL tools for scanning.\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v3\n      with:\n        languages: ${{ matrix.language }}\n        # If you wish to specify custom queries, you can do so here or in a config file.\n        # By default, queries listed here will override any specified in a config file.\n        # Prefix the list here with \"+\" to use these queries and those in the config file.\n\n        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs\n        # queries: security-extended,security-and-quality\n\n\n    # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).\n    # If this step fails, then you should remove it and run the build manually (see below)\n    #- name: Autobuild\n    #  uses: github/codeql-action/autobuild@v3\n\n    # ℹ️ Command-line programs to run using the OS shell.\n    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun\n\n    #   If the Autobuild fails above, remove it and uncomment the following three lines.\n    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.\n\n    - name: Restore dependencies\n      if: ${{ (matrix.language == 'csharp') }} \n      run: dotnet restore src/IdentityServer8.sln\n    - name: Build\n      if: ${{ (matrix.language == 'csharp') }} \n      run: dotnet build src/IdentityServer8.sln --configuration Release --no-restore\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v3\n      with:\n        category: \"/language:${{matrix.language}}\"\n"
  },
  {
    "path": ".github/workflows/develop.yml",
    "content": "# This workflow will build a .NET project\n# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net\n\nname: Develop\n\non:\n  push:\n    branches:\n    - develop\n    paths-ignore:\n    - '**/README.md'\n    - '**/docs'\n    - '.github/**'\n    - \"docs/**\"\n    - \".git/*\"\n    - \".vs/*\"\n    - \".config/*\"\n    - \".github/*\"\n    - \"Directory.Build.props\"\n    - \"Directory.Build.targets\"\n    - \"Directory.Build.props\"\n    - \"docker-compose.yml\"\n    - \"docker-compose.override.yml\"\n    - \"docker-compose.vs.debug.yml\"\n    - \"docker-compose.vs.release.yml\"\n    - \"docker-compose.dcrpoj\"\n    - \"**/*.sln\"\n    - \"global.json\"\n    - \"IdentityServer8.DotNet.ruleset\"\n    - \"LICENSCE\"\n    - \"Nuget.config\"\n    - \"SECURITY.md\"\n    - \"SPONSORS.md\"\n    - \"README.md\"\n    - \"samples\"\n    - \"nuget\"\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        runs-on: [macOS-latest, ubuntu-latest, windows-latest]\n    name: ${{ matrix.runs-on }}\n    runs-on: ${{ matrix.runs-on }}\n    steps:\n    - uses: actions/checkout@v3\n      with:        \n        fetch-depth: 0\n    - name: Setup .NET\n      uses: actions/setup-dotnet@v3\n      with:\n        dotnet-version: 8.0.x\n\n\n    - uses: dotnet/nbgv@master\n      id: nbgv\n\n    - name: Display Package Version\n      run: echo \"PackageVersion=${{ steps.nbgv.outputs.SemVer2 }}\"\n\n    - name: Restore dependencies\n      run: dotnet restore src/IdentityServer8.sln\n    - name: Build\n      run: dotnet build src/IdentityServer8.sln --configuration Release --no-restore -p:Version=${{ steps.nbgv.outputs.SemVer2 }}\n    - name: Test\n      run: dotnet test src/IdentityServer8.sln --configuration Release --no-build --verbosity normal /p:CollectCoverage=true --collect:\"XPlat Code Coverage\" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura\n\n    - name: Upload coverage reports to Codecov\n      uses: codecov/codecov-action@v4.0.1\n      env:\n        token: ${{ secrets.CODECOV_TOKEN }}\n        slug: alexhiggins732/IdentityServer8\n        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n\n    - name: Push\n      if: ${{ (github.event_name == 'push') && (runner.os == 'Windows') }} \n      run: dotnet nuget push .\\nuget\\*.nupkg  --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}\n\n"
  },
  {
    "path": ".github/workflows/master.yml",
    "content": "# This workflow will build a .NET project\n# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net\n\nname: Master\n\non:\n  push:\n    branches:\n    - master\n    paths-ignore:\n    - '**/README.md'\n    - '**/docs'\n    - '.github/**'\n    - \"docs/**\"\n    - \".git/*\"\n    - \".vs/*\"\n    - \".config/*\"\n    - \".github/*\"\n    - \"Directory.Build.props\"\n    - \"Directory.Build.targets\"\n    - \"Directory.Build.props\"\n    - \"docker-compose.yml\"\n    - \"docker-compose.override.yml\"\n    - \"docker-compose.vs.debug.yml\"\n    - \"docker-compose.vs.release.yml\"\n    - \"docker-compose.dcrpoj\"\n    - \"**/*.sln\"\n    - \"global.json\"\n    - \"IdentityServer8.DotNet.ruleset\"\n    - \"LICENSCE\"\n    - \"Nuget.config\"\n    - \"SECURITY.md\"\n    - \"SPONSORS.md\"\n    - \"README.md\"\n    - \"samples\"\n    - \"nuget\"\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        runs-on: [macOS-latest, ubuntu-latest, windows-latest]\n    name: ${{ matrix.runs-on }}\n    runs-on: ${{ matrix.runs-on }}\n    steps:\n    - uses: actions/checkout@v3\n      with:        \n        fetch-depth: 0\n    - name: Setup .NET\n      uses: actions/setup-dotnet@v3\n      with:\n        dotnet-version: 8.0.x\n\n\n    - uses: dotnet/nbgv@master\n      id: nbgv\n    - name: Display Package Version\n      run: echo \"PackageVersion=${{ steps.nbgv.outputs.SimpleVersion }}\"\n\n    - name: Restore dependencies\n      run: dotnet restore src/IdentityServer8.sln\n    - name: Build\n      run: dotnet build src/IdentityServer8.sln --configuration Release --no-restore -p:Version=${{ steps.nbgv.outputs.SimpleVersion }}\n    - name: Test\n      run: dotnet test src/IdentityServer8.sln --configuration Release --no-build --verbosity normal /p:CollectCoverage=true --collect:\"XPlat Code Coverage\" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura\n\n    - name: Upload coverage reports to Codecov\n      uses: codecov/codecov-action@v4.0.1\n      env:\n        token: ${{ secrets.CODECOV_TOKEN }}\n        slug: alexhiggins732/IdentityServer8\n        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n\n    - name: Push\n      if: ${{ (github.event_name == 'push') && (runner.os == 'Windows') }} \n      run: dotnet nuget push .\\nuget\\*.nupkg  --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}\n\n"
  },
  {
    "path": ".github/workflows/pre-release.yml",
    "content": "# This workflow will build a .NET project\n# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net\n\nname: CI\n\non:\n  push:\n    branches-ignore:\n    - develop\n    - release/*\n    - master\n    paths-ignore:\n    - '**/README.md'\n    - '**/docs'\n    - '.github/**'\n    - \"docs/**\"\n    - \".git/*\"\n    - \".vs/*\"\n    - \".config/*\"\n    - \".github/*\"\n    - \"Directory.Build.props\"\n    - \"Directory.Build.targets\"\n    - \"Directory.Build.props\"\n    - \"docker-compose.yml\"\n    - \"docker-compose.override.yml\"\n    - \"docker-compose.vs.debug.yml\"\n    - \"docker-compose.vs.release.yml\"\n    - \"docker-compose.dcrpoj\"\n    - \"**/*.sln\"\n    - \"global.json\"\n    - \"IdentityServer8.DotNet.ruleset\"\n    - \"LICENSCE\"\n    - \"Nuget.config\"\n    - \"SECURITY.md\"\n    - \"SPONSORS.md\"\n    - \"README.md\"\n    - \"samples\"\n    - \"nuget\"\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        runs-on: [macOS-latest, ubuntu-latest, windows-latest]\n    name: ${{ matrix.runs-on }}\n    runs-on: ${{ matrix.runs-on }}\n    steps:\n    - uses: actions/checkout@v3\n      with:        \n        fetch-depth: 0\n    - name: Setup .NET\n      uses: actions/setup-dotnet@v3\n      with:\n        dotnet-version: 8.0.x\n\n\n    - uses: dotnet/nbgv@master\n      id: nbgv\n\n    - name: Display Package Version\n      run: echo \"PackageVersion=${{ steps.nbgv.outputs.SimpleVersion }}-ci.${{ steps.nbgv.outputs.VersionRevision }}\"\n\n\n\n    - name: Restore dependencies\n      run: dotnet restore src/IdentityServer8.sln\n    - name: Build\n      run: dotnet build src/IdentityServer8.sln --configuration Release --no-restore -p:Version=${{ steps.nbgv.outputs.SimpleVersion }}-ci.${{ steps.nbgv.outputs.VersionRevision }}\n    - name: Test\n      run: dotnet test src/IdentityServer8.sln --configuration Release --no-build --verbosity normal /p:CollectCoverage=true --collect:\"XPlat Code Coverage\" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura\n\n    - name: Upload coverage reports to Codecov\n      uses: codecov/codecov-action@v4.0.1\n      env:\n        token: ${{ secrets.CODECOV_TOKEN }}\n        slug: alexhiggins732/IdentityServer8\n        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "# This workflow will build a .NET project\n# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net\n\nname: Release\n\non:\n  push:\n    branches:\n    - release/*\n    paths-ignore:\n    - '**/README.md'\n    - '**/docs'\n    - '.github/**'\n    - \"docs/**\"\n    - \".git/*\"\n    - \".vs/*\"\n    - \".config/*\"\n    - \".github/*\"\n    - \"Directory.Build.props\"\n    - \"Directory.Build.targets\"\n    - \"Directory.Build.props\"\n    - \"docker-compose.yml\"\n    - \"docker-compose.override.yml\"\n    - \"docker-compose.vs.debug.yml\"\n    - \"docker-compose.vs.release.yml\"\n    - \"docker-compose.dcrpoj\"\n    - \"**/*.sln\"\n    - \"global.json\"\n    - \"IdentityServer8.DotNet.ruleset\"\n    - \"LICENSCE\"\n    - \"Nuget.config\"\n    - \"SECURITY.md\"\n    - \"SPONSORS.md\"\n    - \"README.md\"\n    - \"samples\"\n    - \"nuget\"\n\njobs:\n  build:\n    strategy:\n      fail-fast: false\n      matrix:\n        runs-on: [macOS-latest, ubuntu-latest, windows-latest]\n    name: ${{ matrix.runs-on }}\n    runs-on: ${{ matrix.runs-on }}\n    steps:\n    - uses: actions/checkout@v3\n      with:        \n        fetch-depth: 0\n    - name: Setup .NET\n      uses: actions/setup-dotnet@v3\n      with:\n        dotnet-version: 8.0.x\n\n\n    - uses: dotnet/nbgv@master\n      id: nbgv\n \n    - name: Display Package Version\n      run: echo \"PackageVersion=${{ steps.nbgv.outputs.SemVer2 }}\"\n\n\n\n    - name: Restore dependencies\n      run: dotnet restore src/IdentityServer8.sln\n    - name: Build\n      run: dotnet build src/IdentityServer8.sln --configuration Release --no-restore -p:Version=${{ steps.nbgv.outputs.SemVer2 }}\n    - name: Test\n      run: dotnet test src/IdentityServer8.sln --configuration Release --no-build --verbosity normal /p:CollectCoverage=true --collect:\"XPlat Code Coverage\" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura\n\n    - name: Upload coverage reports to Codecov\n      uses: codecov/codecov-action@v4.0.1\n      env:\n        token: ${{ secrets.CODECOV_TOKEN }}\n        slug: alexhiggins732/IdentityServer8\n        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n\n\n    - name: Push\n      if: ${{ (github.event_name == 'push') && (runner.os == 'Windows') }} \n      run: dotnet nuget push .\\nuget\\*.nupkg  --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}\n\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# Rider\n.idea\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\n\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio cache/options directory\n.vs/\nproject.lock.json\n\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\nProperties/launchSettings.json\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\nnode_modules/\nbower_components/\norleans.codegen.cs\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\ndocs/_build/\n\n# Local .NET CLI tools\ntools/\n\n# Visual Studio Code workspace options\n.vscode\n\n# IdentityServer temp files\nIdentityServer8_log.txt\ntempkey.rsa\nsamples/KeyManagement/FileSystem/dataprotectionkeys/\nsamples/KeyManagement/FileSystem/signingkeys/\nworkspace.xml\n\nsrc/IdentityServer8/host/identityserver.db\ntempkey.jwk\n/nuget\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/\n/src/IdentityServer8.Admin/appsettings.production.json\n/src/IdentityServer8.Admin/Scripts/Libs/\n/src/IdentityServer8.Admin/Data/Migrations/\n\n# Don't ignore these log folders\n!/src/IdentityServer8.Admin.UI/Resources/Views/Log/\n!/src/IdentityServer8.Admin.BusinessLogic/Dtos/Log/\n!**/Views/Log/\n!/src/IdentityServer8.Admin.BusinessLogic/Events/Log/\n/src/IdentityServer8.Admin.Api/appsettings.Production.json\n\n\n\n/shared/nginx/certs/\nlib/\n\n"
  },
  {
    "path": ".readthedocs.yaml",
    "content": "# .readthedocs.yaml\n# Read the Docs configuration file\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details\n\n# Required\nversion: 2\n\n# Set the OS, Python version and other tools you might need\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.12\"\n    # You can also specify other tool versions:\n    # nodejs: \"19\"\n    # rust: \"1.64\"\n    # golang: \"1.19\"\n\n# Build documentation in the \"docs/\" directory with Sphinx\nsphinx:\n  configuration: docs/conf.py\n\n# Optionally build your docs in additional formats such as PDF and ePub\n# formats:\n#    - pdf\n#    - epub\n\n# Optional but recommended, declare the Python requirements required\n# to build your documentation\n# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html\npython:\n  install:\n  - requirements: docs/requirements.txt\n"
  },
  {
    "path": "Directory.Build.props",
    "content": "<Project>\n\n    <PropertyGroup>\n        <TargetFramework>net8.0</TargetFramework>\n        <!--always bump /version.json and /docs/conf.py to <Version>X.Y.Z</Version>to keep nuget, build and document versions in sync-->\n        <Version>8.0.4</Version>\n\t\t<IdentityServerVersion>8.0.4</IdentityServerVersion>\n        <PackageId>HigginsSoft.$(MSBuildProjectName)</PackageId>\n        <Title>$(MSBuildProjectName)</Title>\n        <ImplicitUsings>enable</ImplicitUsings>\n\n        <PackageLicenseFile>LICENSE</PackageLicenseFile>\n\n        <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n        <NoWarn>$(NoWarn);CS0618;SYSLIB0023;SYSLIB0020;EF1001</NoWarn>\n\n\t\t<SignAssembly>true</SignAssembly>\n\t\t<AssemblyOriginatorKeyFile>$(SolutionDir)../key.snk</AssemblyOriginatorKeyFile>\n\n\n        <Description>OpenID Connect and OAuth 2.0 Framework for ASP.NET Core</Description>\n        <Copyright>Copyright 2024 HigginsSoft. Alexander Higgins</Copyright>\n        <Authors>HigginsSoft, Alexander Higgins, Brock Allen, Dominick Baier</Authors>\n  \n        <PackageTags>OAuth2 OAuth 2.0 OpenID Connect Security Identity IdentityServer Admin IdentityServer8 OpenIDConnect </PackageTags>\n\n\n        <PackageProjectUrl>https://github.com/alexhiggins732/IdentityServer8</PackageProjectUrl>\n        <RepositoryType>git</RepositoryType>\n        <PackageReleaseNotes>https://github.com/alexhiggins732/IdentityServer8/releases</PackageReleaseNotes>\n\n        <!-- Declare that the Repository URL can be published to NuSpec -->\n        <PublishRepositoryUrl>true</PublishRepositoryUrl>\n        <!-- Embed source files that are not tracked by the source control manager to the PDB -->\n\n\n        <!-- Include PDB in the built .nupkg -->\n        <AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>\n\n        <PackageIcon>icon.jpg</PackageIcon>\n\n\n        <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>\n\n        <!--<CodeAnalysisRuleset>$(MSBuildThisFileDirectory)IdentityServer8.DotNet.ruleset</CodeAnalysisRuleset>-->\n\n        <IsTrimmable>false</IsTrimmable>\n        <EnableAOTAnalyzer>false</EnableAOTAnalyzer>\n\n        <EmbedUntrackedSources>true</EmbedUntrackedSources>\n        <Deterministic>true</Deterministic>\n\t\t<ImplicitUsings>Enable</ImplicitUsings>\n        <LangVersion>latest</LangVersion>\n        <GenerateDocumentationFile>false</GenerateDocumentationFile>\n        <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n        <PackageOutputPath>$(SolutionDir)../nuget</PackageOutputPath>\n\n\n        <IsPackable>false</IsPackable>\n        <GeneratePackageOnBuild>false</GeneratePackageOnBuild>\n        <PackageReadmeFile>README.md</PackageReadmeFile>\n        <DebugSymbols>true</DebugSymbols>\n        <DebugType>portable</DebugType>\n        <IncludeSymbols>true</IncludeSymbols>\n        <SymbolPackageFormat>snupkg</SymbolPackageFormat>\n        <IncludeBuildOutput>true</IncludeBuildOutput>\n    </PropertyGroup>\n\n    <ItemGroup>\n \n        <PackageReference Include=\"Microsoft.CodeAnalysis.NetAnalyzers\" Version=\"$(MicrosoftCodeAnalysisNetAnalyzersPackageVersion)\" PrivateAssets=\"All\" />\n        <PackageReference Include=\"Microsoft.SourceLink.GitHub\" Version=\"$(MicrosoftSourceLinkGitHubPackageVersion)\" PrivateAssets=\"All\" />\n    </ItemGroup>\n\n    <ItemGroup>\n        <None Include=\"$(SolutionDir)../LICENSE\">\n            <Pack>True</Pack>\n            <PackagePath>\\</PackagePath>\n        </None>\n    </ItemGroup>\n    <ItemGroup>\n        <None Include=\"$(SolutionDir)../README.md\">\n            <Pack>True</Pack>\n            <PackagePath>\\</PackagePath>\n        </None>\n\n    </ItemGroup>\n    <ItemGroup>\n        <None Include=\"$(SolutionDir)../icon.jpg\">\n            <Pack>True</Pack>\n            <PackagePath>\\</PackagePath>\n        </None>\n\n    </ItemGroup>\n\n\n</Project>\n"
  },
  {
    "path": "Directory.Build.targets",
    "content": "<Project>\n    <!-- \n    Make a netstandard2.1 copy of the .net ILLinkPack to work around a trimming issue.\n    See https://github.com/dotnet/linker/issues/3175\n    TODO: Remove once .NET 8 + trimming + netstandard2.1 is fixed.\n  -->\n    <Target Name=\"_FixKnownILLinkPack\"\n            BeforeTargets=\"ProcessFrameworkReferences\">\n        <ItemGroup>\n            <KnownILLinkPack Include=\"@(KnownILLinkPack)\"\n                             Condition=\"'%(TargetFramework)' == 'net8.0'\"\n                             TargetFramework=\"netstandard2.1\"\n                             ILLinkPackVersion=\"%(KnownILLinkPack.ILLinkPackVersion)\" />\n        </ItemGroup>\n    </Target>\n\n</Project>\n"
  },
  {
    "path": "Directory.Packages.props",
    "content": "<Project>\n  <PropertyGroup>\n    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>\n    <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>\n    <AspnetVersion>8.0.0</AspnetVersion>\n    <AspnetMinorVersion>8.0.1</AspnetMinorVersion>\n    <MicrosoftExtensionsVersion>8.0.0</MicrosoftExtensionsVersion>\n    <EfVersion>8.0.0</EfVersion>\n    <RuntimeVersion>8.0.0</RuntimeVersion>\n    <AspireVersion>8.0.0-preview.2.23619.3</AspireVersion>\n    <GrpcVersion>2.59.0</GrpcVersion>\n    <SerilogVersion>8.0.0</SerilogVersion>\n    <NoWarn>$(NoWarn);AD0001;ASP0003;ASP0004;ASP0005;ASP0007;ASP0020;ASP0021;ASP0022;ASP0024</NoWarn>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageVersion Include=\"AspNet.Security.OAuth.GitHub\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"AspNetCore.HealthChecks.UI\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"AspNetCore.HealthChecks.MySql\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"AspNetCore.HealthChecks.NpgSql\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"AspNetCore.HealthChecks.OpenIdConnectServer\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"AspNetCore.HealthChecks.SqlServer\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"AspNetCore.HealthChecks.UI.Client\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"AutoMapper\" Version=\"13.0.1 \" />\n    <PackageVersion Include=\"Azure.Extensions.AspNetCore.DataProtection.Keys\" Version=\"1.1.0\" />\n    <PackageVersion Include=\"Azure.Identity\" Version=\"1.10.4\" />\n    <PackageVersion Include=\"Azure.Security.KeyVault.Certificates\" Version=\"4.2.0\" />\n    <PackageVersion Include=\"Bogus\" Version=\"34.0.1\" />\n    <PackageVersion Include=\"bootstrap\" Version=\"5.3.2\" />\n    <PackageVersion Include=\"coverlet.collector\" Version=\"6.0.0\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageVersion>\n    <PackageVersion Include=\"Dapper\" Version=\"2.1.28\" />\n    <PackageVersion Include=\"EntityFramework\" Version=\"6.4.4\" />\n    <PackageVersion Include=\"FluentAssertions\" Version=\"6.11.0\" />\n    <PackageVersion Include=\"FluentValidation\" Version=\"11.9.0\" />\n    <PackageVersion Include=\"FluentValidation.AspNetCore\" Version=\"11.3.0\" />\n    <PackageVersion Include=\"Google.Protobuf\" Version=\"3.23.4\" />\n    <PackageVersion Include=\"Grpc\" Version=\"$(GrpcVersion)\" />\n    <PackageVersion Include=\"Grpc.AspNetCore\" Version=\"$(GrpcVersion)\" />\n    <PackageVersion Include=\"Grpc.AspNetCore.Server\" Version=\"$(GrpcVersion)\" />\n    <PackageVersion Include=\"Grpc.Core\" Version=\"$(GrpcVersion)\" />\n    <PackageVersion Include=\"Grpc.Core.Api\" Version=\"$(GrpcVersion)\" />\n    <PackageVersion Include=\"Grpc.Net.Client\" Version=\"$(GrpcVersion)\" />\n    <PackageVersion Include=\"Grpc.Net.ClientFactory\" Version=\"$(GrpcVersion)\" />\n    <PackageVersion Include=\"Grpc.Tools\" Version=\"$(GrpcVersion)\" PrivateAssets=\"All\" />\n    <PackageVersion Include=\"HtmlAgilityPack\" Version=\"1.11.40\" />\n    <PackageVersion Include=\"Humanizer.Core\" Version=\"2.14.1\" />\n    <PackageVersion Include=\"IdentityModel\" Version=\"6.2.0\" />\n    <PackageVersion Include=\"IdentityModel.OidcClient\" Version=\"5.3.0-preview.1\" />\n    <PackageVersion Include=\"IdentityModel.AspNetCore\" Version=\"4.3.0\" />\n    <PackageVersion Include=\"IdentityModel.AspNetCore.AccessTokenValidation\" Version=\"1.0.0-preview.3\" />\n    <PackageVersion Include=\"IdentityModel.AspNetCore.OAuth2Introspection\" Version=\"4.0.1\" />\n    <PackageVersion Include=\"IdentityServer4.KeyManagement\" Version=\"2.1.0\" />\n    <PackageVersion Include=\"jQuery\" Version=\"3.7.1\" />\n    <PackageVersion Include=\"jQuery.validation\" Version=\"1.19.5\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Authentication.Certificate\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Authentication.Google\" Version=\"3.1.5\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Authentication.JwtBearer\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Authentication.MicrosoftAccount\" Version=\"$(AspnetMinorVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Authentication.OpenIdConnect\" Version=\"8.0.0\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Components.Web\" Version=\"$(AspnetMinorVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.DataProtection.EntityFrameworkCore\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Http.Abstractions\" Version=\"2.2.0\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Identity.UI\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Identity.EntityFrameworkCore\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.Abstractions\" Version=\"2.2.0\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.NewtonsoftJson\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Mvc.Testing\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.OpenApi\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.TestHost\" Version=\"8.0.1\" />\n    <PackageVersion Include=\"Microsoft.AspNetCore.Server.Kestrel\" Version=\"2.2.0\" />\n    <PackageVersion Include=\"Microsoft.Data.SqlClient\" Version=\"5.1.5\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Design\" Version=\"8.0.1\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageVersion>\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.InMemory\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Relational\" Version=\"$(AspnetMinorVersion)\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Sqlite\" Version=\"$(AspnetMinorVersion)\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"$(AspnetMinorVersion)\" />\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Tools\" Version=\"$(AspnetMinorVersion)\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageVersion>\n    <PackageVersion Include=\"Microsoft.EntityFrameworkCore.Tools.DotNet\" Version=\"2.0.3\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.Abstractions\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.AzureKeyVault\" Version=\"3.1.22\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.Binder\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.EnvironmentVariables\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.FileExtensions\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.Json\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Configuration.UserSecrets\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.DependencyInjection\" Version=\"8.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.DependencyInjection.Abstractions\" Version=\"8.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Diagnostics.HealthChecks\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Http\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Http.Resilience\" Version=\"$(MicrosoftExtensionsVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Hosting\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Logging.Abstractions\" Version=\"8.0.0\" />\n    <PackageVersion Include=\"Microsoft.Extensions.Options\" Version=\"$(AspnetMinorVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.ServiceDiscovery\" Version=\"$(AspireVersion)\" />\n    <PackageVersion Include=\"Microsoft.Extensions.ServiceDiscovery.Yarp\" Version=\"$(AspireVersion)\" />\n    <PackageVersion Include=\"Microsoft.Identity.Web\" Version=\"1.22.1\" />\n    <PackageVersion Include=\"Microsoft.Identity.Web.UI\" Version=\"1.16.0\" />\n    <PackageVersion Include=\"Microsoft.IdentityModel.Logging\" Version=\"7.3.1\" />\n    <PackageVersion Include=\"Microsoft.IdentityModel.Protocols.OpenIdConnect\" Version=\"7.3.1\" />\n    <PackageVersion Include=\"Microsoft.jQuery.Unobtrusive.Validation\" Version=\"4.0.0\" />\n    <PackageVersion Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.8.0\" />\n    <PackageVersion Include=\"Microsoft.OpenApi\" Version=\"1.6.10\" />\n    <PackageVersion Include=\"Microsoft.Web.LibraryManager.Build\" Version=\"2.1.175\" />\n    <PackageVersion Include=\"Microsoft.VisualStudio.Azure.Containers.Tools.Targets\" Version=\"1.19.6\" />\n    <PackageVersion Include=\"Microsoft.VisualStudio.Web.CodeGeneration.Design\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"Moq\" Version=\"4.20.70\" />\n    <PackageVersion Include=\"MSTest.TestAdapter\" Version=\"3.1.1\" />\n    <PackageVersion Include=\"MSTest.TestFramework\" Version=\"3.1.1\" />\n    <PackageVersion Include=\"Nerdbank.GitVersioning\" Version=\"3.6.133\" />\n    <PackageVersion Include=\"Newtonsoft.Json\" Version=\"13.0.3\" />\n    <PackageVersion Include=\"Npgsql.EntityFrameworkCore.PostgreSQL\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"NWebsec.AspNetCore.Middleware\" Version=\"3.0.0\" />\n    <PackageVersion Include=\"Persante.Blazor.SharedUI\" Version=\"1.0.11\" />\n    <PackageVersion Include=\"Persante.Common.Api\" Version=\"1.1.4\" />\n    <PackageVersion Include=\"Persante.Common.Infrastructure\" Version=\"1.1.1\" />\n    <PackageVersion Include=\"Persante.Identity.Iam\" Version=\"1.1.30-alpha.5\" />\n    <PackageVersion Include=\"Persante.Identity.Iam.Blazor\" Version=\"1.1.24-alpha.5\" />\n    <PackageVersion Include=\"Persante.Logging\" Version=\"1.0.8\" />\n    <PackageVersion Include=\"Persante.Security.Authentication\" Version=\"1.1.26-alpha.3\" />\n    <PackageVersion Include=\"Pomelo.EntityFrameworkCore.MySql\" Version=\"7.0.0\" />\n    <PackageVersion Include=\"Pomelo.EntityFrameworkCore.MySql.Design\" Version=\"1.1.2\" />\n    <PackageVersion Include=\"protobuf-net\" Version=\"3.2.26\" />\n    <PackageVersion Include=\"protobuf-net.BuildTools\" Version=\"3.2.27\" />\n    <PackageVersion Include=\"protobuf-net.Core\" Version=\"3.2.26\" />\n    <PackageVersion Include=\"protobuf-net.Grpc\" Version=\"1.1.1\" />\n    <PackageVersion Include=\"protobuf-net.Grpc.AspNetCore\" Version=\"1.1.1\" />\n    <PackageVersion Include=\"protobuf-net.Reflection\" Version=\"3.2.12\" />\n    <PackageVersion Include=\"Refit\" Version=\"7.0.0\" />\n    <PackageVersion Include=\"Refit.HttpClientFactory\" Version=\"7.0.0\" />\n    <PackageVersion Include=\"Refit.Newtonsoft.Json\" Version=\"7.0.0\" />\n    <PackageVersion Include=\"Sendgrid\" Version=\"9.25.2\" />\n    <PackageVersion Include=\"Serilog\" Version=\"3.1.1\" />\n    <PackageVersion Include=\"Serilog.AspNetCore\" Version=\"$(AspnetMinorVersion)\" />\n    <PackageVersion Include=\"Serilog.Enrichers.Environment\" Version=\"2.3.0\" />\n    <PackageVersion Include=\"Serilog.Enrichers.Thread\" Version=\"3.1.0\" />\n    <PackageVersion Include=\"Serilog.Extensions.Hosting\" Version=\"$(SerilogVersion)\" />\n    <PackageVersion Include=\"Serilog.Extensions.Logging\" Version=\"$(SerilogVersion)\" />\n    <PackageVersion Include=\"Serilog.Settings.Configuration\" Version=\"$(SerilogVersion)\" />\n    <PackageVersion Include=\"Serilog.Sinks.Console\" Version=\"5.0.1\" />\n    <PackageVersion Include=\"Serilog.Sinks.File\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"Serilog.Sinks.MSSqlServer\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Serilog.Sinks.Seq\" Version=\"6.0.0\" />\n    <PackageVersion Include=\"Skoruba.AuditLogging.EntityFramework\" Version=\"1.0.0\" />\n    <PackageVersion Include=\"Spectre.Console\" Version=\"0.47.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore.Swagger\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"Swashbuckle.AspNetCore.Annotations\" Version=\"6.5.0\" />\n    <PackageVersion Include=\"System.Configuration.ConfigurationManager\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"System.IdentityModel.Tokens.Jwt\" Version=\"7.3.1\" />\n    <PackageVersion Include=\"System.Reactive\" Version=\"6.0.0\" />\n    <PackageVersion Include=\"System.Security.Principal.Windows\" Version=\"5.0.0\" />\n    <PackageVersion Include=\"System.ServiceModel.Primitives\" Version=\"$(AspnetVersion)\" />\n    <PackageVersion Include=\"WireMock.Net\" Version=\"1.5.39\" />\n    <PackageVersion Include=\"xunit\" Version=\"2.6.4\" />\n    <PackageVersion Include=\"xunit.runner.visualstudio\" Version=\"2.5.6\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageVersion>\n    <PackageVersion Include=\"Microsoft.CodeAnalysis.NetAnalyzers\" Version=\"$(AspnetVersion)\" PrivateAssets=\"All\" />\n    <PackageVersion Include=\"Microsoft.SourceLink.GitHub\" Version=\"$(AspnetVersion)\" PrivateAssets=\"All\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "GitReleaseManager.yaml",
    "content": "create:\n  include-footer: false\n  footer-heading:\n  footer-content:\n  footer-includes-milestone: false\n  milestone-replace-text:\nexport:\n  include-created-date-in-title: false\n  created-date-string-format:\n  perform-regex-removal: false\n  regex-text:\n  multiline-regex: false\nissue-labels-include:\n- bug\n- new feature\n- enhancement\n- breaking change\nissue-labels-exclude:\n- Internal Refactoring\n"
  },
  {
    "path": "IdentityServer8.DotNet.ruleset",
    "content": "﻿<?xml version=\"1.0\"?>\n<RuleSet Name=\"All Rules Disabled\" Description=\"All Rules are disabled.\" ToolsVersion=\"15.0\">\n   <Rules AnalyzerId=\"Microsoft.CodeAnalysis.VersionCheckAnalyzer\" RuleNamespace=\"Microsoft.CodeAnalysis.VersionCheckAnalyzer\">\n      <Rule Id=\"CA9999\" Action=\"None\" />             <!-- Analyzer version mismatch -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.CodeQuality.Analyzers\" RuleNamespace=\"Microsoft.CodeQuality.Analyzers\">\n      <Rule Id=\"CA1000\" Action=\"None\" />             <!-- Do not declare static members on generic types -->\n      <Rule Id=\"CA1008\" Action=\"None\" />             <!-- Enums should have zero value -->\n      <Rule Id=\"CA1010\" Action=\"None\" />             <!-- Collections should implement generic interface -->\n      <Rule Id=\"CA1012\" Action=\"None\" />             <!-- Abstract types should not have constructors -->\n      <Rule Id=\"CA1014\" Action=\"None\" />             <!-- Mark assemblies with CLSCompliant -->\n      <Rule Id=\"CA1016\" Action=\"None\" />             <!-- Mark assemblies with assembly version -->\n      <Rule Id=\"CA1017\" Action=\"None\" />             <!-- Mark assemblies with ComVisible -->\n      <Rule Id=\"CA1018\" Action=\"None\" />             <!-- Mark attributes with AttributeUsageAttribute -->\n      <Rule Id=\"CA1024\" Action=\"None\" />             <!-- Use properties where appropriate -->\n      <Rule Id=\"CA1027\" Action=\"None\" />             <!-- Mark enums with FlagsAttribute -->\n      <Rule Id=\"CA1028\" Action=\"None\" />             <!-- Enum Storage should be Int32 -->\n      <Rule Id=\"CA1030\" Action=\"None\" />             <!-- Use events where appropriate -->\n      <Rule Id=\"CA1031\" Action=\"None\" />             <!-- Do not catch general exception types -->\n      <Rule Id=\"CA1033\" Action=\"None\" />             <!-- Interface methods should be callable by child types -->\n      <Rule Id=\"CA1034\" Action=\"None\" />             <!-- Nested types should not be visible -->\n      <Rule Id=\"CA1036\" Action=\"None\" />             <!-- Override methods on comparable types -->\n      <Rule Id=\"CA1040\" Action=\"None\" />             <!-- Avoid empty interfaces -->\n      <Rule Id=\"CA1041\" Action=\"None\" />             <!-- Provide ObsoleteAttribute message -->\n      <Rule Id=\"CA1043\" Action=\"None\" />             <!-- Use Integral Or String Argument For Indexers -->\n      <Rule Id=\"CA1044\" Action=\"None\" />             <!-- Properties should not be write only -->\n      <Rule Id=\"CA1050\" Action=\"None\" />             <!-- Declare types in namespaces -->\n      <Rule Id=\"CA1051\" Action=\"None\" />             <!-- Do not declare visible instance fields -->\n      <Rule Id=\"CA1052\" Action=\"None\" />             <!-- Static holder types should be Static or NotInheritable -->\n      <Rule Id=\"CA1054\" Action=\"None\" />             <!-- Uri parameters should not be strings -->\n      <Rule Id=\"CA1055\" Action=\"None\" />             <!-- Uri return values should not be strings -->\n      <Rule Id=\"CA1056\" Action=\"None\" />             <!-- Uri properties should not be strings -->\n      <Rule Id=\"CA1060\" Action=\"None\" />             <!-- Move pinvokes to native methods class -->\n      <Rule Id=\"CA1061\" Action=\"None\" />             <!-- Do not hide base class methods -->\n      <Rule Id=\"CA1062\" Action=\"None\" />             <!-- Validate arguments of public methods -->\n      <Rule Id=\"CA1063\" Action=\"None\" />             <!-- Implement IDisposable Correctly -->\n      <Rule Id=\"CA1064\" Action=\"None\" />             <!-- Exceptions should be public -->\n      <Rule Id=\"CA1066\" Action=\"None\" />             <!-- Type {0} should implement IEquatable<T> because it overrides Equals -->\n      <Rule Id=\"CA1067\" Action=\"None\" />             <!-- Override Object.Equals(object) when implementing IEquatable<T> -->\n      <Rule Id=\"CA1068\" Action=\"None\" />             <!-- CancellationToken parameters must come last -->\n      <Rule Id=\"CA1501\" Action=\"None\" />             <!-- Avoid excessive inheritance -->\n      <Rule Id=\"CA1502\" Action=\"None\" />             <!-- Avoid excessive complexity -->\n      <Rule Id=\"CA1505\" Action=\"None\" />             <!-- Avoid unmaintainable code -->\n      <Rule Id=\"CA1506\" Action=\"None\" />             <!-- Avoid excessive class coupling -->\n      <Rule Id=\"CA1508\" Action=\"None\" />             <!-- Avoid dead conditional code -->\n      <Rule Id=\"CA1509\" Action=\"None\" />             <!-- Invalid entry in code metrics rule specification file -->\n      <Rule Id=\"CA1707\" Action=\"None\" />             <!-- Identifiers should not contain underscores -->\n      <Rule Id=\"CA1708\" Action=\"None\" />             <!-- Identifiers should differ by more than case -->\n      <Rule Id=\"CA1710\" Action=\"None\" />             <!-- Identifiers should have correct suffix -->\n      <Rule Id=\"CA1711\" Action=\"None\" />             <!-- Identifiers should not have incorrect suffix -->\n      <Rule Id=\"CA1712\" Action=\"None\" />             <!-- Do not prefix enum values with type name -->\n      <Rule Id=\"CA1714\" Action=\"None\" />             <!-- Flags enums should have plural names -->\n      <Rule Id=\"CA1715\" Action=\"None\" />             <!-- Identifiers should have correct prefix -->\n      <Rule Id=\"CA1716\" Action=\"None\" />             <!-- Identifiers should not match keywords -->\n      <Rule Id=\"CA1717\" Action=\"None\" />             <!-- Only FlagsAttribute enums should have plural names -->\n      <Rule Id=\"CA1720\" Action=\"None\" />             <!-- Identifier contains type name -->\n      <Rule Id=\"CA1721\" Action=\"None\" />             <!-- Property names should not match get methods -->\n      <Rule Id=\"CA1724\" Action=\"None\" />             <!-- Type names should not match namespaces -->\n      <Rule Id=\"CA1725\" Action=\"None\" />             <!-- Parameter names should match base declaration -->\n      <Rule Id=\"CA1801\" Action=\"None\" />             <!-- Review unused parameters -->\n      <Rule Id=\"CA1802\" Action=\"None\" />             <!-- Use literals where appropriate -->\n      <Rule Id=\"CA1806\" Action=\"None\" />             <!-- Do not ignore method results -->\n      <Rule Id=\"CA1812\" Action=\"Warning\" />          <!-- Avoid uninstantiated internal classes -->\n      <Rule Id=\"CA1814\" Action=\"None\" />             <!-- Prefer jagged arrays over multidimensional -->\n      <Rule Id=\"CA1815\" Action=\"None\" />             <!-- Override equals and operator equals on value types -->\n      <Rule Id=\"CA1819\" Action=\"None\" />             <!-- Properties should not return arrays -->\n      <Rule Id=\"CA1822\" Action=\"None\" />             <!-- Mark members as static -->\n      <Rule Id=\"CA1823\" Action=\"Warning\" />          <!-- Avoid unused private fields -->\n      <Rule Id=\"CA2007\" Action=\"Error\" />            <!-- Do not directly await a Task -->\n      <Rule Id=\"CA2119\" Action=\"None\" />             <!-- Seal methods that satisfy private interfaces -->\n      <Rule Id=\"CA2211\" Action=\"None\" />             <!-- Non-constant fields should not be visible -->\n      <Rule Id=\"CA2214\" Action=\"None\" />             <!-- Do not call overridable methods in constructors -->\n      <Rule Id=\"CA2217\" Action=\"None\" />             <!-- Do not mark enums with FlagsAttribute -->\n      <Rule Id=\"CA2219\" Action=\"None\" />             <!-- Do not raise exceptions in finally clauses -->\n      <Rule Id=\"CA2225\" Action=\"None\" />             <!-- Operator overloads have named alternates -->\n      <Rule Id=\"CA2226\" Action=\"None\" />             <!-- Operators should have symmetrical overloads -->\n      <Rule Id=\"CA2227\" Action=\"None\" />             <!-- Collection properties should be read only -->\n      <Rule Id=\"CA2231\" Action=\"None\" />             <!-- Overload operator equals on overriding value type Equals -->\n      <Rule Id=\"CA2244\" Action=\"None\" />             <!-- Do not duplicate indexed element initializations -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.CodeQuality.CSharp.Analyzers\" RuleNamespace=\"Microsoft.CodeQuality.CSharp.Analyzers\">\n      <Rule Id=\"CA1001\" Action=\"None\" />             <!-- Types that own disposable fields should be disposable -->\n      <Rule Id=\"CA1003\" Action=\"None\" />             <!-- Use generic event handler instances -->\n      <Rule Id=\"CA1019\" Action=\"None\" />             <!-- Define accessors for attribute arguments -->\n      <Rule Id=\"CA1032\" Action=\"None\" />             <!-- Implement standard exception constructors -->\n      <Rule Id=\"CA1065\" Action=\"None\" />             <!-- Do not raise exceptions in unexpected locations -->\n      <Rule Id=\"CA1200\" Action=\"None\" />             <!-- Avoid using cref tags with a prefix -->\n      <Rule Id=\"CA1507\" Action=\"None\" />             <!-- Use nameof to express symbol names -->\n      <Rule Id=\"CA1821\" Action=\"None\" />             <!-- Remove empty Finalizers -->\n      <Rule Id=\"CA2200\" Action=\"None\" />             <!-- Rethrow to preserve stack details. -->\n      <Rule Id=\"CA2234\" Action=\"None\" />             <!-- Pass system uri objects instead of strings -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.CodeQuality.VisualBasic.Analyzers\" RuleNamespace=\"Microsoft.CodeQuality.VisualBasic.Analyzers\">\n      <Rule Id=\"CA1001\" Action=\"None\" />             <!-- Types that own disposable fields should be disposable -->\n      <Rule Id=\"CA1003\" Action=\"None\" />             <!-- Use generic event handler instances -->\n      <Rule Id=\"CA1019\" Action=\"None\" />             <!-- Define accessors for attribute arguments -->\n      <Rule Id=\"CA1032\" Action=\"None\" />             <!-- Implement standard exception constructors -->\n      <Rule Id=\"CA1065\" Action=\"None\" />             <!-- Do not raise exceptions in unexpected locations -->\n      <Rule Id=\"CA1200\" Action=\"None\" />             <!-- Avoid using cref tags with a prefix -->\n      <Rule Id=\"CA1507\" Action=\"None\" />             <!-- Use nameof to express symbol names -->\n      <Rule Id=\"CA1821\" Action=\"None\" />             <!-- Remove empty Finalizers -->\n      <Rule Id=\"CA2200\" Action=\"None\" />             <!-- Rethrow to preserve stack details. -->\n      <Rule Id=\"CA2218\" Action=\"None\" />             <!-- Override GetHashCode on overriding Equals -->\n      <Rule Id=\"CA2224\" Action=\"None\" />             <!-- Override Equals on overloading operator equals -->\n      <Rule Id=\"CA2234\" Action=\"None\" />             <!-- Pass system uri objects instead of strings -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.NetCore.Analyzers\" RuleNamespace=\"Microsoft.NetCore.Analyzers\">\n      <Rule Id=\"CA1303\" Action=\"None\" />             <!-- Do not pass literals as localized parameters -->\n      <Rule Id=\"CA1304\" Action=\"Error\" />            <!-- Specify CultureInfo -->\n      <Rule Id=\"CA1305\" Action=\"Error\" />            <!-- Specify IFormatProvider -->\n      <Rule Id=\"CA1307\" Action=\"Error\" />            <!-- Specify StringComparison -->\n      <Rule Id=\"CA1308\" Action=\"None\" />             <!-- Normalize strings to uppercase -->\n      <Rule Id=\"CA1401\" Action=\"None\" />             <!-- P/Invokes should not be visible -->\n      <Rule Id=\"CA1813\" Action=\"None\" />             <!-- Avoid unsealed attributes -->\n      <Rule Id=\"CA1816\" Action=\"None\" />             <!-- Dispose methods should call SuppressFinalize -->\n      <Rule Id=\"CA1820\" Action=\"None\" />             <!-- Test for empty strings using string length -->\n      <Rule Id=\"CA1826\" Action=\"None\" />             <!-- Do not use Enumerable methods on indexable collections. Instead use the collection directly -->\n      <Rule Id=\"CA2000\" Action=\"None\" />             <!-- Dispose objects before losing scope -->\n      <Rule Id=\"CA2002\" Action=\"None\" />             <!-- Do not lock on objects with weak identity -->\n      <Rule Id=\"CA2008\" Action=\"None\" />             <!-- Do not create tasks without passing a TaskScheduler -->\n      <Rule Id=\"CA2009\" Action=\"None\" />             <!-- Do not call ToImmutableCollection on an ImmutableCollection value -->\n      <Rule Id=\"CA2100\" Action=\"None\" />             <!-- Review SQL queries for security vulnerabilities -->\n      <Rule Id=\"CA2101\" Action=\"None\" />             <!-- Specify marshaling for P/Invoke string arguments -->\n      <Rule Id=\"CA2208\" Action=\"None\" />             <!-- Instantiate argument exceptions correctly -->\n      <Rule Id=\"CA2213\" Action=\"None\" />             <!-- Disposable fields should be disposed -->\n      <Rule Id=\"CA2216\" Action=\"None\" />             <!-- Disposable types should declare finalizer -->\n      <Rule Id=\"CA2229\" Action=\"None\" />             <!-- Implement serialization constructors -->\n      <Rule Id=\"CA2235\" Action=\"None\" />             <!-- Mark all non-serializable fields -->\n      <Rule Id=\"CA2237\" Action=\"None\" />             <!-- Mark ISerializable types with serializable -->\n      <Rule Id=\"CA2241\" Action=\"None\" />             <!-- Provide correct arguments to formatting methods -->\n      <Rule Id=\"CA2242\" Action=\"None\" />             <!-- Test for NaN correctly -->\n      <Rule Id=\"CA2243\" Action=\"None\" />             <!-- Attribute string literals should parse correctly -->\n      <Rule Id=\"CA2300\" Action=\"None\" />             <!-- Do not use insecure deserializer BinaryFormatter -->\n      <Rule Id=\"CA2301\" Action=\"None\" />             <!-- Do not call BinaryFormatter.Deserialize without first setting BinaryFormatter.Binder -->\n      <Rule Id=\"CA2302\" Action=\"None\" />             <!-- Ensure BinaryFormatter.Binder is set before calling BinaryFormatter.Deserialize -->\n      <Rule Id=\"CA2305\" Action=\"None\" />             <!-- Do not use insecure deserializer LosFormatter -->\n      <Rule Id=\"CA2310\" Action=\"None\" />             <!-- Do not use insecure deserializer NetDataContractSerializer -->\n      <Rule Id=\"CA2311\" Action=\"None\" />             <!-- Do not deserialize without first setting NetDataContractSerializer.Binder -->\n      <Rule Id=\"CA2312\" Action=\"None\" />             <!-- Ensure NetDataContractSerializer.Binder is set before deserializing -->\n      <Rule Id=\"CA2315\" Action=\"None\" />             <!-- Do not use insecure deserializer ObjectStateFormatter -->\n      <Rule Id=\"CA3001\" Action=\"None\" />             <!-- Review code for SQL injection vulnerabilities -->\n      <Rule Id=\"CA3002\" Action=\"None\" />             <!-- Review code for XSS vulnerabilities -->\n      <Rule Id=\"CA3003\" Action=\"None\" />             <!-- Review code for file path injection vulnerabilities -->\n      <Rule Id=\"CA3004\" Action=\"None\" />             <!-- Review code for information disclosure vulnerabilities -->\n      <Rule Id=\"CA3005\" Action=\"None\" />             <!-- Review code for LDAP injection vulnerabilities -->\n      <Rule Id=\"CA3006\" Action=\"None\" />             <!-- Review code for process command injection vulnerabilities -->\n      <Rule Id=\"CA3007\" Action=\"None\" />             <!-- Review code for open redirect vulnerabilities -->\n      <Rule Id=\"CA3008\" Action=\"None\" />             <!-- Review code for XPath injection vulnerabilities -->\n      <Rule Id=\"CA3009\" Action=\"None\" />             <!-- Review code for XML injection vulnerabilities -->\n      <Rule Id=\"CA3010\" Action=\"None\" />             <!-- Review code for XAML injection vulnerabilities -->\n      <Rule Id=\"CA3011\" Action=\"None\" />             <!-- Review code for DLL injection vulnerabilities -->\n      <Rule Id=\"CA3012\" Action=\"None\" />             <!-- Review code for regex injection vulnerabilities -->\n      <Rule Id=\"CA3061\" Action=\"None\" />             <!-- Do Not Add Schema By URL -->\n      <Rule Id=\"CA5350\" Action=\"None\" />             <!-- Do Not Use Weak Cryptographic Algorithms -->\n      <Rule Id=\"CA5351\" Action=\"None\" />             <!-- Do Not Use Broken Cryptographic Algorithms -->\n      <Rule Id=\"CA5358\" Action=\"None\" />             <!-- Do Not Use Unsafe Cipher Modes -->\n      <Rule Id=\"CA5359\" Action=\"None\" />             <!-- Do Not Disable Certificate Validation -->\n      <Rule Id=\"CA5360\" Action=\"None\" />             <!-- Do Not Call Dangerous Methods In Deserialization -->\n      <Rule Id=\"CA5361\" Action=\"None\" />             <!-- Do Not Disable SChannel Use of Strong Crypto -->\n      <Rule Id=\"CA5362\" Action=\"None\" />             <!-- Do Not Refer Self In Serializable Class -->\n      <Rule Id=\"CA5363\" Action=\"None\" />             <!-- Do Not Disable Request Validation -->\n      <Rule Id=\"CA5364\" Action=\"None\" />             <!-- Do Not Use Deprecated Security Protocols -->\n      <Rule Id=\"CA5365\" Action=\"None\" />             <!-- Do Not Disable HTTP Header Checking -->\n      <Rule Id=\"CA5367\" Action=\"None\" />             <!-- Do Not Serialize Types With Pointer Fields -->\n      <Rule Id=\"CA5368\" Action=\"None\" />             <!-- Set ViewStateUserKey For Classes Derived From Page -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.NetCore.CSharp.Analyzers\" RuleNamespace=\"Microsoft.NetCore.CSharp.Analyzers\">\n      <Rule Id=\"CA1309\" Action=\"Error\" />            <!-- Use ordinal stringcomparison -->\n      <Rule Id=\"CA1810\" Action=\"None\" />             <!-- Initialize reference type static fields inline -->\n      <Rule Id=\"CA1824\" Action=\"None\" />             <!-- Mark assemblies with NeutralResourcesLanguageAttribute -->\n      <Rule Id=\"CA1825\" Action=\"Warning\" />          <!-- Avoid zero-length array allocations. -->\n      <Rule Id=\"CA2010\" Action=\"None\" />             <!-- Always consume the value returned by methods marked with PreserveSigAttribute -->\n      <Rule Id=\"CA2201\" Action=\"None\" />             <!-- Do not raise reserved exception types -->\n      <Rule Id=\"CA2207\" Action=\"None\" />             <!-- Initialize value type static fields inline -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.NetCore.VisualBasic.Analyzers\" RuleNamespace=\"Microsoft.NetCore.VisualBasic.Analyzers\">\n      <Rule Id=\"CA1309\" Action=\"Error\" />            <!-- Use ordinal stringcomparison -->\n      <Rule Id=\"CA1810\" Action=\"None\" />             <!-- Initialize reference type static fields inline -->\n      <Rule Id=\"CA1824\" Action=\"None\" />             <!-- Mark assemblies with NeutralResourcesLanguageAttribute -->\n      <Rule Id=\"CA1825\" Action=\"Warning\" />          <!-- Avoid zero-length array allocations. -->\n      <Rule Id=\"CA2010\" Action=\"None\" />             <!-- Always consume the value returned by methods marked with PreserveSigAttribute -->\n      <Rule Id=\"CA2201\" Action=\"None\" />             <!-- Do not raise reserved exception types -->\n      <Rule Id=\"CA2207\" Action=\"None\" />             <!-- Initialize value type static fields inline -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.NetFramework.Analyzers\" RuleNamespace=\"Microsoft.NetFramework.Analyzers\">\n      <Rule Id=\"CA1058\" Action=\"None\" />             <!-- Types should not extend certain base types -->\n      <Rule Id=\"CA2153\" Action=\"None\" />             <!-- Do Not Catch Corrupted State Exceptions -->\n      <Rule Id=\"CA3075\" Action=\"None\" />             <!-- Insecure DTD processing in XML -->\n      <Rule Id=\"CA3147\" Action=\"None\" />             <!-- Mark Verb Handlers With Validate Antiforgery Token -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.NetFramework.CSharp.Analyzers\" RuleNamespace=\"Microsoft.NetFramework.CSharp.Analyzers\">\n      <Rule Id=\"CA3076\" Action=\"None\" />             <!-- Insecure XSLT script processing. -->\n      <Rule Id=\"CA3077\" Action=\"None\" />             <!-- Insecure Processing in API Design, XmlDocument and XmlTextReader -->\n   </Rules>\n   <Rules AnalyzerId=\"Microsoft.NetFramework.VisualBasic.Analyzers\" RuleNamespace=\"Microsoft.NetFramework.VisualBasic.Analyzers\">\n      <Rule Id=\"CA3076\" Action=\"None\" />             <!-- Insecure XSLT script processing. -->\n      <Rule Id=\"CA3077\" Action=\"None\" />             <!-- Insecure Processing in API Design, XmlDocument and XmlTextReader -->\n   </Rules>\n</RuleSet>\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2018, Brock Allen, Dominick Baier\n\n   Copyright 2024, HigginsSoft, Alexander Higgins\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "LicenseHeader.txt",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/"
  },
  {
    "path": "NuGet.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n\t<clear/>\n    <add key=\"NuGet\" value=\"https://api.nuget.org/v3/index.json\" />\n  </packageSources>\n</configuration>"
  },
  {
    "path": "README.md",
    "content": "# Identity Server 8 update\nThis project is a DotNet 8 revival of the Identity Server 4 and Identity Server 4 Admin UI, for Open ID Connect (OIDC) and OAuth, which was archived when .NET Core 3.1 reached end of support.\n\nThe latest verion, 8.0.4, is now available on NuGet. It contains [hundreds of security and bug fixes](https://github.com/alexhiggins732/IdentityServer8/blob/master/docs/CHANGELOG.md) from the original Identity Server 4 project.\n\nIt is recommend you update all previous version, 4 or 8, to the latest version to ensure you have the latest security updates. \n\n- [Documentation](http://identityserver8.readthedocs.io/)\n- [Support](https://identityserver8.readthedocs.io/en/latest/into/support.html)\n- [Gitter Chat](https://app.gitter.im/#/room/#identityserver8:gitter.im)\n\n[HigginsSoft.IdentityServer8 and Admin UI Nuget Packages](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8) are available here for use in DotNet 8.\n\nAll new development in the archived repository has moved to a paid commercial version in the [Duende Software](https://github.com/duendesoftware) organization. \n\nSee [here](https://duendesoftware.com/products/identityserver) for more details on the commerica version.\n\nThis repository will be maintained for bug fixes and security updates for the .NET 8 version of Identity Server 4.\n\nThe source code and unit tests will be updated to use the latest .NET 8 features and best practices.\n\nOnce the source code and unit tests are stabilized, the documentation will be updated to reflect the changes.\n\nGeneral speaking, the existing documentation for Identity Server 4 will be valid for this repository, but the new features and changes will be documented in the new documentation.\n\nIn the meantime, NuGet packages will be published to the [IdentityServer8 NuGet feed](https://www.nuget.org/profiles/IdentityServer8) and the [IdentityServer8 MyGet feed](https://www.myget.org/F/identityserver8/api/v3/index.json).\n\n\n## Build Status And Stats\n\n[![Master | Build](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/master.yml/badge.svg)](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/master.yml)\n[![Release|Build](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/release.yml/badge.svg)](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/release.yml)\n\n[![Develop|Build](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/develop.yml/badge.svg)](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/develop.yml)\n[![CI/CD|Build](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/pre-release.yml/badge.svg)](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/pre-release.yml)\n\n## Code Coverage\n[![Master | Build](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/master.yml/badge.svg)](https://img.shields.io/codecov/c/github/alexhiggins732/identityserver8) [![Master|CodeQL](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/codeql.yml/badge.svg)](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/codeql.yml)\n\n[![Develop|Build](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/develop.yml/badge.svg)](https://img.shields.io/codecov/c/github/alexhiggins732/identityserver8/tree/develop)\n[![Master|CodeQL](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/codeql.yml/badge.svg?branch=develop)](https://github.com/alexhiggins732/IdentityServer8/actions/workflows/codeql.yml?branch=develop)\n\n## Documentation\n[![Documentation Status](https://readthedocs.org/projects/identityserver8/badge/?version=latest)](https://identityserver8.readthedocs.io/en/latest/?badge=latest)\n[Read the docs - identityserver8.readthedocs.io ](http://identityserver8.readthedocs.io/)\n\n## Nuget Packages\n\n### Identity Server 8\n|Package||\n| ------------- | ------------- |\n|[HigginsSoft.IdentityServer8](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8)|\n|[HigginsSoft.IdentityServer8.Storage](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Storage)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Storage)|\n|[HigginsSoft.IdentityServer8.EntityFramework](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.EntityFramework)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.EntityFramework)|\n|[HigginsSoft.IdentityServer8.EntityFramework.Storage](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.EntityFramework.Storage)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.EntityFramework.Storage)|\n|[HigginsSoft.IdentityServer8.AspNetIdentity](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.AspNetIdentity)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.AspNetIdentity)|\n| | |\n\n### Identity Server 8 Administration UI\n|Package||\n| ------------- | ------------- |\n|[HigginsSoft.IdentityServer8.Shared](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Shared)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Shared)|\n|[HigginsSoft.IdentityServer8.Admin.UI](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.UI)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.UI)|\n|[HigginsSoft.IdentityServer8.Shared.Configuration](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Shared.Configuration)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Shared.Configuration)|\n|[HigginsSoft.IdentityServer8.Admin.Api](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.Api)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.Api)|\n|[HigginsSoft.IdentityServer8.Admin](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin)|\n|[HigginsSoft.IdentityServer8.Admin.BusinessLogic.Identity](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.BusinessLogic.Identity)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.BusinessLogic.Identity)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework.Identity](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework.Identity)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework.Identity)|\n|[HigginsSoft.IdentityServer8.Admin.BusinessLogic.Shared](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.BusinessLogic.Shared)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.BusinessLogic.Shared)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework.Extensions](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework.Extensions)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework.Extensions)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework.PostgreSQL](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework.PostgreSQL)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework.PostgreSQL)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework.MySql](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework.MySql)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework.MySql)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework.SqlServer](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework.SqlServer)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework.SqlServer)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework.Shared](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework.Shared)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework.Shared)|\n|[HigginsSoft.IdentityServer8.Admin.BusinessLogic](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.BusinessLogic)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.BusinessLogic)|\n|[HigginsSoft.IdentityServer8.Admin.EntityFramework.Configuration](https://www.nuget.org/packages?q=HigginsSoft.IdentityServer8.Admin.EntityFramework.Configuration)|![NuGet Downloads](https://img.shields.io/nuget/dt/HigginsSoft.IdentityServer8.Admin.EntityFramework.Configuration)|\n| | |\n\n\n## What's New\n\nView the [CHANGELOG](docs/CHANGELOG.md) for the latest changes.\n\n## About IdentityServer8\n[<img align=\"right\" width=\"100px\" src=\"https://dotnetfoundation.org/img/logo_big.svg\" />](https://dotnetfoundation.org/projects?searchquery=IdentityServer&type=project)\n\nIdentityServer is a free, open source [OpenID Connect](http://openid.net/connect/) and [OAuth 2.0](https://tools.ietf.org/html/rfc6749) framework for ASP.NET Core.\nFounded and maintained by [Dominick Baier](https://twitter.com/leastprivilege) and [Brock Allen](https://twitter.com/brocklallen), IdentityServer8 incorporates all the protocol implementations and extensibility points needed to integrate token-based authentication, single-sign-on and API access control in your applications.\nIdentityServer8 is officially [certified](https://openid.net/certification/) by the [OpenID Foundation](https://openid.net) and thus spec-compliant and interoperable.\nIt is part of the [.NET Foundation](https://www.dotnetfoundation.org/), and operates under their [code of conduct](https://www.dotnetfoundation.org/code-of-conduct). It is licensed under [Apache 2](https://opensource.org/licenses/Apache-2.0) (an OSI approved license).\n\nFor project documentation, please visit [readthedocs](https://IdentityServer8.readthedocs.io).\n\n## Branch structure\nActive development happens on the main branch. This always contains the latest version. Each (pre-) release is tagged with the corresponding version. The [aspnetcore1](https://github.com/alexhiggins732/IdentityServer8/tree/aspnetcore1) and [aspnetcore2](https://github.com/alexhiggins732/IdentityServer8/tree/aspnetcore2) branches contain the latest versions of the older ASP.NET Core based versions.\n\n## How to build\n\n* [Install]([https://www.microsoft.com/net/download/core#/current](https://dotnet.microsoft.com/en-us/download#/current) the latest .NET 8 SDK\n* Install Git\n* Clone this repo\n* Run `dotnet build src/identityserver8.slm` or `build.sh` in the root of the cloned repo.\n\n## Documentation\nFor project documentation, please visit [readthedocs](https://IdentityServer8.readthedocs.io).\n\nSee [here](http://docs.identityserver8.io/en/aspnetcore1/) for the 1.x docs, and [here](http://docs.identityserver8.io/en/aspnetcore2/) for the 2.x docs.\n\n## Bug reports and feature requests\nPlease use the [issue tracker](https://github.com/alexhiggins732/IdentityServer8/issues) for that. We only support the latest version for free. For older versions, you can get a commercial support agreement with us.\n\n## Commercial and Community Support\nIf you need help with implementing IdentityServer8 or your security architecture in general, there are both free and commercial support options.\nSee [here](https://IdentityServer8.readthedocs.io/en/latest/intro/support.html) for more details.\n\n## Sponsorship\nIf you are a fan of the project or a company that relies on IdentityServer, you might want to consider sponsoring.\nThis will help us devote more time to answering questions and doing feature development. If you are interested please head to our [Patreon](https://www.patreon.com/identityserver) page which has further details.\n\n### Platinum Sponsors\n[<img src=\"https://user-images.githubusercontent.com/1454075/62819413-39550c00-bb55-11e9-8f2f-a268c3552c71.png\" width=\"200\">](https://udelt.no)\n\n[<img src=\"https://user-images.githubusercontent.com/1454075/66454740-fb973580-ea68-11e9-9993-6c1014881528.png\" width=\"200\">](https://github.com/dotnet-at-microsoft)\n\n### Corporate Sponsors\n[Ritter Insurance Marketing](https://www.ritterim.com)  \n[ExtraNetUserManager](https://www.extranetusermanager.com/)  \n[Knab](https://www.knab.nl/)\n\nYou can see a list of our current sponsors [here](https://github.com/alexhiggins732/IdentityServer8/blob/main/SPONSORS.md) - and for companies we have some nice advertisement options as well.\n\n## Acknowledgements\nIdentityServer8 is built using the following great open source projects and free services:\n\n* [ASP.NET Core](https://github.com/dotnet/aspnetcore)\n* [Bullseye](https://github.com/adamralph/bullseye)\n* [SimpleExec](https://github.com/adamralph/simple-exec)\n* [MinVer](https://github.com/adamralph/minver)\n* [Json.Net](http://www.newtonsoft.com/json)\n* [XUnit](https://xunit.github.io/)\n* [Fluent Assertions](http://www.fluentassertions.com/)\n* [GitReleaseManager](https://github.com/GitTools/GitReleaseManager)\n\n..and last but not least a big thanks to all our [contributors](https://github.com/alexhiggins732/IdentityServer8/graphs/contributors)!\n"
  },
  {
    "path": "SECURITY.MD",
    "content": "# Reporting Security Issues\n\nIf you discover a security issue in IdentityServer, please report it by sending an email to contact@identityserver8.io\n\nThis will allow us to assess the risk, and make a fix available before we add a bug report to the GitHub repository.\n\nThanks!\n"
  },
  {
    "path": "SPONSORS.md",
    "content": "# Sponsors\n\nWe thank those who [support](https://www.patreon.com/identityserver) IdentityServer!\n\n## Corporate\n\n### Platinum\n[Udelt](https://udelt.no/)  \n[Microsoft .NET](https://github.com/dotnet-at-microsoft)\n\n### Gold\n[Ritter Insurance Marketing](https://www.ritterim.com) ([@RitterIM](https://twitter.com/ritterim))   \n[ExtranetUserManager](https://www.extranetusermanager.com) ([@eumgr](https://twitter.com/eumgr))  \n[Knab](https://www.knab.nl/) ([@knab_nl](https://twitter.com/knab_nl))  \n\n### Silver\n\nJacobus Roos  \nSoluto ([@SolutoEng](https://twitter.com/SolutoEng))  \nSteinar\tNoem  \nEffectory ([@effectory](https://twitter.com/effectory))  \nReal Page ([@RealPage](https://twitter.com/RealPage))  \nJustify ([@justify_legal](https://twitter.com/justify_legal))\n\n## Individuals\n\nKhalid Abuhakmeh ([@buhakmeh](https://twitter.com/buhakmeh))  \nRasika Weliwita ([@rasikaweliwita](https://twitter.com/rasikaweliwita))  \nArun David Shelly  \nTobias Höft ([@tobiashoeft](https://twitter.com/tobiashoeft))  \nWilliam Grow  \nJames Roberts  \nChris Simmons ([@netchrisdotcom](https://twitter.com/netchrisdotcom))  \nShawn Wildermuth  \nJohan Boström ([@zarx](https://twitter.com/zarx))  \nAlbert ([@DerAlbert](https://twitter.com/DerAlbert))  \nHugo Biarge ([@hbiarge](https://twitter.com/hbiarge))  \nIbrahim Šuta ([@ibrahimsuta](https://twitter.com/ibrahimsuta))  \nVIJAYA PAL NALLALA  \nMartijn Boland  \nGiuseppe Turitto  \nMauricio Schneider  \nNorman L Covington  \nRyan Mendoza  ([@elryry](https://twitter.com/elryry))  \nColin Blair  \nErik Gulbrandsen  \nOlga Klimova  \nAlexandru Puiu  \nMichael Calasanz  \nFredrik Karlsson ([@fredrik_zenit](https://twitter.com/fredrik_zenit))  \nJeremy Sinclair ([@sinclairinator](https://twitter.com/sinclairinator))  \nBruno Brito  \nJames Hough  \nvanbukin  \n"
  },
  {
    "path": "docker-compose.dcproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" Sdk=\"Microsoft.Docker.Sdk\">\n  <PropertyGroup Label=\"Globals\">\n    <ProjectVersion>2.1</ProjectVersion>\n    <DockerTargetOS>Linux</DockerTargetOS>\n    <ProjectGuid>f817047f-018d-4f93-bda5-58602073b634</ProjectGuid>\n    <DockerLaunchAction>None</DockerLaunchAction>\n    <DockerServiceUrl>{Scheme}://localhost:{ServicePort}</DockerServiceUrl>\n    <DockerServiceName>IdentityServer8.Admin</DockerServiceName>\n  </PropertyGroup>\n  <ItemGroup>\n    <None Include=\"docker-compose.vs.debug.yml\">\n      <DependentUpon>docker-compose.yml</DependentUpon>\n    </None>\n    <None Include=\"docker-compose.override.yml\">\n      <DependentUpon>docker-compose.yml</DependentUpon>\n    </None>\n    <None Include=\"docker-compose.vs.release.yml\">\n      <DependentUpon>docker-compose.yml</DependentUpon>\n    </None>\n    <None Include=\"docker-compose.yml\" />\n    <None Include=\".dockerignore\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "docker-compose.override.yml",
    "content": "version: '3.4'\n\nservices:\n  IdentityServer8.Admin:\n    environment:\n      - ASPNETCORE_ENVIRONMENT=Development\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n  \n  IdentityServer8.Admin.api:\n    environment:\n      - ASPNETCORE_ENVIRONMENT=Development\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n\n  higginssoft.identityserver4.sts.identity:\n    environment:\n      - ASPNETCORE_ENVIRONMENT=Development\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n"
  },
  {
    "path": "docker-compose.vs.debug.yml",
    "content": "version: '3.4'\n\nservices:\n  IdentityServer8.Admin:\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n    labels:\n      com.microsoft.visualstudio.debuggee.arguments: ' --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages  \"bin/Debug/net6.0/IdentityServer8.Admin.dll\" /seed'\n\n  IdentityServer8.Admin.api:\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n\n  higginssoft.identityserver4.sts.identity:\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n"
  },
  {
    "path": "docker-compose.vs.release.yml",
    "content": "version: '3.4'\n\nservices:\n  IdentityServer8.Admin:\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n    labels:\n      com.microsoft.visualstudio.debuggee.arguments: ' --additionalProbingPath /root/.nuget/packages --additionalProbingPath /root/.nuget/fallbackpackages  \"bin/Debug/net6.0/IdentityServer8.Admin.dll\" /seed'\n\n  IdentityServer8.Admin.api:\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n\n  higginssoft.identityserver4.sts.identity:\n    volumes:\n      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro\n"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3.4'\nservices:\n  nginx-proxy:\n    image: jwilder/nginx-proxy\n    container_name: nginx\n    ports:\n      - '80:80'\n      - '443:443'\n    volumes:\n      - '/var/run/docker.sock:/tmp/docker.sock:ro'\n      - './shared/nginx/vhost.d:/etc/nginx/vhost.d'\n      - './shared/nginx/certs:/etc/nginx/certs:ro'\n    networks:\n      proxy: null\n      identityserverui:\n        aliases:\n          - sts.higginssoft.local\n          - admin.higginssoft.local\n          - admin-api.higginssoft.local\n    restart: always\n  IdentityServer8.Admin:\n    image: '${DOCKER_REGISTRY-}higginssoft-identityserver4-admin'\n    build:\n      context: .\n      dockerfile: src/IdentityServer8.Admin/Dockerfile\n    container_name: higginssoft-identityserver4-admin\n    environment:\n      - VIRTUAL_HOST=admin.higginssoft.local\n      - 'ConnectionStrings__ConfigurationDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__PersistedGrantDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__IdentityDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__AdminLogDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__AdminAuditLogDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__DataProtectionDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'AdminConfiguration__IdentityAdminBaseUrl=https://admin.higginssoft.local'\n      - 'AdminConfiguration__IdentityAdminRedirectUri=https://admin.higginssoft.local/signin-oidc'\n      - 'AdminConfiguration__IdentityServerBaseUrl=https://sts.higginssoft.local'\n      - AdminConfiguration__RequireHttpsMetadata=false\n      - 'IdentityServerData__Clients__0__ClientUri=https://admin.higginssoft.local'\n      - 'IdentityServerData__Clients__0__RedirectUris__0=https://admin.higginssoft.local/signin-oidc'\n      - 'IdentityServerData__Clients__0__FrontChannelLogoutUri=https://admin.higginssoft.local/signin-oidc'\n      - 'IdentityServerData__Clients__0__PostLogoutRedirectUris__0=https://admin.higginssoft.local/signout-callback-oidc'\n      - 'IdentityServerData__Clients__0__AllowedCorsOrigins__0=https://admin.higginssoft.local'\n      - 'IdentityServerData__Clients__1__RedirectUris__0=https://admin-api.higginssoft.local/swagger/oauth2-redirect.html'\n      - 'Serilog__WriteTo__1__Args__connectionString=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - DockerConfiguration__UpdateCaCertificate=true\n      - ASPNETCORE_ENVIRONMENT=Development\n    command: dotnet IdentityServer8.Admin.dll /seed\n    depends_on:\n      - db\n      - higginssoft.identityserver4.sts.identity\n    volumes:\n      - './shared/serilog.json:/app/serilog.json'\n      - './shared/identitydata.json:/app/identitydata.json'\n      - './shared/identityserverdata.json:/app/identityserverdata.json'\n      - './shared/nginx/certs/cacerts.crt:/usr/local/share/ca-certificates/cacerts.crt'\n    networks:\n      identityserverui: null\n  IdentityServer8.Admin.api:\n    image: '${DOCKER_REGISTRY-}higginssoft-identityserver4-admin-api'\n    build:\n      context: .\n      dockerfile: src/IdentityServer8.Admin.Api/Dockerfile\n    container_name: higginssoft-identityserver4-admin-api\n    environment:\n      - VIRTUAL_HOST=admin-api.higginssoft.local\n      - AdminApiConfiguration__RequireHttpsMetadata=false\n      - 'AdminApiConfiguration__ApiBaseUrl=https://admin-api.higginssoft.local'\n      - 'AdminApiConfiguration__IdentityServerBaseUrl=https://sts.higginssoft.local'\n      - 'ConnectionStrings__ConfigurationDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__PersistedGrantDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__IdentityDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__AdminLogDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__AdminAuditLogDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__DataProtectionDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - DockerConfiguration__UpdateCaCertificate=true\n      - ASPNETCORE_ENVIRONMENT=Development\n    volumes:\n      - './shared/serilog.json:/app/serilog.json'\n      - './shared/nginx/certs/cacerts.crt:/usr/local/share/ca-certificates/cacerts.crt'\n    networks:\n      identityserverui: null\n  higginssoft.identityserver4.sts.identity:\n    image: '${DOCKER_REGISTRY-}higginssoft-identityserver4-sts-identity'\n    build:\n      context: .\n      dockerfile: src/IdentityServer8.STS.Identity/Dockerfile\n    container_name: higginssoft-identityserver4-sts-identity\n    environment:\n      - VIRTUAL_HOST=sts.higginssoft.local\n      - 'ConnectionStrings__ConfigurationDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__PersistedGrantDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__IdentityDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'ConnectionStrings__DataProtectionDbConnection=Server=db;Database=IdentityServer8Admin;User Id=sa;Password=${DB_PASSWORD:-Password_123};MultipleActiveResultSets=true'\n      - 'AdminConfiguration__IdentityAdminBaseUrl=https://admin.higginssoft.local'\n      - 'IdentityServerOptions__IssuerUri=https://sts.higginssoft.local'\n      - IdentityServerOptions__Events__RaiseErrorEvents=true\n      - IdentityServerOptions__Events__RaiseInformationEvents=true\n      - IdentityServerOptions__Events__RaiseFailureEvents=true\n      - IdentityServerOptions__Events__RaiseSuccessEvents=true\n      - DockerConfiguration__UpdateCaCertificate=true\n      - ASPNETCORE_ENVIRONMENT=Development\n    depends_on:\n      - db\n    volumes:\n      - './shared/serilog.json:/app/serilog.json'\n      - './shared/nginx/certs/cacerts.crt:/usr/local/share/ca-certificates/cacerts.crt'\n    networks:\n      identityserverui:\n        aliases:\n          - sts.higginssoft.local\n  db:\n    image: 'mcr.microsoft.com/mssql/server:2017-CU20-ubuntu-16.04'\n    ports:\n      - '7900:1433'\n    container_name: higginssoft-identityserver4-db\n    environment:\n      SA_PASSWORD: '${DB_PASSWORD:-Password_123}'\n      ACCEPT_EULA: 'Y'\n    volumes:\n      - 'dbdata:/var/opt/mssql'\n    networks:\n      identityserverui: null\nvolumes:\n  dbdata:\n    driver: local\nnetworks:\n  proxy:\n    driver: bridge\n  identityserverui:\n    driver: bridge\n"
  },
  {
    "path": "docs/CHANGELOG.md",
    "content": "# Change Log\nAll notable changes to this project will be documented in this file.\n \nThe format is based on [Keep a Changelog](http://keepachangelog.com/)\nand this project adheres to [Semantic Versioning 2](http://semver.org/).\n \n## [Unreleased] - 2024-02-17\n\n- Current templates and quickstarts being added to seperate template and quickstart repositories to continue previous version functionality.\n- DotNet tool to install template currently under development.\n- \n## [8.0.4] - 2024-02-17\n\nIdentity Server 8.0.4 is a security release that addresses hundreds of security vulnerabilities in the IdentityServer8 code base. We recommend that you update to this version.\n\n- Fix over 100+ security vulnerabilities in the IdentityServer8 code base:\n - #17 Unsafe expansion of self-closing HTML tag\n - #18 URL redirection from remote source\n - #19 DOM text reinterpreted as HTML\n - #20 Incomplete string escaping or encoding\n - #21 Inefficient regular expression bug dependencies\n - #22 Bad HTML filtering regexp bug dependencies\n - #23 User-controlled bypass of sensitive method bug\n - #24 Unsafe jQuery plugins bug dependencies\n\nAdditional the codebase has been refactored to use the latest DotNet 8 features and best practices. \n\nThis includes refactroing in #25 and consolidation of reused code that remove some nearly 1 million lines of code from the base.:\n- Convert Top Level usings\n- Convert Implicit usings.\n- Samples use shared API and MVC projects to reduce code duplication and need to maintain dozens of copies of the same code.\n\n## [8.0.3] - 2024-02-12\n\n- Security Updates: Addtional priority critical security patches addressing issues outline in #9 and #10.\n - [Security: User-controlled bypass of sensitive method] - Login Controller and view have have explicit methods to handle login and cancel to address User-controlled bypass of sensitive method\n - [Security: Logging of user-controlled data] - Unsanitized user input could be used to forge logs and inject arbitrary commands, including server side includes, xss and sql injection into log files.\n- [Maitenance]: Removed over half a million lines of code from the orginal Identity Server 4 code base using packages and libaries.\n - This will allow for easier maintenance and updates to the code base.\n - Developrs can now focus on the core functionality of Identity Server 8 and use LibMan to manage client side packages and keep packages up to date.\n- Documentation Website: identityserver8.readthedocs.io has been created and is now the official documentation website for IdentityServer8\n- Gitter: A Gitter chat room has been created for IdentityServer8. You can join the chat at https://app.gitter.im/#/room/#identityserver8:gitter.im\n- Framework Upgrade: Upgrade Samples, including Clients, Quickstarts, and Key Management, to use DotNet 8 sdk style.\n- [Quickstarts] (https://github.com/alexhiggins732/IdentityServer8/tree/master/samples/Quickstarts) - Updated Quickstart samples to use Dotnet 8 startup with implicit usings and minimal Api.\n- [Clients] (https://github.com/alexhiggins732/IdentityServer8/tree/master/samples/Clients) - Updated client samples to use Dotnet 8 startup with implicit usings and minimal Api.\n- [Key Management] (https://github.com/alexhiggins732/IdentityServer8/tree/master/samples/KeyManagement) - Updated Key management samples to use Dotnet 8 startup with implicit usings and minimal Api. Changed default Entity Framework storage to file system storage as original Key Management is a paid solution. Roadmap: Add DbContext implementation fof key management.\n- Client Side Packages: Client Side packages have now been ignored in source and are now installed using LibMan during the build process. This will allow for easier updates and management of client side packages.\n\n## [8.0.2] - 2024-02-12\n\n- Security Updates: Addtional priority critical security patches addressing issues outline in #9 and #10.\n\n## [8.0.1] - 2024-02-10\n \n- Security Update: High priority critical security patches addressing issues outline in #9 and #10.\n\n \n### Added\n- `IdentityServer8.Security` nuget packages with services to sanitize user input including html, json, xml, javascript, scripts, urls, logs, css, and style sheets.\n\n### Changed\n- [Account Login Controller] (https://github.com/alexhiggins732/IdentityServer8/issues/9) \n- [Account Login View] (https://github.com/alexhiggins732/IdentityServer8/issues/9)  \n \n### Fixed\n- [Security: User-controlled bypass of sensitive method]\n  Login Controller and view have have explicit methods to handle login and cancel to address User-controlled bypass of sensitive method\n- [Security: Logging of user-controlled data]\n  Unsanitized user input could be used to forge logs and inject arbitrary commands, including server side includes, xss and sql injection into log files.\n  \n## [8.0.1] - 2024-02-10\n  \nUpdated build scripts to use Git Flow branching for SemVer2 compatible nuget packages.\n \n### Added\n\n- CodeQl Security scanning\n- Dependabot Package scanning. \n### Changed\n  \n- [IdentityServer8 8.0.1 changes]https://github.com/alexhiggins732/IdentityServer8/pull/7) \n\n### Fixed\n \n- Nuget Package version conflicts.\n \n## [8.0.0] - 2024-02-09\n \n### Added\nBuild scripts and readme documentation for initial port from Identity Server 4 and Identity Server 4 Admin   \n### Changed\nUpgraded Main Identity Server projects and Nuget packages to DotNet 8 \n### Fixed\n \n- Changed mixed dependencies on `System.Text.Json` and `Newtonsoft.Json` to use `System.Text.Json` which resolved several bugs.\n- Change package dependencies and version requirements to run on the latest DotNet 8 packages, resolving many security vulnerablities."
  },
  {
    "path": "docs/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = _build\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  applehelp  to make an Apple Help Book\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  epub3      to make an epub3\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  latexpdfja to make LaTeX files and run them through platex/dvipdfmx\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\t@echo \"  coverage   to run coverage check of the documentation (if enabled)\"\n\t@echo \"  dummy      to check syntax errors of document sources\"\n\n.PHONY: clean\nclean:\n\trm -rf $(BUILDDIR)/*\n\n.PHONY: html\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\n.PHONY: dirhtml\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\n.PHONY: singlehtml\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\n.PHONY: pickle\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\n.PHONY: json\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\n.PHONY: htmlhelp\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\n.PHONY: qthelp\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/IdentityServer8.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/IdentityServer8.qhc\"\n\n.PHONY: applehelp\napplehelp:\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\n.PHONY: devhelp\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/IdentityServer8\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/IdentityServer8\"\n\t@echo \"# devhelp\"\n\n.PHONY: epub\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\n.PHONY: epub3\nepub3:\n\t$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3\n\t@echo\n\t@echo \"Build finished. The epub3 file is in $(BUILDDIR)/epub3.\"\n\n.PHONY: latex\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\n.PHONY: latexpdf\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\n.PHONY: latexpdfja\nlatexpdfja:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\n.PHONY: text\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\n.PHONY: man\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\n.PHONY: texinfo\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\n.PHONY: info\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\n.PHONY: gettext\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\n.PHONY: changes\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\n.PHONY: linkcheck\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\n.PHONY: doctest\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\n.PHONY: coverage\ncoverage:\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\n.PHONY: xml\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\n.PHONY: pseudoxml\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n\n.PHONY: dummy\ndummy:\n\t$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy\n\t@echo\n\t@echo \"Build finished. Dummy builder generates no files.\"\n"
  },
  {
    "path": "docs/autobuild.bat",
    "content": "sphinx-autobuild.exe . .\\_build\\html\\"
  },
  {
    "path": "docs/build-documentation.ps1",
    "content": ".\\docker-build.ps1\ndocker run --rm -v .:/docs sphinx-doc/sphinx_rtd_theme make html\n"
  },
  {
    "path": "docs/conf.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# IdentityServer8 documentation build configuration file, created by\n# sphinx-quickstart on Wed Jul 20 08:57:27 2016.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\n# import os\n# import sys\n# sys.path.insert(0, os.path.abspath('.'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#\n# needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx_rtd_theme',\n]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\n# source_suffix = ['.rst', '.md']\n\n# markdown support\n#from recommonmark.parser import CommonMarkParser\n\n#source_parsers = {\n#    '.md': CommonMarkParser,\n#}\n\nsource_suffix = ['.rst']\n\n\n# The encoding of source files.\n#\n# source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = 'IdentityServer8'\ncopyright = '2024 HigginsSoft, Alexander Higgins'\nauthor = 'Alexander Higgins'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '8.0.0'\n# The full version, including alpha/beta/rc tags.\nrelease = '8.0.4'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#\n# today = ''\n#\n# Else, today_fmt is used as the format for a strftime call.\n#\n# today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#\n# default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#\n# add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#\n# add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#\n# show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'default'\nhighlight_language = 'csharp'\n\n# A list of ignored prefixes for module index sorting.\n# modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n# keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = False\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\nhtml_theme = 'sphinx_rtd_theme'\n\n# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org\nimport os\non_rtd = os.environ.get('READTHEDOCS', None) == 'True'\nif not on_rtd:  # only import and set the theme if we're building docs locally\n#    import sphinx_rtd_theme\n   html_theme = 'sphinx_rtd_theme'\n#    html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]\n\n# otherwise, readthedocs.org uses their theme by default, so no need to specify it\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#\n# html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n# html_theme_path = []\n\n# The name for this set of Sphinx documents.\n# \"<project> v<release> documentation\" by default.\n#\n# html_title = 'IdentityServer8 v1.0.0'\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#\n# html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#\n# html_logo = None\n\n# The name of an image file (relative to this directory) to use as a favicon of\n# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#\nhtml_favicon = 'favicon.ico'\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#\n# html_extra_path = []\n\n# If not None, a 'Last updated on:' timestamp is inserted at every page\n# bottom, using the given strftime format.\n# The empty string is equivalent to '%b %d, %Y'.\n#\n# html_last_updated_fmt = None\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#\n# html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#\n# html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#\n# html_additional_pages = {}\n\n# If false, no module index is generated.\n#\n# html_domain_indices = True\n\n# If false, no index is generated.\n#\n# html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#\n# html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#\n# html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#\n# html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#\n# html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#\n# html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n# html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'\n#\n# html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# 'ja' uses this config value.\n# 'zh' user can custom change `jieba` dictionary path.\n#\n# html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#\n# html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'IdentityServer8doc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n     # The paper size ('letterpaper' or 'a4paper').\n     #\n     # 'papersize': 'letterpaper',\n\n     # The font size ('10pt', '11pt' or '12pt').\n     #\n     # 'pointsize': '10pt',\n\n     # Additional stuff for the LaTeX preamble.\n     #\n     # 'preamble': '',\n\n     # Latex figure (float) alignment\n     #\n     # 'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    (master_doc, 'IdentityServer8.tex', 'IdentityServer8 Documentation',\n     'HigginsSoft, Alexander Higgins', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#\n# latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#\n# latex_use_parts = False\n\n# If true, show page references after internal links.\n#\n# latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#\n# latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#\n# latex_appendices = []\n\n# It false, will not define \\strong, \\code, \titleref, \\crossref ... but only\n# \\sphinxstrong, ..., \\sphinxtitleref, ... To help avoid clash with user added\n# packages.\n#\n# latex_keep_old_macro_names = True\n\n# If false, no module index is generated.\n#\n# latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'IdentityServer8', 'IdentityServer8 Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#\n# man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n    (master_doc, 'IdentityServer8', 'IdentityServer8 Documentation',\n     author, 'IdentityServer8', 'One line description of project.',\n     'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#\n# texinfo_appendices = []\n\n# If false, no module index is generated.\n#\n# texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#\n# texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#\n# texinfo_no_detailmenu = False\n"
  },
  {
    "path": "docs/docker-build.ps1",
    "content": "docker build -t sphinx-doc/sphinx_rtd_theme ."
  },
  {
    "path": "docs/dockerfile",
    "content": "FROM sphinxdoc/sphinx\n\nRUN pip install sphinx_rtd_theme"
  },
  {
    "path": "docs/endpoints/authorize.rst",
    "content": "Authorize Endpoint\n==================\n\nThe authorize endpoint can be used to request tokens or authorization codes via the browser.\nThis process typically involves authentication of the end-user and optionally consent.\n\n.. Note:: IdentityServer supports a subset of the OpenID Connect and OAuth 2.0 authorize request parameters. For a full list, see `here <https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest>`_.\n\n``client_id``\n    identifier of the client (required).\n``request``\n    instead of providing all parameters as individual query string parameters, you can provide a subset or all of them as a JWT\n``request_uri``\n    URL of a pre-packaged JWT containing request parameters\n``scope``\n    one or more registered scopes (required)\n``redirect_uri`` \n    must exactly match one of the allowed redirect URIs for that client (required)\n``response_type`` \n    ``id_token`` requests an identity token (only identity scopes are allowed)\n\n    ``token`` requests an access token (only resource scopes are allowed)\n\n    ``id_token token`` requests an identity token and an access token\n\n    ``code`` requests an authorization code\n\n    ``code id_token`` requests an authorization code and identity token\n\n    ``code id_token token`` requests an authorization code, identity token and access token\n    \n``response_mode``\n    ``form_post`` sends the token response as a form post instead of a fragment encoded redirect (optional)\n``state`` \n    identityserver will echo back the state value on the token response, \n    this is for round tripping state between client and provider, correlating request and response and CSRF/replay protection. (recommended)\n``nonce`` \n    identityserver will echo back the nonce value in the identity token, this is for replay protection)\n\n    *Required for identity tokens via implicit grant.*\n``prompt``\n    ``none`` no UI will be shown during the request. If this is not possible (e.g. because the user has to sign in or consent) an error is returned\n    \n    ``login`` the login UI will be shown, even if the user is already signed-in and has a valid session\n``code_challenge``\n    sends the code challenge for PKCE\n``code_challenge_method``\n    ``plain`` indicates that the challenge is using plain text (not recommended)\n    ``S256`` indicates the challenge is hashed with SHA256\n``login_hint``\n    can be used to pre-fill the username field on the login page\n``ui_locales``\n    gives a hint about the desired display language of the login UI\n``max_age``\n    if the user's logon session exceeds the max age (in seconds), the login UI will be shown\n``acr_values``\n    allows passing in additional authentication related information - identityserver special cases the following proprietary acr_values:\n        \n        ``idp:name_of_idp`` bypasses the login/home realm screen and forwards the user directly to the selected identity provider (if allowed per client configuration)\n        \n        ``tenant:name_of_tenant`` can be used to pass a tenant name to the login UI\n\n**Example**\n\n::\n\n    GET /connect/authorize?\n        client_id=client1&\n        scope=openid email api1&\n        response_type=id_token token&\n        redirect_uri=https://myapp/callback&\n        state=abc&\n        nonce=xyz \n\n(URL encoding removed, and line breaks added for readability)\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ client library to programmatically create authorize requests .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/authorize.html>`_.\n"
  },
  {
    "path": "docs/endpoints/device_authorization.rst",
    "content": "Device Authorization Endpoint\n=============================\n\nThe device authorization endpoint can be used to request device and user codes.\nThis endpoint is used to start the device flow authorization process.\n\n.. Note:: The URL for the end session endpoint is available via the :ref:`discovery endpoint <refDiscovery>`.\n\n``client_id``\n    client identifier (required)\n``client_secret``\n    client secret either in the post body, or as a basic authentication header. Optional.\n``scope``\n    one or more registered scopes. If not specified, a token for all explicitly allowed scopes will be issued.\n\nExample\n^^^^^^^\n\n::\n\n    POST /connect/deviceauthorization\n\n        client_id=client1&\n        client_secret=secret&\n        scope=openid api1\n\n(Form-encoding removed and line breaks added for readability)\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ client library to programmatically access the device authorization endpoint from .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/device_authorize.html>`_."
  },
  {
    "path": "docs/endpoints/discovery.rst",
    "content": ".. _refDiscovery:\nDiscovery Endpoint\n==================\n\nThe discovery endpoint can be used to retrieve metadata about your IdentityServer - \nit returns information like the issuer name, key material, supported scopes etc. See the `spec <https://openid.net/specs/openid-connect-discovery-1_0.html>`_ for more details.\n\nThe discovery endpoint is available via `/.well-known/openid-configuration` relative to the base address, e.g.::\n\n    https://demo.identityserver8.io/.well-known/openid-configuration\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ client library to programmatically access the discovery endpoint from .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/discovery.html>`_.\n"
  },
  {
    "path": "docs/endpoints/endsession.rst",
    "content": ".. _refEndSession:\nEnd Session Endpoint\n====================\n\nThe end session endpoint can be used to trigger single sign-out (see `spec <https://openid.net/specs/openid-connect-rpinitiated-1_0.html>`_).\n\nTo use the end session endpoint a client application will redirect the user's browser to the end session URL.\nAll applications that the user has logged into via the browser during the user's session can participate in the sign-out.\n\n.. Note:: The URL for the end session endpoint is available via the :ref:`discovery endpoint <refDiscovery>`.\n\nParameters\n^^^^^^^^^^\n\n**id_token_hint**\n\nWhen the user is redirected to the endpoint, they will be prompted if they really want to sign-out. \nThis prompt can be bypassed by a client sending the original *id_token* received from authentication.\nThis is passed as a query string parameter called ``id_token_hint``.\n\n**post_logout_redirect_uri**\n\nIf a valid ``id_token_hint`` is passed, then the client may also send a ``post_logout_redirect_uri`` parameter.\nThis can be used to allow the user to redirect back to the client after sign-out.\nThe value must match one of the client's pre-configured `PostLogoutRedirectUris` (:ref:`client docs <refClient>`).\n\n**state**\n\nIf a valid ``post_logout_redirect_uri`` is passed, then the client may also send a ``state`` parameter.\nThis will be returned back to the client as a query string parameter after the user redirects back to the client.\nThis is typically used by clients to round-trip state across the redirect.\n\nExample\n^^^^^^^\n\n::\n\n    GET /connect/endsession?id_token_hint=eyJhbGciOiJSUzI1NiIsImtpZCI6IjdlOGFkZmMzMjU1OTEyNzI0ZDY4NWZmYmIwOThjNDEyIiwidHlwIjoiSldUIn0.eyJuYmYiOjE0OTE3NjUzMjEsImV4cCI6MTQ5MTc2NTYyMSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoianNfb2lkYyIsIm5vbmNlIjoiYTQwNGFjN2NjYWEwNGFmNzkzNmJjYTkyNTJkYTRhODUiLCJpYXQiOjE0OTE3NjUzMjEsInNpZCI6IjI2YTYzNWVmOTQ2ZjRiZGU3ZWUzMzQ2ZjFmMWY1NTZjIiwic3ViIjoiODg0MjExMTMiLCJhdXRoX3RpbWUiOjE0OTE3NjUzMTksImlkcCI6ImxvY2FsIiwiYW1yIjpbInB3ZCJdfQ.STzOWoeVYMtZdRAeRT95cMYEmClixWkmGwVH2Yyiks9BETotbSZiSfgE5kRh72kghN78N3-RgCTUmM2edB3bZx4H5ut3wWsBnZtQ2JLfhTwJAjaLE9Ykt68ovNJySbm8hjZhHzPWKh55jzshivQvTX0GdtlbcDoEA1oNONxHkpDIcr3pRoGi6YveEAFsGOeSQwzT76aId-rAALhFPkyKnVc-uB8IHtGNSyRWLFhwVqAdS3fRNO7iIs5hYRxeFSU7a5ZuUqZ6RRi-bcDhI-djKO5uAwiyhfpbpYcaY_TxXWoCmq8N8uAw9zqFsQUwcXymfOAi2UF3eFZt02hBu-shKA&post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A7017%2Findex.html\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ client library to programmatically create end_session requests .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/end_session.html>`_.\n"
  },
  {
    "path": "docs/endpoints/introspection.rst",
    "content": "Introspection Endpoint\n======================\n\nThe introspection endpoint is an implementation of `RFC 7662 <https://tools.ietf.org/html/rfc7662>`_.\n\nIt can be used to validate reference tokens (or JWTs if the consumer does not have support for appropriate JWT or cryptographic libraries).\nThe introspection endpoint requires authentication - since the client of an introspection endpoint is an API, you configure the secret on the ``ApiResource``.\n\nExample\n^^^^^^^\n\n::\n\n\n    POST /connect/introspect\n    Authorization: Basic xxxyyy\n\n    token=<token>\n\n\nA successful response will return a status code of 200 and either an active or inactive token::\n\n\n    {\n        \"active\": true,\n        \"sub\": \"123\"\n    }\n\n\nUnknown or expired tokens will be marked as inactive::\n\n\n    {\n        \"active\": false,\n    }\n\n\nAn invalid request will return a 400, an unauthorized request 401.\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ client library to programmatically access the introspection endpoint from .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/introspection.html>`_."
  },
  {
    "path": "docs/endpoints/revocation.rst",
    "content": "Revocation Endpoint\n===================\n\nThis endpoint allows revoking access tokens (reference tokens only) and refresh token. \nIt implements the token revocation specification `(RFC 7009) <https://tools.ietf.org/html/rfc7009>`_.\n\n``token``\n    the token to revoke (required)\n``token_type_hint``\n    either ``access_token`` or ``refresh_token`` (optional)\n\nExample\n^^^^^^^\n\n::\n\n    POST /connect/revocation HTTP/1.1\n    Host: server.example.com\n    Content-Type: application/x-www-form-urlencoded\n    Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW\n\n    token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ client library to programmatically access the revocation endpoint from .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/revocation.html>`_."
  },
  {
    "path": "docs/endpoints/token.rst",
    "content": "Token Endpoint\n==============\n\nThe token endpoint can be used to programmatically request tokens.\nIt supports the ``password``, ``authorization_code``, ``client_credentials``, ``refresh_token`` and ``urn:ietf:params:oauth:grant-type:device_code`` grant types.\nFurthermore the token endpoint can be extended to support extension grant types.\n\n.. Note:: IdentityServer supports a subset of the OpenID Connect and OAuth 2.0 token request parameters. For a full list, see `here <http://openid.net/specs/openid-connect-core-1_0.html#TokenRequest>`_.\n\n``client_id``\n    client identifier (required – Either in the body or as part of the authorization header.)\n``client_secret``\n    client secret either in the post body, or as a basic authentication header. Optional.\n``grant_type``\n    ``authorization_code``, ``client_credentials``, ``password``, ``refresh_token``, ``urn:ietf:params:oauth:grant-type:device_code`` or custom\n``scope``\n    one or more registered scopes. If not specified, a token for all explicitly allowed scopes will be issued.\n``redirect_uri`` \n    required for the ``authorization_code`` grant type\n``code``\n    the authorization code (required for ``authorization_code`` grant type)\n``code_verifier``\n    PKCE proof key\n``username`` \n    resource owner username (required for ``password`` grant type)\n``password``\n    resource owner password (required for ``password`` grant type)\n``acr_values``\n   allows passing in additional authentication related information for the ``password`` grant type - identityserver special cases the following proprietary acr_values:\n        \n        ``idp:name_of_idp`` bypasses the login/home realm screen and forwards the user directly to the selected identity provider (if allowed per client configuration)\n        \n        ``tenant:name_of_tenant`` can be used to pass a tenant name to the token endpoint\n``refresh_token``\n    the refresh token (required for ``refresh_token`` grant type)\n``device_code``\n    the device code (required for ``urn:ietf:params:oauth:grant-type:device_code`` grant type)\n\nExample\n^^^^^^^\n\n::\n\n    POST /connect/token\n    CONTENT-TYPE application/x-www-form-urlencoded\n\n        client_id=client1&\n        client_secret=secret&\n        grant_type=authorization_code&\n        code=hdh922&\n        redirect_uri=https://myapp.com/callback\n\n(Form-encoding removed and line breaks added for readability)\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel>`_ client library to programmatically access the token endpoint from .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/token.html>`_.\n"
  },
  {
    "path": "docs/endpoints/userinfo.rst",
    "content": "UserInfo Endpoint\n=================\n\nThe UserInfo endpoint can be used to retrieve identity information about a user (see `spec <http://openid.net/specs/openid-connect-core-1_0.html#UserInfo>`_). \n\nThe caller needs to send a valid access token representing the user.\nDepending on the granted scopes, the UserInfo endpoint will return the mapped claims (at least the `openid` scope is required).\n\nExample\n^^^^^^^\n\n::\n\n    GET /connect/userinfo\n    Authorization: Bearer <access_token>\n\n::\n\n    HTTP/1.1 200 OK\n    Content-Type: application/json\n\n    {\n        \"sub\": \"248289761001\",\n        \"name\": \"Bob Smith\",\n        \"given_name\": \"Bob\",\n        \"family_name\": \"Smith\",\n        \"role\": [\n            \"user\",\n            \"admin\"\n        ]\n    }\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ client library to programmatically access the userinfo endpoint from .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/userinfo.html>`_."
  },
  {
    "path": "docs/index.rst",
    "content": "Welcome to IdentityServer8 (latest)\n=============================================\n\n.. image:: images/logo.png\n   :align: center\n\nIdentityServer8 is an OpenID Connect and OAuth 2.0 framework for ASP.NET DotNet 8.\n\nBrowse the latest `IdentityServer8 source code onGitHub <https://github.com/alexhiggins732/IdentityServer8>`_ or download the `latest IdentyServer8 packages <https://www.nuget.org/packages/HigginsSoft.IdentityServer8//>`_ on NuGet.\n\n.. warning:: \n   This is a revival of the archived IdentityServer4 project which started a new `company <https://duendesoftware.com/>`_ as of Oct, 1st 2020. \n   The new Duende IdentityServer is not longer free open source, but now has various commercial licenses and paid upgrade package.\n   IdentityServer8 and dependenices have been upgraded to DotNet 8 and will be maintained by HigginsSoft, Alexander Higgins and the community as an Open Source project. \n\n.. note:: This docs cover the latest version on main branch. This might not be released yet. Use the version picker in the lower left corner to select docs for a specific version.\n\nIt enables the following features in your applications:\n\n\n| **Authentication as a Service** \n| Centralized login logic and workflow for all of your applications (web, native, mobile, services). IdentityServer is an officially `certified <https://openid.net/certification/>`_ implementation of OpenID Connect.\n\n| **Single Sign-on / Sign-out** \n| Single sign-on (and out) over multiple application types.\n\n| **Access Control for APIs** \n| Issue access tokens for APIs for various types of clients, e.g. server to server, web applications, SPAs and native/mobile apps.\n\n| **Federation Gateway**\n| Support for external identity providers like Azure Active Directory, Google, Facebook etc. This shields your applications from the details of how to connect to these external providers.\n\n| **Focus on Customization**\n| The most important part - many aspects of IdentityServer can be customized to fit **your** needs. Since IdentityServer is a framework and not a boxed product or a SaaS, you can write code to adapt the system the way it makes sense for your scenarios.\n\n| **Mature Open Source**\n| IdentityServer uses the permissive `Apache 2 <https://www.apache.org/licenses/LICENSE-2.0>`_ license that allows building commercial products on top of it. It is also part of the `.NET Foundation <https://dotnetfoundation.org/>`_ which provides governance and legal backing.\n\n| **Free and Commercial Support**\n| If you need help building or running your identity platform, :ref:`let us know <refSupport>`. There are several ways we can help you out.\n\n.. toctree::\n   :maxdepth: 3\n   :hidden:\n   :caption: Introduction\n\n   intro/big_picture\n   intro/architecture\n   intro/terminology\n   intro/specs\n   intro/packaging\n   intro/support\n   intro/test\n   intro/contributing\n\n.. toctree::\n   :maxdepth: 3\n   :hidden:\n   :caption: Quickstarts\n\n   quickstarts/0_overview\n   quickstarts/1_client_credentials\n   quickstarts/2_interactive_aspnetcore\n   quickstarts/3_aspnetcore_and_apis\n   quickstarts/4_javascript_client\n   quickstarts/5_entityframework\n   quickstarts/6_aspnet_identity\n   \n.. toctree::\n   :maxdepth: 3\n   :hidden:\n   :caption: Configuration\n\n   configuration/startup\n   configuration/resources\n   configuration/clients\n   configuration/mvc\n   configuration/apis\n\n.. toctree::\n   :maxdepth: 3\n   :hidden:\n   :caption: Topics\n\n   topics/startup\n   topics/resources\n   topics/clients\n   topics/signin\n   topics/signin_external_providers\n   topics/windows\n   topics/signout\n   topics/signout_external_providers\n   topics/signout_federated\n   topics/federation_gateway\n   topics/consent\n   topics/apis\n   topics/deployment\n   topics/logging\n   topics/events\n   topics/crypto\n   topics/grant_types\n   topics/client_authentication\n   topics/extension_grants\n   topics/resource_owner\n   topics/refresh_tokens\n   topics/reference_tokens\n   topics/persisted_grants\n   topics/pop\n   topics/mtls\n   topics/request_object\n   topics/custom_token_request_validation\n   topics/cors\n   topics/discovery\n   topics/add_apis\n   topics/add_protocols\n   topics/tools\n\n.. toctree::\n   :maxdepth: 3\n   :hidden:\n   :caption: Endpoints\n\n   endpoints/discovery\n   endpoints/authorize\n   endpoints/token\n   endpoints/userinfo\n   endpoints/device_authorization\n   endpoints/introspection\n   endpoints/revocation\n   endpoints/endsession\n\n.. toctree::\n   :maxdepth: 3\n   :hidden:\n   :caption: Reference\n\n   reference/options\n   reference/identity_resource\n   reference/api_scope\n   reference/api_resource\n   reference/client\n   reference/grant_validation_result\n   reference/profileservice\n   reference/interactionservice\n   reference/deviceflow_interactionservice\n   reference/ef\n   reference/aspnet_identity\n\n.. toctree::\n   :maxdepth: 3\n   :hidden:\n   :caption: Misc\n\n   misc/training\n   misc/blogs\n   misc/videos\n"
  },
  {
    "path": "docs/intro/big_picture.rst",
    "content": "The Big Picture\n===============\n\nMost modern applications look more or less like this:\n\n.. image:: images/appArch.png\n\nThe most common interactions are:\n\n* Browsers communicate with web applications\n\n* Web applications communicate with web APIs (sometimes on their own, sometimes on behalf of a user)\n\n* Browser-based applications communicate with web APIs\n\n* Native applications communicate with web APIs\n\n* Server-based applications communicate with web APIs\n\n* Web APIs communicate with web APIs (sometimes on their own, sometimes on behalf of a user)\n\nTypically each and every layer (front-end, middle-tier and back-end) has to protect resources and\nimplement authentication and/or authorization – often against the same user store.\n\nOutsourcing these fundamental security functions to a security token service prevents duplicating that functionality across those applications and endpoints.\n\nRestructuring the application to support a security token service leads to the following architecture and protocols:\n\n.. image:: images/protocols.png\n\nSuch a design divides security concerns into two parts:\n\nAuthentication\n^^^^^^^^^^^^^^\nAuthentication is needed when an application needs to know the identity of the current user.\nTypically these applications manage data on behalf of that user and need to make sure that this user can only\naccess the data for which he is allowed. The most common example for that is (classic) web applications –\nbut native and JS-based applications also have a need for authentication.\n\nThe most common authentication protocols are SAML2p, WS-Federation and OpenID Connect – SAML2p being the\nmost popular and the most widely deployed.\n\nOpenID Connect is the newest of the three, but is considered to be the future because it has the\nmost potential for modern applications. It was built for mobile application scenarios right from the start\nand is designed to be API friendly.\n\nAPI Access\n^^^^^^^^^^\nApplications have two fundamental ways with which they communicate with APIs – using the application identity,\nor delegating the user’s identity. Sometimes both methods need to be combined.\n\nOAuth2 is a protocol that allows applications to request access tokens from a security token service and use them\nto communicate with APIs. This delegation reduces complexity in both the client applications as well as the APIs since\nauthentication and authorization can be centralized.\n\nOpenID Connect and OAuth 2.0 – better together\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nOpenID Connect and OAuth 2.0 are very similar – in fact OpenID Connect is an extension on top of OAuth 2.0.\nThe two fundamental security concerns, authentication and API access, are combined into a  single protocol - often with a single round trip to the security token service. \n\nWe believe that the combination of OpenID Connect and OAuth 2.0 is the best approach to secure modern\napplications for the foreseeable future. IdentityServer8 is an implementation of these two protocols and is\nhighly optimized to solve the typical security problems of today’s mobile, native and web applications.\n\nHow IdentityServer8 can help\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIdentityServer is middleware that adds the spec compliant OpenID Connect and OAuth 2.0 endpoints to an arbitrary ASP.NET Core application.\n\nTypically, you build (or re-use) an application that contains a login and logout page (and maybe consent - depending on your needs),\nand the IdentityServer middleware adds the necessary protocol heads to it, so that client applications can talk to it using those standard protocols.\n\n.. image:: images/middleware.png\n\nThe hosting application can be as complex as you want, but we typically recommend to keep the attack surface as small as possible by including\nauthentication related UI only.\n"
  },
  {
    "path": "docs/intro/contributing.rst",
    "content": "Contributing\n============\nWe are very open to community contributions, but there are a couple of guidelines you should follow so we can handle this without too much effort.\n\nHow to contribute?\n^^^^^^^^^^^^^^^^^^\nThe easiest way to contribute is to open an issue and start a discussion. \nThen we can decide if and how a feature or a change could be implemented. \nIf you should submit a pull request with code changes, start with a description, only make the minimal changes to start with and provide tests that cover those changes.\n\nAlso read this first: `Being a good open source citizen <https://hackernoon.com/being-a-good-open-source-citizen-9060d0ab9732#.x3hocgw85>`_\n\nGeneral feedback and discussions?\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nPlease start a discussion on the `core repo issue tracker <https://github.com/alexhiggins732/IdentityServer8/issues>`_.\n\nBugs and feature requests?\n^^^^^^^^^^^^^^^^^^^^^^^^^^\nPlease log a new issue in the appropriate GitHub repo:\n\n* `Core <https://github.com/alexhiggins732/IdentityServer8>`_\n* `AccessTokenValidation <https://github.com/alexhiggins732/IdentityServer8.AccessTokenValidation>`_\n\nContributing code and content\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou will need to sign a Contributor License Agreement before you can contribute any code or content.\nThis is an automated process that will start after you opened a pull request. \n\nContribution projects\n^^^^^^^^^^^^^^^^^^^^^\nWe very much appreciate if you start a contribution project (e.g. support for Database X or Configuration Store Y). \nTell us about it so we can tweet and link it in our docs.\n\nWe generally don't want to take ownership of those contribution libraries, we are already really busy supporting the core projects.\n\n**Naming conventions**\n\nAs of October 2017, the IdentityServer8.* nuget namespace is reserved for our packages. Please use the following naming conventions:\n\n``YourProjectName.IdentityServer8``\n\nor\n\n``IdentityServer8.Contrib.YourProjectName``\n"
  },
  {
    "path": "docs/intro/packaging.rst",
    "content": "Packaging and Builds\n====================\n\nIdentityServer consists of a number of nuget packages.\n\nIdentityServer8 main repo\n^^^^^^^^^^^^^^^\n`github <https://github.com/alexhiggins732/IdentityServer8>`_\n\nContains the core IdentityServer object model, services and middleware as well as the EntityFramework and ASP.NET Identity integration.\n\nnugets:\n\n* `HigginsSoft.IdentityServer8 <https://www.nuget.org/packages/HigginsSoft.IdentityServer8/>`_\n* `HigginsSoft.IdentityServer8.EntityFramework <https://www.nuget.org/packages/HigginsSoft.IdentityServer8.EntityFramework>`_\n* `HigginsSoft.IdentityServer8.AspNetIdentity <https://www.nuget.org/packages/HigginsSoft.IdentityServer8.AspNetIdentity>`_\n\nQuickstart UI\n^^^^^^^^^^^^^\n`github <https://github.com/alexhiggins732/IdentityServer8.Quickstart.UI>`_\n\nContains a simple starter UI including login, logout and consent pages.\n\nAccess token validation handler\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n`nuget <https://www.nuget.org/packages/HigginsSoft.IdentityServer8.AccessTokenValidation>`_ | `github <https://github.com/alexhiggins732/IdentityServer8.AccessTokenValidation>`_\n\nASP.NET Core authentication handler for validating tokens in APIs. The handler allows supporting both JWT and reference tokens in the same API.\n\nTemplates\n^^^^^^^^^\n`nuget <https://www.nuget.org/packages/HigginsSoft.IdentityServer8.Templates>`_ | `github <https://github.com/alexhiggins732/IdentityServer8.Templates>`_\n\nContains templates for the dotnet CLI.\n\nDev builds\n^^^^^^^^^^\nIn addition we publish CI builds to our package repository.\nAdd the following ``nuget.config`` to your project::\n\n    <?xml version=\"1.0\" encoding=\"utf-8\"?>\n        <configuration>\n            <packageSources>\n                <clear />\n                <add key=\"IdentityServer CI\" value=\"https://www.myget.org/F/identity/api/v3/index.json\" />\n            </packageSources>\n        </configuration>\n"
  },
  {
    "path": "docs/intro/specs.rst",
    "content": "Supported Specifications\n========================\n\nIdentityServer implements the following specifications:\n\nOpenID Connect\n^^^^^^^^^^^^^^\n\n* OpenID Connect Core 1.0 (`spec <http://openid.net/specs/openid-connect-core-1_0.html>`_)\n* OpenID Connect Discovery 1.0 (`spec <http://openid.net/specs/openid-connect-discovery-1_0.html>`_)\n* OpenID Connect RP-Initiated Logout 1.0 - draft 01 (`spec <https://openid.net/specs/openid-connect-rpinitiated-1_0.html>`_)\n* OpenID Connect Session Management 1.0 - draft 30 (`spec <http://openid.net/specs/openid-connect-session-1_0.html>`_)\n* OpenID Connect Front-Channel Logout 1.0 - draft 04 (`spec <https://openid.net/specs/openid-connect-frontchannel-1_0.html>`_)\n* OpenID Connect Back-Channel Logout 1.0 - draft 06 (`spec <https://openid.net/specs/openid-connect-backchannel-1_0.html>`_)\n\nOAuth 2.0\n^^^^^^^^^\n\n* OAuth 2.0 (`RFC 6749 <http://tools.ietf.org/html/rfc6749>`_)\n* OAuth 2.0 Bearer Token Usage (`RFC 6750 <http://tools.ietf.org/html/rfc6750>`_)\n* OAuth 2.0 Multiple Response Types (`spec <http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html>`_)\n* OAuth 2.0 Form Post Response Mode (`spec <http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html>`_)\n* OAuth 2.0 Token Revocation (`RFC 7009 <https://tools.ietf.org/html/rfc7009>`_)\n* OAuth 2.0 Token Introspection (`RFC 7662 <https://tools.ietf.org/html/rfc7662>`_)\n* Proof Key for Code Exchange (`RFC 7636 <https://tools.ietf.org/html/rfc7636>`_)\n* JSON Web Tokens for Client Authentication (`RFC 7523 <https://tools.ietf.org/html/rfc7523>`_)\n* OAuth 2.0 Device Authorization Grant (`RFC 8628 <https://tools.ietf.org/html/rfc8628>`_)\n* OAuth 2.0 Mutual TLS Client Authentication and Certificate-Bound Access Tokens (`RFC 8705 <https://tools.ietf.org/html/rfc8705>`_)\n* JWT Secured Authorization Request (`draft <https://tools.ietf.org/html/draft-ietf-oauth-jwsreq>`_)\n"
  },
  {
    "path": "docs/intro/support.rst",
    "content": ".. _refSupport:\nSupport and Consulting Options\n==============================\n\nWe have several free and commercial support and consulting options for IdentityServer.\n\nFree support\n^^^^^^^^^^^^\nFree support is community-based and uses public forums\n\n**StackOverflow**\n\nThere's an ever growing community of people using IdentityServer that monitor questions on StackOverflow. \nIf time permits, we also try to answer as many questions as possible\n\nYou can subscribe to all IdentityServer8 related questions using this feed:\n\nhttps://stackoverflow.com/questions/tagged/?tagnames=IdentityServer8&sort=newest\n\nPlease use the ``IdentityServer8`` tag when asking new questions\n\n**Gitter**\n\nYou can chat with other IdentityServer8 users in our Gitter chat room:\n\nhttps://app.gitter.im/#/room/#identityserver8:gitter.im\n\n**Reporting a bug**\n\nIf you think you have found a bug or unexpected behavior, please open an issue on the Github `issue tracker <https://github.com/alexhiggins732/IdentityServer8/issues>`_.\nWe try to get back to you ASAP. Please understand that we also have day jobs, and might be too busy to reply immediately.\n\nAlso check the `contribution <https://github.com/alexhiggins732/IdentityServer8/blob/dev/CONTRIBUTING.md>`_ guidelines before posting.\n\nCommercial support\n^^^^^^^^^^^^^^^^^^\nWe are doing consulting, mentoring and custom software development around identity & access control architecture in general, and IdentityServer in particular.\nPlease `get in touch <mailto:contact@identityserver8.io>`_ with us to discuss possible options.\n\n**Training**\n\nWe are regularly doing workshops around identity & access control for modern applications.\nCheck the agenda and upcoming public dates  `here <https://identityserver8.io/training>`_.\nWe can also perform the training privately at your company. \n`Contact us <mailto:contact@identityserver8.io>`_ to request the training on-site. \n\n**AdminUI, WS-Federation, SAML2p, and FIDO2 support**\n\nThere are commercial add-on products available from our partners, Rock Solid Knowledge, on `identityserver8.com <https://www.identityserver8.com/products>`_.\n"
  },
  {
    "path": "docs/intro/terminology.rst",
    "content": "Terminology\n===========\n\nThe specs, documentation and object model use a certain terminology that you should be aware of.\n\n.. image:: images/terminology.png\n\nIdentityServer\n^^^^^^^^^^^^^^\nIdentityServer is an OpenID Connect provider - it implements the OpenID Connect and OAuth 2.0 protocols.\n\nDifferent literature uses different terms for the same role - you probably also find security token service,\nidentity provider, authorization server, IP-STS and more.\n\nBut they are in a nutshell all the same: a piece of software that issues security tokens to clients.\n\nIdentityServer has a number of jobs and features - including:\n\n* protect your resources\n\n* authenticate users using a local account store or via an external identity provider\n\n* provide session management and single sign-on\n\n* manage and authenticate clients\n\n* issue identity and access tokens to clients\n\n* validate tokens\n\nUser\n^^^^\nA user is a human that is using a registered client to access resources.\n\nClient\n^^^^^^\nA client is a piece of software that requests tokens from IdentityServer - either for authenticating a user (requesting an identity token) \nor for accessing a resource (requesting an access token). A client must be first registered with IdentityServer before it can request tokens.\n\nExamples for clients are web applications, native mobile or desktop applications, SPAs, server processes etc.\n\nResources\n^^^^^^^^^\nResources are something you want to protect with IdentityServer - either identity data of your users, or APIs. \n\nEvery resource has a unique name - and clients use this name to specify to which resources they want to get access to.\n\n**Identity data**\nIdentity information (aka claims) about a user, e.g. name or email address.\n\n**APIs**\nAPIs resources represent functionality a client wants to invoke - typically modelled as Web APIs, but not necessarily.\n\nIdentity Token\n^^^^^^^^^^^^^^\nAn identity token represents the outcome of an authentication process. It contains at a bare minimum an identifier for the user \n(called the `sub` aka subject claim) and information about how and when the user authenticated.  It can contain additional identity data.\n\nAccess Token\n^^^^^^^^^^^^\nAn access token allows access to an API resource. Clients request access tokens and forward them to the API. \nAccess tokens contain information about the client and the user (if present).\nAPIs use that information to authorize access to their data.\n"
  },
  {
    "path": "docs/intro/test.rst",
    "content": "Demo Server\n===========\n\nYou can try IdentityServer8 with your favourite client library. We have a test instance at `demo.identityserver8.io <https://demo.identityserver8.io>`_. \nOn the main page you can find instructions on how to configure your client and how to call an API.\n"
  },
  {
    "path": "docs/make.bat",
    "content": "@ECHO OFF\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset BUILDDIR=_build\nset ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .\nset I18NSPHINXOPTS=%SPHINXOPTS% .\nif NOT \"%PAPER%\" == \"\" (\n\tset ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\n\tset I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\n)\n\nif \"%1\" == \"\" goto help\n\nif \"%1\" == \"help\" (\n\t:help\n\techo.Please use `make ^<target^>` where ^<target^> is one of\n\techo.  html       to make standalone HTML files\n\techo.  dirhtml    to make HTML files named index.html in directories\n\techo.  singlehtml to make a single large HTML file\n\techo.  pickle     to make pickle files\n\techo.  json       to make JSON files\n\techo.  htmlhelp   to make HTML files and a HTML help project\n\techo.  qthelp     to make HTML files and a qthelp project\n\techo.  devhelp    to make HTML files and a Devhelp project\n\techo.  epub       to make an epub\n\techo.  epub3      to make an epub3\n\techo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\n\techo.  text       to make text files\n\techo.  man        to make manual pages\n\techo.  texinfo    to make Texinfo files\n\techo.  gettext    to make PO message catalogs\n\techo.  changes    to make an overview over all changed/added/deprecated items\n\techo.  xml        to make Docutils-native XML files\n\techo.  pseudoxml  to make pseudoxml-XML files for display purposes\n\techo.  linkcheck  to check all external links for integrity\n\techo.  doctest    to run all doctests embedded in the documentation if enabled\n\techo.  coverage   to run coverage check of the documentation if enabled\n\techo.  dummy      to check syntax errors of document sources\n\tgoto end\n)\n\nif \"%1\" == \"clean\" (\n\tfor /d %%i in (%BUILDDIR%\\*) do rmdir /q /s %%i\n\tdel /q /s %BUILDDIR%\\*\n\tgoto end\n)\n\n\nREM Check if sphinx-build is available and fallback to Python version if any\n%SPHINXBUILD% 1>NUL 2>NUL\nif errorlevel 9009 goto sphinx_python\ngoto sphinx_ok\n\n:sphinx_python\n\nset SPHINXBUILD=python -m sphinx.__init__\n%SPHINXBUILD% 2> nul\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.http://sphinx-doc.org/\n\texit /b 1\n)\n\n:sphinx_ok\n\n\nif \"%1\" == \"html\" (\n\t%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/html.\n\tgoto end\n)\n\nif \"%1\" == \"dirhtml\" (\n\t%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\n\tgoto end\n)\n\nif \"%1\" == \"singlehtml\" (\n\t%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\n\tgoto end\n)\n\nif \"%1\" == \"pickle\" (\n\t%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the pickle files.\n\tgoto end\n)\n\nif \"%1\" == \"json\" (\n\t%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the JSON files.\n\tgoto end\n)\n\nif \"%1\" == \"htmlhelp\" (\n\t%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run HTML Help Workshop with the ^\n.hhp project file in %BUILDDIR%/htmlhelp.\n\tgoto end\n)\n\nif \"%1\" == \"qthelp\" (\n\t%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run \"qcollectiongenerator\" with the ^\n.qhcp project file in %BUILDDIR%/qthelp, like this:\n\techo.^> qcollectiongenerator %BUILDDIR%\\qthelp\\IdentityServer8.qhcp\n\techo.To view the help file:\n\techo.^> assistant -collectionFile %BUILDDIR%\\qthelp\\IdentityServer8.ghc\n\tgoto end\n)\n\nif \"%1\" == \"devhelp\" (\n\t%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished.\n\tgoto end\n)\n\nif \"%1\" == \"epub\" (\n\t%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The epub file is in %BUILDDIR%/epub.\n\tgoto end\n)\n\nif \"%1\" == \"epub3\" (\n\t%SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The epub3 file is in %BUILDDIR%/epub3.\n\tgoto end\n)\n\nif \"%1\" == \"latex\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"latexpdf\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tcd %BUILDDIR%/latex\n\tmake all-pdf\n\tcd %~dp0\n\techo.\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"latexpdfja\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tcd %BUILDDIR%/latex\n\tmake all-pdf-ja\n\tcd %~dp0\n\techo.\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"text\" (\n\t%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The text files are in %BUILDDIR%/text.\n\tgoto end\n)\n\nif \"%1\" == \"man\" (\n\t%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The manual pages are in %BUILDDIR%/man.\n\tgoto end\n)\n\nif \"%1\" == \"texinfo\" (\n\t%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\n\tgoto end\n)\n\nif \"%1\" == \"gettext\" (\n\t%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The message catalogs are in %BUILDDIR%/locale.\n\tgoto end\n)\n\nif \"%1\" == \"changes\" (\n\t%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.The overview file is in %BUILDDIR%/changes.\n\tgoto end\n)\n\nif \"%1\" == \"linkcheck\" (\n\t%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Link check complete; look for any errors in the above output ^\nor in %BUILDDIR%/linkcheck/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"doctest\" (\n\t%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Testing of doctests in the sources finished, look at the ^\nresults in %BUILDDIR%/doctest/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"coverage\" (\n\t%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Testing of coverage in the sources finished, look at the ^\nresults in %BUILDDIR%/coverage/python.txt.\n\tgoto end\n)\n\nif \"%1\" == \"xml\" (\n\t%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The XML files are in %BUILDDIR%/xml.\n\tgoto end\n)\n\nif \"%1\" == \"pseudoxml\" (\n\t%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\n\tgoto end\n)\n\nif \"%1\" == \"dummy\" (\n\t%SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. Dummy builder generates no files.\n\tgoto end\n)\n\n:end\n"
  },
  {
    "path": "docs/misc/blogs.rst",
    "content": "Blog posts\n==========\n\nTeam posts\n^^^^^^^^^^\n2020\n----\n* `Flexible Access Token Validation in ASP.NET Core <https://leastprivilege.com/2020/07/06/flexible-access-token-validation-in-asp-net-core/>`_\n* `Resource Access in IdentityServer8 v4 and going forward <https://leastprivilege.com/2020/06/18/resource-access-in-IdentityServer8-v4-and-going-forward/>`_\n* `Automatic Token Management for ASP.NET Core and Worker Services 1.0 <https://leastprivilege.com/2020/05/18/automatic-token-management-for-asp-net-core-and-worker-services-1-0/>`_\n* `Mutual TLS and Proof-of-Possession Tokens: Summary <https://leastprivilege.com/2020/02/12/mutual-tls-and-proof-of-possession-tokens-summary/>`_\n* `Mutual TLS and Proof-of-Possession Access Tokens – Part 1: Setup <https://leastprivilege.com/2020/02/07/mutual-tls-and-proof-of-possession-access-tokens-part-1-setup/>`_\n* `Hardening OpenID Connect/OAuth Authorize Requests (and Responses) <https://leastprivilege.com/2020/02/04/hardening-openid-connect-oauth-authorize-requests-and-responses/>`_\n* `Hardening Refresh Tokens <https://leastprivilege.com/2020/01/21/hardening-refresh-tokens/>`_\n* `OAuth 2.0: The long Road to Proof-of-Possession Access Tokens <https://leastprivilege.com/2020/01/15/oauth-2-0-the-long-road-to-proof-of-possession-access-tokens/>`_\n* `Outsourcing IdentityServer8 Token Signing to Azure Key Vault <https://www.scottbrady91.com/Identity-Server/Outsourcing-IdentityServer8-Token-Signing-to-Azure-Key-Vault>`_\n* `Using ECDSA in IdentityServer8 <https://www.scottbrady91.com/Identity-Server/Using-ECDSA-in-IdentityServer8>`_\n\n2019\n----\n* `Scope and claims design in IdentityServer <https://brockallen.com/2019/02/25/scope-and-claims-design-in-identityserver/>`_\n* `Try Device Flow with IdentityServer8 <https://leastprivilege.com/2019/02/08/try-device-flow-with-IdentityServer8/>`_\n* `The State of the Implicit Flow in OAuth2 <https://brockallen.com/2019/01/03/the-state-of-the-implicit-flow-in-oauth2/>`_\n* `An alternative way to secure SPAs (with ASP.NET Core, OpenID Connect, OAuth 2.0 and ProxyKit) <https://leastprivilege.com/2019/01/18/an-alternative-way-to-secure-spas-with-asp-net-core-openid-connect-oauth-2-0-and-proxykit/>`_\n* `Automatic OAuth 2.0 Token Management in ASP.NET Core <https://leastprivilege.com/2019/01/14/automatic-oauth-2-0-token-management-in-asp-net-core/>`_\n* `Encrypting Identity Tokens in IdentityServer8 <https://www.scottbrady91.com/Identity-Server/Encrypting-Identity-Tokens-in-IdentityServer8>`_\n\n2018\n----\n* `IdentityServer8 Update <https://leastprivilege.com/2018/01/17/ndc-london-2018-identityserver-update/>`_ \n* `IdentityServer and Swagger <https://www.scottbrady91.com/Identity-Server/ASPNET-Core-Swagger-UI-Authorization-using-IdentityServer8>`_\n* `Removing Shared Secrets for OAuth Client Authentication <https://www.scottbrady91.com/OAuth/Removing-Shared-Secrets-for-OAuth-Client-Authentication>`_\n* `Creating Your Own IdentityServer8 Storage Library <https://www.scottbrady91.com/Identity-Server/Creating-Your-Own-IdentityServer8-Storage-Library>`_\n\n2017\n----\n* `Platforms where you can run IdentityServer8 <https://leastprivilege.com/2017/01/15/platforms-where-you-can-run-IdentityServer8/>`_ \n* `Optimizing Tokens for size <https://leastprivilege.com/2016/12/14/optimizing-identity-tokens-for-size/>`_\n* `Identity vs Permissions <https://leastprivilege.com/2016/12/16/identity-vs-permissions/>`_\n* `Bootstraping OpenID Connect: Discovery <https://leastprivilege.com/2017/01/06/bootstrapping-openid-connect-discovery/>`_\n* `Extending IdentityServer8 with WS-Federation Support <https://leastprivilege.com/2017/03/03/extending-IdentityServer8-with-ws-federation-support/>`_\n* `Announcing IdentityServer8 RC1 <https://leastprivilege.com/2016/09/06/IdentityServer8-rc1/>`_\n* `Getting Started with IdentityServer 4 <https://www.scottbrady91.com/Identity-Server/Getting-Started-with-IdentityServer-4>`_\n* `IdentityServer 4 SharePoint Integration using WS-Federation <https://www.scottbrady91.com/Identity-Server/IdentityServer-4-SharePoint-Integration-using-WS-Federation>`_\n\nCommunity posts\n^^^^^^^^^^^^^^^\n* `Blazor WebAssembly authentication and authorization with IdentityServer8 <https://nahidfa.com/posts/blazor-webassembly-authentication-and-authorization-with-IdentityServer8/>`_\n* `Additional API Endpoints to IdentityServer 4 <https://lurumad.github.io/aditional-api-endpoints-to-IdentityServer8>`_\n* `Securing Hangfire Dashboard using an OpenID Connect server (IdentityServer 4) <https://lurumad.github.io/securing-hangfire-dashboard-using-an-openid-connect-server-identityserver-4>`_\n* `OAuth 2.0 - OpenID Connect & IdentityServer <https://wp.me/p3mRWu-1Ag/>`_\n* `Running IdentityServer8 in a Docker Container <https://espressocoder.com/2019/01/29/running-IdentityServer8-in-a-docker-container/>`_\n* `Connecting Zendesk and IdentityServer 4 SAML 2.0 Identity Provider <https://lurumad.github.io/connecting-zendesk-and-identityserver-4-saml2p-identity-provider>`_\n* `IdentityServer localization using ui_locales <https://damienbod.com/2017/11/11/IdentityServer8-localization-using-ui_locales-and-the-query-string>`_\n* `Self-issuing an IdentityServer8 token in an IdentityServer8 service <https://www.strathweb.com/2017/10/self-issuing-an-IdentityServer8-token-in-an-IdentityServer8-service/>`_\n* `IdentityServer8 on the ASP.NET Team Blog <https://blogs.msdn.microsoft.com/webdev/2017/01/23/asp-net-core-authentication-with-IdentityServer8/>`_\n* `Angular2 OpenID Connect Implicit Flow with IdentityServer8 <https://damienbod.com/2016/03/02/angular2-openid-connect-implicit-flow-with-IdentityServer8/>`_\n* `Full Server Logout with IdentityServer8 and OpenID Connect Implicit Flow <https://damienbod.com/2016/09/16/full-server-logout-with-IdentityServer8-and-openid-connect-implicit-flow/>`_\n* `IdentityServer8, ASP.NET Identity, Web API and Angular in a single Project <https://damienbod.com/2016/10/01/IdentityServer8-webapi-and-angular2-in-a-single-asp-net-core-project/>`_\n* `Secure your .NETCore web applications using IdentityServer 4 <https://social.technet.microsoft.com/wiki/contents/articles/37169.secure-your-netcore-web-applications-using-identityserver-4.aspx>`_\n* `ASP.NET Core IdentityServer8 Resource Owner Password Flow with custom UserRepository <https://damienbod.com/2017/04/14/asp-net-core-IdentityServer8-resource-owner-password-flow-with-custom-userrepository/>`_\n* `Secure ASP.NET Core MVC with Angular using IdentityServer8 OpenID Connect Hybrid Flow <https://damienbod.com/2017/05/06/secure-asp-net-core-mvc-with-angular-using-IdentityServer8-openid-connect-hybrid-flow//>`_\n* `Adding an external Microsoft login to IdentityServer8 <https://damienbod.com/2017/07/11/adding-an-external-microsoft-login-to-IdentityServer8/>`_\n* `Implementing Two-factor authentication with IdentityServer8 and Twilio <https://damienbod.com/2017/07/14/implementing-two-factor-authentication-with-IdentityServer8-and-twilio/>`_\n* `Security Experiments with gRPC and ASP.NET Core 3.0 <https://damienbod.com/2019/03/06/security-experiments-with-grpc-and-asp-net-core-3-0/>`_\n* `ASP.NET Core OAuth Device Flow Client with IdentityServer8 <https://damienbod.com/2019/02/20/asp-net-core-oauth-device-flow-client-with-IdentityServer8/>`_\n* `Securing a Vue.js app using OpenID Connect Code Flow with PKCE and IdentityServer8 <https://damienbod.com/2019/01/29/securing-a-vue-js-app-using-openid-connect-code-flow-with-pkce-and-IdentityServer8/>`_\n* `Using an OData Client with an ASP.NET Core API <https://damienbod.com/2018/10/18/using-an-odata-client-with-an-asp-net-core-api/>`_\n* `OpenID Connect back-channel logout using Azure Redis Cache and IdentityServer8 <https://damienbod.com/2018/12/18/openid-connect-back-channel-logout-using-azure-redis-cache-and-IdentityServer8/>`_\n* `Single Sign Out in IdentityServer8 with Back Channel Logout <https://blog.tretainfotech.com/posts/2018/august/single-sign-out-in-IdentityServer8-with-back-channel-logout>`_\n\n\n\n"
  },
  {
    "path": "docs/misc/training.rst",
    "content": "Training\n========\nHere are some online, remote and classroom training options to learn more about ASP.NET Core identity & IdentityServer8.\n\nIdentity & Access Control for modern Applications (using ASP.NET Core 2 and IdentityServer8)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThat's our own three day flagship course (including extensive hands-on labs) that we deliver as part of conferences, on-sites and remote.\n\nThe agenda and dates for public training can be found `here <https://identityserver8.io/training>`_,\n`contact <mailto:identity@leastprivilege.com>`_ us for private workshops.\n\nPluralSight courses\n^^^^^^^^^^^^^^^^^^^\nThere are some good courses on PluralSight around identity, ASP.NET Core and IdentityServer.\n\n**new**\n\n* `Securing Angular Apps with OpenID and OAuth2 <https://www.pluralsight.com/courses/openid-and-oauth2-securing-angular-apps>`_\n* `ASP.NET Core Identity Management Playbook <https://app.pluralsight.com/library/courses/aspnet-core-identity-management-playbook/table-of-contents>`_\n* `Getting Started with ASP.NET Core and OAuth <https://www.pluralsight.com/courses/asp-dot-net-core-oauth/>`_\n* `Securing ASP.NET Core with OAuth2 and OpenID Connect <https://app.pluralsight.com/library/courses/asp-dotnet-core-oauth2-openid-connect-securing/>`_\n* `Understanding ASP.NET Core Security (Centralized Authentication with a Token Service) <https://app.pluralsight.com/library/courses/asp-dot-net-core-security-understanding/>`_\n\n**older**\n\n* `Introduction to OAuth2, OpenID Connect and JSON Web Tokens (JWT) <https://app.pluralsight.com/library/courses/oauth2-json-web-tokens-openid-connect-introduction/table-of-contents>`_\n* `Web API v2 Security <https://app.pluralsight.com/library/courses/webapi-v2-security/table-of-contents>`_\n* `Using OAuth to Secure Your ASP.NET API <https://app.pluralsight.com/library/courses/oauth-secure-asp-dot-net-api/table-of-contents>`_\n* `OAuth2 and OpenID Connect Strategies for Angular and ASP.NET <https://app.pluralsight.com/library/courses/oauth2-openid-connect-angular-aspdotnet/table-of-contents>`_\n"
  },
  {
    "path": "docs/misc/videos.rst",
    "content": "Videos\n======\n2020\n^^^^\n* `January [NDC London] -- Implementing OpenID Connect and OAuth 2.0 – Tips from the Trenches  <https://www.youtube.com/watch?v=QpkVnB-N20c>`_\n* `January [NDC London] -- OpenID Connect & OAuth 2.0 – Security Best Practices  <https://www.youtube.com/watch?v=AUgZffkurK0>`_\n\n2019\n^^^^\n* `October [TDC] -- Securing Web Applications and APIs with ASP.NET Core 3.0  <https://vimeo.com/369311388>`_\n* `January [NDC] -- Securing Web Applications and APIs with ASP.NET Core 2.2 and 3.0  <https://www.youtube.com/watch?v=EYk3KTwwbFA>`_\n* `January [NDC] -- Building Clients for OpenID Connect/OAuth 2-based Systems  <https://www.youtube.com/watch?v=BM091_OlX3o>`_\n\n2018\n^^^^\n* `26/09 [DevConf] -- Authorization for modern Applications <https://www.youtube.com/watch?v=Dlrf85NTuAU&feature=youtu.be>`_\n* `17/01 [NDC London] -- IdentityServer v2 on ASP.NET Core v2 - an Update <https://vimeo.com/254635632>`_\n* `17/01 [NDC London] -- Implementing authorization for web apps and APIs (aka PolicyServer announcement) <https://vimeo.com/254635640>`_\n* `17/01 [DotNetRocks] -- IdentityServer and PolicyServer on DotNetRocks <https://dotnetrocks.com/?show=1515>`_\n\n2017\n^^^^\n* `14/09 [Microsoft Learning] -- Introduction to IdentityServer for ASP.NET Core - Brock Allen <https://mva.microsoft.com/en-US/training-courses/introduction-to-identityserver-for-aspnet-core-17945>`_\n* `14/06 [NDC Oslo] -- Implementing Authorization for Web Applications and APIs <https://vimeo.com/223982185>`_\n* `22/02 [NDC Mini Copenhagen] -- IdentityServer8: New & Improved for ASP.NET Core - Dominick Baier <https://vimeo.com/215352044>`_\n* `02/02 [DotNetRocks] -- IdentityServer8 on DotNetRocks <https://www.dotnetrocks.com/?show=1409>`_\n* `16/01 [NDC London] -- IdentityServer8: New and Improved for ASP.NET Core <https://vimeo.com/204141878>`_\n* `16/01 [NDC London] -- Building JavaScript and mobile/native Clients for Token-based Architectures <https://vimeo.com/205451987>`_\n\n2016\n^^^^\n* `The history of .NET identity and IdentityServer Channel9 interview <https://channel9.msdn.com/events/Seth-on-the-Road/NDC-London-2016/Dominick-Baier-on-Identity-Server>`_ \n* `Authentication & secure API access for native & mobile Applications - Dominick Baier <https://vimeo.com/171942749>`_\n* `ASP.NET Identity 3 - Brock Allen <https://vimeo.com/172009501>`_\n* `Introduction to IdentityServer3 - Brock Allen <https://vimeo.com/154172925>`_\n\n2015\n^^^^\n* `Securing Web APIs – Patterns & Anti-Patterns - Dominick Baier <https://vimeo.com/131635255>`_\n* `Authentication and authorization in modern JavaScript web applications – how hard can it be? - Brock Allen <https://vimeo.com/131636653>`_\n\n2014\n^^^^\n* `Unifying Authentication & Delegated API Access for Mobile, Web and the Desktop with OpenID Connect and OAuth 2 - Dominick Baier <https://vimeo.com/113604459>`_\n"
  },
  {
    "path": "docs/quickstarts/0_overview.rst",
    "content": ".. _refQuickstartOverview:\nOverview\n========\nThe quickstarts provide step by step instructions for various common IdentityServer scenarios.\nThey start with the absolute basics and become more complex - \nit is recommended you do them in order.\n\n* adding IdentityServer to an ASP.NET Core application\n* configuring IdentityServer\n* issuing tokens for various clients\n* securing web applications and APIs\n* adding support for EntityFramework based configuration\n* adding support for ASP.NET Identity\n\nEvery quickstart has a reference solution - you can find the code in the \n`samples <https://github.com/alexhiggins732/IdentityServer8/tree/main/samples/Quickstarts>`_ folder.\n\nPreparation\n^^^^^^^^^^^\nThe first thing you should do is install our templates::\n\n    dotnet new -i IdentityServer8.Templates\n\nThey will be used as a starting point for the various tutorials.\n\n.. note:: If you are using private NuGet sources do not forget to add the --nuget-source parameter: --nuget-source https://api.nuget.org/v3/index.json\n\nOK - let's get started!\n\n.. note:: The quickstarts target the IdentityServer 4.x and ASP.NET Core 3.1.x - there are also quickstarts for `ASP.NET Core 2 <http://docs.identityserver8.io/en/aspnetcore2/quickstarts/0_overview.html>`_ and `ASP.NET Core 1 <http://docs.identityserver8.io/en/aspnetcore1/quickstarts/0_overview.html>`_.\n"
  },
  {
    "path": "docs/quickstarts/1_client_credentials.rst",
    "content": ".. _refClientCredentialsQuickstart:\n\nProtecting an API using Client Credentials\n==========================================\nThe following Identity Server 4 quickstart provides step by step instructions for various common IdentityServer scenarios. \nThese start with the absolute basics and become more complex as they progress. We recommend that you follow them in sequence.  \n\nTo see the full list, please go to `IdentityServer8 Quickstarts Overview <https://IdentityServer8.readthedocs.io/en/latest/quickstarts/0_overview.html>`_\n\nThis first quickstart is the most basic scenario for protecting APIs using IdentityServer. \nIn this quickstart you define an API and a Client with which to access it. \nThe client will request an access token from the Identity Server using its client ID and secret and then use the token to gain access to the API.\n\nSource Code\n^^^^^^^^^^^\nAs with all of these quickstarts you can find the source code for it in the `IdentityServer8 <https://github.com/alexhiggins732/IdentityServer8/blob/main/samples>`_ repository. The project for this quickstart is `Quickstart #1: Securing an API using Client Credentials <https://github.com/alexhiggins732/IdentityServer8/tree/main/samples/Quickstarts/1_ClientCredentials>`_\n\nPreparation\n^^^^^^^^^^^\nThe IdentityServer templates for the dotnet CLI are a good starting point for the quickstarts.\nTo install the templates open a console window and type the following command::\n\n    dotnet new -i IdentityServer8.Templates\n\nThey will be used as a starting point for the various tutorials.\n\nSetting up the ASP.NET Core application\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nFirst create a directory for the application - then use our template to create an ASP.NET Core application that includes a basic IdentityServer setup, e.g.::\n\n    md quickstart\n    cd quickstart\n\n    md src\n    cd src\n\n    dotnet new is4empty -n IdentityServer\n\nThis will create the following files:\n\n* ``IdentityServer.csproj`` - the project file and a ``Properties\\launchSettings.json`` file\n* ``Program.cs`` and ``Startup.cs`` - the main application entry point\n* ``Config.cs`` - IdentityServer resources and clients configuration file\n\nYou can now use your favorite text editor to edit or view the files. If you want to have Visual Studio support, you can add a solution file like this::\n\n    cd ..\n    dotnet new sln -n Quickstart\n\nand let it add your IdentityServer project (keep this command in mind as we will create other projects below)::\n\n    dotnet sln add .\\src\\IdentityServer\\IdentityServer.csproj\n\n.. note:: The protocol used in this Template is ``https`` and the port is set to 5001 when running on Kestrel or a random one on IISExpress. You can change that in the ``Properties\\launchSettings.json`` file. For production scenarios you should always use ``https``.\n\nDefining an API Scope\n^^^^^^^^^^^^^^^^^^^^^\nAn API is a resource in your system that you want to protect. \nResource definitions can be loaded in many ways, the template you used to create the project above shows how to use a \"code as configuration\" approach.\n\nThe Config.cs is already created for you. Open it, update the code to look like this::\n\n    public static class Config\n    {\n        public static IEnumerable<ApiScope> ApiScopes =>\n            new List<ApiScope>\n            {\n                new ApiScope(\"api1\", \"My API\")\n            };\n    }\n\n(see the full file `here <https://github.com/alexhiggins732/IdentityServer8/blob/main/samples/Quickstarts/1_ClientCredentials/src/IdentityServer/Config.cs>`_).\n\t\n.. note:: If you will be using this in production it is important to give your API a logical name. Developers will be using this to connect to your api though your Identity server.  It should describe your api in simple terms to both developers and users.\n\nDefining the client\n^^^^^^^^^^^^^^^^^^^\nThe next step is to define a client application that we will use to access our new API.\n\nFor this scenario, the client will not have an interactive user, and will authenticate using the so called client secret with IdentityServer.\n\nFor this, add a client definition:: \n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            new Client\n            {\n                ClientId = \"client\",\n\n                // no interactive user, use the clientid/secret for authentication\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n\n                // secret for authentication\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            }\n        };\n\nYou can think of the ClientId and the ClientSecret as the login and password for your application itself.  \nIt identifies your application to the identity server so that it knows which application is trying to connect to it.\t\n\n\t\nConfiguring IdentityServer\n^^^^^^^^^^^^^^^^^^^^^^^^^^\nLoading the resource and client definitions happens in `Startup.cs <https://github.com/alexhiggins732/IdentityServer8/blob/main/samples/Quickstarts/1_ClientCredentials/src/IdentityServer/Startup.cs>`_ - update the code to look like this::\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var builder = services.AddIdentityServer()\n            .AddDeveloperSigningCredential()        //This is for dev only scenarios when you don’t have a certificate to use.\n            .AddInMemoryApiScopes(Config.ApiScopes)\n            .AddInMemoryClients(Config.Clients);\n\n        // omitted for brevity\n    }\n\nThat's it - your identity server should now be configured. If you run the server and navigate the browser to ``https://localhost:5001/.well-known/openid-configuration``, you should see the so-called discovery document. \nThe discovery document is a standard endpoint in identity servers.  The discovery document will be used by your clients and APIs to download the necessary configuration data.\n\n.. image:: images/1_discovery.png\n\nAt first startup, IdentityServer will create a developer signing key for you, it's a file called ``tempkey.jwk``.\nYou don't have to check that file into your source control, it will be re-created if it is not present.\n\nAdding an API\n^^^^^^^^^^^^^\nNext, add an API to your solution. \n\nYou can either use the ASP.NET Core Web API template from Visual Studio or use the .NET CLI to create the API project as we do here.\nRun from within the ``src`` folder the following command::\n\n    dotnet new webapi -n Api\n\nThen add it to the solution by running the following commands::\n\n    cd ..\n    dotnet sln add .\\src\\Api\\Api.csproj\n\nConfigure the API application to run on ``https://localhost:6001`` only. You can do this by editing the `launchSettings.json <https://github.com/alexhiggins732/IdentityServer8/blob/main/samples/Quickstarts/1_ClientCredentials/src/Api/Properties/launchSettings.json>`_ file inside the Properties folder. Change the application URL setting to be::\n\n    \"applicationUrl\": \"https://localhost:6001\"\n\nThe controller\n--------------\nAdd a new class called ``IdentityController``::\n\n    [Route(\"identity\")]\n    [Authorize]\n    public class IdentityController : ControllerBase\n    {\n        [HttpGet]\n        public IActionResult Get()\n        {\n            return new JsonResult(from c in User.Claims select new { c.Type, c.Value });\n        }\n    }\n\nThis controller will be used later to test the authorization requirement, as well as visualize the claims identity through the eyes of the API.\n\nAdding a Nuget Dependency\n-------------------------\nIn order for the configuration step to work the nuget package dependency has to be added, run this command in the root directory::\n\n    dotnet add .\\\\src\\\\api\\\\Api.csproj package Microsoft.AspNetCore.Authentication.JwtBearer\n\nConfiguration\n-------------\nThe last step is to add the authentication services to DI (dependency injection) and the authentication middleware to the pipeline.\nThese will:\n\n* validate the incoming token to make sure it is coming from a trusted issuer\n* validate that the token is valid to be used with this api (aka audience)\n\nUpdate `Startup` to look like this::\n\n    public class Startup\n    {\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddControllers();\n\n            services.AddAuthentication(\"Bearer\")\n                .AddJwtBearer(\"Bearer\", options =>\n                {\n                    options.Authority = \"https://localhost:5001\";\n\n                    options.TokenValidationParameters = new TokenValidationParameters\n                    {\n                        ValidateAudience = false\n                    };\n                });\n        }\n\n        public void Configure(IApplicationBuilder app)\n        {\n            app.UseRouting();\n\n            app.UseAuthentication();\n            app.UseAuthorization();\n\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapControllers();\n            });\n        }\n    }\n\n* ``AddAuthentication`` adds the authentication services to DI and configures ``Bearer`` as the default scheme. \n* ``UseAuthentication`` adds the authentication middleware to the pipeline so authentication will be performed automatically on every call into the host.\n* ``UseAuthorization`` adds the authorization middleware to make sure, our API endpoint cannot be accessed by anonymous clients.\n\nNavigating to the controller ``https://localhost:6001/identity`` on a browser should return a 401 status code. \nThis means your API requires a credential and is now protected by IdentityServer.\n\n.. note:: If you are wondering, why the above code disables audience validation, have a look :ref:`here <refResources>` for a more in-depth discussion.\n\nCreating the client\n^^^^^^^^^^^^^^^^^^^\nThe last step is to write a client that requests an access token, and then uses this token to access the API. For that, add a console project to your solution, remember to create it in the ``src``::\n\n    dotnet new console -n Client\n    \nThen as before, add it to your solution using::\n\n    cd ..\n    dotnet sln add .\\src\\Client\\Client.csproj\n\nThe token endpoint at IdentityServer implements the OAuth 2.0 protocol, and you could use raw HTTP to access it. \nHowever, we have a client library called IdentityModel, that encapsulates the protocol interaction in an easy to use API.\n\nAdd the ``IdentityModel`` NuGet package to your client. \nThis can be done either via Visual Studio's Nuget Package manager or dotnet CLI::\n\n    cd src\n    cd client\n    dotnet add package IdentityModel\n\nIdentityModel includes a client library to use with the discovery endpoint. This way you only need to know the base-address of IdentityServer - the actual endpoint addresses can be read from the metadata::\n\n    // discover endpoints from metadata\n    var client = new HttpClient();\n    var disco = await client.GetDiscoveryDocumentAsync(\"https://localhost:5001\");\n    if (disco.IsError)\n    {\n        Console.WriteLine(disco.Error);\n        return;\n    }\n.. note:: If you get an error connecting it may be that you are running `https` and the development certificate for ``localhost`` is not trusted. You can run ``dotnet dev-certs https --trust`` in order to trust the development certificate. This only needs to be done once.\n\nNext you can use the information from the discovery document to request a token to IdentityServer to access ``api1``::\n\n    // request token\n    var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"client\",\n        ClientSecret = \"secret\",\n        Scope = \"api1\"\n    });\n    \n    if (tokenResponse.IsError)\n    {\n        Console.WriteLine(tokenResponse.Error);\n        return;\n    }\n\n    Console.WriteLine(tokenResponse.Json);\n\n(full file can be found `here <https://github.com/alexhiggins732/IdentityServer8/blob/main/samples/Quickstarts/1_ClientCredentials/src/Client/Program.cs>`_)\n\n.. note:: Copy and paste the access token from the console to `jwt.ms <https://jwt.ms>`_ to inspect the raw token.\n\nCalling the API\n^^^^^^^^^^^^^^^\nTo send the access token to the API you typically use the HTTP Authorization header. This is done using the ``SetBearerToken`` extension method::\n\n    // call api\n    var apiClient = new HttpClient();\n    apiClient.SetBearerToken(tokenResponse.AccessToken);\n\n    var response = await apiClient.GetAsync(\"https://localhost:6001/identity\");\n    if (!response.IsSuccessStatusCode)\n    {\n        Console.WriteLine(response.StatusCode);\n    }\n    else\n    {\n        var content = await response.Content.ReadAsStringAsync();\n        Console.WriteLine(JArray.Parse(content));\n    }\n\n(If you are in Visual Studio you can right-click on the solution and select \"Multiple Startup Projects\", and ensure the Api and IdentityServer will start; then run the solution; then, to step through the Client code, you can right-click on the \"Client\" project and select Debug... Start New Instance).\nThe output should look like this:\n\n.. image:: images/1_client_screenshot.png\n\n.. note:: By default an access token will contain claims about the scope, lifetime (nbf and exp), the client ID (client_id) and the issuer name (iss).\n\nAuthorization at the API\n^^^^^^^^^^^^^^^^^^^^^^^^\nRight now, the API accepts any access token issued by your identity server.\n\nIn the following we will add code that allows checking for the presence of the scope in the access token that the client asked for (and got granted).\nFor this we will use the ASP.NET Core authorization policy system. Add the following to the ``ConfigureServices`` method in ``Startup``::\n\n    services.AddAuthorization(options =>\n    {\n        options.AddPolicy(\"ApiScope\", policy =>\n        {\n            policy.RequireAuthenticatedUser();\n            policy.RequireClaim(\"scope\", \"api1\");\n        });\n    });\n\nYou can now enforce this policy at various levels, e.g.\n\n* globally\n* for all API endpoints\n* for specific controllers/actions\n\nTypically you setup the policy for all API endpoints in the routing system::\n\n    app.UseEndpoints(endpoints =>\n    {\n        endpoints.MapControllers()\n            .RequireAuthorization(\"ApiScope\");\n    });\n\n\nFurther experiments\n^^^^^^^^^^^^^^^^^^^\nThis walkthrough focused on the success path so far\n\n* client was able to request token\n* client could use the token to access the API\n\nYou can now try to provoke errors to learn how the system behaves, e.g.\n\n* try to connect to IdentityServer when it is not running (unavailable)\n* try to use an invalid client id or secret to request the token\n* try to ask for an invalid scope during the token request\n* try to call the API when it is not running (unavailable)\n* don't send the token to the API\n* configure the API to require a different scope than the one in the token\n"
  },
  {
    "path": "docs/quickstarts/2_interactive_aspnetcore.rst",
    "content": ".. _refInteractiveQuickstart:\nInteractive Applications with ASP.NET Core\n==========================================\n\n.. note:: For any pre-requisites (like e.g. templates) have a look at the :ref:`overview <refQuickstartOverview>` first.\n\nIn this quickstart we want to add support for interactive user authentication via the\nOpenID Connect protocol to our IdentityServer we built in the previous chapter.\n\nOnce that is in place, we will create an MVC application that will use IdentityServer for \nauthentication.\n\nAdding the UI\n^^^^^^^^^^^^^\nAll the protocol support needed for OpenID Connect is already built into IdentityServer.\nYou need to provide the necessary UI parts for login, logout, consent and error.\n\nWhile the look & feel as well as the exact workflows will probably always differ in every\nIdentityServer implementation, we provide an MVC-based sample UI that you can use as a starting point.\n\nThis UI can be found in the `Quickstart UI repo <https://github.com/alexhiggins732/IdentityServer8.Quickstart.UI/tree/main>`_.\nYou can clone or download this repo and drop the controllers, views, models and CSS into your IdentityServer web application.\n\nAlternatively you can use the .NET CLI (run from within the ``src/IdentityServer`` folder)::\n\n    dotnet new is4ui\n\nOnce you have added the MVC UI, you will also need to enable MVC, both in the DI system and in the pipeline.\nWhen you look at ``Startup.cs`` you will find comments in the ``ConfigureServices`` and ``Configure`` method that tell you how to enable MVC.\n\n.. note:: There is also a template called ``is4inmem`` which combines a basic IdentityServer including the standard UI.\n\nRun the IdentityServer application, you should now see a home page.\n\nSpend some time inspecting the controllers and models - especially the ``AccountController`` which is the main UI entry point.\nThe better you understand them, the easier it will be to make future modifications. \nMost of the code lives in the \"Quickstart\" folder using a \"feature folder\" style. \nIf this style doesn't suit you, feel free to organize the code in any way you want.\n\nCreating an MVC client\n^^^^^^^^^^^^^^^^^^^^^^\nNext you will create an MVC application.\nUse the ASP.NET Core \"Web Application\" (i.e. MVC) template for that. \n\nrun from the src folder::\n\n    dotnet new mvc -n MvcClient\n    cd ..\n    dotnet sln add .\\src\\MvcClient\\MvcClient.csproj\n\n.. note:: We recommend using the self-host option over IIS Express. The rest of the docs assume you are using self-hosting on port 5002.\n\nTo add support for OpenID Connect authentication to the MVC application, you first need to add the nuget package containing the OpenID Connect handler to your project, e.g.::\n\n    dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect\n\n..then add the following to ``ConfigureServices`` in ``Startup``::\n\n    using System.IdentityModel.Tokens.Jwt;\n    \n    // ...\n    \n    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n    services.AddAuthentication(options =>\n        {\n            options.DefaultScheme = \"Cookies\";\n            options.DefaultChallengeScheme = \"oidc\";\n        })\n        .AddCookie(\"Cookies\")\n        .AddOpenIdConnect(\"oidc\", options =>\n        {\n            options.Authority = \"https://localhost:5001\";\n\n            options.ClientId = \"mvc\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.SaveTokens = true;\n        });\n\n``AddAuthentication`` adds the authentication services to DI.\n\nWe are using a cookie to locally sign-in the user (via ``\"Cookies\"`` as the ``DefaultScheme``),\nand we set the ``DefaultChallengeScheme`` to ``oidc`` because when we need the user to login, we will be using the OpenID Connect protocol.\n\nWe then use ``AddCookie`` to add the handler that can process cookies.\n\nFinally, ``AddOpenIdConnect`` is used to configure the handler that performs the OpenID Connect protocol.\nThe ``Authority`` indicates where the trusted token service is located.\nWe then identify this client via the ``ClientId`` and the ``ClientSecret``. \n``SaveTokens`` is used to persist the tokens from IdentityServer in the cookie (as they will be needed later).\n\n.. note:: We use the so called ``authorization code`` flow with PKCE to connect to the OpenID Connect provider. See :ref:`here <refGrantTypes>` for more information on protocol flows.\n\nAnd then to ensure the execution of the authentication services on each request, add ``UseAuthentication`` to ``Configure`` in ``Startup``::\n\n    app.UseStaticFiles();\n\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n\n    app.UseEndpoints(endpoints =>\n    {\n        endpoints.MapDefaultControllerRoute()\n            .RequireAuthorization();\n    });\n\n.. note:: The ``RequireAuthorization`` method disables anonymous access for the entire application. \nYou can also use the ``[Authorize]`` attribute, if you want to specify authorization on a per controller or action method basis.\n\nAlso modify the home view to display the claims of the user as well as the cookie properties::\n\n    @using Microsoft.AspNetCore.Authentication\n\n    <h2>Claims</h2>\n\n    <dl>\n        @foreach (var claim in User.Claims)\n        {\n            <dt>@claim.Type</dt>\n            <dd>@claim.Value</dd>\n        }\n    </dl>\n\n    <h2>Properties</h2>\n\n    <dl>\n        @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n        {\n            <dt>@prop.Key</dt>\n            <dd>@prop.Value</dd>\n        }\n    </dl>\n\nIf you now navigate to the application using the browser, a redirect attempt will be made\nto IdentityServer - this will result in an error because the MVC client is not registered yet.\n\nAdding support for OpenID Connect Identity Scopes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nSimilar to OAuth 2.0, OpenID Connect also uses the scopes concept.\nAgain, scopes represent something you want to protect and that clients want to access.\nIn contrast to OAuth, scopes in OIDC don't represent APIs, but identity data like user id, \nname or email address.\n\nAdd support for the standard ``openid`` (subject id) and ``profile`` (first name, last name etc..) scopes\nby amending the ``IdentityResources`` property in ``Config.cs``::\n\n    public static IEnumerable<IdentityResource> IdentityResources =>\n        new List<IdentityResource>\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n        };\n\nRegister the identity resources with IdentityServer in ``startup.cs``::\n\n    var builder = services.AddIdentityServer()\n        .AddInMemoryIdentityResources(Config.IdentityResources)\n        .AddInMemoryApiScopes(Config.ApiScopes)\n        .AddInMemoryClients(Config.Clients);\n\n.. note:: All standard scopes and their corresponding claims can be found in the OpenID Connect `specification <https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims>`_\n\nAdding Test Users\n^^^^^^^^^^^^^^^^^\nThe sample UI also comes with an in-memory \"user database\". You can enable this in IdentityServer by adding the ``AddTestUsers`` extension method::\n\n    var builder = services.AddIdentityServer()\n        .AddInMemoryIdentityResources(Config.IdentityResources)\n        .AddInMemoryApiScopes(Config.ApiScopes)\n        .AddInMemoryClients(Config.Clients)\n        .AddTestUsers(TestUsers.Users);\n\nWhen you navigate to the ``TestUsers`` class, you can see that two users called ``alice`` and ``bob`` as well as some identity claims are defined.\nYou can use those users to login.\n\nAdding the MVC Client to the IdentityServer Configuration\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThe last step is to add a new configuration entry for the MVC client to the IdentityServer.\n\nOpenID Connect-based clients are very similar to the OAuth 2.0 clients we added so far.\nBut since the flows in OIDC are always interactive, we need to add some redirect URLs to our configuration.\n\nThe client list should look like this::\n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            // machine to machine client (from quickstart 1)\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            },\n            // interactive ASP.NET Core MVC client\n            new Client\n            {\n                ClientId = \"mvc\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                \n                // where to redirect to after login\n                RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                // where to redirect to after logout\n                PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                AllowedScopes = new List<string>\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile\n                }\n            }\n        };\n\nTesting the client\n^^^^^^^^^^^^^^^^^^\nNow finally everything should be in place for the new MVC client.\n\nTrigger the authentication handshake by navigating to the protected controller action.\nYou should see a redirect to the login page of the IdentityServer.\n\n.. image:: images/3_login.png\n\nAfter that, the IdentityServer will redirect back to the MVC client, where the OpenID Connect authentication handler processes the response and signs-in the user locally by setting a cookie.\nFinally the MVC view will show the contents of the cookie.\n\n.. image:: images/3_claims.png\n\nAs you can see, the cookie has two parts, the claims of the user, and some metadata. This metadata also contains the original token that was issued by the IdentityServer.\nFeel free to copy this token to `jwt.ms <https://jwt.ms>`_ to inspect its content.\n\nAdding sign-out\n^^^^^^^^^^^^^^^\nThe very last step is to add sign-out to the MVC client.\n\nWith an authentication service like IdentityServer, it is not enough to clear the local application cookies.\nIn addition you also need to make a roundtrip to the IdentityServer to clear the central single sign-on session.\n\nThe exact protocol steps are implemented inside the OpenID Connect handler, \nsimply add the following code to some controller to trigger the sign-out::\n\n    public IActionResult Logout()\n    {\n        return SignOut(\"Cookies\", \"oidc\");\n    }\n\nThis will clear the local cookie and then redirect to the IdentityServer.\nThe IdentityServer will clear its cookies and then give the user a link to return back to the MVC application.\n\nGetting claims from the UserInfo endpoint\n^^^^^^^^^^^^^^^\nYou might have noticed that even though we've configured the client to be allowed to retrieve the ``profile`` identity scope, the claims associated with that scope (such as ``name``, ``family_name``, ``website`` etc.) don't appear in the returned token. We need to tell the client to pull remaining claims from the `UserInfo <https://IdentityServer8.readthedocs.io/en/latest/endpoints/userinfo.html>`_ endpoint by specifying scopes that the client application needs to access and setting the ``GetClaimsFromUserInfoEndpoint`` option. In the following example we're requesting the ``profile`` scope, but it could be any scope (or scopes) that the client is authorized to access::\n\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        // ...\n        options.Scope.Add(\"profile\");\n        options.GetClaimsFromUserInfoEndpoint = true;\n        // ...\n    });\n\nAfter restarting the client app, logging out, and logging back in you should see additional user claims associated with the ``profile`` identity scope displayed on the page.\n\n.. image:: images/3_additional_claims.png\n\nFurther Experiments\n^^^^^^^^^^^^^^^^^^^\nFeel free to add more claims to the test users - and also more identity resources. \n\nThe process for defining an identity resource is as follows:\n\n* add a new identity resource to the list - give it a name and specify which claims should be returned when this resource is requested\n* give the client access to the resource via the ``AllowedScopes`` property on the client configuration\n* request the resource by adding it to the ``Scopes`` collection on the OpenID Connect handler configuration in the client\n* (optional) if the identity resource is associated with a non-standard claim (e.g. ``myclaim1``), on the client side add the `ClaimAction <https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.openidconnect.openidconnectoptions.claimactions?view=aspnetcore-3.0>`_ mapping between the claim appearing in JSON (returned from the UserInfo endpoint) and the User `Claim <https://docs.microsoft.com/en-us/dotnet/api/system.security.claims.claim>`_ ::\n\n    using Microsoft.AspNetCore.Authentication\n    // ...\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        // ...\n        options.ClaimActions.MapUniqueJsonKey(\"myclaim1\", \"myclaim1\");\n        // ...\n    });\n\nIt is also noteworthy, that the retrieval of claims for tokens is an extensibility point - ``IProfileService``.\nSince we are using ``AddTestUsers``, the ``TestUserProfileService`` is used by default.\nYou can inspect the source code `here <https://github.com/alexhiggins732/IdentityServer8/blob/main/src/IdentityServer8/src/Test/TestUserProfileService.cs>`_\nto see how it works.\n\n.. _refExternalAuthenticationQuickstart:\nAdding Support for External Authentication\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nNext we will add support for external authentication.\nThis is really easy, because all you really need is an ASP.NET Core compatible authentication handler.\n\nASP.NET Core itself ships with support for Google, Facebook, Twitter, Microsoft Account and OpenID Connect.\nIn addition you can find implementations for many other authentication providers `here <https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers>`_.\n\nAdding Google support\n^^^^^^^^^^^^^^^^^^^^^\nTo be able to use Google for authentication, you first need to register with them.\nThis is done at their developer `console <https://console.developers.google.com/>`_.\nCreate a new project, enable the Google+ API and configure the callback address of your\nlocal IdentityServer by adding the */signin-google* path to your base-address (e.g. https://localhost:5001/signin-google).\n\nThe developer console will show you a client ID and secret issued by Google - you will need that in the next step.\n\nAdd the Google authentication handler to the DI of the IdentityServer host.\nThis is done by first adding the ``Microsoft.AspNetCore.Authentication.Google`` nuget package and then adding this snippet to ``ConfigureServices`` in ``Startup``::\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"<insert here>\";\n            options.ClientSecret = \"<insert here>\";\n        });\n    \nBy default, IdentityServer configures a cookie handler specifically for the results of external authentication (with the scheme based on the constant ``IdentityServerConstants.ExternalCookieAuthenticationScheme``).\nThe configuration for the Google handler is then using that cookie handler.\n\nNow run the MVC client and try to authenticate - you will see a Google button on the login page:\n\n.. image:: images/4_login_page.png\n\nAfter authentication with the MVC client, you can see that the claims are now being sourced from Google data.\n\n.. note:: If you are interested in the magic that automatically renders the Google button on the login page, inspect the ``BuildLoginViewModel`` method on the ``AccountController``.\n\nFurther experiments\n^^^^^^^^^^^^^^^^^^^\nYou can add an additional external provider.\nWe have a `cloud-hosted demo <https://demo.identityserver8.io>`_ version of IdentityServer8 which you can integrate using OpenID Connect.\n\nAdd the OpenId Connect handler to DI::\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"<insert here>\";\n            options.ClientSecret = \"<insert here>\";\n        })\n        .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n            options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n            options.SaveTokens = true;\n\n            options.Authority = \"https://demo.identityserver8.io/\";\n            options.ClientId = \"interactive.confidential\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.TokenValidationParameters = new TokenValidationParameters\n            {\n                NameClaimType = \"name\",\n                RoleClaimType = \"role\"\n            };\n        });\n\nAnd now a user should be able to use the cloud-hosted demo identity provider.\n\n.. note:: The quickstart UI auto-provisions external users. As an external user logs in for the first time, a new local user is created, and all the external claims are copied over and associated with the new user. The way you deal with such a situation is completely up to you though. Maybe you want to show some sort of registration UI first. The source code for the default quickstart can be found `here <https://github.com/alexhiggins732/IdentityServer8.Quickstart.UI>`_. The controller where auto-provisioning is executed can be found `here <https://github.com/alexhiggins732/IdentityServer8.Quickstart.UI/blob/main/Quickstart/Account/ExternalController.cs>`_.\n"
  },
  {
    "path": "docs/quickstarts/3_aspnetcore_and_apis.rst",
    "content": ".. _refAspNetCoreAndApis:\nASP.NET Core and API access\n===========================\nIn the previous quickstarts we explored both API access and user authentication. \nNow we want to bring the two parts together.\n\nThe beauty of the OpenID Connect & OAuth 2.0 combination is, that you can achieve both with a single protocol and a single exchange with the token service.\n\nSo far we only asked for identity resources during the token request, once we start also including API resources, IdentityServer will return two tokens:\nthe identity token containing the information about the authentication and session, and the access token to access APIs on behalf of the logged on user.\n\nModifying the client configuration\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nUpdating the client configuration in IdentityServer is straightforward - we simply need to add the ``api1`` resource to the allowed scopes list.\nIn addition we enable support for refresh tokens via the ``AllowOfflineAccess`` property::\n\n    new Client\n    {\n        ClientId = \"mvc\",\n        ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n        AllowedGrantTypes = GrantTypes.Code,\n                \n        // where to redirect to after login\n        RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n        // where to redirect to after logout\n        PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n        \n        AllowOfflineAccess = true,\n\n        AllowedScopes = new List<string>\n        {\n            IdentityServerConstants.StandardScopes.OpenId,\n            IdentityServerConstants.StandardScopes.Profile,\n            \"api1\"\n        }\n    }\n\nModifying the MVC client\n^^^^^^^^^^^^^^^^^^^^^^^^\nAll that's left to do now in the client is to ask for the additional resources via the scope parameter. This is done in the OpenID Connect handler configuration::\n\n    services.AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"Cookies\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n        .AddCookie(\"Cookies\")\n        .AddOpenIdConnect(\"oidc\", options =>\n        {\n            options.Authority = \"https://localhost:5001\";\n\n            options.ClientId = \"mvc\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.SaveTokens = true;\n\n            options.Scope.Add(\"api1\");\n            options.Scope.Add(\"offline_access\");\n        });\n\nSince ``SaveTokens`` is enabled, ASP.NET Core will automatically store the resulting access and refresh token in the authentication session.\nYou should be able to inspect the data on the page that prints out the contents of the session that you created earlier.\n\nUsing the access token\n^^^^^^^^^^^^^^^^^^^^^^\nYou can access the tokens in the session using the standard ASP.NET Core extension methods \nthat you can find in the ``Microsoft.AspNetCore.Authentication`` namespace::\n\n    var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\nFor accessing the API using the access token, all you need to do is retrieve the token, and set it on your HttpClient::\n\n    public async Task<IActionResult> CallApi()\n    {\n        var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = new HttpClient();\n        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n        var content = await client.GetStringAsync(\"https://localhost:6001/identity\");\n\n        ViewBag.Json = JArray.Parse(content).ToString();\n        return View(\"json\");\n    }\n\nCreate a view called json.cshtml that outputs the json like this::\n\n    <pre>@ViewBag.Json</pre>\n\nMake sure the API is running, start the MVC client and call ``/home/CallApi`` after authentication.\n\nManaging the access token\n^^^^^^^^^^^^^^^^^^^^^^^^^\nBy far the most complex task for a typical client is to manage the access token. You typically want to \n\n* request the access and refresh token at login time\n* cache those tokens\n* use the access token to call APIs until it expires\n* use the refresh token to get a new access token\n* start over\n\nASP.NET Core has many built-in facility that can help you with those tasks (like caching or sessions), \nbut there is still quite some work left to do. \nFeel free to have a look at `this <https://github.com/IdentityModel/IdentityModel.AspNetCore>`_ library, which can automate \nmany of the boilerplate tasks.\n"
  },
  {
    "path": "docs/quickstarts/4_javascript_client.rst",
    "content": ".. _refJavaScriptQuickstart:\nAdding a JavaScript client\n==========================\n\n.. note:: For any pre-requisites (like e.g. templates) have a look at the :ref:`overview <refQuickstartOverview>` first.\n\nThis quickstart will show how to build a browser-based JavaScript client application (sometimes referred to as a \"Single Page Application\" or \"`SPA`\").\n\nThe user will login to IdentityServer, invoke the web API with an access token issued by IdentityServer, and logout of IdentityServer. \nAll of this will be driven from the JavaScript running in the browser.\n\nNew Project for the JavaScript client\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nCreate a new project for the JavaScript application.\nIt can simply be an empty web project, an empty ASP.NET Core application, or something else like a Node.js application.\nThis quickstart will use an ASP.NET Core application.\n\nCreate a new \"Empty\" ASP.NET Core web application in the `~/src` directory.\nYou can use Visual Studio or do this from the command line::\n\n    md JavaScriptClient\n    cd JavaScriptClient\n    dotnet new web\n\nAs we have done before, with other client projects, add this project also to your solution. Run this from the root folder which has the sln file::\n\n    dotnet sln add .\\src\\JavaScriptClient\\JavaScriptClient.csproj\n    \nModify hosting\n^^^^^^^^^^^^^^^\n\nModify the `JavaScriptClient` project to run on https://localhost:5003.\n\nAdd the static file middleware\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nGiven that this project is designed to run client-side, all we need ASP.NET Core to do is to serve up the static HTML and JavaScript files that will make up our application.\nThe static file middleware is designed to do this.\n\nRegister the static file middleware in `Startup.cs` in the ``Configure`` method (and at the same time remove everything else)::\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseDefaultFiles();\n        app.UseStaticFiles();\n    }\n\nThis middleware will now serve up static files from the application's `~/wwwroot` folder.\nThis is where we will put our HTML and JavaScript files.\nIf that folder does not exist in your project, create it now.\n\nReference oidc-client\n^^^^^^^^^^^^^^^^^^^^^\n\nIn one of the previous quickstarts in the ASP.NET Core MVC-based client project we used a library to handle the OpenID Connect protocol. \nIn this quickstart in the `JavaScriptClient` project we need a similar library, except one that works in JavaScript and is designed to run in the browser.\nThe `oidc-client library <https://github.com/IdentityModel/oidc-client-js>`_ is one such library. \nIt is available via `NPM <https://github.com/IdentityModel/oidc-client-js>`_, `Bower <https://bower.io/search/?q=oidc-client>`_,  as well as a `direct download <https://github.com/IdentityModel/oidc-client-js/tree/release/dist>`_ from github.\n\n**NPM**\n\nIf you want to use NPM to download `oidc-client`, then run these commands from your `JavaScriptClient` project directory::\n\n    npm i oidc-client\n    copy node_modules\\oidc-client\\dist\\* wwwroot\n\nThis downloads the latest `oidc-client` package locally, and then copies the relevant JavaScript files into `~/wwwroot` so they can be served up by your application.\n\n**Manual download**\n\nIf you want to simply download the `oidc-client` JavaScript files manually, browse to `the GitHub repository <https://github.com/IdentityModel/oidc-client-js/tree/release/dist>`_  and download the JavaScript files. Once downloaded, copy them into `~/wwwroot` so they can be served up by your application.\n\nAdd your HTML and JavaScript files\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nNext is to add your HTML and JavaScript files to `~/wwwroot`.\nWe will have two HTML files and one application-specific JavaScript file (in addition to the `oidc-client.js` library).\nIn `~/wwwroot`, add a HTML file named `index.html` and `callback.html`, and add a JavaScript file called `app.js`.\n\n**index.html**\n\nThis will be the main page in our application. \nIt will simply contain the HTML for the buttons for the user to login, logout, and call the web API.\nIt will also contain the ``<script>`` tags to include our two JavaScript files.\nIt will also contain a ``<pre>`` used for showing messages to the user.\n\nIt should look like this::\n\n    <!DOCTYPE html>\n    <html>\n    <head>\n        <meta charset=\"utf-8\" />\n        <title></title>\n    </head>\n    <body>\n        <button id=\"login\">Login</button>\n        <button id=\"api\">Call API</button>\n        <button id=\"logout\">Logout</button>\n\n        <pre id=\"results\"></pre>\n\n        <script src=\"oidc-client.js\"></script>\n        <script src=\"app.js\"></script>\n    </body>\n    </html>\n\n**app.js**\n\nThis will contain the main code for our application.\nThe first thing is to add a helper function to log messages to the ``<pre>``::\n\n    function log() {\n        document.getElementById('results').innerText = '';\n\n        Array.prototype.forEach.call(arguments, function (msg) {\n            if (msg instanceof Error) {\n                msg = \"Error: \" + msg.message;\n            }\n            else if (typeof msg !== 'string') {\n                msg = JSON.stringify(msg, null, 2);\n            }\n            document.getElementById('results').innerHTML += msg + '\\r\\n';\n        });\n    }\n\nNext, add code to register ``click`` event handlers to the three buttons::\n\n    document.getElementById(\"login\").addEventListener(\"click\", login, false);\n    document.getElementById(\"api\").addEventListener(\"click\", api, false);\n    document.getElementById(\"logout\").addEventListener(\"click\", logout, false);\n\nNext, we can use the ``UserManager`` class from the `oidc-client` library to manage the OpenID Connect protocol. \nIt requires similar configuration that was necessary in the MVC Client (albeit with different values). \nAdd this code to configure and instantiate the ``UserManager``::\n\n    var config = {\n        authority: \"https://localhost:5001\",\n        client_id: \"js\",\n        redirect_uri: \"https://localhost:5003/callback.html\",\n        response_type: \"code\",\n        scope:\"openid profile api1\",\n        post_logout_redirect_uri : \"https://localhost:5003/index.html\",\n    };\n    var mgr = new Oidc.UserManager(config);\n\nNext, the ``UserManager`` provides a ``getUser`` API to know if the user is logged into the JavaScript application.\nIt uses a JavaScript ``Promise`` to return the results asynchronously. \nThe returned ``User`` object has a ``profile`` property which contains the claims for the user.\nAdd this code to detect if the user is logged into the JavaScript application::\n\n    mgr.getUser().then(function (user) {\n        if (user) {\n            log(\"User logged in\", user.profile);\n        }\n        else {\n            log(\"User not logged in\");\n        }\n    });\n\nNext, we want to implement the ``login``, ``api``, and ``logout`` functions. \nThe ``UserManager`` provides a ``signinRedirect`` to log the user in, and a ``signoutRedirect`` to log the user out.\nThe ``User`` object that we obtained in the above code also has an ``access_token`` property which can be used to authenticate to a web API.\nThe ``access_token`` will be passed to the web API via the `Authorization` header with the `Bearer` scheme.\nAdd this code to implement those three functions in our application::\n\n    function login() {\n        mgr.signinRedirect();\n    }\n\n    function api() {\n        mgr.getUser().then(function (user) {\n            var url = \"https://localhost:6001/identity\";\n\n            var xhr = new XMLHttpRequest();\n            xhr.open(\"GET\", url);\n            xhr.onload = function () {\n                log(xhr.status, JSON.parse(xhr.responseText));\n            }\n            xhr.setRequestHeader(\"Authorization\", \"Bearer \" + user.access_token);\n            xhr.send();\n        });\n    }\n\n    function logout() {\n        mgr.signoutRedirect();\n    }\n\n.. Note:: See the :ref:`client credentials quickstart <refClientCredentialsQuickstart>` for information on how to create the api used in the code above.\n\n**callback.html**\n\nThis HTML file is the designated ``redirect_uri`` page once the user has logged into IdentityServer.\nIt will complete the OpenID Connect protocol sign-in handshake with IdentityServer. \nThe code for this is all provided by the ``UserManager`` class we used earlier. \nOnce the sign-in is complete, we can then redirect the user back to the main `index.html` page. \nAdd this code to complete the signin process::\n\n    <!DOCTYPE html>\n    <html>\n    <head>\n        <meta charset=\"utf-8\" />\n        <title></title>\n    </head>\n    <body>\n        <script src=\"oidc-client.js\"></script>\n        <script>\n            new Oidc.UserManager({response_mode:\"query\"}).signinRedirectCallback().then(function() {\n                window.location = \"index.html\";\n            }).catch(function(e) {\n                console.error(e);\n            });\n        </script>\n    </body>\n    </html>\n\nAdd a client registration to IdentityServer for the JavaScript client\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nNow that the client application is ready to go, we need to define a configuration entry in IdentityServer for this new JavaScript client.\nIn the IdentityServer project locate the client configuration (in `Config.cs`).\nAdd a new `Client` to the list for our new JavaScript application.\nIt should have the configuration listed below::\n\n    // JavaScript Client\n    new Client\n    {\n        ClientId = \"js\",\n        ClientName = \"JavaScript Client\",\n        AllowedGrantTypes = GrantTypes.Code,\n        RequireClientSecret = false,\n        \n        RedirectUris =           { \"https://localhost:5003/callback.html\" },\n        PostLogoutRedirectUris = { \"https://localhost:5003/index.html\" },\n        AllowedCorsOrigins =     { \"https://localhost:5003\" },\n\n        AllowedScopes = \n        {\n            IdentityServerConstants.StandardScopes.OpenId,\n            IdentityServerConstants.StandardScopes.Profile,\n            \"api1\"\n        }\n    }\n\nAllowing Ajax calls to the Web API with CORS\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nOne last bit of configuration that is necessary is to configure CORS in the web API project. \nThis will allow Ajax calls to be made from `https://localhost:5003` to `https://localhost:6001`.\n\n**Configure CORS**\n\nAdd the CORS services to the dependency injection system in ``ConfigureServices`` in `Startup.cs`::\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        // ...\n\n        services.AddCors(options =>\n        {\n            // this defines a CORS policy called \"default\"\n            options.AddPolicy(\"default\", policy =>\n            {\n                policy.WithOrigins(\"https://localhost:5003\")\n                    .AllowAnyHeader()\n                    .AllowAnyMethod();\n            });\n        });\n    }\n\nAdd the CORS middleware to the pipeline in ``Configure`` (just after routing)::\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseRouting();\n\n        app.UseCors(\"default\");\n\n        // ...\n    }\n\nRun the JavaScript application\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nNow you should be able to run the JavaScript client application:\n\n.. image:: images/jsclient_not_logged_in.png\n\nClick the \"Login\" button to sign the user in.\nOnce the user is returned back to the JavaScript application, you should see their profile information:\n \n.. image:: images/jsclient_logged_in.png\n\nAnd click the \"API\" button to invoke the web API:\n\n.. image:: images/jsclient_api_results.png\n\nAnd finally click \"Logout\" to sign the user out.\n\n.. image:: images/jsclient_signed_out.png\n\nYou now have the start of a JavaScript client application that uses IdentityServer for sign-in, sign-out, and authenticating calls to web APIs.\n"
  },
  {
    "path": "docs/quickstarts/5_entityframework.rst",
    "content": ".. _refEntityFrameworkQuickstart:\nUsing EntityFramework Core for configuration and operational data\n=================================================================\n\nIn the previous quickstarts, we created our client and scope data in code.\nOn startup, IdentityServer loaded this configuration data into memory.\nIf we wanted to modify this configuration data, we had to stop and start IdentityServer.\n\nIdentityServer also generates temporary data, such as authorization codes, consent choices, and refresh tokens.\nBy default, these are also stored in-memory.\n\nTo move this data into a database that is persistent between restarts and across multiple IdentityServer instances, we can use the IdentityServer8 Entity Framework library.\n\n.. Note:: In addition to manually configuring EF support, there is also an IdentityServer template to create a new project with EF support, using ``dotnet new is4ef``.\n\nIdentityServer8.EntityFramework\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n``IdentityServer8.EntityFramework`` implements the required stores and services using the following DbContexts:\n\n    * ConfigurationDbContext - used for configuration data such as clients, resources, and scopes\n    * PersistedGrantDbContext - used for temporary operational data such as authorization codes, and refresh tokens\n\nThese contexts are suitable for any Entity Framework Core compatible relational database.\n\nYou can find these contexts, their entities, and the IdentityServer8 stores that use them in the ``IdentityServer8.EntityFramework.Storage`` nuget package.\n\nYou can find the extension methods to register them in your IdentityServer in ``IdentityServer8.EntityFramework``, which we will do now::\n\n    dotnet add package IdentityServer8.EntityFramework\n\nUsing SqlServer\n^^^^^^^^^^^^^^^\n\nFor this quickstart, we will use the LocalDb version of SQLServer that comes with Visual Studio.\nTo add SQL Server support to our IdentityServer project, you’ll need the following nuget package::\n\n    dotnet add package Microsoft.EntityFrameworkCore.SqlServer\n\nDatabase Schema Changes and Using EF Migrations\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe ``IdentityServer8.EntityFramework.Storage`` package contains entity classes that map from IdentityServer’s models.\nAs IdentityServer’s models change, so will the entity classes in ``IdentityServer8.EntityFramework.Storage``.\nAs you use ``IdentityServer8.EntityFramework.Storage`` and upgrade over time, you are responsible for your database schema and changes necessary to that schema as the entity classes change.\nOne approach for managing those changes is to use `EF migrations <https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/index>`_, which is what we’ll use in this quickstart.\nIf migrations are not your preference, then you can manage the schema changes in any way you see fit.\n\n.. Note:: You can find the `latest SQL scripts <https://github.com/alexhiggins732/IdentityServer8/tree/main/src/EntityFramework.Storage/migrations/SqlServer/Migrations>`_ for SqlServer in the IdentityServer8.EntityFramework.Storage repository.\n\nConfiguring the Stores\n^^^^^^^^^^^^^^^^^^^^^^\n\nTo start using these stores, you’ll need to replace any existing calls to ``AddInMemoryClients``, ``AddInMemoryIdentityResources``, ``AddInMemoryApiScopes``, ``AddInMemoryApiResources``, and ``AddInMemoryPersistedGrants`` in your ``ConfigureServices`` method in `Startup.cs` with ``AddConfigurationStore`` and ``AddOperationalStore``.\n\nThese methods each require a ``DbContextOptionsBuilder``, meaning your code will look something like this::\n\n    var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;\n    const string connectionString = @\"Data Source=(LocalDb)\\MSSQLLocalDB;database=IdentityServer8.Quickstart.EntityFramework-4.0.0;trusted_connection=yes;\";\n\n    services.AddIdentityServer()\n        .AddTestUsers(TestUsers.Users)\n        .AddConfigurationStore(options =>\n        {\n            options.ConfigureDbContext = b => b.UseSqlServer(connectionString,\n                sql => sql.MigrationsAssembly(migrationsAssembly));\n        })\n        .AddOperationalStore(options =>\n        {\n            options.ConfigureDbContext = b => b.UseSqlServer(connectionString,\n                sql => sql.MigrationsAssembly(migrationsAssembly));\n        });\n\nYou might need these namespaces added to the file::\n\n    using Microsoft.EntityFrameworkCore;\n    using System.Reflection;\n\n\nBecause we are using EF migrations in this quickstart, the call to ``MigrationsAssembly`` is used to inform Entity Framework that the host project will contain the migrations code.\nThis is necessary since the host project is in a different assembly than the one that contains the ``DbContext`` classes.\n\nAdding Migrations\n^^^^^^^^^^^^^^^^^\n\nOnce the IdentityServer has been configured to use Entity Framework, we’ll need to generate some migrations.\n\nTo create migrations, you will need to install the Entity Framework Core CLI on your machine and the ``Microsoft.EntityFrameworkCore.Design`` nuget package in IdentityServer::\n\n    dotnet tool install --global dotnet-ef\n    dotnet add package Microsoft.EntityFrameworkCore.Design\n\nTo create the migrations, open a command prompt in the IdentityServer project directory and run the following two commands::\n\n    dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb\n    dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb\n\nYou should now see a ``~/Data/Migrations/IdentityServer`` folder in your project containing the code for your newly created migrations.\n\nInitializing the Database\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\nNow that we have the migrations, we can write code to create the database from the migrations.\nWe can also seed the database with the in-memory configuration data that we already defined in the previous quickstarts.\n\n.. Note:: The approach used in this quickstart is used to make it easy to get IdentityServer up and running. You should devise your own database creation and maintenance strategy that is appropriate for your architecture.\n\nIn `Startup.cs` add this method to help initialize the database::\n\n    private void InitializeDatabase(IApplicationBuilder app)\n    {\n        using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())\n        {\n            serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();\n\n            var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();\n            context.Database.Migrate();\n            if (!context.Clients.Any())\n            {\n                foreach (var client in Config.Clients)\n                {\n                    context.Clients.Add(client.ToEntity());\n                }\n                context.SaveChanges();\n            }\n\n            if (!context.IdentityResources.Any())\n            {\n                foreach (var resource in Config.IdentityResources)\n                {\n                    context.IdentityResources.Add(resource.ToEntity());\n                }\n                context.SaveChanges();\n            }\n\n            if (!context.ApiScopes.Any())\n            {\n                foreach (var resource in Config.ApiScopes)\n                {\n                    context.ApiScopes.Add(resource.ToEntity());\n                }\n                context.SaveChanges();\n            }\n        }\n    }\n\nThe above code may require you to add the following namespaces to your file::\n\n    using System.Linq;\n    using IdentityServer8.EntityFramework.DbContexts;\n    using IdentityServer8.EntityFramework.Mappers;\n\nAnd then we can invoke this from the ``Configure`` method::\n\n    public void Configure(IApplicationBuilder app)\n    {\n        // this will do the initial DB population\n        InitializeDatabase(app);\n\n        // the rest of the code that was already here\n        // ...\n    }\n\nNow if you run the IdentityServer project, the database should be created and seeded with the quickstart configuration data.\nYou should be able to use SQL Server Management Studio or Visual Studio to connect and inspect the data.\n\n.. image:: images/ef_database.png\n\n.. Note:: The above ``InitializeDatabase`` helper API is convenient to seed the database, but this approach is not ideal to leave in to execute each time the application runs. Once your database is populated, consider removing the call to the API.\n\nRun the client applications\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nYou should now be able to run any of the existing client applications and sign-in, get tokens, and call the API -- all based upon the database configuration.\n"
  },
  {
    "path": "docs/quickstarts/6_aspnet_identity.rst",
    "content": ".. _refAspNetIdentityQuickstart:\nUsing ASP.NET Core Identity\n===========================\n\n.. note:: For any pre-requisites (like e.g. templates) have a look at the :ref:`overview <refQuickstartOverview>` first.\n\nIdentityServer is designed for flexibility and part of that is allowing you to use any database you want for your users and their data (including passwords).\nIf you are starting with a new user database, then ASP.NET Core Identity is one option you could choose.\nThis quickstart shows how to use ASP.NET Core Identity with IdentityServer.\n\nThe approach this quickstart takes to using ASP.NET Core Identity is to create a new project for the IdentityServer host.\nThis new project will replace the prior IdentityServer project we built up in the previous quickstarts.\nThe reason for this new project is due to the differences in UI assets when using ASP.NET Core Identity (mainly around the differences in login and logout).\nAll the other projects in this solution (for the clients and the API) will remain the same.\n\n.. Note:: This quickstart assumes you are familiar with how ASP.NET Core Identity works. If you are not, it is recommended that you first `learn about it <https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity>`_.\n\nNew Project for ASP.NET Core Identity\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe first step is to add a new project for ASP.NET Core Identity to your solution.\nWe provide a template that contains the minimal UI assets needed to ASP.NET Core Identity with IdentityServer.\nYou will eventually delete the old project for IdentityServer, but there are some items that you will need to migrate over.\n\nStart by creating a new IdentityServer project that will use ASP.NET Core Identity::\n    \n    cd quickstart/src\n    dotnet new is4aspid -n IdentityServerAspNetIdentity\n\nWhen prompted to \"seed\" the user database, choose \"Y\" for \"yes\".\nThis populates the user database with our \"alice\" and \"bob\" users. \nTheir passwords are \"Pass123$\".\n\n.. Note:: The template uses Sqlite as the database for the users, and EF migrations are pre-created in the template. If you wish to use a different database provider, you will need to change the provider used in the code and re-create the EF migrations.\n\nInspect the new project\n^^^^^^^^^^^^^^^^^^^^^^^\n\nOpen the new project in the editor of your choice, and inspect the generated code.\nBe sure to look at:\n\nIdentityServerAspNetIdentity.csproj\n-----------------------------------\n\nNotice the reference to `IdentityServer8.AspNetIdentity`. \nThis NuGet package contains the ASP.NET Core Identity integration components for IdentityServer.\n\nStartup.cs\n----------\n\nIn `ConfigureServices` notice the necessary ``AddDbContext<ApplicationDbContext>`` and ``AddIdentity<ApplicationUser, IdentityRole>`` calls are done to configure ASP.NET Core Identity.\n\nAlso notice that much of the same IdentityServer configuration you did in the previous quickstarts is already done.\nThe template uses the in-memory style for clients and resources, and those are sourced from `Config.cs`.\n\nFinally, notice the addition of the new call to ``AddAspNetIdentity<ApplicationUser>``.\n``AddAspNetIdentity`` adds the integration layer to allow IdentityServer to access the user data for the ASP.NET Core Identity user database.\nThis is needed when IdentityServer must add claims for the users into tokens.\n\nNote that ``AddIdentity<ApplicationUser, IdentityRole>`` must be invoked before ``AddIdentityServer``.\n\nConfig.cs\n-----------\n\n`Config.cs` contains the hard-coded in-memory clients and resource definitions.\nTo keep the same clients and API working as the prior quickstarts, we need to copy over the configuration data from the old IdentityServer project into this one.\nDo that now, and afterwards `Config.cs` should look like this::\n\n    public static class Config\n    {\n        public static IEnumerable<IdentityResource> IdentityResources =>\n            new List<IdentityResource>\n            {\n                new IdentityResources.OpenId(),\n                new IdentityResources.Profile(),\n            };\n\n        public static IEnumerable<ApiScope> ApiScopes =>\n            new List<ApiScope>\n            {\n                new ApiScope(\"api1\", \"My API\")\n            };\n\n        public static IEnumerable<Client> Clients =>\n            new List<Client>\n            {\n                // machine to machine client\n                new Client\n                {\n                    ClientId = \"client\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.ClientCredentials,\n                    // scopes that client has access to\n                    AllowedScopes = { \"api1\" }\n                },\n                \n                // interactive ASP.NET Core MVC client\n                new Client\n                {\n                    ClientId = \"mvc\",\n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    \n                    // where to redirect to after login\n                    RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                    // where to redirect to after logout\n                    PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                    AllowedScopes = new List<string>\n                    {\n                        IdentityServerConstants.StandardScopes.OpenId,\n                        IdentityServerConstants.StandardScopes.Profile,\n                        \"api1\"\n                    }\n                }\n            };\n    }\n\n\nAt this point, you no longer need the old IdentityServer project.\n\nProgram.cs and SeedData.cs\n--------------------------\n\n`Program.cs`'s ``Main`` is a little different than most ASP.NET Core projects.\nNotice how this looks for a command line argument called `/seed` which is used as a flag to seed the users in the ASP.NET Core Identity database.\n\nLook at the ``SeedData`` class' code to see how the database is created and the first users are created.\n\nAccountController\n-----------------\n\nThe last code to inspect in this template is the ``AccountController``. \nThis contains a slightly different login and logout code than the prior quickstart and templates.\nNotice the use of the ``SignInManager<ApplicationUser>`` and ``UserManager<ApplicationUser>`` from ASP.NET Core Identity to validate credentials and manage the authentication session.\n\nMuch of the rest of the code is the same from the prior quickstarts and templates.\n\nLogging in with the MVC client\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAt this point, you should be able to run all of the existing clients and samples.\nOne exception is the `ResourceOwnerClient` -- the password will need to be updated to ``Pass123$`` from ``password``.\n\nLaunch the MVC client application, and you should be able to click the \"Secure\" link to get logged in.\n\n.. image:: images/aspid_mvc_client.png\n\nYou should be redirected to the ASP.NET Core Identity login page.\nLogin with your newly created user:\n\n.. image:: images/aspid_login.png\n\nAfter login you see the normal consent page. \nAfter consent you will be redirected back to the MVC client application where your user's claims should be listed.\n\n.. image:: images/aspid_claims.png\n\nYou should also be able to click \"Call API using application identity\" to invoke the API on behalf of the user:\n\n.. image:: images/aspid_api_claims.png\n\nAnd now you're using users from ASP.NET Core Identity in IdentityServer.\n\nWhat's Missing?\n^^^^^^^^^^^^^^^\n\nMuch of the rest of the code in this template is similar to the other quickstart and templates we provide.\nThe one thing you will notice that is missing from this template is UI code for user registration, password reset, and the other things you might expect from the Visual Studio ASP.NET Core Identity template.\n\nGiven the variety of requirements and different approaches to using ASP.NET Core Identity, our template deliberately does not provide those features.\nYou are expected to know how ASP.NET Core Identity works sufficiently well to add those features to your project.\nAlternatively, you can create a new project based on the Visual Studio ASP.NET Core Identity template and add the IdentityServer features you have learned about in these quickstarts to that project.\n"
  },
  {
    "path": "docs/quickstarts/community.rst",
    "content": "Community quickstarts & samples\n===============================\nThese samples are not maintained by the IdentityServer organization.\nThe IdentityServer organization happily links to community samples, but can't make any guarantees about the samples.\nPlease contact the authors directly.\n\nVarious ASP.NET Core security samples\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhttps://github.com/leastprivilege/AspNetCoreSecuritySamples\n\nCo-hosting IdentityServer8 and a Web API\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThis sample shows how to host an API in the same host as the IdentityServer that is protecting the API.\n\nhttps://github.com/brockallen/IdentityServerAndApi\n\nIdentityServer8 samples for MongoDB\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n* IdentityServer8-mongo: Similar to Quickstart EntityFramework configuration but using MongoDB for the configuration data.\n* IdentityServer8-mongo-AspIdentity: More elaborated sample based on uses ASP.NET Identity for identity management that uses using MongoDB for the configuration data\n\nhttps://github.com/souzartn/IdentityServer8.Samples.Mongo\n\nExchanging external tokens from Facebook, Google and Twitter\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n* Shows how to exchange an external authentication token to an identity server acesss token using an extension grant\n\nhttps://github.com/waqaskhan540/IdentityServerExternalAuth\n\n\n.NET Core and ASP.NET Core \"Platform\" scenario\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n* Shows an interaction of trusted \"internal\" applications and \"external\" applications with .NET Core 2.0 and ASP.NET Core 2.0 applications\nhttps://github.com/BenjaminAbt/Samples.AspNetCore-IdentityServer8\n\n\nSecuring a Node API with tokens from IdentityServer8 using JWKS\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n* Shows how to secure a Node (Express) API using the JWKS endpoint and RS256 algorithm from IdentityServer8.\n* Provides an alternative to the NodeJsApi sample from IdentityServer samples using higher quality - production ready modules.\n\nhttps://github.com/lyphtec/idsvr4-node-jwks\n"
  },
  {
    "path": "docs/readme.md",
    "content": "# IdentityServer8 documentation\n\nThe folder contains the documentation for IdentityServer8.\n\nWe are using [Read the docs](https://readthedocs.org/) to host the documentation and the rendered version\ncan be found [here](https://IdentityServer8.readthedocs.io).\n\nDoc pages are authored in ReStructuredText (RST) - you can find a primer [here](http://www.sphinx-doc.org/en/stable/rest.html).\n\nYou can find more information about RTD and Sphinx under the following links:\n\n* [Read the Docs documentation](https://docs.readthedocs.io/en/latest/index.html)\n* [Sphinx](http://www.sphinx-doc.org/)\n* [Getting started Screencast](https://www.youtube.com/watch?feature=player_embedded&v=oJsUvBQyHBs)\n"
  },
  {
    "path": "docs/reference/api_resource.rst",
    "content": ".. _refApiResource:\nAPI Resource\n=================\nThis class models an API resource.\n\n``Enabled``\n    Indicates if this resource is enabled and can be requested. Defaults to true.\n``Name``\n    The unique name of the API. This value is used for authentication with introspection and will be added to the audience of the outgoing access token.\n``DisplayName``\n    This value can be used e.g. on the consent screen.\n``Description``\n    This value can be used e.g. on the consent screen.\n``ApiSecrets``\n    The API secret is used for the introspection endpoint. The API can authenticate with introspection using the API name and secret.\n``AllowedAccessTokenSigningAlgorithms``\n    List of allowed signing algorithms for access token. If empty, will use the server default signing algorithm.\n``UserClaims``\n    List of associated user claim types that should be included in the access token.\n``Scopes``\n    List of API scope names.\n\nDefining API resources in appsettings.json\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThe ``AddInMemoryApiResource`` extensions method also supports adding API resources from the ASP.NET Core configuration file::\n\n    \"IdentityServer\": {\n        \"IssuerUri\": \"urn:sso.company.com\",\n        \"ApiResources\": [\n            {\n                \"Name\": \"resource1\",\n                \"DisplayName\": \"Resource #1\",\n\n                \"Scopes\": [\n                    \"resource1.scope1\",\n                    \"shared.scope\"\n                ]\n            },\n            {\n                \"Name\": \"resource2\",\n                \"DisplayName\": \"Resource #2\",\n                \n                \"UserClaims\": [\n                    \"name\",\n                    \"email\"\n                ],\n\n                \"Scopes\": [\n                    \"resource2.scope1\",\n                    \"shared.scope\"\n                ]\n            }\n        ]\n    }\n\nThen pass the configuration section to the ``AddInMemoryApiResource`` method::\n\n    AddInMemoryApiResources(configuration.GetSection(\"IdentityServer:ApiResources\"))\n"
  },
  {
    "path": "docs/reference/api_scope.rst",
    "content": ".. _refApiScope:\nAPI Scope\n=================\nThis class models an OAuth scope.\n\n``Enabled``\n    Indicates if this resource is enabled and can be requested. Defaults to true.\n``Name``\n    The unique name of the API. This value is used for authentication with introspection and will be added to the audience of the outgoing access token.\n``DisplayName``\n    This value can be used e.g. on the consent screen.\n``Description``\n    This value can be used e.g. on the consent screen.\n``UserClaims``\n    List of associated user claim types that should be included in the access token.\n\nDefining API scope in appsettings.json\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe ``AddInMemoryApiResource`` extension method also supports adding clients from the ASP.NET Core configuration file::\n\n    \"IdentityServer\": {\n        \"IssuerUri\": \"urn:sso.company.com\",\n        \"ApiScopes\": [\n            {\n                \"Name\": \"IdentityServerApi\"\n            },\n            {\n                \"Name\": \"resource1.scope1\"\n            },\n            {\n                \"Name\": \"resource2.scope1\"\n            },\n            {\n                \"Name\": \"scope3\"\n            },\n            {\n                \"Name\": \"shared.scope\"\n            },\n            {\n                \"Name\": \"transaction\",\n                \"DisplayName\": \"Transaction\",\n                \"Description\": \"A transaction\"\n            }\n        ]\n    }\n\nThen pass the configuration section to the ``AddInMemoryApiScopes`` method::\n\n    AddInMemoryApiScopes(configuration.GetSection(\"IdentityServer:ApiScopes\"))\n"
  },
  {
    "path": "docs/reference/aspnet_identity.rst",
    "content": ".. _refAspNetId:\nASP.NET Identity Support\n========================\n\nAn ASP.NET Identity-based implementation is provided for managing the identity database for users of IdentityServer.\nThis implementation implements the extensibility points in IdentityServer needed to load identity data for your users to emit claims into tokens.\n\nThe repo for this support is located `here <https://github.com/alexhiggins732/IdentityServer8.AspNetIdentity/>`_ and the NuGet package is `here <https://www.nuget.org/packages/HigginsSoft.IdentityServer8.AspNetIdentity>`_.\n\nTo use this library, configure ASP.NET Identity normally. \nThen use the ``AddAspNetIdentity`` extension method after the call to ``AddIdentityServer``::\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddIdentity<ApplicationUser, IdentityRole>()\n            .AddEntityFrameworkStores<ApplicationDbContext>()\n            .AddDefaultTokenProviders();\n\n        services.AddIdentityServer()\n            .AddAspNetIdentity<ApplicationUser>();\n    }\n\n``AddAspNetIdentity`` requires as a generic parameter the class that models your user for ASP.NET Identity (and the same one passed to ``AddIdentity`` to configure ASP.NET Identity).\nThis configures IdentityServer to use the ASP.NET Identity implementations of ``IUserClaimsPrincipalFactory``, ``IResourceOwnerPasswordValidator``, and ``IProfileService``.\nIt also configures some of ASP.NET Identity's options for use with IdentityServer (such as claim types to use and authentication cookie settings).\n\nWhen using your own implementation of ``IUserClaimsPrincipalFactory``, make sure that you register it before calling the IdentityServer ``AddAspNetIdentity`` extension method."
  },
  {
    "path": "docs/reference/client.rst",
    "content": ".. _refClient:\nClient\n======\nThe ``Client`` class models an OpenID Connect or OAuth 2.0 client - \ne.g. a native application, a web application or a JS-based application.\n\nBasics\n^^^^^^\n``Enabled``\n    Specifies if client is enabled. Defaults to `true`.\n``ClientId``\n    Unique ID of the client\n``ClientSecrets``\n    List of client secrets - credentials to access the token endpoint.\n``RequireClientSecret``\n    Specifies whether this client needs a secret to request tokens from the token endpoint (defaults to ``true``)\n``RequireRequestObject``\n    Specifies whether this client needs to wrap the authorize request parameters in a JWT (defaults to ``false``)\n``AllowedGrantTypes``\n    Specifies the grant types the client is allowed to use. Use the ``GrantTypes`` class for common combinations.\n``RequirePkce``\n    Specifies whether clients using an authorization code based grant type must send a proof key (defaults to ``true``).\n``AllowPlainTextPkce``\n    Specifies whether clients using PKCE can use a plain text code challenge (not recommended - and default to ``false``)\n``RedirectUris``\n    Specifies the allowed URIs to return tokens or authorization codes to\n``AllowedScopes``\n    By default a client has no access to any resources - specify the allowed resources by adding the corresponding scopes names\n``AllowOfflineAccess``\n    Specifies whether this client can request refresh tokens (be requesting the ``offline_access`` scope)\n``AllowAccessTokensViaBrowser``\n    Specifies whether this client is allowed to receive access tokens via the browser. \n    This is useful to harden flows that allow multiple response types \n    (e.g. by disallowing a hybrid flow client that is supposed to use `code id_token` to add the `token` response type \n    and thus leaking the token to the browser.\n``Properties``\n    Dictionary to hold any custom client-specific values as needed.\n\nAuthentication/Logout\n^^^^^^^^^^^^^^^^^^^^^\n``PostLogoutRedirectUris``\n    Specifies allowed URIs to redirect to after logout. See the `OIDC Connect Session Management spec <https://openid.net/specs/openid-connect-session-1_0.html>`_ for more details.\n``FrontChannelLogoutUri``\n    Specifies logout URI at client for HTTP based front-channel logout. See the `OIDC Front-Channel spec <https://openid.net/specs/openid-connect-frontchannel-1_0.html>`_ for more details.\n``FrontChannelLogoutSessionRequired``\n    Specifies if the user's session id should be sent to the FrontChannelLogoutUri. Defaults to true.\n``BackChannelLogoutUri``\n    Specifies logout URI at client for HTTP based back-channel logout. See the `OIDC Back-Channel spec <https://openid.net/specs/openid-connect-backchannel-1_0.html>`_ for more details.\n``BackChannelLogoutSessionRequired``\n    Specifies if the user's session id should be sent in the request to the BackChannelLogoutUri. Defaults to true.\n``EnableLocalLogin``\n    Specifies if this client can use local accounts, or external IdPs only. Defaults to `true`.\n``IdentityProviderRestrictions``\n    Specifies which external IdPs can be used with this client (if list is empty all IdPs are allowed). Defaults to empty.\n``UserSsoLifetime`` `added in 2.3`\n    The maximum duration (in seconds) since the last time the user authenticated. Defaults to ``null``.\n    You can adjust the lifetime of a session token to control when and how often a user is required to reenter credentials instead of being silently authenticated, when using a web application.\n\nToken\n^^^^^\n``IdentityTokenLifetime``\n    Lifetime to identity token in seconds (defaults to 300 seconds / 5 minutes)\n``AllowedIdentityTokenSigningAlgorithms``\n    List of allowed signing algorithms for identity token. If empty, will use the server default signing algorithm.\n``AccessTokenLifetime``\n    Lifetime of access token in seconds (defaults to 3600 seconds / 1 hour)\n``AuthorizationCodeLifetime``\n    Lifetime of authorization code in seconds (defaults to 300 seconds / 5 minutes)\n``AbsoluteRefreshTokenLifetime``\n    Maximum lifetime of a refresh token in seconds. Defaults to 2592000 seconds / 30 days\n``SlidingRefreshTokenLifetime``\n    Sliding lifetime of a refresh token in seconds. Defaults to 1296000 seconds / 15 days\n``RefreshTokenUsage``\n    ``ReUse`` the refresh token handle will stay the same when refreshing tokens\n    \n    ``OneTime`` the refresh token handle will be updated when refreshing tokens. This is the default.\n``RefreshTokenExpiration``\n    ``Absolute`` the refresh token will expire on a fixed point in time (specified by the AbsoluteRefreshTokenLifetime). This is the default.\n    \n    ``Sliding`` when refreshing the token, the lifetime of the refresh token will be renewed (by the amount specified in SlidingRefreshTokenLifetime). The lifetime will not exceed `AbsoluteRefreshTokenLifetime`.\n``UpdateAccessTokenClaimsOnRefresh``\n    Gets or sets a value indicating whether the access token (and its claims) should be updated on a refresh token request.\n``AccessTokenType``\n    Specifies whether the access token is a reference token or a self contained JWT token (defaults to `Jwt`).\n``IncludeJwtId``\n    Specifies whether JWT access tokens should have an embedded unique ID (via the `jti` claim). Defaults to ``true``.\n``AllowedCorsOrigins``\n    If specified, will be used by the default CORS policy service implementations (In-Memory and EF) to build a CORS policy for JavaScript clients.\n``Claims``\n    Allows settings claims for the client (will be included in the access token).\n``AlwaysSendClientClaims``\n    If set, the client claims will be sent for every flow. If not, only for client credentials flow (default is `false`)\n``AlwaysIncludeUserClaimsInIdToken``\n    When requesting both an id token and access token, should the user claims always be added to the id token instead of requiring the client to use the userinfo endpoint. Default is `false`.\n``ClientClaimsPrefix``\n    If set, the prefix client claim types will be prefixed with. Defaults to `client_`. The intent is to make sure they don't accidentally collide with user claims.\n``PairWiseSubjectSalt``\n    Salt value used in pair-wise subjectId generation for users of this client.\n\nConsent Screen\n^^^^^^^^^^^^^^\n``RequireConsent``\n    Specifies whether a consent screen is required. Defaults to ``false``.\n``AllowRememberConsent``\n    Specifies whether user can choose to store consent decisions. Defaults to ``true``.\n``ConsentLifetime``\n    Lifetime of a user consent in seconds. Defaults to null (no expiration).\n``ClientName``\n    Client display name (used for logging and consent screen)\n``ClientUri``\n    URI to further information about client (used on consent screen)\n``LogoUri``\n    URI to client logo (used on consent screen)\n\nDevice flow\n^^^^^^^^^^^\n``UserCodeType``\n    Specifies the type of user code to use for the client. Otherwise falls back to default.\n``DeviceCodeLifetime``\n    Lifetime to device code in seconds (defaults to 300 seconds / 5 minutes)\n"
  },
  {
    "path": "docs/reference/deviceflow_interactionservice.rst",
    "content": "Device Flow Interaction Service\n==================================\n\nThe ``IDeviceFlowInteractionService`` interface is intended to provide services to be used by the user interface to communicate with IdentityServer during device flow authorization.\nIt is available from the dependency injection system and would normally be injected as a constructor parameter into your MVC controllers for the user interface of IdentityServer.\n\nIDeviceFlowInteractionService APIs\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n``GetAuthorizationContextAsync``\n    Returns the ``DeviceFlowAuthorizationRequest`` based on the ``userCode`` passed to the login or consent pages.\n\n``DeviceFlowInteractionResult``\n    Completes device authorization for the given ``userCode``.\n\nDeviceFlowAuthorizationRequest\n^^^^^^^^^^^^^^^^^^^^\n``ClientId``\n    The client identifier that initiated the request.\n``ScopesRequested``\n    The scopes requested from the authorization request.\n\nDeviceFlowInteractionResult\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\n``IsError``\n    Specifies if the authorization request errored.\n``ErrorDescription``\n    Error description upon failure.\n"
  },
  {
    "path": "docs/reference/ef.rst",
    "content": ".. _refEF:\nEntity Framework Support\n========================\n\nAn EntityFramework-based implementation is provided for the configuration and operational data extensibility points in IdentityServer.\nThe use of EntityFramework allows any EF-supported database to be used with this library.\n\nThe code for this library is located `here <https://github.com/alexhiggins732/IdentityServer8/tree/main/src/EntityFramework>`_ (with the underlying storage code `here <https://github.com/alexhiggins732/IdentityServer8/tree/main/src/EntityFramework.Storage>`_) and the NuGet package is `here <https://www.nuget.org/packages/HigginsSoft.IdentityServer8.EntityFramework>`_.\n\nThe features provided by this library are broken down into two main areas: configuration store and operational store support.\nThese two different areas can be used independently or together, based upon the needs of the hosting application.\n\nConfiguration Store support for Clients, Resources, and CORS settings\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf client, identity resource, API resource, or CORS data is desired to be loaded from a EF-supported database \n(rather than use in-memory configuration), then the configuration store can be used.\nThis support provides implementations of the ``IClientStore``, ``IResourceStore``, and the ``ICorsPolicyService`` extensibility points.\nThese implementations use a ``DbContext``-derived class called ``ConfigurationDbContext`` to model the tables in the database.\n\nTo use the configuration store support, use the ``AddConfigurationStore`` extension method after the call to ``AddIdentityServer``::\n\n    public IServiceProvider ConfigureServices(IServiceCollection services)\n    {\n        const string connectionString = @\"Data Source=(LocalDb)\\MSSQLLocalDB;database=IdentityServer8.EntityFramework-2.0.0;trusted_connection=yes;\";\n        var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;\n        \n        services.AddIdentityServer()\n            // this adds the config data from DB (clients, resources, CORS)\n            .AddConfigurationStore(options =>\n            {\n                options.ConfigureDbContext = builder =>\n                    builder.UseSqlServer(connectionString,\n                        sql => sql.MigrationsAssembly(migrationsAssembly));\n            });\n    }\n\nTo configure the configuration store, use the ``ConfigurationStoreOptions`` options object passed to the configuration callback.\n\nConfigurationStoreOptions\n^^^^^^^^^^^^^^^^^^^^^^^^^\nThis options class contains properties to control the configuration store and ``ConfigurationDbContext``.\n\n``ConfigureDbContext``\n    Delegate of type ``Action<DbContextOptionsBuilder>`` used as a callback to configure the underlying ``ConfigurationDbContext``.\n    The delegate can configure the ``ConfigurationDbContext`` in the same way if EF were being used directly with ``AddDbContext``, which allows any EF-supported database to be used.\n``DefaultSchema``\n    Allows setting the default database schema name for all the tables in the ``ConfigurationDbContext``\n    ::\n            options.DefaultSchema = \"myConfigurationSchema\";      \n\nIf you need to change the schema for the Migration History Table, you can chain another action to the ``UseSqlServer``::\n\n    options.ConfigureDbContext = b =>\n        b.UseSqlServer(connectionString,\n            sql => sql.MigrationsAssembly(migrationsAssembly).MigrationsHistoryTable(\"MyConfigurationMigrationTable\", \"myConfigurationSchema\"));\n\nOperational Store support for persisted grants\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf :ref:`persisted grants <refPersistedGrants>` are desired to be loaded from a EF-supported database (rather than the default in-memory database), then the operational store can be used.\nThis support provides implementations of the ``IPersistedGrantStore`` extensibility point.\nThe implementation uses a ``DbContext``-derived class called ``PersistedGrantDbContext`` to model the table in the database.\n\nTo use the operational store support, use the ``AddOperationalStore`` extension method after the call to ``AddIdentityServer``::\n\n    public IServiceProvider ConfigureServices(IServiceCollection services)\n    {\n        const string connectionString = @\"Data Source=(LocalDb)\\MSSQLLocalDB;database=IdentityServer8.EntityFramework-2.0.0;trusted_connection=yes;\";\n        var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;\n        \n        services.AddIdentityServer()\n            // this adds the operational data from DB (codes, tokens, consents)\n            .AddOperationalStore(options =>\n            {\n                options.ConfigureDbContext = builder =>\n                    builder.UseSqlServer(connectionString,\n                        sql => sql.MigrationsAssembly(migrationsAssembly));\n\n                // this enables automatic token cleanup. this is optional.\n                options.EnableTokenCleanup = true;\n                options.TokenCleanupInterval = 3600; // interval in seconds (default is 3600)\n            });\n    }\n\nTo configure the operational store, use the ``OperationalStoreOptions`` options object passed to the configuration callback.\n\nOperationalStoreOptions\n^^^^^^^^^^^^^^^^^^^^^^^\nThis options class contains properties to control the operational store and ``PersistedGrantDbContext``.\n\n``ConfigureDbContext``\n    Delegate of type ``Action<DbContextOptionsBuilder>`` used as a callback to configure the underlying ``PersistedGrantDbContext``.\n    The delegate can configure the ``PersistedGrantDbContext`` in the same way if EF were being used directly with ``AddDbContext``, which allows any EF-supported database to be used.\n``DefaultSchema``\n    Allows setting the default database schema name for all the tables in the ``PersistedGrantDbContext``.\n``EnableTokenCleanup``\n    Indicates whether expired grants will be automatically cleaned up from the database. The default is ``false``.\n``TokenCleanupInterval``\n    The token cleanup interval (in seconds). The default is 3600 (1 hour).\n\n.. note:: The token cleanup feature does *not* remove persisted grants that are *consumed* (see :ref:`persisted grants <refPersistedGrants>`).\n\nDatabase creation and schema changes across different versions of IdentityServer\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIt is very likely that across different versions of IdentityServer (and the EF support) that the database schema will change to accommodate new and changing features.\n\nWe do not provide any support for creating your database or migrating your data from one version to another. \nYou are expected to manage the database creation, schema changes, and data migration in any way your organization sees fit.\n\nUsing EF migrations is one possible approach to this. \nIf you do wish to use migrations, then see the :ref:`EF quickstart <refEntityFrameworkQuickstart>` for samples on how to get started, or consult the Microsoft `documentation on EF migrations <https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/index>`_.\n\nWe also publish `sample SQL scripts <https://github.com/alexhiggins732/IdentityServer8/tree/main/src/EntityFramework.Storage/migrations/SqlServer/Migrations>`_ for the current version of the database schema.\n"
  },
  {
    "path": "docs/reference/grant_validation_result.rst",
    "content": ".. _refGrantValidationResult:\nGrantValidationResult\n=====================\n\nThe ``GrantValidationResult`` class models the outcome of grant validation for extensions grants and resource owner password grants.\n\nThe most common usage is to either new it up using an identity (success case)::\n\n    context.Result = new GrantValidationResult(\n        subject: \"818727\", \n        authenticationMethod: \"custom\", \n        claims: optionalClaims);\n\n...or using an error and description (failure case)::\n\n    context.Result = new GrantValidationResult(\n        TokenRequestErrors.InvalidGrant, \n        \"invalid custom credential\");\n\nIn both case you can pass additional custom values that will be included in the token response."
  },
  {
    "path": "docs/reference/identity_resource.rst",
    "content": ".. _refIdentityResource:\nIdentity Resource\n=================\n\nThis class models an identity resource.\n\n``Enabled``\n    Indicates if this resource is enabled and can be requested. Defaults to true.\n``Name``\n    The unique name of the identity resource. This is the value a client will use for the scope parameter in the authorize request.\n``DisplayName``\n    This value will be used e.g. on the consent screen.\n``Description``\n    This value will be used e.g. on the consent screen.\n``Required``\n    Specifies whether the user can de-select the scope on the consent screen (if the consent screen wants to implement such a feature). Defaults to false.\n``Emphasize``\n    Specifies whether the consent screen will emphasize this scope (if the consent screen wants to implement such a feature). Use this setting for sensitive or important scopes. Defaults to false.\n``ShowInDiscoveryDocument``\n    Specifies whether this scope is shown in the discovery document. Defaults to true.\n``UserClaims``\n    List of associated user claim types that should be included in the identity token."
  },
  {
    "path": "docs/reference/interactionservice.rst",
    "content": ".. _refInteractionService:\nIdentityServer Interaction Service\n==================================\n\nThe ``IIdentityServerInteractionService`` interface is intended to provide services to be used by the user interface to communicate with IdentityServer, mainly pertaining to user interaction.\nIt is available from the dependency injection system and would normally be injected as a constructor parameter into your MVC controllers for the user interface of IdentityServer.\n\nIIdentityServerInteractionService APIs\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n``GetAuthorizationContextAsync``\n    Returns the ``AuthorizationRequest`` based on the ``returnUrl`` passed to the login or consent pages.\n\n``IsValidReturnUrl``\n    Indicates if the ``returnUrl`` is a valid URL for redirect after login or consent.\n\n``GetErrorContextAsync``\n    Returns the ``ErrorMessage`` based on the ``errorId`` passed to the error page.\n\n``GetLogoutContextAsync``\n    Returns the ``LogoutRequest`` based on the ``logoutId`` passed to the logout page.\n\n``CreateLogoutContextAsync``\n    Used to create a ``logoutId`` if there is not one presently.\n    This creates a cookie capturing all the current state needed for signout and the ``logoutId`` identifies that cookie.\n    This is typically used when there is no current ``logoutId`` and the logout page must capture the current user's state needed for sign-out prior to redirecting to an external identity provider for signout.\n    The newly created ``logoutId`` would need to be round-tripped to the external identity provider at signout time, and then used on the signout callback page in the same way it would be on the normal logout page.\n\n``GrantConsentAsync``\n    Accepts a ``ConsentResponse`` to inform IdentityServer of the user's consent to a particular ``AuthorizationRequest``.\n\n``DenyAuthorizationAsync``\n    Accepts a ``AuthorizationError`` to inform IdentityServer of the error to return to the client for a particular ``AuthorizationRequest``.\n\n``GetAllUserGrantsAsync``\n    Returns a collection of ``Grant`` for the user. These represent a user's consent or a clients access to a user's resource.\n\n``RevokeUserConsentAsync``\n    Revokes all of a user's consents and grants for a client.\n\n``RevokeTokensForCurrentSessionAsync``\n    Revokes all of a user's consents and grants for clients the user has signed into during their current session.\n\nAuthorizationRequest\n^^^^^^^^^^^^^^^^^^^^\n``Client``\n    The client that initiated the request.\n``RedirectUri``\n    The URI to redirect the user to after successful authorization.\n``DisplayMode``\n    The display mode passed from the authorization request.\n``UiLocales``\n    The UI locales passed from the authorization request.\n``IdP``\n    The external identity provider requested.\n    This is used to bypass home realm discovery (HRD).\n    This is provided via the \"idp:\" prefix to the ``acr_values`` parameter on the authorize request.\n``Tenant``\n    The tenant requested.\n    This is provided via the \"tenant:\" prefix to the ``acr_values`` parameter on the authorize request.\n``LoginHint``\n    The expected username the user will use to login.\n    This is requested from the client via the ``login_hint`` parameter on the authorize request.\n``PromptMode``\n    The prompt mode requested from the authorization request.\n``AcrValues``\n    The acr values passed from the authorization request.\n``ValidatedResources``\n    The ``ResourceValidationResult`` which represents the validated resources from the authorization request.\n``Parameters``\n    The entire parameter collection passed to the authorization request.\n``RequestObjectValues``\n    The validated contents of the request object (if present).\n\nResourceValidationResult\n^^^^^^^^^^^^^^^^^^^^^^^^\n``Resources``\n    The resources of the result.\n``ParsedScopes``\n    The parsed scopes represented by the result.\n``RawScopeValues``\n    The original (raw) scope values represented by the validated result.\n\nErrorMessage\n^^^^^^^^^^^^\n``DisplayMode``\n    The display mode passed from the authorization request.\n``UiLocales``\n    The UI locales passed from the authorization request.\n``Error``\n    The error code.\n``RequestId``\n    The per-request identifier. This can be used to display to the end user and can be used in diagnostics.\n\nLogoutRequest\n^^^^^^^^^^^^^\n``ClientId``\n    The client identifier that initiated the request.\n``PostLogoutRedirectUri``\n    The URL to redirect the user to after they have logged out.\n``SessionId``\n    The user's current session id.\n``SignOutIFrameUrl``\n    The URL to render in an ``<iframe>`` on the logged out page to enable single sign-out.\n``Parameters``\n    The entire parameter collection passed to the end session endpoint.\n``ShowSignoutPrompt``\n    Indicates if the user should be prompted for signout based upon the parameters passed to the end session endpoint.\n\nConsentResponse\n^^^^^^^^^^^^^^^\n``ScopesValuesConsented``\n    The collection of scopes the user consented to.\n``RememberConsent``\n    Flag indicating if the user's consent is to be persisted.\n``Description``\n    Optional description the user can set for the grant (e.g. the name of the device being used when consent is given). This can be presented back to the user from the :ref:`persisted grant service <refPersistedGrants>`.\n``Error``\n    Error, if any, for the consent response. This will be returned to the client in the authorization response.\n``ErrorDescription``\n    Error description. This will be returned to the client in the authorization response.\n\nGrant\n^^^^^\n``SubjectId``\n    The subject id that allowed the grant.\n``ClientId``\n    The client identifier for the grant.\n``Description``\n    The description the user assigned to the client or device being authorized.\n``Scopes``\n    The collection of scopes granted.\n``CreationTime``\n    The date and time when the grant was granted.\n``Expiration``\n    The date and time when the grant will expire.\n"
  },
  {
    "path": "docs/reference/options.rst",
    "content": ".. _refOptions:\nIdentityServer Options\n======================\n\n* ``IssuerUri``\n    Set the issuer name that will appear in the discovery document and the issued JWT tokens.\n    It is recommended to not set this property, which infers the issuer name from the host name that is used by the clients.\n\n* ``LowerCaseIssuerUri``\n    Set to ``false`` to preserve the original casing of the IssuerUri. Defaults to ``true``.\n\n* ``AccessTokenJwtType``\n    Specifies the value used for the JWT typ header for access tokens (defaults to ``at+jwt``).\n\n* ``EmitScopesAsSpaceDelimitedStringInJwt``\n    Specifies whether scopes in JWTs are emitted as array or string\n\n* ``EmitStaticAudienceClaim``\n    Emits an ``aud`` claim with the format issuer/resources. Defaults to false.\n\nEndpoints\n^^^^^^^^^\nAllows enabling/disabling individual endpoints, e.g. token, authorize, userinfo etc.\n\nBy default all endpoints are enabled, but you can lock down your server by disabling endpoint that you don't need.\n\n* ``EnableJwtRequestUri``\n    JWT request_uri processing is enabled on the authorize endpoint. Defaults to ``false``.\n\nDiscovery\n^^^^^^^^^\nAllows enabling/disabling various sections of the discovery document, e.g. endpoints, scopes, claims, grant types etc.\n\nThe ``CustomEntries`` dictionary allows adding custom elements to the discovery document.\n\nAuthentication\n^^^^^^^^^^^^^^\n* ``CookieAuthenticationScheme``\n    Sets the cookie authentication scheme configured by the host used for interactive users. If not set, the scheme will be inferred from the host's default authentication scheme. This setting is typically used when AddPolicyScheme is used in the host as the default scheme.\n\n* ``CookieLifetime``\n    The authentication cookie lifetime (only effective if the IdentityServer-provided cookie handler is used).\n\n* ``CookieSlidingExpiration``\n    Specifies if the cookie should be sliding or not (only effective if the IdentityServer-provided cookie handler is used).\n\n* ``CookieSameSiteMode``\n    Specifies the SameSite mode for the internal cookies.\n\n* ``RequireAuthenticatedUserForSignOutMessage``\n    Indicates if user must be authenticated to accept parameters to end session endpoint. Defaults to false.\n\n* ``CheckSessionCookieName``\n    The name of the cookie used for the check session endpoint.\n\n* ``CheckSessionCookieDomain``\n    The domain of the cookie used for the check session endpoint.\n\n* ``CheckSessionCookieSameSiteMode``\n    The SameSite mode of the cookie used for the check session endpoint.\n\n* ``RequireCspFrameSrcForSignout``\n    If set, will require frame-src CSP headers being emitting on the end session callback endpoint which renders iframes to clients for front-channel signout notification. Defaults to true.\n\nEvents\n^^^^^^\nAllows configuring if and which events should be submitted to a registered event sink. See :ref:`here <refEvents>` for more information on events.\n\nInputLengthRestrictions\n^^^^^^^^^^^^^^^^^^^^^^^\nAllows setting length restrictions on various protocol parameters like client id, scope, redirect URI etc.\n\nUserInteraction\n^^^^^^^^^^^^^^^\n\n* ``LoginUrl``, ``LogoutUrl``, ``ConsentUrl``, ``ErrorUrl``, ``DeviceVerificationUrl``\n    Sets the URLs for the login, logout, consent, error and device verification pages.\n* ``LoginReturnUrlParameter``\n    Sets the name of the return URL parameter passed to the login page. Defaults to *returnUrl*.\n* ``LogoutIdParameter``\n    Sets the name of the logout message id parameter passed to the logout page. Defaults to *logoutId*.\n* ``ConsentReturnUrlParameter``\n    Sets the name of the return URL parameter passed to the consent page. Defaults to *returnUrl*.\n* ``ErrorIdParameter``\n    Sets the name of the error message id parameter passed to the error page. Defaults to *errorId*.\n* ``CustomRedirectReturnUrlParameter``\n    Sets the name of the return URL parameter passed to a custom redirect from the authorization endpoint. Defaults to *returnUrl*.\n* ``DeviceVerificationUserCodeParameter``\n    Sets the name of the user code parameter passed to the device verification page. Defaults to *userCode*.\n* ``CookieMessageThreshold``\n    Certain interactions between IdentityServer and some UI pages require a cookie to pass state and context (any of the pages above that have a configurable \"message id\" parameter).\n    Since browsers have limits on the number of cookies and their size, this setting is used to prevent too many cookies being created. \n    The value sets the maximum number of message cookies of any type that will be created.\n    The oldest message cookies will be purged once the limit has been reached.\n    This effectively indicates how many tabs can be opened by a user when using IdentityServer.\n\nCaching\n^^^^^^^\nThese settings only apply if the respective caching has been enabled in the services configuration in startup.\n\n* ``ClientStoreExpiration``\n    Cache duration of client configuration loaded from the client store.\n\n* ``ResourceStoreExpiration``\n    Cache duration of identity and API resource configuration loaded from the resource store.\n\nCORS\n^^^^\nIdentityServer supports CORS for some of its endpoints.\nThe underlying CORS implementation is provided from ASP.NET Core, and as such it is automatically registered in the dependency injection system.\n\n* ``CorsPolicyName``\n    Name of the CORS policy that will be evaluated for CORS requests into IdentityServer (defaults to ``\"IdentityServer8\"``).\n    The policy provider that handles this is implemented in terms of the ``ICorsPolicyService`` registered in the dependency injection system.\n    If you wish to customize the set of CORS origins allowed to connect, then it is recommended that you provide a custom implementation of ``ICorsPolicyService``.\n\n* ``CorsPaths``\n    The endpoints within IdentityServer where CORS is supported. \n    Defaults to the discovery, user info, token, and revocation endpoints.\n\n* ``PreflightCacheDuration``\n    `Nullable<TimeSpan>` indicating the value to be used in the preflight `Access-Control-Max-Age` response header.\n    Defaults to `null` indicating no caching header is set on the response.\n\nCSP (Content Security Policy)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIdentityServer emits CSP headers for some responses, where appropriate.\n\n* ``Level``\n    The level of CSP to use. CSP Level 2 is used by default, but if older browsers must be supported then this be changed to ``CspLevel.One`` to accommodate them.\n\n* ``AddDeprecatedHeader``\n    Indicates if the older ``X-Content-Security-Policy`` CSP header should also be emitted (in addition to the standards-based header value). Defaults to true.\n\nDevice Flow\n^^^^^^^^^^^\n\n* ``DefaultUserCodeType``\n    The user code type to use, unless set at the client level. Defaults to *Numeric*, a 9-digit code.\n* ``Interval``\n    Defines the minimum allowed polling interval on the token endpoint. Defaults to *5*.\n\nMutual TLS\n^^^^^^^^^^\n\n* ``Enabled``\n    Specifies if MTLS support should be enabled. Defaults to ``false``.\n* ``ClientCertificateAuthenticationScheme``\n    Specifies the name of the authentication handler for X.509 client certificates. Defaults to ``\"Certificate\"``.\n* ``DomainName``\n    Specifies either the name of the sub-domain or full domain for running the MTLS endpoints (will use path-based endpoints if not set).\n    Use a simple string (e.g. \"mtls\") to set a sub-domain, use a full domain name (e.g. \"identityserver-mtls.io\") to set a full domain name.\n    When a full domain name is used, you also need to set the ``IssuerName`` to a fixed value.\n* ``AlwaysEmitConfirmationClaim``\n    Specifies whether a cnf claim gets emitted for access tokens if a client certificate was present.\n    Normally the cnf claims only gets emitted if the client used the client certificate for authentication,\n    setting this to true, will set the claim regardless of the authentication method. (defaults to false).\n"
  },
  {
    "path": "docs/reference/profileservice.rst",
    "content": ".. _refProfileService:\nProfile Service\n===============\n\nOften IdentityServer requires identity information about users when creating tokens or when handling requests to the userinfo or introspection endpoints.\nBy default, IdentityServer only has the claims in the authentication cookie to draw upon for this identity data.\n\nIt is impractical to put all of the possible claims needed for users into the cookie, so IdentityServer defines an extensibility point for allowing claims to be dynamically loaded as needed for a user.\nThis extensibility point is the ``IProfileService`` and it is common for a developer to implement this interface to access a custom database or API that contains the identity data for users.\n\nIProfileService APIs\n^^^^^^^^^^^^^^^^^^^^\n\n``GetProfileDataAsync``\n    The API that is expected to load claims for a user. It is passed an instance of ``ProfileDataRequestContext``.\n\n``IsActiveAsync``\n    The API that is expected to indicate if a user is currently allowed to obtain tokens. It is passed an instance of ``IsActiveContext``.\n\nProfileDataRequestContext\n^^^^^^^^^^^^^^^^^^^^^^^^^\n\nModels the request for user claims and is the vehicle to return those claims. It contains these properties:\n\n``Subject``\n    The ``ClaimsPrincipal`` modeling the user.\n``Client``\n    The ``Client`` for which the claims are being requested.\n``RequestedClaimTypes``\n    The collection of claim types being requested.\n``Caller``\n    An identifier for the context in which the claims are being requested (e.g. an identity token, an access token, or the user info endpoint). The constant ``IdentityServerConstants.ProfileDataCallers`` contains the different constant values.\n``IssuedClaims``\n    The list of ``Claim`` s that will be returned. This is expected to be populated by the custom ``IProfileService`` implementation.\n``AddRequestedClaims``\n    Extension method on the ``ProfileDataRequestContext`` to populate the ``IssuedClaims``, but first filters the claims based on ``RequestedClaimTypes``.\n\nRequested scopes and claims mapping\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe scopes requested by the client control what user claims are returned in the tokens to the client. \nThe ``GetProfileDataAsync`` method is responsible for dynamically obtaining those claims based on the ``RequestedClaimTypes`` collection on the ``ProfileDataRequestContext``.\n\nThe ``RequestedClaimTypes`` collection is populated based on the user claims defined on the :ref:`resources <refResources>` that model the scopes.\nIf requesting an identity token and the scopes requested are an :ref:`identity resources <refIdentityResource>`, then the claims in the ``RequestedClaimTypes`` will be populated based on the user claim types defined in the ``IdentityResource``.\nIf requesting an access token and the scopes requested are an :ref:`API resources <refApiResource>`, then the claims in the ``RequestedClaimTypes`` will be populated based on the user claim types defined in the ``ApiResource`` and/or the ``Scope``.\n\nIsActiveContext\n^^^^^^^^^^^^^^^\n\nModels the request to determine if the user is currently allowed to obtain tokens. It contains these properties:\n\n``Subject``\n    The ``ClaimsPrincipal`` modeling the user.\n``Client``\n    The ``Client`` for which the claims are being requested.\n``Caller``\n    An identifier for the context in which the claims are being requested (e.g. an identity token, an access token, or the user info endpoint). The constant ``IdentityServerConstants.ProfileDataCallers`` contains the different constant values.\n``IsActive``\n    The flag indicating if the user is allowed to obtain tokens. This is expected to be assigned by the custom ``IProfileService`` implementation.\n"
  },
  {
    "path": "docs/requirements.txt",
    "content": "sphinx==7.1.2\nsphinx-rtd-theme==1.3.0rc1"
  },
  {
    "path": "docs/topics/add_apis.rst",
    "content": "Adding more API Endpoints\n=========================\nIt's a common scenario to add additional API endpoints to the application hosting IdentityServer.\nThese endpoints are typically protected by IdentityServer itself.\n\nFor simple scenarios, we give you some helpers. See the advanced section to understand more of the internal plumbing.\n\n.. note:: You could achieve the same by using either our ``IdentityServerAuthentication`` handler or Microsoft's ``JwtBearer`` handler. But this is not recommended since it requires more configuration and creates dependencies on external libraries that might lead to conflicts in future updates.\n\nStart by registering your API as an ``ApiResource``, e.g.::\n\n    public static IEnumerable<ApiResource> Apis = new List<ApiResource>\n    {\n        // local API\n        new ApiResource(IdentityServerConstants.LocalApi.ScopeName),\n    };\n\n..and give your clients access to this API, e.g.::\n\n    new Client\n    {\n        // rest omitted\n        AllowedScopes = { IdentityServerConstants.LocalApi.ScopeName },   \n    }\n\n.. note:: The value of ``IdentityServerConstants.LocalApi.ScopeName`` is ``IdentityServerApi``.\n\nTo enable token validation for local APIs, add the following to your IdentityServer startup::\n\n    services.AddLocalApiAuthentication();\n\nTo protect an API controller, decorate it with an ``Authorize`` attribute using the ``LocalApi.PolicyName`` policy::\n\n    [Route(\"localApi\")]\n    [Authorize(LocalApi.PolicyName)]\n    public class LocalApiController : ControllerBase\n    {\n        public IActionResult Get()\n        {\n            // omitted\n        }\n    }\n\nAuthorized clients can then request a token for the ``IdentityServerApi`` scope and use it to call the API.\n\nDiscovery\n^^^^^^^^^\nYou can also add your endpoints to the discovery document if you want, e.g like this::\n\n    services.AddIdentityServer(options =>\n    {\n        options.Discovery.CustomEntries.Add(\"local_api\", \"~/localapi\");\n    })\n\nAdvanced\n^^^^^^^^\nUnder the covers, the ``AddLocalApiAuthentication`` helper does a couple of things:\n\n* adds an authentication handler that validates incoming tokens using IdentityServer's built-in token validation engine (the name of this handler is ``IdentityServerAccessToken`` or ``IdentityServerConstants.LocalApi.AuthenticationScheme``\n* configures the authentication handler to require a scope claim inside the access token of value ``IdentityServerApi``\n* sets up an authorization policy that checks for a scope claim of value ``IdentityServerApi``\n\nThis covers the most common scenarios. You can customize this behavior in the following ways:\n\n* Add the authentication handler yourself by calling ``services.AddAuthentication().AddLocalApi(...)``\n    * this way you can specify the required scope name yourself, or (by specifying no scope at all) accept any token from the current IdentityServer instance\n* Do your own scope validation/authorization in your controllers using custom policies or code, e.g.::\n\n    services.AddAuthorization(options =>\n    {\n        options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy =>\n        {\n            policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme);\n            policy.RequireAuthenticatedUser();\n            // custom requirements\n        });\n    });\n\nClaims Transformation\n^^^^^^^^^^^^^^^^^^^^^\nYou can provide a callback to transform the claims of the incoming token after validation.\nEither use the helper method, e.g.::\n\n    services.AddLocalApiAuthentication(principal =>\n    {\n        principal.Identities.First().AddClaim(new Claim(\"additional_claim\", \"additional_value\"));\n\n        return Task.FromResult(principal);\n    });\n    \n...or implement the event on the options if you add the authentication handler manually.\n"
  },
  {
    "path": "docs/topics/add_protocols.rst",
    "content": "Adding new Protocols\n====================\n\nIdentityServer8 allows adding support for other protocols besides the built-in \nsupport for OpenID Connect and OAuth 2.0.\n\nYou can add those additional protocol endpoints either as middleware or using e.g. MVC controllers.\nIn both cases you have access to the ASP.NET Core DI system which allows re-using our\ninternal services like access to client definitions or key material.\n\nA sample for adding WS-Federation support can be found `here <https://github.com/alexhiggins732/IdentityServer8.WsFederation>`_.\n\nTypical authentication workflow\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAn authentication request typically works like this:\n\n* authentication request arrives at protocol endpoint\n* protocol endpoint does input validation\n* redirection to login page with a return URL set back to protocol endpoint (if user is anonymous)\n    * access to current request details via the ``IIdentityServerInteractionService``\n    * authentication of user (either locally or via external authentication middleware)\n    * signing in the user\n    * redirect back to protocol endpoint\n* creation of protocol response (token creation and redirect back to client)\n\nUseful IdentityServer services\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nTo achieve the above workflow, some interaction points with IdentityServer are needed.\n\n**Access to configuration and redirecting to the login page**\n\nYou can get access to the IdentityServer configuration by injecting the ``IdentityServerOptions``\nclass into your code. This, e.g. has the configured path to the login page::\n\n    var returnUrl = Url.Action(\"Index\");\n    returnUrl = returnUrl.AddQueryString(Request.QueryString.Value);\n\n    var loginUrl = _options.UserInteraction.LoginUrl;\n    var url = loginUrl.AddQueryString(_options.UserInteraction.LoginReturnUrlParameter, returnUrl);\n\n    return Redirect(url);\n\n**Interaction between the login page and current protocol request**\n\nThe ``IIdentityServerInteractionService`` supports turning a protocol return URL into a \nparsed and validated context object::\n\n    var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n\nBy default the interaction service only understands OpenID Connect protocol messages.\nTo extend support, you can write your own ``IReturnUrlParser``::\n\n    public interface IReturnUrlParser\n    {\n        bool IsValidReturnUrl(string returnUrl);\n        Task<AuthorizationRequest> ParseAsync(string returnUrl);\n    }\n\n..and then register the parser in DI::\n\n    builder.Services.AddTransient<IReturnUrlParser, WsFederationReturnUrlParser>();\n\nThis allows the login page to get to information like the client configuration and other \nprotocol parameters.\n\n**Access to configuration and key material for creating the protocol response**\n\nBy injecting the ``IKeyMaterialService`` into your code, you get access to the configured \nsigning credential and validation keys::\n\n    var credential = await _keys.GetSigningCredentialsAsync();\n    var key = credential.Key as Microsoft.IdentityModel.Tokens.X509SecurityKey; \n        \n    var descriptor = new SecurityTokenDescriptor\n    {\n        AppliesToAddress = result.Client.ClientId,\n        Lifetime = new Lifetime(DateTime.UtcNow, DateTime.UtcNow.AddSeconds(result.Client.IdentityTokenLifetime)),\n        ReplyToAddress = result.Client.RedirectUris.First(),\n        SigningCredentials = new X509SigningCredentials(key.Certificate, result.RelyingParty.SignatureAlgorithm, result.RelyingParty.DigestAlgorithm),\n        Subject = outgoingSubject,\n        TokenIssuerName = _contextAccessor.HttpContext.GetIdentityServerIssuerUri(),\n        TokenType = result.RelyingParty.TokenType\n    };"
  },
  {
    "path": "docs/topics/apis.rst",
    "content": ".. _refProtectingApis:\nProtecting APIs\n===============\nIdentityServer issues access tokens in the `JWT <https://tools.ietf.org/html/rfc7519>`_ (JSON Web Token) format by default.\n\nEvery relevant platform today has support for validating JWT tokens, a good list of JWT libraries can be found `here <https://jwt.io>`_.\nPopular libraries are e.g.:\n\n* `JWT bearer authentication handler <https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer/>`_ for ASP.NET Core\n* `JWT bearer authentication middleware <https://www.nuget.org/packages/Microsoft.Owin.Security.Jwt>`_ for Katana\n\nProtecting an ASP.NET Core-based API is only a matter of adding the JWT bearer authentication handler::\n\n    public class Startup\n    {\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)\n                .AddJwtBearer(options =>\n                {\n                    // base-address of your identityserver\n                    options.Authority = \"https://demo.identityserver8.io\";\n\n                    // if you are using API resources, you can specify the name here\n                    options.Audience = \"resource1\";\n\n                    // IdentityServer emits a typ header by default, recommended extra check\n                    options.TokenValidationParameters.ValidTypes = new[] { \"at+jwt\" };\n                });\n        }\n    }\n\n.. note:: If you are not using the audience claim, you can turn off the audience check via ``options.TokenValidationParameters.ValidateAudience = false;``. See :ref:`here <refApiResources>` for more information on resources, scopes, audiences and authorization.\n\nValidating reference tokens\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIf you are using reference tokens, you need an authentication handler that implements `OAuth 2.0 token introspection <https://tools.ietf.org/html/rfc7662>`_, \ne.g. `this one <https://github.com/IdentityModel/IdentityModel.AspNetCore.OAuth2Introspection>`_:: \n\n    services.AddAuthentication(\"token\")\n        .AddOAuth2Introspection(\"token\", options =>\n        {\n            options.Authority = Constants.Authority;\n\n            // this maps to the API resource name and secret\n            options.ClientId = \"resource1\";\n            options.ClientSecret = \"secret\";\n        });\n\nSupporting both JWTs and reference tokens\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou can setup ASP.NET Core to dispatch to the right handler based on the incoming token, see `this <https://leastprivilege.com/2020/07/06/flexible-access-token-validation-in-asp-net-core/>`_ blog post for more information.\nIn this case you setup one default handler, and some forwarding logic, e.g.::\n\n    services.AddAuthentication(\"token\")\n\n        // JWT tokens\n        .AddJwtBearer(\"token\", options =>\n        {\n            options.Authority = Constants.Authority;\n            options.Audience = \"resource1\";\n\n            options.TokenValidationParameters.ValidTypes = new[] { \"at+jwt\" };\n\n            // if token does not contain a dot, it is a reference token\n            options.ForwardDefaultSelector = Selector.ForwardReferenceToken(\"introspection\");\n        })\n\n        // reference tokens\n        .AddOAuth2Introspection(\"introspection\", options =>\n        {\n            options.Authority = Constants.Authority;\n\n            options.ClientId = \"resource1\";\n            options.ClientSecret = \"secret\";\n        });"
  },
  {
    "path": "docs/topics/client_authentication.rst",
    "content": "Client Authentication\n=====================\nIn certain situations, clients need to authenticate with IdentityServer, e.g.\n\n* confidential applications (aka clients) requesting tokens at the token endpoint\n* APIs validating reference tokens at the introspection endpoint\n\nFor that purpose you can assign a list of secrets to a client or an API resource.\n\nSecret parsing and validation is an extensibility point in identityserver, out of the box it supports shared secrets\nas well as transmitting the shared secret via a basic authentication header or the POST body.\n\nCreating a shared secret\n^^^^^^^^^^^^^^^^^^^^^^^^\nThe following code sets up a hashed shared secret::\n\n    var secret = new Secret(\"secret\".Sha256());\n\nThis secret can now be assigned to either a ``Client`` or an ``ApiResource``. \nNotice that both do not only support a single secret, but multiple. This is useful for secret rollover and rotation::\n\n    var client = new Client\n    {\n        ClientId = \"client\",\n        ClientSecrets = new List<Secret> { secret },\n\n        AllowedGrantTypes = GrantTypes.ClientCredentials,\n        AllowedScopes = \n        {\n            \"api1\", \"api2\"\n        }\n    };\n\nIn fact you can also assign a description and an expiration date to a secret. The description will be used for logging, and \nthe expiration date for enforcing a secret lifetime::\n\n    var secret = new Secret(\n        \"secret\".Sha256(), \n        \"2016 secret\", \n        new DateTime(2016, 12, 31));  \n\nAuthentication using a shared secret\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou can either send the client id/secret combination as part of the POST body::\n\n    POST /connect/token\n    \n    client_id=client1&\n    client_secret=secret&\n    ...\n\n..or as a basic authentication header::\n\n    POST /connect/token\n    \n    Authorization: Basic xxxxx\n\n    ...\n\nYou can manually create a basic authentication header using the following C# code::\n\n    var credentials = string.Format(\"{0}:{1}\", clientId, clientSecret);\n    var headerValue = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));\n\n    var client = new HttpClient();\n    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Basic\", headerValue);\n\nThe `IdentityModel <https://github.com/IdentityModel/IdentityModel>`_ library has helper classes called ``TokenClient`` and ``IntrospectionClient`` that encapsulate\nboth authentication and protocol messages.\n\nAuthentication using an asymmetric Key\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThere are other techniques to authenticate clients, e.g. based on public/private key cryptography.\nIdentityServer includes support for private key JWT client secrets (see `RFC 7523 <https://tools.ietf.org/html/rfc7523>`_\nand `here <https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication>`_).\n\nSecret extensibility typically consists of three things:\n\n* a secret definition\n* a secret parser that knows how to extract the secret from the incoming request\n* a secret validator that knows how to validate the parsed secret based on the definition\n\nSecret parsers and validators are implementations of the ``ISecretParser`` and ``ISecretValidator`` interfaces. \nTo make them available to IdentityServer, you need to register them with the DI container, e.g.::\n\n    builder.AddSecretParser<JwtBearerClientAssertionSecretParser>()\n    builder.AddSecretValidator<PrivateKeyJwtSecretValidator>()\n\nOur default private key JWT secret validator expects the full (leaf) certificate as base64 on the secret definition \nor an ESA/EC JSON web key::\n\n    var client = new Client\n    {\n        ClientId = \"client.jwt\",\n        ClientSecrets =\n        {\n            new Secret\n            {\n                Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                Value = \"MIIDATCCAe2gAwIBAgIQoHUYAquk9rBJcq8W+F0FAzAJBgUrDgMCHQUAMBIxEDAOBgNVBAMTB0RldlJvb3QwHhcNMTAwMTIwMjMwMDAwWhcNMjAwMTIwMjMwMDAwWjARMQ8wDQYDVQQDEwZDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSaY4x1eXqjHF1iXQcF3pbFrIbmNw19w/IdOQxbavmuPbhY7jX0IORu/GQiHjmhqWt8F4G7KGLhXLC1j7rXdDmxXRyVJBZBTEaSYukuX7zGeUXscdpgODLQVay/0hUGz54aDZPAhtBHaYbog+yH10sCXgV1Mxtzx3dGelA6pPwiAmXwFxjJ1HGsS/hdbt+vgXhdlzud3ZSfyI/TJAnFeKxsmbJUyqMfoBl1zFKG4MOvgHhBjekp+r8gYNGknMYu9JDFr1ue0wylaw9UwG8ZXAkYmYbn2wN/CpJl3gJgX42/9g87uLvtVAmz5L+rZQTlS1ibv54ScR2lcRpGQiQav/LAgMBAAGjXDBaMBMGA1UdJQQMMAoGCCsGAQUFBwMCMEMGA1UdAQQ8MDqAENIWANpX5DZ3bX3WvoDfy0GhFDASMRAwDgYDVQQDEwdEZXZSb290ghAsWTt7E82DjU1E1p427Qj2MAkGBSsOAwIdBQADggEBADLje0qbqGVPaZHINLn+WSM2czZk0b5NG80btp7arjgDYoWBIe2TSOkkApTRhLPfmZTsaiI3Ro/64q+Dk3z3Kt7w+grHqu5nYhsn7xQFAQUf3y2KcJnRdIEk0jrLM4vgIzYdXsoC6YO+9QnlkNqcN36Y8IpSVSTda6gRKvGXiAhu42e2Qey/WNMFOL+YzMXGt/nDHL/qRKsuXBOarIb++43DV3YnxGTx22llhOnPpuZ9/gnNY7KLjODaiEciKhaKqt/b57mTEz4jTF4kIg6BP03MUfDXeVlM1Qf1jB43G2QQ19n5lUiqTpmQkcfLfyci2uBZ8BkOhXr3Vk9HIk/xBXQ=\"\n            }\n            new Secret\n            {\n                Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                Value = \"{'e':'AQAB','kid':'ZzAjSnraU3bkWGnnAqLapYGpTyNfLbjbzgAPbbW2GEA','kty':'RSA','n':'wWwQFtSzeRjjerpEM5Rmqz_DsNaZ9S1Bw6UbZkDLowuuTCjBWUax0vBMMxdy6XjEEK4Oq9lKMvx9JzjmeJf1knoqSNrox3Ka0rnxXpNAz6sATvme8p9mTXyp0cX4lF4U2J54xa2_S9NF5QWvpXvBeC4GAJx7QaSw4zrUkrc6XyaAiFnLhQEwKJCwUw4NOqIuYvYp_IXhw-5Ti_icDlZS-282PcccnBeOcX7vc21pozibIdmZJKqXNsL1Ibx5Nkx1F1jLnekJAmdaACDjYRLL_6n3W4wUp19UvzB1lGtXcJKLLkqB6YDiZNu16OSiSprfmrRXvYmvD8m6Fnl5aetgKw'}\"\n            }\n        },\n\n        AllowedGrantTypes = GrantTypes.ClientCredentials,\n        AllowedScopes = { \"api1\", \"api2\" }\n    };\n"
  },
  {
    "path": "docs/topics/clients.rst",
    "content": "Defining Clients\n================\nClients represent applications that can request tokens from your identityserver.\n\nThe details vary, but you typically define the following common settings for a client:\n\n* a unique client ID\n* a secret if needed\n* the allowed interactions with the token service (called a grant type)\n* a network location where identity and/or access token gets sent to (called a redirect URI)\n* a list of scopes (aka resources) the client is allowed to access\n\n.. Note:: At runtime, clients are retrieved via an implementation of the ``IClientStore``. This allows loading them from arbitrary data sources like config files or databases. For this document we will use the in-memory version of the client store. You can wire up the in-memory store in ``ConfigureServices`` via the ``AddInMemoryClients`` extensions method.\n\nDefining a client for server to server communication\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIn this scenario no interactive user is present - a service (aka client) wants to communicate with an API (aka scope)::\n\n    public class Clients\n    {\n        public static IEnumerable<Client> Get()\n        {\n            return new List<Client>\n            {\n                new Client\n                {\n                    ClientId = \"service.client\",                    \n                    ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                    AllowedGrantTypes = GrantTypes.ClientCredentials,\n                    AllowedScopes = { \"api1\", \"api2.read_only\" }\n                }\n            };\n        }\n    }\n\n.. _startClientsMVC:\nDefining an interactive application for use authentication and delegated API access\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nInteractive applications (e.g. web applications or native desktop/mobile) applications use the authorization code flow.\nThis flow gives you the best security because the access tokens are transmitted via back-channel calls only (and gives you access to refresh tokens)::\n\n    var interactiveClient = new Client\n    {\n        ClientId = \"interactive\",\n\n        AllowedGrantTypes = GrantTypes.Code,\n        AllowOfflineAccess = true,\n        ClientSecrets = { new Secret(\"secret\".Sha256()) },\n        \n        RedirectUris =           { \"http://localhost:21402/signin-oidc\" },\n        PostLogoutRedirectUris = { \"http://localhost:21402/\" },\n        FrontChannelLogoutUri =    \"http://localhost:21402/signout-oidc\",\n\n        AllowedScopes = \n        {\n            IdentityServerConstants.StandardScopes.OpenId,\n            IdentityServerConstants.StandardScopes.Profile,\n            IdentityServerConstants.StandardScopes.Email,\n\n            \"api1\", \"api2.read_only\"\n        },\n    };\n\n.. Note:: see the :ref:`grant types <refGrantTypes>` topic for more information on choosing the right grant type for your client.\n\nDefining clients in appsettings.json\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe ``AddInMemoryClients`` extensions method also supports adding clients from the ASP.NET Core configuration file. This allows you to define static clients directly from the appsettings.json file::\n\n    \"IdentityServer\": {\n      \"IssuerUri\": \"urn:sso.company.com\",\n      \"Clients\": [\n        {\n          \"Enabled\": true,\n          \"ClientId\": \"local-dev\",\n          \"ClientName\": \"Local Development\",\n          \"ClientSecrets\": [ { \"Value\": \"<Insert Sha256 hash of the secret encoded as Base64 string>\" } ],\n          \"AllowedGrantTypes\": [ \"client_credentials\" ],\n          \"AllowedScopes\": [ \"api1\" ],\n        }\n      ]\n    }\n    \nThen pass the configuration section to the ``AddInMemoryClients`` method::\n\n    AddInMemoryClients(configuration.GetSection(\"IdentityServer:Clients\"))\n"
  },
  {
    "path": "docs/topics/consent.rst",
    "content": ".. _refConsent:\nConsent\n=======\n\nDuring an authorization request, if IdentityServer requires user consent the browser will be redirected to the consent page.\n\nConsent is used to allow an end user to grant a client access to resources (:ref:`identity <refIdentityResource>` or :ref:`API <refApiResource>`).\nThis is typically only necessary for third-party clients, and can be enabled/disabled per-client on the :ref:`client settings <refClient>`.\n\nConsent Page\n^^^^^^^^^^^^\nIn order for the user to grant consent, a consent page must be provided by the hosting application.\nThe `quickstart UI <https://github.com/alexhiggins732/IdentityServer8.Quickstart.UI>`_ has a basic implementation of a consent page.\n\nA consent page normally renders the display name of the current user, \nthe display name of the client requesting access, \nthe logo of the client, \na link for more information about the client, \nand the list of resources the client is requesting access to.\nIt's also common to allow the user to indicate that their consent should be \"remembered\" so they are not prompted again in the future for the same client.\n\nOnce the user has provided consent, the consent page must inform IdentityServer of the consent, and then the browser must be redirected back to the authorization endpoint. \n\nAuthorization Context\n^^^^^^^^^^^^^^^^^^^^^\n\nIdentityServer will pass a `returnUrl` parameter (configurable on the :ref:`user interaction options <refOptions>`) to the consent page which contains the parameters of the authorization request.\nThese parameters provide the context for the consent page, and can be read with help from the :ref:`interaction service <refInteractionService>`.\nThe ``GetAuthorizationContextAsync`` API will return an instance of ``AuthorizationRequest``.\n\nAdditional details about the client or resources can be obtained using the ``IClientStore`` and ``IResourceStore`` interfaces. \n\nInforming IdentityServer of the consent result\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe ``GrantConsentAsync`` API on the :ref:`interaction service <refInteractionService>` allows the consent page to inform IdentityServer of the outcome of consent (which might also be to deny the client access).\n\nIdentityServer will temporarily persist the outcome of the consent.\nThis persistence uses a cookie by default, as it only needs to last long enough to convey the outcome back to the authorization endpoint.\nThis temporary persistence is different than the persistence used for the \"remember my consent\" feature (and it is the authorization endpoint which persists the \"remember my consent\" for the user).\nIf you wish to use some other persistence between the consent page and the authorization redirect, then you can implement ``IMessageStore<ConsentResponse>`` and register the implementation in DI.\n\nReturning the user to the authorization endpoint\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nOnce the consent page has informed IdentityServer of the outcome, the user can be redirected back to the `returnUrl`. \nYour consent page should protect against open redirects by verifying that the `returnUrl` is valid.\nThis can be done by calling ``IsValidReturnUrl`` on the :ref:`interaction service <refInteractionService>`.\nAlso, if ``GetAuthorizationContextAsync`` returns a non-null result, then you can also trust that the `returnUrl` is valid.\n\n\n\n"
  },
  {
    "path": "docs/topics/cors.rst",
    "content": ".. _refCors:\nCORS\n====\n\nMany endpoints in IdentityServer will be accessed via Ajax calls from JavaScript-based clients.\nGiven that IdentityServer will most likely be hosted on a different origin than these clients, this implies that `Cross-Origin Resource Sharing <http://www.html5rocks.com/en/tutorials/cors/>`_ (CORS) will need to be configured.\n\nClient-based CORS Configuration\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nOne approach to configuring CORS is to use the ``AllowedCorsOrigins`` collection on the :ref:`client configuration <refClient>`.\nSimply add the origin of the client to the collection and the default configuration in IdentityServer will consult these values to allow cross-origin calls from the origins.\n\n.. Note:: Be sure to use an origin (not a URL) when configuring CORS. For example: ``https://foo:123/`` is a URL, whereas ``https://foo:123`` is an origin.\n\nThis default CORS implementation will be in use if you are using either the \"in-memory\" or EF-based client configuration that we provide.\nIf you define your own ``IClientStore``, then you will need to implement your own custom CORS policy service (see below).\n\nCustom Cors Policy Service\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIdentityServer allows the hosting application to implement the ``ICorsPolicyService`` to completely control the CORS policy.\n\nThe single method to implement is: ``Task<bool> IsOriginAllowedAsync(string origin)``. \nReturn ``true`` if the `origin` is allowed, ``false`` otherwise.\n\nOnce implemented, simply register the implementation in DI and IdentityServer will then use your custom implementation.\n\n**DefaultCorsPolicyService**\n\nIf you simply wish to hard-code a set of allowed origins, then there is a pre-built ``ICorsPolicyService`` implementation you can use called ``DefaultCorsPolicyService``.\nThis would be configured as a singleton in DI, and hard-coded with its ``AllowedOrigins`` collection, or setting the flag ``AllowAll`` to ``true`` to allow all origins.\nFor example, in ``ConfigureServices``::\n\n    services.AddSingleton<ICorsPolicyService>((container) => {\n        var logger = container.GetRequiredService<ILogger<DefaultCorsPolicyService>>();\n        return new DefaultCorsPolicyService(logger) {\n            AllowedOrigins = { \"https://foo\", \"https://bar\" }\n        };\n    });\n\n.. Note:: Use ``AllowAll`` with caution.\n\n\nMixing IdentityServer's CORS policy with ASP.NET Core's CORS policies\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIdentityServer uses the CORS middleware from ASP.NET Core to provide its CORS implementation.\nIt is possible that your application that hosts IdentityServer might also require CORS for its own custom endpoints.\nIn general, both should work together in the same application.\n\nYour code should use the documented CORS features from ASP.NET Core without regard to IdentityServer.\nThis means you should define policies and register the middleware as normal.\nIf your application defines policies in ``ConfigureServices``, then those should continue to work in the same places you are using them (either where you configure the CORS middleware or where you use the MVC ``EnableCors`` attributes in your controller code).\nIf instead you define an inline policy in the use of the CORS middleware (via the policy builder callback), then that too should continue to work normally.\n\nThe one scenario where there might be a conflict between your use of the ASP.NET Core CORS services and IdentityServer is if you decide to create a custom ``ICorsPolicyProvider``.\nGiven the design of the ASP.NET Core's CORS services and middleware, IdentityServer implements its own custom ``ICorsPolicyProvider`` and registers it in the DI system.\nFortunately, the IdentityServer implementation is designed to use the decorator pattern to wrap any existing  ``ICorsPolicyProvider`` that is already registered in DI.\nWhat this means is that you can also implement the ``ICorsPolicyProvider``, but it simply needs to be registered prior to IdentityServer in DI (e.g. in ``ConfigureServices``).\n"
  },
  {
    "path": "docs/topics/crypto.rst",
    "content": ".. _refCrypto:\nCryptography, Keys and HTTPS\n============================\n\nIdentityServer relies on a couple of crypto mechanisms to do its job.\n\nToken signing and validation\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIdentityServer needs an asymmetric key pair to sign and validate JWTs. \nThis keymaterial can be either packaged as a certificate or just raw keys.\nBoth RSA and ECDSA keys are supported and the supported signing algorithms are: RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384 and ES512.\n\nYou can use multiple signing keys simultaneously, but only one signing key per algorithm is supported.\nThe first signing key you register is considered the default signing key.\n\nBoth :ref:`clients <refClient>` and :ref:`API resources <refApiResource>` can express preferences on the signing algorithm.\nIf you request a single token for multiple API resources, all resources need to agree on at least one allowed signing algorithm.\n\nLoading of signing key and the corresponding validation part is done by implementations of ``ISigningCredentialStore`` and ``IValidationKeysStore``.\nIf you want to customize the loading of the keys, you can implement those interfaces and register them with DI.\n\nThe DI builder extensions has a couple of convenience methods to set signing and validation keys - see :ref:`here <refStartupKeyMaterial>`.\n\nSigning key rollover\n^^^^^^^^^^^^^^^^^^^^\nWhile you can only use one signing key at a time, you can publish more than one validation key to the discovery document.\nThis is useful for key rollover.\n\nIn a nutshell, a rollover typically works like this:\n\n1. you request/create new key material\n2. you publish the new validation key in addition to the current one. You can use the ``AddValidationKey`` builder extension method for that.\n3. all clients and APIs now have a chance to learn about the new key the next time they update their local copy of the discovery document\n4. after a certain amount of time (e.g. 24h) all clients and APIs should now accept both the old and the new key material\n5. keep the old key material around for as long as you like, maybe you have long-lived tokens that need validation\n6. retire the old key material when it is not used anymore\n7. all clients and APIs will \"forget\" the old key next time they update their local copy of the discovery document\n\nThis requires that clients and APIs use the discovery document, and also have a feature to periodically refresh their configuration.\n\nBrock wrote a more detailed `blog post <https://brockallen.com/2019/08/09/identityserver-and-signing-key-rotation/>`_ about key rotation, and also\ncreated a `commercial component <https://www.identityserver8.com/products/keymanagement>`_, that can automatically take care of all those details.\n\nData protection\n^^^^^^^^^^^^^^^\nCookie authentication in ASP.NET Core (or anti-forgery in MVC) use the ASP.NET Core data protection feature.\nDepending on your deployment scenario, this might require additional configuration. See the Microsoft `docs <https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview>`_ for more information.\n\nHTTPS\n^^^^^\nWe don't enforce the use of HTTPS, but for production it is mandatory for every interaction with IdentityServer.\n"
  },
  {
    "path": "docs/topics/custom_token_request_validation.rst",
    "content": ".. _refCustomTokenRequestValidation:\nCustom Token Request Validation and Issuance\n============================================\n\nYou can run custom code as part of the token issuance pipeline at the token endpoint.\nThis allows e.g. for\n\n* adding additional validation logic\n* changing certain parameters (e.g. token lifetime) dynamically\n\nFor this purpose, implement (and register) the ``ICustomTokenRequestValidator`` interface::\n\n    /// <summary>\n    /// Allows inserting custom validation logic into token requests\n    /// </summary>\n    public interface ICustomTokenRequestValidator\n    {\n        /// <summary>\n        /// Custom validation logic for a token request.\n        /// </summary>\n        /// <param name=\"context\">The context.</param>\n        /// <returns>\n        /// The validation result\n        /// </returns>\n        Task ValidateAsync(CustomTokenRequestValidationContext context);\n    }\n\nThe context object gives you access to:\n\n* adding custom response parameters\n* return an error and error description\n* modifying the request parameters, e.g. access token lifetime and type, client claims, and the confirmation method\n\nYou can register your implementation of the validator using the ``AddCustomTokenRequestValidator`` extension method on the configuration builder.\n"
  },
  {
    "path": "docs/topics/deployment.rst",
    "content": "Deployment\n==========\nYour identity server is `just` a standard ASP.NET Core application including the IdentityServer middleware.\nRead the official Microsoft `documentation <https://docs.microsoft.com/en-us/aspnet/core/publishing>`_ on publishing and deployment first\n(and especially the `section <https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2#scenarios-and-use-cases>`_ about load balancers and proxies).\n\nTypical architecture\n^^^^^^^^^^^^^^^^^^^^\nTypically you will design your IdentityServer deployment for high availability:\n\n.. image:: images/deployment.png\n\nIdentityServer itself is stateless and does not require server affinity - but there is data that needs to be shared between the instances.\n\nConfiguration data\n^^^^^^^^^^^^^^^^^^\nThis typically includes:\n\n* resources\n* clients\n* startup configuration, e.g. key material, external provider settings etc...\n\nThe way you store that data depends on your environment. In situations where configuration data rarely changes we recommend using the in-memory stores and code or configuration files.\n\nIn highly dynamic environments (e.g. Saas) we recommend using a database or configuration service to load configuration dynamically.\n\nIdentityServer supports code configuration and configuration files (see `here <https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration>`_) out of the box.\nFor databases we provide support for `Entity Framework Core <https://github.com/alexhiggins732/IdentityServer8.EntityFramework>`_ based databases.\n\nYou can also build your own configuration stores by implementing ``IResourceStore`` and ``IClientStore``.\n\nKey material\n^^^^^^^^^^^^\n\nAnother important piece of startup configuration is your key material, see :ref:`here <refCrypto>` for more details on key material and cryptography.\n\nOperational data\n^^^^^^^^^^^^^^^^\nFor certain operations, IdentityServer needs a persistence store to keep state, this includes:\n\n* issuing authorization codes\n* issuing reference and refresh tokens\n* storing consent\n\nYou can either use a traditional database for storing operational data, or use a cache with persistence features like Redis.\nThe EF Core implementation mentioned above has also support for operational data.\n\nYou can also implement support for your own custom storage mechanism by implementing ``IPersistedGrantStore`` - by default IdentityServer injects an in-memory version.\n\nASP.NET Core data protection\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nASP.NET Core itself needs shared key material for protecting sensitive data like cookies, state strings etc.\nSee the official docs `here <https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/>`_.\n\nYou can either re-use one of the above persistence store or use something simple like a shared file if possible.\n\nASP.NET Core distributed caching\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nSome components rely on ASP.NET Core distributed caching. In order to work in a multi server environment, this needs to be set up correctly. \nThe `official docs <https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed/>`_ describe several options.\n\nThe following components rely on ``IDistributedCache``:\n\n* ``services.AddOidcStateDataFormatterCache()`` configures the OpenIdConnect handlers to persist the state parameter into the server-side ``IDistributedCache``.\n* ``DefaultReplayCache``\n* ``DistributedDeviceFlowThrottlingService``\n* ``DistributedCacheAuthorizationParametersMessageStore``\n"
  },
  {
    "path": "docs/topics/discovery.rst",
    "content": "Discovery\n=========\n\nThe discovery document can be found at *https://baseaddress/.well-known/openid-configuration*. \nIt contains information about the endpoints, key material and features of your IdentityServer.\n\nBy default all information is included in the discovery document, but by using configuration options, you can hide\nindividual sections, e.g.::\n\n    services.AddIdentityServer(options =>\n    {\n        options.Discovery.ShowIdentityScopes = false;\n        options.Discovery.ShowApiScopes = false;\n        options.Discovery.ShowClaims = false;\n        options.Discovery.ShowExtensionGrantTypes = false;\n    });\n\nExtending discovery\n^^^^^^^^^^^^^^^^^^^\nYou can add custom entries to the discovery document, e.g::\n\n    services.AddIdentityServer(options =>\n    {\n        options.Discovery.CustomEntries.Add(\"my_setting\", \"foo\");\n        options.Discovery.CustomEntries.Add(\"my_complex_setting\", \n            new\n            {\n                foo = \"foo\",\n                bar = \"bar\"\n            });\n    });\n\nWhen you add a custom value that starts with ~/ it will be expanded to an absolute path below the IdentityServer base address, e.g.::\n\n    options.Discovery.CustomEntries.Add(\"my_custom_endpoint\", \"~/custom\");\n\nIf you want to take full control over the rendering of the discovery (and jwks) document, you can implement the ``IDiscoveryResponseGenerator``\ninterface (or derive from our default implementation)."
  },
  {
    "path": "docs/topics/events.rst",
    "content": ".. _refEvents:\nEvents\n======\nWhile logging is more low level \"printf\" style - events represent higher level information about certain operations in IdentityServer.\nEvents are structured data and include event IDs, success/failure information, categories and details.\nThis makes it easy to query and analyze them and extract useful information that can be used for further processing.\n\nEvents work great with event stores like `ELK <https://www.elastic.co/webinars/introduction-elk-stack>`_, `Seq <https://getseq.net/>`_ or `Splunk <https://www.splunk.com/>`_.\n\nEmitting events\n^^^^^^^^^^^^^^^\nEvents are not turned on by default - but can be globally configured in the ``ConfigureServices`` method, e.g.::\n\n    services.AddIdentityServer(options =>\n    {\n        options.Events.RaiseSuccessEvents = true;\n        options.Events.RaiseFailureEvents = true;\n        options.Events.RaiseErrorEvents = true;\n    });\n\nTo emit an event use the ``IEventService`` from the DI container and call the ``RaiseAsync`` method, e.g.::\n\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        if (_users.ValidateCredentials(model.Username, model.Password))\n        {\n            // issue authentication cookie with subject ID and username\n            var user = _users.FindByUsername(model.Username);\n            await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username));\n        }\n        else\n        {\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\"));\n        }\n    }\n\nCustom sinks\n^^^^^^^^^^^^\nOur default event sink will simply serialize the event class to JSON and forward it to the ASP.NET Core logging system.\nIf you want to connect to a custom event store, implement the ``IEventSink`` interface and register it with DI.\n\nThe following example uses `Seq <https://getseq.net/>`_ to emit events::\n\n     public class SeqEventSink : IEventSink\n    {\n        private readonly Logger _log;\n\n        public SeqEventSink()\n        {\n            _log = new LoggerConfiguration()\n                .WriteTo.Seq(\"http://localhost:5341\")\n                .CreateLogger();\n        }\n\n        public Task PersistAsync(Event evt)\n        {\n            if (evt.EventType == EventTypes.Success ||\n                evt.EventType == EventTypes.Information)\n            {\n                _log.Information(\"{Name} ({Id}), Details: {@details}\",\n                    evt.Name,\n                    evt.Id,\n                    evt);\n            }\n            else\n            {\n                _log.Error(\"{Name} ({Id}), Details: {@details}\",\n                    evt.Name,\n                    evt.Id,\n                    evt);\n            }\n\n            return Task.CompletedTask;\n        }\n    }\n\nAdd the ``Serilog.Sinks.Seq`` package to your host to make the above code work.\n\nBuilt-in events\n^^^^^^^^^^^^^^^\nThe following events are defined in IdentityServer:\n\n``ApiAuthenticationFailureEvent`` & ``ApiAuthenticationSuccessEvent``\n    Gets raised for successful/failed API authentication at the introspection endpoint.\n``ClientAuthenticationSuccessEvent`` & ``ClientAuthenticationFailureEvent``\n    Gets raised for successful/failed client authentication at the token endpoint.\n``TokenIssuedSuccessEvent`` & ``TokenIssuedFailureEvent``\n    Gets raised for successful/failed attempts to request identity tokens, access tokens, refresh tokens and authorization codes.\n``TokenIntrospectionSuccessEvent`` & ``TokenIntrospectionFailureEvent``\n    Gets raised for successful token introspection requests.\n``TokenRevokedSuccessEvent``\n    Gets raised for successful token revocation requests.\n``UserLoginSuccessEvent`` & ``UserLoginFailureEvent``\n    Gets raised by the quickstart UI for successful/failed user logins.\n``UserLogoutSuccessEvent``\n    Gets raised for successful logout requests.\n``ConsentGrantedEvent`` & ``ConsentDeniedEvent``\n    Gets raised in the consent UI.\n``UnhandledExceptionEvent``\n    Gets raised for unhandled exceptions.\n``DeviceAuthorizationFailureEvent`` & ``DeviceAuthorizationSuccessEvent``\n    Gets raised for successful/failed device authorization requests.\n\nCustom events\n^^^^^^^^^^^^^\nYou can create your own events and emit them via our infrastructure.\n\nYou need to derive from our base ``Event`` class which injects contextual information like activity ID, timestamp, etc.\nYour derived class can then add arbitrary data fields specific to the event context::\n\n    public class UserLoginFailureEvent : Event\n    {\n        public UserLoginFailureEvent(string username, string error)\n            : base(EventCategories.Authentication,\n                    \"User Login Failure\",\n                    EventTypes.Failure, \n                    EventIds.UserLoginFailure,\n                    error)\n        {\n            Username = username;\n        }\n\n        public string Username { get; set; }\n    }\n"
  },
  {
    "path": "docs/topics/extension_grants.rst",
    "content": ".. _refExtensionGrants:\nExtension Grants\n================\n\nOAuth 2.0 defines standard grant types for the token endpoint, such as ``password``, ``authorization_code`` and ``refresh_token``. Extension grants are a way to add support for non-standard token issuance scenarios like token translation, delegation, or custom credentials.\n\nYou can add support for additional grant types by implementing the ``IExtensionGrantValidator`` interface::\n\n    public interface IExtensionGrantValidator\n    {\n        /// <summary>\n        /// Handles the custom grant request.\n        /// </summary>\n        /// <param name=\"request\">The validation context.</param>\n        Task ValidateAsync(ExtensionGrantValidationContext context);\n\n        /// <summary>\n        /// Returns the grant type this validator can deal with\n        /// </summary>\n        /// <value>\n        /// The type of the grant.\n        /// </value>\n        string GrantType { get; }\n    }\n\nThe ``ExtensionGrantValidationContext`` object gives you access to:\n\n* the incoming token request - both the well-known validated values, as well as any custom values (via the ``Raw`` collection)\n* the result - either error or success\n* custom response parameters\n\nTo register the extension grant, add it to DI::\n\n    builder.AddExtensionGrantValidator<MyExtensionsGrantValidator>();\n\n\nExample: Simple delegation using an extension grant\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nImagine the following scenario - a front end client calls a middle tier API using a token acquired via an interactive flow (e.g. hybrid flow).\nThis middle tier API (API 1) now wants to call a back end API (API 2) on behalf of the interactive user:\n\n.. image:: images/delegation.png\n\nIn other words, the middle tier API (API 1) needs an access token containing the user's identity, but with the scope of the back end API (API 2).\n\n.. note:: You might have heard of the term *poor man's delegation* where the access token from the front end is simply forwarded to the back end. This has some shortcomings, e.g. *API 2* must now accept the *API 1* scope which would allow the user to call *API 2* directly. Also - you might want to add some delegation specific claims into the token, e.g. the fact that the call path is via *API 1*.\n\n**Implementing the extension grant**\n\nThe front end would send the token to API 1, and now this token needs to be exchanged at IdentityServer with a new token for API 2.\n\nOn the wire the call to token service for the exchange could look like this::\n\n    POST /connect/token\n\n    grant_type=delegation&\n    scope=api2&\n    token=...&\n    client_id=api1.client\n    client_secret=secret\n\nIt's the job of the extension grant validator to handle that request by validating the incoming token, and returning a result that represents the new token::\n\n    public class DelegationGrantValidator : IExtensionGrantValidator\n    {\n        private readonly ITokenValidator _validator;\n\n        public DelegationGrantValidator(ITokenValidator validator)\n        {\n            _validator = validator;\n        }\n\n        public string GrantType => \"delegation\";\n\n        public async Task ValidateAsync(ExtensionGrantValidationContext context)\n        {\n            var userToken = context.Request.Raw.Get(\"token\");\n\n            if (string.IsNullOrEmpty(userToken))\n            {\n                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);\n                return;\n            }\n\n            var result = await _validator.ValidateAccessTokenAsync(userToken);\n            if (result.IsError)\n            {\n                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);\n                return;\n            }\n\n            // get user's identity\n            var sub = result.Claims.FirstOrDefault(c => c.Type == \"sub\").Value;\n\n            context.Result = new GrantValidationResult(sub, GrantType);\n            return;\n        }\n    }\n\nDon't forget to register the validator with DI.\n\n**Registering the delegation client**\n\nYou need a client registration in IdentityServer that allows a client to use this new extension grant, e.g.::\n\n    var client = new Client\n    {\n        ClientId = \"api1.client\",\n        ClientSecrets = new List<Secret>\n        {\n            new Secret(\"secret\".Sha256())\n        },\n        \n        AllowedGrantTypes = { \"delegation\" },\n\n        AllowedScopes = new List<string>\n        {\n            \"api2\"\n        }\n    }\n\n**Calling the token endpoint**\n\nIn API 1 you can now construct the HTTP payload yourself, or use the *IdentityModel* helper library::\n\n\n    public async Task<TokenResponse> DelegateAsync(string userToken)\n    {\n        var client = _httpClientFactory.CreateClient();\n        // or \n        // var client = new HttpClient();\n\n        // send custom grant to token endpoint, return response\n        return await client.RequestTokenAsync(new TokenRequest\n        {\n            Address = disco.TokenEndpoint,\n            GrantType = \"delegation\",\n\n            ClientId = \"api1.client\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api2\" },\n                { \"token\", userToken}\n            }                \n        });\n    }\n\nThe ``TokenResponse.AccessToken`` will now contain the delegation access token.\n"
  },
  {
    "path": "docs/topics/federation_gateway.rst",
    "content": "Federation Gateway\n==================\n\nA common architecture is the so-called federation gateway. In this approach IdentityServer acts as a gateway to one or more external identity providers.\n\n.. image:: images/federation_gateway.png\n\nThis architecture has the following advantages\n\n* your applications only need to know about the one token service (the gateway) and are shielded from all the details about connecting to the external provider(s). This also means that you can add or change those external providers without needing to update your applications.\n* you control the gateway (as opposed to some external service provider) - this means you can make any changes to it and can protect your applications from changes those external providers might do to their own services.\n* most external providers only support a fixed set of claims and claim types - having a gateway in the middle allows post-processing the response from the providers to transform/add/amend domain specific identity information.\n* some providers don't support access tokens (e.g. social providers) - since the gateway knows about your APIs, it can issue access tokens based on the external identities.\n* some providers charge by the number of applications you connect to them. The gateway acts as a single application to the external provider. Internally you can connect as many applications as you want.\n* some providers use proprietary protocols or made proprietary modifications to standard protocols - with a gateway there is only one place you need to deal with that.\n* forcing every authentication (internal or external) through one single place gives you tremendous flexibility with regards to identity mapping, providing a stable identity to all your applications and dealing with new requirements\n\nIn other words - owning your federation gateway gives you a lot of control over your identity infrastructure. And since the identity of your users is one of your most important assets, we recommend taking control over the gateway.\n\nImplementation\n^^^^^^^^^^^^^^\nOur `quick start UI <https://github.com/alexhiggins732/IdentityServer8.Quickstart.UI>`_ utilizes some of the below features. Also check out the :ref:`external authentication quickstart <refExternalAuthenticationQuickstart>` and the \ndocs about :ref:`external providers <refExternalIdentityProviders>`.\n\n* You can add support for external identity providers by adding authentication handlers to your IdentityServer application.\n* You can programmatically query those external providers by calling ``IAuthenticationSchemeProvider``. This allows to dynamically render your login page based on the registered external providers.\n* Our client configuration model allows restricting the available providers on a per client basis (use the ``IdentityProviderRestrictions`` property).\n* You can also use the ``EnableLocalLogin`` property on the client to tell your UI whether the username/password input should be rendered.\n* Our quickstart UI funnels all external authentication calls through a single callback (see ``ExternalLoginCallback`` on the ``AccountController`` class). This allows for a single point for post-processing.\n"
  },
  {
    "path": "docs/topics/grant_types.rst",
    "content": ".. _refGrantTypes:\nGrant Types\n^^^^^^^^^^^\nThe OpenID Connect and OAuth 2.0 specifications define so-called grant types (often also called flows - or protocol flows).\nGrant types specify how a client can interact with the token service.\n\nYou need to specify which grant types a client can use via the ``AllowedGrantTypes`` property on the ``Client`` configuration.\nThis allows locking down the protocol interactions that are allowed for a given client.\n\nA client can be configured to use more than a single grant type (e.g. Authorization Code flow for user centric operations and client credentials for server to server communication).\nThe ``GrantTypes`` class can be used to pick from typical grant type combinations::\n\n    Client.AllowedGrantTypes = GrantTypes.CodeAndClientCredentials;\n\nYou can also specify the grant types list manually::\n\n    Client.AllowedGrantTypes = \n    {\n        GrantType.Code, \n        GrantType.ClientCredentials,\n        \"my_custom_grant_type\" \n    };\n\nWhile IdentityServer supports all standard grant types, you really only need to know two of them for common application scenarios.\n\nMachine to Machine Communication\n================================\nThis is the simplest type of communication. Tokens are always requested on behalf of a client, no interactive user is present.\n\nIn this scenario, you send a token request to the token endpoint using the ``client credentials`` grant type.\nThe client typically has to authenticate with the token endpoint using its client ID and secret.\n\nSee the :ref:`Client Credentials Quick Start <refClientCredentialsQuickstart>` for a sample how to use it. \n\nInteractive Clients\n===================\nThis is the most common type of client scenario: web applications, SPAs or native/mobile apps with interactive users.\n\n.. Note:: Feel free to skip to the summary, if you don't care about all the technical details.\n\nFor this type of clients, the ``authorization code`` flow was designed. That flow consists of two physical operations:\n\n* a front-channel step via the browser where all \"interactive\" things happen, e.g. login page, consent etc. This step results in an authorization code that represents the outcome of the front-channel operation.\n* a back-channel step where the authorization code from step 1 gets exchanged with the requested tokens. Confidential clients need to authenticate at this point.\n\nThis flow has the following security properties:\n\n* no data (besides the authorization code which is basically a random string) gets leaked over the browser channel\n* authorization codes can only be used once\n* the authorization code can only be turned into tokens when (for confidential clients - more on that later) the client secret is known\n\nThis sounds all very good - still there is one problem called `code substitution attack <https://nat.sakimura.org/2016/01/25/cut-and-pasted-code-attack-in-oauth-2-0-rfc6749/>`_.\nThere are two modern mitigation techniques for this:\n\n**OpenID Connect Hybrid Flow**\n\nThis uses a response type of ``code id_token`` to add an additional identity token to the response. This token is signed and protected against substitution.\nIn addition it contains the hash of the code via the ``c_hash`` claim. This allows checking that you indeed got the right code (experts call this a detached signature).\n\nThis solves the problem but has the following down-sides:\n\n* the ``id_token`` gets transmitted over the front-channel and might leak additional (personal identifiable) data\n* all the mitigation steps (e.g. crypto) need to be implemented by the client. This results in more complicated client library implementations.\n\n**RFC 7636 - Proof Key for Code Exchange (PKCE)**\n\nThis essentially introduces a per-request secret for code flow (please read up on the details `here <https://tools.ietf.org/html/rfc7636>`_).\nAll the client has to implement for this, is creating a random string and hashing it using SHA256.\n\nThis also solves the substitution problem, because the client can prove that it is the same client on front and back-channel, and has the following additional advantages:\n\n* the client implementation is very simple compared to hybrid flow\n* it also solves the problem of the absence of a static secret for public clients\n* no additional front-channel response artifacts are needed\n\n**Summary**\n\nInteractive clients should use an authorization code-based flow. To protect against code substitution, either hybrid flow or PKCE should be used.\nIf PKCE is available, this is the simpler solution to the problem.\n\nPKCE is already the official recommendation for `native <https://tools.ietf.org/html/rfc8252#section-6>`_ applications \nand `SPAs <https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-03#section-4>`_ - and with the release of ASP.NET Core 3 also by default supported in the OpenID Connect handler as well.\n\nThis is how you would configure an interactive client::\n\n    var client = new Client\n    {\n        ClientId = \"...\",\n\n        // set client secret for confidential clients\n        ClientSecret = { ... },\n\n        // ...or turn off for public clients\n        RequireClientSecret = false,\n\n        AllowedGrantTypes = GrantTypes.Code,\n        RequirePkce = true\n    };\n\n\nInteractive clients without browsers or with constrained input devices\n======================================================================\nThis grant type is detailed `RFC 8628 <https://tools.ietf.org/html/rfc8628>`_.\n\nThis flow outsources user authentication and consent to an external device (e.g. a smart phone).\nIt is typically used by devices that don't have proper keyboards (e.g. TVs, gaming consoles...) and can request both identity and API resources.\n\nCustom scenarios\n================\nExtension grants allow extending the token endpoint with new grant types. See :ref:`this <refExtensionGrants>` for more details. \n"
  },
  {
    "path": "docs/topics/logging.rst",
    "content": "\nLogging\n=======\nIdentityServer uses the standard logging facilities provided by ASP.NET Core.\nThe Microsoft `documentation <https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging>`_ has a good intro and a description of the built-in logging providers.\n\nWe are roughly following the Microsoft guidelines for usage of log levels:\n\n* ``Trace`` For information that is valuable only to a developer troubleshooting an issue. These messages may contain sensitive application data like tokens and should not be enabled in a production environment.\n* ``Debug`` For following the internal flow and understanding why certain decisions are made. Has short-term usefulness during development and debugging.\n* ``Information`` For tracking the general flow of the application. These logs typically have some long-term value.\n* ``Warning`` For abnormal or unexpected events in the application flow. These may include errors or other conditions that do not cause the application to stop, but which may need to be investigated.\n* ``Error`` For errors and exceptions that cannot be handled. Examples: failed validation of a protocol request.\n* ``Critical`` For failures that require immediate attention. Examples: missing store implementation, invalid key material...\n\nSetup for Serilog\n^^^^^^^^^^^^^^^^^\nWe personally like `Serilog <https://serilog.net/>`_ and the ``Serilog.AspNetCore`` package a lot. Give it a try::\n\n    public class Program\n    {\n        public static int Main(string[] args)\n        {\n            Activity.DefaultIdFormat = ActivityIdFormat.W3C;\n\n            Log.Logger = new LoggerConfiguration()\n                .MinimumLevel.Debug()\n                .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n                .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n                .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n                .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n                .Enrich.FromLogContext()\n                .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n                .CreateLogger();\n\n            try\n            {\n                Log.Information(\"Starting host...\");\n                CreateHostBuilder(args).Build().Run();\n                return 0;\n            }\n            catch (Exception ex)\n            {\n                Log.Fatal(ex, \"Host terminated unexpectedly.\");\n                return 1;\n            }\n            finally\n            {\n                Log.CloseAndFlush();\n            }\n        }\n\n        public static IHostBuilder CreateHostBuilder(string[] args) =>\n            Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)\n                .UseSerilog()\n                .ConfigureWebHostDefaults(webBuilder =>\n                {\n                    webBuilder.UseStartup<Startup>();\n                });\n    }"
  },
  {
    "path": "docs/topics/mtls.rst",
    "content": ".. _refMutualTLS:\nMutual TLS\n==========\nMutual TLS support in IdentityServer allows for two features:\n\n* Client authentication to IdentityServer endpoints using a TLS X.509 client certificate\n* Binding of access tokens to clients using a TLS X.509 client certificate\n\n.. Note:: See the `\"OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens\" <https://tools.ietf.org/html/rfc8705>`_ spec for more information\n\nSetting up MTLS involves a couple of steps.\n\nServer setup\n^^^^^^^^^^^^\nIt's the hosting layer's responsibility to do the actual validation of the client certificate.\nIdentityServer will then use that information to associate the certificate with a client and embed the certificate information in the access tokens.\n\nDepending which server you are using, those steps are different. See `this <https://leastprivilege.com/2020/02/07/mutual-tls-and-proof-of-possession-access-tokens-part-1-setup/>`_ blog post for more information.\n\n.. Note:: `mkcert <https://github.com/FiloSottile/mkcert>`_ is a nice utility for creating certificates for development purposes.\n\nASP.NET Core setup\n^^^^^^^^^^^^^^^^^^\nDepending on the server setup, there are different ways how the ASP.NET Core host will receive the client certificate. While for IIS and pure Kestrel hosting, there are no additional steps, \ntypically you have a reverse proxy in front of the application server. \n\nThis means that in addition to the typical forwarded headers handling, you also need to process the header that contains the client certificate.\nAdd a call to ``app.UseCertificateForwarding();`` in the beginning of your middleware pipeline for that.\n\nThe exact format how proxies transmit the certificates is not standardized, that's why you need to register a callback to do the actual header parsing.\nThe Microsoft `docs <https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1>`_ show how that would work for Azure Web Apps.\n\nIf you are using Nginx (which we found is the most flexible hosting option), you need to register the following service in ``ConfigureServices``::\n\n    services.AddCertificateForwarding(options =>\n    {\n        // header name might be different, based on your nginx config\n        options.CertificateHeader = \"X-SSL-CERT\";\n\n        options.HeaderConverter = (headerValue) =>\n        {\n            X509Certificate2 clientCertificate = null;\n\n            if(!string.IsNullOrWhiteSpace(headerValue))\n            {\n                var bytes = Encoding.UTF8.GetBytes(Uri.UnescapeDataString(headerValue));\n                clientCertificate = new X509Certificate2(bytes);\n            }\n\n            return clientCertificate;\n        };\n    });\n\nOnce, the certificate has been loaded, you also need to setup the authentication handler.\nIn this scenario we want to support self-signed certificates, hence the ``CertificateType.All`` and no revocation checking.\nThese settings might be different in your environment:: \n\n    services.AddAuthentication()\n        .AddCertificate(options =>\n        {\n            options.AllowedCertificateTypes = CertificateTypes.All;\n            options.RevocationMode = X509RevocationMode.NoCheck;\n        });\n\nIdentityServer setup\n^^^^^^^^^^^^^^^^^^^^\nNext step is to enable MTLS in IdentityServer. For that you need to specify the name of the certificate authentication handler you set-up in the last step (defaults to ``Certificate``),\nand the MTLS hosting strategy.\n\nIn IdentityServer, the mutual TLS endpoints, can be configured in three ways (assuming IdentityServer is running on ``https://identityserver8.io``:\n\n* path-based - endpoints located beneath the path ``~/connect/mtls``, e.g. ``https://identityserver8.io/connect/mtls/token``.\n* sub-domain based - endpoints are on a sub-domain of the main server, e.g. ``https://mtls.identityserver8.io/connect/token``.\n* domain-based - endpoints are on a different domain, e.g. ``https://identityserver-mtls.io``.  \n\nFor example::\n\n    var builder = services.AddIdentityServer(options =>\n    {\n        options.MutualTls.Enabled = true;\n        options.MutualTls.ClientCertificateAuthenticationScheme = \"Certificate\";\n        \n        // uses sub-domain hosting\n        options.MutualTls.DomainName = \"mtls\";\n    });\n\nIdentityServer's discovery document reflects those endpoints:\n\n.. image:: images/mtls_endpoints.png\n\n\nClient authentication\n^^^^^^^^^^^^^^^^^^^^^\nClients can use a X.509 client certificate as an authentication mechanism to endpoints in IdentityServer.\n\nFor this you need to associate a client certificate with a client in IdentityServer.\nUse the :ref:`IdentityServer builder <refStartup>` to add the services to DI which contain a default implementation to do that either thumbprint or common-name based::\n\n    builder.AddMutualTlsSecretValidators();\n\nFinally, for the :ref:`client configuration <refClient>` add to the ``ClientSecrets`` collection a secret type of either ``SecretTypes.X509CertificateName`` \nif you wish to authenticate the client from the certificate distinguished name or ``SecretTypes.X509CertificateThumbprint`` if you wish to authenticate the client by certificate thumbprint.\n\nFor example::\n\n    new Client\n    {\n        ClientId = \"mtls\",\n        AllowedGrantTypes = GrantTypes.ClientCredentials,\n        AllowedScopes = { \"api1\" }\n        ClientSecrets = \n        {\n            // name based\n            new Secret(@\"CN=mtls.test, OU=ROO\\ballen@roo, O=mkcert development certificate\", \"mtls.test\")\n            {\n                Type = SecretTypes.X509CertificateName\n            },\n            // or thumbprint based\n            //new Secret(\"bca0d040847f843c5ee0fa6eb494837470155868\", \"mtls.test\")\n            //{\n            //    Type = SecretTypes.X509CertificateThumbprint\n            //},\n        },\n    }\n\nUsing a client certificate to authenticate to IdentityServer\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nWhen writing a client to connect to IdentityServer, the ``SocketsHttpHandler`` (or ``HttpClientHandler`` if you are on older .NET Framework versions) \nclass provides a convenient mechanism to add a client certificate to outgoing requests.\n\nAnd then HTTP calls (including using the various `IdentityModel <https://github.com/IdentityModel/IdentityModel2>`_ extension methods) with the ``HttpClient`` \nwill perform client certificate authentication at the TLS channel.\n\nFor example::\n\n    static async Task<TokenResponse> RequestTokenAsync()\n    {\n        var handler = new SocketsHttpHandler();\n        var cert = new X509Certificate2(\"client.p12\", \"password\");\n        handler.SslOptions.ClientCertificates = new X509CertificateCollection { cert };\n\n        var client = new HttpClient(handler);\n\n        var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n        if (disco.IsError) throw new Exception(disco.Error);\n\n        var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = disco\n                            .TryGetValue(OidcConstants.Discovery.MtlsEndpointAliases)\n                            .Value<string>(OidcConstants.Discovery.TokenEndpoint)\n                            .ToString(),\n                            \n            ClientId = \"mtls\",\n            Scope = \"api1\"\n        });\n\n        if (response.IsError) throw new Exception(response.Error);\n        return response;\n    }\n\n\nSender-constrained access tokens\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nWhenever a client authenticates to IdentityServer using a client certificate, the thumbprint of that certificate will be embedded in the access token.\n\nClients can use a X.509 client certificate as a mechanism for sender-constrained access tokens when authenticating to APIs.\nThe use of these sender-constrained access tokens requires the client to use the same X.509 client certificate to authenticate to the API as the one used for IdentityServer.\n\nConfirmation claim\n~~~~~~~~~~~~~~~~~~\nWhen a client obtains an access token and has authenticated with mutual TLS, IdentityServer issues a confirmation claim (or ``cnf``) in the access token.\nThis value is a hash of the thumbprint of the client certificate used to authenticate with IdentityServer.\n\nThis value can be seen in this screen shot of a decoded access token:\n\n.. image:: images/mtls_access_token_with_cnf.png\n\nThe API will then use this value to ensure the client certificate being used at the API matches the confirmation value in the access token.\n\nValidating and accepting a client certificate in APIs\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nAs mentioned above for client authentication in IdentityServer, in the API the web server is expected to perform the client certificate validation at the TLS layer.\n\nAdditionally, the API hosting application will need a mechanism to accept the client certificate in order to obtain the thumbprint to perform the confirmation claim validation.\nBelow is an example how an API in ASP.NET Core might be configured for both access tokens and client certificates::\n\n    services.AddAuthentication(\"token\")\n        .AddIdentityServerAuthentication(\"token\", options =>\n        {\n            options.Authority = \"https://identityserver8.io\";\n            options.ApiName = \"api1\";\n\n        })\n        .AddCertificate(options =>\n        {\n            options.AllowedCertificateTypes = CertificateTypes.All;\n        });\n\nFinally, a mechanism is needed that runs after the authentication middleware to authenticate the client certificate and compare the thumbprint to the ``cnf`` from the access token.\n\nBelow is a simple middleware that checks the claims::\n\n    public class ConfirmationValidationMiddlewareOptions\n    {\n        public string CertificateSchemeName { get; set; } = CertificateAuthenticationDefaults.AuthenticationScheme;\n        public string JwtBearerSchemeName { get; set; } = JwtBearerDefaults.AuthenticationScheme;\n    }\n    \n    // this middleware validate the cnf claim (if present) against the thumbprint of the X.509 client certificate for the current client\n    public class ConfirmationValidationMiddleware\n    {\n        private readonly RequestDelegate _next;\n        private readonly ConfirmationValidationMiddlewareOptions _options;\n\n        public ConfirmationValidationMiddleware(RequestDelegate next, ConfirmationValidationMiddlewareOptions options = null)\n        {\n            _next = next;\n            _options = options ?? new ConfirmationValidationMiddlewareOptions();\n        }\n\n        public async Task Invoke(HttpContext ctx)\n        {\n            if (ctx.User.Identity.IsAuthenticated)\n            {\n                var cnfJson = ctx.User.FindFirst(\"cnf\")?.Value;\n                if (!String.IsNullOrWhiteSpace(cnfJson))\n                {\n                    var certResult = await ctx.AuthenticateAsync(_options.CertificateSchemeName);\n                    if (!certResult.Succeeded)\n                    {\n                        await ctx.ChallengeAsync(_options.CertificateSchemeName);\n                        return;\n                    }\n\n                    var certificate = await ctx.Connection.GetClientCertificateAsync();\n                    var thumbprint = Base64UrlTextEncoder.Encode(certificate.GetCertHash(HashAlgorithmName.SHA256));\n\n                    var cnf = JObject.Parse(cnfJson);\n                    var sha256 = cnf.Value<string>(\"x5t#S256\");\n\n                    if (String.IsNullOrWhiteSpace(sha256) ||\n                        !thumbprint.Equals(sha256, StringComparison.Ordinal))\n                    {\n                        await ctx.ChallengeAsync(_options.JwtBearerSchemeName);\n                        return;\n                    }\n                }\n            }\n\n            await _next(ctx);\n        }\n\nBelow is an example pipeline for an API::\n\n    app.UseForwardedHeaders(new ForwardedHeadersOptions\n        {\n            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto\n        });\n        \n    app.UseCertificateForwarding();\n    app.UseRouting();\n    app.UseAuthentication();\n    \n    app.UseMiddleware<ConfirmationValidationMiddleware>(new ConfirmationValidationMiddlewareOptions\n    {\n        CertificateSchemeName = CertificateAuthenticationDefaults.AuthenticationScheme,\n        JwtBearerSchemeName = \"token\"\n    });\n\n    app.UseAuthorization();\n    \n    app.UseEndpoints(endpoints =>\n    {\n        endpoints.MapControllers();\n    });\n\nOnce the above middleware succeeds, then the caller has been authenticated with a sender-constrained access token.\n\nIntrospection and the confirmation claim\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nWhen the access token is a JWT, then the confirmation claim is contained in the token as a claim.\nWhen using reference tokens, the claims that the access token represents must be obtained via introspection.\nThe introspection endpoint in IdentityServer will return a ``cnf`` claim for reference tokens obtained via mutual TLS.\n\nEphemeral client certificates\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou can use the IdentityServer MTLS support also to create sender-constrained access tokens without using the client certificate for client authentication.\nThis is useful for situations where you already have client secrets in place that you don't want to change, e.g. shared secrets, or better private key JWTs. \n\nStill, if a client certificate is present, the confirmation claim can be embedded in outgoing access tokens. And as long as the client is using the same client certificate to \nrequest the token and calling the API, this will give you the desired proof-of-possession properties.\n\nFor this enable the following setting in the options::\n\n    var builder = services.AddIdentityServer(options =>\n    {\n        // other settings\n        \n        options.MutualTls.AlwaysEmitConfirmationClaim = true;\n    });\n\nUsing an ephemeral certificate to request a token\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nIn this scenario, the client uses *some* client secret (a shared secret in the below sample), but attaches an additional client certificate to the token request.\nSince this certificate does not need to be associated with the client at the token services, it can be created on the fly::\n\n    static X509Certificate2 CreateClientCertificate(string name)\n    {\n        X500DistinguishedName distinguishedName = new X500DistinguishedName($\"CN={name}\");\n\n        using (RSA rsa = RSA.Create(2048))\n        {\n            var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1);\n\n            request.CertificateExtensions.Add(\n                new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature , false));\n\n            request.CertificateExtensions.Add(\n                new X509EnhancedKeyUsageExtension(\n                    new OidCollection { new Oid(\"1.3.6.1.5.5.7.3.2\") }, false));\n\n            return request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)), new DateTimeOffset(DateTime.UtcNow.AddDays(10)));\n        }\n    }\n\nThen use this client certificate in addition to the already setup-up client secret::\n\n    static async Task<TokenResponse> RequestTokenAsync()\n    {\n        var client = new HttpClient(GetHandler(ClientCertificate));\n\n        var disco = await client.GetDiscoveryDocumentAsync(\"https://identityserver.local\");\n        if (disco.IsError) throw new Exception(disco.Error);\n\n        var endpoint = disco\n            .TryGetValue(OidcConstants.Discovery.MtlsEndpointAliases)\n            .Value<string>(OidcConstants.Discovery.TokenEndpoint)\n            .ToString();\n        \n        var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = endpoint,\n\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        if (response.IsError) throw new Exception(response.Error);\n        return response;\n    }\n\n    static SocketsHttpHandler GetHandler(X509Certificate2 certificate)\n    {\n        var handler = new SocketsHttpHandler();\n        handler.SslOptions.ClientCertificates = new X509CertificateCollection { certificate };\n\n        return handler;\n    }\n"
  },
  {
    "path": "docs/topics/persisted_grants.rst",
    "content": ".. _refPersistedGrants:\nPersisted Grants\n================\nMany grant types require persistence in IdentityServer.\nThese include authorization codes, refresh tokens, reference tokens, and remembered user consents.\nInternally in IdentityServer, the default storage for these grants is in a common store called the persisted grants store.\n\nPersisted Grant\n^^^^^^^^^^^^^^^\nThe persisted grant is the data type that maintains the values for a grant. \nIt has these properties:\n\n``Key``\n    The unique identifier for the persisted grant in the store.\n``Type``\n    The type of the grant.\n``SubjectId``\n    The subject id to which the grant belongs.\n``ClientId``\n    The client identifier for which the grant was created.\n``Description``\n    The description the user assigned to the grant or device being authorized.\n``CreationTime``\n    The date/time the grant was created.\n``Expiration``\n    The expiration of the grant.\n``ConsumedTime``\n    The date/time the grant was \"consumed\" (see below).\n``Data``\n    The grant specific serialized data.\n\n.. note:: The ``Data`` property contains a copy of all of the values (and more) and is considered authoritative by IdentityServer, thus the above values, by default, are considered informational and read-only.\n\nThe presence of the record in the store without a ``ConsumedTime`` and while still within the ``Expiration`` represents the validity of the grant.\nSetting either of these two values, or removing the record from the store effectively revokes the grant.\n\nGrant Consumption\n^^^^^^^^^^^^^^^^^\nSome grant types are one-time use only (either by definition or configuration).\nOnce they are \"used\", rather than deleting the record, the ``ConsumedTime`` value is set in the database marking them as having been used.\nThis \"soft delete\" allows for custom implementations to either have flexibility in allowing a grant to be re-used (typically within a short window of time),\nor to be used in risk assessment and threat mitigation scenarios (where suspicious activity is detected) to revoke access.\nFor refresh tokens, this sort of custom logic would be performed in the ``IRefreshTokenService``.\n\nPersisted Grant Service\n^^^^^^^^^^^^^^^^^^^^^^^\nWorking with the grants store directly might be too low level. \nAs such, a higher level service called ``IPersistedGrantService`` is provided.\nIt abstracts and aggregates the different grant types into one concept, and allows querying and revoking the persisted grants for a user.\n\nIt contains these APIs:\n\n``GetAllGrantsAsync``\n    Gets all the grants for a user based upon subject id. \n``RemoveAllGrantsAsync``\n    Removes grants from the store based on the subject id and optionally a client id and/or a session id.\n"
  },
  {
    "path": "docs/topics/pop.rst",
    "content": "Proof-of-Possession Access Tokens\n=================================\nBy default, OAuth access tokens are so called *bearer* tokens. This means they are not bound to a client and anybody who possess the token can use it (compare to cash).\n\n*Proof-of-Possession* (short PoP) tokens are bound to the client that requested the token. \nIf that token leaks, it cannot be used by anyone else (compare to a credit card - well at least in an ideal world).\n\nSee `this <https://leastprivilege.com/2020/01/15/oauth-2-0-the-long-road-to-proof-of-possession-access-tokens/>`_ blog post for more history and motivation.\n\nIdentityServer supports PoP tokens by using the :ref:`Mutual TLS mechanism <refMutualTLS>`."
  },
  {
    "path": "docs/topics/reference_tokens.rst",
    "content": "Reference Tokens\n================\nAccess tokens can come in two flavours - self-contained or reference.\n\nA JWT token would be a self-contained access token - it's a protected data structure with claims and an expiration.\nOnce an API has learned about the key material, it can validate self-contained tokens without needing to communicate with the issuer.\nThis makes JWTs hard to revoke. They will stay valid until they expire.\n\nWhen using reference tokens - IdentityServer will store the contents of the token in a data store and will only issue a unique identifier for this token back to the client.\nThe API receiving this reference must then open a back-channel communication to IdentityServer to validate the token.\n\n.. image:: images/reference_tokens.png\n\nYou can switch the token type of a client using the following setting::\n\n    client.AccessTokenType = AccessTokenType.Reference;\n\nIdentityServer provides an implementation of the OAuth 2.0 introspection specification which allows APIs to dereference the tokens.\nYou can either use our dedicated `introspection handler <https://github.com/IdentityModel/IdentityModel.AspNetCore.OAuth2Introspection>`_\nor use the `identity server authentication handler <https://github.com/alexhiggins732/IdentityServer8.AccessTokenValidation>`_ which can validate both JWTs and reference tokens.\n\nThe introspection endpoint requires authentication - since the client of an introspection endpoint is an API, you configure the secret on the ``ApiResource``::\n\n    var api = new ApiResource(\"api1\")\n    {\n        ApiSecrets = { new Secret(\"secret\".Sha256()) }\n    }\n\nSee :ref:`here <refProtectingApis>` for more information on how to configure the IdentityServer authentication middleware for APIs.\n"
  },
  {
    "path": "docs/topics/refresh_tokens.rst",
    "content": "Refresh Tokens\n==============\nSince access tokens have finite lifetimes, refresh tokens allow requesting new access tokens without user interaction.\n\nRefresh tokens are supported for the following flows: authorization code, hybrid and resource owner password credential flow.\nThe clients needs to be explicitly authorized to request refresh tokens by setting ``AllowOfflineAccess`` to ``true``.\n\nAdditional client settings\n^^^^^^^^^^^^^^^^^^^^^^^^^^\n``AbsoluteRefreshTokenLifetime``\n    Maximum lifetime of a refresh token in seconds. Defaults to 2592000 seconds / 30 days. Zero allows refresh tokens that, when used with ``RefreshTokenExpiration = Sliding`` only expire after the SlidingRefreshTokenLifetime is passed.\n``SlidingRefreshTokenLifetime``\n    Sliding lifetime of a refresh token in seconds. Defaults to 1296000 seconds / 15 days\n``RefreshTokenUsage``\n    ``ReUse`` the refresh token handle will stay the same when refreshing tokens\n    \n    ``OneTimeOnly`` the refresh token handle will be updated when refreshing tokens\n``RefreshTokenExpiration``\n    ``Absolute`` the refresh token will expire on a fixed point in time (specified by the AbsoluteRefreshTokenLifetime). This is the default.\n    \n    ``Sliding`` when refreshing the token, the lifetime of the refresh token will be renewed (by the amount specified in SlidingRefreshTokenLifetime). The lifetime will not exceed `AbsoluteRefreshTokenLifetime`.\n``UpdateAccessTokenClaimsOnRefresh``\n    Gets or sets a value indicating whether the access token (and its claims) should be updated on a refresh token request.\n\n.. note:: Public clients (clients without a client secret) should rotate their refresh tokens. Set the ``RefreshTokenUsage`` to ``OneTimeOnly``.\n\nRequesting a refresh token\n^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou can request a refresh token by adding a scope called ``offline_access`` to the scope parameter.\n\nRequesting an access token using a refresh token\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nTo get a new access token, you send the refresh token to the token endpoint.\nThis will result in a new token response containing a new access token and its expiration and potentially also a new refresh token depending on the client configuration (see above).\n\n::\n\n    POST /connect/token\n\n        client_id=client&\n        client_secret=secret&\n        grant_type=refresh_token&\n        refresh_token=hdh922\n        \n(Form-encoding removed and line breaks added for readability)\n\n.. Note:: You can use the `IdentityModel <https://github.com/IdentityModel/IdentityModel>`_ client library to programmatically access the token endpoint from .NET code. For more information check the IdentityModel `docs <https://identitymodel.readthedocs.io/en/latest/client/token.html>`_.\n\n.. Note:: The refresh token, must be valid or an invalid_grant error is returned.  By default, a refresh_token can only be used once.  Using an already used refresh_token will result in an invalid_grant error.\n\nCustomizing refresh token behavior\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAll refresh token handling is implemented in the ``DefaultRefreshTokenService`` (which is the default implementation of the ``IRefreshTokenService`` interface)::\n\n    public interface IRefreshTokenService\n    {\n        /// <summary>\n        /// Validates a refresh token.\n        /// </summary>\n        Task<TokenValidationResult> ValidateRefreshTokenAsync(string token, Client client);\n        \n        /// <summary>\n        /// Creates the refresh token.\n        /// </summary>\n        Task<string> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken, Client client);\n\n        /// <summary>\n        /// Updates the refresh token.\n        /// </summary>\n        Task<string> UpdateRefreshTokenAsync(string handle, RefreshToken refreshToken, Client client);\n    }\n\nThe logic around refresh token handling is pretty involved, and we don't recommend implementing the interface from scratch,\nunless you exactly know what you are doing.\nIf you want to customize certain behavior, it is more recommended to derive from the default implementation and call the base checks first.\n\nThe most common customization that you probably want to do is how to deal with refresh token replays.\nThis is for situations where the token usage has been set to one-time only, but the same token gets sent more than once.\nThis could either point to a replay attack of the refresh token, or to faulty client code like logic bugs or race conditions.\n\nIt is important to note, that a refresh token is never deleted in the database. \nOnce it has been used, the ``ConsumedTime`` property will be set.\nIf a token is received that has already been consumed, the default service will call a virtual method called ``AcceptConsumedTokenAsync``.\n\nThe default implementation will reject the request, but here you can implement custom logic like grace periods, \nor revoking additional refresh or access tokens.\n"
  },
  {
    "path": "docs/topics/request_object.rst",
    "content": "Authorize Request Objects\n=========================\nInstead of providing the parameters for an authorize request as individual query string key/value pairs, you can package them up in signed JWTs.\nThis makes the parameters tamper proof and you can authenticate the client already on the front-channel.\n\nYou can either transmit them by value or by reference to the authorize endpoint - see the `spec <https://openid.net/specs/openid-connect-core-1_0.html#JWTRequests>`_ for more details.\n\nIdentityServer requires the request JWTs to be signed. We support X509 certificates and JSON web keys, e.g.::\n\n    var client = new Client\n    {\n        ClientId = \"foo\",\n        \n        // set this to true to accept signed requests only\n        RequireRequestObject = true,\n\n        ClientSecrets = \n        {\n            new Secret\n            {\n                // X509 cert base64-encoded\n                Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                Value = Convert.ToBase64String(cert.Export(X509ContentType.Cert))\n            },\n            new Secret\n            {\n                // RSA key as JWK\n                Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                Value =\n                    \"{'e':'AQAB','kid':'ZzAjSnraU3bkWGnnAqLapYGpTyNfLbjbzgAPbbW2GEA','kty':'RSA','n':'wWwQFtSzeRjjerpEM5Rmqz_DsNaZ9S1Bw6UbZkDLowuuTCjBWUax0vBMMxdy6XjEEK4Oq9lKMvx9JzjmeJf1knoqSNrox3Ka0rnxXpNAz6sATvme8p9mTXyp0cX4lF4U2J54xa2_S9NF5QWvpXvBeC4GAJx7QaSw4zrUkrc6XyaAiFnLhQEwKJCwUw4NOqIuYvYp_IXhw-5Ti_icDlZS-282PcccnBeOcX7vc21pozibIdmZJKqXNsL1Ibx5Nkx1F1jLnekJAmdaACDjYRLL_6n3W4wUp19UvzB1lGtXcJKLLkqB6YDiZNu16OSiSprfmrRXvYmvD8m6Fnl5aetgKw'}\"\n            }\n        }\n    }\n\n.. note:: Microsoft.IdentityModel.Tokens.JsonWebKeyConverter has various helpers to convert keys to JWKs\n\nPassing request JWTs by reference\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIf the ``request_uri`` parameter is used, IdentityServer will make an outgoing HTTP call to fetch the JWT from the specified URL.\n\nYou can customize the HTTP client used for this outgoing connection, e.g. to add caching or retry logic (e.g. via the Polly library)::\n\n    builder.AddJwtRequestUriHttpClient(client =>\n    {\n        client.Timeout = TimeSpan.FromSeconds(30);\n    })\n        .AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(new[]\n        {\n            TimeSpan.FromSeconds(1),\n            TimeSpan.FromSeconds(2),\n            TimeSpan.FromSeconds(3)\n        }));\n\n.. note:: Request URI processing is disabled by default. Enable on the :ref:`IdentityServer Options <refOptions>` under ``Endpoints``. Also see the security considerations from the JAR `specification <https://tools.ietf.org/html/draft-ietf-oauth-jwsreq-23#section-10.4>`_.\n\nAccessing the request object data\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou can access the validated data from the request object in two ways\n\n* wherever you have access to the ``ValidatedAuthorizeRequest``, the ``RequestObjectValues`` dictionary holds the values\n* in the UI code you can call ``IIdentityServerInteractionService.GetAuthorizationContextAsync``, the resulting ``AuthorizationRequest`` object contains the ``RequestObjectValues`` dictionary as well\n"
  },
  {
    "path": "docs/topics/resource_owner.rst",
    "content": ".. _refResourceOwnerPasswordValidator:\nResource Owner Password Validation\n===================================\n\nIf you want to use the OAuth 2.0 resource owner password credential grant (aka ``password``), you need to implement and register the ``IResourceOwnerPasswordValidator`` interface::\n\n    public interface IResourceOwnerPasswordValidator\n    {\n        /// <summary>\n        /// Validates the resource owner password credential\n        /// </summary>\n        /// <param name=\"context\">The context.</param>\n        Task ValidateAsync(ResourceOwnerPasswordValidationContext context);\n    }\n\nOn the context you will find already parsed protocol parameters like ``UserName`` and ``Password``, but also the raw request if you want to look at other input data.\n\nYour job is then to implement the password validation and set the ``Result`` on the context accordingly. See the :ref:`GrantValidationResult <refGrantValidationResult>` documentation."
  },
  {
    "path": "docs/topics/resources.rst",
    "content": ".. _refResources:\nDefining Resources\n==================\nThe ultimate job of an OpenID Connect/OAuth token service is to control access to resources.\n\nThe two fundamental resource types in IdentityServer are:\n\n* **identity resources:** represent claims about a user like user ID, display name, email address etc…\n* **API resources:** represent functionality a client wants to access. Typically, they are HTTP-based endpoints (aka APIs), but could be also message queuing endpoints or similar.\n\n.. note:: You can define resources using a C# object model - or load them from a data store. An implementation of ``IResourceStore`` deals with these low-level details. For this document we are using the in-memory implementation.\n\nIdentity Resources\n------------------\nAn identity resource is a named group of claims that can be requested using the *scope* parameter.\n\nThe OpenID Connect specification `suggests <https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims>`_ a couple of standard \nscope name to claim type mappings that might be useful to you for inspiration, but you can freely design them yourself.\n\nOne of them is actually mandatory, the *openid* scope, which tells the provider to return the *sub* (subject id) claim in the identity token.\n\nThis is how you could define the openid scope in code::\n\n    public static IEnumerable<IdentityResource> GetIdentityResources()\n    {\n        return new List<IdentityResource>\n        {\n            new IdentityResource(\n                name: \"openid\",\n                userClaims: new[] { \"sub\" },\n                displayName: \"Your user identifier\")\n        };\n    }\n\nBut since this is one of the standard scopes from the spec you can shorten that to::\n\n    public static IEnumerable<IdentityResource> GetIdentityResources()\n    {\n        return new List<IdentityResource>\n        {\n            new IdentityResources.OpenId()\n        };\n    }\n\n.. note:: see the reference section for more information on ``IdentityResource``.\n\nThe following example shows a custom identity resource called *profile* that represents the display name, email address and website claim::\n\n    public static IEnumerable<IdentityResource> GetIdentityResources()\n    {\n        return new List<IdentityResource>\n        {\n            new IdentityResource(\n                name: \"profile\",\n                userClaims: new[] { \"name\", \"email\", \"website\" },\n                displayName: \"Your profile data\")\n        };\n    }\n\nOnce the resource is defined, you can give access to it to a client via the ``AllowedScopes`` option (other properties omitted)::\n\n    var client = new Client\n    {\n        ClientId = \"client\",\n        \n        AllowedScopes = { \"openid\", \"profile\" }\n    };\n\n\nThe client can then request the resource using the scope parameter (other parameters omitted)::\n\n    https://demo.identityserver8.io/connect/authorize?client_id=client&scope=openid profile\n\nIdentityServer will then use the scope names to create a list of requested claim types, \nand present that to your implementation of the :ref:`profile service <refProfileService>`.\n\n.. _refApiResources:\nAPIs\n----\nDesigning your API surface can be a complicated task. IdentityServer provides a couple of primitives to help you with that.\n\nThe original OAuth 2.0 specification has the concept of scopes, which is just defined as *the scope of access* that the client requests.\nTechnically speaking, the *scope* parameter is a list of space delimited values - you need to provide the structure and semantics of it.\n\nIn more complex systems, often the notion of a *resource* is introduced. This might be e.g. a physical or logical API. \nIn turn each API can potentially have scopes as well. Some scopes might be exclusive to that resource, and some scopes might be shared.\n\nLet's start with simple scopes first, and then we'll have a look how resources can help structure scopes.\n\nScopes\n^^^^^^\nLet's model something very simple - a system that has three logical operations *read*, *write*, and *delete*.\n\nYou can define them using the ``ApiScope`` class::\n\n    public static IEnumerable<ApiScope> GetApiScopes()\n    {\n        return new List<ApiScope>\n        {\n            new ApiScope(name: \"read\",   displayName: \"Read your data.\"),\n            new ApiScope(name: \"write\",  displayName: \"Write your data.\"),\n            new ApiScope(name: \"delete\", displayName: \"Delete your data.\")\n        };\n    }\n\nYou can then assign the scopes to various clients, e.g.::\n\n    var webViewer = new Client\n    {\n        ClientId = \"web_viewer\",\n        \n        AllowedScopes = { \"openid\", \"profile\", \"read\" }\n    };\n\n    var mobileApp = new Client\n    {\n        ClientId = \"mobile_app\",\n        \n        AllowedScopes = { \"openid\", \"profile\", \"read\", \"write\", \"delete\" }\n    }\n\nAuthorization based on Scopes\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nWhen a client asks for a scope (and that scope is allowed via configuration and not denied via consent), \nthe value of that scope will be included in the resulting access token as a claim of type *scope* (for both JWTs and introspection), e.g.::\n\n    {\n        \"typ\": \"at+jwt\"\n    }.\n    {\n        \"client_id\": \"mobile_app\",\n        \"sub\": \"123\",\n\n        \"scope\": \"read write delete\"\n    }\n\nThe consumer of the access token can use that data to make sure that the client is actually allowed to invoke the corresponding functionality.\n\n.. note:: Be aware, that scopes are purely for authorizing clients - not users. IOW - the *write* scope allows the client to invoke the functionality associated with that. Still that client can most probably only write the data the belongs to the current user. This additional user centric authorization is application logic and not covered by OAuth.\n\nYou can add more identity information about the user by deriving additional claims from the scope request. The following scope definition tells the configuration system,\nthat when a *write* scope gets granted, the *user_level* claim should be added to the access token::\n\n    var writeScope = new ApiScope(\n        name: \"write\",\n        displayName: \"Write your data.\",\n        userClaims: new[] { \"user_level\" });\n\nThis will pass the *user_level* claim as a requested claim type to the profile service, \nso that the consumer of the access token can use this data as input for authorization decisions or business logic.\n\n.. note:: When using the scope-only model, no aud (audience) claim will be added to the token, since this concept does not apply. If you need an aud claim, you can enable the ``EmitStaticAudience`` setting on the options. This will emit an aud claim in the ``issuer_name/resources`` format. If you need more control of the aud claim, use API resources.\n\nParameterized Scopes\n^^^^^^^^^^^^^^^^^^^^\nSometimes scopes have a certain structure, e.g. a scope name with an additional parameter: *transaction:id* or *read_patient:patientid*.\n\nIn this case you would create a scope without the parameter part and assign that name to a client, but in addition provide some logic to parse the structure\nof the scope at runtime using the ``IScopeParser`` interface or by deriving from our default implementation, e.g.::\n\n    public class ParameterizedScopeParser : DefaultScopeParser\n    {\n        public ParameterizedScopeParser(ILogger<DefaultScopeParser> logger) : base(logger)\n        {\n        }\n\n        public override void ParseScopeValue(ParseScopeContext scopeContext)\n        {\n            const string transactionScopeName = \"transaction\";\n            const string separator = \":\";\n            const string transactionScopePrefix = transactionScopeName + separator;\n\n            var scopeValue = scopeContext.RawValue;\n\n            if (scopeValue.StartsWith(transactionScopePrefix))\n            {\n                // we get in here with a scope like \"transaction:something\"\n                var parts = scopeValue.Split(separator, StringSplitOptions.RemoveEmptyEntries);\n                if (parts.Length == 2)\n                {\n                    scopeContext.SetParsedValues(transactionScopeName, parts[1]);\n                }\n                else\n                {\n                    scopeContext.SetError(\"transaction scope missing transaction parameter value\");\n                }\n            }\n            else if (scopeValue != transactionScopeName)\n            {\n                // we get in here with a scope not like \"transaction\"\n                base.ParseScopeValue(scopeContext);\n            }\n            else\n            {\n                // we get in here with a scope exactly \"transaction\", which is to say we're ignoring it \n                // and not including it in the results\n                scopeContext.SetIgnore();\n            }\n        }\n    }\n\nYou then have access to the parsed value throughout the pipeline, e.g. in the profile service::\n\n    public class HostProfileService : IProfileService\n    {\n        public override async Task GetProfileDataAsync(ProfileDataRequestContext context)\n        {\n            var transaction = context.RequestedResources.ParsedScopes.FirstOrDefault(x => x.ParsedName == \"transaction\");\n            if (transaction?.ParsedParameter != null)\n            {\n                context.IssuedClaims.Add(new Claim(\"transaction_id\", transaction.ParsedParameter));\n            }\n        }\n    }\n\nAPI Resources\n^^^^^^^^^^^^^\nWhen the API surface gets larger, a flat list of scopes like the one used above might not be feasible.\n\nYou typically need to introduce some sort of namespacing to organize the scope names, and maybe you also want to group them together and \nget some higher-level constructs like an *audience* claim in access tokens.\nYou might also have scenarios, where multiple resources should support the same scope names, whereas sometime you explicitly want to isolate a scope to a certain resource.\n\nIn IdentityServer, the ``ApiResource`` class allows some additional organization. Let's use the following scope definition::\n\n    public static IEnumerable<ApiScope> GetApiScopes()\n    {\n        return new List<ApiScope>\n        {\n            // invoice API specific scopes\n            new ApiScope(name: \"invoice.read\",   displayName: \"Reads your invoices.\"),\n            new ApiScope(name: \"invoice.pay\",    displayName: \"Pays your invoices.\"),\n\n            // customer API specific scopes\n            new ApiScope(name: \"customer.read\",    displayName: \"Reads you customers information.\"),\n            new ApiScope(name: \"customer.contact\", displayName: \"Allows contacting one of your customers.\"),\n\n            // shared scope\n            new ApiScope(name: \"manage\", displayName: \"Provides administrative access to invoice and customer data.\")\n        };\n    }\n\nWith ``ApiResource`` you can now create two logical APIs and their corresponding scopes::\n\n    public static readonly IEnumerable<ApiResource> GetApiResources()\n    { \n        return new List<ApiResource>\n        {\n            new ApiResource(\"invoice\", \"Invoice API\")\n            {\n                Scopes = { \"invoice.read\", \"invoice.pay\", \"manage\" }\n            },\n            \n            new ApiResource(\"customer\", \"Customer API\")\n            {\n                Scopes = { \"customer.read\", \"customer.contact\", \"manage\" }\n            }\n        };\n    }\n\nUsing the API resource grouping gives you the following additional features\n\n* support for the JWT *aud* claim. The value(s) of the audience claim will be the name of the API resource(s)\n* support for adding common user claims across all contained scopes\n* support for introspection by assigning an API secret to the resource\n* support for configuring the access token signing algorithm for the resource\n\nLet's have a look at some example access tokens for the above resource configuration.\n\n**Client requests** invoice.read and invoice.pay::\n\n    {\n        \"typ\": \"at+jwt\"\n    }.\n    {\n        \"client_id\": \"client\",\n        \"sub\": \"123\",\n\n        \"aud\": \"invoice\",\n        \"scope\": \"invoice.read invoice.pay\"\n    }\n\n**Client requests** invoice.read and customer.read::\n\n    {\n        \"typ\": \"at+jwt\"\n    }.\n    {\n        \"client_id\": \"client\",\n        \"sub\": \"123\",\n\n        \"aud\": [ \"invoice\", \"customer\" ]\n        \"scope\": \"invoice.read customer.read\"\n    }\n\n**Client requests** manage::\n\n    {\n        \"typ\": \"at+jwt\"\n    }.\n    {\n        \"client_id\": \"client\",\n        \"sub\": \"123\",\n\n        \"aud\": [ \"invoice\", \"customer\" ]\n        \"scope\": \"manage\"\n    }\n\nMigration steps to v4\n^^^^^^^^^^^^^^^^^^^^^\nAs described above, starting with v4, scopes have their own definition and can optionally be referenced by resources. \nBefore v4, scopes were always contained within a resource.\n\nTo migrate to v4 you need to split up scope and resource registration, typically by first registering all your scopes\n(e.g. using the ``AddInMemoryApiScopes`` method), and then register the API resources (if any) afterwards.\nThe API resources will then reference the prior registered scopes by name.\n"
  },
  {
    "path": "docs/topics/signin.rst",
    "content": ".. _refSignIn:\nSign-in\n=======\n\nIn order for IdentityServer to issue tokens on behalf of a user, that user must sign-in to IdentityServer.\n\nCookie authentication\n^^^^^^^^^^^^^^^^^^^^^\nAuthentication is tracked with a cookie managed by the `cookie authentication <https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie>`_ handler from ASP.NET Core.\n\nIdentityServer registers two cookie handlers (one for the authentication session and one for temporary external cookies). These are used by default and you can get their\nnames from the ``IdentityServerConstants`` class (``DefaultCookieAuthenticationScheme`` and ``ExternalCookieAuthenticationScheme``) if you want to reference them manually.\n\nOnly the basic settings are exposed for these cookies (expiration and sliding), but you can register your own cookie handlers if you need more control.\nIdentityServer uses whichever cookie handler matches the ``DefaultAuthenticateScheme`` as configured on the ``AuthenticationOptions`` when using ``AddAuthentication`` from ASP.NET Core.\n\n.. note:: In addition to the authentication cookie, IdentityServer will issue an additional cookie which defaults to the name \"idsrv.session\". This cookie is derived from the main authentication cookie, and it used for the check session endpoint for :ref:`browser-based JavaScript clients at signout time <refSignOut>`. It is kept in sync with the authentication cookie, and is removed when the user signs out.\n\nOverriding cookie handler configuration\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIf you wish to use your own cookie authentication handler, then you must configure it yourself.\nThis must be done in ``ConfigureServices`` after registering IdentityServer in DI (with ``AddIdentityServer``).\nFor example::\n\n    services.AddIdentityServer()\n        .AddInMemoryClients(Clients.Get())\n        .AddInMemoryIdentityResources(Resources.GetIdentityResources())\n        .AddInMemoryApiResources(Resources.GetApiResources())\n        .AddDeveloperSigningCredential()\n        .AddTestUsers(TestUsers.Users);\n\n    services.AddAuthentication(\"MyCookie\")\n        .AddCookie(\"MyCookie\", options =>\n        {\n            options.ExpireTimeSpan = ...;\n        });\n\n.. note:: IdentityServer internally calls both ``AddAuthentication`` and ``AddCookie`` with a custom scheme (via the constant ``IdentityServerConstants.DefaultCookieAuthenticationScheme``), so to override them you must make the same calls after ``AddIdentityServer``.\n\nLogin User Interface and Identity Management System\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nIdentityServer does not provide any user-interface or user database for user authentication.\nThese are things you are expected to provide or develop yourself.\n\nIf you need a starting point for a basic UI (login, logout, consent and manage grants), \nyou can use our `quickstart UI <https://github.com/alexhiggins732/IdentityServer8.Quickstart.UI>`_.\n\nThe quickstart UI authenticates users against an in-memory database. You would replace those bits with access to your real user store.\nWe have samples that use :ref:`ASP.NET Identity <refAspNetIdentityQuickstart>`.\n\nLogin Workflow\n^^^^^^^^^^^^^^\nWhen IdentityServer receives a request at the authorization endpoint and the user is not authenticated, the user will be redirected to the configured login page.\nYou must inform IdentityServer of the path to your login page via the ``UserInteraction`` settings on the :ref:`options <refOptions>` (the default is ``/account/login``).\nA ``returnUrl`` parameter will be passed informing your login page where the user should be redirected once login is complete.\n\n.. image:: images/signin_flow.png\n\n.. Note:: Beware `open-redirect attacks <https://en.wikipedia.org/wiki/URL_redirection#Security_issues>`_ via the ``returnUrl`` parameter. You should validate that the ``returnUrl`` refers to well-known location. See the :ref:`interaction service <refInteractionService>` for APIs to validate the ``returnUrl`` parameter.\n\nLogin Context\n^^^^^^^^^^^^^\nOn your login page you might require information about the context of the request in order to customize the login experience \n(such as client, prompt parameter, IdP hint, or something else).\nThis is made available via the ``GetAuthorizationContextAsync`` API on the :ref:`interaction service <refInteractionService>`.\n\nIssuing a cookie and Claims\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThere are authentication-related extension methods on the ``HttpContext`` from ASP.NET Core to issue the authentication cookie and sign a user in. \nThe authentication scheme used must match the cookie handler you are using (see above).\n\nWhen you sign the user in you must issue at least a ``sub`` claim and a ``name`` claim.\nIdentityServer also provides a few ``SignInAsync`` extension methods on the ``HttpContext`` to make this more convenient.\n\nYou can also optionally issue an ``idp`` claim (for the identity provider name), an ``amr`` claim (for the authentication method used), and/or an ``auth_time`` claim (for the epoch time a user authenticated).\nIf you do not provide these, then IdentityServer will provide default values.\n"
  },
  {
    "path": "docs/topics/signin_external_providers.rst",
    "content": ".. _refExternalIdentityProviders:\nSign-in with External Identity Providers\n========================================\n\nASP.NET Core has a flexible way to deal with external authentication. This involves a couple of steps.\n\n.. Note:: If you are using ASP.NET Identity, many of the underlying technical details are hidden from you. It is recommended that you also read the Microsoft `docs <https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/>`_ and do the ASP.NET Identity :ref:`quickstart <refAspNetIdentityQuickstart>`.\n\nAdding authentication handlers for external providers\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThe protocol implementation that is needed to talk to an external provider is encapsulated in an *authentication handler*.\nSome providers use proprietary protocols (e.g. social providers like Facebook) and some use standard protocols, e.g. OpenID Connect, WS-Federation or SAML2p.\n\nSee this :ref:`quickstart <refExternalAuthenticationQuickstart>` for step-by-step instructions for adding external authentication and configuring it.\n\nThe role of cookies\n^^^^^^^^^^^^^^^^^^^\nOne option on an external authentication handlers is called ``SignInScheme``, e.g.::\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = \"scheme of cookie handler to use\";\n\n            options.ClientId = \"...\";\n            options.ClientSecret = \"...\";\n        })\n\nThe signin scheme specifies the name of the cookie handler that will temporarily store the outcome of the external authentication, \ne.g. the claims that got sent by the external provider. This is necessary, since there are typically a couple of redirects involved until you are done with the \nexternal authentication process.\n\nGiven that this is such a common practise, IdentityServer registers a cookie handler specifically for this external provider workflow.\nThe scheme is represented via the ``IdentityServerConstants.ExternalCookieAuthenticationScheme`` constant.\nIf you were to use our external cookie handler, then for the ``SignInScheme`` above you'd assign the value to be the ``IdentityServerConstants.ExternalCookieAuthenticationScheme`` constant::\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"...\";\n            options.ClientSecret = \"...\";\n        })\n\nYou can also register your own custom cookie handler instead, like this::\n\n    services.AddAuthentication()\n        .AddCookie(\"YourCustomScheme\")\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = \"YourCustomScheme\";\n\n            options.ClientId = \"...\";\n            options.ClientSecret = \"...\";\n        })\n\n.. Note:: For specialized scenarios, you can also short-circuit the external cookie mechanism and forward the external user directly to the main cookie handler. This typically involves handling events on the external handler to make sure you do the correct claims transformation from the external identity source.\n\nTriggering the authentication handler\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nYou invoke an external authentication handler via the ``ChallengeAsync`` extension method on the ``HttpContext`` (or using the MVC ``ChallengeResult``).\n\nYou typically want to pass in some options to the challenge operation, e.g. the path to your callback page and the name of the provider for bookkeeping, e.g.::\n\n    var callbackUrl = Url.Action(\"ExternalLoginCallback\");\n    \n    var props = new AuthenticationProperties\n    {\n        RedirectUri = callbackUrl,\n        Items = \n        { \n            { \"scheme\", provider },\n            { \"returnUrl\", returnUrl }\n        }\n    };\n    \n    return Challenge(provider, props);\n\nHandling the callback and signing in the user\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nOn the callback page your typical tasks are:\n\n* inspect the identity returned by the external provider.\n* make a decision how you want to deal with that user. This might be different based on the fact if this is a new user or a returning user.\n* new users might need additional steps and UI before they are allowed in.\n* probably create a new internal user account that is linked to the external provider.\n* store the external claims that you want to keep.\n* delete the temporary cookie\n* sign-in the user\n\n**Inspecting the external identity**::\n\n    // read external identity from the temporary cookie\n    var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n    if (result?.Succeeded != true)\n    {\n        throw new Exception(\"External authentication error\");\n    }\n\n    // retrieve claims of the external user\n    var externalUser = result.Principal;\n    if (externalUser == null)\n    {\n        throw new Exception(\"External authentication error\");\n    }\n\n    // retrieve claims of the external user\n    var claims = externalUser.Claims.ToList();\n\n    // try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier\n    // depending on the external provider, some other claim type might be used\n    var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);\n    if (userIdClaim == null)\n    {\n        userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);\n    }\n    if (userIdClaim == null)\n    {\n        throw new Exception(\"Unknown userid\");\n    }\n    \n    var externalUserId = userIdClaim.Value;\n    var externalProvider = userIdClaim.Issuer;\n\n    // use externalProvider and externalUserId to find your user, or provision a new user\n\n**Clean-up and sign-in**::\n\n    // issue authentication cookie for user\n    await HttpContext.SignInAsync(new IdentityServerUser(user.SubjectId) {\n        DisplayName = user.Username,\n        IdentityProvider = provider,\n        AdditionalClaims = additionalClaims,\n        AuthenticationTime = DateTime.Now\n    });\n\n    // delete temporary cookie used during external authentication\n    await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n    // validate return URL and redirect back to authorization endpoint or a local page\n    if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl))\n    {\n        return Redirect(returnUrl);\n    }\n\n    return Redirect(\"~/\");\n\nState, URL length, and ISecureDataFormat\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nWhen redirecting to an external provider for sign-in, frequently state from the client application must be round-tripped.\nThis means that state is captured prior to leaving the client and preserved until the user has returned to the client application.\nMany protocols, including OpenID Connect, allow passing some sort of state as a parameter as part of the request, and the identity provider will return that state on the response.\nThe OpenID Connect authentication handler provided by ASP.NET Core utilizes this feature of the protocol, and that is how it implements the ``returnUrl`` feature mentioned above.\n\nThe problem with storing state in a request parameter is that the request URL can get too large (over the common limit of 2000 characters).\nThe OpenID Connect authentication handler does provide an extensibility point to store the state in your server, rather than in the request URL. \nYou can implement this yourself by implementing ``ISecureDataFormat<AuthenticationProperties>`` and configuring it on the `OpenIdConnectOptions <https://github.com/aspnet/AspNetCore/blob/main/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs#L249>`_.\n\nFortunately, IdentityServer provides an implementation of this for you, backed by the ``IDistributedCache`` implementation registered in the DI container (e.g. the standard ``MemoryDistributedCache``).\nTo use the IdentityServer provided secure data format implementation, simply call the ``AddOidcStateDataFormatterCache`` extension method on the ``IServiceCollection`` when configuring DI.\nIf no parameters are passed, then all OpenID Connect handlers configured will use the IdentityServer provided secure data format implementation::\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        // configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache.\n        services.AddOidcStateDataFormatterCache();\n\n        services.AddAuthentication()\n            .AddOpenIdConnect(\"demoidsrv\", \"IdentityServer\", options =>\n            {\n                // ...\n            })\n            .AddOpenIdConnect(\"aad\", \"Azure AD\", options =>\n            {\n                // ...\n            })\n            .AddOpenIdConnect(\"adfs\", \"ADFS\", options =>\n            {\n                // ...\n            });\n    }\n\n\nIf only particular schemes are to be configured, then pass those schemes as parameters::\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        // configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache.\n        services.AddOidcStateDataFormatterCache(\"aad\", \"demoidsrv\");\n\n        services.AddAuthentication()\n            .AddOpenIdConnect(\"demoidsrv\", \"IdentityServer\", options =>\n            {\n                // ...\n            })\n            .AddOpenIdConnect(\"aad\", \"Azure AD\", options =>\n            {\n                // ...\n            })\n            .AddOpenIdConnect(\"adfs\", \"ADFS\", options =>\n            {\n                // ...\n            });\n    }\n\n"
  },
  {
    "path": "docs/topics/signout.rst",
    "content": ".. _refSignOut:\nSign-out\n========\n\nSigning out of IdentityServer is as simple as removing the authentication cookie, \nbut for doing a complete federated sign-out, we must consider signing the user out of the client applications (and maybe even up-stream identity providers) as well.\n\nRemoving the authentication cookie\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nTo remove the authentication cookie, simply use the ``SignOutAsync`` extension method on the ``HttpContext``.\nYou will need to pass the scheme used (which is provided by ``IdentityServerConstants.DefaultCookieAuthenticationScheme`` unless you have changed it)::\n\n    await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);\n\nOr you can use the convenience extension method that is provided by IdentityServer::\n\n    await HttpContext.SignOutAsync();\n\n.. Note:: Typically you should prompt the user for signout (meaning require a POST), otherwise an attacker could hotlink to your logout page causing the user to be automatically logged out.\n\nNotifying clients that the user has signed-out\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nAs part of the signout process you will want to ensure client applications are informed that the user has signed out.\nIdentityServer supports the `front-channel <https://openid.net/specs/openid-connect-frontchannel-1_0.html>`_ specification for server-side clients (e.g. MVC),\nthe `back-channel <https://openid.net/specs/openid-connect-backchannel-1_0.html>`_  specification for server-side clients (e.g. MVC),\nand the `session management <https://openid.net/specs/openid-connect-session-1_0.html>`_ specification for browser-based JavaScript clients (e.g. SPA, React, Angular, etc.).\n\n**Front-channel server-side clients**\n\nTo signout the user from the server-side client applications via the front-channel spec, the \"logged out\" page in IdentityServer must render an ``<iframe>`` to notify the clients that the user has signed out.\nClients that wish to be notified must have the ``FrontChannelLogoutUri`` configuration value set.\nIdentityServer tracks which clients the user has signed into, and provides an API called ``GetLogoutContextAsync`` on the ``IIdentityServerInteractionService`` (:ref:`details <refInteractionService>`). \nThis API returns a ``LogoutRequest`` object with a ``SignOutIFrameUrl`` property that your logged out page must render into an ``<iframe>``.\n\n**Back-channel server-side clients**\n\nTo signout the user from the server-side client applications via the back-channel spec the ``IBackChannelLogoutService`` service can be used. \nIdentityServer will automatically use this service when your logout page removes the user's authentication cookie via a call to ``HttpContext.SignOutAsync``.\nClients that wish to be notified must have the ``BackChannelLogoutUri`` configuration value set.\n\n**Browser-based JavaScript clients**\n\nGiven how the `session management <https://openid.net/specs/openid-connect-session-1_0.html>`_ specification is designed, there is nothing special in IdentityServer that you need to do to notify these clients that the user has signed out.\nThe clients, though, must perform monitoring on the `check_session_iframe`, and this is implemented by the `oidc-client JavaScript library <https://github.com/IdentityModel/oidc-client-js/>`_.\n\nSign-out initiated by a client application\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf sign-out was initiated by a client application, then the client first redirected the user to the :ref:`end session endpoint <refEndSession>`.\nProcessing at the end session endpoint might require some temporary state to be maintained (e.g. the client's post logout redirect uri) across the redirect to the logout page.\nThis state might be of use to the logout page, and the identifier for the state is passed via a `logoutId` parameter to the logout page.\n\nThe ``GetLogoutContextAsync`` API on the :ref:`interaction service <refInteractionService>` can be used to load the state.\nOf interest on the ``LogoutRequest`` model context class is the ``ShowSignoutPrompt`` which indicates if the request for sign-out has been authenticated, and therefore it's safe to not prompt the user for sign-out.\n\nBy default this state is managed as a protected data structure passed via the `logoutId` value.\nIf you wish to use some other persistence between the end session endpoint and the logout page, then you can implement ``IMessageStore<LogoutMessage>`` and register the implementation in DI.\n"
  },
  {
    "path": "docs/topics/signout_external_providers.rst",
    "content": ".. _refSignOutExternal:\nSign-out of External Identity Providers\n=======================================\n\nWhen a user is :ref:`signing-out <refSignOut>` of IdentityServer, and they have used an :ref:`external identity provider <refExternalIdentityProviders>` to sign-in then it is likely that they should be redirected to also sign-out of the external provider.\nNot all external providers support sign-out, as it depends on the protocol and features they support.\n\nTo detect that a user must be redirected to an external identity provider for sign-out is typically done by using a ``idp`` claim issued into the cookie at IdentityServer.\nThe value set into this claim is the ``AuthenticationScheme`` of the corresponding authentication middleware.\nAt sign-out time this claim is consulted to know if an external sign-out is required.\n\nRedirecting the user to an external identity provider is problematic due to the cleanup and state management already required by the normal sign-out workflow.\nThe only way to then complete the normal sign-out and cleanup process at IdentityServer is to then request from the external identity provider that after its logout that the user be redirected back to IdentityServer.\nNot all external providers support post-logout redirects, as it depends on the protocol and features they support.\n\nThe workflow at sign-out is then to revoke IdentityServer's authentication cookie, and then redirect to the external provider requesting a post-logout redirect.\nThe post-logout redirect should maintain the necessary sign-out state described :ref:`here <refSignOut>` (i.e. the ``logoutId`` parameter value).\nTo redirect back to IdentityServer after the external provider sign-out, the ``RedirectUri`` should be used on the ``AuthenticationProperties`` when using ASP.NET Core's ``SignOutAsync`` API, for example::\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await _account.BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        var user = HttpContext.User;\n        if (user?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(user.GetSubjectId(), user.GetName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\nOnce the user is signed-out of the external provider and then redirected back, the normal sign-out processing at IdentityServer should execute which involves processing the ``logoutId`` and doing all necessary cleanup.\n"
  },
  {
    "path": "docs/topics/signout_federated.rst",
    "content": ".. _refSignOutFederated:\nFederated Sign-out\n==================\n\nFederated sign-out is the situation where a user has used an external identity provider to log into IdentityServer, and then the user logs out of that external identity provider via a workflow unknown to IdentityServer.\nWhen the user signs out, it will be useful for IdentityServer to be notified so that it can sign the user out of IdentityServer and all of the applications that use IdentityServer.\n\nNot all external identity providers support federated sign-out, but those that do will provide a mechanism to notify clients that the user has signed out.\nThis notification usually comes in the form of a request in an ``<iframe>`` from the external identity provider's \"logged out\" page.\nIdentityServer must then notify all of its clients (as discussed :ref:`here <refSignOut>`), also typically in the form of a request in an ``<iframe>`` from within the external identity provider's ``<iframe>``.\n\nWhat makes federated sign-out a special case (when compared to a normal :ref:`sign-out <refSignOut>`) is that the federated sign-out request is not to the normal sign-out endpoint in IdentityServer.\nIn fact, each external IdentityProvider will have a different endpoint into your IdentityServer host. \nThis is due to that fact that each external identity provider might use a different protocol, and each middleware listens on different endpoints.\n\nThe net effect of all of these factors is that there is no \"logged out\" page being rendered as we would on the normal sign-out workflow, \nwhich means we are missing the sign-out notifications to IdentityServer's clients.\nWe must add code for each of these federated sign-out endpoints to render the necessary notifications to achieve federated sign-out.\n\nFortunately IdentityServer already contains this code. \nWhen requests come into IdentityServer and invoke the handlers for external authentication providers, IdentityServer detects if these are federated signout requests and if they are it will automatically render the same ``<iframe>`` as :ref:`described here for signout <refSignOut>`.\nIn short, federated signout is automatically supported.\n"
  },
  {
    "path": "docs/topics/startup.rst",
    "content": ".. _refStartup:\nStartup\n=======\n\nIdentityServer is a combination of middleware and services.\nAll configuration is done in your startup class.\n\nConfiguring services\n^^^^^^^^^^^^^^^^^^^^\nYou add the IdentityServer services to the DI system by calling::\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var builder = services.AddIdentityServer();\n    }\n\nOptionally you can pass in options into this call. See :ref:`here <refOptions>` for details on options.\n\nThis will return you a builder object that in turn has a number of convenience methods to wire up additional services.\n\n.. _refStartupKeyMaterial:\nKey material\n^^^^^^^^^^^^\nIdentityServer supports X.509 certificates (both raw files and a reference to the Windows certificate store), \nRSA keys and EC keys for token signatures and validation. Each key can be configured with a (compatible) signing algorithm, \ne.g. RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384 or ES512.\n\nYou can configure the key material with the following methods:\n\n* ``AddSigningCredential``\n    Adds a signing key that provides the specified key material to the various token creation/validation services.\n* ``AddDeveloperSigningCredential``\n    Creates temporary key material at startup time. This is for dev scenarios. The generated key will be persisted in the local directory by default.\n* ``AddValidationKey``\n    Adds a key for validating tokens. They will be used by the internal token validator and will show up in the discovery document.\n\nIn-Memory configuration stores\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe various \"in-memory\" configuration APIs allow for configuring IdentityServer from an in-memory list of configuration objects.\nThese \"in-memory\" collections can be hard-coded in the hosting application, or could be loaded dynamically from a configuration file or a database.\nBy design, though, these collections are only created when the hosting application is starting up.\n\nUse of these configuration APIs are designed for use when prototyping, developing, and/or testing where it is not necessary to dynamically consult database at runtime for the configuration data.\nThis style of configuration might also be appropriate for production scenarios if the configuration rarely changes, or it is not inconvenient to require restarting the application if the value must be changed.\n\n* ``AddInMemoryClients``\n    Registers ``IClientStore`` and ``ICorsPolicyService`` implementations based on the in-memory collection of ``Client`` configuration objects.\n* ``AddInMemoryIdentityResources``\n    Registers ``IResourceStore`` implementation based on the in-memory collection of ``IdentityResource`` configuration objects.\n* ``AddInMemoryApiScopes``\n    Registers ``IResourceStore`` implementation based on the in-memory collection of ``ApiScope`` configuration objects.\n* ``AddInMemoryApiResources``\n    Registers ``IResourceStore`` implementation based on the in-memory collection of ``ApiResource`` configuration objects.\n\nTest stores\n^^^^^^^^^^^\n\nThe ``TestUser`` class models a user, their credentials, and claims in IdentityServer. \nUse of ``TestUser`` is similar to the use of the \"in-memory\" stores in that it is intended for when prototyping, developing, and/or testing.\nThe use of ``TestUser`` is not recommended in production.\n\n* ``AddTestUsers``\n    Registers ``TestUserStore`` based on a collection of ``TestUser`` objects.\n    ``TestUserStore`` is used by the default quickstart UI.\n    Also registers implementations of ``IProfileService`` and ``IResourceOwnerPasswordValidator``.\n\nAdditional services\n^^^^^^^^^^^^^^^^^^^\n\n* ``AddExtensionGrantValidator``\n    Adds ``IExtensionGrantValidator`` implementation for use with extension grants.\n\n* ``AddSecretParser``\n    Adds ``ISecretParser`` implementation for parsing client or API resource credentials.\n\n* ``AddSecretValidator``\n    Adds ``ISecretValidator`` implementation for validating client or API resource credentials against a credential store.\n\n* ``AddResourceOwnerValidator``\n    Adds ``IResourceOwnerPasswordValidator`` implementation for validating user credentials for the resource owner password credentials grant type.\n\n* ``AddProfileService``\n    Adds ``IProfileService`` implementation for connecting to your :ref:`custom user profile store<refProfileService>`.\n    The ``DefaultProfileService`` class provides the default implementation which relies upon the authentication cookie as the only source of claims for issuing in tokens.\n\n* ``AddAuthorizeInteractionResponseGenerator``\n    Adds ``IAuthorizeInteractionResponseGenerator`` implementation to customize logic at authorization endpoint for when a user must be shown a UI for error, login, consent, or any other custom page.\n    The ``AuthorizeInteractionResponseGenerator`` class provides a default implementation, so consider deriving from this existing class if you need to augment the existing behavior.\n\n* ``AddCustomAuthorizeRequestValidator``\n    Adds ``ICustomAuthorizeRequestValidator`` implementation to customize request parameter validation at the authorization endpoint.\n\n* ``AddCustomTokenRequestValidator``\n    Adds ``ICustomTokenRequestValidator`` implementation to customize request parameter validation at the token endpoint.\n\n* ``AddRedirectUriValidator``\n    Adds ``IRedirectUriValidator`` implementation to customize redirect URI validation.\n\n* ``AddAppAuthRedirectUriValidator``\n    Adds a an \"AppAuth\" (OAuth 2.0 for Native Apps) compliant redirect URI validator (does strict validation but also allows http://127.0.0.1 with random port).\n\n* ``AddJwtBearerClientAuthentication``\n    Adds support for client authentication using JWT bearer assertions.\n\n* ``AddMutualTlsSecretValidators``\n    Adds the X509 secret validators for mutual TLS.\n\nCaching\n^^^^^^^\n\nClient and resource configuration data is used frequently by IdentityServer.\nIf this data is being loaded from a database or other external store, then it might be expensive to frequently re-load the same data.\n\n* ``AddInMemoryCaching``\n    To use any of the caches described below, an implementation of ``ICache<T>`` must be registered in DI.\n    This API registers a default in-memory implementation of ``ICache<T>`` that's based on ASP.NET Core's ``MemoryCache``.\n\n* ``AddClientStoreCache``\n    Registers a ``IClientStore`` decorator implementation which will maintain an in-memory cache of ``Client`` configuration objects.\n    The cache duration is configurable on the ``Caching`` configuration options on the ``IdentityServerOptions``.\n\n* ``AddResourceStoreCache``\n    Registers a ``IResourceStore`` decorator implementation which will maintain an in-memory cache of ``IdentityResource`` and ``ApiResource`` configuration objects.\n    The cache duration is configurable on the ``Caching`` configuration options on the ``IdentityServerOptions``.\n\n* ``AddCorsPolicyCache``\n    Registers a ``ICorsPolicyService`` decorator implementation which will maintain an in-memory cache of the results of the CORS policy service evaluation.\n    The cache duration is configurable on the ``Caching`` configuration options on the ``IdentityServerOptions``.\n\nFurther customization of the cache is possible:\n\nThe default caching relies upon the ``ICache<T>`` implementation.\nIf you wish to customize the caching behavior for the specific configuration objects, you can replace this implementation in the dependency injection system.\n\nThe default implementation of the ``ICache<T>`` itself relies upon the ``IMemoryCache`` interface (and ``MemoryCache`` implementation) provided by .NET.\nIf you wish to customize the in-memory caching behavior, you can replace the ``IMemoryCache`` implementation in the dependency injection system.\n\nConfiguring the pipeline\n^^^^^^^^^^^^^^^^^^^^^^^^\nYou need to add IdentityServer to the pipeline by calling::\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseIdentityServer();\n    }\n\n.. note:: ``UseIdentityServer`` includes a call to ``UseAuthentication``, so it's not necessary to have both.\n\nThere is no additional configuration for the middleware.\n\nBe aware that order matters in the pipeline. \nFor example, you will want to add IdentitySever before the UI framework that implements the login screen.\n"
  },
  {
    "path": "docs/topics/tools.rst",
    "content": "Tools\n=====\n\nThe ``IdentityServerTools`` class is a collection of useful internal tools that you might need when writing extensibility code\nfor IdentityServer. To use it, inject it into your code, e.g. a controller::\n\n    public MyController(IdentityServerTools tools)\n    {\n        _tools = tools;\n    }\n\nThe ``IssueJwtAsync`` method allows creating JWT tokens using the IdentityServer token creation engine. The ``IssueClientJwtAsync`` is an easier\nversion of that for creating tokens for server-to-server communication (e.g. when you have to call an IdentityServer protected API from your code)::\n\n    public async Task<IActionResult> MyAction()\n    {\n        var token = await _tools.IssueClientJwtAsync(\n            clientId: \"client_id\",\n            lifetime: 3600,\n            audiences: new[] { \"backend.api\" });\n\n        // more code\n    }"
  },
  {
    "path": "docs/topics/windows.rst",
    "content": "Windows Authentication\n======================\nThere are several ways how you can enable Windows authentication in ASP.NET Core (and thus in IdentityServer).\n\n* On Windows using IIS hosting (both in- and out-of process)\n* On Windows using HTTP.SYS hosting\n* On any platform using the Negotiate authentication handler (added in ASP.NET Core 3.0)\n\n.. Note:: We only have documentation for IIS hosting. If you want to contribute to the docs, please open a PR. thanks!\n\nOn Windows using IIS hosting\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nThe typical ``CreateDefaultBuilder`` host setup enables support for IIS-based Windows authentication when hosting in IIS.\nMake sure that Windows authentication is enabled in ``launchSettings.json`` or your IIS configuration.\n\nThe IIS integration layer will configure a Windows authentication handler into DI that can be invoked via the authentication service.\nTypically in IdentityServer it is advisable to disable the automatic behavior. \n\nThis is done in ``ConfigureServices`` (details vary depending on in-proc vs out-of-proc hosting)::\n\n    // configures IIS out-of-proc settings (see https://github.com/aspnet/AspNetCore/issues/14882)\n    services.Configure<IISOptions>(iis =>\n    {\n        iis.AuthenticationDisplayName = \"Windows\";\n        iis.AutomaticAuthentication = false;\n    });\n\n    // ..or configures IIS in-proc settings\n    services.Configure<IISServerOptions>(iis =>\n    {\n        iis.AuthenticationDisplayName = \"Windows\";\n        iis.AutomaticAuthentication = false;\n    });\n\nYou trigger Windows authentication by calling ``ChallengeAsync`` on the ``Windows`` scheme (or if you want to use a constant: ``Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme``).\n\nThis will send the ``Www-Authenticate`` header back to the browser which will then re-load the current URL including the Windows identity.\nYou can tell that Windows authentication was successful, when you call ``AuthenticateAsync`` on the ``Windows`` scheme and the principal returned\nis of type ``WindowsPrincipal``.\n\nThe principal will have information like user and group SID and the Windows account name. The following snippet shows how to\ntrigger authentication, and if successful convert the information into a standard ``ClaimsPrincipal`` for the temp-Cookie approach::\n\n    private async Task<IActionResult> ChallengeWindowsAsync(string returnUrl)\n    {\n        // see if windows auth has already been requested and succeeded\n        var result = await HttpContext.AuthenticateAsync(\"Windows\");\n        if (result?.Principal is WindowsPrincipal wp)\n        {\n            // we will issue the external cookie and then redirect the\n            // user back to the external callback, in essence, treating windows\n            // auth the same as any other external authentication mechanism\n            var props = new AuthenticationProperties()\n            {\n                RedirectUri = Url.Action(\"Callback\"),\n                Items =\n                {\n                    { \"returnUrl\", returnUrl },\n                    { \"scheme\", \"Windows\" },\n                }\n            };\n\n            var id = new ClaimsIdentity(\"Windows\");\n\n            // the sid is a good sub value\n            id.AddClaim(new Claim(JwtClaimTypes.Subject, wp.FindFirst(ClaimTypes.PrimarySid).Value));\n\n            // the account name is the closest we have to a display name\n            id.AddClaim(new Claim(JwtClaimTypes.Name, wp.Identity.Name));\n\n            // add the groups as claims -- be careful if the number of groups is too large\n            var wi = wp.Identity as WindowsIdentity;\n\n            // translate group SIDs to display names\n            var groups = wi.Groups.Translate(typeof(NTAccount));\n            var roles = groups.Select(x => new Claim(JwtClaimTypes.Role, x.Value));\n            id.AddClaims(roles);\n            \n\n            await HttpContext.SignInAsync(\n                IdentityServerConstants.ExternalCookieAuthenticationScheme,\n                new ClaimsPrincipal(id),\n                props);\n            return Redirect(props.RedirectUri);\n        }\n        else\n        {\n            // trigger windows auth\n            // since windows auth don't support the redirect uri,\n            // this URL is re-triggered when we call challenge\n            return Challenge(\"Windows\");\n        }\n    }\n"
  },
  {
    "path": "global.json",
    "content": "{\n  \"sdk\": {\n    \"version\": \"8.0.100\"\n  }\n}"
  },
  {
    "path": "main.cmd",
    "content": "start ./src/IdentityServer8/IdentityServer8.sln"
  },
  {
    "path": "samples/Clients/Clients.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Clients/ClientsGlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Clients;"
  },
  {
    "path": "samples/Clients/Directory.Build.props",
    "content": "<Project>\n    <ImportGroup>\n        <Import Project=\"../Directory.Build.props\" />\n    </ImportGroup>\n\t<ItemGroup>\n        <Compile Include=\"$(SolutionDir)..\\ClientsGlobalUsings.cs\" Link=\"ClientsGlobalUsings.cs\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/old/Clients.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{179A2A2C-3B3D-437C-B5F3-3B81472C8335}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tDirectory.Build.props = Directory.Build.props\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcHybrid\", \"MvcHybrid\\MvcHybrid.csproj\", \"{926ACA55-AA27-475D-90CB-AC6D4B113322}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcHybridAutomaticRefresh\", \"MvcHybridAutomaticRefresh\\MvcHybridAutomaticRefresh.csproj\", \"{AF1E5A26-F1DC-4B71-988D-F3B69F47D604}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcImplicit\", \"MvcImplicit\\MvcImplicit.csproj\", \"{24B7CDFC-87B7-4C45-A73B-AA0D9FAD25B8}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcImplicitJwtRequest\", \"MvcImplicitJwtRequest\\MvcImplicitJwtRequest.csproj\", \"{DD2BC29A-9874-4953-8AAC-9ABF8DE97F2F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcManual\", \"MvcManual\\MvcManual.csproj\", \"{B3757E48-9817-4390-9A35-58D106C2D6E2}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"root\", \"root\", \"{3CDFF45B-4773-419E-99DA-BE8545B7DECB}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\..\\..\\Directory.Build.props = ..\\..\\..\\Directory.Build.props\n\t\t..\\..\\..\\Directory.Packages.props = ..\\..\\..\\Directory.Packages.props\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Constants\", \"..\\shared\\Constants\\Constants.csproj\", \"{F2D39DF0-367D-456B-820F-2A081F7C1CC7}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"samples\", \"samples\", \"{66694F08-6E72-4D7B-A555-D4EB25A9CCC8}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\..\\Directory.Build.props = ..\\..\\Directory.Build.props\n\t\t..\\..\\SamplesGlobalUsings.cs = ..\\..\\SamplesGlobalUsings.cs\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Clients\", \"Clients\", \"{97D760DC-D81F-43D4-93D0-B81BD2112705}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\ClientsGlobalUsings.cs = ..\\ClientsGlobalUsings.cs\n\t\t..\\..\\Directory.Build.props = ..\\..\\Directory.Build.props\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"old\", \"old\", \"{B729491B-30F9-4DB3-B871-77BA9BA8BE8D}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tDirectory.Build.props = Directory.Build.props\n\t\tMvcUsings.cs = MvcUsings.cs\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{926ACA55-AA27-475D-90CB-AC6D4B113322}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{926ACA55-AA27-475D-90CB-AC6D4B113322}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{926ACA55-AA27-475D-90CB-AC6D4B113322}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{926ACA55-AA27-475D-90CB-AC6D4B113322}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{AF1E5A26-F1DC-4B71-988D-F3B69F47D604}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{AF1E5A26-F1DC-4B71-988D-F3B69F47D604}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{AF1E5A26-F1DC-4B71-988D-F3B69F47D604}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{AF1E5A26-F1DC-4B71-988D-F3B69F47D604}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{24B7CDFC-87B7-4C45-A73B-AA0D9FAD25B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{24B7CDFC-87B7-4C45-A73B-AA0D9FAD25B8}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{24B7CDFC-87B7-4C45-A73B-AA0D9FAD25B8}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{24B7CDFC-87B7-4C45-A73B-AA0D9FAD25B8}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{DD2BC29A-9874-4953-8AAC-9ABF8DE97F2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{DD2BC29A-9874-4953-8AAC-9ABF8DE97F2F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{DD2BC29A-9874-4953-8AAC-9ABF8DE97F2F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{DD2BC29A-9874-4953-8AAC-9ABF8DE97F2F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{B3757E48-9817-4390-9A35-58D106C2D6E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B3757E48-9817-4390-9A35-58D106C2D6E2}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B3757E48-9817-4390-9A35-58D106C2D6E2}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B3757E48-9817-4390-9A35-58D106C2D6E2}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F2D39DF0-367D-456B-820F-2A081F7C1CC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F2D39DF0-367D-456B-820F-2A081F7C1CC7}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F2D39DF0-367D-456B-820F-2A081F7C1CC7}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F2D39DF0-367D-456B-820F-2A081F7C1CC7}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{3CDFF45B-4773-419E-99DA-BE8545B7DECB} = {179A2A2C-3B3D-437C-B5F3-3B81472C8335}\n\t\t{66694F08-6E72-4D7B-A555-D4EB25A9CCC8} = {3CDFF45B-4773-419E-99DA-BE8545B7DECB}\n\t\t{97D760DC-D81F-43D4-93D0-B81BD2112705} = {66694F08-6E72-4D7B-A555-D4EB25A9CCC8}\n\t\t{B729491B-30F9-4DB3-B871-77BA9BA8BE8D} = {97D760DC-D81F-43D4-93D0-B81BD2112705}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {BAD78470-3D66-466E-9C17-2A67F0905B18}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Clients/old/Clients.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Clients/old/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n  <ItemGroup>\n      <Compile Include=\"$(SolutionDir)MvcUsings.cs\" Link=\"MvcUsings.cs\" />\n     <ProjectReference Include=\"$(SolutionDir)..\\shared\\Constants\\Constants.csproj\" Condition=\"$(MSBuildProjectName) != 'Constants' \" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly IHttpClientFactory _httpClientFactory;\n    private readonly IDiscoveryCache _discoveryCache;\n\n    public HomeController(IHttpClientFactory httpClientFactory, IDiscoveryCache discoveryCache)\n    {\n        _httpClientFactory = httpClientFactory;\n        _discoveryCache = discoveryCache;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public IActionResult Secure()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public async Task<IActionResult> CallApi()\n    {\n        var token = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = _httpClientFactory.CreateClient();\n        client.SetBearerToken(token);\n\n        var response = await client.GetStringAsync(Constants.SampleApi + \"identity\");\n        ViewBag.Json = JsonSerializer.Deserialize<JsonElement>(response).ToString();\n\n        return View();\n    }\n\n    public async Task<IActionResult> RenewTokens()\n    {\n        var disco = await _discoveryCache.GetAsync();\n        if (disco.IsError) throw new Exception(disco.Error);\n\n        var rt = await HttpContext.GetTokenAsync(\"refresh_token\");\n        var tokenClient = _httpClientFactory.CreateClient();\n\n        var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = disco.TokenEndpoint,\n\n            ClientId = \"mvc.hybrid\",\n            ClientSecret = \"secret\",\n            RefreshToken = rt\n        });\n\n        if (!tokenResult.IsError)\n        {\n            var old_id_token = await HttpContext.GetTokenAsync(\"id_token\");\n            var new_access_token = tokenResult.AccessToken;\n            var new_refresh_token = tokenResult.RefreshToken;\n            var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);\n\n            var info = await HttpContext.AuthenticateAsync(\"Cookies\");\n\n            info.Properties.UpdateTokenValue(\"refresh_token\", new_refresh_token);\n            info.Properties.UpdateTokenValue(\"access_token\", new_access_token);\n            info.Properties.UpdateTokenValue(\"expires_at\", expiresAt.ToString(\"o\", CultureInfo.InvariantCulture));\n\n            await HttpContext.SignInAsync(\"Cookies\", info.Principal, info.Properties);\n            return Redirect(\"~/Home/Secure\");\n        }\n\n        ViewData[\"Error\"] = tokenResult.Error;\n        return View(\"Error\");\n    }\n\n    public IActionResult Logout()\n    {\n        return new SignOutResult(new[] { \"Cookies\", \"oidc\" });\n    }\n\n    public IActionResult Error()\n    {\n        return View();\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/MvcHybrid.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nWebHost.CreateDefaultBuilder(args)\n    .UseStartup<Startup>()\n    .Build();"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:21402/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\npublic class Startup\n{\n    public Startup()\n    {\n        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddControllersWithViews();\n        services.AddHttpClient();\n\n        services.AddSingleton<IDiscoveryCache>(r =>\n        {\n            var factory = r.GetRequiredService<IHttpClientFactory>();\n            return new DiscoveryCache(Constants.Authority, () => factory.CreateClient());\n        });\n\n        services.AddAuthentication(options =>\n        {\n            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;\n            options.DefaultChallengeScheme = \"oidc\";\n        })\n            .AddCookie(options =>\n            {\n                options.ExpireTimeSpan = TimeSpan.FromMinutes(60);\n                options.Cookie.Name = \"mvchybrid\";\n            })\n            .AddOpenIdConnect(\"oidc\", options =>\n            {\n                options.Authority = Constants.Authority;\n                options.RequireHttpsMetadata = false;\n\n                options.ClientSecret = \"secret\";\n                options.ClientId = \"mvc.hybrid\";\n\n                options.ResponseType = \"code id_token\";\n\n                options.Scope.Clear();\n                options.Scope.Add(\"openid\");\n                options.Scope.Add(\"profile\");\n                options.Scope.Add(\"email\");\n                options.Scope.Add(\"api1\");\n                options.Scope.Add(\"offline_access\");\n               \n                options.ClaimActions.MapAllExcept(\"iss\", \"nbf\", \"exp\", \"aud\", \"nonce\", \"iat\", \"c_hash\");\n\n                options.GetClaimsFromUserInfoEndpoint = true;\n                options.SaveTokens = true;\n\n                options.TokenValidationParameters = new TokenValidationParameters\n                {\n                    NameClaimType = JwtClaimTypes.Name,\n                    RoleClaimType = JwtClaimTypes.Role,\n                };\n            });\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseDeveloperExceptionPage();\n        app.UseStaticFiles();\n\n        app.UseRouting();\n        app.UseAuthentication();\n        app.UseAuthorization();\n\n        app.UseEndpoints(endpoints =>\n        {\n            endpoints.MapDefaultControllerRoute();\n        });\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Views/Home/CallApi.cshtml",
    "content": "﻿<h1>API Response</h1>\n\n<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n@if(User.Identity.IsAuthenticated)\n{\n    <h1>Logged in as: @User.Identity.Name</h1>\n}\nelse\n{\n    <h1>Not Logged In</h1>\n}"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Views/Home/Secure.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<div class=\"panel\">\n    <a class=\"btn btn-primary\" href=\"~/home/callapi\">Call API</a>\n    <a class=\"btn btn-primary\" href=\"~/home/renewtokens\">Renew Tokens</a>\n</div>\n\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Views/Shared/Error.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.\n</p>\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcHybrid</title>\n\n    <environment names=\"Development\">\n        <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.css\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n    </environment>\n    <environment names=\"Staging,Production\">\n        <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.min.css\" asp-append-version=\"true\" />\n    </environment>\n</head>\n<body>\n    <div class=\"navbar navbar-inverse navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\" class=\"navbar-brand\">MvcHybrid</a>\n            </div>\n            <div class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li><a asp-controller=\"Home\" asp-action=\"Secure\">Secure</a></li>\n                    <li><a asp-controller=\"Home\" asp-action=\"Logout\">Logout</a></li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"container body-content\">\n        @RenderBody()\n        <hr />\n        <footer>\n            <p>&copy; 2016 - MvcHybrid</p>\n        </footer>\n    </div>\n\n    <environment names=\"Development\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.js\"></script>\n        <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    </environment>\n    <environment names=\"Staging,Production\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.min.js\"></script>\n        <script src=\"~/js/site.min.js\" asp-append-version=\"true\"></script>\n    </environment>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/appsettings.json",
    "content": "﻿{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/wwwroot/css/site.css",
    "content": "﻿body {\n    padding-top: 50px;\n    padding-bottom: 20px;\n}\n\n/* Wrapping element */\n/* Set some basic padding to keep content from hitting the edges */\n.body-content {\n    padding-left: 15px;\n    padding-right: 15px;\n}\n\n/* Set widths on the form inputs since otherwise they're 100% wide */\ninput,\nselect,\ntextarea {\n    max-width: 280px;\n}\n\n/* Carousel */\n.carousel-caption p {\n    font-size: 20px;\n    line-height: 1.4;\n}\n\n/* Make .svg files in the carousel display properly in older browsers */\n.carousel-inner .item img[src$=\".svg\"]\n{\n    width: 100%;\n}\n\n/* Hide/rearrange for smaller screens */\n@media screen and (max-width: 767px) {\n  /* Hide captions */\n  .carousel-caption {\n    display: none\n  }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybrid/wwwroot/js/site.js",
    "content": "﻿// Write your Javascript code.\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/AutomaticTokenManagement/AutomaticTokenManagementBuilderExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityModel.AspNetCore\n{\n    public static class AutomaticTokenManagementBuilderExtensions\n    {\n        public static AuthenticationBuilder AddAutomaticTokenManagement(this AuthenticationBuilder builder, Action<AutomaticTokenManagementOptions> options)\n        {\n            builder.Services.Configure(options);\n            return builder.AddAutomaticTokenManagement();\n        }\n\n        public static AuthenticationBuilder AddAutomaticTokenManagement(this AuthenticationBuilder builder)\n        {\n            builder.Services.AddHttpClient(\"tokenClient\");\n            builder.Services.AddTransient<TokenEndpointService>();\n\n            builder.Services.AddTransient<AutomaticTokenManagementCookieEvents>();\n            builder.Services.AddSingleton<IConfigureOptions<CookieAuthenticationOptions>, AutomaticTokenManagementConfigureCookieOptions>();\n\n            return builder;\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/AutomaticTokenManagement/AutomaticTokenManagementConfigureCookieOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityModel.AspNetCore\n{\n    public class AutomaticTokenManagementConfigureCookieOptions : IConfigureNamedOptions<CookieAuthenticationOptions>\n    {\n        private readonly AuthenticationScheme _scheme;\n\n        public AutomaticTokenManagementConfigureCookieOptions(IAuthenticationSchemeProvider provider)\n        {\n            _scheme = provider.GetDefaultSignInSchemeAsync().GetAwaiter().GetResult();\n        }\n\n        public void Configure(CookieAuthenticationOptions options)\n        { }\n\n        public void Configure(string name, CookieAuthenticationOptions options)\n        {\n            if (name == _scheme.Name)\n            {\n                options.EventsType = typeof(AutomaticTokenManagementCookieEvents);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/AutomaticTokenManagement/AutomaticTokenManagementCookieEvents.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityModel.AspNetCore\n{\n    public class AutomaticTokenManagementCookieEvents : CookieAuthenticationEvents\n    {\n        private readonly TokenEndpointService _service;\n        private readonly AutomaticTokenManagementOptions _options;\n        private readonly ILogger _logger;\n        private readonly ISystemClock _clock;\n        \n        private static readonly ConcurrentDictionary<string, bool> _pendingRefreshTokenRequests =\n            new ConcurrentDictionary<string, bool>();\n\n        public AutomaticTokenManagementCookieEvents(\n            TokenEndpointService service,\n            IOptions<AutomaticTokenManagementOptions> options,\n            ILogger<AutomaticTokenManagementCookieEvents> logger,\n            ISystemClock clock)\n        {\n            _service = service;\n            _options = options.Value;\n            _logger = logger;\n            _clock = clock;\n        }\n\n        public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)\n        {\n            var tokens = context.Properties.GetTokens();\n            if (tokens == null || !tokens.Any())\n            {\n                _logger.LogDebug(\"No tokens found in cookie properties. SaveTokens must be enabled for automatic token refresh.\");\n                return;\n            }\n\n            var refreshToken = tokens.SingleOrDefault(t => t.Name == OpenIdConnectParameterNames.RefreshToken);\n            if (refreshToken == null)\n            {\n                _logger.LogWarning(\"No refresh token found in cookie properties. A refresh token must be requested and SaveTokens must be enabled.\");\n                return;\n            }\n\n            var expiresAt = tokens.SingleOrDefault(t => t.Name == \"expires_at\");\n            if (expiresAt == null)\n            {\n                _logger.LogWarning(\"No expires_at value found in cookie properties.\");\n                return;\n            }\n\n            var dtExpires = DateTimeOffset.Parse(expiresAt.Value, CultureInfo.InvariantCulture);\n            var dtRefresh = dtExpires.Subtract(_options.RefreshBeforeExpiration);\n\n            if (dtRefresh < _clock.UtcNow)\n            {\n                var shouldRefresh = _pendingRefreshTokenRequests.TryAdd(refreshToken.Value, true);\n                if (shouldRefresh)\n                {\n                    try\n                    {\n                        var response = await _service.RefreshTokenAsync(refreshToken.Value);\n\n                        if (response.IsError)\n                        {\n                            _logger.LogWarning(\"Error refreshing token: {error}\", response.Error);\n                            context.RejectPrincipal();\n                            return;\n                        }\n\n                        context.Properties.UpdateTokenValue(\"access_token\", response.AccessToken);\n                        context.Properties.UpdateTokenValue(\"refresh_token\", response.RefreshToken);\n\n                        var newExpiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(response.ExpiresIn);\n                        context.Properties.UpdateTokenValue(\"expires_at\", newExpiresAt.ToString(\"o\", CultureInfo.InvariantCulture));\n\n                        await context.HttpContext.SignInAsync(context.Principal, context.Properties);\n                    }\n                    finally\n                    {\n                        _pendingRefreshTokenRequests.TryRemove(refreshToken.Value, out _);\n                    }\n                }\n            }\n        }\n\n        public override async Task SigningOut(CookieSigningOutContext context)\n        {\n            if (_options.RevokeRefreshTokenOnSignout == false) return;\n\n            var result = await context.HttpContext.AuthenticateAsync();\n\n            if (!result.Succeeded)\n            {\n                _logger.LogDebug(\"Can't find cookie for default scheme. Might have been deleted already.\");\n                return;\n            }\n\n            var tokens = result.Properties.GetTokens();\n            if (tokens == null || !tokens.Any())\n            {\n                _logger.LogDebug(\"No tokens found in cookie properties. SaveTokens must be enabled for automatic token revocation.\");\n                return;\n            }\n\n            var refreshToken = tokens.SingleOrDefault(t => t.Name == OpenIdConnectParameterNames.RefreshToken);\n            if (refreshToken == null)\n            {\n                _logger.LogWarning(\"No refresh token found in cookie properties. A refresh token must be requested and SaveTokens must be enabled.\");\n                return;\n            }\n\n            var response = await _service.RevokeTokenAsync(refreshToken.Value);\n\n            if (response.IsError)\n            {\n                _logger.LogWarning(\"Error revoking token: {error}\", response.Error);\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/AutomaticTokenManagement/AutomaticTokenManagementOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityModel.AspNetCore\n{\n    public class AutomaticTokenManagementOptions\n    {\n        public string Scheme { get; set; }\n        public TimeSpan RefreshBeforeExpiration { get; set; } = TimeSpan.FromMinutes(1);\n        public bool RevokeRefreshTokenOnSignout { get; set; } = true;\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/AutomaticTokenManagement/TokenEndpointService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityModel.AspNetCore\n{\n    public class TokenEndpointService\n    {\n        private readonly AutomaticTokenManagementOptions _managementOptions;\n        private readonly IOptionsSnapshot<OpenIdConnectOptions> _oidcOptions;\n        private readonly IAuthenticationSchemeProvider _schemeProvider;\n        private readonly IHttpClientFactory _httpClientFactory;\n        private readonly ILogger<TokenEndpointService> _logger;\n\n        public TokenEndpointService(\n            IOptions<AutomaticTokenManagementOptions> managementOptions,\n            IOptionsSnapshot<OpenIdConnectOptions> oidcOptions,\n            IAuthenticationSchemeProvider schemeProvider,\n            IHttpClientFactory httpClientFactory,\n            ILogger<TokenEndpointService> logger)\n        {\n            _managementOptions = managementOptions.Value;\n            _oidcOptions = oidcOptions;\n            _schemeProvider = schemeProvider;\n            _httpClientFactory = httpClientFactory;\n            _logger = logger;\n        }\n\n        public async Task<TokenResponse> RefreshTokenAsync(string refreshToken)\n        {\n            var oidcOptions = await GetOidcOptionsAsync();\n            var configuration = await oidcOptions.ConfigurationManager.GetConfigurationAsync(default(CancellationToken));\n\n            var tokenClient = _httpClientFactory.CreateClient(\"tokenClient\");\n\n            return await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest\n            {\n                Address = configuration.TokenEndpoint,\n\n                ClientId = oidcOptions.ClientId,\n                ClientSecret = oidcOptions.ClientSecret,\n                RefreshToken = refreshToken\n            });\n        }\n\n        public async Task<TokenRevocationResponse> RevokeTokenAsync(string refreshToken)\n        {\n            var oidcOptions = await GetOidcOptionsAsync();\n            var configuration = await oidcOptions.ConfigurationManager.GetConfigurationAsync(default(CancellationToken));\n\n            var tokenClient = _httpClientFactory.CreateClient(\"tokenClient\");\n\n            return await tokenClient.RevokeTokenAsync(new TokenRevocationRequest\n            {\n                Address = configuration.AdditionalData[OidcConstants.Discovery.RevocationEndpoint].ToString(),\n                ClientId = oidcOptions.ClientId,\n                ClientSecret = oidcOptions.ClientSecret,\n                Token = refreshToken,\n                TokenTypeHint = OidcConstants.TokenTypes.RefreshToken\n            });\n        }\n\n        private async Task<OpenIdConnectOptions> GetOidcOptionsAsync()\n        {\n            if (string.IsNullOrEmpty(_managementOptions.Scheme))\n            {\n                var scheme = await _schemeProvider.GetDefaultChallengeSchemeAsync();\n                return _oidcOptions.Get(scheme.Name);\n            }\n            else\n            {\n                return _oidcOptions.Get(_managementOptions.Scheme);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly IHttpClientFactory _httpClientFactory;\n    \n    public HomeController(IHttpClientFactory httpClientFactory)\n    {\n        _httpClientFactory = httpClientFactory;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public IActionResult Secure()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public async Task<IActionResult> CallApi()\n    {\n        var token = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = _httpClientFactory.CreateClient();\n        client.SetBearerToken(token);\n\n        var response = await client.GetStringAsync(Constants.SampleApi + \"identity\");\n        ViewBag.Json = JsonSerializer.Deserialize<JsonElement>(response).ToString();\n\n        return View();\n    }\n\n    public IActionResult Logout()\n    {\n        return new SignOutResult(new[] { \"Cookies\", \"oidc\" });\n    }\n\n    public IActionResult Error()\n    {\n        return View();\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/MvcHybridAutomaticRefresh.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nvar builder = WebApplication.CreateBuilder(args);\n\nJwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n\nvar services = builder.Services;\n\nservices.AddMvc();\nservices.AddHttpClient();\n\nservices.AddAuthentication(options =>\n{\n    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;\n    options.DefaultChallengeScheme = \"oidc\";\n})\n    .AddCookie(options =>\n    {\n        options.ExpireTimeSpan = TimeSpan.FromMinutes(60);\n        options.Cookie.Name = \"mvchybridautorefresh\";\n    })\n    .AddAutomaticTokenManagement()\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        options.Authority = Constants.Authority;\n        options.RequireHttpsMetadata = false;\n\n        options.ClientSecret = \"secret\";\n        options.ClientId = \"mvc.hybrid.autorefresh\";\n\n        options.ResponseType = \"code id_token\";\n\n        options.Scope.Clear();\n        options.Scope.Add(\"openid\");\n        options.Scope.Add(\"profile\");\n        options.Scope.Add(\"email\");\n        options.Scope.Add(\"api1\");\n        options.Scope.Add(\"offline_access\");\n\n        options.ClaimActions.MapAllExcept(\"iss\", \"nbf\", \"exp\", \"aud\", \"nonce\", \"iat\", \"c_hash\");\n\n        options.GetClaimsFromUserInfoEndpoint = true;\n        options.SaveTokens = true;\n\n        options.TokenValidationParameters = new TokenValidationParameters\n        {\n            NameClaimType = JwtClaimTypes.Name,\n            RoleClaimType = JwtClaimTypes.Role,\n        };\n    });\n       \n\n\n\nusing (var app = builder.Build())\n{\n    app.UseDeveloperExceptionPage();\n    app.UseStaticFiles();\n\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n\n    app.UseDeveloperExceptionPage();\n    app.UseStaticFiles();\n    app.UseAuthentication();\n\n\n\n    app.MapControllerRoute(\n               name: \"default\",\n                      pattern: \"{controller=Home}/{action=Index}/{id?}\");\n\n    await app.RunAsync();\n}\n\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:21404/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Views/Home/CallApi.cshtml",
    "content": "﻿<h1>API Response</h1>\n\n<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n@if(User.Identity.IsAuthenticated)\n{\n    <h1>Logged in as: @User.Identity.Name</h1>\n}\nelse\n{\n    <h1>Not Logged In</h1>\n}"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Views/Home/Secure.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<div class=\"panel\">\n    <a class=\"btn btn-primary\" href=\"~/home/callapi\">Call API</a>\n</div>\n\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Views/Shared/Error.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.\n</p>\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcHybrid</title>\n\n    <environment names=\"Development\">\n        <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.css\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n    </environment>\n    <environment names=\"Staging,Production\">\n        <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.min.css\" asp-append-version=\"true\" />\n    </environment>\n</head>\n<body>\n    <div class=\"navbar navbar-inverse navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\" class=\"navbar-brand\">MvcHybrid</a>\n            </div>\n            <div class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li><a asp-controller=\"Home\" asp-action=\"Secure\">Secure</a></li>\n                    <li><a asp-controller=\"Home\" asp-action=\"Logout\">Logout</a></li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"container body-content\">\n        @RenderBody()\n        <hr />\n        <footer>\n            <p>&copy; 2016 - MvcHybrid</p>\n        </footer>\n    </div>\n\n    <environment names=\"Development\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.js\"></script>\n        <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    </environment>\n    <environment names=\"Staging,Production\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.min.js\"></script>\n        <script src=\"~/js/site.min.js\" asp-append-version=\"true\"></script>\n    </environment>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/appsettings.json",
    "content": "﻿{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/wwwroot/css/site.css",
    "content": "﻿body {\n    padding-top: 50px;\n    padding-bottom: 20px;\n}\n\n/* Wrapping element */\n/* Set some basic padding to keep content from hitting the edges */\n.body-content {\n    padding-left: 15px;\n    padding-right: 15px;\n}\n\n/* Set widths on the form inputs since otherwise they're 100% wide */\ninput,\nselect,\ntextarea {\n    max-width: 280px;\n}\n\n/* Carousel */\n.carousel-caption p {\n    font-size: 20px;\n    line-height: 1.4;\n}\n\n/* Make .svg files in the carousel display properly in older browsers */\n.carousel-inner .item img[src$=\".svg\"]\n{\n    width: 100%;\n}\n\n/* Hide/rearrange for smaller screens */\n@media screen and (max-width: 767px) {\n  /* Hide captions */\n  .carousel-caption {\n    display: none\n  }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcHybridAutomaticRefresh/wwwroot/js/site.js",
    "content": "﻿// Write your Javascript code.\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public IActionResult Secure()\n    {\n        return View();\n    }\n\n    public IActionResult Logout()\n    {\n        return new SignOutResult(new string[] { \"oidc\", \"Cookies\" });\n    }\n\n    public IActionResult Error()\n    {\n        return View();\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/MvcImplicit.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nWebHost.CreateDefaultBuilder(args)\n    .UseStartup<Startup>()\n    .Build();"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:44077/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class Startup\n{\n    public Startup()\n    {\n        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddControllersWithViews();\n\n        services.AddAuthentication(options =>\n        {\n            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;\n            options.DefaultChallengeScheme = \"oidc\";\n        })\n            .AddCookie(options =>\n            {\n                options.ExpireTimeSpan = TimeSpan.FromMinutes(60);\n                options.Cookie.Name = \"mvcimplicit\";\n            })\n            .AddOpenIdConnect(\"oidc\", options =>\n            {\n                options.Authority = Constants.Authority;\n                options.RequireHttpsMetadata = false;\n\n                options.ClientId = \"mvc.implicit\";\n\n                options.Scope.Clear();\n                options.Scope.Add(\"openid\");\n                options.Scope.Add(\"profile\");\n                options.Scope.Add(\"email\");\n\n                options.SaveTokens = true;\n\n                options.TokenValidationParameters = new TokenValidationParameters\n                {\n                    NameClaimType = JwtClaimTypes.Name,\n                    RoleClaimType = JwtClaimTypes.Role,\n                };\n            });\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseDeveloperExceptionPage();\n        app.UseStaticFiles();\n\n        app.UseRouting();\n        app.UseAuthentication();\n        app.UseAuthorization();\n\n        app.UseEndpoints(endpoints =>\n        {\n            endpoints.MapDefaultControllerRoute();\n        });\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n@if(User.Identity.IsAuthenticated)\n{\n    <h1>Logged in as: @User.Identity.Name</h1>\n}\nelse\n{\n    <h1>Not Logged In</h1>\n}"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Views/Home/Secure.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Views/Shared/Error.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcImplicit</title>\n\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <div class=\"navbar navbar-inverse navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a asp-controller=\"Home\" asp-action=\"Index\" class=\"navbar-brand\">MvcImplicit</a>\n            </div>\n            <div class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li><a asp-controller=\"Home\" asp-action=\"Secure\">Secure</a></li>\n                    <li><a asp-controller=\"Home\" asp-action=\"Logout\">Logout</a></li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"container body-content\">\n        @RenderBody()\n        <hr />\n        <footer>\n            <p>&copy; 2016 - MvcImplicit</p>\n        </footer>\n    </div>\n    <environment names=\"Development\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.js\"></script>\n        <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    </environment>\n    <environment names=\"Staging,Production\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.min.js\"></script>\n        <script src=\"~/js/site.min.js\" asp-append-version=\"true\"></script>\n    </environment>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Views/_ViewImports.cshtml",
    "content": "\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/wwwroot/css/site.css",
    "content": "﻿body {\n    padding-top: 50px;\n    padding-bottom: 20px;\n}\n\n/* Wrapping element */\n/* Set some basic padding to keep content from hitting the edges */\n.body-content {\n    padding-left: 15px;\n    padding-right: 15px;\n}\n\n/* Set widths on the form inputs since otherwise they're 100% wide */\ninput,\nselect,\ntextarea {\n    max-width: 280px;\n}\n\n/* Carousel */\n.carousel-caption {\n    z-index: 10 !important;\n}\n\n    .carousel-caption p {\n        font-size: 20px;\n        line-height: 1.4;\n    }\n\n@media (min-width: 768px) {\n    .carousel-caption {\n        z-index: 10 !important;\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicit/wwwroot/js/site.js",
    "content": "﻿// Write your Javascript code.\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\npublic class HomeController : Controller\n{\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public IActionResult Secure()\n    {\n        return View();\n    }\n\n    public IActionResult Logout()\n    {\n        return new SignOutResult(new string[] { \"oidc\", \"Cookies\" });\n    }\n\n    public IActionResult Error()\n    {\n        return View();\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/MvcImplicitJwtRequest.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Update=\"Client.pfx\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nWebHost.CreateDefaultBuilder(args)\n    .UseStartup<Startup>()\n    .Build();"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:44077/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class Startup\n{\n    public Startup()\n    {\n        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddControllersWithViews();\n\n        services.AddAuthentication(options =>\n        {\n            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;\n            options.DefaultChallengeScheme = \"oidc\";\n        })\n            .AddCookie(options =>\n            {\n                options.ExpireTimeSpan = TimeSpan.FromMinutes(60);\n                options.Cookie.Name = \"mvcimplicit\";\n            })\n            .AddOpenIdConnect(\"oidc\", options =>\n            {\n                options.Authority = Constants.Authority;\n                options.RequireHttpsMetadata = false;\n\n                options.ClientId = \"mvc.implicit\";\n\n                options.Scope.Clear();\n                options.Scope.Add(\"openid\");\n                options.Scope.Add(\"profile\");\n                options.Scope.Add(\"email\");\n\n                options.SaveTokens = true;\n\n                options.TokenValidationParameters = new TokenValidationParameters\n                {\n                    NameClaimType = JwtClaimTypes.Name,\n                    RoleClaimType = JwtClaimTypes.Role,\n                };\n\n                options.Events.OnRedirectToIdentityProvider = e =>\n                {\n                    var jwt = CreateJwtRequest(\n                        options.ClientId,\n                        options.Authority,\n                        new Claim(\"additional_data\", \"data\"));\n\n                    e.ProtocolMessage.SetParameter(\"request\", jwt);\n\n                    return Task.CompletedTask;\n                };\n            });\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseDeveloperExceptionPage();\n        app.UseStaticFiles();\n\n        app.UseRouting();\n        app.UseAuthentication();\n        app.UseAuthorization();\n\n        app.UseEndpoints(endpoints =>\n        {\n            endpoints.MapDefaultControllerRoute();\n        });\n    }\n\n    private static string CreateJwtRequest(string clientId, string audience, params Claim[] claims)\n    {\n        var certificate = new X509Certificate2(\"client.pfx\");\n        var now = DateTime.UtcNow;\n\n        var token = new JwtSecurityToken(\n                clientId,\n                audience,\n                claims,\n                now,\n                now.AddMinutes(1),\n                new SigningCredentials(\n                    new X509SecurityKey(certificate),\n                    SecurityAlgorithms.RsaSha256\n                )\n            );\n\n        var tokenHandler = new JwtSecurityTokenHandler();\n        return tokenHandler.WriteToken(token);\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n@if(User.Identity.IsAuthenticated)\n{\n    <h1>Logged in as: @User.Identity.Name</h1>\n}\nelse\n{\n    <h1>Not Logged In</h1>\n}"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Views/Home/Secure.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Views/Shared/Error.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Views/Shared/_Layout.cshtml",
    "content": "﻿<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcImplicit</title>\n\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <div class=\"navbar navbar-inverse navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a asp-controller=\"Home\" asp-action=\"Index\" class=\"navbar-brand\">MvcImplicit</a>\n            </div>\n            <div class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li><a asp-controller=\"Home\" asp-action=\"Secure\">Secure</a></li>\n                    <li><a asp-controller=\"Home\" asp-action=\"Logout\">Logout</a></li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"container body-content\">\n        @RenderBody()\n        <hr />\n        <footer>\n            <p>&copy; 2016 - MvcImplicit</p>\n        </footer>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/wwwroot/css/site.css",
    "content": "﻿body {\n    padding-top: 50px;\n    padding-bottom: 20px;\n}\n\n/* Wrapping element */\n/* Set some basic padding to keep content from hitting the edges */\n.body-content {\n    padding-left: 15px;\n    padding-right: 15px;\n}\n\n/* Set widths on the form inputs since otherwise they're 100% wide */\ninput,\nselect,\ntextarea {\n    max-width: 280px;\n}\n\n/* Carousel */\n.carousel-caption {\n    z-index: 10 !important;\n}\n\n    .carousel-caption p {\n        font-size: 20px;\n        line-height: 1.4;\n    }\n\n@media (min-width: 768px) {\n    .carousel-caption {\n        z-index: 10 !important;\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcImplicitJwtRequest/wwwroot/js/site.js",
    "content": "﻿// Write your Javascript code.\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    public async Task<IActionResult> Secure()\n    {\n        if (User.Identity.IsAuthenticated) return View();\n\n        return await StartAuthentication();\n    }\n\n    public async Task <IActionResult> Logout()\n    {\n        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);\n\n        var client = new HttpClient();\n        var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n\n        return Redirect(disco.EndSessionEndpoint);\n    }\n\n    public async Task<IActionResult> FrontChannelLogout(string sid)\n    {\n        if (User.Identity.IsAuthenticated)\n        {\n            var currentSid = User.FindFirst(\"sid\")?.Value ?? \"\";\n            if (string.Equals(currentSid, sid, StringComparison.Ordinal))\n            {\n                await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);\n            }\n        }\n\n        return NoContent();\n    }\n\n    [HttpPost]\n    [AllowAnonymous]\n    public async Task<IActionResult> BackChannelLogout(string logout_token)\n    {\n        Response.Headers.Append(\"Cache-Control\", \"no-cache, no-store\");\n        Response.Headers.Append(\"Pragma\", \"no-cache\");\n\n        try\n        {\n            var user = await ValidateLogoutToken(logout_token);\n\n            // these are the sub & sid to signout\n            var sub = user.FindFirst(\"sub\")?.Value;\n            var sid = user.FindFirst(\"sid\")?.Value;\n\n            return Ok();\n        }\n        catch { }\n\n        return BadRequest();\n    }\n\n    public IActionResult Error()\n    {\n        return View();\n    }\n\n    private async Task<IActionResult> StartAuthentication()\n    {\n        // read discovery document to find authorize endpoint\n        var client = new HttpClient();\n        var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n\n        var authorizeUrl = new RequestUrl(disco.AuthorizeEndpoint).CreateAuthorizeUrl(\n            clientId: \"mvc.manual\",\n            responseType: \"id_token\",\n            scope: \"openid profile\",\n            redirectUri: \"http://localhost:44078/home/callback\",\n            state: \"random_state\",\n            nonce: \"random_nonce\",\n            responseMode: \"form_post\");\n\n        return Redirect(authorizeUrl);\n    }\n\n    public async Task<IActionResult> Callback()\n    {\n        var state = Request.Form[\"state\"].FirstOrDefault();\n        var idToken = Request.Form[\"id_token\"].FirstOrDefault();\n        var error = Request.Form[\"error\"].FirstOrDefault();\n\n        if (!string.IsNullOrEmpty(error)) throw new Exception(error);\n        if (!string.Equals(state, \"random_state\")) throw new Exception(\"invalid state\");\n\n        var user = await ValidateIdentityToken(idToken);\n\n        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);\n        return Redirect(\"/home/secure\");\n    }\n\n    private async Task<ClaimsPrincipal> ValidateIdentityToken(string idToken)\n    {\n        var user = await ValidateJwt(idToken);\n\n        var nonce = user.FindFirst(\"nonce\")?.Value ?? \"\";\n        if (!string.Equals(nonce, \"random_nonce\")) throw new Exception(\"invalid nonce\");\n\n        return user;\n    }\n\n    private async Task<ClaimsPrincipal> ValidateLogoutToken(string logoutToken)\n    {\n        var claims = await ValidateJwt(logoutToken);\n\n        if (claims.FindFirst(\"sub\") == null && claims.FindFirst(\"sid\") == null) throw new Exception(\"Invalid logout token\");\n\n        var nonce = claims.FindFirstValue(\"nonce\");\n        if (!String.IsNullOrWhiteSpace(nonce)) throw new Exception(\"Invalid logout token\");\n\n        var eventsJson = claims.FindFirst(\"events\")?.Value;\n        if (String.IsNullOrWhiteSpace(eventsJson)) throw new Exception(\"Invalid logout token\");\n\n        var events = JsonSerializer.Deserialize<JsonElement>(eventsJson);\n        var logoutEvent = events.TryGetValue(\"http://schemas.openid.net/event/backchannel-logout\");\n        if (logoutEvent.ValueKind== JsonValueKind.Null) throw new Exception(\"Invalid logout token\");\n\n        return claims;\n    }\n\n    private static async Task<ClaimsPrincipal> ValidateJwt(string jwt)\n    {\n        // read discovery document to find issuer and key material\n        var client = new HttpClient();\n        var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n\n        var keys = new List<SecurityKey>();\n        foreach (var webKey in disco.KeySet.Keys)\n        {\n            var e = Base64Url.Decode(webKey.E);\n            var n = Base64Url.Decode(webKey.N);\n\n            var key = new RsaSecurityKey(new RSAParameters { Exponent = e, Modulus = n })\n            {\n                KeyId = webKey.Kid\n            };\n\n            keys.Add(key);\n        }\n\n        var parameters = new TokenValidationParameters\n        {\n            ValidIssuer = disco.Issuer,\n            ValidAudience = \"mvc.manual\",\n            IssuerSigningKeys = keys,\n\n            NameClaimType = JwtClaimTypes.Name,\n            RoleClaimType = JwtClaimTypes.Role,\n\n            RequireSignedTokens = true\n        };\n\n        var handler = new JwtSecurityTokenHandler();\n        handler.InboundClaimTypeMap.Clear();\n\n        var user = handler.ValidateToken(jwt, parameters, out var _);\n        return user;\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/MvcManual.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nWebHost.CreateDefaultBuilder(args)\n    .UseStartup<Startup>()\n    .Build();"
  },
  {
    "path": "samples/Clients/old/MvcManual/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:44078/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/old/MvcManual/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddMvc();\n\n        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)\n            .AddCookie(options =>\n            {\n                options.Cookie.Name = \"mvcmanual\";\n            });\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseDeveloperExceptionPage();\n        app.UseStaticFiles();\n\n        app.UseRouting();\n        app.UseAuthentication();\n        app.UseAuthorization();\n\n        app.UseEndpoints(endpoints =>\n        {\n            endpoints.MapDefaultControllerRoute();\n        });\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n@if(User.Identity.IsAuthenticated)\n{\n    <h1>Logged in as: @User.Identity.Name</h1>\n}\nelse\n{\n    <h1>Not Logged In</h1>\n}"
  },
  {
    "path": "samples/Clients/old/MvcManual/Views/Home/Secure.cshtml",
    "content": "﻿<h1>Secure</h1>\n\n<div>\n    <dl>\n        @foreach (var claim in User.Claims)\n        {\n            <dt>@claim.Type</dt>\n            <dd>@claim.Value</dd>\n        }\n    </dl>\n</div>"
  },
  {
    "path": "samples/Clients/old/MvcManual/Views/Shared/Error.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MVC Manual</title>\n\n    <environment names=\"Development\">\n        <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.css\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n    </environment>\n    <environment names=\"Staging,Production\">\n        <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    </environment>\n</head>\n<body>\n    <div class=\"navbar navbar-inverse navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a asp-controller=\"Home\" asp-action=\"Index\" class=\"navbar-brand\">MVC Manual</a>\n            </div>\n            <div class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li><a asp-controller=\"Home\" asp-action=\"Secure\">Secure</a></li>\n                    <li><a asp-controller=\"Home\" asp-action=\"Logout\">Logout</a></li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"container body-content\">\n        @RenderBody()\n        <hr />\n        <footer>\n            <p>&copy; 2016 - MVC Manual</p>\n        </footer>\n    </div>\n\n    <environment names=\"Development\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.js\"></script>\n    </environment>\n    <environment names=\"Staging,Production\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.min.js\"></script>\n    </environment>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/Views/_ViewImports.cshtml",
    "content": "\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/old/MvcManual/wwwroot/css/site.css",
    "content": "﻿body {\n    padding-top: 50px;\n    padding-bottom: 20px;\n}\n\n/* Wrapping element */\n/* Set some basic padding to keep content from hitting the edges */\n.body-content {\n    padding-left: 15px;\n    padding-right: 15px;\n}\n\n/* Set widths on the form inputs since otherwise they're 100% wide */\ninput,\nselect,\ntextarea {\n    max-width: 280px;\n}\n\n/* Carousel */\n.carousel-caption {\n    z-index: 10 !important;\n}\n\n    .carousel-caption p {\n        font-size: 20px;\n        line-height: 1.4;\n    }\n\n@media (min-width: 768px) {\n    .carousel-caption {\n        z-index: 10 !important;\n    }\n}\n"
  },
  {
    "path": "samples/Clients/old/MvcManual/wwwroot/js/site.js",
    "content": "// Write your Javascript code.\n"
  },
  {
    "path": "samples/Clients/old/MvcUsings.cs",
    "content": "global using IdentityModel;\nglobal using IdentityModel.AspNetCore;\nglobal using IdentityModel.Client;\nglobal using Microsoft.AspNetCore;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authentication.Cookies;\nglobal using Microsoft.AspNetCore.Authentication.OpenIdConnect;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Http;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.IdentityModel.Protocols.OpenIdConnect;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using System;\nglobal using System.Collections.Concurrent;\nglobal using System.Globalization;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net.Http;\nglobal using System.Security.Cryptography;\nglobal using System.Text.Json;\nglobal using System.Threading.Tasks;\n"
  },
  {
    "path": "samples/Clients/readme.md",
    "content": "The client samples are designed to be used with the host in this repo:\n\nhttps://github.com/alexhiggins732/IdentityServer8/tree/main/src/IdentityServer8\n"
  },
  {
    "path": "samples/Clients/shared/Constants/ConsoleExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic static class ConsoleExtensions\n{\n    /// <summary>\n    /// Writes green text to the console.\n    /// </summary>\n    /// <param name=\"text\">The text.</param>\n    [DebuggerStepThrough]\n    public static void ConsoleGreen(this string text)\n    {\n        text.ColoredWriteLine(ConsoleColor.Green);\n    }\n\n    /// <summary>\n    /// Writes red text to the console.\n    /// </summary>\n    /// <param name=\"text\">The text.</param>\n    [DebuggerStepThrough]\n    public static void ConsoleRed(this string text)\n    {\n        text.ColoredWriteLine(ConsoleColor.Red);\n    }\n\n    /// <summary>\n    /// Writes yellow text to the console.\n    /// </summary>\n    /// <param name=\"text\">The text.</param>\n    [DebuggerStepThrough]\n    public static void ConsoleYellow(this string text)\n    {\n        text.ColoredWriteLine(ConsoleColor.Yellow);\n    }\n\n    /// <summary>\n    /// Writes out text with the specified ConsoleColor.\n    /// </summary>\n    /// <param name=\"text\">The text.</param>\n    /// <param name=\"color\">The color.</param>\n    [DebuggerStepThrough]\n    public static void ColoredWriteLine(this string text, ConsoleColor color)\n    {\n        Console.ForegroundColor = color;\n        Console.WriteLine(text);\n        Console.ResetColor();\n    }\n}\n"
  },
  {
    "path": "samples/Clients/shared/Constants/Constants.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class Constants\n{\n    public const string Authority = \"https://localhost:5001\";\n    public const string AuthorityMtls = \"https://identityserver.local\";\n\n    public const string SampleApi = \"https://localhost:5005/\";\n    public const string SampleApiMtls = \"https://api.identityserver.local/\";\n}\n"
  },
  {
    "path": "samples/Clients/shared/Constants/Constants.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n</Project>"
  },
  {
    "path": "samples/Clients/shared/Constants/TokenResponseExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Clients;\n\npublic static class TokenResponseExtensions\n{\n    public static void Show(this TokenResponse response)\n    {\n        if (!response.IsError)\n        {\n            \"Token response:\".ConsoleGreen();\n            Console.WriteLine(response.Json);\n\n            if (response.AccessToken.Contains(\".\"))\n            {\n                \"\\nAccess Token (decoded):\".ConsoleGreen();\n\n                var parts = response.AccessToken.Split('.');\n                var header = parts[0];\n                var claims = parts[1];\n\n                var headerJson = Encoding.UTF8.GetString(Base64Url.Decode(header));\n                var claimsJson = Encoding.UTF8.GetString(Base64Url.Decode(claims));\n                Console.WriteLine(JsonSerializer.Deserialize<JsonElement>(headerJson));\n                Console.WriteLine(JsonSerializer.Deserialize<JsonElement>(claimsJson));\n            }\n        }\n        else\n        {\n            if (response.ErrorType == ResponseErrorType.Http)\n            {\n                \"HTTP error: \".ConsoleGreen();\n                Console.WriteLine(response.Error);\n                \"HTTP status code: \".ConsoleGreen();\n                Console.WriteLine(response.HttpStatusCode);\n            }\n            else\n            {\n                \"Protocol error response:\".ConsoleGreen();\n                Console.WriteLine(response.Raw);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/APIs/ResourceBasedApi/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\nConsole.Title = \"Resource API\";\n\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Host.UseSerilog();\n\nvar services = builder.Services;\n\nservices.AddControllers();\n\nservices.AddCors()\n    .AddDistributedMemoryCache()\n    .AddScopeTransformation()\n    .AddAuthentication(\"token\")\n\n    // JWT tokens\n    .AddJwtBearer(\"token\", options =>\n    {\n        options.Authority = Constants.Authority;\n        options.Audience = \"resource1\";\n\n        options.TokenValidationParameters.ValidTypes = new[] { \"at+jwt\" };\n\n        // if token does not contain a dot, it is a reference token\n        options.ForwardDefaultSelector = Selector.ForwardReferenceToken(\"introspection\");\n    })\n\n    // reference tokens\n    .AddOAuth2Introspection(\"introspection\", options =>\n    {\n        options.Authority = Constants.Authority;\n\n        options.ClientId = \"resource1\";\n        options.ClientSecret = \"secret\";\n    });\n\n\n\nusing (var app = builder.Build())\n{\n    app\n        .UseRouting()\n        .UseAuthentication()\n        .UseAuthorization()\n        .UseCors(policy =>\n        {\n            policy.WithOrigins(\"https://localhost:44300\");\n\n            policy.AllowAnyHeader();\n            policy.AllowAnyMethod();\n            policy.WithExposedHeaders(\"WWW-Authenticate\");\n        });\n\n    app.MapControllers().RequireAuthorization();\n\n    app.MapGet(\"/identity\", (HttpContext ctx, ILogger logger) =>\n    {\n        var claims = ctx.User.Claims.Select(c => new { c.Type, c.Value });\n        logger.LogInformation(\"claims: {claims}\", claims);\n        return Results.Json(claims);\n    });\n\n    await app.RunAsync();\n}\n\n\nvoid ConfigureLogger()\n{\n    Log.Logger = new LoggerConfiguration()\n        .MinimumLevel.Verbose()\n        .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n        .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n        .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n        .Enrich.FromLogContext()\n        .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n        .CreateLogger();\n}\n"
  },
  {
    "path": "samples/Clients/src/APIs/ResourceBasedApi/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Api\": {\n      \"commandName\": \"Project\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5005\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/src/APIs/ResourceBasedApi/ResourceBasedApi.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n</Project>"
  },
  {
    "path": "samples/Clients/src/APIs/SimpleApi/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\nConsole.Title = \"Resource API\";\n\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Host.UseSerilog();\n\nvar services = builder.Services;\n\nservices.AddControllers();\n\nservices.AddCors()\n    .AddDistributedMemoryCache()\n    .AddScopeTransformation()\n    .AddAuthentication(\"token\")\n\n    // JWT tokens\n    .AddJwtBearer(\"token\", options =>\n    {\n        options.Authority = Constants.Authority;\n        options.TokenValidationParameters.ValidateAudience = false;\n        options.TokenValidationParameters.ValidTypes = new[] { \"at+jwt\" };\n    })\n\n    // Use multiple token validation handlers:\n    // https://stackoverflow.com/questions/63399810/can-i-create-an-identity-server-4-asp-net-core-api-using-2-different-token-authe\n    //https://leastprivilege.com/2020/07/06/flexible-access-token-validation-in-asp-net-core/\n    //https://leastprivilege.com/2020/06/15/the-jwt-profile-for-oauth-2-0-access-tokens-and-identityserver/\n    // reference tokens\n    .AddOAuth2Introspection(\"introspection\", options =>\n    {\n        options.Authority = Constants.Authority;\n        options.ClientId = \"resource1\";\n        options.ClientSecret = \"secret\";\n    });\n\n\n\nusing (var app = builder.Build())\n{\n    app\n        .UseRouting()\n        .UseAuthentication()\n        .UseAuthorization()\n        .UseCors(policy =>\n        {\n            policy.WithOrigins(\"https://localhost:44300\");\n\n            policy.AllowAnyHeader();\n            policy.AllowAnyMethod();\n            policy.WithExposedHeaders(\"WWW-Authenticate\");\n        });\n\n\n\n    app.MapGet(\"/identity\", (HttpContext ctx, ILogger logger) =>\n    {\n        var claims = ctx.User.Claims.Select(c => new { c.Type, c.Value });\n        logger.LogInformation(\"claims: {claims}\", claims);\n        return Results.Json(claims);\n    });\n\n    await app.RunAsync();\n}\n\n\nvoid ConfigureLogger()\n{\n    Log.Logger = new LoggerConfiguration()\n        .MinimumLevel.Verbose()\n        .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n        .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n        .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n        .Enrich.FromLogContext()\n        .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n        .CreateLogger();\n}\n"
  },
  {
    "path": "samples/Clients/src/APIs/SimpleApi/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Api\": {\n      \"commandName\": \"Project\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5005\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/src/APIs/SimpleApi/SimpleApi.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n</Project>"
  },
  {
    "path": "samples/Clients/src/Clients.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{179A2A2C-3B3D-437C-B5F3-3B81472C8335}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\shared\\Constants\\Constants.csproj = ..\\shared\\Constants\\Constants.csproj\n\t\t..\\Directory.Build.props = ..\\Directory.Build.props\n\t\t..\\SolutionUsings.cs = ..\\SolutionUsings.cs\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"APIs\", \"APIs\", \"{AFE7085F-051E-4829-955F-3426FE643BDD}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleClientCredentialsFlow\", \"ConsoleClientCredentialsFlow\\ConsoleClientCredentialsFlow.csproj\", \"{6729A51B-A7D9-43F3-8F48-D55478254AB7}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleResourceOwnerFlow\", \"ConsoleResourceOwnerFlow\\ConsoleResourceOwnerFlow.csproj\", \"{9BFE1F4E-C2F4-49FC-917E-BE25C0F42D84}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleClientCredentialsFlowPostBody\", \"ConsoleClientCredentialsFlowPostBody\\ConsoleClientCredentialsFlowPostBody.csproj\", \"{BEA2C25F-0551-4AFC-9961-7DB934724FF1}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleResourceOwnerFlowRefreshToken\", \"ConsoleResourceOwnerFlowRefreshToken\\ConsoleResourceOwnerFlowRefreshToken.csproj\", \"{2952A3E3-8831-419B-B14C-448C409961A7}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleResourceOwnerFlowUserInfo\", \"ConsoleResourceOwnerFlowUserInfo\\ConsoleResourceOwnerFlowUserInfo.csproj\", \"{120F561D-5670-4C80-8CAB-4D770204DC91}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleIntrospectionClient\", \"ConsoleIntrospectionClient\\ConsoleIntrospectionClient.csproj\", \"{395F9DF7-AE5A-403E-BE7A-4AF045B21BB3}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleResourceOwnerFlowReference\", \"ConsoleResourceOwnerFlowReference\\ConsoleResourceOwnerFlowReference.csproj\", \"{0E9145DB-CC70-44F9-B52B-1D7D4C2B2E5F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleExtensionGrant\", \"ConsoleCustomGrant\\ConsoleExtensionGrant.csproj\", \"{546267CD-BE21-44E1-A06E-C7558864EE4F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"JsOidc\", \"JsOidc\\JsOidc.csproj\", \"{A29115B9-30E4-4967-AD5A-C32394B8A64C}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleResourceOwnerFlowPublic\", \"ConsoleResourceOwnerFlowPublic\\ConsoleResourceOwnerFlowPublic.csproj\", \"{8648122C-EE91-4B3B-98CD-355C3F1B9FDF}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsolePrivateKeyJwtClient\", \"ConsolePrivateKeyJwtClient\\ConsolePrivateKeyJwtClient.csproj\", \"{1EC25581-781E-4FEA-A8AC-72BBD599FB87}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleCode\", \"ConsoleCode\\ConsoleCode.csproj\", \"{BB38F47A-1BBF-47E1-9872-088FC81DC825}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcHybridBackChannel\", \"MvcHybridBackChannel\\MvcHybridBackChannel.csproj\", \"{57F395AD-48D2-48BF-A117-881E112D947E}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleDeviceFlow\", \"ConsoleDeviceFlow\\ConsoleDeviceFlow.csproj\", \"{879689CC-38F7-418F-9721-9D4158302B69}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleClientCredentialsFlowCallingIdentityServerApi\", \"ConsoleClientCredentialsFlowCallingIdentityServerApi\\ConsoleClientCredentialsFlowCallingIdentityServerApi.csproj\", \"{141BD303-CD29-472F-B5D8-C1F28ED0621A}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleMTLSClient\", \"ConsoleMTLSClient\\ConsoleMTLSClient.csproj\", \"{EA1583D5-80DE-4A11-9530-26A0ED1FBA2C}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcCode\", \"MvcCode\\MvcCode.csproj\", \"{9FB83FF6-5A75-4036-80E6-11B302B921BE}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcAutomaticTokenManagement\", \"MvcAutomaticTokenManagement\\MvcAutomaticTokenManagement.csproj\", \"{8302E4DD-2A99-439C-9D0C-A4BCF48E3FA3}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"WindowsConsoleSystemBrowser\", \"WindowsConsoleSystemBrowser\\WindowsConsoleSystemBrowser.csproj\", \"{43BF1DCB-7343-471E-A53C-D59F19E2EB74}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleEphemeralMtlsClient\", \"ConsoleEphemeralMtlsClient\\ConsoleEphemeralMtlsClient.csproj\", \"{47A706D4-4DF6-437E-9401-61878ECA243C}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Web\", \"Web\", \"{158628D7-8B68-451E-AF22-B64F473C5943}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Console\", \"Console\", \"{D027D36B-262B-450A-B444-5B7893B5142E}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleParameterizedScopeClient\", \"ConsoleParameterizedScopeClient\\ConsoleParameterizedScopeClient.csproj\", \"{AE8D301D-BDDD-4E04-A487-FD08BAF18B75}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SimpleApi\", \"APIs\\SimpleApi\\SimpleApi.csproj\", \"{215D863E-9D87-42F4-AD17-209C330C6ECB}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ResourceBasedApi\", \"APIs\\ResourceBasedApi\\ResourceBasedApi.csproj\", \"{933613BD-35B0-4F79-A7A7-02F663C55B61}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{EF723CAE-AB9F-4FFB-A36A-D56F9F1DC1B3}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\..\\Directory.Build.props = ..\\..\\Directory.Build.props\n\t\t..\\..\\Directory.Packages.props = ..\\..\\Directory.Packages.props\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Constants\", \"..\\shared\\Constants\\Constants.csproj\", \"{DB7A49D0-27E5-4B20-A153-D132BE9655D3}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{6729A51B-A7D9-43F3-8F48-D55478254AB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{6729A51B-A7D9-43F3-8F48-D55478254AB7}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{6729A51B-A7D9-43F3-8F48-D55478254AB7}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{6729A51B-A7D9-43F3-8F48-D55478254AB7}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{9BFE1F4E-C2F4-49FC-917E-BE25C0F42D84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9BFE1F4E-C2F4-49FC-917E-BE25C0F42D84}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9BFE1F4E-C2F4-49FC-917E-BE25C0F42D84}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9BFE1F4E-C2F4-49FC-917E-BE25C0F42D84}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BEA2C25F-0551-4AFC-9961-7DB934724FF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BEA2C25F-0551-4AFC-9961-7DB934724FF1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BEA2C25F-0551-4AFC-9961-7DB934724FF1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BEA2C25F-0551-4AFC-9961-7DB934724FF1}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{2952A3E3-8831-419B-B14C-448C409961A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{2952A3E3-8831-419B-B14C-448C409961A7}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{2952A3E3-8831-419B-B14C-448C409961A7}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{2952A3E3-8831-419B-B14C-448C409961A7}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{120F561D-5670-4C80-8CAB-4D770204DC91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{120F561D-5670-4C80-8CAB-4D770204DC91}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{120F561D-5670-4C80-8CAB-4D770204DC91}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{120F561D-5670-4C80-8CAB-4D770204DC91}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{395F9DF7-AE5A-403E-BE7A-4AF045B21BB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{395F9DF7-AE5A-403E-BE7A-4AF045B21BB3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{395F9DF7-AE5A-403E-BE7A-4AF045B21BB3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{395F9DF7-AE5A-403E-BE7A-4AF045B21BB3}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{0E9145DB-CC70-44F9-B52B-1D7D4C2B2E5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{0E9145DB-CC70-44F9-B52B-1D7D4C2B2E5F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{0E9145DB-CC70-44F9-B52B-1D7D4C2B2E5F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{0E9145DB-CC70-44F9-B52B-1D7D4C2B2E5F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{546267CD-BE21-44E1-A06E-C7558864EE4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{546267CD-BE21-44E1-A06E-C7558864EE4F}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{546267CD-BE21-44E1-A06E-C7558864EE4F}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{546267CD-BE21-44E1-A06E-C7558864EE4F}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A29115B9-30E4-4967-AD5A-C32394B8A64C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A29115B9-30E4-4967-AD5A-C32394B8A64C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A29115B9-30E4-4967-AD5A-C32394B8A64C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A29115B9-30E4-4967-AD5A-C32394B8A64C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8648122C-EE91-4B3B-98CD-355C3F1B9FDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8648122C-EE91-4B3B-98CD-355C3F1B9FDF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8648122C-EE91-4B3B-98CD-355C3F1B9FDF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8648122C-EE91-4B3B-98CD-355C3F1B9FDF}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{1EC25581-781E-4FEA-A8AC-72BBD599FB87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{1EC25581-781E-4FEA-A8AC-72BBD599FB87}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{1EC25581-781E-4FEA-A8AC-72BBD599FB87}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1EC25581-781E-4FEA-A8AC-72BBD599FB87}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BB38F47A-1BBF-47E1-9872-088FC81DC825}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BB38F47A-1BBF-47E1-9872-088FC81DC825}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BB38F47A-1BBF-47E1-9872-088FC81DC825}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BB38F47A-1BBF-47E1-9872-088FC81DC825}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{57F395AD-48D2-48BF-A117-881E112D947E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{57F395AD-48D2-48BF-A117-881E112D947E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{57F395AD-48D2-48BF-A117-881E112D947E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{57F395AD-48D2-48BF-A117-881E112D947E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{879689CC-38F7-418F-9721-9D4158302B69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{879689CC-38F7-418F-9721-9D4158302B69}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{879689CC-38F7-418F-9721-9D4158302B69}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{879689CC-38F7-418F-9721-9D4158302B69}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{141BD303-CD29-472F-B5D8-C1F28ED0621A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{141BD303-CD29-472F-B5D8-C1F28ED0621A}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{141BD303-CD29-472F-B5D8-C1F28ED0621A}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{141BD303-CD29-472F-B5D8-C1F28ED0621A}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{EA1583D5-80DE-4A11-9530-26A0ED1FBA2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{EA1583D5-80DE-4A11-9530-26A0ED1FBA2C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{EA1583D5-80DE-4A11-9530-26A0ED1FBA2C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{EA1583D5-80DE-4A11-9530-26A0ED1FBA2C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{9FB83FF6-5A75-4036-80E6-11B302B921BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9FB83FF6-5A75-4036-80E6-11B302B921BE}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9FB83FF6-5A75-4036-80E6-11B302B921BE}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9FB83FF6-5A75-4036-80E6-11B302B921BE}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8302E4DD-2A99-439C-9D0C-A4BCF48E3FA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8302E4DD-2A99-439C-9D0C-A4BCF48E3FA3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8302E4DD-2A99-439C-9D0C-A4BCF48E3FA3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8302E4DD-2A99-439C-9D0C-A4BCF48E3FA3}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{43BF1DCB-7343-471E-A53C-D59F19E2EB74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{43BF1DCB-7343-471E-A53C-D59F19E2EB74}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{43BF1DCB-7343-471E-A53C-D59F19E2EB74}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{43BF1DCB-7343-471E-A53C-D59F19E2EB74}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{47A706D4-4DF6-437E-9401-61878ECA243C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{47A706D4-4DF6-437E-9401-61878ECA243C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{47A706D4-4DF6-437E-9401-61878ECA243C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{47A706D4-4DF6-437E-9401-61878ECA243C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{AE8D301D-BDDD-4E04-A487-FD08BAF18B75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{AE8D301D-BDDD-4E04-A487-FD08BAF18B75}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{AE8D301D-BDDD-4E04-A487-FD08BAF18B75}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{AE8D301D-BDDD-4E04-A487-FD08BAF18B75}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{215D863E-9D87-42F4-AD17-209C330C6ECB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{215D863E-9D87-42F4-AD17-209C330C6ECB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{215D863E-9D87-42F4-AD17-209C330C6ECB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{215D863E-9D87-42F4-AD17-209C330C6ECB}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{933613BD-35B0-4F79-A7A7-02F663C55B61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{933613BD-35B0-4F79-A7A7-02F663C55B61}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{933613BD-35B0-4F79-A7A7-02F663C55B61}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{933613BD-35B0-4F79-A7A7-02F663C55B61}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{DB7A49D0-27E5-4B20-A153-D132BE9655D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{DB7A49D0-27E5-4B20-A153-D132BE9655D3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{DB7A49D0-27E5-4B20-A153-D132BE9655D3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{DB7A49D0-27E5-4B20-A153-D132BE9655D3}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{6729A51B-A7D9-43F3-8F48-D55478254AB7} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{9BFE1F4E-C2F4-49FC-917E-BE25C0F42D84} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{BEA2C25F-0551-4AFC-9961-7DB934724FF1} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{2952A3E3-8831-419B-B14C-448C409961A7} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{120F561D-5670-4C80-8CAB-4D770204DC91} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{395F9DF7-AE5A-403E-BE7A-4AF045B21BB3} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{0E9145DB-CC70-44F9-B52B-1D7D4C2B2E5F} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{546267CD-BE21-44E1-A06E-C7558864EE4F} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{A29115B9-30E4-4967-AD5A-C32394B8A64C} = {158628D7-8B68-451E-AF22-B64F473C5943}\n\t\t{8648122C-EE91-4B3B-98CD-355C3F1B9FDF} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{1EC25581-781E-4FEA-A8AC-72BBD599FB87} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{BB38F47A-1BBF-47E1-9872-088FC81DC825} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{57F395AD-48D2-48BF-A117-881E112D947E} = {158628D7-8B68-451E-AF22-B64F473C5943}\n\t\t{879689CC-38F7-418F-9721-9D4158302B69} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{141BD303-CD29-472F-B5D8-C1F28ED0621A} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{EA1583D5-80DE-4A11-9530-26A0ED1FBA2C} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{9FB83FF6-5A75-4036-80E6-11B302B921BE} = {158628D7-8B68-451E-AF22-B64F473C5943}\n\t\t{8302E4DD-2A99-439C-9D0C-A4BCF48E3FA3} = {158628D7-8B68-451E-AF22-B64F473C5943}\n\t\t{43BF1DCB-7343-471E-A53C-D59F19E2EB74} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{47A706D4-4DF6-437E-9401-61878ECA243C} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{AE8D301D-BDDD-4E04-A487-FD08BAF18B75} = {D027D36B-262B-450A-B444-5B7893B5142E}\n\t\t{215D863E-9D87-42F4-AD17-209C330C6ECB} = {AFE7085F-051E-4829-955F-3426FE643BDD}\n\t\t{933613BD-35B0-4F79-A7A7-02F663C55B61} = {AFE7085F-051E-4829-955F-3426FE643BDD}\n\t\t{EF723CAE-AB9F-4FFB-A36A-D56F9F1DC1B3} = {179A2A2C-3B3D-437C-B5F3-3B81472C8335}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {BAD78470-3D66-466E-9C17-2A67F0905B18}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Clients/src/ConsoleClientCredentialsFlow/ConsoleClientCredentialsFlow.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleClientCredentialsFlow/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConsole.Title = \"Console Client Credentials Flow\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"client\",\n        ClientSecret = \"secret\",\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var obj = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(obj);\n}"
  },
  {
    "path": "samples/Clients/src/ConsoleClientCredentialsFlowCallingIdentityServerApi/ConsoleClientCredentialsFlowCallingIdentityServerApi.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleClientCredentialsFlowCallingIdentityServerApi/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n\nConsole.Title = \"Console Client Credentials Flow calling IdentityServer API\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"client\",\n        ClientSecret = \"secret\",\n        Scope = \"IdentityServerApi\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.Authority;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"localApi\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var obj = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(obj);\n}\n\n"
  },
  {
    "path": "samples/Clients/src/ConsoleClientCredentialsFlowPostBody/ConsoleClientCredentialsFlowPostBody.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleClientCredentialsFlowPostBody/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConsole.Title = \"Console ClientCredentials Flow PostBody\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n        ClientCredentialStyle = ClientCredentialStyle.PostBody,\n\n        ClientId = \"client\",\n        ClientSecret = \"secret\",\n        Scope = \"resource1.scope1\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var obj = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(obj);\n}"
  },
  {
    "path": "samples/Clients/src/ConsoleCode/ConsoleCode.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleCode/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nOidcClient oidcClient = null!;\nHttpClient apiClient = new HttpClient { BaseAddress = new Uri(Constants.SampleApi) };\n\n\nConsole.WriteLine(\"+-----------------------+\");\nConsole.WriteLine(\"|  Sign in with OIDC    |\");\nConsole.WriteLine(\"+-----------------------+\");\nConsole.WriteLine(\"\");\nConsole.WriteLine(\"Press any key to sign in...\");\nConsole.ReadKey();\n\nawait SignIn();\n\n async Task SignIn()\n{\n    // create a redirect URI using an available port on the loopback address.\n    // requires the OP to allow random ports on 127.0.0.1 - otherwise set a static port\n    var browser = new SystemBrowser();\n    string redirectUri = string.Format($\"http://127.0.0.1:{browser.Port}\");\n\n    var options = new OidcClientOptions\n    {\n        Authority = Constants.Authority,\n\n        ClientId = \"console.pkce\",\n\n        RedirectUri = redirectUri,\n        Scope = \"openid profile resource1.scope1\",\n        FilterClaims = false,\n        Browser = browser\n    };\n\n    var serilog = new LoggerConfiguration()\n        .MinimumLevel.Error()\n        .Enrich.FromLogContext()\n        .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}{Exception}{NewLine}\")\n        .CreateLogger();\n\n    options.LoggerFactory.AddSerilog(serilog);\n\n    oidcClient = new OidcClient(options);\n    var result = await oidcClient.LoginAsync(new LoginRequest());\n\n    ShowResult(result);\n    await NextSteps(result);\n}\n\nvoid ShowResult(LoginResult result)\n{\n    if (result.IsError)\n    {\n        Console.WriteLine(\"\\n\\nError:\\n{0}\", result.Error);\n        return;\n    }\n\n    Console.WriteLine(\"\\n\\nClaims:\");\n    foreach (var claim in result.User.Claims)\n    {\n        Console.WriteLine(\"{0}: {1}\", claim.Type, claim.Value);\n    }\n\n    Console.WriteLine($\"\\nidentity token: {result.IdentityToken}\");\n    Console.WriteLine($\"access token:   {result.AccessToken}\");\n    Console.WriteLine($\"refresh token:  {result?.RefreshToken ?? \"none\"}\");\n}\n\nasync Task NextSteps(LoginResult result)\n{\n    var currentAccessToken = result.AccessToken;\n    var currentRefreshToken = result.RefreshToken;\n\n    var menu = \"  x...exit  c...call api   \";\n    if (currentRefreshToken != null) menu += \"r...refresh token   \";\n\n    while (true)\n    {\n        Console.WriteLine(\"\\n\\n\");\n\n        Console.Write(menu);\n        var key = Console.ReadKey();\n\n        if (key.Key == ConsoleKey.X) return;\n        if (key.Key == ConsoleKey.C) await CallApi(currentAccessToken);\n        if (key.Key == ConsoleKey.R)\n        {\n            var refreshResult = await oidcClient.RefreshTokenAsync(currentRefreshToken);\n            if (result.IsError)\n            {\n                Console.WriteLine($\"Error: {refreshResult.Error}\");\n            }\n            else\n            {\n                currentRefreshToken = refreshResult.RefreshToken;\n                currentAccessToken = refreshResult.AccessToken;\n\n                Console.WriteLine(\"\\n\\n\");\n                Console.WriteLine($\"access token:   {result.AccessToken}\");\n                Console.WriteLine($\"refresh token:  {result?.RefreshToken ?? \"none\"}\");\n            }\n        }\n    }\n}\n\nasync Task CallApi(string currentAccessToken)\n{\n    apiClient.SetBearerToken(currentAccessToken);\n    var response = await apiClient.GetAsync(\"identity\");\n\n    if (response.IsSuccessStatusCode)\n    {\n        var json = JsonSerializer.Deserialize<JsonElement>(await response.Content.ReadAsStringAsync());\n        Console.WriteLine(\"\\n\\n\");\n        Console.WriteLine(json);\n    }\n    else\n    {\n        Console.WriteLine($\"Error: {response.ReasonPhrase}\");\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsoleCode/SystemBrowser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class SystemBrowser : IBrowser\n{\n    public int Port { get; }\n    private readonly string _path;\n\n    public SystemBrowser(int? port = null, string path = null)\n    {\n        _path = path;\n\n        if (!port.HasValue)\n        {\n            Port = GetRandomUnusedPort();\n        }\n        else\n        {\n            Port = port.Value;\n        }\n    }\n\n    private int GetRandomUnusedPort()\n    {\n        var listener = new TcpListener(IPAddress.Loopback, 0);\n        listener.Start();\n        var port = ((IPEndPoint)listener.LocalEndpoint).Port;\n        listener.Stop();\n        return port;\n    }\n\n    public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)\n    {\n        using (var listener = new LoopbackHttpListener(Port, _path))\n        {\n            OpenBrowser(options.StartUrl);\n\n            try\n            {\n                var result = await listener.WaitForCallbackAsync();\n                if (String.IsNullOrWhiteSpace(result))\n                {\n                    return new BrowserResult { ResultType = BrowserResultType.UnknownError, Error = \"Empty response.\" };\n                }\n\n                return new BrowserResult { Response = result, ResultType = BrowserResultType.Success };\n            }\n            catch (TaskCanceledException ex)\n            {\n                return new BrowserResult { ResultType = BrowserResultType.Timeout, Error = ex.Message };\n            }\n            catch (Exception ex)\n            {\n                return new BrowserResult { ResultType = BrowserResultType.UnknownError, Error = ex.Message };\n            }\n        }\n    }\n\n    public static void OpenBrowser(string url)\n    {\n        try\n        {\n            Process.Start(url);\n        }\n        catch\n        {\n            // hack because of this: https://github.com/dotnet/corefx/issues/10361\n            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n            {\n                url = url.Replace(\"&\", \"^&\");\n                Process.Start(new ProcessStartInfo(\"cmd\", $\"/c start {url}\") { CreateNoWindow = true });\n            }\n            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))\n            {\n                Process.Start(\"xdg-open\", url);\n            }\n            else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))\n            {\n                Process.Start(\"open\", url);\n            }\n            else\n            {\n                throw;\n            }\n        }\n    }\n}\n\npublic class LoopbackHttpListener : IDisposable\n{\n    const int DefaultTimeout = 60 * 5; // 5 mins (in seconds)\n\n    IWebHost _host;\n    TaskCompletionSource<string> _source = new TaskCompletionSource<string>();\n    string _url;\n\n    public string Url => _url;\n\n    public LoopbackHttpListener(int port, string path = null)\n    {\n        path = path ?? String.Empty;\n        if (path.StartsWith(\"/\")) path = path.Substring(1);\n\n        _url = $\"http://127.0.0.1:{port}/{path}\";\n\n        _host = new WebHostBuilder()\n            .UseKestrel()\n            .UseUrls(_url)\n            .Configure(Configure)\n            .Build();\n        _host.Start();\n    }\n\n    public void Dispose()\n    {\n        Task.Run(async () =>\n        {\n            await Task.Delay(500);\n            _host.Dispose();\n        });\n    }\n\n    void Configure(IApplicationBuilder app)\n    {\n        app.Run(async ctx =>\n        {\n            if (ctx.Request.Method == \"GET\")\n            {\n                SetResult(ctx.Request.QueryString.Value, ctx);\n            }\n            else if (ctx.Request.Method == \"POST\")\n            {\n                if (!ctx.Request.ContentType.Equals(\"application/x-www-form-urlencoded\", StringComparison.OrdinalIgnoreCase))\n                {\n                    ctx.Response.StatusCode = 415;\n                }\n                else\n                {\n                    using (var sr = new StreamReader(ctx.Request.Body, Encoding.UTF8))\n                    {\n                        var body = await sr.ReadToEndAsync();\n                        SetResult(body, ctx);\n                    }\n                }\n            }\n            else\n            {\n                ctx.Response.StatusCode = 405;\n            }\n        });\n    }\n\n    private void SetResult(string value, HttpContext ctx)\n    {\n        try\n        {\n            ctx.Response.StatusCode = 200;\n            ctx.Response.ContentType = \"text/html\";\n            ctx.Response.WriteAsync(\"<h1>You can now return to the application.</h1>\");\n            ctx.Response.Body.Flush();\n\n            _source.TrySetResult(value);\n        }\n        catch\n        {\n            ctx.Response.StatusCode = 400;\n            ctx.Response.ContentType = \"text/html\";\n            ctx.Response.WriteAsync(\"<h1>Invalid request.</h1>\");\n            ctx.Response.Body.Flush();\n        }\n    }\n\n    public Task<string> WaitForCallbackAsync(int timeoutInSeconds = DefaultTimeout)\n    {\n        Task.Run(async () =>\n        {\n            await Task.Delay(timeoutInSeconds * 1000);\n            _source.TrySetCanceled();\n        });\n\n        return _source.Task;\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsoleCustomGrant/ConsoleExtensionGrant.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleCustomGrant/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nIDiscoveryCache cache = new DiscoveryCache(Constants.Authority);\n\n\nConsole.Title = \"Console Custom Grant\";\n\n// custom grant type with subject support\nvar response = await RequestTokenAsync(\"custom\");\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\nConsole.ReadLine();\n\n// custom grant type without subject support\nresponse = await RequestTokenAsync(\"custom.nosubject\");\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\n\nasync Task<TokenResponse> RequestTokenAsync(string grantType)\n{\n    var client = new HttpClient();\n\n    var disco = await cache.GetAsync();\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestTokenAsync(new TokenRequest\n    {\n        Address = disco.TokenEndpoint,\n        GrantType = grantType,\n\n        ClientId = \"client.custom\",\n        ClientSecret = \"secret\",\n\n        Parameters =\n                {\n                    { \"scope\", \"resource1.scope1\" },\n                    { \"custom_credential\", \"custom credential\"}\n                }\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsoleDeviceFlow/ConsoleDeviceFlow.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleDeviceFlow/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nIDiscoveryCache cache = new DiscoveryCache(Constants.Authority);\n\nConsole.Title = \"Console Device Flow\";\n\nvar authorizeResponse = await RequestAuthorizationAsync();\n\nvar tokenResponse = await RequestTokenAsync(authorizeResponse);\ntokenResponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(tokenResponse.AccessToken);\n\n\nasync Task<DeviceAuthorizationResponse> RequestAuthorizationAsync()\n{\n    var disco = await cache.GetAsync();\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var client = new HttpClient();\n    var response = await client.RequestDeviceAuthorizationAsync(new DeviceAuthorizationRequest\n    {\n        Address = disco.DeviceAuthorizationEndpoint,\n        ClientId = \"device\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n\n    Console.WriteLine($\"user code   : {response.UserCode}\");\n    Console.WriteLine($\"device code : {response.DeviceCode}\");\n    Console.WriteLine($\"URL         : {response.VerificationUri}\");\n    Console.WriteLine($\"Complete URL: {response.VerificationUriComplete}\");\n\n    Console.WriteLine($\"\\nPress enter to launch browser ({response.VerificationUri})\");\n    Console.ReadLine();\n\n    Process.Start(new ProcessStartInfo(response.VerificationUriComplete) { UseShellExecute = true });\n    return response;\n}\n\nasync Task<TokenResponse> RequestTokenAsync(DeviceAuthorizationResponse authorizeResponse)\n{\n    var disco = await cache.GetAsync();\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var client = new HttpClient();\n\n    while (true)\n    {\n        var response = await client.RequestDeviceTokenAsync(new DeviceTokenRequest\n        {\n            Address = disco.TokenEndpoint,\n            ClientId = \"device\",\n            DeviceCode = authorizeResponse.DeviceCode\n        });\n\n        if (response.IsError)\n        {\n            if (response.Error == OidcConstants.TokenErrors.AuthorizationPending || response.Error == OidcConstants.TokenErrors.SlowDown)\n            {\n                Console.WriteLine($\"{response.Error}...waiting.\");\n                Thread.Sleep(authorizeResponse.Interval * 1000);\n            }\n            else\n            {\n                throw new Exception(response.Error);\n            }\n        }\n        else\n        {\n            return response;\n        }\n    }\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsoleEphemeralMtlsClient/ConsoleEphemeralMtlsClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleEphemeralMtlsClient/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Clients;\nglobal using IdentityModel.Client;\nglobal using System.Security.Cryptography;\nglobal using System.Security.Cryptography.X509Certificates;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Clients/src/ConsoleEphemeralMtlsClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nX509Certificate2 clientCertificate = null!;\n\n\nclientCertificate = CreateClientCertificate(\"client\");\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient(GetHandler(clientCertificate));\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.AuthorityMtls);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var endpoint = disco.TokenEndpoint;\n    //.TryGetValue(OidcConstants.Discovery.MtlsEndpointAliases)\n    //.TryGetValue<string>(OidcConstants.Discovery.TokenEndpoint)\n    ////.Value<string>(OidcConstants.Discovery.TokenEndpoint)\n    //.ToString();\n\n    var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = endpoint,\n\n        ClientId = \"client\",\n        ClientSecret = \"secret\",\n        Scope = \"resource1.scope1\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var client = new HttpClient(GetHandler(clientCertificate))\n    {\n        BaseAddress = new Uri(Constants.SampleApiMtls)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}\n\nX509Certificate2 CreateClientCertificate(string name)\n{\n    X500DistinguishedName distinguishedName = new X500DistinguishedName($\"CN={name}\");\n\n    using (var rsa = RSA.Create(2048))\n    {\n        var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);\n\n        request.CertificateExtensions.Add(\n            new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));\n\n        request.CertificateExtensions.Add(\n            new X509EnhancedKeyUsageExtension(\n                new OidCollection { new Oid(\"1.3.6.1.5.5.7.3.2\") }, false));\n\n        return request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)), new DateTimeOffset(DateTime.UtcNow.AddDays(3650)));\n    }\n}\n\nSocketsHttpHandler GetHandler(X509Certificate2 certificate)\n{\n    var handler = new SocketsHttpHandler\n    {\n        SslOptions =\n                {\n                    ClientCertificates = new X509CertificateCollection {certificate}\n                }\n    };\n\n    return handler;\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsoleIntrospectionClient/ConsoleIntrospectionClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleIntrospectionClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nIDiscoveryCache cached = new DiscoveryCache(Constants.Authority);\n\n\nConsole.Title = \"Console Introspection Client\";\n\nvar response = await RequestTokenAsync();\nawait IntrospectAsync(response.AccessToken);\n\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var disco = await cached.GetAsync();\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var client = new HttpClient();\n    var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"roclient.reference\",\n        ClientSecret = \"secret\",\n\n        UserName = \"bob\",\n        Password = \"bob\",\n        Scope = \"resource1.scope1 resource2.scope1\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n async Task IntrospectAsync(string accessToken)\n{\n    var disco = await cached.GetAsync();\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var client = new HttpClient();\n    var result = await client.IntrospectTokenAsync(new TokenIntrospectionRequest\n    {\n        Address = disco.IntrospectionEndpoint,\n\n        ClientId = \"api1\",\n        ClientSecret = \"secret\",\n        Token = accessToken\n    });\n\n    if (result.IsError)\n    {\n        Console.WriteLine(result.Error);\n    }\n    else\n    {\n        if (result.IsActive)\n        {\n            result.Claims.ToList().ForEach(c => Console.WriteLine(\"{0}: {1}\",\n                c.Type, c.Value));\n        }\n        else\n        {\n            Console.WriteLine(\"token is not active\");\n        }\n    }\n}"
  },
  {
    "path": "samples/Clients/src/ConsoleMTLSClient/ConsoleMTLSClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup> \n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n  <ItemGroup>\n    <None Update=\"client.p12\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleMTLSClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n\nConsole.Title = \"Console mTLS Client\";\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient(GetHandler());\n\n    var disco = await client.GetDiscoveryDocumentAsync(\"https://identityserver.local\");\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var endpoint = disco.TokenEndpoint;\n    //.TryGetValue(OidcConstants.Discovery.MtlsEndpointAliases)\n    //.Value<string>(OidcConstants.Discovery.TokenEndpoint)\n    //.ToString();\n\n    var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = endpoint,\n\n        ClientId = \"mtls\",\n        Scope = \"resource1.scope1\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var client = new HttpClient(GetHandler())\n    {\n        BaseAddress = new Uri(Constants.SampleApi)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}\n\nSocketsHttpHandler GetHandler()\n{\n    var handler = new SocketsHttpHandler();\n\n    var cert = new X509Certificate2(\"client.p12\", \"changeit\");\n    handler.SslOptions.ClientCertificates = new X509CertificateCollection { cert };\n\n    return handler;\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsoleParameterizedScopeClient/ConsoleParameterizedScopeClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "samples/Clients/src/ConsoleParameterizedScopeClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConsole.Title = \"Console Parameterized Scope Client\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n        ClientId = \"parameterized.client\",\n        ClientSecret = \"secret\",\n        Scope = \"transaction:123\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient { BaseAddress = new Uri(baseAddress) };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsolePrivateKeyJwtClient/ConsolePrivateKeyJwtClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n  <ItemGroup>\n    <None Update=\"client.p12\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Clients/src/ConsolePrivateKeyJwtClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nstring rsaKey = \"{'d':'GmiaucNIzdvsEzGjZjd43SDToy1pz-Ph-shsOUXXh-dsYNGftITGerp8bO1iryXh_zUEo8oDK3r1y4klTonQ6bLsWw4ogjLPmL3yiqsoSjJa1G2Ymh_RY_sFZLLXAcrmpbzdWIAkgkHSZTaliL6g57vA7gxvd8L4s82wgGer_JmURI0ECbaCg98JVS0Srtf9GeTRHoX4foLWKc1Vq6NHthzqRMLZe-aRBNU9IMvXNd7kCcIbHCM3GTD_8cFj135nBPP2HOgC_ZXI1txsEf-djqJj8W5vaM7ViKU28IDv1gZGH3CatoysYx6jv1XJVvb2PH8RbFKbJmeyUm3Wvo-rgQ','dp':'YNjVBTCIwZD65WCht5ve06vnBLP_Po1NtL_4lkholmPzJ5jbLYBU8f5foNp8DVJBdFQW7wcLmx85-NC5Pl1ZeyA-Ecbw4fDraa5Z4wUKlF0LT6VV79rfOF19y8kwf6MigyrDqMLcH_CRnRGg5NfDsijlZXffINGuxg6wWzhiqqE','dq':'LfMDQbvTFNngkZjKkN2CBh5_MBG6Yrmfy4kWA8IC2HQqID5FtreiY2MTAwoDcoINfh3S5CItpuq94tlB2t-VUv8wunhbngHiB5xUprwGAAnwJ3DL39D2m43i_3YP-UO1TgZQUAOh7Jrd4foatpatTvBtY3F1DrCrUKE5Kkn770M','e':'AQAB','kid':'ZzAjSnraU3bkWGnnAqLapYGpTyNfLbjbzgAPbbW2GEA','kty':'RSA','n':'wWwQFtSzeRjjerpEM5Rmqz_DsNaZ9S1Bw6UbZkDLowuuTCjBWUax0vBMMxdy6XjEEK4Oq9lKMvx9JzjmeJf1knoqSNrox3Ka0rnxXpNAz6sATvme8p9mTXyp0cX4lF4U2J54xa2_S9NF5QWvpXvBeC4GAJx7QaSw4zrUkrc6XyaAiFnLhQEwKJCwUw4NOqIuYvYp_IXhw-5Ti_icDlZS-282PcccnBeOcX7vc21pozibIdmZJKqXNsL1Ibx5Nkx1F1jLnekJAmdaACDjYRLL_6n3W4wUp19UvzB1lGtXcJKLLkqB6YDiZNu16OSiSprfmrRXvYmvD8m6Fnl5aetgKw','p':'7enorp9Pm9XSHaCvQyENcvdU99WCPbnp8vc0KnY_0g9UdX4ZDH07JwKu6DQEwfmUA1qspC-e_KFWTl3x0-I2eJRnHjLOoLrTjrVSBRhBMGEH5PvtZTTThnIY2LReH-6EhceGvcsJ_MhNDUEZLykiH1OnKhmRuvSdhi8oiETqtPE','q':'0CBLGi_kRPLqI8yfVkpBbA9zkCAshgrWWn9hsq6a7Zl2LcLaLBRUxH0q1jWnXgeJh9o5v8sYGXwhbrmuypw7kJ0uA3OgEzSsNvX5Ay3R9sNel-3Mqm8Me5OfWWvmTEBOci8RwHstdR-7b9ZT13jk-dsZI7OlV_uBja1ny9Nz9ts','qi':'pG6J4dcUDrDndMxa-ee1yG4KjZqqyCQcmPAfqklI2LmnpRIjcK78scclvpboI3JQyg6RCEKVMwAhVtQM6cBcIO3JrHgqeYDblp5wXHjto70HVW6Z8kBruNx1AH9E8LzNvSRL-JVTFzBkJuNgzKQfD0G77tQRgJ-Ri7qu3_9o1M4'}\";\n\nConsole.Title = \"Console Client Credentials Flow with JWT Assertion\";\n\n// X.509 cert\nvar certificate = new X509Certificate2(\"client.p12\", \"changeit\");\nvar x509Credential = new X509SigningCredentials(certificate);\n\nvar response = await RequestTokenAsync(x509Credential);\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\n// RSA JsonWebkey\nvar jwk = new JsonWebKey(rsaKey);\nresponse = await RequestTokenAsync(new SigningCredentials(jwk, \"RS256\"));\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\nasync Task<TokenResponse> RequestTokenAsync(SigningCredentials credential)\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var clientToken = CreateClientToken(credential, \"client.jwt\", disco.TokenEndpoint);\n\n    var response = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n        Scope = \"resource1.scope1\",\n\n        ClientAssertion =\n        {\n            Type = OidcConstants.ClientAssertionTypes.JwtBearer,\n            Value = clientToken\n        }\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}\n\nstatic string CreateClientToken(SigningCredentials credential, string clientId, string audience)\n{\n\n    var now = DateTime.UtcNow;\n\n    var token = new JwtSecurityToken\n    (\n        clientId,\n        audience,\n        new List<Claim>()\n        {\n            new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()),\n            new Claim(JwtClaimTypes.Subject, clientId),\n            new Claim(JwtClaimTypes.IssuedAt, now.ToEpochTime().ToString(), ClaimValueTypes.Integer64)\n        },\n        now,\n        now.AddMinutes(1),\n        credential\n    );\n\n    var tokenHandler = new JwtSecurityTokenHandler();\n    return tokenHandler.WriteToken(token);\n}"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlow/ConsoleResourceOwnerFlow.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlow/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConsole.Title = \"Console ResourceOwner Flow\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"roclient\",\n        ClientSecret = \"secret\",\n\n        UserName = \"bob\",\n        Password = \"bob\",\n\n        Scope = \"resource1.scope1 resource2.scope1\",\n\n        Parameters =\n                {\n                    { \"acr_values\", \"tenant:custom_account_store1 foo bar quux\" }\n                }\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowPublic/ConsoleResourceOwnerFlowPublic.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowPublic/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n\nConsole.Title = \"Console ResourceOwner Flow Public\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"roclient.public\",\n\n        UserName = \"bob\",\n        Password = \"bob\",\n\n        Scope = \"resource1.scope1 resource2.scope1\",\n\n        Parameters =\n                {\n                    { \"acr_values\", \"tenant:custom_account_store1 foo bar quux\" }\n                }\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowReference/ConsoleResourceOwnerFlowReference.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowReference/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConsole.Title = \"Console ResourceOwner Flow Reference\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\nawait CallServiceAsync(response.AccessToken);\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var client = new HttpClient();\n\n    var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"roclient.reference\",\n        ClientSecret = \"secret\",\n\n        UserName = \"bob\",\n        Password = \"bob\",\n\n        Scope = \"resource1.scope1 resource2.scope1 scope3\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n\n    while (true)\n    {\n        var response = await client.GetStringAsync(\"identity\");\n\n        \"\\n\\nService claims:\".ConsoleGreen();\n        var json = JsonSerializer.Deserialize<JsonElement>(response);\n        Console.WriteLine(json);\n\n        Console.ReadLine();\n    }\n}"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowRefreshToken/ConsoleResourceOwnerFlowRefreshToken.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowRefreshToken/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Clients;\nglobal using IdentityModel;\nglobal using IdentityModel.Client;\nglobal using System.Text;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowRefreshToken/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n\nHttpClient tokenClient = new HttpClient();\nDiscoveryCache cache = new DiscoveryCache(Constants.Authority);\n\n\nConsole.Title = \"Console ResourceOwner Flow RefreshToken\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nConsole.ReadLine();\n\nvar refresh_token = response.RefreshToken;\n\nwhile (true)\n{\n    response = await RefreshTokenAsync(refresh_token);\n    ShowResponse(response);\n\n    Console.ReadLine();\n    await CallServiceAsync(response.AccessToken);\n\n    if (response.RefreshToken != refresh_token)\n    {\n        refresh_token = response.RefreshToken;\n    }\n}\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var disco = await cache.GetAsync();\n\n    var response = await tokenClient.RequestPasswordTokenAsync(new PasswordTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"roclient\",\n        ClientSecret = \"secret\",\n\n        UserName = \"bob\",\n        Password = \"bob\",\n\n        Scope = \"resource1.scope1 offline_access\",\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n async Task<TokenResponse> RefreshTokenAsync(string refreshToken)\n{\n    Console.WriteLine(\"Using refresh token: {0}\", refreshToken);\n\n    var disco = await cache.GetAsync();\n    var response = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"roclient\",\n        ClientSecret = \"secret\",\n        RefreshToken = refreshToken\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task CallServiceAsync(string token)\n{\n    var baseAddress = Constants.SampleApi;\n\n    var client = new HttpClient\n    {\n        BaseAddress = new Uri(baseAddress)\n    };\n\n    client.SetBearerToken(token);\n    var response = await client.GetStringAsync(\"identity\");\n\n    \"\\n\\nService claims:\".ConsoleGreen();\n    var json = JsonSerializer.Deserialize<JsonElement>(response);\n    Console.WriteLine(json);\n}\n\nstatic void ShowResponse(TokenResponse response)\n{\n    if (!response.IsError)\n    {\n        \"Token response:\".ConsoleGreen();\n        Console.WriteLine(response.Json);\n\n        if (response.AccessToken.Contains(\".\"))\n        {\n            \"\\nAccess Token (decoded):\".ConsoleGreen();\n\n            var parts = response.AccessToken.Split('.');\n            var header = parts[0];\n            var claims = parts[1];\n\n            var headerJson = Encoding.UTF8.GetString(Base64Url.Decode(header));\n            Console.WriteLine(JsonSerializer.Deserialize<JsonElement>(header));\n            var claimsJson = Encoding.UTF8.GetString(Base64Url.Decode(claims));\n            Console.WriteLine(JsonSerializer.Deserialize<JsonElement>(claims));\n        }\n    }\n    else\n    {\n        if (response.ErrorType == ResponseErrorType.Http)\n        {\n            \"HTTP error: \".ConsoleGreen();\n            Console.WriteLine(response.Error);\n            \"HTTP status code: \".ConsoleGreen();\n            Console.WriteLine(response.HttpStatusCode);\n        }\n        else\n        {\n            \"Protocol error response:\".ConsoleGreen();\n            Console.WriteLine(response.Json);\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowUserInfo/ConsoleResourceOwnerFlowUserInfo.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/ConsoleResourceOwnerFlowUserInfo/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n\nHttpClient tokenClient = new HttpClient();\nDiscoveryCache cache = new DiscoveryCache(Constants.Authority);\n\n\nConsole.Title = \"Console ResourceOwner Flow UserInfo\";\n\nvar response = await RequestTokenAsync();\nresponse.Show();\n\nawait GetClaimsAsync(response.AccessToken);\n\n\nasync Task<TokenResponse> RequestTokenAsync()\n{\n    var disco = await cache.GetAsync();\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await tokenClient.RequestPasswordTokenAsync(new PasswordTokenRequest\n    {\n        Address = disco.TokenEndpoint,\n\n        ClientId = \"roclient\",\n        ClientSecret = \"secret\",\n\n        UserName = \"bob\",\n        Password = \"bob\",\n\n        Scope = \"openid custom.profile\"\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n    return response;\n}\n\nasync Task GetClaimsAsync(string token)\n{\n    var disco = await cache.GetAsync();\n    if (disco.IsError) throw new Exception(disco.Error);\n\n    var response = await tokenClient.GetUserInfoAsync(new UserInfoRequest\n    {\n        Address = disco.UserInfoEndpoint,\n        Token = token\n    });\n\n    if (response.IsError) throw new Exception(response.Error);\n\n    \"\\n\\nUser claims:\".ConsoleGreen();\n    foreach (var claim in response.Claims)\n    {\n        Console.WriteLine(\"{0}\\n {1}\", claim.Type, claim.Value);\n    }\n}"
  },
  {
    "path": "samples/Clients/src/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n  <ItemGroup>\n     <ProjectReference Include=\"$(SolutionDir)..\\shared\\Constants\\Constants.csproj\" Condition=\"$(MSBuildProjectName) != 'Constants' \" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/JsOidc/JsOidc.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n</Project>"
  },
  {
    "path": "samples/Clients/src/JsOidc/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n\n// run a static files web server\nvar app = WebApplication.Create(args);\napp\n    .UseDefaultFiles()\n    .UseStaticFiles();\n\n// uncomment to enable to test w/ CSP (Content-Security-Policy)\n/*\napp.Use(async (ctx, next) =>\n{\n    ctx.Response.OnStarting(() =>\n    {\n        if (ctx.Response.ContentType?.StartsWith(\"text/html\") == true)\n        {\n            ctx.Response.Headers.Add(\"Content-Security-Policy\", \"default-src 'self'; connect-src http://localhost:5000 http://localhost:3721; frame-src 'self' http://localhost:5000\");\n        }\n        return Task.CompletedTask;\n    });\n\n    await next();\n});\n*/\n\nawait app.RunAsync();"
  },
  {
    "path": "samples/Clients/src/JsOidc/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:44300/\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/src/JsOidc/web.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <system.webServer>\n    <handlers>\n      <add name=\"aspNetCore\" path=\"*\" verb=\"*\" modules=\"AspNetCoreModuleV2\" resourceType=\"Unspecified\" />\n    </handlers>\n    <aspNetCore processPath=\"%LAUNCHER_PATH%\" arguments=\"%LAUNCHER_ARGS%\" forwardWindowsAuthToken=\"false\" stdoutLogEnabled=\"false\" hostingModel=\"InProcess\">\n      <environmentVariables>\n        <environmentVariable name=\"ASPNETCORE_ENVIRONMENT\" value=\"Development\" />\n      </environmentVariables>\n    </aspNetCore>\n  </system.webServer>\n</configuration>"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/StyleSheet.css",
    "content": "﻿pre:empty {\n    display: none;\n}\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/app.js",
    "content": "﻿/// <reference path=\"libs/oidc-client.js\" />\n\nvar config = {\n    authority: \"https://localhost:5001/\",\n    client_id: \"js_oidc\",\n    redirect_uri: window.location.origin + \"/callback.html\",\n    post_logout_redirect_uri: window.location.origin + \"/index.html\",\n\n    // if we choose to use popup window instead for logins\n    popup_redirect_uri: window.location.origin + \"/popup.html\",\n    popupWindowFeatures: \"menubar=yes,location=yes,toolbar=yes,width=1200,height=800,left=100,top=100;resizable=yes\",\n\n    // these two will be done dynamically from the buttons clicked, but are\n    // needed if you want to use the silent_renew\n    response_type: \"code\",\n    scope: \"openid profile email resource1.scope1 resource2.scope1\",\n\n    // this will toggle if profile endpoint is used\n    loadUserInfo: true,\n\n    // silent renew will get a new access_token via an iframe \n    // just prior to the old access_token expiring (60 seconds prior)\n    silent_redirect_uri: window.location.origin + \"/silent.html\",\n    automaticSilentRenew: true,\n\n    monitorAnonymousSession: true,\n\n    // will revoke (reference) access tokens at logout time\n    revokeAccessTokenOnSignout: true,\n\n    // this will allow all the OIDC protocol claims to be visible in the window. normally a client app \n    // wouldn't care about them or want them taking up space\n    filterProtocolClaims: false\n};\nOidc.Log.logger = window.console;\nOidc.Log.level = Oidc.Log.DEBUG;\n\nvar mgr = new Oidc.UserManager(config);\n\nmgr.events.addUserLoaded(function (user) {\n    log(\"User loaded\");\n    showTokens();\n});\nmgr.events.addUserUnloaded(function () {\n    log(\"User logged out locally\");\n    showTokens();\n});\nmgr.events.addAccessTokenExpiring(function () {\n    log(\"Access token expiring...\");\n});\nmgr.events.addSilentRenewError(function (err) {\n    log(\"Silent renew error: \" + err.message);\n});\nmgr.events.addUserSignedIn(function (e) {\n    log(\"user logged in to the token server\");\n});\nmgr.events.addUserSignedOut(function () {\n    log(\"User signed out of OP\");\n});\n\nfunction login() {\n    mgr.signinRedirect();\n}\n\nfunction popup() {\n    mgr.signinPopup().then(function () {\n        log(\"Logged In\");\n    });\n}\n\nfunction logout() {\n    mgr.signoutRedirect();\n}\n\nfunction revoke() {\n    mgr.revokeAccessToken().then(function () {\n        log(\"Access Token Revoked.\")\n    }).catch(function (err) {\n        log(err);\n    });\n}\n\nfunction renewToken() {\n    mgr.signinSilent()\n        .then(function () {\n            log(\"silent renew success\");\n            showTokens();\n        }).catch(function (err) {\n            log(\"silent renew error\", err);\n        });\n}\nfunction callApi() {\n    mgr.getUser().then(function (user) {\n        var xhr = new XMLHttpRequest();\n        xhr.onload = function (e) {\n            if (xhr.status >= 400) {\n                display(\"#ajax-result\", {\n                    status: xhr.status,\n                    statusText: xhr.statusText,\n                    wwwAuthenticate: xhr.getResponseHeader(\"WWW-Authenticate\")\n                });\n            }\n            else {\n                display(\"#ajax-result\", xhr.response);\n            }\n        };\n        xhr.open(\"GET\", \"https://localhost:5005/identity\", true);\n        xhr.setRequestHeader(\"Authorization\", \"Bearer \" + user.access_token);\n        xhr.send();\n    });\n}\n\nif (window.location.hash) {\n    handleCallback();\n}\n\ndocument.querySelector(\".login\").addEventListener(\"click\", login, false);\ndocument.querySelector(\".popup\").addEventListener(\"click\", popup, false);\ndocument.querySelector(\".renew\").addEventListener(\"click\", renewToken, false);\ndocument.querySelector(\".call\").addEventListener(\"click\", callApi, false);\ndocument.querySelector(\".revoke\").addEventListener(\"click\", revoke, false);\ndocument.querySelector(\".logout\").addEventListener(\"click\", logout, false);\n\n\nfunction log(data) {\n    document.getElementById('response').innerText = '';\n\n    Array.prototype.forEach.call(arguments, function (msg) {\n        if (msg instanceof Error) {\n            msg = \"Error: \" + msg.message;\n        }\n        else if (typeof msg !== 'string') {\n            msg = JSON.stringify(msg, null, 2);\n        }\n        document.getElementById('response').innerText += msg + '\\r\\n';\n    });\n}\n\nfunction display(selector, data) {\n    if (data && typeof data === 'string') {\n        try {\n            data = JSON.parse(data);\n        }\n        catch (e) { }\n    }\n    if (data && typeof data !== 'string') {\n        data = JSON.stringify(data, null, 2);\n    }\n    document.querySelector(selector).textContent = data;\n}\n\nfunction showTokens() {\n    mgr.getUser().then(function (user) {\n        if (user) {\n            display(\"#id-token\", user);\n        }\n        else {\n            log(\"Not logged in\");\n        }\n    });\n}\nshowTokens();\n\nfunction handleCallback() {\n    mgr.signinRedirectCallback().then(function (user) {\n        var hash = window.location.hash.substr(1);\n        var result = hash.split('&').reduce(function (result, item) {\n            var parts = item.split('=');\n            result[parts[0]] = parts[1];\n            return result;\n        }, {});\n\n        log(result);\n        showTokens();\n\n        window.history.replaceState({},\n            window.document.title,\n            window.location.origin + window.location.pathname);\n\n    }, function (error) {\n        log(error);\n    });\n}"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/callback.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n<head>\n    <title></title>\n    <link href=\"libs/bootstrap.min.css\" rel=\"stylesheet\" />\n</head>\n<body>\n    <div class=\"container\">\n        <header class=\"page-header\">\n            <h1>Processing callback...</h1>\n        </header>\n\n        <div class=\"row\">\n            <div class=\"col-md-2\">\n                <a href=\"index.html\" class=\"btn btn-primary\">Back to index</a>\n            </div>\n        </div>\n    </div>\n\n    <script src=\"libs/oidc-client.js\"></script>\n    <script src=\"callback.js\"></script>\n</body>\n</html>\n\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/callback.js",
    "content": "﻿var mgr = new Oidc.UserManager({ loadUserInfo: true, filterProtocolClaims: true, response_mode:\"query\" });\nmgr.signinRedirectCallback().then(function (user) {\n    console.log(user);\n    window.history.replaceState({},\n        window.document.title,\n        window.location.origin + window.location.pathname);\n    window.location = \"index.html\";\n});\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/index.html",
    "content": "﻿<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <title></title>\n    <link href=\"libs/bootstrap.min.css\" rel=\"stylesheet\" />\n    <link href=\"StyleSheet.css\" rel=\"stylesheet\" />\n</head>\n<body>\n    <div class=\"container\">\n        <header class=\"page-header\">\n            <h1>JavaScript Oidc Client</h1>\n        </header>\n\n        <div class=\"row\">\n            <ul class=\"list-unstyled list-inline\">\n                <li><a class=\"btn btn-primary\" href=\"index.html\">Home</a></li>\n                <li><button class=\"btn btn-default login\">Login</button></li>\n                <li><button class=\"btn btn-default popup\">Login with popup</button></li>\n                <li><button class=\"btn btn-primary renew\">Renew Token</button></li>\n                <li><button class=\"btn btn-primary call\">Call Service</button></li>\n                <li><button class=\"btn btn-info revoke\">Revoke Access Token</button></li>\n                <li><button class=\"btn btn-info logout\">Logout</button></li>\n            </ul>\n        </div>\n\n        <div class=\"row\">\n            <ul class=\"list-unstyled list-inline\">\n            </ul>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"panel panel-default\">\n                <div class=\"panel-heading\">Message</div>\n                <div class=\"panel-body\">\n                    <pre id=\"response\"></pre>\n                </div>\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-6\">\n                <div class=\"panel panel-default\">\n                    <div class=\"panel-heading\">Current User</div>\n                    <div class=\"panel-body\">\n                        <pre id=\"id-token\"></pre>\n                    </div>\n                </div>\n            </div>\n\n            <!--<div class=\"col-sm-4\">\n                <div class=\"panel panel-default\">\n                    <div class=\"panel-heading\">Access Token</div>\n                    <div class=\"panel-body\">\n                        <pre id=\"access-token\"></pre>\n                    </div>\n                </div>\n            </div>-->\n\n            <div class=\"col-sm-6\">\n                <div class=\"panel panel-default\">\n                    <div class=\"panel-heading\">Ajax Result</div>\n                    <div class=\"panel-body\">\n                        <pre id=\"ajax-result\"></pre>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <script src=\"libs/oidc-client.js\"></script>\n    <script src=\"app.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/libs/oidc-client.d.ts",
    "content": "/* Provides a namespace for when the library is loaded outside a module loader environment */\nexport as namespace Oidc;\n\nexport const Version: string;\n\nexport interface Logger {\n  error(message?: any, ...optionalParams: any[]): void;\n  info(message?: any, ...optionalParams: any[]): void;\n  debug(message?: any, ...optionalParams: any[]): void;\n  warn(message?: any, ...optionalParams: any[]): void;\n}\n\nexport interface AccessTokenEvents {\n\n  load(container: User): void;\n\n  unload(): void;\n\n  /** Subscribe to events raised prior to the access token expiring */\n  addAccessTokenExpiring(callback: (...ev: any[]) => void): void;\n  removeAccessTokenExpiring(callback: (...ev: any[]) => void): void;\n\n  /** Subscribe to events raised after the access token has expired */\n  addAccessTokenExpired(callback: (...ev: any[]) => void): void;\n  removeAccessTokenExpired(callback: (...ev: any[]) => void): void;\n}\n\nexport class InMemoryWebStorage {\n  getItem(key: string): any;\n\n  setItem(key: string, value: any): any;\n\n  removeItem(key: string): any;\n\n  key(index: number): any;\n\n  length?: number;\n}\n\nexport class Log {\n  static readonly NONE: 0;\n  static readonly ERROR: 1;\n  static readonly WARN: 2;\n  static readonly INFO: 3;\n  static readonly DEBUG: 4;\n\n  static reset(): void;\n\n  static level: number;\n\n  static logger: Logger;\n\n  static debug(message?: any, ...optionalParams: any[]): void;\n  static info(message?: any, ...optionalParams: any[]): void;\n  static warn(message?: any, ...optionalParams: any[]): void;\n  static error(message?: any, ...optionalParams: any[]): void;\n}\n\nexport interface MetadataService {\n  new (settings: OidcClientSettings): MetadataService;\n\n  metadataUrl?: string;\n\n  getMetadata(): Promise<OidcMetadata>;\n\n  getIssuer(): Promise<string>;\n\n  getAuthorizationEndpoint(): Promise<string>;\n\n  getUserInfoEndpoint(): Promise<string>;\n\n  getTokenEndpoint(): Promise<string | undefined>;\n\n  getCheckSessionIframe(): Promise<string | undefined>;\n\n  getEndSessionEndpoint(): Promise<string | undefined>;\n\n  getRevocationEndpoint(): Promise<string | undefined>;\n\n  getKeysEndpoint(): Promise<string | undefined>;\n\n  getSigningKeys(): Promise<any[]>;\n}\n\nexport interface MetadataServiceCtor {\n  (settings: OidcClientSettings, jsonServiceCtor?: any): MetadataService;\n}\n\nexport interface ResponseValidator {\n  validateSigninResponse(state: any, response: any): Promise<SigninResponse>;\n  validateSignoutResponse(state: any, response: any): Promise<SignoutResponse>;\n}\n\nexport interface ResponseValidatorCtor {\n  (settings: OidcClientSettings, metadataServiceCtor?: MetadataServiceCtor, userInfoServiceCtor?: any): ResponseValidator;\n}\n\nexport interface SigninRequest {\n  url: string;\n  state: any;\n}\n\nexport interface SignoutRequest {\n  url: string;\n  state?: any;\n}\n\nexport class OidcClient {\n  constructor(settings: OidcClientSettings);\n\n  readonly settings: OidcClientSettings;\n\n  createSigninRequest(args?: any): Promise<SigninRequest>;\n  processSigninResponse(url?: string, stateStore?: StateStore): Promise<SigninResponse>;\n\n  createSignoutRequest(args?: any): Promise<SignoutRequest>;\n  processSignoutResponse(url?: string, stateStore?: StateStore): Promise<SignoutResponse>;\n\n  clearStaleState(stateStore: StateStore): Promise<any>;\n\n  readonly metadataService: MetadataService;\n}\n\nexport interface OidcClientSettings {\n  /** The URL of the OIDC/OAuth2 provider */\n  authority?: string;\n  readonly metadataUrl?: string;\n  /** Provide metadata when authority server does not allow CORS on the metadata endpoint */\n  metadata?: Partial<OidcMetadata>;\n  /** Provide signingKeys when authority server does not allow CORS on the jwks uri */\n  signingKeys?: any[];\n  /** Your client application's identifier as registered with the OIDC/OAuth2 */\n  client_id?: string;\n  client_secret?: string;\n  /** The type of response desired from the OIDC/OAuth2 provider (default: 'id_token') */\n  readonly response_type?: string;\n  readonly response_mode?: string;\n  /** The scope being requested from the OIDC/OAuth2 provider (default: 'openid') */\n  readonly scope?: string;\n  /** The redirect URI of your client application to receive a response from the OIDC/OAuth2 provider */\n  readonly redirect_uri?: string;\n  /** The OIDC/OAuth2 post-logout redirect URI */\n  readonly post_logout_redirect_uri?: string;\n  /** The OIDC/OAuth2 post-logout redirect URI when using popup */\n  readonly popup_post_logout_redirect_uri?: string;\n  readonly prompt?: string;\n  readonly display?: string;\n  readonly max_age?: number;\n  readonly ui_locales?: string;\n  readonly acr_values?: string;\n  /** Should OIDC protocol claims be removed from profile (default: true) */\n  readonly filterProtocolClaims?: boolean;\n  /** Flag to control if additional identity data is loaded from the user info endpoint in order to populate the user's profile (default: true) */\n  readonly loadUserInfo?: boolean;\n  /** Number (in seconds) indicating the age of state entries in storage for authorize requests that are considered abandoned and thus can be cleaned up (default: 300) */\n  readonly staleStateAge?: number;\n  /** The window of time (in seconds) to allow the current time to deviate when validating id_token's iat, nbf, and exp values (default: 300) */\n  readonly clockSkew?: number;\n  readonly stateStore?: StateStore;\n  readonly userInfoJwtIssuer?: 'ANY' | 'OP' | string;\n  ResponseValidatorCtor?: ResponseValidatorCtor;\n  MetadataServiceCtor?: MetadataServiceCtor;\n  /** An object containing additional query string parameters to be including in the authorization request */\n  extraQueryParams?: Record<string, any>;\n}\n\nexport class UserManager extends OidcClient {\n  constructor(settings: UserManagerSettings);\n\n  readonly settings: UserManagerSettings;\n\n  /** Removes stale state entries in storage for incomplete authorize requests */\n  clearStaleState(): Promise<void>;\n\n  /** Load the User object for the currently authenticated user */\n  getUser(): Promise<User | null>;\n  storeUser(user: User): Promise<void>;\n  /** Remove from any storage the currently authenticated user */\n  removeUser(): Promise<void>;\n\n  /** Trigger a request (via a popup window) to the authorization endpoint. The result of the promise is the authenticated User */\n  signinPopup(args?: any): Promise<User>;\n  /** Notify the opening window of response from the authorization endpoint */\n  signinPopupCallback(url?: string): Promise<User | undefined>;\n\n  /** Trigger a silent request (via an iframe or refreshtoken if available) to the authorization endpoint */\n  signinSilent(args?: any): Promise<User>;\n  /** Notify the parent window of response from the authorization endpoint */\n  signinSilentCallback(url?: string): Promise<User | undefined>;\n\n  /** Trigger a redirect of the current window to the authorization endpoint */\n  signinRedirect(args?: any): Promise<void>;\n  /** Process response from the authorization endpoint. */\n  signinRedirectCallback(url?: string): Promise<User>;\n\n  /** Trigger a redirect of the current window to the end session endpoint */\n  signoutRedirect(args?: any): Promise<void>;\n  /** Process response from the end session endpoint */\n  signoutRedirectCallback(url?: string): Promise<SignoutResponse>;\n\n  /** Trigger a redirect of a popup window window to the end session endpoint */\n  signoutPopup(args?: any): Promise<void>;\n  /** Process response from the end session endpoint from a popup window */\n  signoutPopupCallback(url?: string, keepOpen?: boolean): Promise<void>;\n  signoutPopupCallback(keepOpen?: boolean): Promise<void>;\n\n  /** Proxy to Popup, Redirect and Silent callbacks */\n  signinCallback(url?: string): Promise<User>;\n\n  /** Proxy to Popup and Redirect callbacks */\n  signoutCallback(url?: string): Promise<SignoutResponse | void>;\n\n  /** Query OP for user's current signin status */\n  querySessionStatus(args?: any): Promise<SessionStatus>;\n\n  revokeAccessToken(): Promise<void>;\n\n  /** Enables silent renew  */\n  startSilentRenew(): void;\n  /** Disables silent renew */\n  stopSilentRenew(): void;\n\n  events: UserManagerEvents;\n}\n\nexport interface SessionStatus {\n  /** Opaque session state used to validate if session changed (monitorSession) */\n  session_state: string;\n  /** Subject identifier */\n  sub: string;\n  /** Session ID */\n  sid?: string;\n}\n\nexport interface UserManagerEvents extends AccessTokenEvents {\n  load(user: User): any;\n  unload(): any;\n\n  /** Subscribe to events raised when user session has been established (or re-established) */\n  addUserLoaded(callback: UserManagerEvents.UserLoadedCallback): void;\n  removeUserLoaded(callback: UserManagerEvents.UserLoadedCallback): void;\n\n  /** Subscribe to events raised when a user session has been terminated */\n  addUserUnloaded(callback: UserManagerEvents.UserUnloadedCallback): void;\n  removeUserUnloaded(callback: UserManagerEvents.UserUnloadedCallback): void;\n\n  /** Subscribe to events raised when the automatic silent renew has failed */\n  addSilentRenewError(callback: UserManagerEvents.SilentRenewErrorCallback): void;\n  removeSilentRenewError(callback: UserManagerEvents.SilentRenewErrorCallback): void;\n\n  /** Subscribe to events raised when the user's sign-in status at the OP has changed */\n  addUserSignedOut(callback: UserManagerEvents.UserSignedOutCallback): void;\n  removeUserSignedOut(callback: UserManagerEvents.UserSignedOutCallback): void;\n\n  /** When `monitorSession` subscribe to events raised when the user session changed */\n  addUserSessionChanged(callback: UserManagerEvents.UserSessionChangedCallback): void;\n  removeUserSessionChanged(callback: UserManagerEvents.UserSessionChangedCallback): void;\n}\n\nexport namespace UserManagerEvents {\n  export type UserLoadedCallback = (user: User) => void;\n  export type UserUnloadedCallback = () => void;\n  export type SilentRenewErrorCallback = (error: Error) => void;\n  export type UserSignedOutCallback = () => void;\n  export type UserSessionChangedCallback = () => void;\n}\n\nexport interface UserManagerSettings extends OidcClientSettings {\n  /** The URL for the page containing the call to signinPopupCallback to handle the callback from the OIDC/OAuth2 */\n  readonly popup_redirect_uri?: string;\n  /** The features parameter to window.open for the popup signin window.\n   *  default: 'location=no,toolbar=no,width=500,height=500,left=100,top=100'\n   */\n  readonly popupWindowFeatures?: string;\n  /** The target parameter to window.open for the popup signin window (default: '_blank') */\n  readonly popupWindowTarget?: any;\n  /** The URL for the page containing the code handling the silent renew */\n  readonly silent_redirect_uri?: any;\n  /** Number of milliseconds to wait for the silent renew to return before assuming it has failed or timed out (default: 10000) */\n  readonly silentRequestTimeout?: any;\n  /** Flag to indicate if there should be an automatic attempt to renew the access token prior to its expiration (default: false) */\n  readonly automaticSilentRenew?: boolean;\n  readonly validateSubOnSilentRenew?: boolean;\n  /** Flag to control if id_token is included as id_token_hint in silent renew calls (default: true) */\n  readonly includeIdTokenInSilentRenew?: boolean;\n  /** Will raise events for when user has performed a signout at the OP (default: true) */\n  readonly monitorSession?: boolean;\n  /** Interval, in ms, to check the user's session (default: 2000) */\n  readonly checkSessionInterval?: number;\n  readonly query_status_response_type?: string;\n  readonly stopCheckSessionOnError?: boolean;\n  /** Will invoke the revocation endpoint on signout if there is an access token for the user (default: false) */\n  readonly revokeAccessTokenOnSignout?: boolean;\n  /** The number of seconds before an access token is to expire to raise the accessTokenExpiring event (default: 60) */\n  readonly accessTokenExpiringNotificationTime?: number;\n  readonly redirectNavigator?: any;\n  readonly popupNavigator?: any;\n  readonly iframeNavigator?: any;\n  /** Storage object used to persist User for currently authenticated user (default: session storage) */\n  readonly userStore?: WebStorageStateStore;\n}\n\nexport interface WebStorageStateStoreSettings {\n  prefix?: string;\n  store?: any;\n}\n\nexport interface StateStore {\n  set(key: string, value: any): Promise<void>;\n\n  get(key: string): Promise<any>;\n\n  remove(key: string): Promise<any>;\n\n  getAllKeys(): Promise<string[]>;\n}\n\nexport class WebStorageStateStore implements StateStore {\n  constructor(settings: WebStorageStateStoreSettings);\n\n  set(key: string, value: any): Promise<void>;\n\n  get(key: string): Promise<any>;\n\n  remove(key: string): Promise<any>;\n\n  getAllKeys(): Promise<string[]>;\n}\n\nexport interface SigninResponse {\n  new (url: string, delimiter?: string): SigninResponse;\n\n  access_token: string;\n  code: string;\n  error: string;\n  error_description: string;\n  error_uri: string;\n  id_token: string;\n  profile: any;\n  scope: string;\n  session_state: string;\n  state: any;\n  token_type: string;\n\n  readonly expired: boolean | undefined;\n  readonly expires_in: number | undefined;\n  readonly isOpenIdConnect: boolean;\n  readonly scopes: string[];\n}\n\nexport interface SignoutResponse {\n  new (url: string): SignoutResponse;\n\n  error?: string;\n  error_description?: string;\n  error_uri?: string;\n  state?: any;\n}\n\nexport interface UserSettings {\n  id_token: string;\n  session_state: string;\n  access_token: string;\n  refresh_token: string;\n  token_type: string;\n  scope: string;\n  profile: Profile;\n  expires_at: number;\n  state: any;\n}\n\nexport class User {\n  constructor(settings: UserSettings);\n\n  /** The id_token returned from the OIDC provider */\n  id_token: string;\n  /** The session state value returned from the OIDC provider (opaque) */\n  session_state?: string;\n  /** The access token returned from the OIDC provider. */\n  access_token: string;\n  /** Refresh token returned from the OIDC provider (if requested) */\n  refresh_token?: string;\n  /** The token_type returned from the OIDC provider */\n  token_type: string;\n  /** The scope returned from the OIDC provider */\n  scope: string;\n  /** The claims represented by a combination of the id_token and the user info endpoint */\n  profile: Profile;\n  /** The expires at returned from the OIDC provider */\n  expires_at: number;\n  /** The custom state transferred in the last signin */\n  state: any;\n\n  toStorageString(): string;\n  static fromStorageString(storageString: string): User;\n\n  /** Calculated number of seconds the access token has remaining */\n  readonly expires_in: number;\n  /** Calculated value indicating if the access token is expired */\n  readonly expired: boolean;\n  /** Array representing the parsed values from the scope */\n  readonly scopes: string[];\n}\n\nexport type Profile = IDTokenClaims & ProfileStandardClaims;\n\ninterface IDTokenClaims {\n  /** Issuer Identifier */\n  iss: string;\n  /** Subject identifier */\n  sub: string;\n  /** Audience(s): client_id ... */\n  aud: string;\n  /** Expiration time */\n  exp: number;\n  /** Issued at */\n  iat: number;\n  /** Time when the End-User authentication occurred */\n  auth_time?: number;\n  /** Time when the End-User authentication occurred */\n  nonce?: number;\n  /** Access Token hash value */\n  at_hash?: string;\n  /** Authentication Context Class Reference */\n  acr?: string;\n  /** Authentication Methods References */\n  amr?: string[];\n  /** Authorized Party - the party to which the ID Token was issued */\n  azp?: string;\n  /** Session ID - String identifier for a Session */\n  sid?: string;\n\n  /** Other custom claims */\n  [claimKey: string]: any;\n}\n\ninterface ProfileStandardClaims {\n  /** End-User's full name */\n  name?: string;\n  /** Given name(s) or first name(s) of the End-User */\n  given_name?: string;\n  /** Surname(s) or last name(s) of the End-User */\n  family_name?: string;\n  /** Middle name(s) of the End-User */\n  middle_name?: string;\n  /** Casual name of the End-User that may or may not be the same as the given_name. */\n  nickname?: string;\n  /** Shorthand name that the End-User wishes to be referred to at the RP, such as janedoe or j.doe. */\n  preferred_username?: string;\n  /** URL of the End-User's profile page */\n  profile?: string;\n  /** URL of the End-User's profile picture */\n  picture?: string;\n  /** URL of the End-User's Web page or blog */\n  website?: string;\n  /** End-User's preferred e-mail address */\n  email?: string;\n  /** True if the End-User's e-mail address has been verified; otherwise false. */\n  email_verified?: boolean;\n  /** End-User's gender. Values defined by this specification are female and male. */\n  gender?: string;\n  /** End-User's birthday, represented as an ISO 8601:2004 [ISO8601‑2004] YYYY-MM-DD format */\n  birthdate?: string;\n  /** String from zoneinfo [zoneinfo] time zone database representing the End-User's time zone. */\n  zoneinfo?: string;\n  /** End-User's locale, represented as a BCP47 [RFC5646] language tag. */\n  locale?: string;\n  /** End-User's preferred telephone number. */\n  phone_number?: string;\n  /** True if the End-User's phone number has been verified; otherwise false. */\n  phone_number_verified?: boolean;\n  /** object \tEnd-User's preferred address in JSON [RFC4627] */\n  address?: OidcAddress;\n  /** Time the End-User's information was last updated. */\n  updated_at?: number;\n}\n\ninterface OidcAddress {\n  /** Full mailing address, formatted for display or use on a mailing label */\n  formatted?: string;\n  /** Full street address component, which MAY include house number, street name, Post Office Box, and multi-line extended street address information */\n  street_address?: string;\n  /** City or locality component */\n  locality?: string;\n  /** State, province, prefecture, or region component */\n  region?: string;\n  /** Zip code or postal code component */\n  postal_code?: string;\n  /** Country name component */\n  country?: string;\n}\n\nexport class CordovaPopupWindow {\n  constructor(params: any);\n  navigate(params: any): Promise<any>;\n  promise: Promise<any>;\n}\n\nexport class CordovaPopupNavigator {\n  prepare(params: any): Promise<CordovaPopupWindow>;\n}\n\nexport class CordovaIFrameNavigator {\n  prepare(params: any): Promise<CordovaPopupWindow>;\n}\n\nexport interface OidcMetadata {\n  issuer: string;\n  authorization_endpoint:string;\n  token_endpoint: string;\n  token_endpoint_auth_methods_supported:string[];\n  token_endpoint_auth_signing_alg_values_supported: string[];\n  userinfo_endpoint: string;\n  check_session_iframe: string;\n  end_session_endpoint: string;\n  jwks_uri: string;\n  registration_endpoint: string;\n  scopes_supported: string[];\n  response_types_supported: string[];\n  acr_values_supported: string[];\n  subject_types_supported: string[];\n  userinfo_signing_alg_values_supported: string[];\n  userinfo_encryption_alg_values_supported: string[];\n  userinfo_encryption_enc_values_supported: string[];\n  id_token_signing_alg_values_supported: string[];\n  id_token_encryption_alg_values_supported: string[];\n  id_token_encryption_enc_values_supported: string[];\n  request_object_signing_alg_values_supported: string[];\n  display_values_supported: string[];\n  claim_types_supported: string[];\n  claims_supported: string[];\n  claims_parameter_supported: boolean;\n  service_documentation: string;\n  ui_locales_supported: string[];\n\n  revocation_endpoint: string;\n  introspection_endpoint: string;\n  frontchannel_logout_supported: boolean;\n  frontchannel_logout_session_supported: boolean;\n  backchannel_logout_supported: boolean;\n  backchannel_logout_session_supported: boolean;\n  grant_types_supported: string[];\n  response_modes_supported: string[];\n  code_challenge_methods_supported: string[];\n}\n\nexport interface CheckSessionIFrame {\n  new (callback: () => void, client_id: string, url: string, interval?: number, stopOnError?: boolean): CheckSessionIFrame\n\n  load(): Promise<void>;\n\n  start(session_state: string): void;\n\n  stop(): void;\n}\n\nexport interface CheckSessionIFrameCtor {\n  (callback: () => void, client_id: string, url: string, interval?: number, stopOnError?: boolean): CheckSessionIFrame;\n}\n\nexport class SessionMonitor {\n  constructor(userManager: UserManager, CheckSessionIFrameCtor: CheckSessionIFrameCtor);\n}\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/libs/oidc-client.js",
    "content": "var Oidc =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ \"./index.js\":\n/*!******************!*\\\n  !*** ./index.js ***!\n  \\******************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _Log = __webpack_require__(/*! ./src/Log.js */ \"./src/Log.js\");\n\nvar _OidcClient = __webpack_require__(/*! ./src/OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./src/OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./src/WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _InMemoryWebStorage = __webpack_require__(/*! ./src/InMemoryWebStorage.js */ \"./src/InMemoryWebStorage.js\");\n\nvar _UserManager = __webpack_require__(/*! ./src/UserManager.js */ \"./src/UserManager.js\");\n\nvar _AccessTokenEvents = __webpack_require__(/*! ./src/AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./src/MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _CordovaPopupNavigator = __webpack_require__(/*! ./src/CordovaPopupNavigator.js */ \"./src/CordovaPopupNavigator.js\");\n\nvar _CordovaIFrameNavigator = __webpack_require__(/*! ./src/CordovaIFrameNavigator.js */ \"./src/CordovaIFrameNavigator.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./src/CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./src/TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./src/SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _Global = __webpack_require__(/*! ./src/Global.js */ \"./src/Global.js\");\n\nvar _User = __webpack_require__(/*! ./src/User.js */ \"./src/User.js\");\n\nvar _version = __webpack_require__(/*! ./version.js */ \"./version.js\");\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nexports.default = {\n    Version: _version.Version,\n    Log: _Log.Log,\n    OidcClient: _OidcClient.OidcClient,\n    OidcClientSettings: _OidcClientSettings.OidcClientSettings,\n    WebStorageStateStore: _WebStorageStateStore.WebStorageStateStore,\n    InMemoryWebStorage: _InMemoryWebStorage.InMemoryWebStorage,\n    UserManager: _UserManager.UserManager,\n    AccessTokenEvents: _AccessTokenEvents.AccessTokenEvents,\n    MetadataService: _MetadataService.MetadataService,\n    CordovaPopupNavigator: _CordovaPopupNavigator.CordovaPopupNavigator,\n    CordovaIFrameNavigator: _CordovaIFrameNavigator.CordovaIFrameNavigator,\n    CheckSessionIFrame: _CheckSessionIFrame.CheckSessionIFrame,\n    TokenRevocationClient: _TokenRevocationClient.TokenRevocationClient,\n    SessionMonitor: _SessionMonitor.SessionMonitor,\n    Global: _Global.Global,\n    User: _User.User\n};\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./jsrsasign/dist/jsrsasign.js\":\n/*!*************************************!*\\\n  !*** ./jsrsasign/dist/jsrsasign.js ***!\n  \\*************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(Buffer) {\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/*\n * jsrsasign(all) 8.0.12 (2018-04-22) (c) 2010-2018 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n\nvar navigator = {};\nnavigator.userAgent = false;\n\nvar window = {};\n\n/*!\nCopyright (c) 2011, Yahoo! Inc. All rights reserved.\nCode licensed under the BSD License:\nhttp://developer.yahoo.com/yui/license.html\nversion: 2.9.0\n*/\nif (YAHOO === undefined) {\n  var YAHOO = {};\n}YAHOO.lang = { extend: function extend(g, h, f) {\n    if (!h || !g) {\n      throw new Error(\"YAHOO.lang.extend failed, please check that all dependencies are included.\");\n    }var d = function d() {};d.prototype = h.prototype;g.prototype = new d();g.prototype.constructor = g;g.superclass = h.prototype;if (h.prototype.constructor == Object.prototype.constructor) {\n      h.prototype.constructor = h;\n    }if (f) {\n      var b;for (b in f) {\n        g.prototype[b] = f[b];\n      }var e = function e() {},\n          c = [\"toString\", \"valueOf\"];try {\n        if (/MSIE/.test(navigator.userAgent)) {\n          e = function e(j, i) {\n            for (b = 0; b < c.length; b = b + 1) {\n              var l = c[b],\n                  k = i[l];if (typeof k === \"function\" && k != Object.prototype[l]) {\n                j[l] = k;\n              }\n            }\n          };\n        }\n      } catch (a) {}e(g.prototype, f);\n    }\n  } };\n/*! CryptoJS v3.1.2 core-fix.js\n * code.google.com/p/crypto-js\n * (c) 2009-2013 by Jeff Mott. All rights reserved.\n * code.google.com/p/crypto-js/wiki/License\n * THIS IS FIX of 'core.js' to fix Hmac issue.\n * https://code.google.com/p/crypto-js/issues/detail?id=84\n * https://crypto-js.googlecode.com/svn-history/r667/branches/3.x/src/core.js\n */\nvar CryptoJS = CryptoJS || function (e, g) {\n  var a = {};var b = a.lib = {};var j = b.Base = function () {\n    function n() {}return { extend: function extend(p) {\n        n.prototype = this;var o = new n();if (p) {\n          o.mixIn(p);\n        }if (!o.hasOwnProperty(\"init\")) {\n          o.init = function () {\n            o.$super.init.apply(this, arguments);\n          };\n        }o.init.prototype = o;o.$super = this;return o;\n      }, create: function create() {\n        var o = this.extend();o.init.apply(o, arguments);return o;\n      }, init: function init() {}, mixIn: function mixIn(p) {\n        for (var o in p) {\n          if (p.hasOwnProperty(o)) {\n            this[o] = p[o];\n          }\n        }if (p.hasOwnProperty(\"toString\")) {\n          this.toString = p.toString;\n        }\n      }, clone: function clone() {\n        return this.init.prototype.extend(this);\n      } };\n  }();var l = b.WordArray = j.extend({ init: function init(o, n) {\n      o = this.words = o || [];if (n != g) {\n        this.sigBytes = n;\n      } else {\n        this.sigBytes = o.length * 4;\n      }\n    }, toString: function toString(n) {\n      return (n || h).stringify(this);\n    }, concat: function concat(t) {\n      var q = this.words;var p = t.words;var n = this.sigBytes;var s = t.sigBytes;this.clamp();if (n % 4) {\n        for (var r = 0; r < s; r++) {\n          var o = p[r >>> 2] >>> 24 - r % 4 * 8 & 255;q[n + r >>> 2] |= o << 24 - (n + r) % 4 * 8;\n        }\n      } else {\n        for (var r = 0; r < s; r += 4) {\n          q[n + r >>> 2] = p[r >>> 2];\n        }\n      }this.sigBytes += s;return this;\n    }, clamp: function clamp() {\n      var o = this.words;var n = this.sigBytes;o[n >>> 2] &= 4294967295 << 32 - n % 4 * 8;o.length = e.ceil(n / 4);\n    }, clone: function clone() {\n      var n = j.clone.call(this);n.words = this.words.slice(0);return n;\n    }, random: function random(p) {\n      var o = [];for (var n = 0; n < p; n += 4) {\n        o.push(e.random() * 4294967296 | 0);\n      }return new l.init(o, p);\n    } });var m = a.enc = {};var h = m.Hex = { stringify: function stringify(p) {\n      var r = p.words;var o = p.sigBytes;var q = [];for (var n = 0; n < o; n++) {\n        var s = r[n >>> 2] >>> 24 - n % 4 * 8 & 255;q.push((s >>> 4).toString(16));q.push((s & 15).toString(16));\n      }return q.join(\"\");\n    }, parse: function parse(p) {\n      var n = p.length;var q = [];for (var o = 0; o < n; o += 2) {\n        q[o >>> 3] |= parseInt(p.substr(o, 2), 16) << 24 - o % 8 * 4;\n      }return new l.init(q, n / 2);\n    } };var d = m.Latin1 = { stringify: function stringify(q) {\n      var r = q.words;var p = q.sigBytes;var n = [];for (var o = 0; o < p; o++) {\n        var s = r[o >>> 2] >>> 24 - o % 4 * 8 & 255;n.push(String.fromCharCode(s));\n      }return n.join(\"\");\n    }, parse: function parse(p) {\n      var n = p.length;var q = [];for (var o = 0; o < n; o++) {\n        q[o >>> 2] |= (p.charCodeAt(o) & 255) << 24 - o % 4 * 8;\n      }return new l.init(q, n);\n    } };var c = m.Utf8 = { stringify: function stringify(n) {\n      try {\n        return decodeURIComponent(escape(d.stringify(n)));\n      } catch (o) {\n        throw new Error(\"Malformed UTF-8 data\");\n      }\n    }, parse: function parse(n) {\n      return d.parse(unescape(encodeURIComponent(n)));\n    } };var i = b.BufferedBlockAlgorithm = j.extend({ reset: function reset() {\n      this._data = new l.init();this._nDataBytes = 0;\n    }, _append: function _append(n) {\n      if (typeof n == \"string\") {\n        n = c.parse(n);\n      }this._data.concat(n);this._nDataBytes += n.sigBytes;\n    }, _process: function _process(w) {\n      var q = this._data;var x = q.words;var n = q.sigBytes;var t = this.blockSize;var v = t * 4;var u = n / v;if (w) {\n        u = e.ceil(u);\n      } else {\n        u = e.max((u | 0) - this._minBufferSize, 0);\n      }var s = u * t;var r = e.min(s * 4, n);if (s) {\n        for (var p = 0; p < s; p += t) {\n          this._doProcessBlock(x, p);\n        }var o = x.splice(0, s);q.sigBytes -= r;\n      }return new l.init(o, r);\n    }, clone: function clone() {\n      var n = j.clone.call(this);n._data = this._data.clone();return n;\n    }, _minBufferSize: 0 });var f = b.Hasher = i.extend({ cfg: j.extend(), init: function init(n) {\n      this.cfg = this.cfg.extend(n);this.reset();\n    }, reset: function reset() {\n      i.reset.call(this);this._doReset();\n    }, update: function update(n) {\n      this._append(n);this._process();return this;\n    }, finalize: function finalize(n) {\n      if (n) {\n        this._append(n);\n      }var o = this._doFinalize();return o;\n    }, blockSize: 512 / 32, _createHelper: function _createHelper(n) {\n      return function (p, o) {\n        return new n.init(o).finalize(p);\n      };\n    }, _createHmacHelper: function _createHmacHelper(n) {\n      return function (p, o) {\n        return new k.HMAC.init(n, o).finalize(p);\n      };\n    } });var k = a.algo = {};return a;\n}(Math);\n/*\nCryptoJS v3.1.2 x64-core-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (g) {\n  var a = CryptoJS,\n      f = a.lib,\n      e = f.Base,\n      h = f.WordArray,\n      a = a.x64 = {};a.Word = e.extend({ init: function init(b, c) {\n      this.high = b;this.low = c;\n    } });a.WordArray = e.extend({ init: function init(b, c) {\n      b = this.words = b || [];this.sigBytes = c != g ? c : 8 * b.length;\n    }, toX32: function toX32() {\n      for (var b = this.words, c = b.length, a = [], d = 0; d < c; d++) {\n        var e = b[d];a.push(e.high);a.push(e.low);\n      }return h.create(a, this.sigBytes);\n    }, clone: function clone() {\n      for (var b = e.clone.call(this), c = b.words = this.words.slice(0), a = c.length, d = 0; d < a; d++) {\n        c[d] = c[d].clone();\n      }return b;\n    } });\n})();\n\n/*\nCryptoJS v3.1.2 enc-base64.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  var h = CryptoJS,\n      j = h.lib.WordArray;h.enc.Base64 = { stringify: function stringify(b) {\n      var e = b.words,\n          f = b.sigBytes,\n          c = this._map;b.clamp();b = [];for (var a = 0; a < f; a += 3) {\n        for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) {\n          b.push(c.charAt(d >>> 6 * (3 - g) & 63));\n        }\n      }if (e = c.charAt(64)) for (; b.length % 4;) {\n        b.push(e);\n      }return b.join(\"\");\n    }, parse: function parse(b) {\n      var e = b.length,\n          f = this._map,\n          c = f.charAt(64);c && (c = b.indexOf(c), -1 != c && (e = c));for (var c = [], a = 0, d = 0; d < e; d++) {\n        if (d % 4) {\n          var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4),\n              h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4);c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4);a++;\n        }\n      }return j.create(c, a);\n    }, _map: \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\" };\n})();\n\n/*\nCryptoJS v3.1.2 sha256-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (k) {\n  for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function u(q) {\n    return 4294967296 * (q - (q | 0)) | 0;\n  }, l = 2, b = 0; 64 > b;) {\n    var d;a: {\n      d = l;for (var w = k.sqrt(d), r = 2; r <= w; r++) {\n        if (!(d % r)) {\n          d = !1;break a;\n        }\n      }d = !0;\n    }d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++);l++;\n  }var n = [],\n      h = h.SHA256 = j.extend({ _doReset: function _doReset() {\n      this._hash = new v.init(s.slice(0));\n    }, _doProcessBlock: function _doProcessBlock(q, h) {\n      for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) {\n        if (16 > e) n[e] = q[h + e] | 0;else {\n          var m = n[e - 15],\n              p = n[e - 2];n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16];\n        }m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e];p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b);l = j;j = g;g = f;f = k + m | 0;k = b;b = d;d = c;c = m + p | 0;\n      }a[0] = a[0] + c | 0;a[1] = a[1] + d | 0;a[2] = a[2] + b | 0;a[3] = a[3] + k | 0;a[4] = a[4] + f | 0;a[5] = a[5] + g | 0;a[6] = a[6] + j | 0;a[7] = a[7] + l | 0;\n    }, _doFinalize: function _doFinalize() {\n      var d = this._data,\n          b = d.words,\n          a = 8 * this._nDataBytes,\n          c = 8 * d.sigBytes;\n      b[c >>> 5] |= 128 << 24 - c % 32;b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296);b[(c + 64 >>> 9 << 4) + 15] = a;d.sigBytes = 4 * b.length;this._process();return this._hash;\n    }, clone: function clone() {\n      var b = j.clone.call(this);b._hash = this._hash.clone();return b;\n    } });g.SHA256 = j._createHelper(h);g.HmacSHA256 = j._createHmacHelper(h);\n})(Math);\n\n/*\nCryptoJS v3.1.2 sha512-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  function a() {\n    return d.create.apply(d, arguments);\n  }for (var n = CryptoJS, r = n.lib.Hasher, e = n.x64, d = e.Word, T = e.WordArray, e = n.algo, ea = [a(1116352408, 3609767458), a(1899447441, 602891725), a(3049323471, 3964484399), a(3921009573, 2173295548), a(961987163, 4081628472), a(1508970993, 3053834265), a(2453635748, 2937671579), a(2870763221, 3664609560), a(3624381080, 2734883394), a(310598401, 1164996542), a(607225278, 1323610764), a(1426881987, 3590304994), a(1925078388, 4068182383), a(2162078206, 991336113), a(2614888103, 633803317), a(3248222580, 3479774868), a(3835390401, 2666613458), a(4022224774, 944711139), a(264347078, 2341262773), a(604807628, 2007800933), a(770255983, 1495990901), a(1249150122, 1856431235), a(1555081692, 3175218132), a(1996064986, 2198950837), a(2554220882, 3999719339), a(2821834349, 766784016), a(2952996808, 2566594879), a(3210313671, 3203337956), a(3336571891, 1034457026), a(3584528711, 2466948901), a(113926993, 3758326383), a(338241895, 168717936), a(666307205, 1188179964), a(773529912, 1546045734), a(1294757372, 1522805485), a(1396182291, 2643833823), a(1695183700, 2343527390), a(1986661051, 1014477480), a(2177026350, 1206759142), a(2456956037, 344077627), a(2730485921, 1290863460), a(2820302411, 3158454273), a(3259730800, 3505952657), a(3345764771, 106217008), a(3516065817, 3606008344), a(3600352804, 1432725776), a(4094571909, 1467031594), a(275423344, 851169720), a(430227734, 3100823752), a(506948616, 1363258195), a(659060556, 3750685593), a(883997877, 3785050280), a(958139571, 3318307427), a(1322822218, 3812723403), a(1537002063, 2003034995), a(1747873779, 3602036899), a(1955562222, 1575990012), a(2024104815, 1125592928), a(2227730452, 2716904306), a(2361852424, 442776044), a(2428436474, 593698344), a(2756734187, 3733110249), a(3204031479, 2999351573), a(3329325298, 3815920427), a(3391569614, 3928383900), a(3515267271, 566280711), a(3940187606, 3454069534), a(4118630271, 4000239992), a(116418474, 1914138554), a(174292421, 2731055270), a(289380356, 3203993006), a(460393269, 320620315), a(685471733, 587496836), a(852142971, 1086792851), a(1017036298, 365543100), a(1126000580, 2618297676), a(1288033470, 3409855158), a(1501505948, 4234509866), a(1607167915, 987167468), a(1816402316, 1246189591)], v = [], w = 0; 80 > w; w++) {\n    v[w] = a();\n  }e = e.SHA512 = r.extend({ _doReset: function _doReset() {\n      this._hash = new T.init([new d.init(1779033703, 4089235720), new d.init(3144134277, 2227873595), new d.init(1013904242, 4271175723), new d.init(2773480762, 1595750129), new d.init(1359893119, 2917565137), new d.init(2600822924, 725511199), new d.init(528734635, 4215389547), new d.init(1541459225, 327033209)]);\n    }, _doProcessBlock: function _doProcessBlock(a, d) {\n      for (var f = this._hash.words, F = f[0], e = f[1], n = f[2], r = f[3], G = f[4], H = f[5], I = f[6], f = f[7], w = F.high, J = F.low, X = e.high, K = e.low, Y = n.high, L = n.low, Z = r.high, M = r.low, $ = G.high, N = G.low, aa = H.high, O = H.low, ba = I.high, P = I.low, ca = f.high, Q = f.low, k = w, g = J, z = X, x = K, A = Y, y = L, U = Z, B = M, l = $, h = N, R = aa, C = O, S = ba, D = P, V = ca, E = Q, m = 0; 80 > m; m++) {\n        var s = v[m];if (16 > m) var j = s.high = a[d + 2 * m] | 0,\n            b = s.low = a[d + 2 * m + 1] | 0;else {\n          var j = v[m - 15],\n              b = j.high,\n              p = j.low,\n              j = (b >>> 1 | p << 31) ^ (b >>> 8 | p << 24) ^ b >>> 7,\n              p = (p >>> 1 | b << 31) ^ (p >>> 8 | b << 24) ^ (p >>> 7 | b << 25),\n              u = v[m - 2],\n              b = u.high,\n              c = u.low,\n              u = (b >>> 19 | c << 13) ^ (b << 3 | c >>> 29) ^ b >>> 6,\n              c = (c >>> 19 | b << 13) ^ (c << 3 | b >>> 29) ^ (c >>> 6 | b << 26),\n              b = v[m - 7],\n              W = b.high,\n              t = v[m - 16],\n              q = t.high,\n              t = t.low,\n              b = p + b.low,\n              j = j + W + (b >>> 0 < p >>> 0 ? 1 : 0),\n              b = b + c,\n              j = j + u + (b >>> 0 < c >>> 0 ? 1 : 0),\n              b = b + t,\n              j = j + q + (b >>> 0 < t >>> 0 ? 1 : 0);s.high = j;s.low = b;\n        }var W = l & R ^ ~l & S,\n            t = h & C ^ ~h & D,\n            s = k & z ^ k & A ^ z & A,\n            T = g & x ^ g & y ^ x & y,\n            p = (k >>> 28 | g << 4) ^ (k << 30 | g >>> 2) ^ (k << 25 | g >>> 7),\n            u = (g >>> 28 | k << 4) ^ (g << 30 | k >>> 2) ^ (g << 25 | k >>> 7),\n            c = ea[m],\n            fa = c.high,\n            da = c.low,\n            c = E + ((h >>> 14 | l << 18) ^ (h >>> 18 | l << 14) ^ (h << 23 | l >>> 9)),\n            q = V + ((l >>> 14 | h << 18) ^ (l >>> 18 | h << 14) ^ (l << 23 | h >>> 9)) + (c >>> 0 < E >>> 0 ? 1 : 0),\n            c = c + t,\n            q = q + W + (c >>> 0 < t >>> 0 ? 1 : 0),\n            c = c + da,\n            q = q + fa + (c >>> 0 < da >>> 0 ? 1 : 0),\n            c = c + b,\n            q = q + j + (c >>> 0 < b >>> 0 ? 1 : 0),\n            b = u + T,\n            s = p + s + (b >>> 0 < u >>> 0 ? 1 : 0),\n            V = S,\n            E = D,\n            S = R,\n            D = C,\n            R = l,\n            C = h,\n            h = B + c | 0,\n            l = U + q + (h >>> 0 < B >>> 0 ? 1 : 0) | 0,\n            U = A,\n            B = y,\n            A = z,\n            y = x,\n            z = k,\n            x = g,\n            g = c + b | 0,\n            k = q + s + (g >>> 0 < c >>> 0 ? 1 : 0) | 0;\n      }J = F.low = J + g;F.high = w + k + (J >>> 0 < g >>> 0 ? 1 : 0);K = e.low = K + x;e.high = X + z + (K >>> 0 < x >>> 0 ? 1 : 0);L = n.low = L + y;n.high = Y + A + (L >>> 0 < y >>> 0 ? 1 : 0);M = r.low = M + B;r.high = Z + U + (M >>> 0 < B >>> 0 ? 1 : 0);N = G.low = N + h;G.high = $ + l + (N >>> 0 < h >>> 0 ? 1 : 0);O = H.low = O + C;H.high = aa + R + (O >>> 0 < C >>> 0 ? 1 : 0);P = I.low = P + D;\n      I.high = ba + S + (P >>> 0 < D >>> 0 ? 1 : 0);Q = f.low = Q + E;f.high = ca + V + (Q >>> 0 < E >>> 0 ? 1 : 0);\n    }, _doFinalize: function _doFinalize() {\n      var a = this._data,\n          d = a.words,\n          f = 8 * this._nDataBytes,\n          e = 8 * a.sigBytes;d[e >>> 5] |= 128 << 24 - e % 32;d[(e + 128 >>> 10 << 5) + 30] = Math.floor(f / 4294967296);d[(e + 128 >>> 10 << 5) + 31] = f;a.sigBytes = 4 * d.length;this._process();return this._hash.toX32();\n    }, clone: function clone() {\n      var a = r.clone.call(this);a._hash = this._hash.clone();return a;\n    }, blockSize: 32 });n.SHA512 = r._createHelper(e);n.HmacSHA512 = r._createHmacHelper(e);\n})();\n\n/*\nCryptoJS v3.1.2 sha384-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  var c = CryptoJS,\n      a = c.x64,\n      b = a.Word,\n      e = a.WordArray,\n      a = c.algo,\n      d = a.SHA512,\n      a = a.SHA384 = d.extend({ _doReset: function _doReset() {\n      this._hash = new e.init([new b.init(3418070365, 3238371032), new b.init(1654270250, 914150663), new b.init(2438529370, 812702999), new b.init(355462360, 4144912697), new b.init(1731405415, 4290775857), new b.init(2394180231, 1750603025), new b.init(3675008525, 1694076839), new b.init(1203062813, 3204075428)]);\n    }, _doFinalize: function _doFinalize() {\n      var a = d._doFinalize.call(this);a.sigBytes -= 16;return a;\n    } });c.SHA384 = d._createHelper(a);c.HmacSHA384 = d._createHmacHelper(a);\n})();\n\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar b64map = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";var b64pad = \"=\";function hex2b64(d) {\n  var b;var e;var a = \"\";for (b = 0; b + 3 <= d.length; b += 3) {\n    e = parseInt(d.substring(b, b + 3), 16);a += b64map.charAt(e >> 6) + b64map.charAt(e & 63);\n  }if (b + 1 == d.length) {\n    e = parseInt(d.substring(b, b + 1), 16);a += b64map.charAt(e << 2);\n  } else {\n    if (b + 2 == d.length) {\n      e = parseInt(d.substring(b, b + 2), 16);a += b64map.charAt(e >> 2) + b64map.charAt((e & 3) << 4);\n    }\n  }if (b64pad) {\n    while ((a.length & 3) > 0) {\n      a += b64pad;\n    }\n  }return a;\n}function b64tohex(f) {\n  var d = \"\";var e;var b = 0;var c;var a;for (e = 0; e < f.length; ++e) {\n    if (f.charAt(e) == b64pad) {\n      break;\n    }a = b64map.indexOf(f.charAt(e));if (a < 0) {\n      continue;\n    }if (b == 0) {\n      d += int2char(a >> 2);c = a & 3;b = 1;\n    } else {\n      if (b == 1) {\n        d += int2char(c << 2 | a >> 4);c = a & 15;b = 2;\n      } else {\n        if (b == 2) {\n          d += int2char(c);d += int2char(a >> 2);c = a & 3;b = 3;\n        } else {\n          d += int2char(c << 2 | a >> 4);d += int2char(a & 15);b = 0;\n        }\n      }\n    }\n  }if (b == 1) {\n    d += int2char(c << 2);\n  }return d;\n}function b64toBA(e) {\n  var d = b64tohex(e);var c;var b = new Array();for (c = 0; 2 * c < d.length; ++c) {\n    b[c] = parseInt(d.substring(2 * c, 2 * c + 2), 16);\n  }return b;\n};\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar dbits;var canary = 244837814094590;var j_lm = (canary & 16777215) == 15715070;function BigInteger(e, d, f) {\n  if (e != null) {\n    if (\"number\" == typeof e) {\n      this.fromNumber(e, d, f);\n    } else {\n      if (d == null && \"string\" != typeof e) {\n        this.fromString(e, 256);\n      } else {\n        this.fromString(e, d);\n      }\n    }\n  }\n}function nbi() {\n  return new BigInteger(null);\n}function am1(f, a, b, e, h, g) {\n  while (--g >= 0) {\n    var d = a * this[f++] + b[e] + h;h = Math.floor(d / 67108864);b[e++] = d & 67108863;\n  }return h;\n}function am2(f, q, r, e, o, a) {\n  var k = q & 32767,\n      p = q >> 15;while (--a >= 0) {\n    var d = this[f] & 32767;var g = this[f++] >> 15;var b = p * d + g * k;d = k * d + ((b & 32767) << 15) + r[e] + (o & 1073741823);o = (d >>> 30) + (b >>> 15) + p * g + (o >>> 30);r[e++] = d & 1073741823;\n  }return o;\n}function am3(f, q, r, e, o, a) {\n  var k = q & 16383,\n      p = q >> 14;while (--a >= 0) {\n    var d = this[f] & 16383;var g = this[f++] >> 14;var b = p * d + g * k;d = k * d + ((b & 16383) << 14) + r[e] + o;o = (d >> 28) + (b >> 14) + p * g;r[e++] = d & 268435455;\n  }return o;\n}if (j_lm && navigator.appName == \"Microsoft Internet Explorer\") {\n  BigInteger.prototype.am = am2;dbits = 30;\n} else {\n  if (j_lm && navigator.appName != \"Netscape\") {\n    BigInteger.prototype.am = am1;dbits = 26;\n  } else {\n    BigInteger.prototype.am = am3;dbits = 28;\n  }\n}BigInteger.prototype.DB = dbits;BigInteger.prototype.DM = (1 << dbits) - 1;BigInteger.prototype.DV = 1 << dbits;var BI_FP = 52;BigInteger.prototype.FV = Math.pow(2, BI_FP);BigInteger.prototype.F1 = BI_FP - dbits;BigInteger.prototype.F2 = 2 * dbits - BI_FP;var BI_RM = \"0123456789abcdefghijklmnopqrstuvwxyz\";var BI_RC = new Array();var rr, vv;rr = \"0\".charCodeAt(0);for (vv = 0; vv <= 9; ++vv) {\n  BI_RC[rr++] = vv;\n}rr = \"a\".charCodeAt(0);for (vv = 10; vv < 36; ++vv) {\n  BI_RC[rr++] = vv;\n}rr = \"A\".charCodeAt(0);for (vv = 10; vv < 36; ++vv) {\n  BI_RC[rr++] = vv;\n}function int2char(a) {\n  return BI_RM.charAt(a);\n}function intAt(b, a) {\n  var d = BI_RC[b.charCodeAt(a)];return d == null ? -1 : d;\n}function bnpCopyTo(b) {\n  for (var a = this.t - 1; a >= 0; --a) {\n    b[a] = this[a];\n  }b.t = this.t;b.s = this.s;\n}function bnpFromInt(a) {\n  this.t = 1;this.s = a < 0 ? -1 : 0;if (a > 0) {\n    this[0] = a;\n  } else {\n    if (a < -1) {\n      this[0] = a + this.DV;\n    } else {\n      this.t = 0;\n    }\n  }\n}function nbv(a) {\n  var b = nbi();b.fromInt(a);return b;\n}function bnpFromString(h, c) {\n  var e;if (c == 16) {\n    e = 4;\n  } else {\n    if (c == 8) {\n      e = 3;\n    } else {\n      if (c == 256) {\n        e = 8;\n      } else {\n        if (c == 2) {\n          e = 1;\n        } else {\n          if (c == 32) {\n            e = 5;\n          } else {\n            if (c == 4) {\n              e = 2;\n            } else {\n              this.fromRadix(h, c);return;\n            }\n          }\n        }\n      }\n    }\n  }this.t = 0;this.s = 0;var g = h.length,\n      d = false,\n      f = 0;while (--g >= 0) {\n    var a = e == 8 ? h[g] & 255 : intAt(h, g);if (a < 0) {\n      if (h.charAt(g) == \"-\") {\n        d = true;\n      }continue;\n    }d = false;if (f == 0) {\n      this[this.t++] = a;\n    } else {\n      if (f + e > this.DB) {\n        this[this.t - 1] |= (a & (1 << this.DB - f) - 1) << f;this[this.t++] = a >> this.DB - f;\n      } else {\n        this[this.t - 1] |= a << f;\n      }\n    }f += e;if (f >= this.DB) {\n      f -= this.DB;\n    }\n  }if (e == 8 && (h[0] & 128) != 0) {\n    this.s = -1;if (f > 0) {\n      this[this.t - 1] |= (1 << this.DB - f) - 1 << f;\n    }\n  }this.clamp();if (d) {\n    BigInteger.ZERO.subTo(this, this);\n  }\n}function bnpClamp() {\n  var a = this.s & this.DM;while (this.t > 0 && this[this.t - 1] == a) {\n    --this.t;\n  }\n}function bnToString(c) {\n  if (this.s < 0) {\n    return \"-\" + this.negate().toString(c);\n  }var e;if (c == 16) {\n    e = 4;\n  } else {\n    if (c == 8) {\n      e = 3;\n    } else {\n      if (c == 2) {\n        e = 1;\n      } else {\n        if (c == 32) {\n          e = 5;\n        } else {\n          if (c == 4) {\n            e = 2;\n          } else {\n            return this.toRadix(c);\n          }\n        }\n      }\n    }\n  }var g = (1 << e) - 1,\n      l,\n      a = false,\n      h = \"\",\n      f = this.t;var j = this.DB - f * this.DB % e;if (f-- > 0) {\n    if (j < this.DB && (l = this[f] >> j) > 0) {\n      a = true;h = int2char(l);\n    }while (f >= 0) {\n      if (j < e) {\n        l = (this[f] & (1 << j) - 1) << e - j;l |= this[--f] >> (j += this.DB - e);\n      } else {\n        l = this[f] >> (j -= e) & g;if (j <= 0) {\n          j += this.DB;--f;\n        }\n      }if (l > 0) {\n        a = true;\n      }if (a) {\n        h += int2char(l);\n      }\n    }\n  }return a ? h : \"0\";\n}function bnNegate() {\n  var a = nbi();BigInteger.ZERO.subTo(this, a);return a;\n}function bnAbs() {\n  return this.s < 0 ? this.negate() : this;\n}function bnCompareTo(b) {\n  var d = this.s - b.s;if (d != 0) {\n    return d;\n  }var c = this.t;d = c - b.t;if (d != 0) {\n    return this.s < 0 ? -d : d;\n  }while (--c >= 0) {\n    if ((d = this[c] - b[c]) != 0) {\n      return d;\n    }\n  }return 0;\n}function nbits(a) {\n  var c = 1,\n      b;if ((b = a >>> 16) != 0) {\n    a = b;c += 16;\n  }if ((b = a >> 8) != 0) {\n    a = b;c += 8;\n  }if ((b = a >> 4) != 0) {\n    a = b;c += 4;\n  }if ((b = a >> 2) != 0) {\n    a = b;c += 2;\n  }if ((b = a >> 1) != 0) {\n    a = b;c += 1;\n  }return c;\n}function bnBitLength() {\n  if (this.t <= 0) {\n    return 0;\n  }return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ this.s & this.DM);\n}function bnpDLShiftTo(c, b) {\n  var a;for (a = this.t - 1; a >= 0; --a) {\n    b[a + c] = this[a];\n  }for (a = c - 1; a >= 0; --a) {\n    b[a] = 0;\n  }b.t = this.t + c;b.s = this.s;\n}function bnpDRShiftTo(c, b) {\n  for (var a = c; a < this.t; ++a) {\n    b[a - c] = this[a];\n  }b.t = Math.max(this.t - c, 0);b.s = this.s;\n}function bnpLShiftTo(j, e) {\n  var b = j % this.DB;var a = this.DB - b;var g = (1 << a) - 1;var f = Math.floor(j / this.DB),\n      h = this.s << b & this.DM,\n      d;for (d = this.t - 1; d >= 0; --d) {\n    e[d + f + 1] = this[d] >> a | h;h = (this[d] & g) << b;\n  }for (d = f - 1; d >= 0; --d) {\n    e[d] = 0;\n  }e[f] = h;e.t = this.t + f + 1;e.s = this.s;e.clamp();\n}function bnpRShiftTo(g, d) {\n  d.s = this.s;var e = Math.floor(g / this.DB);if (e >= this.t) {\n    d.t = 0;return;\n  }var b = g % this.DB;var a = this.DB - b;var f = (1 << b) - 1;d[0] = this[e] >> b;for (var c = e + 1; c < this.t; ++c) {\n    d[c - e - 1] |= (this[c] & f) << a;d[c - e] = this[c] >> b;\n  }if (b > 0) {\n    d[this.t - e - 1] |= (this.s & f) << a;\n  }d.t = this.t - e;d.clamp();\n}function bnpSubTo(d, f) {\n  var e = 0,\n      g = 0,\n      b = Math.min(d.t, this.t);while (e < b) {\n    g += this[e] - d[e];f[e++] = g & this.DM;g >>= this.DB;\n  }if (d.t < this.t) {\n    g -= d.s;while (e < this.t) {\n      g += this[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += this.s;\n  } else {\n    g += this.s;while (e < d.t) {\n      g -= d[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g -= d.s;\n  }f.s = g < 0 ? -1 : 0;if (g < -1) {\n    f[e++] = this.DV + g;\n  } else {\n    if (g > 0) {\n      f[e++] = g;\n    }\n  }f.t = e;f.clamp();\n}function bnpMultiplyTo(c, e) {\n  var b = this.abs(),\n      f = c.abs();var d = b.t;e.t = d + f.t;while (--d >= 0) {\n    e[d] = 0;\n  }for (d = 0; d < f.t; ++d) {\n    e[d + b.t] = b.am(0, f[d], e, d, 0, b.t);\n  }e.s = 0;e.clamp();if (this.s != c.s) {\n    BigInteger.ZERO.subTo(e, e);\n  }\n}function bnpSquareTo(d) {\n  var a = this.abs();var b = d.t = 2 * a.t;while (--b >= 0) {\n    d[b] = 0;\n  }for (b = 0; b < a.t - 1; ++b) {\n    var e = a.am(b, a[b], d, 2 * b, 0, 1);if ((d[b + a.t] += a.am(b + 1, 2 * a[b], d, 2 * b + 1, e, a.t - b - 1)) >= a.DV) {\n      d[b + a.t] -= a.DV;d[b + a.t + 1] = 1;\n    }\n  }if (d.t > 0) {\n    d[d.t - 1] += a.am(b, a[b], d, 2 * b, 0, 1);\n  }d.s = 0;d.clamp();\n}function bnpDivRemTo(n, h, g) {\n  var w = n.abs();if (w.t <= 0) {\n    return;\n  }var k = this.abs();if (k.t < w.t) {\n    if (h != null) {\n      h.fromInt(0);\n    }if (g != null) {\n      this.copyTo(g);\n    }return;\n  }if (g == null) {\n    g = nbi();\n  }var d = nbi(),\n      a = this.s,\n      l = n.s;var v = this.DB - nbits(w[w.t - 1]);if (v > 0) {\n    w.lShiftTo(v, d);k.lShiftTo(v, g);\n  } else {\n    w.copyTo(d);k.copyTo(g);\n  }var p = d.t;var b = d[p - 1];if (b == 0) {\n    return;\n  }var o = b * (1 << this.F1) + (p > 1 ? d[p - 2] >> this.F2 : 0);var A = this.FV / o,\n      z = (1 << this.F1) / o,\n      x = 1 << this.F2;var u = g.t,\n      s = u - p,\n      f = h == null ? nbi() : h;d.dlShiftTo(s, f);if (g.compareTo(f) >= 0) {\n    g[g.t++] = 1;g.subTo(f, g);\n  }BigInteger.ONE.dlShiftTo(p, f);f.subTo(d, d);while (d.t < p) {\n    d[d.t++] = 0;\n  }while (--s >= 0) {\n    var c = g[--u] == b ? this.DM : Math.floor(g[u] * A + (g[u - 1] + x) * z);if ((g[u] += d.am(0, c, g, s, 0, p)) < c) {\n      d.dlShiftTo(s, f);g.subTo(f, g);while (g[u] < --c) {\n        g.subTo(f, g);\n      }\n    }\n  }if (h != null) {\n    g.drShiftTo(p, h);if (a != l) {\n      BigInteger.ZERO.subTo(h, h);\n    }\n  }g.t = p;g.clamp();if (v > 0) {\n    g.rShiftTo(v, g);\n  }if (a < 0) {\n    BigInteger.ZERO.subTo(g, g);\n  }\n}function bnMod(b) {\n  var c = nbi();this.abs().divRemTo(b, null, c);if (this.s < 0 && c.compareTo(BigInteger.ZERO) > 0) {\n    b.subTo(c, c);\n  }return c;\n}function Classic(a) {\n  this.m = a;\n}function cConvert(a) {\n  if (a.s < 0 || a.compareTo(this.m) >= 0) {\n    return a.mod(this.m);\n  } else {\n    return a;\n  }\n}function cRevert(a) {\n  return a;\n}function cReduce(a) {\n  a.divRemTo(this.m, null, a);\n}function cMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}function cSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}Classic.prototype.convert = cConvert;Classic.prototype.revert = cRevert;Classic.prototype.reduce = cReduce;Classic.prototype.mulTo = cMulTo;Classic.prototype.sqrTo = cSqrTo;function bnpInvDigit() {\n  if (this.t < 1) {\n    return 0;\n  }var a = this[0];if ((a & 1) == 0) {\n    return 0;\n  }var b = a & 3;b = b * (2 - (a & 15) * b) & 15;b = b * (2 - (a & 255) * b) & 255;b = b * (2 - ((a & 65535) * b & 65535)) & 65535;b = b * (2 - a * b % this.DV) % this.DV;return b > 0 ? this.DV - b : -b;\n}function Montgomery(a) {\n  this.m = a;this.mp = a.invDigit();this.mpl = this.mp & 32767;this.mph = this.mp >> 15;this.um = (1 << a.DB - 15) - 1;this.mt2 = 2 * a.t;\n}function montConvert(a) {\n  var b = nbi();a.abs().dlShiftTo(this.m.t, b);b.divRemTo(this.m, null, b);if (a.s < 0 && b.compareTo(BigInteger.ZERO) > 0) {\n    this.m.subTo(b, b);\n  }return b;\n}function montRevert(a) {\n  var b = nbi();a.copyTo(b);this.reduce(b);return b;\n}function montReduce(a) {\n  while (a.t <= this.mt2) {\n    a[a.t++] = 0;\n  }for (var c = 0; c < this.m.t; ++c) {\n    var b = a[c] & 32767;var d = b * this.mpl + ((b * this.mph + (a[c] >> 15) * this.mpl & this.um) << 15) & a.DM;b = c + this.m.t;a[b] += this.m.am(0, d, a, c, 0, this.m.t);while (a[b] >= a.DV) {\n      a[b] -= a.DV;a[++b]++;\n    }\n  }a.clamp();a.drShiftTo(this.m.t, a);if (a.compareTo(this.m) >= 0) {\n    a.subTo(this.m, a);\n  }\n}function montSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}function montMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}Montgomery.prototype.convert = montConvert;Montgomery.prototype.revert = montRevert;Montgomery.prototype.reduce = montReduce;Montgomery.prototype.mulTo = montMulTo;Montgomery.prototype.sqrTo = montSqrTo;function bnpIsEven() {\n  return (this.t > 0 ? this[0] & 1 : this.s) == 0;\n}function bnpExp(h, j) {\n  if (h > 4294967295 || h < 1) {\n    return BigInteger.ONE;\n  }var f = nbi(),\n      a = nbi(),\n      d = j.convert(this),\n      c = nbits(h) - 1;d.copyTo(f);while (--c >= 0) {\n    j.sqrTo(f, a);if ((h & 1 << c) > 0) {\n      j.mulTo(a, d, f);\n    } else {\n      var b = f;f = a;a = b;\n    }\n  }return j.revert(f);\n}function bnModPowInt(b, a) {\n  var c;if (b < 256 || a.isEven()) {\n    c = new Classic(a);\n  } else {\n    c = new Montgomery(a);\n  }return this.exp(b, c);\n}BigInteger.prototype.copyTo = bnpCopyTo;BigInteger.prototype.fromInt = bnpFromInt;BigInteger.prototype.fromString = bnpFromString;BigInteger.prototype.clamp = bnpClamp;BigInteger.prototype.dlShiftTo = bnpDLShiftTo;BigInteger.prototype.drShiftTo = bnpDRShiftTo;BigInteger.prototype.lShiftTo = bnpLShiftTo;BigInteger.prototype.rShiftTo = bnpRShiftTo;BigInteger.prototype.subTo = bnpSubTo;BigInteger.prototype.multiplyTo = bnpMultiplyTo;BigInteger.prototype.squareTo = bnpSquareTo;BigInteger.prototype.divRemTo = bnpDivRemTo;BigInteger.prototype.invDigit = bnpInvDigit;BigInteger.prototype.isEven = bnpIsEven;BigInteger.prototype.exp = bnpExp;BigInteger.prototype.toString = bnToString;BigInteger.prototype.negate = bnNegate;BigInteger.prototype.abs = bnAbs;BigInteger.prototype.compareTo = bnCompareTo;BigInteger.prototype.bitLength = bnBitLength;BigInteger.prototype.mod = bnMod;BigInteger.prototype.modPowInt = bnModPowInt;BigInteger.ZERO = nbv(0);BigInteger.ONE = nbv(1);\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction bnClone() {\n  var a = nbi();this.copyTo(a);return a;\n}function bnIntValue() {\n  if (this.s < 0) {\n    if (this.t == 1) {\n      return this[0] - this.DV;\n    } else {\n      if (this.t == 0) {\n        return -1;\n      }\n    }\n  } else {\n    if (this.t == 1) {\n      return this[0];\n    } else {\n      if (this.t == 0) {\n        return 0;\n      }\n    }\n  }return (this[1] & (1 << 32 - this.DB) - 1) << this.DB | this[0];\n}function bnByteValue() {\n  return this.t == 0 ? this.s : this[0] << 24 >> 24;\n}function bnShortValue() {\n  return this.t == 0 ? this.s : this[0] << 16 >> 16;\n}function bnpChunkSize(a) {\n  return Math.floor(Math.LN2 * this.DB / Math.log(a));\n}function bnSigNum() {\n  if (this.s < 0) {\n    return -1;\n  } else {\n    if (this.t <= 0 || this.t == 1 && this[0] <= 0) {\n      return 0;\n    } else {\n      return 1;\n    }\n  }\n}function bnpToRadix(c) {\n  if (c == null) {\n    c = 10;\n  }if (this.signum() == 0 || c < 2 || c > 36) {\n    return \"0\";\n  }var f = this.chunkSize(c);var e = Math.pow(c, f);var i = nbv(e),\n      j = nbi(),\n      h = nbi(),\n      g = \"\";this.divRemTo(i, j, h);while (j.signum() > 0) {\n    g = (e + h.intValue()).toString(c).substr(1) + g;j.divRemTo(i, j, h);\n  }return h.intValue().toString(c) + g;\n}function bnpFromRadix(m, h) {\n  this.fromInt(0);if (h == null) {\n    h = 10;\n  }var f = this.chunkSize(h);var g = Math.pow(h, f),\n      e = false,\n      a = 0,\n      l = 0;for (var c = 0; c < m.length; ++c) {\n    var k = intAt(m, c);if (k < 0) {\n      if (m.charAt(c) == \"-\" && this.signum() == 0) {\n        e = true;\n      }continue;\n    }l = h * l + k;if (++a >= f) {\n      this.dMultiply(g);this.dAddOffset(l, 0);a = 0;l = 0;\n    }\n  }if (a > 0) {\n    this.dMultiply(Math.pow(h, a));this.dAddOffset(l, 0);\n  }if (e) {\n    BigInteger.ZERO.subTo(this, this);\n  }\n}function bnpFromNumber(f, e, h) {\n  if (\"number\" == typeof e) {\n    if (f < 2) {\n      this.fromInt(1);\n    } else {\n      this.fromNumber(f, h);if (!this.testBit(f - 1)) {\n        this.bitwiseTo(BigInteger.ONE.shiftLeft(f - 1), op_or, this);\n      }if (this.isEven()) {\n        this.dAddOffset(1, 0);\n      }while (!this.isProbablePrime(e)) {\n        this.dAddOffset(2, 0);if (this.bitLength() > f) {\n          this.subTo(BigInteger.ONE.shiftLeft(f - 1), this);\n        }\n      }\n    }\n  } else {\n    var d = new Array(),\n        g = f & 7;d.length = (f >> 3) + 1;e.nextBytes(d);if (g > 0) {\n      d[0] &= (1 << g) - 1;\n    } else {\n      d[0] = 0;\n    }this.fromString(d, 256);\n  }\n}function bnToByteArray() {\n  var b = this.t,\n      c = new Array();c[0] = this.s;var e = this.DB - b * this.DB % 8,\n      f,\n      a = 0;if (b-- > 0) {\n    if (e < this.DB && (f = this[b] >> e) != (this.s & this.DM) >> e) {\n      c[a++] = f | this.s << this.DB - e;\n    }while (b >= 0) {\n      if (e < 8) {\n        f = (this[b] & (1 << e) - 1) << 8 - e;f |= this[--b] >> (e += this.DB - 8);\n      } else {\n        f = this[b] >> (e -= 8) & 255;if (e <= 0) {\n          e += this.DB;--b;\n        }\n      }if ((f & 128) != 0) {\n        f |= -256;\n      }if (a == 0 && (this.s & 128) != (f & 128)) {\n        ++a;\n      }if (a > 0 || f != this.s) {\n        c[a++] = f;\n      }\n    }\n  }return c;\n}function bnEquals(b) {\n  return this.compareTo(b) == 0;\n}function bnMin(b) {\n  return this.compareTo(b) < 0 ? this : b;\n}function bnMax(b) {\n  return this.compareTo(b) > 0 ? this : b;\n}function bnpBitwiseTo(c, h, e) {\n  var d,\n      g,\n      b = Math.min(c.t, this.t);for (d = 0; d < b; ++d) {\n    e[d] = h(this[d], c[d]);\n  }if (c.t < this.t) {\n    g = c.s & this.DM;for (d = b; d < this.t; ++d) {\n      e[d] = h(this[d], g);\n    }e.t = this.t;\n  } else {\n    g = this.s & this.DM;for (d = b; d < c.t; ++d) {\n      e[d] = h(g, c[d]);\n    }e.t = c.t;\n  }e.s = h(this.s, c.s);e.clamp();\n}function op_and(a, b) {\n  return a & b;\n}function bnAnd(b) {\n  var c = nbi();this.bitwiseTo(b, op_and, c);return c;\n}function op_or(a, b) {\n  return a | b;\n}function bnOr(b) {\n  var c = nbi();this.bitwiseTo(b, op_or, c);return c;\n}function op_xor(a, b) {\n  return a ^ b;\n}function bnXor(b) {\n  var c = nbi();this.bitwiseTo(b, op_xor, c);return c;\n}function op_andnot(a, b) {\n  return a & ~b;\n}function bnAndNot(b) {\n  var c = nbi();this.bitwiseTo(b, op_andnot, c);return c;\n}function bnNot() {\n  var b = nbi();for (var a = 0; a < this.t; ++a) {\n    b[a] = this.DM & ~this[a];\n  }b.t = this.t;b.s = ~this.s;return b;\n}function bnShiftLeft(b) {\n  var a = nbi();if (b < 0) {\n    this.rShiftTo(-b, a);\n  } else {\n    this.lShiftTo(b, a);\n  }return a;\n}function bnShiftRight(b) {\n  var a = nbi();if (b < 0) {\n    this.lShiftTo(-b, a);\n  } else {\n    this.rShiftTo(b, a);\n  }return a;\n}function lbit(a) {\n  if (a == 0) {\n    return -1;\n  }var b = 0;if ((a & 65535) == 0) {\n    a >>= 16;b += 16;\n  }if ((a & 255) == 0) {\n    a >>= 8;b += 8;\n  }if ((a & 15) == 0) {\n    a >>= 4;b += 4;\n  }if ((a & 3) == 0) {\n    a >>= 2;b += 2;\n  }if ((a & 1) == 0) {\n    ++b;\n  }return b;\n}function bnGetLowestSetBit() {\n  for (var a = 0; a < this.t; ++a) {\n    if (this[a] != 0) {\n      return a * this.DB + lbit(this[a]);\n    }\n  }if (this.s < 0) {\n    return this.t * this.DB;\n  }return -1;\n}function cbit(a) {\n  var b = 0;while (a != 0) {\n    a &= a - 1;++b;\n  }return b;\n}function bnBitCount() {\n  var c = 0,\n      a = this.s & this.DM;for (var b = 0; b < this.t; ++b) {\n    c += cbit(this[b] ^ a);\n  }return c;\n}function bnTestBit(b) {\n  var a = Math.floor(b / this.DB);if (a >= this.t) {\n    return this.s != 0;\n  }return (this[a] & 1 << b % this.DB) != 0;\n}function bnpChangeBit(c, b) {\n  var a = BigInteger.ONE.shiftLeft(c);this.bitwiseTo(a, b, a);return a;\n}function bnSetBit(a) {\n  return this.changeBit(a, op_or);\n}function bnClearBit(a) {\n  return this.changeBit(a, op_andnot);\n}function bnFlipBit(a) {\n  return this.changeBit(a, op_xor);\n}function bnpAddTo(d, f) {\n  var e = 0,\n      g = 0,\n      b = Math.min(d.t, this.t);while (e < b) {\n    g += this[e] + d[e];f[e++] = g & this.DM;g >>= this.DB;\n  }if (d.t < this.t) {\n    g += d.s;while (e < this.t) {\n      g += this[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += this.s;\n  } else {\n    g += this.s;while (e < d.t) {\n      g += d[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += d.s;\n  }f.s = g < 0 ? -1 : 0;if (g > 0) {\n    f[e++] = g;\n  } else {\n    if (g < -1) {\n      f[e++] = this.DV + g;\n    }\n  }f.t = e;f.clamp();\n}function bnAdd(b) {\n  var c = nbi();this.addTo(b, c);return c;\n}function bnSubtract(b) {\n  var c = nbi();this.subTo(b, c);return c;\n}function bnMultiply(b) {\n  var c = nbi();this.multiplyTo(b, c);return c;\n}function bnSquare() {\n  var a = nbi();this.squareTo(a);return a;\n}function bnDivide(b) {\n  var c = nbi();this.divRemTo(b, c, null);return c;\n}function bnRemainder(b) {\n  var c = nbi();this.divRemTo(b, null, c);return c;\n}function bnDivideAndRemainder(b) {\n  var d = nbi(),\n      c = nbi();this.divRemTo(b, d, c);return new Array(d, c);\n}function bnpDMultiply(a) {\n  this[this.t] = this.am(0, a - 1, this, 0, 0, this.t);++this.t;this.clamp();\n}function bnpDAddOffset(b, a) {\n  if (b == 0) {\n    return;\n  }while (this.t <= a) {\n    this[this.t++] = 0;\n  }this[a] += b;while (this[a] >= this.DV) {\n    this[a] -= this.DV;if (++a >= this.t) {\n      this[this.t++] = 0;\n    }++this[a];\n  }\n}function NullExp() {}function nNop(a) {\n  return a;\n}function nMulTo(a, c, b) {\n  a.multiplyTo(c, b);\n}function nSqrTo(a, b) {\n  a.squareTo(b);\n}NullExp.prototype.convert = nNop;NullExp.prototype.revert = nNop;NullExp.prototype.mulTo = nMulTo;NullExp.prototype.sqrTo = nSqrTo;function bnPow(a) {\n  return this.exp(a, new NullExp());\n}function bnpMultiplyLowerTo(b, f, e) {\n  var d = Math.min(this.t + b.t, f);e.s = 0;e.t = d;while (d > 0) {\n    e[--d] = 0;\n  }var c;for (c = e.t - this.t; d < c; ++d) {\n    e[d + this.t] = this.am(0, b[d], e, d, 0, this.t);\n  }for (c = Math.min(b.t, f); d < c; ++d) {\n    this.am(0, b[d], e, d, 0, f - d);\n  }e.clamp();\n}function bnpMultiplyUpperTo(b, e, d) {\n  --e;var c = d.t = this.t + b.t - e;d.s = 0;while (--c >= 0) {\n    d[c] = 0;\n  }for (c = Math.max(e - this.t, 0); c < b.t; ++c) {\n    d[this.t + c - e] = this.am(e - c, b[c], d, 0, 0, this.t + c - e);\n  }d.clamp();d.drShiftTo(1, d);\n}function Barrett(a) {\n  this.r2 = nbi();this.q3 = nbi();BigInteger.ONE.dlShiftTo(2 * a.t, this.r2);this.mu = this.r2.divide(a);this.m = a;\n}function barrettConvert(a) {\n  if (a.s < 0 || a.t > 2 * this.m.t) {\n    return a.mod(this.m);\n  } else {\n    if (a.compareTo(this.m) < 0) {\n      return a;\n    } else {\n      var b = nbi();a.copyTo(b);this.reduce(b);return b;\n    }\n  }\n}function barrettRevert(a) {\n  return a;\n}function barrettReduce(a) {\n  a.drShiftTo(this.m.t - 1, this.r2);if (a.t > this.m.t + 1) {\n    a.t = this.m.t + 1;a.clamp();\n  }this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);while (a.compareTo(this.r2) < 0) {\n    a.dAddOffset(1, this.m.t + 1);\n  }a.subTo(this.r2, a);while (a.compareTo(this.m) >= 0) {\n    a.subTo(this.m, a);\n  }\n}function barrettSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}function barrettMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}Barrett.prototype.convert = barrettConvert;Barrett.prototype.revert = barrettRevert;Barrett.prototype.reduce = barrettReduce;Barrett.prototype.mulTo = barrettMulTo;Barrett.prototype.sqrTo = barrettSqrTo;function bnModPow(q, f) {\n  var o = q.bitLength(),\n      h,\n      b = nbv(1),\n      v;if (o <= 0) {\n    return b;\n  } else {\n    if (o < 18) {\n      h = 1;\n    } else {\n      if (o < 48) {\n        h = 3;\n      } else {\n        if (o < 144) {\n          h = 4;\n        } else {\n          if (o < 768) {\n            h = 5;\n          } else {\n            h = 6;\n          }\n        }\n      }\n    }\n  }if (o < 8) {\n    v = new Classic(f);\n  } else {\n    if (f.isEven()) {\n      v = new Barrett(f);\n    } else {\n      v = new Montgomery(f);\n    }\n  }var p = new Array(),\n      d = 3,\n      s = h - 1,\n      a = (1 << h) - 1;p[1] = v.convert(this);if (h > 1) {\n    var A = nbi();v.sqrTo(p[1], A);while (d <= a) {\n      p[d] = nbi();v.mulTo(A, p[d - 2], p[d]);d += 2;\n    }\n  }var l = q.t - 1,\n      x,\n      u = true,\n      c = nbi(),\n      y;o = nbits(q[l]) - 1;while (l >= 0) {\n    if (o >= s) {\n      x = q[l] >> o - s & a;\n    } else {\n      x = (q[l] & (1 << o + 1) - 1) << s - o;if (l > 0) {\n        x |= q[l - 1] >> this.DB + o - s;\n      }\n    }d = h;while ((x & 1) == 0) {\n      x >>= 1;--d;\n    }if ((o -= d) < 0) {\n      o += this.DB;--l;\n    }if (u) {\n      p[x].copyTo(b);u = false;\n    } else {\n      while (d > 1) {\n        v.sqrTo(b, c);v.sqrTo(c, b);d -= 2;\n      }if (d > 0) {\n        v.sqrTo(b, c);\n      } else {\n        y = b;b = c;c = y;\n      }v.mulTo(c, p[x], b);\n    }while (l >= 0 && (q[l] & 1 << o) == 0) {\n      v.sqrTo(b, c);y = b;b = c;c = y;if (--o < 0) {\n        o = this.DB - 1;--l;\n      }\n    }\n  }return v.revert(b);\n}function bnGCD(c) {\n  var b = this.s < 0 ? this.negate() : this.clone();var h = c.s < 0 ? c.negate() : c.clone();if (b.compareTo(h) < 0) {\n    var e = b;b = h;h = e;\n  }var d = b.getLowestSetBit(),\n      f = h.getLowestSetBit();if (f < 0) {\n    return b;\n  }if (d < f) {\n    f = d;\n  }if (f > 0) {\n    b.rShiftTo(f, b);h.rShiftTo(f, h);\n  }while (b.signum() > 0) {\n    if ((d = b.getLowestSetBit()) > 0) {\n      b.rShiftTo(d, b);\n    }if ((d = h.getLowestSetBit()) > 0) {\n      h.rShiftTo(d, h);\n    }if (b.compareTo(h) >= 0) {\n      b.subTo(h, b);b.rShiftTo(1, b);\n    } else {\n      h.subTo(b, h);h.rShiftTo(1, h);\n    }\n  }if (f > 0) {\n    h.lShiftTo(f, h);\n  }return h;\n}function bnpModInt(e) {\n  if (e <= 0) {\n    return 0;\n  }var c = this.DV % e,\n      b = this.s < 0 ? e - 1 : 0;if (this.t > 0) {\n    if (c == 0) {\n      b = this[0] % e;\n    } else {\n      for (var a = this.t - 1; a >= 0; --a) {\n        b = (c * b + this[a]) % e;\n      }\n    }\n  }return b;\n}function bnModInverse(f) {\n  var j = f.isEven();if (this.isEven() && j || f.signum() == 0) {\n    return BigInteger.ZERO;\n  }var i = f.clone(),\n      h = this.clone();var g = nbv(1),\n      e = nbv(0),\n      l = nbv(0),\n      k = nbv(1);while (i.signum() != 0) {\n    while (i.isEven()) {\n      i.rShiftTo(1, i);if (j) {\n        if (!g.isEven() || !e.isEven()) {\n          g.addTo(this, g);e.subTo(f, e);\n        }g.rShiftTo(1, g);\n      } else {\n        if (!e.isEven()) {\n          e.subTo(f, e);\n        }\n      }e.rShiftTo(1, e);\n    }while (h.isEven()) {\n      h.rShiftTo(1, h);if (j) {\n        if (!l.isEven() || !k.isEven()) {\n          l.addTo(this, l);k.subTo(f, k);\n        }l.rShiftTo(1, l);\n      } else {\n        if (!k.isEven()) {\n          k.subTo(f, k);\n        }\n      }k.rShiftTo(1, k);\n    }if (i.compareTo(h) >= 0) {\n      i.subTo(h, i);if (j) {\n        g.subTo(l, g);\n      }e.subTo(k, e);\n    } else {\n      h.subTo(i, h);if (j) {\n        l.subTo(g, l);\n      }k.subTo(e, k);\n    }\n  }if (h.compareTo(BigInteger.ONE) != 0) {\n    return BigInteger.ZERO;\n  }if (k.compareTo(f) >= 0) {\n    return k.subtract(f);\n  }if (k.signum() < 0) {\n    k.addTo(f, k);\n  } else {\n    return k;\n  }if (k.signum() < 0) {\n    return k.add(f);\n  } else {\n    return k;\n  }\n}var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];function bnIsProbablePrime(e) {\n  var d,\n      b = this.abs();if (b.t == 1 && b[0] <= lowprimes[lowprimes.length - 1]) {\n    for (d = 0; d < lowprimes.length; ++d) {\n      if (b[0] == lowprimes[d]) {\n        return true;\n      }\n    }return false;\n  }if (b.isEven()) {\n    return false;\n  }d = 1;while (d < lowprimes.length) {\n    var a = lowprimes[d],\n        c = d + 1;while (c < lowprimes.length && a < lplim) {\n      a *= lowprimes[c++];\n    }a = b.modInt(a);while (d < c) {\n      if (a % lowprimes[d++] == 0) {\n        return false;\n      }\n    }\n  }return b.millerRabin(e);\n}function bnpMillerRabin(f) {\n  var g = this.subtract(BigInteger.ONE);var c = g.getLowestSetBit();if (c <= 0) {\n    return false;\n  }var h = g.shiftRight(c);f = f + 1 >> 1;if (f > lowprimes.length) {\n    f = lowprimes.length;\n  }var b = nbi();for (var e = 0; e < f; ++e) {\n    b.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);var l = b.modPow(h, this);if (l.compareTo(BigInteger.ONE) != 0 && l.compareTo(g) != 0) {\n      var d = 1;while (d++ < c && l.compareTo(g) != 0) {\n        l = l.modPowInt(2, this);if (l.compareTo(BigInteger.ONE) == 0) {\n          return false;\n        }\n      }if (l.compareTo(g) != 0) {\n        return false;\n      }\n    }\n  }return true;\n}BigInteger.prototype.chunkSize = bnpChunkSize;BigInteger.prototype.toRadix = bnpToRadix;BigInteger.prototype.fromRadix = bnpFromRadix;BigInteger.prototype.fromNumber = bnpFromNumber;BigInteger.prototype.bitwiseTo = bnpBitwiseTo;BigInteger.prototype.changeBit = bnpChangeBit;BigInteger.prototype.addTo = bnpAddTo;BigInteger.prototype.dMultiply = bnpDMultiply;BigInteger.prototype.dAddOffset = bnpDAddOffset;BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;BigInteger.prototype.modInt = bnpModInt;BigInteger.prototype.millerRabin = bnpMillerRabin;BigInteger.prototype.clone = bnClone;BigInteger.prototype.intValue = bnIntValue;BigInteger.prototype.byteValue = bnByteValue;BigInteger.prototype.shortValue = bnShortValue;BigInteger.prototype.signum = bnSigNum;BigInteger.prototype.toByteArray = bnToByteArray;BigInteger.prototype.equals = bnEquals;BigInteger.prototype.min = bnMin;BigInteger.prototype.max = bnMax;BigInteger.prototype.and = bnAnd;BigInteger.prototype.or = bnOr;BigInteger.prototype.xor = bnXor;BigInteger.prototype.andNot = bnAndNot;BigInteger.prototype.not = bnNot;BigInteger.prototype.shiftLeft = bnShiftLeft;BigInteger.prototype.shiftRight = bnShiftRight;BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;BigInteger.prototype.bitCount = bnBitCount;BigInteger.prototype.testBit = bnTestBit;BigInteger.prototype.setBit = bnSetBit;BigInteger.prototype.clearBit = bnClearBit;BigInteger.prototype.flipBit = bnFlipBit;BigInteger.prototype.add = bnAdd;BigInteger.prototype.subtract = bnSubtract;BigInteger.prototype.multiply = bnMultiply;BigInteger.prototype.divide = bnDivide;BigInteger.prototype.remainder = bnRemainder;BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;BigInteger.prototype.modPow = bnModPow;BigInteger.prototype.modInverse = bnModInverse;BigInteger.prototype.pow = bnPow;BigInteger.prototype.gcd = bnGCD;BigInteger.prototype.isProbablePrime = bnIsProbablePrime;BigInteger.prototype.square = bnSquare;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction Arcfour() {\n  this.i = 0;this.j = 0;this.S = new Array();\n}function ARC4init(d) {\n  var c, a, b;for (c = 0; c < 256; ++c) {\n    this.S[c] = c;\n  }a = 0;for (c = 0; c < 256; ++c) {\n    a = a + this.S[c] + d[c % d.length] & 255;b = this.S[c];this.S[c] = this.S[a];this.S[a] = b;\n  }this.i = 0;this.j = 0;\n}function ARC4next() {\n  var a;this.i = this.i + 1 & 255;this.j = this.j + this.S[this.i] & 255;a = this.S[this.i];this.S[this.i] = this.S[this.j];this.S[this.j] = a;return this.S[a + this.S[this.i] & 255];\n}Arcfour.prototype.init = ARC4init;Arcfour.prototype.next = ARC4next;function prng_newstate() {\n  return new Arcfour();\n}var rng_psize = 256;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar rng_state;var rng_pool;var rng_pptr;function rng_seed_int(a) {\n  rng_pool[rng_pptr++] ^= a & 255;rng_pool[rng_pptr++] ^= a >> 8 & 255;rng_pool[rng_pptr++] ^= a >> 16 & 255;rng_pool[rng_pptr++] ^= a >> 24 & 255;if (rng_pptr >= rng_psize) {\n    rng_pptr -= rng_psize;\n  }\n}function rng_seed_time() {\n  rng_seed_int(new Date().getTime());\n}if (rng_pool == null) {\n  rng_pool = new Array();rng_pptr = 0;var t;if (window !== undefined && (window.crypto !== undefined || window.msCrypto !== undefined)) {\n    var crypto = window.crypto || window.msCrypto;if (crypto.getRandomValues) {\n      var ua = new Uint8Array(32);crypto.getRandomValues(ua);for (t = 0; t < 32; ++t) {\n        rng_pool[rng_pptr++] = ua[t];\n      }\n    } else {\n      if (navigator.appName == \"Netscape\" && navigator.appVersion < \"5\") {\n        var z = window.crypto.random(32);for (t = 0; t < z.length; ++t) {\n          rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;\n        }\n      }\n    }\n  }while (rng_pptr < rng_psize) {\n    t = Math.floor(65536 * Math.random());rng_pool[rng_pptr++] = t >>> 8;rng_pool[rng_pptr++] = t & 255;\n  }rng_pptr = 0;rng_seed_time();\n}function rng_get_byte() {\n  if (rng_state == null) {\n    rng_seed_time();rng_state = prng_newstate();rng_state.init(rng_pool);for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {\n      rng_pool[rng_pptr] = 0;\n    }rng_pptr = 0;\n  }return rng_state.next();\n}function rng_get_bytes(b) {\n  var a;for (a = 0; a < b.length; ++a) {\n    b[a] = rng_get_byte();\n  }\n}function SecureRandom() {}SecureRandom.prototype.nextBytes = rng_get_bytes;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction parseBigInt(b, a) {\n  return new BigInteger(b, a);\n}function linebrk(c, d) {\n  var a = \"\";var b = 0;while (b + d < c.length) {\n    a += c.substring(b, b + d) + \"\\n\";b += d;\n  }return a + c.substring(b, c.length);\n}function byte2Hex(a) {\n  if (a < 16) {\n    return \"0\" + a.toString(16);\n  } else {\n    return a.toString(16);\n  }\n}function pkcs1pad2(e, h) {\n  if (h < e.length + 11) {\n    throw \"Message too long for RSA\";return null;\n  }var g = new Array();var d = e.length - 1;while (d >= 0 && h > 0) {\n    var f = e.charCodeAt(d--);if (f < 128) {\n      g[--h] = f;\n    } else {\n      if (f > 127 && f < 2048) {\n        g[--h] = f & 63 | 128;g[--h] = f >> 6 | 192;\n      } else {\n        g[--h] = f & 63 | 128;g[--h] = f >> 6 & 63 | 128;g[--h] = f >> 12 | 224;\n      }\n    }\n  }g[--h] = 0;var b = new SecureRandom();var a = new Array();while (h > 2) {\n    a[0] = 0;while (a[0] == 0) {\n      b.nextBytes(a);\n    }g[--h] = a[0];\n  }g[--h] = 2;g[--h] = 0;return new BigInteger(g);\n}function oaep_mgf1_arr(c, a, e) {\n  var b = \"\",\n      d = 0;while (b.length < a) {\n    b += e(String.fromCharCode.apply(String, c.concat([(d & 4278190080) >> 24, (d & 16711680) >> 16, (d & 65280) >> 8, d & 255])));d += 1;\n  }return b;\n}function oaep_pad(q, a, f, l) {\n  var c = KJUR.crypto.MessageDigest;var o = KJUR.crypto.Util;var b = null;if (!f) {\n    f = \"sha1\";\n  }if (typeof f === \"string\") {\n    b = c.getCanonicalAlgName(f);l = c.getHashLength(b);f = function f(i) {\n      return hextorstr(o.hashHex(rstrtohex(i), b));\n    };\n  }if (q.length + 2 * l + 2 > a) {\n    throw \"Message too long for RSA\";\n  }var k = \"\",\n      e;for (e = 0; e < a - q.length - 2 * l - 2; e += 1) {\n    k += \"\\x00\";\n  }var h = f(\"\") + k + \"\\x01\" + q;var g = new Array(l);new SecureRandom().nextBytes(g);var j = oaep_mgf1_arr(g, h.length, f);var p = [];for (e = 0; e < h.length; e += 1) {\n    p[e] = h.charCodeAt(e) ^ j.charCodeAt(e);\n  }var m = oaep_mgf1_arr(p, g.length, f);var d = [0];for (e = 0; e < g.length; e += 1) {\n    d[e + 1] = g[e] ^ m.charCodeAt(e);\n  }return new BigInteger(d.concat(p));\n}function RSAKey() {\n  this.n = null;this.e = 0;this.d = null;this.p = null;this.q = null;this.dmp1 = null;this.dmq1 = null;this.coeff = null;\n}function RSASetPublic(b, a) {\n  this.isPublic = true;this.isPrivate = false;if (typeof b !== \"string\") {\n    this.n = b;this.e = a;\n  } else {\n    if (b != null && a != null && b.length > 0 && a.length > 0) {\n      this.n = parseBigInt(b, 16);this.e = parseInt(a, 16);\n    } else {\n      throw \"Invalid RSA public key\";\n    }\n  }\n}function RSADoPublic(a) {\n  return a.modPowInt(this.e, this.n);\n}function RSAEncrypt(d) {\n  var a = pkcs1pad2(d, this.n.bitLength() + 7 >> 3);if (a == null) {\n    return null;\n  }var e = this.doPublic(a);if (e == null) {\n    return null;\n  }var b = e.toString(16);if ((b.length & 1) == 0) {\n    return b;\n  } else {\n    return \"0\" + b;\n  }\n}function RSAEncryptOAEP(f, e, b) {\n  var a = oaep_pad(f, this.n.bitLength() + 7 >> 3, e, b);if (a == null) {\n    return null;\n  }var g = this.doPublic(a);if (g == null) {\n    return null;\n  }var d = g.toString(16);if ((d.length & 1) == 0) {\n    return d;\n  } else {\n    return \"0\" + d;\n  }\n}RSAKey.prototype.doPublic = RSADoPublic;RSAKey.prototype.setPublic = RSASetPublic;RSAKey.prototype.encrypt = RSAEncrypt;RSAKey.prototype.encryptOAEP = RSAEncryptOAEP;RSAKey.prototype.type = \"RSA\";\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction ECFieldElementFp(b, a) {\n  this.x = a;this.q = b;\n}function feFpEquals(a) {\n  if (a == this) {\n    return true;\n  }return this.q.equals(a.q) && this.x.equals(a.x);\n}function feFpToBigInteger() {\n  return this.x;\n}function feFpNegate() {\n  return new ECFieldElementFp(this.q, this.x.negate().mod(this.q));\n}function feFpAdd(a) {\n  return new ECFieldElementFp(this.q, this.x.add(a.toBigInteger()).mod(this.q));\n}function feFpSubtract(a) {\n  return new ECFieldElementFp(this.q, this.x.subtract(a.toBigInteger()).mod(this.q));\n}function feFpMultiply(a) {\n  return new ECFieldElementFp(this.q, this.x.multiply(a.toBigInteger()).mod(this.q));\n}function feFpSquare() {\n  return new ECFieldElementFp(this.q, this.x.square().mod(this.q));\n}function feFpDivide(a) {\n  return new ECFieldElementFp(this.q, this.x.multiply(a.toBigInteger().modInverse(this.q)).mod(this.q));\n}ECFieldElementFp.prototype.equals = feFpEquals;ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger;ECFieldElementFp.prototype.negate = feFpNegate;ECFieldElementFp.prototype.add = feFpAdd;ECFieldElementFp.prototype.subtract = feFpSubtract;ECFieldElementFp.prototype.multiply = feFpMultiply;ECFieldElementFp.prototype.square = feFpSquare;ECFieldElementFp.prototype.divide = feFpDivide;function ECPointFp(c, a, d, b) {\n  this.curve = c;this.x = a;this.y = d;if (b == null) {\n    this.z = BigInteger.ONE;\n  } else {\n    this.z = b;\n  }this.zinv = null;\n}function pointFpGetX() {\n  if (this.zinv == null) {\n    this.zinv = this.z.modInverse(this.curve.q);\n  }return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}function pointFpGetY() {\n  if (this.zinv == null) {\n    this.zinv = this.z.modInverse(this.curve.q);\n  }return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}function pointFpEquals(a) {\n  if (a == this) {\n    return true;\n  }if (this.isInfinity()) {\n    return a.isInfinity();\n  }if (a.isInfinity()) {\n    return this.isInfinity();\n  }var c, b;c = a.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(a.z)).mod(this.curve.q);if (!c.equals(BigInteger.ZERO)) {\n    return false;\n  }b = a.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(a.z)).mod(this.curve.q);return b.equals(BigInteger.ZERO);\n}function pointFpIsInfinity() {\n  if (this.x == null && this.y == null) {\n    return true;\n  }return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);\n}function pointFpNegate() {\n  return new ECPointFp(this.curve, this.x, this.y.negate(), this.z);\n}function pointFpAdd(l) {\n  if (this.isInfinity()) {\n    return l;\n  }if (l.isInfinity()) {\n    return this;\n  }var p = l.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(l.z)).mod(this.curve.q);var o = l.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(l.z)).mod(this.curve.q);if (BigInteger.ZERO.equals(o)) {\n    if (BigInteger.ZERO.equals(p)) {\n      return this.twice();\n    }return this.curve.getInfinity();\n  }var j = new BigInteger(\"3\");var e = this.x.toBigInteger();var n = this.y.toBigInteger();var c = l.x.toBigInteger();var k = l.y.toBigInteger();var m = o.square();var i = m.multiply(o);var d = e.multiply(m);var g = p.square().multiply(this.z);var a = g.subtract(d.shiftLeft(1)).multiply(l.z).subtract(i).multiply(o).mod(this.curve.q);var h = d.multiply(j).multiply(p).subtract(n.multiply(i)).subtract(g.multiply(p)).multiply(l.z).add(p.multiply(i)).mod(this.curve.q);var f = i.multiply(this.z).multiply(l.z).mod(this.curve.q);return new ECPointFp(this.curve, this.curve.fromBigInteger(a), this.curve.fromBigInteger(h), f);\n}function pointFpTwice() {\n  if (this.isInfinity()) {\n    return this;\n  }if (this.y.toBigInteger().signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = new BigInteger(\"3\");var c = this.x.toBigInteger();var h = this.y.toBigInteger();var e = h.multiply(this.z);var j = e.multiply(h).mod(this.curve.q);var i = this.curve.a.toBigInteger();var k = c.square().multiply(g);if (!BigInteger.ZERO.equals(i)) {\n    k = k.add(this.z.square().multiply(i));\n  }k = k.mod(this.curve.q);var b = k.square().subtract(c.shiftLeft(3).multiply(j)).shiftLeft(1).multiply(e).mod(this.curve.q);var f = k.multiply(g).multiply(c).subtract(j.shiftLeft(1)).shiftLeft(2).multiply(j).subtract(k.square().multiply(k)).mod(this.curve.q);var d = e.square().multiply(e).shiftLeft(3).mod(this.curve.q);return new ECPointFp(this.curve, this.curve.fromBigInteger(b), this.curve.fromBigInteger(f), d);\n}function pointFpMultiply(b) {\n  if (this.isInfinity()) {\n    return this;\n  }if (b.signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = b;var f = g.multiply(new BigInteger(\"3\"));var l = this.negate();var d = this;var c;for (c = f.bitLength() - 2; c > 0; --c) {\n    d = d.twice();var a = f.testBit(c);var j = g.testBit(c);if (a != j) {\n      d = d.add(a ? this : l);\n    }\n  }return d;\n}function pointFpMultiplyTwo(c, a, b) {\n  var d;if (c.bitLength() > b.bitLength()) {\n    d = c.bitLength() - 1;\n  } else {\n    d = b.bitLength() - 1;\n  }var f = this.curve.getInfinity();var e = this.add(a);while (d >= 0) {\n    f = f.twice();if (c.testBit(d)) {\n      if (b.testBit(d)) {\n        f = f.add(e);\n      } else {\n        f = f.add(this);\n      }\n    } else {\n      if (b.testBit(d)) {\n        f = f.add(a);\n      }\n    }--d;\n  }return f;\n}ECPointFp.prototype.getX = pointFpGetX;ECPointFp.prototype.getY = pointFpGetY;ECPointFp.prototype.equals = pointFpEquals;ECPointFp.prototype.isInfinity = pointFpIsInfinity;ECPointFp.prototype.negate = pointFpNegate;ECPointFp.prototype.add = pointFpAdd;ECPointFp.prototype.twice = pointFpTwice;ECPointFp.prototype.multiply = pointFpMultiply;ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo;function ECCurveFp(e, d, c) {\n  this.q = e;this.a = this.fromBigInteger(d);this.b = this.fromBigInteger(c);this.infinity = new ECPointFp(this, null, null);\n}function curveFpGetQ() {\n  return this.q;\n}function curveFpGetA() {\n  return this.a;\n}function curveFpGetB() {\n  return this.b;\n}function curveFpEquals(a) {\n  if (a == this) {\n    return true;\n  }return this.q.equals(a.q) && this.a.equals(a.a) && this.b.equals(a.b);\n}function curveFpGetInfinity() {\n  return this.infinity;\n}function curveFpFromBigInteger(a) {\n  return new ECFieldElementFp(this.q, a);\n}function curveFpDecodePointHex(d) {\n  switch (parseInt(d.substr(0, 2), 16)) {case 0:\n      return this.infinity;case 2:case 3:\n      return null;case 4:case 6:case 7:\n      var a = (d.length - 2) / 2;var c = d.substr(2, a);var b = d.substr(a + 2, a);return new ECPointFp(this, this.fromBigInteger(new BigInteger(c, 16)), this.fromBigInteger(new BigInteger(b, 16)));default:\n      return null;}\n}ECCurveFp.prototype.getQ = curveFpGetQ;ECCurveFp.prototype.getA = curveFpGetA;ECCurveFp.prototype.getB = curveFpGetB;ECCurveFp.prototype.equals = curveFpEquals;ECCurveFp.prototype.getInfinity = curveFpGetInfinity;ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger;ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex;\n/*! (c) Stefan Thomas | https://github.com/bitcoinjs/bitcoinjs-lib\n */\nECFieldElementFp.prototype.getByteLength = function () {\n  return Math.floor((this.toBigInteger().bitLength() + 7) / 8);\n};ECPointFp.prototype.getEncoded = function (c) {\n  var d = function d(h, f) {\n    var g = h.toByteArrayUnsigned();if (f < g.length) {\n      g = g.slice(g.length - f);\n    } else {\n      while (f > g.length) {\n        g.unshift(0);\n      }\n    }return g;\n  };var a = this.getX().toBigInteger();var e = this.getY().toBigInteger();var b = d(a, 32);if (c) {\n    if (e.isEven()) {\n      b.unshift(2);\n    } else {\n      b.unshift(3);\n    }\n  } else {\n    b.unshift(4);b = b.concat(d(e, 32));\n  }return b;\n};ECPointFp.decodeFrom = function (g, c) {\n  var f = c[0];var e = c.length - 1;var d = c.slice(1, 1 + e / 2);var b = c.slice(1 + e / 2, 1 + e);d.unshift(0);b.unshift(0);var a = new BigInteger(d);var h = new BigInteger(b);return new ECPointFp(g, g.fromBigInteger(a), g.fromBigInteger(h));\n};ECPointFp.decodeFromHex = function (g, c) {\n  var f = c.substr(0, 2);var e = c.length - 2;var d = c.substr(2, e / 2);var b = c.substr(2 + e / 2, e / 2);var a = new BigInteger(d, 16);var h = new BigInteger(b, 16);return new ECPointFp(g, g.fromBigInteger(a), g.fromBigInteger(h));\n};ECPointFp.prototype.add2D = function (c) {\n  if (this.isInfinity()) {\n    return c;\n  }if (c.isInfinity()) {\n    return this;\n  }if (this.x.equals(c.x)) {\n    if (this.y.equals(c.y)) {\n      return this.twice();\n    }return this.curve.getInfinity();\n  }var g = c.x.subtract(this.x);var e = c.y.subtract(this.y);var a = e.divide(g);var d = a.square().subtract(this.x).subtract(c.x);var f = a.multiply(this.x.subtract(d)).subtract(this.y);return new ECPointFp(this.curve, d, f);\n};ECPointFp.prototype.twice2D = function () {\n  if (this.isInfinity()) {\n    return this;\n  }if (this.y.toBigInteger().signum() == 0) {\n    return this.curve.getInfinity();\n  }var b = this.curve.fromBigInteger(BigInteger.valueOf(2));var e = this.curve.fromBigInteger(BigInteger.valueOf(3));var a = this.x.square().multiply(e).add(this.curve.a).divide(this.y.multiply(b));var c = a.square().subtract(this.x.multiply(b));var d = a.multiply(this.x.subtract(c)).subtract(this.y);return new ECPointFp(this.curve, c, d);\n};ECPointFp.prototype.multiply2D = function (b) {\n  if (this.isInfinity()) {\n    return this;\n  }if (b.signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = b;var f = g.multiply(new BigInteger(\"3\"));var l = this.negate();var d = this;var c;for (c = f.bitLength() - 2; c > 0; --c) {\n    d = d.twice();var a = f.testBit(c);var j = g.testBit(c);if (a != j) {\n      d = d.add2D(a ? this : l);\n    }\n  }return d;\n};ECPointFp.prototype.isOnCurve = function () {\n  var d = this.getX().toBigInteger();var i = this.getY().toBigInteger();var f = this.curve.getA().toBigInteger();var c = this.curve.getB().toBigInteger();var h = this.curve.getQ();var e = i.multiply(i).mod(h);var g = d.multiply(d).multiply(d).add(f.multiply(d)).add(c).mod(h);return e.equals(g);\n};ECPointFp.prototype.toString = function () {\n  return \"(\" + this.getX().toBigInteger().toString() + \",\" + this.getY().toBigInteger().toString() + \")\";\n};ECPointFp.prototype.validate = function () {\n  var c = this.curve.getQ();if (this.isInfinity()) {\n    throw new Error(\"Point is at infinity.\");\n  }var a = this.getX().toBigInteger();var b = this.getY().toBigInteger();if (a.compareTo(BigInteger.ONE) < 0 || a.compareTo(c.subtract(BigInteger.ONE)) > 0) {\n    throw new Error(\"x coordinate out of bounds\");\n  }if (b.compareTo(BigInteger.ONE) < 0 || b.compareTo(c.subtract(BigInteger.ONE)) > 0) {\n    throw new Error(\"y coordinate out of bounds\");\n  }if (!this.isOnCurve()) {\n    throw new Error(\"Point is not on the curve.\");\n  }if (this.multiply(c).isInfinity()) {\n    throw new Error(\"Point is not a scalar multiple of G.\");\n  }return true;\n};\n/*! Mike Samuel (c) 2009 | code.google.com/p/json-sans-eval\n */\nvar jsonParse = function () {\n  var e = \"(?:-?\\\\b(?:0|[1-9][0-9]*)(?:\\\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\\\b)\";var j = '(?:[^\\\\0-\\\\x08\\\\x0a-\\\\x1f\"\\\\\\\\]|\\\\\\\\(?:[\"/\\\\\\\\bfnrt]|u[0-9A-Fa-f]{4}))';var i = '(?:\"' + j + '*\")';var d = new RegExp(\"(?:false|true|null|[\\\\{\\\\}\\\\[\\\\]]|\" + e + \"|\" + i + \")\", \"g\");var k = new RegExp(\"\\\\\\\\(?:([^u])|u(.{4}))\", \"g\");var g = { '\"': '\"', \"/\": \"/\", \"\\\\\": \"\\\\\", b: \"\\b\", f: \"\\f\", n: \"\\n\", r: \"\\r\", t: \"\\t\" };function h(l, m, n) {\n    return m ? g[m] : String.fromCharCode(parseInt(n, 16));\n  }var c = new String(\"\");var a = \"\\\\\";var f = { \"{\": Object, \"[\": Array };var b = Object.hasOwnProperty;return function (u, q) {\n    var p = u.match(d);var x;var v = p[0];var l = false;if (\"{\" === v) {\n      x = {};\n    } else {\n      if (\"[\" === v) {\n        x = [];\n      } else {\n        x = [];l = true;\n      }\n    }var t;var r = [x];for (var o = 1 - l, m = p.length; o < m; ++o) {\n      v = p[o];var w;switch (v.charCodeAt(0)) {default:\n          w = r[0];w[t || w.length] = +v;t = void 0;break;case 34:\n          v = v.substring(1, v.length - 1);if (v.indexOf(a) !== -1) {\n            v = v.replace(k, h);\n          }w = r[0];if (!t) {\n            if (w instanceof Array) {\n              t = w.length;\n            } else {\n              t = v || c;break;\n            }\n          }w[t] = v;t = void 0;break;case 91:\n          w = r[0];r.unshift(w[t || w.length] = []);t = void 0;break;case 93:\n          r.shift();break;case 102:\n          w = r[0];w[t || w.length] = false;t = void 0;break;case 110:\n          w = r[0];w[t || w.length] = null;t = void 0;break;case 116:\n          w = r[0];w[t || w.length] = true;t = void 0;break;case 123:\n          w = r[0];r.unshift(w[t || w.length] = {});t = void 0;break;case 125:\n          r.shift();break;}\n    }if (l) {\n      if (r.length !== 1) {\n        throw new Error();\n      }x = x[0];\n    } else {\n      if (r.length) {\n        throw new Error();\n      }\n    }if (q) {\n      var s = function s(C, B) {\n        var D = C[B];if (D && (typeof D === \"undefined\" ? \"undefined\" : _typeof(D)) === \"object\") {\n          var n = null;for (var z in D) {\n            if (b.call(D, z) && D !== C) {\n              var y = s(D, z);if (y !== void 0) {\n                D[z] = y;\n              } else {\n                if (!n) {\n                  n = [];\n                }n.push(z);\n              }\n            }\n          }if (n) {\n            for (var A = n.length; --A >= 0;) {\n              delete D[n[A]];\n            }\n          }\n        }return q.call(C, B, D);\n      };x = s({ \"\": x }, \"\");\n    }return x;\n  };\n}();\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1) {\n  KJUR.asn1 = {};\n}KJUR.asn1.ASN1Util = new function () {\n  this.integerToByteHex = function (a) {\n    var b = a.toString(16);if (b.length % 2 == 1) {\n      b = \"0\" + b;\n    }return b;\n  };this.bigIntToMinTwosComplementsHex = function (j) {\n    var f = j.toString(16);if (f.substr(0, 1) != \"-\") {\n      if (f.length % 2 == 1) {\n        f = \"0\" + f;\n      } else {\n        if (!f.match(/^[0-7]/)) {\n          f = \"00\" + f;\n        }\n      }\n    } else {\n      var a = f.substr(1);var e = a.length;if (e % 2 == 1) {\n        e += 1;\n      } else {\n        if (!f.match(/^[0-7]/)) {\n          e += 2;\n        }\n      }var g = \"\";for (var d = 0; d < e; d++) {\n        g += \"f\";\n      }var c = new BigInteger(g, 16);var b = c.xor(j).add(BigInteger.ONE);f = b.toString(16).replace(/^-/, \"\");\n    }return f;\n  };this.getPEMStringFromHex = function (a, b) {\n    return hextopem(a, b);\n  };this.newObject = function (k) {\n    var D = KJUR,\n        n = D.asn1,\n        z = n.DERBoolean,\n        e = n.DERInteger,\n        s = n.DERBitString,\n        h = n.DEROctetString,\n        v = n.DERNull,\n        w = n.DERObjectIdentifier,\n        l = n.DEREnumerated,\n        g = n.DERUTF8String,\n        f = n.DERNumericString,\n        y = n.DERPrintableString,\n        u = n.DERTeletexString,\n        p = n.DERIA5String,\n        C = n.DERUTCTime,\n        j = n.DERGeneralizedTime,\n        m = n.DERSequence,\n        c = n.DERSet,\n        r = n.DERTaggedObject,\n        o = n.ASN1Util.newObject;var t = Object.keys(k);if (t.length != 1) {\n      throw \"key of param shall be only one.\";\n    }var F = t[0];if (\":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:\".indexOf(\":\" + F + \":\") == -1) {\n      throw \"undefined key: \" + F;\n    }if (F == \"bool\") {\n      return new z(k[F]);\n    }if (F == \"int\") {\n      return new e(k[F]);\n    }if (F == \"bitstr\") {\n      return new s(k[F]);\n    }if (F == \"octstr\") {\n      return new h(k[F]);\n    }if (F == \"null\") {\n      return new v(k[F]);\n    }if (F == \"oid\") {\n      return new w(k[F]);\n    }if (F == \"enum\") {\n      return new l(k[F]);\n    }if (F == \"utf8str\") {\n      return new g(k[F]);\n    }if (F == \"numstr\") {\n      return new f(k[F]);\n    }if (F == \"prnstr\") {\n      return new y(k[F]);\n    }if (F == \"telstr\") {\n      return new u(k[F]);\n    }if (F == \"ia5str\") {\n      return new p(k[F]);\n    }if (F == \"utctime\") {\n      return new C(k[F]);\n    }if (F == \"gentime\") {\n      return new j(k[F]);\n    }if (F == \"seq\") {\n      var d = k[F];var E = [];for (var x = 0; x < d.length; x++) {\n        var B = o(d[x]);E.push(B);\n      }return new m({ array: E });\n    }if (F == \"set\") {\n      var d = k[F];var E = [];for (var x = 0; x < d.length; x++) {\n        var B = o(d[x]);E.push(B);\n      }return new c({ array: E });\n    }if (F == \"tag\") {\n      var A = k[F];if (Object.prototype.toString.call(A) === \"[object Array]\" && A.length == 3) {\n        var q = o(A[2]);return new r({ tag: A[0], explicit: A[1], obj: q });\n      } else {\n        var b = {};if (A.explicit !== undefined) {\n          b.explicit = A.explicit;\n        }if (A.tag !== undefined) {\n          b.tag = A.tag;\n        }if (A.obj === undefined) {\n          throw \"obj shall be specified for 'tag'.\";\n        }b.obj = o(A.obj);return new r(b);\n      }\n    }\n  };this.jsonToASN1HEX = function (b) {\n    var a = this.newObject(b);return a.getEncodedHex();\n  };\n}();KJUR.asn1.ASN1Util.oidHexToInt = function (a) {\n  var j = \"\";var k = parseInt(a.substr(0, 2), 16);var d = Math.floor(k / 40);var c = k % 40;var j = d + \".\" + c;var e = \"\";for (var f = 2; f < a.length; f += 2) {\n    var g = parseInt(a.substr(f, 2), 16);var h = (\"00000000\" + g.toString(2)).slice(-8);e = e + h.substr(1, 7);if (h.substr(0, 1) == \"0\") {\n      var b = new BigInteger(e, 2);j = j + \".\" + b.toString(10);e = \"\";\n    }\n  }return j;\n};KJUR.asn1.ASN1Util.oidIntToHex = function (f) {\n  var e = function e(a) {\n    var k = a.toString(16);if (k.length == 1) {\n      k = \"0\" + k;\n    }return k;\n  };var d = function d(o) {\n    var n = \"\";var k = new BigInteger(o, 10);var a = k.toString(2);var l = 7 - a.length % 7;if (l == 7) {\n      l = 0;\n    }var q = \"\";for (var m = 0; m < l; m++) {\n      q += \"0\";\n    }a = q + a;for (var m = 0; m < a.length - 1; m += 7) {\n      var p = a.substr(m, 7);if (m != a.length - 7) {\n        p = \"1\" + p;\n      }n += e(parseInt(p, 2));\n    }return n;\n  };if (!f.match(/^[0-9.]+$/)) {\n    throw \"malformed oid string: \" + f;\n  }var g = \"\";var b = f.split(\".\");var j = parseInt(b[0]) * 40 + parseInt(b[1]);g += e(j);b.splice(0, 2);for (var c = 0; c < b.length; c++) {\n    g += d(b[c]);\n  }return g;\n};KJUR.asn1.ASN1Object = function () {\n  var c = true;var b = null;var d = \"00\";var e = \"00\";var a = \"\";this.getLengthHexFromValue = function () {\n    if (typeof this.hV == \"undefined\" || this.hV == null) {\n      throw \"this.hV is null or undefined.\";\n    }if (this.hV.length % 2 == 1) {\n      throw \"value hex must be even length: n=\" + a.length + \",v=\" + this.hV;\n    }var i = this.hV.length / 2;var h = i.toString(16);if (h.length % 2 == 1) {\n      h = \"0\" + h;\n    }if (i < 128) {\n      return h;\n    } else {\n      var g = h.length / 2;if (g > 15) {\n        throw \"ASN.1 length too long to represent by 8x: n = \" + i.toString(16);\n      }var f = 128 + g;return f.toString(16) + h;\n    }\n  };this.getEncodedHex = function () {\n    if (this.hTLV == null || this.isModified) {\n      this.hV = this.getFreshValueHex();this.hL = this.getLengthHexFromValue();this.hTLV = this.hT + this.hL + this.hV;this.isModified = false;\n    }return this.hTLV;\n  };this.getValueHex = function () {\n    this.getEncodedHex();return this.hV;\n  };this.getFreshValueHex = function () {\n    return \"\";\n  };\n};KJUR.asn1.DERAbstractString = function (c) {\n  KJUR.asn1.DERAbstractString.superclass.constructor.call(this);var b = null;var a = null;this.getString = function () {\n    return this.s;\n  };this.setString = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = d;this.hV = utf8tohex(this.s).toLowerCase();\n  };this.setStringHex = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = null;this.hV = d;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof c != \"undefined\") {\n    if (typeof c == \"string\") {\n      this.setString(c);\n    } else {\n      if (typeof c.str != \"undefined\") {\n        this.setString(c.str);\n      } else {\n        if (typeof c.hex != \"undefined\") {\n          this.setStringHex(c.hex);\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);KJUR.asn1.DERAbstractTime = function (c) {\n  KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);var b = null;var a = null;this.localDateToUTC = function (f) {\n    utc = f.getTime() + f.getTimezoneOffset() * 60000;var e = new Date(utc);return e;\n  };this.formatDate = function (m, o, e) {\n    var g = this.zeroPadding;var n = this.localDateToUTC(m);var p = String(n.getFullYear());if (o == \"utc\") {\n      p = p.substr(2, 2);\n    }var l = g(String(n.getMonth() + 1), 2);var q = g(String(n.getDate()), 2);var h = g(String(n.getHours()), 2);var i = g(String(n.getMinutes()), 2);var j = g(String(n.getSeconds()), 2);var r = p + l + q + h + i + j;if (e === true) {\n      var f = n.getMilliseconds();if (f != 0) {\n        var k = g(String(f), 3);k = k.replace(/[0]+$/, \"\");r = r + \".\" + k;\n      }\n    }return r + \"Z\";\n  };this.zeroPadding = function (e, d) {\n    if (e.length >= d) {\n      return e;\n    }return new Array(d - e.length + 1).join(\"0\") + e;\n  };this.getString = function () {\n    return this.s;\n  };this.setString = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = d;this.hV = stohex(d);\n  };this.setByDateValue = function (h, j, e, d, f, g) {\n    var i = new Date(Date.UTC(h, j - 1, e, d, f, g, 0));this.setByDate(i);\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);KJUR.asn1.DERAbstractStructured = function (b) {\n  KJUR.asn1.DERAbstractString.superclass.constructor.call(this);var a = null;this.setByASN1ObjectArray = function (c) {\n    this.hTLV = null;this.isModified = true;this.asn1Array = c;\n  };this.appendASN1Object = function (c) {\n    this.hTLV = null;this.isModified = true;this.asn1Array.push(c);\n  };this.asn1Array = new Array();if (typeof b != \"undefined\") {\n    if (typeof b.array != \"undefined\") {\n      this.asn1Array = b.array;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);KJUR.asn1.DERBoolean = function () {\n  KJUR.asn1.DERBoolean.superclass.constructor.call(this);this.hT = \"01\";this.hTLV = \"0101ff\";\n};YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);KJUR.asn1.DERInteger = function (a) {\n  KJUR.asn1.DERInteger.superclass.constructor.call(this);this.hT = \"02\";this.setByBigInteger = function (b) {\n    this.hTLV = null;this.isModified = true;this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(b);\n  };this.setByInteger = function (c) {\n    var b = new BigInteger(String(c), 10);this.setByBigInteger(b);\n  };this.setValueHex = function (b) {\n    this.hV = b;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.bigint != \"undefined\") {\n      this.setByBigInteger(a.bigint);\n    } else {\n      if (typeof a[\"int\"] != \"undefined\") {\n        this.setByInteger(a[\"int\"]);\n      } else {\n        if (typeof a == \"number\") {\n          this.setByInteger(a);\n        } else {\n          if (typeof a.hex != \"undefined\") {\n            this.setValueHex(a.hex);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);KJUR.asn1.DERBitString = function (b) {\n  if (b !== undefined && typeof b.obj !== \"undefined\") {\n    var a = KJUR.asn1.ASN1Util.newObject(b.obj);b.hex = \"00\" + a.getEncodedHex();\n  }KJUR.asn1.DERBitString.superclass.constructor.call(this);this.hT = \"03\";this.setHexValueIncludingUnusedBits = function (c) {\n    this.hTLV = null;this.isModified = true;this.hV = c;\n  };this.setUnusedBitsAndHexValue = function (c, e) {\n    if (c < 0 || 7 < c) {\n      throw \"unused bits shall be from 0 to 7: u = \" + c;\n    }var d = \"0\" + c;this.hTLV = null;this.isModified = true;this.hV = d + e;\n  };this.setByBinaryString = function (e) {\n    e = e.replace(/0+$/, \"\");var f = 8 - e.length % 8;if (f == 8) {\n      f = 0;\n    }for (var g = 0; g <= f; g++) {\n      e += \"0\";\n    }var j = \"\";for (var g = 0; g < e.length - 1; g += 8) {\n      var d = e.substr(g, 8);var c = parseInt(d, 2).toString(16);if (c.length == 1) {\n        c = \"0\" + c;\n      }j += c;\n    }this.hTLV = null;this.isModified = true;this.hV = \"0\" + f + j;\n  };this.setByBooleanArray = function (e) {\n    var d = \"\";for (var c = 0; c < e.length; c++) {\n      if (e[c] == true) {\n        d += \"1\";\n      } else {\n        d += \"0\";\n      }\n    }this.setByBinaryString(d);\n  };this.newFalseArray = function (e) {\n    var c = new Array(e);for (var d = 0; d < e; d++) {\n      c[d] = false;\n    }return c;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof b != \"undefined\") {\n    if (typeof b == \"string\" && b.toLowerCase().match(/^[0-9a-f]+$/)) {\n      this.setHexValueIncludingUnusedBits(b);\n    } else {\n      if (typeof b.hex != \"undefined\") {\n        this.setHexValueIncludingUnusedBits(b.hex);\n      } else {\n        if (typeof b.bin != \"undefined\") {\n          this.setByBinaryString(b.bin);\n        } else {\n          if (typeof b.array != \"undefined\") {\n            this.setByBooleanArray(b.array);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);KJUR.asn1.DEROctetString = function (b) {\n  if (b !== undefined && typeof b.obj !== \"undefined\") {\n    var a = KJUR.asn1.ASN1Util.newObject(b.obj);b.hex = a.getEncodedHex();\n  }KJUR.asn1.DEROctetString.superclass.constructor.call(this, b);this.hT = \"04\";\n};YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERNull = function () {\n  KJUR.asn1.DERNull.superclass.constructor.call(this);this.hT = \"05\";this.hTLV = \"0500\";\n};YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);KJUR.asn1.DERObjectIdentifier = function (c) {\n  var b = function b(d) {\n    var e = d.toString(16);if (e.length == 1) {\n      e = \"0\" + e;\n    }return e;\n  };var a = function a(k) {\n    var j = \"\";var e = new BigInteger(k, 10);var d = e.toString(2);var f = 7 - d.length % 7;if (f == 7) {\n      f = 0;\n    }var m = \"\";for (var g = 0; g < f; g++) {\n      m += \"0\";\n    }d = m + d;for (var g = 0; g < d.length - 1; g += 7) {\n      var l = d.substr(g, 7);if (g != d.length - 7) {\n        l = \"1\" + l;\n      }j += b(parseInt(l, 2));\n    }return j;\n  };KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);this.hT = \"06\";this.setValueHex = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = null;this.hV = d;\n  };this.setValueOidString = function (f) {\n    if (!f.match(/^[0-9.]+$/)) {\n      throw \"malformed oid string: \" + f;\n    }var g = \"\";var d = f.split(\".\");var j = parseInt(d[0]) * 40 + parseInt(d[1]);g += b(j);d.splice(0, 2);for (var e = 0; e < d.length; e++) {\n      g += a(d[e]);\n    }this.hTLV = null;this.isModified = true;this.s = null;this.hV = g;\n  };this.setValueName = function (e) {\n    var d = KJUR.asn1.x509.OID.name2oid(e);if (d !== \"\") {\n      this.setValueOidString(d);\n    } else {\n      throw \"DERObjectIdentifier oidName undefined: \" + e;\n    }\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (c !== undefined) {\n    if (typeof c === \"string\") {\n      if (c.match(/^[0-2].[0-9.]+$/)) {\n        this.setValueOidString(c);\n      } else {\n        this.setValueName(c);\n      }\n    } else {\n      if (c.oid !== undefined) {\n        this.setValueOidString(c.oid);\n      } else {\n        if (c.hex !== undefined) {\n          this.setValueHex(c.hex);\n        } else {\n          if (c.name !== undefined) {\n            this.setValueName(c.name);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);KJUR.asn1.DEREnumerated = function (a) {\n  KJUR.asn1.DEREnumerated.superclass.constructor.call(this);this.hT = \"0a\";this.setByBigInteger = function (b) {\n    this.hTLV = null;this.isModified = true;this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(b);\n  };this.setByInteger = function (c) {\n    var b = new BigInteger(String(c), 10);this.setByBigInteger(b);\n  };this.setValueHex = function (b) {\n    this.hV = b;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a[\"int\"] != \"undefined\") {\n      this.setByInteger(a[\"int\"]);\n    } else {\n      if (typeof a == \"number\") {\n        this.setByInteger(a);\n      } else {\n        if (typeof a.hex != \"undefined\") {\n          this.setValueHex(a.hex);\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);KJUR.asn1.DERUTF8String = function (a) {\n  KJUR.asn1.DERUTF8String.superclass.constructor.call(this, a);this.hT = \"0c\";\n};YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);KJUR.asn1.DERNumericString = function (a) {\n  KJUR.asn1.DERNumericString.superclass.constructor.call(this, a);this.hT = \"12\";\n};YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERPrintableString = function (a) {\n  KJUR.asn1.DERPrintableString.superclass.constructor.call(this, a);this.hT = \"13\";\n};YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERTeletexString = function (a) {\n  KJUR.asn1.DERTeletexString.superclass.constructor.call(this, a);this.hT = \"14\";\n};YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERIA5String = function (a) {\n  KJUR.asn1.DERIA5String.superclass.constructor.call(this, a);this.hT = \"16\";\n};YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);KJUR.asn1.DERUTCTime = function (a) {\n  KJUR.asn1.DERUTCTime.superclass.constructor.call(this, a);this.hT = \"17\";this.setByDate = function (b) {\n    this.hTLV = null;this.isModified = true;this.date = b;this.s = this.formatDate(this.date, \"utc\");this.hV = stohex(this.s);\n  };this.getFreshValueHex = function () {\n    if (typeof this.date == \"undefined\" && typeof this.s == \"undefined\") {\n      this.date = new Date();this.s = this.formatDate(this.date, \"utc\");this.hV = stohex(this.s);\n    }return this.hV;\n  };if (a !== undefined) {\n    if (a.str !== undefined) {\n      this.setString(a.str);\n    } else {\n      if (typeof a == \"string\" && a.match(/^[0-9]{12}Z$/)) {\n        this.setString(a);\n      } else {\n        if (a.hex !== undefined) {\n          this.setStringHex(a.hex);\n        } else {\n          if (a.date !== undefined) {\n            this.setByDate(a.date);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);KJUR.asn1.DERGeneralizedTime = function (a) {\n  KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, a);this.hT = \"18\";this.withMillis = false;this.setByDate = function (b) {\n    this.hTLV = null;this.isModified = true;this.date = b;this.s = this.formatDate(this.date, \"gen\", this.withMillis);this.hV = stohex(this.s);\n  };this.getFreshValueHex = function () {\n    if (this.date === undefined && this.s === undefined) {\n      this.date = new Date();this.s = this.formatDate(this.date, \"gen\", this.withMillis);this.hV = stohex(this.s);\n    }return this.hV;\n  };if (a !== undefined) {\n    if (a.str !== undefined) {\n      this.setString(a.str);\n    } else {\n      if (typeof a == \"string\" && a.match(/^[0-9]{14}Z$/)) {\n        this.setString(a);\n      } else {\n        if (a.hex !== undefined) {\n          this.setStringHex(a.hex);\n        } else {\n          if (a.date !== undefined) {\n            this.setByDate(a.date);\n          }\n        }\n      }\n    }if (a.millis === true) {\n      this.withMillis = true;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);KJUR.asn1.DERSequence = function (a) {\n  KJUR.asn1.DERSequence.superclass.constructor.call(this, a);this.hT = \"30\";this.getFreshValueHex = function () {\n    var c = \"\";for (var b = 0; b < this.asn1Array.length; b++) {\n      var d = this.asn1Array[b];c += d.getEncodedHex();\n    }this.hV = c;return this.hV;\n  };\n};YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);KJUR.asn1.DERSet = function (a) {\n  KJUR.asn1.DERSet.superclass.constructor.call(this, a);this.hT = \"31\";this.sortFlag = true;this.getFreshValueHex = function () {\n    var b = new Array();for (var c = 0; c < this.asn1Array.length; c++) {\n      var d = this.asn1Array[c];b.push(d.getEncodedHex());\n    }if (this.sortFlag == true) {\n      b.sort();\n    }this.hV = b.join(\"\");return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.sortflag != \"undefined\" && a.sortflag == false) {\n      this.sortFlag = false;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);KJUR.asn1.DERTaggedObject = function (a) {\n  KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);this.hT = \"a0\";this.hV = \"\";this.isExplicit = true;this.asn1Object = null;this.setASN1Object = function (b, c, d) {\n    this.hT = c;this.isExplicit = b;this.asn1Object = d;if (this.isExplicit) {\n      this.hV = this.asn1Object.getEncodedHex();this.hTLV = null;this.isModified = true;\n    } else {\n      this.hV = null;this.hTLV = d.getEncodedHex();this.hTLV = this.hTLV.replace(/^../, c);this.isModified = false;\n    }\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.tag != \"undefined\") {\n      this.hT = a.tag;\n    }if (typeof a.explicit != \"undefined\") {\n      this.isExplicit = a.explicit;\n    }if (typeof a.obj != \"undefined\") {\n      this.asn1Object = a.obj;this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);\nvar ASN1HEX = new function () {}();ASN1HEX.getLblen = function (c, a) {\n  if (c.substr(a + 2, 1) != \"8\") {\n    return 1;\n  }var b = parseInt(c.substr(a + 3, 1));if (b == 0) {\n    return -1;\n  }if (0 < b && b < 10) {\n    return b + 1;\n  }return -2;\n};ASN1HEX.getL = function (c, b) {\n  var a = ASN1HEX.getLblen(c, b);if (a < 1) {\n    return \"\";\n  }return c.substr(b + 2, a * 2);\n};ASN1HEX.getVblen = function (d, a) {\n  var c, b;c = ASN1HEX.getL(d, a);if (c == \"\") {\n    return -1;\n  }if (c.substr(0, 1) === \"8\") {\n    b = new BigInteger(c.substr(2), 16);\n  } else {\n    b = new BigInteger(c, 16);\n  }return b.intValue();\n};ASN1HEX.getVidx = function (c, b) {\n  var a = ASN1HEX.getLblen(c, b);if (a < 0) {\n    return a;\n  }return b + (a + 1) * 2;\n};ASN1HEX.getV = function (d, a) {\n  var c = ASN1HEX.getVidx(d, a);var b = ASN1HEX.getVblen(d, a);return d.substr(c, b * 2);\n};ASN1HEX.getTLV = function (b, a) {\n  return b.substr(a, 2) + ASN1HEX.getL(b, a) + ASN1HEX.getV(b, a);\n};ASN1HEX.getNextSiblingIdx = function (d, a) {\n  var c = ASN1HEX.getVidx(d, a);var b = ASN1HEX.getVblen(d, a);return c + b * 2;\n};ASN1HEX.getChildIdx = function (e, f) {\n  var j = ASN1HEX;var g = new Array();var i = j.getVidx(e, f);if (e.substr(f, 2) == \"03\") {\n    g.push(i + 2);\n  } else {\n    g.push(i);\n  }var l = j.getVblen(e, f);var c = i;var d = 0;while (1) {\n    var b = j.getNextSiblingIdx(e, c);if (b == null || b - i >= l * 2) {\n      break;\n    }if (d >= 200) {\n      break;\n    }g.push(b);c = b;d++;\n  }return g;\n};ASN1HEX.getNthChildIdx = function (d, b, e) {\n  var c = ASN1HEX.getChildIdx(d, b);return c[e];\n};ASN1HEX.getIdxbyList = function (e, d, c, i) {\n  var g = ASN1HEX;var f, b;if (c.length == 0) {\n    if (i !== undefined) {\n      if (e.substr(d, 2) !== i) {\n        throw \"checking tag doesn't match: \" + e.substr(d, 2) + \"!=\" + i;\n      }\n    }return d;\n  }f = c.shift();b = g.getChildIdx(e, d);return g.getIdxbyList(e, b[f], c, i);\n};ASN1HEX.getTLVbyList = function (d, c, b, f) {\n  var e = ASN1HEX;var a = e.getIdxbyList(d, c, b);if (a === undefined) {\n    throw \"can't find nthList object\";\n  }if (f !== undefined) {\n    if (d.substr(a, 2) != f) {\n      throw \"checking tag doesn't match: \" + d.substr(a, 2) + \"!=\" + f;\n    }\n  }return e.getTLV(d, a);\n};ASN1HEX.getVbyList = function (e, c, b, g, i) {\n  var f = ASN1HEX;var a, d;a = f.getIdxbyList(e, c, b, g);if (a === undefined) {\n    throw \"can't find nthList object\";\n  }d = f.getV(e, a);if (i === true) {\n    d = d.substr(2);\n  }return d;\n};ASN1HEX.hextooidstr = function (e) {\n  var h = function h(b, a) {\n    if (b.length >= a) {\n      return b;\n    }return new Array(a - b.length + 1).join(\"0\") + b;\n  };var l = [];var o = e.substr(0, 2);var f = parseInt(o, 16);l[0] = new String(Math.floor(f / 40));l[1] = new String(f % 40);var m = e.substr(2);var k = [];for (var g = 0; g < m.length / 2; g++) {\n    k.push(parseInt(m.substr(g * 2, 2), 16));\n  }var j = [];var d = \"\";for (var g = 0; g < k.length; g++) {\n    if (k[g] & 128) {\n      d = d + h((k[g] & 127).toString(2), 7);\n    } else {\n      d = d + h((k[g] & 127).toString(2), 7);j.push(new String(parseInt(d, 2)));d = \"\";\n    }\n  }var n = l.join(\".\");if (j.length > 0) {\n    n = n + \".\" + j.join(\".\");\n  }return n;\n};ASN1HEX.dump = function (t, c, l, g) {\n  var p = ASN1HEX;var j = p.getV;var y = p.dump;var w = p.getChildIdx;var e = t;if (t instanceof KJUR.asn1.ASN1Object) {\n    e = t.getEncodedHex();\n  }var q = function q(A, i) {\n    if (A.length <= i * 2) {\n      return A;\n    } else {\n      var v = A.substr(0, i) + \"..(total \" + A.length / 2 + \"bytes)..\" + A.substr(A.length - i, i);return v;\n    }\n  };if (c === undefined) {\n    c = { ommit_long_octet: 32 };\n  }if (l === undefined) {\n    l = 0;\n  }if (g === undefined) {\n    g = \"\";\n  }var x = c.ommit_long_octet;if (e.substr(l, 2) == \"01\") {\n    var h = j(e, l);if (h == \"00\") {\n      return g + \"BOOLEAN FALSE\\n\";\n    } else {\n      return g + \"BOOLEAN TRUE\\n\";\n    }\n  }if (e.substr(l, 2) == \"02\") {\n    var h = j(e, l);return g + \"INTEGER \" + q(h, x) + \"\\n\";\n  }if (e.substr(l, 2) == \"03\") {\n    var h = j(e, l);return g + \"BITSTRING \" + q(h, x) + \"\\n\";\n  }if (e.substr(l, 2) == \"04\") {\n    var h = j(e, l);if (p.isASN1HEX(h)) {\n      var k = g + \"OCTETSTRING, encapsulates\\n\";k = k + y(h, c, 0, g + \"  \");return k;\n    } else {\n      return g + \"OCTETSTRING \" + q(h, x) + \"\\n\";\n    }\n  }if (e.substr(l, 2) == \"05\") {\n    return g + \"NULL\\n\";\n  }if (e.substr(l, 2) == \"06\") {\n    var m = j(e, l);var a = KJUR.asn1.ASN1Util.oidHexToInt(m);var o = KJUR.asn1.x509.OID.oid2name(a);var b = a.replace(/\\./g, \" \");if (o != \"\") {\n      return g + \"ObjectIdentifier \" + o + \" (\" + b + \")\\n\";\n    } else {\n      return g + \"ObjectIdentifier (\" + b + \")\\n\";\n    }\n  }if (e.substr(l, 2) == \"0c\") {\n    return g + \"UTF8String '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"13\") {\n    return g + \"PrintableString '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"14\") {\n    return g + \"TeletexString '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"16\") {\n    return g + \"IA5String '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"17\") {\n    return g + \"UTCTime \" + hextoutf8(j(e, l)) + \"\\n\";\n  }if (e.substr(l, 2) == \"18\") {\n    return g + \"GeneralizedTime \" + hextoutf8(j(e, l)) + \"\\n\";\n  }if (e.substr(l, 2) == \"30\") {\n    if (e.substr(l, 4) == \"3000\") {\n      return g + \"SEQUENCE {}\\n\";\n    }var k = g + \"SEQUENCE\\n\";var d = w(e, l);var f = c;if ((d.length == 2 || d.length == 3) && e.substr(d[0], 2) == \"06\" && e.substr(d[d.length - 1], 2) == \"04\") {\n      var o = p.oidname(j(e, d[0]));var r = JSON.parse(JSON.stringify(c));r.x509ExtName = o;f = r;\n    }for (var u = 0; u < d.length; u++) {\n      k = k + y(e, f, d[u], g + \"  \");\n    }return k;\n  }if (e.substr(l, 2) == \"31\") {\n    var k = g + \"SET\\n\";var d = w(e, l);for (var u = 0; u < d.length; u++) {\n      k = k + y(e, c, d[u], g + \"  \");\n    }return k;\n  }var z = parseInt(e.substr(l, 2), 16);if ((z & 128) != 0) {\n    var n = z & 31;if ((z & 32) != 0) {\n      var k = g + \"[\" + n + \"]\\n\";var d = w(e, l);for (var u = 0; u < d.length; u++) {\n        k = k + y(e, c, d[u], g + \"  \");\n      }return k;\n    } else {\n      var h = j(e, l);if (h.substr(0, 8) == \"68747470\") {\n        h = hextoutf8(h);\n      }if (c.x509ExtName === \"subjectAltName\" && n == 2) {\n        h = hextoutf8(h);\n      }var k = g + \"[\" + n + \"] \" + h + \"\\n\";return k;\n    }\n  }return g + \"UNKNOWN(\" + e.substr(l, 2) + \") \" + j(e, l) + \"\\n\";\n};ASN1HEX.isASN1HEX = function (e) {\n  var d = ASN1HEX;if (e.length % 2 == 1) {\n    return false;\n  }var c = d.getVblen(e, 0);var b = e.substr(0, 2);var f = d.getL(e, 0);var a = e.length - b.length - f.length;if (a == c * 2) {\n    return true;\n  }return false;\n};ASN1HEX.oidname = function (a) {\n  var c = KJUR.asn1;if (KJUR.lang.String.isHex(a)) {\n    a = c.ASN1Util.oidHexToInt(a);\n  }var b = c.x509.OID.oid2name(a);if (b === \"\") {\n    b = a;\n  }return b;\n};\nvar KJUR;if (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.lang == \"undefined\" || !KJUR.lang) {\n  KJUR.lang = {};\n}KJUR.lang.String = function () {};function Base64x() {}function stoBA(d) {\n  var b = new Array();for (var c = 0; c < d.length; c++) {\n    b[c] = d.charCodeAt(c);\n  }return b;\n}function BAtos(b) {\n  var d = \"\";for (var c = 0; c < b.length; c++) {\n    d = d + String.fromCharCode(b[c]);\n  }return d;\n}function BAtohex(b) {\n  var e = \"\";for (var d = 0; d < b.length; d++) {\n    var c = b[d].toString(16);if (c.length == 1) {\n      c = \"0\" + c;\n    }e = e + c;\n  }return e;\n}function stohex(a) {\n  return BAtohex(stoBA(a));\n}function stob64(a) {\n  return hex2b64(stohex(a));\n}function stob64u(a) {\n  return b64tob64u(hex2b64(stohex(a)));\n}function b64utos(a) {\n  return BAtos(b64toBA(b64utob64(a)));\n}function b64tob64u(a) {\n  a = a.replace(/\\=/g, \"\");a = a.replace(/\\+/g, \"-\");a = a.replace(/\\//g, \"_\");return a;\n}function b64utob64(a) {\n  if (a.length % 4 == 2) {\n    a = a + \"==\";\n  } else {\n    if (a.length % 4 == 3) {\n      a = a + \"=\";\n    }\n  }a = a.replace(/-/g, \"+\");a = a.replace(/_/g, \"/\");return a;\n}function hextob64u(a) {\n  if (a.length % 2 == 1) {\n    a = \"0\" + a;\n  }return b64tob64u(hex2b64(a));\n}function b64utohex(a) {\n  return b64tohex(b64utob64(a));\n}var utf8tob64u, b64utoutf8;if (typeof Buffer === \"function\") {\n  exports.utf8tob64u = utf8tob64u = function utf8tob64u(a) {\n    return b64tob64u(new Buffer(a, \"utf8\").toString(\"base64\"));\n  };exports.b64utoutf8 = b64utoutf8 = function b64utoutf8(a) {\n    return new Buffer(b64utob64(a), \"base64\").toString(\"utf8\");\n  };\n} else {\n  exports.utf8tob64u = utf8tob64u = function utf8tob64u(a) {\n    return hextob64u(uricmptohex(encodeURIComponentAll(a)));\n  };exports.b64utoutf8 = b64utoutf8 = function b64utoutf8(a) {\n    return decodeURIComponent(hextouricmp(b64utohex(a)));\n  };\n}function utf8tob64(a) {\n  return hex2b64(uricmptohex(encodeURIComponentAll(a)));\n}function b64toutf8(a) {\n  return decodeURIComponent(hextouricmp(b64tohex(a)));\n}function utf8tohex(a) {\n  return uricmptohex(encodeURIComponentAll(a));\n}function hextoutf8(a) {\n  return decodeURIComponent(hextouricmp(a));\n}function hextorstr(c) {\n  var b = \"\";for (var a = 0; a < c.length - 1; a += 2) {\n    b += String.fromCharCode(parseInt(c.substr(a, 2), 16));\n  }return b;\n}function rstrtohex(c) {\n  var a = \"\";for (var b = 0; b < c.length; b++) {\n    a += (\"0\" + c.charCodeAt(b).toString(16)).slice(-2);\n  }return a;\n}function hextob64(a) {\n  return hex2b64(a);\n}function hextob64nl(b) {\n  var a = hextob64(b);var c = a.replace(/(.{64})/g, \"$1\\r\\n\");c = c.replace(/\\r\\n$/, \"\");return c;\n}function b64nltohex(b) {\n  var a = b.replace(/[^0-9A-Za-z\\/+=]*/g, \"\");var c = b64tohex(a);return c;\n}function hextopem(a, b) {\n  var c = hextob64nl(a);return \"-----BEGIN \" + b + \"-----\\r\\n\" + c + \"\\r\\n-----END \" + b + \"-----\\r\\n\";\n}function pemtohex(a, b) {\n  if (a.indexOf(\"-----BEGIN \") == -1) {\n    throw \"can't find PEM header: \" + b;\n  }if (b !== undefined) {\n    a = a.replace(\"-----BEGIN \" + b + \"-----\", \"\");a = a.replace(\"-----END \" + b + \"-----\", \"\");\n  } else {\n    a = a.replace(/-----BEGIN [^-]+-----/, \"\");a = a.replace(/-----END [^-]+-----/, \"\");\n  }return b64nltohex(a);\n}function hextoArrayBuffer(d) {\n  if (d.length % 2 != 0) {\n    throw \"input is not even length\";\n  }if (d.match(/^[0-9A-Fa-f]+$/) == null) {\n    throw \"input is not hexadecimal\";\n  }var b = new ArrayBuffer(d.length / 2);var a = new DataView(b);for (var c = 0; c < d.length / 2; c++) {\n    a.setUint8(c, parseInt(d.substr(c * 2, 2), 16));\n  }return b;\n}function ArrayBuffertohex(b) {\n  var d = \"\";var a = new DataView(b);for (var c = 0; c < b.byteLength; c++) {\n    d += (\"00\" + a.getUint8(c).toString(16)).slice(-2);\n  }return d;\n}function zulutomsec(n) {\n  var l, j, m, e, f, i, b, k;var a, h, g, c;c = n.match(/^(\\d{2}|\\d{4})(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(|\\.\\d+)Z$/);if (c) {\n    a = c[1];l = parseInt(a);if (a.length === 2) {\n      if (50 <= l && l < 100) {\n        l = 1900 + l;\n      } else {\n        if (0 <= l && l < 50) {\n          l = 2000 + l;\n        }\n      }\n    }j = parseInt(c[2]) - 1;m = parseInt(c[3]);e = parseInt(c[4]);f = parseInt(c[5]);i = parseInt(c[6]);b = 0;h = c[7];if (h !== \"\") {\n      g = (h.substr(1) + \"00\").substr(0, 3);b = parseInt(g);\n    }return Date.UTC(l, j, m, e, f, i, b);\n  }throw \"unsupported zulu format: \" + n;\n}function zulutosec(a) {\n  var b = zulutomsec(a);return ~~(b / 1000);\n}function zulutodate(a) {\n  return new Date(zulutomsec(a));\n}function datetozulu(g, e, f) {\n  var b;var a = g.getUTCFullYear();if (e) {\n    if (a < 1950 || 2049 < a) {\n      throw \"not proper year for UTCTime: \" + a;\n    }b = (\"\" + a).slice(-2);\n  } else {\n    b = (\"000\" + a).slice(-4);\n  }b += (\"0\" + (g.getUTCMonth() + 1)).slice(-2);b += (\"0\" + g.getUTCDate()).slice(-2);b += (\"0\" + g.getUTCHours()).slice(-2);b += (\"0\" + g.getUTCMinutes()).slice(-2);b += (\"0\" + g.getUTCSeconds()).slice(-2);if (f) {\n    var c = g.getUTCMilliseconds();if (c !== 0) {\n      c = (\"00\" + c).slice(-3);c = c.replace(/0+$/g, \"\");b += \".\" + c;\n    }\n  }b += \"Z\";return b;\n}function uricmptohex(a) {\n  return a.replace(/%/g, \"\");\n}function hextouricmp(a) {\n  return a.replace(/(..)/g, \"%$1\");\n}function ipv6tohex(g) {\n  var b = \"malformed IPv6 address\";if (!g.match(/^[0-9A-Fa-f:]+$/)) {\n    throw b;\n  }g = g.toLowerCase();var d = g.split(\":\").length - 1;if (d < 2) {\n    throw b;\n  }var e = \":\".repeat(7 - d + 2);g = g.replace(\"::\", e);var c = g.split(\":\");if (c.length != 8) {\n    throw b;\n  }for (var f = 0; f < 8; f++) {\n    c[f] = (\"0000\" + c[f]).slice(-4);\n  }return c.join(\"\");\n}function hextoipv6(e) {\n  if (!e.match(/^[0-9A-Fa-f]{32}$/)) {\n    throw \"malformed IPv6 address octet\";\n  }e = e.toLowerCase();var b = e.match(/.{1,4}/g);for (var d = 0; d < 8; d++) {\n    b[d] = b[d].replace(/^0+/, \"\");if (b[d] == \"\") {\n      b[d] = \"0\";\n    }\n  }e = \":\" + b.join(\":\") + \":\";var c = e.match(/:(0:){2,}/g);if (c === null) {\n    return e.slice(1, -1);\n  }var f = \"\";for (var d = 0; d < c.length; d++) {\n    if (c[d].length > f.length) {\n      f = c[d];\n    }\n  }e = e.replace(f, \"::\");return e.slice(1, -1);\n}function hextoip(b) {\n  var d = \"malformed hex value\";if (!b.match(/^([0-9A-Fa-f][0-9A-Fa-f]){1,}$/)) {\n    throw d;\n  }if (b.length == 8) {\n    var c;try {\n      c = parseInt(b.substr(0, 2), 16) + \".\" + parseInt(b.substr(2, 2), 16) + \".\" + parseInt(b.substr(4, 2), 16) + \".\" + parseInt(b.substr(6, 2), 16);return c;\n    } catch (a) {\n      throw d;\n    }\n  } else {\n    if (b.length == 32) {\n      return hextoipv6(b);\n    } else {\n      return b;\n    }\n  }\n}function iptohex(f) {\n  var j = \"malformed IP address\";f = f.toLowerCase(f);if (f.match(/^[0-9.]+$/)) {\n    var b = f.split(\".\");if (b.length !== 4) {\n      throw j;\n    }var g = \"\";try {\n      for (var e = 0; e < 4; e++) {\n        var h = parseInt(b[e]);g += (\"0\" + h.toString(16)).slice(-2);\n      }return g;\n    } catch (c) {\n      throw j;\n    }\n  } else {\n    if (f.match(/^[0-9a-f:]+$/) && f.indexOf(\":\") !== -1) {\n      return ipv6tohex(f);\n    } else {\n      throw j;\n    }\n  }\n}function encodeURIComponentAll(a) {\n  var d = encodeURIComponent(a);var b = \"\";for (var c = 0; c < d.length; c++) {\n    if (d[c] == \"%\") {\n      b = b + d.substr(c, 3);c = c + 2;\n    } else {\n      b = b + \"%\" + stohex(d[c]);\n    }\n  }return b;\n}function newline_toUnix(a) {\n  a = a.replace(/\\r\\n/mg, \"\\n\");return a;\n}function newline_toDos(a) {\n  a = a.replace(/\\r\\n/mg, \"\\n\");a = a.replace(/\\n/mg, \"\\r\\n\");return a;\n}KJUR.lang.String.isInteger = function (a) {\n  if (a.match(/^[0-9]+$/)) {\n    return true;\n  } else {\n    if (a.match(/^-[0-9]+$/)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n};KJUR.lang.String.isHex = function (a) {\n  if (a.length % 2 == 0 && (a.match(/^[0-9a-f]+$/) || a.match(/^[0-9A-F]+$/))) {\n    return true;\n  } else {\n    return false;\n  }\n};KJUR.lang.String.isBase64 = function (a) {\n  a = a.replace(/\\s+/g, \"\");if (a.match(/^[0-9A-Za-z+\\/]+={0,3}$/) && a.length % 4 == 0) {\n    return true;\n  } else {\n    return false;\n  }\n};KJUR.lang.String.isBase64URL = function (a) {\n  if (a.match(/[+/=]/)) {\n    return false;\n  }a = b64utob64(a);return KJUR.lang.String.isBase64(a);\n};KJUR.lang.String.isIntegerArray = function (a) {\n  a = a.replace(/\\s+/g, \"\");if (a.match(/^\\[[0-9,]+\\]$/)) {\n    return true;\n  } else {\n    return false;\n  }\n};function hextoposhex(a) {\n  if (a.length % 2 == 1) {\n    return \"0\" + a;\n  }if (a.substr(0, 1) > \"7\") {\n    return \"00\" + a;\n  }return a;\n}function intarystrtohex(b) {\n  b = b.replace(/^\\s*\\[\\s*/, \"\");b = b.replace(/\\s*\\]\\s*$/, \"\");b = b.replace(/\\s*/g, \"\");try {\n    var c = b.split(/,/).map(function (g, e, h) {\n      var f = parseInt(g);if (f < 0 || 255 < f) {\n        throw \"integer not in range 0-255\";\n      }var d = (\"00\" + f.toString(16)).slice(-2);return d;\n    }).join(\"\");return c;\n  } catch (a) {\n    throw \"malformed integer array string: \" + a;\n  }\n}var strdiffidx = function strdiffidx(c, a) {\n  var d = c.length;if (c.length > a.length) {\n    d = a.length;\n  }for (var b = 0; b < d; b++) {\n    if (c.charCodeAt(b) != a.charCodeAt(b)) {\n      return b;\n    }\n  }if (c.length != a.length) {\n    return d;\n  }return -1;\n};\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.Util = new function () {\n  this.DIGESTINFOHEAD = { sha1: \"3021300906052b0e03021a05000414\", sha224: \"302d300d06096086480165030402040500041c\", sha256: \"3031300d060960864801650304020105000420\", sha384: \"3041300d060960864801650304020205000430\", sha512: \"3051300d060960864801650304020305000440\", md2: \"3020300c06082a864886f70d020205000410\", md5: \"3020300c06082a864886f70d020505000410\", ripemd160: \"3021300906052b2403020105000414\" };this.DEFAULTPROVIDER = { md5: \"cryptojs\", sha1: \"cryptojs\", sha224: \"cryptojs\", sha256: \"cryptojs\", sha384: \"cryptojs\", sha512: \"cryptojs\", ripemd160: \"cryptojs\", hmacmd5: \"cryptojs\", hmacsha1: \"cryptojs\", hmacsha224: \"cryptojs\", hmacsha256: \"cryptojs\", hmacsha384: \"cryptojs\", hmacsha512: \"cryptojs\", hmacripemd160: \"cryptojs\", MD5withRSA: \"cryptojs/jsrsa\", SHA1withRSA: \"cryptojs/jsrsa\", SHA224withRSA: \"cryptojs/jsrsa\", SHA256withRSA: \"cryptojs/jsrsa\", SHA384withRSA: \"cryptojs/jsrsa\", SHA512withRSA: \"cryptojs/jsrsa\", RIPEMD160withRSA: \"cryptojs/jsrsa\", MD5withECDSA: \"cryptojs/jsrsa\", SHA1withECDSA: \"cryptojs/jsrsa\", SHA224withECDSA: \"cryptojs/jsrsa\", SHA256withECDSA: \"cryptojs/jsrsa\", SHA384withECDSA: \"cryptojs/jsrsa\", SHA512withECDSA: \"cryptojs/jsrsa\", RIPEMD160withECDSA: \"cryptojs/jsrsa\", SHA1withDSA: \"cryptojs/jsrsa\", SHA224withDSA: \"cryptojs/jsrsa\", SHA256withDSA: \"cryptojs/jsrsa\", MD5withRSAandMGF1: \"cryptojs/jsrsa\", SHA1withRSAandMGF1: \"cryptojs/jsrsa\", SHA224withRSAandMGF1: \"cryptojs/jsrsa\", SHA256withRSAandMGF1: \"cryptojs/jsrsa\", SHA384withRSAandMGF1: \"cryptojs/jsrsa\", SHA512withRSAandMGF1: \"cryptojs/jsrsa\", RIPEMD160withRSAandMGF1: \"cryptojs/jsrsa\" };this.CRYPTOJSMESSAGEDIGESTNAME = { md5: CryptoJS.algo.MD5, sha1: CryptoJS.algo.SHA1, sha224: CryptoJS.algo.SHA224, sha256: CryptoJS.algo.SHA256, sha384: CryptoJS.algo.SHA384, sha512: CryptoJS.algo.SHA512, ripemd160: CryptoJS.algo.RIPEMD160 };this.getDigestInfoHex = function (a, b) {\n    if (typeof this.DIGESTINFOHEAD[b] == \"undefined\") {\n      throw \"alg not supported in Util.DIGESTINFOHEAD: \" + b;\n    }return this.DIGESTINFOHEAD[b] + a;\n  };this.getPaddedDigestInfoHex = function (h, a, j) {\n    var c = this.getDigestInfoHex(h, a);var d = j / 4;if (c.length + 22 > d) {\n      throw \"key is too short for SigAlg: keylen=\" + j + \",\" + a;\n    }var b = \"0001\";var k = \"00\" + c;var g = \"\";var l = d - b.length - k.length;for (var f = 0; f < l; f += 2) {\n      g += \"ff\";\n    }var e = b + g + k;return e;\n  };this.hashString = function (a, c) {\n    var b = new KJUR.crypto.MessageDigest({ alg: c });return b.digestString(a);\n  };this.hashHex = function (b, c) {\n    var a = new KJUR.crypto.MessageDigest({ alg: c });return a.digestHex(b);\n  };this.sha1 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha1\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha256 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha256\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha256Hex = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha256\", prov: \"cryptojs\" });return b.digestHex(a);\n  };this.sha512 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha512\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha512Hex = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha512\", prov: \"cryptojs\" });return b.digestHex(a);\n  };\n}();KJUR.crypto.Util.md5 = function (a) {\n  var b = new KJUR.crypto.MessageDigest({ alg: \"md5\", prov: \"cryptojs\" });return b.digestString(a);\n};KJUR.crypto.Util.ripemd160 = function (a) {\n  var b = new KJUR.crypto.MessageDigest({ alg: \"ripemd160\", prov: \"cryptojs\" });return b.digestString(a);\n};KJUR.crypto.Util.SECURERANDOMGEN = new SecureRandom();KJUR.crypto.Util.getRandomHexOfNbytes = function (b) {\n  var a = new Array(b);KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(a);return BAtohex(a);\n};KJUR.crypto.Util.getRandomBigIntegerOfNbytes = function (a) {\n  return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbytes(a), 16);\n};KJUR.crypto.Util.getRandomHexOfNbits = function (d) {\n  var c = d % 8;var a = (d - c) / 8;var b = new Array(a + 1);KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(b);b[0] = (255 << c & 255 ^ 255) & b[0];return BAtohex(b);\n};KJUR.crypto.Util.getRandomBigIntegerOfNbits = function (a) {\n  return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbits(a), 16);\n};KJUR.crypto.Util.getRandomBigIntegerZeroToMax = function (b) {\n  var a = b.bitLength();while (1) {\n    var c = KJUR.crypto.Util.getRandomBigIntegerOfNbits(a);if (b.compareTo(c) != -1) {\n      return c;\n    }\n  }\n};KJUR.crypto.Util.getRandomBigIntegerMinToMax = function (e, b) {\n  var c = e.compareTo(b);if (c == 1) {\n    throw \"biMin is greater than biMax\";\n  }if (c == 0) {\n    return e;\n  }var a = b.subtract(e);var d = KJUR.crypto.Util.getRandomBigIntegerZeroToMax(a);return d.add(e);\n};KJUR.crypto.MessageDigest = function (c) {\n  var b = null;var a = null;var d = null;this.setAlgAndProvider = function (g, f) {\n    g = KJUR.crypto.MessageDigest.getCanonicalAlgName(g);if (g !== null && f === undefined) {\n      f = KJUR.crypto.Util.DEFAULTPROVIDER[g];\n    }if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(g) != -1 && f == \"cryptojs\") {\n      try {\n        this.md = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[g].create();\n      } catch (e) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + g + \"/\" + e;\n      }this.updateString = function (h) {\n        this.md.update(h);\n      };this.updateHex = function (h) {\n        var i = CryptoJS.enc.Hex.parse(h);this.md.update(i);\n      };this.digest = function () {\n        var h = this.md.finalize();return h.toString(CryptoJS.enc.Hex);\n      };this.digestString = function (h) {\n        this.updateString(h);return this.digest();\n      };this.digestHex = function (h) {\n        this.updateHex(h);return this.digest();\n      };\n    }if (\":sha256:\".indexOf(g) != -1 && f == \"sjcl\") {\n      try {\n        this.md = new sjcl.hash.sha256();\n      } catch (e) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + g + \"/\" + e;\n      }this.updateString = function (h) {\n        this.md.update(h);\n      };this.updateHex = function (i) {\n        var h = sjcl.codec.hex.toBits(i);this.md.update(h);\n      };this.digest = function () {\n        var h = this.md.finalize();return sjcl.codec.hex.fromBits(h);\n      };this.digestString = function (h) {\n        this.updateString(h);return this.digest();\n      };this.digestHex = function (h) {\n        this.updateHex(h);return this.digest();\n      };\n    }\n  };this.updateString = function (e) {\n    throw \"updateString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.updateHex = function (e) {\n    throw \"updateHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digest = function () {\n    throw \"digest() not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digestString = function (e) {\n    throw \"digestString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digestHex = function (e) {\n    throw \"digestHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };if (c !== undefined) {\n    if (c.alg !== undefined) {\n      this.algName = c.alg;if (c.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      }this.setAlgAndProvider(this.algName, this.provName);\n    }\n  }\n};KJUR.crypto.MessageDigest.getCanonicalAlgName = function (a) {\n  if (typeof a === \"string\") {\n    a = a.toLowerCase();a = a.replace(/-/, \"\");\n  }return a;\n};KJUR.crypto.MessageDigest.getHashLength = function (c) {\n  var b = KJUR.crypto.MessageDigest;var a = b.getCanonicalAlgName(c);if (b.HASHLENGTH[a] === undefined) {\n    throw \"not supported algorithm: \" + c;\n  }return b.HASHLENGTH[a];\n};KJUR.crypto.MessageDigest.HASHLENGTH = { md5: 16, sha1: 20, sha224: 28, sha256: 32, sha384: 48, sha512: 64, ripemd160: 20 };KJUR.crypto.Mac = function (d) {\n  var f = null;var c = null;var a = null;var e = null;var b = null;this.setAlgAndProvider = function (k, i) {\n    k = k.toLowerCase();if (k == null) {\n      k = \"hmacsha1\";\n    }k = k.toLowerCase();if (k.substr(0, 4) != \"hmac\") {\n      throw \"setAlgAndProvider unsupported HMAC alg: \" + k;\n    }if (i === undefined) {\n      i = KJUR.crypto.Util.DEFAULTPROVIDER[k];\n    }this.algProv = k + \"/\" + i;var g = k.substr(4);if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(g) != -1 && i == \"cryptojs\") {\n      try {\n        var j = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[g];this.mac = CryptoJS.algo.HMAC.create(j, this.pass);\n      } catch (h) {\n        throw \"setAlgAndProvider hash alg set fail hashAlg=\" + g + \"/\" + h;\n      }this.updateString = function (l) {\n        this.mac.update(l);\n      };this.updateHex = function (l) {\n        var m = CryptoJS.enc.Hex.parse(l);this.mac.update(m);\n      };this.doFinal = function () {\n        var l = this.mac.finalize();return l.toString(CryptoJS.enc.Hex);\n      };this.doFinalString = function (l) {\n        this.updateString(l);return this.doFinal();\n      };this.doFinalHex = function (l) {\n        this.updateHex(l);return this.doFinal();\n      };\n    }\n  };this.updateString = function (g) {\n    throw \"updateString(str) not supported for this alg/prov: \" + this.algProv;\n  };this.updateHex = function (g) {\n    throw \"updateHex(hex) not supported for this alg/prov: \" + this.algProv;\n  };this.doFinal = function () {\n    throw \"digest() not supported for this alg/prov: \" + this.algProv;\n  };this.doFinalString = function (g) {\n    throw \"digestString(str) not supported for this alg/prov: \" + this.algProv;\n  };this.doFinalHex = function (g) {\n    throw \"digestHex(hex) not supported for this alg/prov: \" + this.algProv;\n  };this.setPassword = function (h) {\n    if (typeof h == \"string\") {\n      var g = h;if (h.length % 2 == 1 || !h.match(/^[0-9A-Fa-f]+$/)) {\n        g = rstrtohex(h);\n      }this.pass = CryptoJS.enc.Hex.parse(g);return;\n    }if ((typeof h === \"undefined\" ? \"undefined\" : _typeof(h)) != \"object\") {\n      throw \"KJUR.crypto.Mac unsupported password type: \" + h;\n    }var g = null;if (h.hex !== undefined) {\n      if (h.hex.length % 2 != 0 || !h.hex.match(/^[0-9A-Fa-f]+$/)) {\n        throw \"Mac: wrong hex password: \" + h.hex;\n      }g = h.hex;\n    }if (h.utf8 !== undefined) {\n      g = utf8tohex(h.utf8);\n    }if (h.rstr !== undefined) {\n      g = rstrtohex(h.rstr);\n    }if (h.b64 !== undefined) {\n      g = b64tohex(h.b64);\n    }if (h.b64u !== undefined) {\n      g = b64utohex(h.b64u);\n    }if (g == null) {\n      throw \"KJUR.crypto.Mac unsupported password type: \" + h;\n    }this.pass = CryptoJS.enc.Hex.parse(g);\n  };if (d !== undefined) {\n    if (d.pass !== undefined) {\n      this.setPassword(d.pass);\n    }if (d.alg !== undefined) {\n      this.algName = d.alg;if (d.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      }this.setAlgAndProvider(this.algName, this.provName);\n    }\n  }\n};KJUR.crypto.Signature = function (o) {\n  var q = null;var n = null;var r = null;var c = null;var l = null;var d = null;var k = null;var h = null;var p = null;var e = null;var b = -1;var g = null;var j = null;var a = null;var i = null;var f = null;this._setAlgNames = function () {\n    var s = this.algName.match(/^(.+)with(.+)$/);if (s) {\n      this.mdAlgName = s[1].toLowerCase();this.pubkeyAlgName = s[2].toLowerCase();\n    }\n  };this._zeroPaddingOfSignature = function (x, w) {\n    var v = \"\";var t = w / 4 - x.length;for (var u = 0; u < t; u++) {\n      v = v + \"0\";\n    }return v + x;\n  };this.setAlgAndProvider = function (u, t) {\n    this._setAlgNames();if (t != \"cryptojs/jsrsa\") {\n      throw \"provider not supported: \" + t;\n    }if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(this.mdAlgName) != -1) {\n      try {\n        this.md = new KJUR.crypto.MessageDigest({ alg: this.mdAlgName });\n      } catch (s) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + this.mdAlgName + \"/\" + s;\n      }this.init = function (w, x) {\n        var y = null;try {\n          if (x === undefined) {\n            y = KEYUTIL.getKey(w);\n          } else {\n            y = KEYUTIL.getKey(w, x);\n          }\n        } catch (v) {\n          throw \"init failed:\" + v;\n        }if (y.isPrivate === true) {\n          this.prvKey = y;this.state = \"SIGN\";\n        } else {\n          if (y.isPublic === true) {\n            this.pubKey = y;this.state = \"VERIFY\";\n          } else {\n            throw \"init failed.:\" + y;\n          }\n        }\n      };this.updateString = function (v) {\n        this.md.updateString(v);\n      };this.updateHex = function (v) {\n        this.md.updateHex(v);\n      };this.sign = function () {\n        this.sHashHex = this.md.digest();if (typeof this.ecprvhex != \"undefined\" && typeof this.eccurvename != \"undefined\") {\n          var v = new KJUR.crypto.ECDSA({ curve: this.eccurvename });this.hSign = v.signHex(this.sHashHex, this.ecprvhex);\n        } else {\n          if (this.prvKey instanceof RSAKey && this.pubkeyAlgName === \"rsaandmgf1\") {\n            this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex, this.mdAlgName, this.pssSaltLen);\n          } else {\n            if (this.prvKey instanceof RSAKey && this.pubkeyAlgName === \"rsa\") {\n              this.hSign = this.prvKey.signWithMessageHash(this.sHashHex, this.mdAlgName);\n            } else {\n              if (this.prvKey instanceof KJUR.crypto.ECDSA) {\n                this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n              } else {\n                if (this.prvKey instanceof KJUR.crypto.DSA) {\n                  this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n                } else {\n                  throw \"Signature: unsupported private key alg: \" + this.pubkeyAlgName;\n                }\n              }\n            }\n          }\n        }return this.hSign;\n      };this.signString = function (v) {\n        this.updateString(v);return this.sign();\n      };this.signHex = function (v) {\n        this.updateHex(v);return this.sign();\n      };this.verify = function (v) {\n        this.sHashHex = this.md.digest();if (typeof this.ecpubhex != \"undefined\" && typeof this.eccurvename != \"undefined\") {\n          var w = new KJUR.crypto.ECDSA({ curve: this.eccurvename });return w.verifyHex(this.sHashHex, v, this.ecpubhex);\n        } else {\n          if (this.pubKey instanceof RSAKey && this.pubkeyAlgName === \"rsaandmgf1\") {\n            return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, v, this.mdAlgName, this.pssSaltLen);\n          } else {\n            if (this.pubKey instanceof RSAKey && this.pubkeyAlgName === \"rsa\") {\n              return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n            } else {\n              if (KJUR.crypto.ECDSA !== undefined && this.pubKey instanceof KJUR.crypto.ECDSA) {\n                return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n              } else {\n                if (KJUR.crypto.DSA !== undefined && this.pubKey instanceof KJUR.crypto.DSA) {\n                  return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n                } else {\n                  throw \"Signature: unsupported public key alg: \" + this.pubkeyAlgName;\n                }\n              }\n            }\n          }\n        }\n      };\n    }\n  };this.init = function (s, t) {\n    throw \"init(key, pass) not supported for this alg:prov=\" + this.algProvName;\n  };this.updateString = function (s) {\n    throw \"updateString(str) not supported for this alg:prov=\" + this.algProvName;\n  };this.updateHex = function (s) {\n    throw \"updateHex(hex) not supported for this alg:prov=\" + this.algProvName;\n  };this.sign = function () {\n    throw \"sign() not supported for this alg:prov=\" + this.algProvName;\n  };this.signString = function (s) {\n    throw \"digestString(str) not supported for this alg:prov=\" + this.algProvName;\n  };this.signHex = function (s) {\n    throw \"digestHex(hex) not supported for this alg:prov=\" + this.algProvName;\n  };this.verify = function (s) {\n    throw \"verify(hSigVal) not supported for this alg:prov=\" + this.algProvName;\n  };this.initParams = o;if (o !== undefined) {\n    if (o.alg !== undefined) {\n      this.algName = o.alg;if (o.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      } else {\n        this.provName = o.prov;\n      }this.algProvName = this.algName + \":\" + this.provName;this.setAlgAndProvider(this.algName, this.provName);this._setAlgNames();\n    }if (o.psssaltlen !== undefined) {\n      this.pssSaltLen = o.psssaltlen;\n    }if (o.prvkeypem !== undefined) {\n      if (o.prvkeypas !== undefined) {\n        throw \"both prvkeypem and prvkeypas parameters not supported\";\n      } else {\n        try {\n          var q = KEYUTIL.getKey(o.prvkeypem);this.init(q);\n        } catch (m) {\n          throw \"fatal error to load pem private key: \" + m;\n        }\n      }\n    }\n  }\n};KJUR.crypto.Cipher = function (a) {};KJUR.crypto.Cipher.encrypt = function (e, f, d) {\n  if (f instanceof RSAKey && f.isPublic) {\n    var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);if (c === \"RSA\") {\n      return f.encrypt(e);\n    }if (c === \"RSAOAEP\") {\n      return f.encryptOAEP(e, \"sha1\");\n    }var b = c.match(/^RSAOAEP(\\d+)$/);if (b !== null) {\n      return f.encryptOAEP(e, \"sha\" + b[1]);\n    }throw \"Cipher.encrypt: unsupported algorithm for RSAKey: \" + d;\n  } else {\n    throw \"Cipher.encrypt: unsupported key or algorithm\";\n  }\n};KJUR.crypto.Cipher.decrypt = function (e, f, d) {\n  if (f instanceof RSAKey && f.isPrivate) {\n    var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);if (c === \"RSA\") {\n      return f.decrypt(e);\n    }if (c === \"RSAOAEP\") {\n      return f.decryptOAEP(e, \"sha1\");\n    }var b = c.match(/^RSAOAEP(\\d+)$/);if (b !== null) {\n      return f.decryptOAEP(e, \"sha\" + b[1]);\n    }throw \"Cipher.decrypt: unsupported algorithm for RSAKey: \" + d;\n  } else {\n    throw \"Cipher.decrypt: unsupported key or algorithm\";\n  }\n};KJUR.crypto.Cipher.getAlgByKeyAndName = function (b, a) {\n  if (b instanceof RSAKey) {\n    if (\":RSA:RSAOAEP:RSAOAEP224:RSAOAEP256:RSAOAEP384:RSAOAEP512:\".indexOf(a) != -1) {\n      return a;\n    }if (a === null || a === undefined) {\n      return \"RSA\";\n    }throw \"getAlgByKeyAndName: not supported algorithm name for RSAKey: \" + a;\n  }throw \"getAlgByKeyAndName: not supported algorithm name: \" + a;\n};KJUR.crypto.OID = new function () {\n  this.oidhex2name = { \"2a864886f70d010101\": \"rsaEncryption\", \"2a8648ce3d0201\": \"ecPublicKey\", \"2a8648ce380401\": \"dsa\", \"2a8648ce3d030107\": \"secp256r1\", \"2b8104001f\": \"secp192k1\", \"2b81040021\": \"secp224r1\", \"2b8104000a\": \"secp256k1\", \"2b81040023\": \"secp521r1\", \"2b81040022\": \"secp384r1\", \"2a8648ce380403\": \"SHA1withDSA\", \"608648016503040301\": \"SHA224withDSA\", \"608648016503040302\": \"SHA256withDSA\" };\n}();\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.ECDSA = function (h) {\n  var e = \"secp256r1\";var g = null;var b = null;var f = null;var a = new SecureRandom();var d = null;this.type = \"EC\";this.isPrivate = false;this.isPublic = false;function c(s, o, r, n) {\n    var j = Math.max(o.bitLength(), n.bitLength());var t = s.add2D(r);var q = s.curve.getInfinity();for (var p = j - 1; p >= 0; --p) {\n      q = q.twice2D();q.z = BigInteger.ONE;if (o.testBit(p)) {\n        if (n.testBit(p)) {\n          q = q.add2D(t);\n        } else {\n          q = q.add2D(s);\n        }\n      } else {\n        if (n.testBit(p)) {\n          q = q.add2D(r);\n        }\n      }\n    }return q;\n  }this.getBigRandom = function (i) {\n    return new BigInteger(i.bitLength(), a).mod(i.subtract(BigInteger.ONE)).add(BigInteger.ONE);\n  };this.setNamedCurve = function (i) {\n    this.ecparams = KJUR.crypto.ECParameterDB.getByName(i);this.prvKeyHex = null;this.pubKeyHex = null;this.curveName = i;\n  };this.setPrivateKeyHex = function (i) {\n    this.isPrivate = true;this.prvKeyHex = i;\n  };this.setPublicKeyHex = function (i) {\n    this.isPublic = true;this.pubKeyHex = i;\n  };this.getPublicKeyXYHex = function () {\n    var k = this.pubKeyHex;if (k.substr(0, 2) !== \"04\") {\n      throw \"this method supports uncompressed format(04) only\";\n    }var j = this.ecparams.keylen / 4;if (k.length !== 2 + j * 2) {\n      throw \"malformed public key hex length\";\n    }var i = {};i.x = k.substr(2, j);i.y = k.substr(2 + j);return i;\n  };this.getShortNISTPCurveName = function () {\n    var i = this.curveName;if (i === \"secp256r1\" || i === \"NIST P-256\" || i === \"P-256\" || i === \"prime256v1\") {\n      return \"P-256\";\n    }if (i === \"secp384r1\" || i === \"NIST P-384\" || i === \"P-384\") {\n      return \"P-384\";\n    }return null;\n  };this.generateKeyPairHex = function () {\n    var k = this.ecparams.n;var n = this.getBigRandom(k);var l = this.ecparams.G.multiply(n);var q = l.getX().toBigInteger();var o = l.getY().toBigInteger();var i = this.ecparams.keylen / 4;var m = (\"0000000000\" + n.toString(16)).slice(-i);var r = (\"0000000000\" + q.toString(16)).slice(-i);var p = (\"0000000000\" + o.toString(16)).slice(-i);var j = \"04\" + r + p;this.setPrivateKeyHex(m);this.setPublicKeyHex(j);return { ecprvhex: m, ecpubhex: j };\n  };this.signWithMessageHash = function (i) {\n    return this.signHex(i, this.prvKeyHex);\n  };this.signHex = function (o, j) {\n    var t = new BigInteger(j, 16);var l = this.ecparams.n;var q = new BigInteger(o, 16);do {\n      var m = this.getBigRandom(l);var u = this.ecparams.G;var p = u.multiply(m);var i = p.getX().toBigInteger().mod(l);\n    } while (i.compareTo(BigInteger.ZERO) <= 0);var v = m.modInverse(l).multiply(q.add(t.multiply(i))).mod(l);return KJUR.crypto.ECDSA.biRSSigToASN1Sig(i, v);\n  };this.sign = function (m, u) {\n    var q = u;var j = this.ecparams.n;var p = BigInteger.fromByteArrayUnsigned(m);do {\n      var l = this.getBigRandom(j);var t = this.ecparams.G;var o = t.multiply(l);var i = o.getX().toBigInteger().mod(j);\n    } while (i.compareTo(BigInteger.ZERO) <= 0);var v = l.modInverse(j).multiply(p.add(q.multiply(i))).mod(j);return this.serializeSig(i, v);\n  };this.verifyWithMessageHash = function (j, i) {\n    return this.verifyHex(j, i, this.pubKeyHex);\n  };this.verifyHex = function (m, i, p) {\n    var l, j;var o = KJUR.crypto.ECDSA.parseSigHex(i);l = o.r;j = o.s;var k;k = ECPointFp.decodeFromHex(this.ecparams.curve, p);var n = new BigInteger(m, 16);return this.verifyRaw(n, l, j, k);\n  };this.verify = function (o, p, j) {\n    var l, i;if (Bitcoin.Util.isArray(p)) {\n      var n = this.parseSig(p);l = n.r;i = n.s;\n    } else {\n      if (\"object\" === (typeof p === \"undefined\" ? \"undefined\" : _typeof(p)) && p.r && p.s) {\n        l = p.r;i = p.s;\n      } else {\n        throw \"Invalid value for signature\";\n      }\n    }var k;if (j instanceof ECPointFp) {\n      k = j;\n    } else {\n      if (Bitcoin.Util.isArray(j)) {\n        k = ECPointFp.decodeFrom(this.ecparams.curve, j);\n      } else {\n        throw \"Invalid format for pubkey value, must be byte array or ECPointFp\";\n      }\n    }var m = BigInteger.fromByteArrayUnsigned(o);return this.verifyRaw(m, l, i, k);\n  };this.verifyRaw = function (o, i, w, m) {\n    var l = this.ecparams.n;var u = this.ecparams.G;if (i.compareTo(BigInteger.ONE) < 0 || i.compareTo(l) >= 0) {\n      return false;\n    }if (w.compareTo(BigInteger.ONE) < 0 || w.compareTo(l) >= 0) {\n      return false;\n    }var p = w.modInverse(l);var k = o.multiply(p).mod(l);var j = i.multiply(p).mod(l);var q = u.multiply(k).add(m.multiply(j));var t = q.getX().toBigInteger().mod(l);return t.equals(i);\n  };this.serializeSig = function (k, j) {\n    var l = k.toByteArraySigned();var i = j.toByteArraySigned();var m = [];m.push(2);m.push(l.length);m = m.concat(l);m.push(2);m.push(i.length);m = m.concat(i);m.unshift(m.length);m.unshift(48);return m;\n  };this.parseSig = function (n) {\n    var m;if (n[0] != 48) {\n      throw new Error(\"Signature not a valid DERSequence\");\n    }m = 2;if (n[m] != 2) {\n      throw new Error(\"First element in signature must be a DERInteger\");\n    }var l = n.slice(m + 2, m + 2 + n[m + 1]);m += 2 + n[m + 1];if (n[m] != 2) {\n      throw new Error(\"Second element in signature must be a DERInteger\");\n    }var i = n.slice(m + 2, m + 2 + n[m + 1]);m += 2 + n[m + 1];var k = BigInteger.fromByteArrayUnsigned(l);var j = BigInteger.fromByteArrayUnsigned(i);return { r: k, s: j };\n  };this.parseSigCompact = function (m) {\n    if (m.length !== 65) {\n      throw \"Signature has the wrong length\";\n    }var j = m[0] - 27;if (j < 0 || j > 7) {\n      throw \"Invalid signature type\";\n    }var o = this.ecparams.n;var l = BigInteger.fromByteArrayUnsigned(m.slice(1, 33)).mod(o);var k = BigInteger.fromByteArrayUnsigned(m.slice(33, 65)).mod(o);return { r: l, s: k, i: j };\n  };this.readPKCS5PrvKeyHex = function (l) {\n    var n = ASN1HEX;var m = KJUR.crypto.ECDSA.getName;var p = n.getVbyList;if (n.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var i, k, o;try {\n      i = p(l, 0, [2, 0], \"06\");k = p(l, 0, [1], \"04\");try {\n        o = p(l, 0, [3, 0], \"03\").substr(2);\n      } catch (j) {}\n    } catch (j) {\n      throw \"malformed PKCS#1/5 plain ECC private key\";\n    }this.curveName = m(i);if (this.curveName === undefined) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(o);this.setPrivateKeyHex(k);this.isPublic = false;\n  };this.readPKCS8PrvKeyHex = function (l) {\n    var q = ASN1HEX;var i = KJUR.crypto.ECDSA.getName;var n = q.getVbyList;if (q.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var j, p, m, k;try {\n      j = n(l, 0, [1, 0], \"06\");p = n(l, 0, [1, 1], \"06\");m = n(l, 0, [2, 0, 1], \"04\");try {\n        k = n(l, 0, [2, 0, 2, 0], \"03\").substr(2);\n      } catch (o) {}\n    } catch (o) {\n      throw \"malformed PKCS#8 plain ECC private key\";\n    }this.curveName = i(p);if (this.curveName === undefined) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(k);this.setPrivateKeyHex(m);this.isPublic = false;\n  };this.readPKCS8PubKeyHex = function (l) {\n    var n = ASN1HEX;var m = KJUR.crypto.ECDSA.getName;var p = n.getVbyList;if (n.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var k, i, o;try {\n      k = p(l, 0, [0, 0], \"06\");i = p(l, 0, [0, 1], \"06\");o = p(l, 0, [1], \"03\").substr(2);\n    } catch (j) {\n      throw \"malformed PKCS#8 ECC public key\";\n    }this.curveName = m(i);if (this.curveName === null) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(o);\n  };this.readCertPubKeyHex = function (k, p) {\n    if (p !== 5) {\n      p = 6;\n    }var m = ASN1HEX;var l = KJUR.crypto.ECDSA.getName;var o = m.getVbyList;if (m.isASN1HEX(k) === false) {\n      throw \"not ASN.1 hex string\";\n    }var i, n;try {\n      i = o(k, 0, [0, p, 0, 1], \"06\");n = o(k, 0, [0, p, 1], \"03\").substr(2);\n    } catch (j) {\n      throw \"malformed X.509 certificate ECC public key\";\n    }this.curveName = l(i);if (this.curveName === null) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(n);\n  };if (h !== undefined) {\n    if (h.curve !== undefined) {\n      this.curveName = h.curve;\n    }\n  }if (this.curveName === undefined) {\n    this.curveName = e;\n  }this.setNamedCurve(this.curveName);if (h !== undefined) {\n    if (h.prv !== undefined) {\n      this.setPrivateKeyHex(h.prv);\n    }if (h.pub !== undefined) {\n      this.setPublicKeyHex(h.pub);\n    }\n  }\n};KJUR.crypto.ECDSA.parseSigHex = function (a) {\n  var b = KJUR.crypto.ECDSA.parseSigHexInHexRS(a);var d = new BigInteger(b.r, 16);var c = new BigInteger(b.s, 16);return { r: d, s: c };\n};KJUR.crypto.ECDSA.parseSigHexInHexRS = function (f) {\n  var j = ASN1HEX;var i = j.getChildIdx;var g = j.getV;if (f.substr(0, 2) != \"30\") {\n    throw \"signature is not a ASN.1 sequence\";\n  }var h = i(f, 0);if (h.length != 2) {\n    throw \"number of signature ASN.1 sequence elements seem wrong\";\n  }var e = h[0];var d = h[1];if (f.substr(e, 2) != \"02\") {\n    throw \"1st item of sequene of signature is not ASN.1 integer\";\n  }if (f.substr(d, 2) != \"02\") {\n    throw \"2nd item of sequene of signature is not ASN.1 integer\";\n  }var c = g(f, e);var b = g(f, d);return { r: c, s: b };\n};KJUR.crypto.ECDSA.asn1SigToConcatSig = function (c) {\n  var d = KJUR.crypto.ECDSA.parseSigHexInHexRS(c);var b = d.r;var a = d.s;if (b.substr(0, 2) == \"00\" && b.length % 32 == 2) {\n    b = b.substr(2);\n  }if (a.substr(0, 2) == \"00\" && a.length % 32 == 2) {\n    a = a.substr(2);\n  }if (b.length % 32 == 30) {\n    b = \"00\" + b;\n  }if (a.length % 32 == 30) {\n    a = \"00\" + a;\n  }if (b.length % 32 != 0) {\n    throw \"unknown ECDSA sig r length error\";\n  }if (a.length % 32 != 0) {\n    throw \"unknown ECDSA sig s length error\";\n  }return b + a;\n};KJUR.crypto.ECDSA.concatSigToASN1Sig = function (a) {\n  if (a.length / 2 * 8 % (16 * 8) != 0) {\n    throw \"unknown ECDSA concatinated r-s sig  length error\";\n  }var c = a.substr(0, a.length / 2);var b = a.substr(a.length / 2);return KJUR.crypto.ECDSA.hexRSSigToASN1Sig(c, b);\n};KJUR.crypto.ECDSA.hexRSSigToASN1Sig = function (b, a) {\n  var d = new BigInteger(b, 16);var c = new BigInteger(a, 16);return KJUR.crypto.ECDSA.biRSSigToASN1Sig(d, c);\n};KJUR.crypto.ECDSA.biRSSigToASN1Sig = function (f, d) {\n  var c = KJUR.asn1;var b = new c.DERInteger({ bigint: f });var a = new c.DERInteger({ bigint: d });var e = new c.DERSequence({ array: [b, a] });return e.getEncodedHex();\n};KJUR.crypto.ECDSA.getName = function (a) {\n  if (a === \"2a8648ce3d030107\") {\n    return \"secp256r1\";\n  }if (a === \"2b8104000a\") {\n    return \"secp256k1\";\n  }if (a === \"2b81040022\") {\n    return \"secp384r1\";\n  }if (\"|secp256r1|NIST P-256|P-256|prime256v1|\".indexOf(a) !== -1) {\n    return \"secp256r1\";\n  }if (\"|secp256k1|\".indexOf(a) !== -1) {\n    return \"secp256k1\";\n  }if (\"|secp384r1|NIST P-384|P-384|\".indexOf(a) !== -1) {\n    return \"secp384r1\";\n  }return null;\n};\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.ECParameterDB = new function () {\n  var b = {};var c = {};function a(d) {\n    return new BigInteger(d, 16);\n  }this.getByName = function (e) {\n    var d = e;if (typeof c[d] != \"undefined\") {\n      d = c[e];\n    }if (typeof b[d] != \"undefined\") {\n      return b[d];\n    }throw \"unregistered EC curve name: \" + d;\n  };this.regist = function (A, l, o, g, m, e, j, f, k, u, d, x) {\n    b[A] = {};var s = a(o);var z = a(g);var y = a(m);var t = a(e);var w = a(j);var r = new ECCurveFp(s, z, y);var q = r.decodePointHex(\"04\" + f + k);b[A][\"name\"] = A;b[A][\"keylen\"] = l;b[A][\"curve\"] = r;b[A][\"G\"] = q;b[A][\"n\"] = t;b[A][\"h\"] = w;b[A][\"oid\"] = d;b[A][\"info\"] = x;for (var v = 0; v < u.length; v++) {\n      c[u[v]] = A;\n    }\n  };\n}();KJUR.crypto.ECParameterDB.regist(\"secp128r1\", 128, \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF\", \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC\", \"E87579C11079F43DD824993C2CEE5ED3\", \"FFFFFFFE0000000075A30D1B9038A115\", \"1\", \"161FF7528B899B2D0C28607CA52C5B86\", \"CF5AC8395BAFEB13C02DA292DDED7A83\", [], \"\", \"secp128r1 : SECG curve over a 128 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp160k1\", 160, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73\", \"0\", \"7\", \"0100000000000000000001B8FA16DFAB9ACA16B6B3\", \"1\", \"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB\", \"938CF935318FDCED6BC28286531733C3F03C4FEE\", [], \"\", \"secp160k1 : SECG curve over a 160 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp160r1\", 160, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC\", \"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45\", \"0100000000000000000001F4C8F927AED3CA752257\", \"1\", \"4A96B5688EF573284664698968C38BB913CBFC82\", \"23A628553168947D59DCC912042351377AC5FB32\", [], \"\", \"secp160r1 : SECG curve over a 160 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp192k1\", 192, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37\", \"0\", \"3\", \"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D\", \"1\", \"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D\", \"9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D\", []);KJUR.crypto.ECParameterDB.regist(\"secp192r1\", 192, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", \"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1\", \"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831\", \"1\", \"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012\", \"07192B95FFC8DA78631011ED6B24CDD573F977A11E794811\", []);KJUR.crypto.ECParameterDB.regist(\"secp224r1\", 224, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE\", \"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D\", \"1\", \"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21\", \"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34\", []);KJUR.crypto.ECParameterDB.regist(\"secp256k1\", 256, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\", \"0\", \"7\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\", \"1\", \"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\", \"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\", []);KJUR.crypto.ECParameterDB.regist(\"secp256r1\", 256, \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\", \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC\", \"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B\", \"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551\", \"1\", \"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296\", \"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5\", [\"NIST P-256\", \"P-256\", \"prime256v1\"]);KJUR.crypto.ECParameterDB.regist(\"secp384r1\", 384, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC\", \"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973\", \"1\", \"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7\", \"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f\", [\"NIST P-384\", \"P-384\"]);KJUR.crypto.ECParameterDB.regist(\"secp521r1\", 521, \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\", \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC\", \"051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00\", \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409\", \"1\", \"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66\", \"011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650\", [\"NIST P-521\", \"P-521\"]);\nvar KEYUTIL = function () {\n  var d = function d(p, r, q) {\n    return k(CryptoJS.AES, p, r, q);\n  };var e = function e(p, r, q) {\n    return k(CryptoJS.TripleDES, p, r, q);\n  };var a = function a(p, r, q) {\n    return k(CryptoJS.DES, p, r, q);\n  };var k = function k(s, x, u, q) {\n    var r = CryptoJS.enc.Hex.parse(x);var w = CryptoJS.enc.Hex.parse(u);var p = CryptoJS.enc.Hex.parse(q);var t = {};t.key = w;t.iv = p;t.ciphertext = r;var v = s.decrypt(t, w, { iv: p });return CryptoJS.enc.Hex.stringify(v);\n  };var l = function l(p, r, q) {\n    return g(CryptoJS.AES, p, r, q);\n  };var o = function o(p, r, q) {\n    return g(CryptoJS.TripleDES, p, r, q);\n  };var f = function f(p, r, q) {\n    return g(CryptoJS.DES, p, r, q);\n  };var g = function g(t, y, v, q) {\n    var s = CryptoJS.enc.Hex.parse(y);var x = CryptoJS.enc.Hex.parse(v);var p = CryptoJS.enc.Hex.parse(q);var w = t.encrypt(s, x, { iv: p });var r = CryptoJS.enc.Hex.parse(w.toString());var u = CryptoJS.enc.Base64.stringify(r);return u;\n  };var i = { \"AES-256-CBC\": { proc: d, eproc: l, keylen: 32, ivlen: 16 }, \"AES-192-CBC\": { proc: d, eproc: l, keylen: 24, ivlen: 16 }, \"AES-128-CBC\": { proc: d, eproc: l, keylen: 16, ivlen: 16 }, \"DES-EDE3-CBC\": { proc: e, eproc: o, keylen: 24, ivlen: 8 }, \"DES-CBC\": { proc: a, eproc: f, keylen: 8, ivlen: 8 } };var c = function c(p) {\n    return i[p][\"proc\"];\n  };var m = function m(p) {\n    var r = CryptoJS.lib.WordArray.random(p);var q = CryptoJS.enc.Hex.stringify(r);return q;\n  };var n = function n(v) {\n    var w = {};var q = v.match(new RegExp(\"DEK-Info: ([^,]+),([0-9A-Fa-f]+)\", \"m\"));if (q) {\n      w.cipher = q[1];w.ivsalt = q[2];\n    }var p = v.match(new RegExp(\"-----BEGIN ([A-Z]+) PRIVATE KEY-----\"));if (p) {\n      w.type = p[1];\n    }var u = -1;var x = 0;if (v.indexOf(\"\\r\\n\\r\\n\") != -1) {\n      u = v.indexOf(\"\\r\\n\\r\\n\");x = 2;\n    }if (v.indexOf(\"\\n\\n\") != -1) {\n      u = v.indexOf(\"\\n\\n\");x = 1;\n    }var t = v.indexOf(\"-----END\");if (u != -1 && t != -1) {\n      var r = v.substring(u + x * 2, t - x);r = r.replace(/\\s+/g, \"\");w.data = r;\n    }return w;\n  };var j = function j(q, y, p) {\n    var v = p.substring(0, 16);var t = CryptoJS.enc.Hex.parse(v);var r = CryptoJS.enc.Utf8.parse(y);var u = i[q][\"keylen\"] + i[q][\"ivlen\"];var x = \"\";var w = null;for (;;) {\n      var s = CryptoJS.algo.MD5.create();if (w != null) {\n        s.update(w);\n      }s.update(r);s.update(t);w = s.finalize();x = x + CryptoJS.enc.Hex.stringify(w);if (x.length >= u * 2) {\n        break;\n      }\n    }var z = {};z.keyhex = x.substr(0, i[q][\"keylen\"] * 2);z.ivhex = x.substr(i[q][\"keylen\"] * 2, i[q][\"ivlen\"] * 2);return z;\n  };var b = function b(p, v, r, w) {\n    var s = CryptoJS.enc.Base64.parse(p);var q = CryptoJS.enc.Hex.stringify(s);var u = i[v][\"proc\"];var t = u(q, r, w);return t;\n  };var h = function h(p, s, q, u) {\n    var r = i[s][\"eproc\"];var t = r(p, q, u);return t;\n  };return { version: \"1.0.0\", parsePKCS5PEM: function parsePKCS5PEM(p) {\n      return n(p);\n    }, getKeyAndUnusedIvByPasscodeAndIvsalt: function getKeyAndUnusedIvByPasscodeAndIvsalt(q, p, r) {\n      return j(q, p, r);\n    }, decryptKeyB64: function decryptKeyB64(p, r, q, s) {\n      return b(p, r, q, s);\n    }, getDecryptedKeyHex: function getDecryptedKeyHex(y, x) {\n      var q = n(y);var t = q.type;var r = q.cipher;var p = q.ivsalt;var s = q.data;var w = j(r, x, p);var v = w.keyhex;var u = b(s, r, v, p);return u;\n    }, getEncryptedPKCS5PEMFromPrvKeyHex: function getEncryptedPKCS5PEMFromPrvKeyHex(x, s, A, t, r) {\n      var p = \"\";if (typeof t == \"undefined\" || t == null) {\n        t = \"AES-256-CBC\";\n      }if (typeof i[t] == \"undefined\") {\n        throw \"KEYUTIL unsupported algorithm: \" + t;\n      }if (typeof r == \"undefined\" || r == null) {\n        var v = i[t][\"ivlen\"];var u = m(v);r = u.toUpperCase();\n      }var z = j(t, A, r);var y = z.keyhex;var w = h(s, t, y, r);var q = w.replace(/(.{64})/g, \"$1\\r\\n\");var p = \"-----BEGIN \" + x + \" PRIVATE KEY-----\\r\\n\";p += \"Proc-Type: 4,ENCRYPTED\\r\\n\";p += \"DEK-Info: \" + t + \",\" + r + \"\\r\\n\";p += \"\\r\\n\";p += q;p += \"\\r\\n-----END \" + x + \" PRIVATE KEY-----\\r\\n\";return p;\n    }, parseHexOfEncryptedPKCS8: function parseHexOfEncryptedPKCS8(y) {\n      var B = ASN1HEX;var z = B.getChildIdx;var w = B.getV;var t = {};var r = z(y, 0);if (r.length != 2) {\n        throw \"malformed format: SEQUENCE(0).items != 2: \" + r.length;\n      }t.ciphertext = w(y, r[1]);var A = z(y, r[0]);if (A.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0).items != 2: \" + A.length;\n      }if (w(y, A[0]) != \"2a864886f70d01050d\") {\n        throw \"this only supports pkcs5PBES2\";\n      }var p = z(y, A[1]);if (A.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1).items != 2: \" + p.length;\n      }var q = z(y, p[1]);if (q.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.1).items != 2: \" + q.length;\n      }if (w(y, q[0]) != \"2a864886f70d0307\") {\n        throw \"this only supports TripleDES\";\n      }t.encryptionSchemeAlg = \"TripleDES\";t.encryptionSchemeIV = w(y, q[1]);var s = z(y, p[0]);if (s.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.0).items != 2: \" + s.length;\n      }if (w(y, s[0]) != \"2a864886f70d01050c\") {\n        throw \"this only supports pkcs5PBKDF2\";\n      }var x = z(y, s[1]);if (x.length < 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.0.1).items < 2: \" + x.length;\n      }t.pbkdf2Salt = w(y, x[0]);var u = w(y, x[1]);try {\n        t.pbkdf2Iter = parseInt(u, 16);\n      } catch (v) {\n        throw \"malformed format pbkdf2Iter: \" + u;\n      }return t;\n    }, getPBKDF2KeyHexFromParam: function getPBKDF2KeyHexFromParam(u, p) {\n      var t = CryptoJS.enc.Hex.parse(u.pbkdf2Salt);var q = u.pbkdf2Iter;var s = CryptoJS.PBKDF2(p, t, { keySize: 192 / 32, iterations: q });var r = CryptoJS.enc.Hex.stringify(s);return r;\n    }, _getPlainPKCS8HexFromEncryptedPKCS8PEM: function _getPlainPKCS8HexFromEncryptedPKCS8PEM(x, y) {\n      var r = pemtohex(x, \"ENCRYPTED PRIVATE KEY\");var p = this.parseHexOfEncryptedPKCS8(r);var u = KEYUTIL.getPBKDF2KeyHexFromParam(p, y);var v = {};v.ciphertext = CryptoJS.enc.Hex.parse(p.ciphertext);var t = CryptoJS.enc.Hex.parse(u);var s = CryptoJS.enc.Hex.parse(p.encryptionSchemeIV);var w = CryptoJS.TripleDES.decrypt(v, t, { iv: s });var q = CryptoJS.enc.Hex.stringify(w);return q;\n    }, getKeyFromEncryptedPKCS8PEM: function getKeyFromEncryptedPKCS8PEM(s, q) {\n      var p = this._getPlainPKCS8HexFromEncryptedPKCS8PEM(s, q);var r = this.getKeyFromPlainPrivatePKCS8Hex(p);return r;\n    }, parsePlainPrivatePKCS8Hex: function parsePlainPrivatePKCS8Hex(s) {\n      var v = ASN1HEX;var u = v.getChildIdx;var t = v.getV;var q = {};q.algparam = null;if (s.substr(0, 2) != \"30\") {\n        throw \"malformed plain PKCS8 private key(code:001)\";\n      }var r = u(s, 0);if (r.length != 3) {\n        throw \"malformed plain PKCS8 private key(code:002)\";\n      }if (s.substr(r[1], 2) != \"30\") {\n        throw \"malformed PKCS8 private key(code:003)\";\n      }var p = u(s, r[1]);if (p.length != 2) {\n        throw \"malformed PKCS8 private key(code:004)\";\n      }if (s.substr(p[0], 2) != \"06\") {\n        throw \"malformed PKCS8 private key(code:005)\";\n      }q.algoid = t(s, p[0]);if (s.substr(p[1], 2) == \"06\") {\n        q.algparam = t(s, p[1]);\n      }if (s.substr(r[2], 2) != \"04\") {\n        throw \"malformed PKCS8 private key(code:006)\";\n      }q.keyidx = v.getVidx(s, r[2]);return q;\n    }, getKeyFromPlainPrivatePKCS8PEM: function getKeyFromPlainPrivatePKCS8PEM(q) {\n      var p = pemtohex(q, \"PRIVATE KEY\");var r = this.getKeyFromPlainPrivatePKCS8Hex(p);return r;\n    }, getKeyFromPlainPrivatePKCS8Hex: function getKeyFromPlainPrivatePKCS8Hex(p) {\n      var q = this.parsePlainPrivatePKCS8Hex(p);var r;if (q.algoid == \"2a864886f70d010101\") {\n        r = new RSAKey();\n      } else {\n        if (q.algoid == \"2a8648ce380401\") {\n          r = new KJUR.crypto.DSA();\n        } else {\n          if (q.algoid == \"2a8648ce3d0201\") {\n            r = new KJUR.crypto.ECDSA();\n          } else {\n            throw \"unsupported private key algorithm\";\n          }\n        }\n      }r.readPKCS8PrvKeyHex(p);return r;\n    }, _getKeyFromPublicPKCS8Hex: function _getKeyFromPublicPKCS8Hex(q) {\n      var p;var r = ASN1HEX.getVbyList(q, 0, [0, 0], \"06\");if (r === \"2a864886f70d010101\") {\n        p = new RSAKey();\n      } else {\n        if (r === \"2a8648ce380401\") {\n          p = new KJUR.crypto.DSA();\n        } else {\n          if (r === \"2a8648ce3d0201\") {\n            p = new KJUR.crypto.ECDSA();\n          } else {\n            throw \"unsupported PKCS#8 public key hex\";\n          }\n        }\n      }p.readPKCS8PubKeyHex(q);return p;\n    }, parsePublicRawRSAKeyHex: function parsePublicRawRSAKeyHex(r) {\n      var u = ASN1HEX;var t = u.getChildIdx;var s = u.getV;var p = {};if (r.substr(0, 2) != \"30\") {\n        throw \"malformed RSA key(code:001)\";\n      }var q = t(r, 0);if (q.length != 2) {\n        throw \"malformed RSA key(code:002)\";\n      }if (r.substr(q[0], 2) != \"02\") {\n        throw \"malformed RSA key(code:003)\";\n      }p.n = s(r, q[0]);if (r.substr(q[1], 2) != \"02\") {\n        throw \"malformed RSA key(code:004)\";\n      }p.e = s(r, q[1]);return p;\n    }, parsePublicPKCS8Hex: function parsePublicPKCS8Hex(t) {\n      var v = ASN1HEX;var u = v.getChildIdx;var s = v.getV;var q = {};q.algparam = null;var r = u(t, 0);if (r.length != 2) {\n        throw \"outer DERSequence shall have 2 elements: \" + r.length;\n      }var w = r[0];if (t.substr(w, 2) != \"30\") {\n        throw \"malformed PKCS8 public key(code:001)\";\n      }var p = u(t, w);if (p.length != 2) {\n        throw \"malformed PKCS8 public key(code:002)\";\n      }if (t.substr(p[0], 2) != \"06\") {\n        throw \"malformed PKCS8 public key(code:003)\";\n      }q.algoid = s(t, p[0]);if (t.substr(p[1], 2) == \"06\") {\n        q.algparam = s(t, p[1]);\n      } else {\n        if (t.substr(p[1], 2) == \"30\") {\n          q.algparam = {};q.algparam.p = v.getVbyList(t, p[1], [0], \"02\");q.algparam.q = v.getVbyList(t, p[1], [1], \"02\");q.algparam.g = v.getVbyList(t, p[1], [2], \"02\");\n        }\n      }if (t.substr(r[1], 2) != \"03\") {\n        throw \"malformed PKCS8 public key(code:004)\";\n      }q.key = s(t, r[1]).substr(2);return q;\n    } };\n}();KEYUTIL.getKey = function (l, k, n) {\n  var G = ASN1HEX,\n      L = G.getChildIdx,\n      v = G.getV,\n      d = G.getVbyList,\n      c = KJUR.crypto,\n      i = c.ECDSA,\n      C = c.DSA,\n      w = RSAKey,\n      M = pemtohex,\n      F = KEYUTIL;if (typeof w != \"undefined\" && l instanceof w) {\n    return l;\n  }if (typeof i != \"undefined\" && l instanceof i) {\n    return l;\n  }if (typeof C != \"undefined\" && l instanceof C) {\n    return l;\n  }if (l.curve !== undefined && l.xy !== undefined && l.d === undefined) {\n    return new i({ pub: l.xy, curve: l.curve });\n  }if (l.curve !== undefined && l.d !== undefined) {\n    return new i({ prv: l.d, curve: l.curve });\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d === undefined) {\n    var P = new w();P.setPublic(l.n, l.e);return P;\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p !== undefined && l.q !== undefined && l.dp !== undefined && l.dq !== undefined && l.co !== undefined && l.qi === undefined) {\n    var P = new w();P.setPrivateEx(l.n, l.e, l.d, l.p, l.q, l.dp, l.dq, l.co);return P;\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p === undefined) {\n    var P = new w();P.setPrivate(l.n, l.e, l.d);return P;\n  }if (l.p !== undefined && l.q !== undefined && l.g !== undefined && l.y !== undefined && l.x === undefined) {\n    var P = new C();P.setPublic(l.p, l.q, l.g, l.y);return P;\n  }if (l.p !== undefined && l.q !== undefined && l.g !== undefined && l.y !== undefined && l.x !== undefined) {\n    var P = new C();P.setPrivate(l.p, l.q, l.g, l.y, l.x);return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d === undefined) {\n    var P = new w();P.setPublic(b64utohex(l.n), b64utohex(l.e));return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p !== undefined && l.q !== undefined && l.dp !== undefined && l.dq !== undefined && l.qi !== undefined) {\n    var P = new w();P.setPrivateEx(b64utohex(l.n), b64utohex(l.e), b64utohex(l.d), b64utohex(l.p), b64utohex(l.q), b64utohex(l.dp), b64utohex(l.dq), b64utohex(l.qi));return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d !== undefined) {\n    var P = new w();P.setPrivate(b64utohex(l.n), b64utohex(l.e), b64utohex(l.d));return P;\n  }if (l.kty === \"EC\" && l.crv !== undefined && l.x !== undefined && l.y !== undefined && l.d === undefined) {\n    var j = new i({ curve: l.crv });var t = j.ecparams.keylen / 4;var B = (\"0000000000\" + b64utohex(l.x)).slice(-t);var z = (\"0000000000\" + b64utohex(l.y)).slice(-t);var u = \"04\" + B + z;j.setPublicKeyHex(u);return j;\n  }if (l.kty === \"EC\" && l.crv !== undefined && l.x !== undefined && l.y !== undefined && l.d !== undefined) {\n    var j = new i({ curve: l.crv });var t = j.ecparams.keylen / 4;var B = (\"0000000000\" + b64utohex(l.x)).slice(-t);var z = (\"0000000000\" + b64utohex(l.y)).slice(-t);var u = \"04\" + B + z;var b = (\"0000000000\" + b64utohex(l.d)).slice(-t);j.setPublicKeyHex(u);j.setPrivateKeyHex(b);return j;\n  }if (n === \"pkcs5prv\") {\n    var J = l,\n        G = ASN1HEX,\n        N,\n        P;N = L(J, 0);if (N.length === 9) {\n      P = new w();P.readPKCS5PrvKeyHex(J);\n    } else {\n      if (N.length === 6) {\n        P = new C();P.readPKCS5PrvKeyHex(J);\n      } else {\n        if (N.length > 2 && J.substr(N[1], 2) === \"04\") {\n          P = new i();P.readPKCS5PrvKeyHex(J);\n        } else {\n          throw \"unsupported PKCS#1/5 hexadecimal key\";\n        }\n      }\n    }return P;\n  }if (n === \"pkcs8prv\") {\n    var P = F.getKeyFromPlainPrivatePKCS8Hex(l);return P;\n  }if (n === \"pkcs8pub\") {\n    return F._getKeyFromPublicPKCS8Hex(l);\n  }if (n === \"x509pub\") {\n    return X509.getPublicKeyFromCertHex(l);\n  }if (l.indexOf(\"-END CERTIFICATE-\", 0) != -1 || l.indexOf(\"-END X509 CERTIFICATE-\", 0) != -1 || l.indexOf(\"-END TRUSTED CERTIFICATE-\", 0) != -1) {\n    return X509.getPublicKeyFromCertPEM(l);\n  }if (l.indexOf(\"-END PUBLIC KEY-\") != -1) {\n    var O = pemtohex(l, \"PUBLIC KEY\");return F._getKeyFromPublicPKCS8Hex(O);\n  }if (l.indexOf(\"-END RSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") == -1) {\n    var m = M(l, \"RSA PRIVATE KEY\");return F.getKey(m, null, \"pkcs5prv\");\n  }if (l.indexOf(\"-END DSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") == -1) {\n    var I = M(l, \"DSA PRIVATE KEY\");var E = d(I, 0, [1], \"02\");var D = d(I, 0, [2], \"02\");var K = d(I, 0, [3], \"02\");var r = d(I, 0, [4], \"02\");var s = d(I, 0, [5], \"02\");var P = new C();P.setPrivate(new BigInteger(E, 16), new BigInteger(D, 16), new BigInteger(K, 16), new BigInteger(r, 16), new BigInteger(s, 16));return P;\n  }if (l.indexOf(\"-END PRIVATE KEY-\") != -1) {\n    return F.getKeyFromPlainPrivatePKCS8PEM(l);\n  }if (l.indexOf(\"-END RSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var o = F.getDecryptedKeyHex(l, k);var H = new RSAKey();H.readPKCS5PrvKeyHex(o);return H;\n  }if (l.indexOf(\"-END EC PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var I = F.getDecryptedKeyHex(l, k);var P = d(I, 0, [1], \"04\");var f = d(I, 0, [2, 0], \"06\");var A = d(I, 0, [3, 0], \"03\").substr(2);var e = \"\";if (KJUR.crypto.OID.oidhex2name[f] !== undefined) {\n      e = KJUR.crypto.OID.oidhex2name[f];\n    } else {\n      throw \"undefined OID(hex) in KJUR.crypto.OID: \" + f;\n    }var j = new i({ curve: e });j.setPublicKeyHex(A);j.setPrivateKeyHex(P);j.isPublic = false;return j;\n  }if (l.indexOf(\"-END DSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var I = F.getDecryptedKeyHex(l, k);var E = d(I, 0, [1], \"02\");var D = d(I, 0, [2], \"02\");var K = d(I, 0, [3], \"02\");var r = d(I, 0, [4], \"02\");var s = d(I, 0, [5], \"02\");var P = new C();P.setPrivate(new BigInteger(E, 16), new BigInteger(D, 16), new BigInteger(K, 16), new BigInteger(r, 16), new BigInteger(s, 16));return P;\n  }if (l.indexOf(\"-END ENCRYPTED PRIVATE KEY-\") != -1) {\n    return F.getKeyFromEncryptedPKCS8PEM(l, k);\n  }throw \"not supported argument\";\n};KEYUTIL.generateKeypair = function (a, c) {\n  if (a == \"RSA\") {\n    var b = c;var h = new RSAKey();h.generate(b, \"10001\");h.isPrivate = true;h.isPublic = true;var f = new RSAKey();var e = h.n.toString(16);var i = h.e.toString(16);f.setPublic(e, i);f.isPrivate = false;f.isPublic = true;var k = {};k.prvKeyObj = h;k.pubKeyObj = f;return k;\n  } else {\n    if (a == \"EC\") {\n      var d = c;var g = new KJUR.crypto.ECDSA({ curve: d });var j = g.generateKeyPairHex();var h = new KJUR.crypto.ECDSA({ curve: d });h.setPublicKeyHex(j.ecpubhex);h.setPrivateKeyHex(j.ecprvhex);h.isPrivate = true;h.isPublic = false;var f = new KJUR.crypto.ECDSA({ curve: d });f.setPublicKeyHex(j.ecpubhex);f.isPrivate = false;f.isPublic = true;var k = {};k.prvKeyObj = h;k.pubKeyObj = f;return k;\n    } else {\n      throw \"unknown algorithm: \" + a;\n    }\n  }\n};KEYUTIL.getPEM = function (b, D, y, m, q, j) {\n  var F = KJUR,\n      k = F.asn1,\n      z = k.DERObjectIdentifier,\n      f = k.DERInteger,\n      l = k.ASN1Util.newObject,\n      a = k.x509,\n      C = a.SubjectPublicKeyInfo,\n      e = F.crypto,\n      u = e.DSA,\n      r = e.ECDSA,\n      n = RSAKey;function A(s) {\n    var G = l({ seq: [{ \"int\": 0 }, { \"int\": { bigint: s.n } }, { \"int\": s.e }, { \"int\": { bigint: s.d } }, { \"int\": { bigint: s.p } }, { \"int\": { bigint: s.q } }, { \"int\": { bigint: s.dmp1 } }, { \"int\": { bigint: s.dmq1 } }, { \"int\": { bigint: s.coeff } }] });return G;\n  }function B(G) {\n    var s = l({ seq: [{ \"int\": 1 }, { octstr: { hex: G.prvKeyHex } }, { tag: [\"a0\", true, { oid: { name: G.curveName } }] }, { tag: [\"a1\", true, { bitstr: { hex: \"00\" + G.pubKeyHex } }] }] });return s;\n  }function x(s) {\n    var G = l({ seq: [{ \"int\": 0 }, { \"int\": { bigint: s.p } }, { \"int\": { bigint: s.q } }, { \"int\": { bigint: s.g } }, { \"int\": { bigint: s.y } }, { \"int\": { bigint: s.x } }] });return G;\n  }if ((n !== undefined && b instanceof n || u !== undefined && b instanceof u || r !== undefined && b instanceof r) && b.isPublic == true && (D === undefined || D == \"PKCS8PUB\")) {\n    var E = new C(b);var w = E.getEncodedHex();return hextopem(w, \"PUBLIC KEY\");\n  }if (D == \"PKCS1PRV\" && n !== undefined && b instanceof n && (y === undefined || y == null) && b.isPrivate == true) {\n    var E = A(b);var w = E.getEncodedHex();return hextopem(w, \"RSA PRIVATE KEY\");\n  }if (D == \"PKCS1PRV\" && r !== undefined && b instanceof r && (y === undefined || y == null) && b.isPrivate == true) {\n    var i = new z({ name: b.curveName });var v = i.getEncodedHex();var h = B(b);var t = h.getEncodedHex();var p = \"\";p += hextopem(v, \"EC PARAMETERS\");p += hextopem(t, \"EC PRIVATE KEY\");return p;\n  }if (D == \"PKCS1PRV\" && u !== undefined && b instanceof u && (y === undefined || y == null) && b.isPrivate == true) {\n    var E = x(b);var w = E.getEncodedHex();return hextopem(w, \"DSA PRIVATE KEY\");\n  }if (D == \"PKCS5PRV\" && n !== undefined && b instanceof n && y !== undefined && y != null && b.isPrivate == true) {\n    var E = A(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"RSA\", w, y, m, j);\n  }if (D == \"PKCS5PRV\" && r !== undefined && b instanceof r && y !== undefined && y != null && b.isPrivate == true) {\n    var E = B(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"EC\", w, y, m, j);\n  }if (D == \"PKCS5PRV\" && u !== undefined && b instanceof u && y !== undefined && y != null && b.isPrivate == true) {\n    var E = x(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"DSA\", w, y, m, j);\n  }var o = function o(G, s) {\n    var I = c(G, s);var H = new l({ seq: [{ seq: [{ oid: { name: \"pkcs5PBES2\" } }, { seq: [{ seq: [{ oid: { name: \"pkcs5PBKDF2\" } }, { seq: [{ octstr: { hex: I.pbkdf2Salt } }, { \"int\": I.pbkdf2Iter }] }] }, { seq: [{ oid: { name: \"des-EDE3-CBC\" } }, { octstr: { hex: I.encryptionSchemeIV } }] }] }] }, { octstr: { hex: I.ciphertext } }] });return H.getEncodedHex();\n  };var c = function c(N, O) {\n    var H = 100;var M = CryptoJS.lib.WordArray.random(8);var L = \"DES-EDE3-CBC\";var s = CryptoJS.lib.WordArray.random(8);var I = CryptoJS.PBKDF2(O, M, { keySize: 192 / 32, iterations: H });var J = CryptoJS.enc.Hex.parse(N);var K = CryptoJS.TripleDES.encrypt(J, I, { iv: s }) + \"\";var G = {};G.ciphertext = K;G.pbkdf2Salt = CryptoJS.enc.Hex.stringify(M);G.pbkdf2Iter = H;G.encryptionSchemeAlg = L;G.encryptionSchemeIV = CryptoJS.enc.Hex.stringify(s);return G;\n  };if (D == \"PKCS8PRV\" && n != undefined && b instanceof n && b.isPrivate == true) {\n    var g = A(b);var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"rsaEncryption\" } }, { \"null\": true }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }if (D == \"PKCS8PRV\" && r !== undefined && b instanceof r && b.isPrivate == true) {\n    var g = new l({ seq: [{ \"int\": 1 }, { octstr: { hex: b.prvKeyHex } }, { tag: [\"a1\", true, { bitstr: { hex: \"00\" + b.pubKeyHex } }] }] });var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"ecPublicKey\" } }, { oid: { name: b.curveName } }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }if (D == \"PKCS8PRV\" && u !== undefined && b instanceof u && b.isPrivate == true) {\n    var g = new f({ bigint: b.x });var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"dsa\" } }, { seq: [{ \"int\": { bigint: b.p } }, { \"int\": { bigint: b.q } }, { \"int\": { bigint: b.g } }] }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }throw \"unsupported object nor format\";\n};KEYUTIL.getKeyFromCSRPEM = function (b) {\n  var a = pemtohex(b, \"CERTIFICATE REQUEST\");var c = KEYUTIL.getKeyFromCSRHex(a);return c;\n};KEYUTIL.getKeyFromCSRHex = function (a) {\n  var c = KEYUTIL.parseCSRHex(a);var b = KEYUTIL.getKey(c.p8pubkeyhex, null, \"pkcs8pub\");return b;\n};KEYUTIL.parseCSRHex = function (d) {\n  var i = ASN1HEX;var f = i.getChildIdx;var c = i.getTLV;var b = {};var g = d;if (g.substr(0, 2) != \"30\") {\n    throw \"malformed CSR(code:001)\";\n  }var e = f(g, 0);if (e.length < 1) {\n    throw \"malformed CSR(code:002)\";\n  }if (g.substr(e[0], 2) != \"30\") {\n    throw \"malformed CSR(code:003)\";\n  }var a = f(g, e[0]);if (a.length < 3) {\n    throw \"malformed CSR(code:004)\";\n  }b.p8pubkeyhex = c(g, a[2]);return b;\n};KEYUTIL.getJWKFromKey = function (d) {\n  var b = {};if (d instanceof RSAKey && d.isPrivate) {\n    b.kty = \"RSA\";b.n = hextob64u(d.n.toString(16));b.e = hextob64u(d.e.toString(16));b.d = hextob64u(d.d.toString(16));b.p = hextob64u(d.p.toString(16));b.q = hextob64u(d.q.toString(16));b.dp = hextob64u(d.dmp1.toString(16));b.dq = hextob64u(d.dmq1.toString(16));b.qi = hextob64u(d.coeff.toString(16));return b;\n  } else {\n    if (d instanceof RSAKey && d.isPublic) {\n      b.kty = \"RSA\";b.n = hextob64u(d.n.toString(16));b.e = hextob64u(d.e.toString(16));return b;\n    } else {\n      if (d instanceof KJUR.crypto.ECDSA && d.isPrivate) {\n        var a = d.getShortNISTPCurveName();if (a !== \"P-256\" && a !== \"P-384\") {\n          throw \"unsupported curve name for JWT: \" + a;\n        }var c = d.getPublicKeyXYHex();b.kty = \"EC\";b.crv = a;b.x = hextob64u(c.x);b.y = hextob64u(c.y);b.d = hextob64u(d.prvKeyHex);return b;\n      } else {\n        if (d instanceof KJUR.crypto.ECDSA && d.isPublic) {\n          var a = d.getShortNISTPCurveName();if (a !== \"P-256\" && a !== \"P-384\") {\n            throw \"unsupported curve name for JWT: \" + a;\n          }var c = d.getPublicKeyXYHex();b.kty = \"EC\";b.crv = a;b.x = hextob64u(c.x);b.y = hextob64u(c.y);return b;\n        }\n      }\n    }\n  }throw \"not supported key object\";\n};\nRSAKey.getPosArrayOfChildrenFromHex = function (a) {\n  return ASN1HEX.getChildIdx(a, 0);\n};RSAKey.getHexValueArrayOfChildrenFromHex = function (f) {\n  var n = ASN1HEX;var i = n.getV;var k = RSAKey.getPosArrayOfChildrenFromHex(f);var e = i(f, k[0]);var j = i(f, k[1]);var b = i(f, k[2]);var c = i(f, k[3]);var h = i(f, k[4]);var g = i(f, k[5]);var m = i(f, k[6]);var l = i(f, k[7]);var d = i(f, k[8]);var k = new Array();k.push(e, j, b, c, h, g, m, l, d);return k;\n};RSAKey.prototype.readPrivateKeyFromPEMString = function (d) {\n  var c = pemtohex(d);var b = RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]);\n};RSAKey.prototype.readPKCS5PrvKeyHex = function (c) {\n  var b = RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]);\n};RSAKey.prototype.readPKCS8PrvKeyHex = function (e) {\n  var c, j, l, b, a, f, d, k;var m = ASN1HEX;var g = m.getVbyList;if (m.isASN1HEX(e) === false) {\n    throw \"not ASN.1 hex string\";\n  }try {\n    c = g(e, 0, [2, 0, 1], \"02\");j = g(e, 0, [2, 0, 2], \"02\");l = g(e, 0, [2, 0, 3], \"02\");b = g(e, 0, [2, 0, 4], \"02\");a = g(e, 0, [2, 0, 5], \"02\");f = g(e, 0, [2, 0, 6], \"02\");d = g(e, 0, [2, 0, 7], \"02\");k = g(e, 0, [2, 0, 8], \"02\");\n  } catch (i) {\n    throw \"malformed PKCS#8 plain RSA private key\";\n  }this.setPrivateEx(c, j, l, b, a, f, d, k);\n};RSAKey.prototype.readPKCS5PubKeyHex = function (c) {\n  var e = ASN1HEX;var b = e.getV;if (e.isASN1HEX(c) === false) {\n    throw \"keyHex is not ASN.1 hex string\";\n  }var a = e.getChildIdx(c, 0);if (a.length !== 2 || c.substr(a[0], 2) !== \"02\" || c.substr(a[1], 2) !== \"02\") {\n    throw \"wrong hex for PKCS#5 public key\";\n  }var f = b(c, a[0]);var d = b(c, a[1]);this.setPublic(f, d);\n};RSAKey.prototype.readPKCS8PubKeyHex = function (b) {\n  var c = ASN1HEX;if (c.isASN1HEX(b) === false) {\n    throw \"not ASN.1 hex string\";\n  }if (c.getTLVbyList(b, 0, [0, 0]) !== \"06092a864886f70d010101\") {\n    throw \"not PKCS8 RSA public key\";\n  }var a = c.getTLVbyList(b, 0, [1, 0]);this.readPKCS5PubKeyHex(a);\n};RSAKey.prototype.readCertPubKeyHex = function (b, d) {\n  var a, c;a = new X509();a.readCertHex(b);c = a.getPublicKeyHex();this.readPKCS8PubKeyHex(c);\n};\nvar _RE_HEXDECONLY = new RegExp(\"\");_RE_HEXDECONLY.compile(\"[^0-9a-f]\", \"gi\");function _rsasign_getHexPaddedDigestInfoForString(d, e, a) {\n  var b = function b(f) {\n    return KJUR.crypto.Util.hashString(f, a);\n  };var c = b(d);return KJUR.crypto.Util.getPaddedDigestInfoHex(c, a, e);\n}function _zeroPaddingOfSignature(e, d) {\n  var c = \"\";var a = d / 4 - e.length;for (var b = 0; b < a; b++) {\n    c = c + \"0\";\n  }return c + e;\n}RSAKey.prototype.sign = function (d, a) {\n  var b = function b(e) {\n    return KJUR.crypto.Util.hashString(e, a);\n  };var c = b(d);return this.signWithMessageHash(c, a);\n};RSAKey.prototype.signWithMessageHash = function (e, c) {\n  var f = KJUR.crypto.Util.getPaddedDigestInfoHex(e, c, this.n.bitLength());var b = parseBigInt(f, 16);var d = this.doPrivate(b);var a = d.toString(16);return _zeroPaddingOfSignature(a, this.n.bitLength());\n};function pss_mgf1_str(c, a, e) {\n  var b = \"\",\n      d = 0;while (b.length < a) {\n    b += hextorstr(e(rstrtohex(c + String.fromCharCode.apply(String, [(d & 4278190080) >> 24, (d & 16711680) >> 16, (d & 65280) >> 8, d & 255]))));d += 1;\n  }return b;\n}RSAKey.prototype.signPSS = function (e, a, d) {\n  var c = function c(f) {\n    return KJUR.crypto.Util.hashHex(f, a);\n  };var b = c(rstrtohex(e));if (d === undefined) {\n    d = -1;\n  }return this.signWithMessageHashPSS(b, a, d);\n};RSAKey.prototype.signWithMessageHashPSS = function (l, a, k) {\n  var b = hextorstr(l);var g = b.length;var m = this.n.bitLength() - 1;var c = Math.ceil(m / 8);var d;var o = function o(i) {\n    return KJUR.crypto.Util.hashHex(i, a);\n  };if (k === -1 || k === undefined) {\n    k = g;\n  } else {\n    if (k === -2) {\n      k = c - g - 2;\n    } else {\n      if (k < -2) {\n        throw \"invalid salt length\";\n      }\n    }\n  }if (c < g + k + 2) {\n    throw \"data too long\";\n  }var f = \"\";if (k > 0) {\n    f = new Array(k);new SecureRandom().nextBytes(f);f = String.fromCharCode.apply(String, f);\n  }var n = hextorstr(o(rstrtohex(\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + b + f)));var j = [];for (d = 0; d < c - k - g - 2; d += 1) {\n    j[d] = 0;\n  }var e = String.fromCharCode.apply(String, j) + \"\\x01\" + f;var h = pss_mgf1_str(n, e.length, o);var q = [];for (d = 0; d < e.length; d += 1) {\n    q[d] = e.charCodeAt(d) ^ h.charCodeAt(d);\n  }var p = 65280 >> 8 * c - m & 255;q[0] &= ~p;for (d = 0; d < g; d++) {\n    q.push(n.charCodeAt(d));\n  }q.push(188);return _zeroPaddingOfSignature(this.doPrivate(new BigInteger(q)).toString(16), this.n.bitLength());\n};function _rsasign_getDecryptSignatureBI(a, d, c) {\n  var b = new RSAKey();b.setPublic(d, c);var e = b.doPublic(a);return e;\n}function _rsasign_getHexDigestInfoFromSig(a, c, b) {\n  var e = _rsasign_getDecryptSignatureBI(a, c, b);var d = e.toString(16).replace(/^1f+00/, \"\");return d;\n}function _rsasign_getAlgNameAndHashFromHexDisgestInfo(f) {\n  for (var e in KJUR.crypto.Util.DIGESTINFOHEAD) {\n    var d = KJUR.crypto.Util.DIGESTINFOHEAD[e];var b = d.length;if (f.substring(0, b) == d) {\n      var c = [e, f.substring(b)];return c;\n    }\n  }return [];\n}RSAKey.prototype.verify = function (f, j) {\n  j = j.replace(_RE_HEXDECONLY, \"\");j = j.replace(/[ \\n]+/g, \"\");var b = parseBigInt(j, 16);if (b.bitLength() > this.n.bitLength()) {\n    return 0;\n  }var i = this.doPublic(b);var e = i.toString(16).replace(/^1f+00/, \"\");var g = _rsasign_getAlgNameAndHashFromHexDisgestInfo(e);if (g.length == 0) {\n    return false;\n  }var d = g[0];var h = g[1];var a = function a(k) {\n    return KJUR.crypto.Util.hashString(k, d);\n  };var c = a(f);return h == c;\n};RSAKey.prototype.verifyWithMessageHash = function (e, a) {\n  a = a.replace(_RE_HEXDECONLY, \"\");a = a.replace(/[ \\n]+/g, \"\");var b = parseBigInt(a, 16);if (b.bitLength() > this.n.bitLength()) {\n    return 0;\n  }var h = this.doPublic(b);var g = h.toString(16).replace(/^1f+00/, \"\");var c = _rsasign_getAlgNameAndHashFromHexDisgestInfo(g);if (c.length == 0) {\n    return false;\n  }var d = c[0];var f = c[1];return f == e;\n};RSAKey.prototype.verifyPSS = function (c, b, a, f) {\n  var e = function e(g) {\n    return KJUR.crypto.Util.hashHex(g, a);\n  };var d = e(rstrtohex(c));if (f === undefined) {\n    f = -1;\n  }return this.verifyWithMessageHashPSS(d, b, a, f);\n};RSAKey.prototype.verifyWithMessageHashPSS = function (f, s, l, c) {\n  var k = new BigInteger(s, 16);if (k.bitLength() > this.n.bitLength()) {\n    return false;\n  }var r = function r(i) {\n    return KJUR.crypto.Util.hashHex(i, l);\n  };var j = hextorstr(f);var h = j.length;var g = this.n.bitLength() - 1;var m = Math.ceil(g / 8);var q;if (c === -1 || c === undefined) {\n    c = h;\n  } else {\n    if (c === -2) {\n      c = m - h - 2;\n    } else {\n      if (c < -2) {\n        throw \"invalid salt length\";\n      }\n    }\n  }if (m < h + c + 2) {\n    throw \"data too long\";\n  }var a = this.doPublic(k).toByteArray();for (q = 0; q < a.length; q += 1) {\n    a[q] &= 255;\n  }while (a.length < m) {\n    a.unshift(0);\n  }if (a[m - 1] !== 188) {\n    throw \"encoded message does not end in 0xbc\";\n  }a = String.fromCharCode.apply(String, a);var d = a.substr(0, m - h - 1);var e = a.substr(d.length, h);var p = 65280 >> 8 * m - g & 255;if ((d.charCodeAt(0) & p) !== 0) {\n    throw \"bits beyond keysize not zero\";\n  }var n = pss_mgf1_str(e, d.length, r);var o = [];for (q = 0; q < d.length; q += 1) {\n    o[q] = d.charCodeAt(q) ^ n.charCodeAt(q);\n  }o[0] &= ~p;var b = m - h - c - 2;for (q = 0; q < b; q += 1) {\n    if (o[q] !== 0) {\n      throw \"leftmost octets not zero\";\n    }\n  }if (o[b] !== 1) {\n    throw \"0x01 marker not found\";\n  }return e === hextorstr(r(rstrtohex(\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + j + String.fromCharCode.apply(String, o.slice(-c)))));\n};RSAKey.SALT_LEN_HLEN = -1;RSAKey.SALT_LEN_MAX = -2;RSAKey.SALT_LEN_RECOVER = -2;\nfunction X509() {\n  var k = ASN1HEX,\n      j = k.getChildIdx,\n      h = k.getV,\n      b = k.getTLV,\n      f = k.getVbyList,\n      c = k.getTLVbyList,\n      g = k.getIdxbyList,\n      d = k.getVidx,\n      i = k.oidname,\n      a = X509,\n      e = pemtohex;this.hex = null;this.version = 0;this.foffset = 0;this.aExtInfo = null;this.getVersion = function () {\n    if (this.hex === null || this.version !== 0) {\n      return this.version;\n    }if (c(this.hex, 0, [0, 0]) !== \"a003020102\") {\n      this.version = 1;this.foffset = -1;return 1;\n    }this.version = 3;return 3;\n  };this.getSerialNumberHex = function () {\n    return f(this.hex, 0, [0, 1 + this.foffset], \"02\");\n  };this.getSignatureAlgorithmField = function () {\n    return i(f(this.hex, 0, [0, 2 + this.foffset, 0], \"06\"));\n  };this.getIssuerHex = function () {\n    return c(this.hex, 0, [0, 3 + this.foffset], \"30\");\n  };this.getIssuerString = function () {\n    return a.hex2dn(this.getIssuerHex());\n  };this.getSubjectHex = function () {\n    return c(this.hex, 0, [0, 5 + this.foffset], \"30\");\n  };this.getSubjectString = function () {\n    return a.hex2dn(this.getSubjectHex());\n  };this.getNotBefore = function () {\n    var l = f(this.hex, 0, [0, 4 + this.foffset, 0]);l = l.replace(/(..)/g, \"%$1\");l = decodeURIComponent(l);return l;\n  };this.getNotAfter = function () {\n    var l = f(this.hex, 0, [0, 4 + this.foffset, 1]);l = l.replace(/(..)/g, \"%$1\");l = decodeURIComponent(l);return l;\n  };this.getPublicKeyHex = function () {\n    return k.getTLVbyList(this.hex, 0, [0, 6 + this.foffset], \"30\");\n  };this.getPublicKeyIdx = function () {\n    return g(this.hex, 0, [0, 6 + this.foffset], \"30\");\n  };this.getPublicKeyContentIdx = function () {\n    var l = this.getPublicKeyIdx();return g(this.hex, l, [1, 0], \"30\");\n  };this.getPublicKey = function () {\n    return KEYUTIL.getKey(this.getPublicKeyHex(), null, \"pkcs8pub\");\n  };this.getSignatureAlgorithmName = function () {\n    return i(f(this.hex, 0, [1, 0], \"06\"));\n  };this.getSignatureValueHex = function () {\n    return f(this.hex, 0, [2], \"03\", true);\n  };this.verifySignature = function (n) {\n    var o = this.getSignatureAlgorithmName();var l = this.getSignatureValueHex();var m = c(this.hex, 0, [0], \"30\");var p = new KJUR.crypto.Signature({ alg: o });p.init(n);p.updateHex(m);return p.verify(l);\n  };this.parseExt = function () {\n    if (this.version !== 3) {\n      return -1;\n    }var p = g(this.hex, 0, [0, 7, 0], \"30\");var m = j(this.hex, p);this.aExtInfo = new Array();for (var n = 0; n < m.length; n++) {\n      var q = {};q.critical = false;var l = j(this.hex, m[n]);var r = 0;if (l.length === 3) {\n        q.critical = true;r = 1;\n      }q.oid = k.hextooidstr(f(this.hex, m[n], [0], \"06\"));var o = g(this.hex, m[n], [1 + r]);q.vidx = d(this.hex, o);this.aExtInfo.push(q);\n    }\n  };this.getExtInfo = function (n) {\n    var l = this.aExtInfo;var o = n;if (!n.match(/^[0-9.]+$/)) {\n      o = KJUR.asn1.x509.OID.name2oid(n);\n    }if (o === \"\") {\n      return undefined;\n    }for (var m = 0; m < l.length; m++) {\n      if (l[m].oid === o) {\n        return l[m];\n      }\n    }return undefined;\n  };this.getExtBasicConstraints = function () {\n    var n = this.getExtInfo(\"basicConstraints\");if (n === undefined) {\n      return n;\n    }var l = h(this.hex, n.vidx);if (l === \"\") {\n      return {};\n    }if (l === \"0101ff\") {\n      return { cA: true };\n    }if (l.substr(0, 8) === \"0101ff02\") {\n      var o = h(l, 6);var m = parseInt(o, 16);return { cA: true, pathLen: m };\n    }throw \"basicConstraints parse error\";\n  };this.getExtKeyUsageBin = function () {\n    var o = this.getExtInfo(\"keyUsage\");if (o === undefined) {\n      return \"\";\n    }var m = h(this.hex, o.vidx);if (m.length % 2 != 0 || m.length <= 2) {\n      throw \"malformed key usage value\";\n    }var l = parseInt(m.substr(0, 2));var n = parseInt(m.substr(2), 16).toString(2);return n.substr(0, n.length - l);\n  };this.getExtKeyUsageString = function () {\n    var n = this.getExtKeyUsageBin();var l = new Array();for (var m = 0; m < n.length; m++) {\n      if (n.substr(m, 1) == \"1\") {\n        l.push(X509.KEYUSAGE_NAME[m]);\n      }\n    }return l.join(\",\");\n  };this.getExtSubjectKeyIdentifier = function () {\n    var l = this.getExtInfo(\"subjectKeyIdentifier\");if (l === undefined) {\n      return l;\n    }return h(this.hex, l.vidx);\n  };this.getExtAuthorityKeyIdentifier = function () {\n    var p = this.getExtInfo(\"authorityKeyIdentifier\");if (p === undefined) {\n      return p;\n    }var l = {};var o = b(this.hex, p.vidx);var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      if (o.substr(m[n], 2) === \"80\") {\n        l.kid = h(o, m[n]);\n      }\n    }return l;\n  };this.getExtExtKeyUsageName = function () {\n    var p = this.getExtInfo(\"extKeyUsage\");if (p === undefined) {\n      return p;\n    }var l = new Array();var o = b(this.hex, p.vidx);if (o === \"\") {\n      return l;\n    }var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      l.push(i(h(o, m[n])));\n    }return l;\n  };this.getExtSubjectAltName = function () {\n    var m = this.getExtSubjectAltName2();var l = new Array();for (var n = 0; n < m.length; n++) {\n      if (m[n][0] === \"DNS\") {\n        l.push(m[n][1]);\n      }\n    }return l;\n  };this.getExtSubjectAltName2 = function () {\n    var p, s, r;var q = this.getExtInfo(\"subjectAltName\");if (q === undefined) {\n      return q;\n    }var l = new Array();var o = b(this.hex, q.vidx);var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      r = o.substr(m[n], 2);p = h(o, m[n]);if (r === \"81\") {\n        s = hextoutf8(p);l.push([\"MAIL\", s]);\n      }if (r === \"82\") {\n        s = hextoutf8(p);l.push([\"DNS\", s]);\n      }if (r === \"84\") {\n        s = X509.hex2dn(p, 0);l.push([\"DN\", s]);\n      }if (r === \"86\") {\n        s = hextoutf8(p);l.push([\"URI\", s]);\n      }if (r === \"87\") {\n        s = hextoip(p);l.push([\"IP\", s]);\n      }\n    }return l;\n  };this.getExtCRLDistributionPointsURI = function () {\n    var q = this.getExtInfo(\"cRLDistributionPoints\");if (q === undefined) {\n      return q;\n    }var l = new Array();var m = j(this.hex, q.vidx);for (var o = 0; o < m.length; o++) {\n      try {\n        var r = f(this.hex, m[o], [0, 0, 0], \"86\");var p = hextoutf8(r);l.push(p);\n      } catch (n) {}\n    }return l;\n  };this.getExtAIAInfo = function () {\n    var p = this.getExtInfo(\"authorityInfoAccess\");if (p === undefined) {\n      return p;\n    }var l = { ocsp: [], caissuer: [] };var m = j(this.hex, p.vidx);for (var n = 0; n < m.length; n++) {\n      var q = f(this.hex, m[n], [0], \"06\");var o = f(this.hex, m[n], [1], \"86\");if (q === \"2b06010505073001\") {\n        l.ocsp.push(hextoutf8(o));\n      }if (q === \"2b06010505073002\") {\n        l.caissuer.push(hextoutf8(o));\n      }\n    }return l;\n  };this.getExtCertificatePolicies = function () {\n    var o = this.getExtInfo(\"certificatePolicies\");if (o === undefined) {\n      return o;\n    }var l = b(this.hex, o.vidx);var u = [];var s = j(l, 0);for (var r = 0; r < s.length; r++) {\n      var t = {};var n = j(l, s[r]);t.id = i(h(l, n[0]));if (n.length === 2) {\n        var m = j(l, n[1]);for (var q = 0; q < m.length; q++) {\n          var p = f(l, m[q], [0], \"06\");if (p === \"2b06010505070201\") {\n            t.cps = hextoutf8(f(l, m[q], [1]));\n          } else {\n            if (p === \"2b06010505070202\") {\n              t.unotice = hextoutf8(f(l, m[q], [1, 0]));\n            }\n          }\n        }\n      }u.push(t);\n    }return u;\n  };this.readCertPEM = function (l) {\n    this.readCertHex(e(l));\n  };this.readCertHex = function (l) {\n    this.hex = l;this.getVersion();try {\n      g(this.hex, 0, [0, 7], \"a3\");this.parseExt();\n    } catch (m) {}\n  };this.getInfo = function () {\n    var m = X509;var B, u, z;B = \"Basic Fields\\n\";B += \"  serial number: \" + this.getSerialNumberHex() + \"\\n\";B += \"  signature algorithm: \" + this.getSignatureAlgorithmField() + \"\\n\";B += \"  issuer: \" + this.getIssuerString() + \"\\n\";B += \"  notBefore: \" + this.getNotBefore() + \"\\n\";B += \"  notAfter: \" + this.getNotAfter() + \"\\n\";B += \"  subject: \" + this.getSubjectString() + \"\\n\";B += \"  subject public key info: \\n\";u = this.getPublicKey();B += \"    key algorithm: \" + u.type + \"\\n\";if (u.type === \"RSA\") {\n      B += \"    n=\" + hextoposhex(u.n.toString(16)).substr(0, 16) + \"...\\n\";B += \"    e=\" + hextoposhex(u.e.toString(16)) + \"\\n\";\n    }z = this.aExtInfo;if (z !== undefined && z !== null) {\n      B += \"X509v3 Extensions:\\n\";for (var r = 0; r < z.length; r++) {\n        var n = z[r];var A = KJUR.asn1.x509.OID.oid2name(n.oid);if (A === \"\") {\n          A = n.oid;\n        }var x = \"\";if (n.critical === true) {\n          x = \"CRITICAL\";\n        }B += \"  \" + A + \" \" + x + \":\\n\";if (A === \"basicConstraints\") {\n          var v = this.getExtBasicConstraints();if (v.cA === undefined) {\n            B += \"    {}\\n\";\n          } else {\n            B += \"    cA=true\";if (v.pathLen !== undefined) {\n              B += \", pathLen=\" + v.pathLen;\n            }B += \"\\n\";\n          }\n        } else {\n          if (A === \"keyUsage\") {\n            B += \"    \" + this.getExtKeyUsageString() + \"\\n\";\n          } else {\n            if (A === \"subjectKeyIdentifier\") {\n              B += \"    \" + this.getExtSubjectKeyIdentifier() + \"\\n\";\n            } else {\n              if (A === \"authorityKeyIdentifier\") {\n                var l = this.getExtAuthorityKeyIdentifier();if (l.kid !== undefined) {\n                  B += \"    kid=\" + l.kid + \"\\n\";\n                }\n              } else {\n                if (A === \"extKeyUsage\") {\n                  var w = this.getExtExtKeyUsageName();B += \"    \" + w.join(\", \") + \"\\n\";\n                } else {\n                  if (A === \"subjectAltName\") {\n                    var t = this.getExtSubjectAltName2();B += \"    \" + t + \"\\n\";\n                  } else {\n                    if (A === \"cRLDistributionPoints\") {\n                      var y = this.getExtCRLDistributionPointsURI();B += \"    \" + y + \"\\n\";\n                    } else {\n                      if (A === \"authorityInfoAccess\") {\n                        var p = this.getExtAIAInfo();if (p.ocsp !== undefined) {\n                          B += \"    ocsp: \" + p.ocsp.join(\",\") + \"\\n\";\n                        }if (p.caissuer !== undefined) {\n                          B += \"    caissuer: \" + p.caissuer.join(\",\") + \"\\n\";\n                        }\n                      } else {\n                        if (A === \"certificatePolicies\") {\n                          var o = this.getExtCertificatePolicies();for (var q = 0; q < o.length; q++) {\n                            if (o[q].id !== undefined) {\n                              B += \"    policy oid: \" + o[q].id + \"\\n\";\n                            }if (o[q].cps !== undefined) {\n                              B += \"    cps: \" + o[q].cps + \"\\n\";\n                            }\n                          }\n                        }\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }B += \"signature algorithm: \" + this.getSignatureAlgorithmName() + \"\\n\";B += \"signature: \" + this.getSignatureValueHex().substr(0, 16) + \"...\\n\";return B;\n  };\n}X509.hex2dn = function (f, b) {\n  if (b === undefined) {\n    b = 0;\n  }if (f.substr(b, 2) !== \"30\") {\n    throw \"malformed DN\";\n  }var c = new Array();var d = ASN1HEX.getChildIdx(f, b);for (var e = 0; e < d.length; e++) {\n    c.push(X509.hex2rdn(f, d[e]));\n  }c = c.map(function (a) {\n    return a.replace(\"/\", \"\\\\/\");\n  });return \"/\" + c.join(\"/\");\n};X509.hex2rdn = function (f, b) {\n  if (b === undefined) {\n    b = 0;\n  }if (f.substr(b, 2) !== \"31\") {\n    throw \"malformed RDN\";\n  }var c = new Array();var d = ASN1HEX.getChildIdx(f, b);for (var e = 0; e < d.length; e++) {\n    c.push(X509.hex2attrTypeValue(f, d[e]));\n  }c = c.map(function (a) {\n    return a.replace(\"+\", \"\\\\+\");\n  });return c.join(\"+\");\n};X509.hex2attrTypeValue = function (d, i) {\n  var j = ASN1HEX;var h = j.getV;if (i === undefined) {\n    i = 0;\n  }if (d.substr(i, 2) !== \"30\") {\n    throw \"malformed attribute type and value\";\n  }var g = j.getChildIdx(d, i);if (g.length !== 2 || d.substr(g[0], 2) !== \"06\") {\n    \"malformed attribute type and value\";\n  }var b = h(d, g[0]);var f = KJUR.asn1.ASN1Util.oidHexToInt(b);var e = KJUR.asn1.x509.OID.oid2atype(f);var a = h(d, g[1]);var c = hextorstr(a);return e + \"=\" + c;\n};X509.getPublicKeyFromCertHex = function (b) {\n  var a = new X509();a.readCertHex(b);return a.getPublicKey();\n};X509.getPublicKeyFromCertPEM = function (b) {\n  var a = new X509();a.readCertPEM(b);return a.getPublicKey();\n};X509.getPublicKeyInfoPropOfCertPEM = function (c) {\n  var e = ASN1HEX;var g = e.getVbyList;var b = {};var a, f, d;b.algparam = null;a = new X509();a.readCertPEM(c);f = a.getPublicKeyHex();b.keyhex = g(f, 0, [1], \"03\").substr(2);b.algoid = g(f, 0, [0, 0], \"06\");if (b.algoid === \"2a8648ce3d0201\") {\n    b.algparam = g(f, 0, [0, 1], \"06\");\n  }return b;\n};X509.KEYUSAGE_NAME = [\"digitalSignature\", \"nonRepudiation\", \"keyEncipherment\", \"dataEncipherment\", \"keyAgreement\", \"keyCertSign\", \"cRLSign\", \"encipherOnly\", \"decipherOnly\"];\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.jws == \"undefined\" || !KJUR.jws) {\n  KJUR.jws = {};\n}KJUR.jws.JWS = function () {\n  var b = KJUR,\n      a = b.jws.JWS,\n      c = a.isSafeJSONString;this.parseJWS = function (g, j) {\n    if (this.parsedJWS !== undefined && (j || this.parsedJWS.sigvalH !== undefined)) {\n      return;\n    }var i = g.match(/^([^.]+)\\.([^.]+)\\.([^.]+)$/);if (i == null) {\n      throw \"JWS signature is not a form of 'Head.Payload.SigValue'.\";\n    }var k = i[1];var e = i[2];var l = i[3];var n = k + \".\" + e;this.parsedJWS = {};this.parsedJWS.headB64U = k;this.parsedJWS.payloadB64U = e;this.parsedJWS.sigvalB64U = l;this.parsedJWS.si = n;if (!j) {\n      var h = b64utohex(l);var f = parseBigInt(h, 16);this.parsedJWS.sigvalH = h;this.parsedJWS.sigvalBI = f;\n    }var d = b64utoutf8(k);var m = b64utoutf8(e);this.parsedJWS.headS = d;this.parsedJWS.payloadS = m;if (!c(d, this.parsedJWS, \"headP\")) {\n      throw \"malformed JSON string for JWS Head: \" + d;\n    }\n  };\n};KJUR.jws.JWS.sign = function (i, v, y, z, a) {\n  var w = KJUR,\n      m = w.jws,\n      q = m.JWS,\n      g = q.readSafeJSONString,\n      p = q.isSafeJSONString,\n      d = w.crypto,\n      k = d.ECDSA,\n      o = d.Mac,\n      c = d.Signature,\n      t = JSON;var s, j, n;if (typeof v != \"string\" && (typeof v === \"undefined\" ? \"undefined\" : _typeof(v)) != \"object\") {\n    throw \"spHeader must be JSON string or object: \" + v;\n  }if ((typeof v === \"undefined\" ? \"undefined\" : _typeof(v)) == \"object\") {\n    j = v;s = t.stringify(j);\n  }if (typeof v == \"string\") {\n    s = v;if (!p(s)) {\n      throw \"JWS Head is not safe JSON string: \" + s;\n    }j = g(s);\n  }n = y;if ((typeof y === \"undefined\" ? \"undefined\" : _typeof(y)) == \"object\") {\n    n = t.stringify(y);\n  }if ((i == \"\" || i == null) && j.alg !== undefined) {\n    i = j.alg;\n  }if (i != \"\" && i != null && j.alg === undefined) {\n    j.alg = i;s = t.stringify(j);\n  }if (i !== j.alg) {\n    throw \"alg and sHeader.alg doesn't match: \" + i + \"!=\" + j.alg;\n  }var r = null;if (q.jwsalg2sigalg[i] === undefined) {\n    throw \"unsupported alg name: \" + i;\n  } else {\n    r = q.jwsalg2sigalg[i];\n  }var e = utf8tob64u(s);var l = utf8tob64u(n);var b = e + \".\" + l;var x = \"\";if (r.substr(0, 4) == \"Hmac\") {\n    if (z === undefined) {\n      throw \"mac key shall be specified for HS* alg\";\n    }var h = new o({ alg: r, prov: \"cryptojs\", pass: z });h.updateString(b);x = h.doFinal();\n  } else {\n    if (r.indexOf(\"withECDSA\") != -1) {\n      var f = new c({ alg: r });f.init(z, a);f.updateString(b);hASN1Sig = f.sign();x = KJUR.crypto.ECDSA.asn1SigToConcatSig(hASN1Sig);\n    } else {\n      if (r != \"none\") {\n        var f = new c({ alg: r });f.init(z, a);f.updateString(b);x = f.sign();\n      }\n    }\n  }var u = hextob64u(x);return b + \".\" + u;\n};KJUR.jws.JWS.verify = function (w, B, n) {\n  var x = KJUR,\n      q = x.jws,\n      t = q.JWS,\n      i = t.readSafeJSONString,\n      e = x.crypto,\n      p = e.ECDSA,\n      s = e.Mac,\n      d = e.Signature,\n      m;if ((typeof RSAKey === \"undefined\" ? \"undefined\" : _typeof(RSAKey)) !== undefined) {\n    m = RSAKey;\n  }var y = w.split(\".\");if (y.length !== 3) {\n    return false;\n  }var f = y[0];var r = y[1];var c = f + \".\" + r;var A = b64utohex(y[2]);var l = i(b64utoutf8(y[0]));var k = null;var z = null;if (l.alg === undefined) {\n    throw \"algorithm not specified in header\";\n  } else {\n    k = l.alg;z = k.substr(0, 2);\n  }if (n != null && Object.prototype.toString.call(n) === \"[object Array]\" && n.length > 0) {\n    var b = \":\" + n.join(\":\") + \":\";if (b.indexOf(\":\" + k + \":\") == -1) {\n      throw \"algorithm '\" + k + \"' not accepted in the list\";\n    }\n  }if (k != \"none\" && B === null) {\n    throw \"key shall be specified to verify.\";\n  }if (typeof B == \"string\" && B.indexOf(\"-----BEGIN \") != -1) {\n    B = KEYUTIL.getKey(B);\n  }if (z == \"RS\" || z == \"PS\") {\n    if (!(B instanceof m)) {\n      throw \"key shall be a RSAKey obj for RS* and PS* algs\";\n    }\n  }if (z == \"ES\") {\n    if (!(B instanceof p)) {\n      throw \"key shall be a ECDSA obj for ES* algs\";\n    }\n  }if (k == \"none\") {}var u = null;if (t.jwsalg2sigalg[l.alg] === undefined) {\n    throw \"unsupported alg name: \" + k;\n  } else {\n    u = t.jwsalg2sigalg[k];\n  }if (u == \"none\") {\n    throw \"not supported\";\n  } else {\n    if (u.substr(0, 4) == \"Hmac\") {\n      var o = null;if (B === undefined) {\n        throw \"hexadecimal key shall be specified for HMAC\";\n      }var j = new s({ alg: u, pass: B });j.updateString(c);o = j.doFinal();return A == o;\n    } else {\n      if (u.indexOf(\"withECDSA\") != -1) {\n        var h = null;try {\n          h = p.concatSigToASN1Sig(A);\n        } catch (v) {\n          return false;\n        }var g = new d({ alg: u });g.init(B);g.updateString(c);return g.verify(h);\n      } else {\n        var g = new d({ alg: u });g.init(B);g.updateString(c);return g.verify(A);\n      }\n    }\n  }\n};KJUR.jws.JWS.parse = function (g) {\n  var c = g.split(\".\");var b = {};var f, e, d;if (c.length != 2 && c.length != 3) {\n    throw \"malformed sJWS: wrong number of '.' splitted elements\";\n  }f = c[0];e = c[1];if (c.length == 3) {\n    d = c[2];\n  }b.headerObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(f));b.payloadObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(e));b.headerPP = JSON.stringify(b.headerObj, null, \"  \");if (b.payloadObj == null) {\n    b.payloadPP = b64utoutf8(e);\n  } else {\n    b.payloadPP = JSON.stringify(b.payloadObj, null, \"  \");\n  }if (d !== undefined) {\n    b.sigHex = b64utohex(d);\n  }return b;\n};KJUR.jws.JWS.verifyJWT = function (e, l, r) {\n  var d = KJUR,\n      j = d.jws,\n      o = j.JWS,\n      n = o.readSafeJSONString,\n      p = o.inArray,\n      f = o.includedArray;var k = e.split(\".\");var c = k[0];var i = k[1];var q = c + \".\" + i;var m = b64utohex(k[2]);var h = n(b64utoutf8(c));var g = n(b64utoutf8(i));if (h.alg === undefined) {\n    return false;\n  }if (r.alg === undefined) {\n    throw \"acceptField.alg shall be specified\";\n  }if (!p(h.alg, r.alg)) {\n    return false;\n  }if (g.iss !== undefined && _typeof(r.iss) === \"object\") {\n    if (!p(g.iss, r.iss)) {\n      return false;\n    }\n  }if (g.sub !== undefined && _typeof(r.sub) === \"object\") {\n    if (!p(g.sub, r.sub)) {\n      return false;\n    }\n  }if (g.aud !== undefined && _typeof(r.aud) === \"object\") {\n    if (typeof g.aud == \"string\") {\n      if (!p(g.aud, r.aud)) {\n        return false;\n      }\n    } else {\n      if (_typeof(g.aud) == \"object\") {\n        if (!f(g.aud, r.aud)) {\n          return false;\n        }\n      }\n    }\n  }var b = j.IntDate.getNow();if (r.verifyAt !== undefined && typeof r.verifyAt === \"number\") {\n    b = r.verifyAt;\n  }if (r.gracePeriod === undefined || typeof r.gracePeriod !== \"number\") {\n    r.gracePeriod = 0;\n  }if (g.exp !== undefined && typeof g.exp == \"number\") {\n    if (g.exp + r.gracePeriod < b) {\n      return false;\n    }\n  }if (g.nbf !== undefined && typeof g.nbf == \"number\") {\n    if (b < g.nbf - r.gracePeriod) {\n      return false;\n    }\n  }if (g.iat !== undefined && typeof g.iat == \"number\") {\n    if (b < g.iat - r.gracePeriod) {\n      return false;\n    }\n  }if (g.jti !== undefined && r.jti !== undefined) {\n    if (g.jti !== r.jti) {\n      return false;\n    }\n  }if (!o.verify(e, l, r.alg)) {\n    return false;\n  }return true;\n};KJUR.jws.JWS.includedArray = function (b, a) {\n  var c = KJUR.jws.JWS.inArray;if (b === null) {\n    return false;\n  }if ((typeof b === \"undefined\" ? \"undefined\" : _typeof(b)) !== \"object\") {\n    return false;\n  }if (typeof b.length !== \"number\") {\n    return false;\n  }for (var d = 0; d < b.length; d++) {\n    if (!c(b[d], a)) {\n      return false;\n    }\n  }return true;\n};KJUR.jws.JWS.inArray = function (d, b) {\n  if (b === null) {\n    return false;\n  }if ((typeof b === \"undefined\" ? \"undefined\" : _typeof(b)) !== \"object\") {\n    return false;\n  }if (typeof b.length !== \"number\") {\n    return false;\n  }for (var c = 0; c < b.length; c++) {\n    if (b[c] == d) {\n      return true;\n    }\n  }return false;\n};KJUR.jws.JWS.jwsalg2sigalg = { HS256: \"HmacSHA256\", HS384: \"HmacSHA384\", HS512: \"HmacSHA512\", RS256: \"SHA256withRSA\", RS384: \"SHA384withRSA\", RS512: \"SHA512withRSA\", ES256: \"SHA256withECDSA\", ES384: \"SHA384withECDSA\", PS256: \"SHA256withRSAandMGF1\", PS384: \"SHA384withRSAandMGF1\", PS512: \"SHA512withRSAandMGF1\", none: \"none\" };KJUR.jws.JWS.isSafeJSONString = function (c, b, d) {\n  var e = null;try {\n    e = jsonParse(c);if ((typeof e === \"undefined\" ? \"undefined\" : _typeof(e)) != \"object\") {\n      return 0;\n    }if (e.constructor === Array) {\n      return 0;\n    }if (b) {\n      b[d] = e;\n    }return 1;\n  } catch (a) {\n    return 0;\n  }\n};KJUR.jws.JWS.readSafeJSONString = function (b) {\n  var c = null;try {\n    c = jsonParse(b);if ((typeof c === \"undefined\" ? \"undefined\" : _typeof(c)) != \"object\") {\n      return null;\n    }if (c.constructor === Array) {\n      return null;\n    }return c;\n  } catch (a) {\n    return null;\n  }\n};KJUR.jws.JWS.getEncodedSignatureValueFromJWS = function (b) {\n  var a = b.match(/^[^.]+\\.[^.]+\\.([^.]+)$/);if (a == null) {\n    throw \"JWS signature is not a form of 'Head.Payload.SigValue'.\";\n  }return a[1];\n};KJUR.jws.JWS.getJWKthumbprint = function (d) {\n  if (d.kty !== \"RSA\" && d.kty !== \"EC\" && d.kty !== \"oct\") {\n    throw \"unsupported algorithm for JWK Thumprint\";\n  }var a = \"{\";if (d.kty === \"RSA\") {\n    if (typeof d.n != \"string\" || typeof d.e != \"string\") {\n      throw \"wrong n and e value for RSA key\";\n    }a += '\"e\":\"' + d.e + '\",';a += '\"kty\":\"' + d.kty + '\",';a += '\"n\":\"' + d.n + '\"}';\n  } else {\n    if (d.kty === \"EC\") {\n      if (typeof d.crv != \"string\" || typeof d.x != \"string\" || typeof d.y != \"string\") {\n        throw \"wrong crv, x and y value for EC key\";\n      }a += '\"crv\":\"' + d.crv + '\",';a += '\"kty\":\"' + d.kty + '\",';a += '\"x\":\"' + d.x + '\",';a += '\"y\":\"' + d.y + '\"}';\n    } else {\n      if (d.kty === \"oct\") {\n        if (typeof d.k != \"string\") {\n          throw \"wrong k value for oct(symmetric) key\";\n        }a += '\"kty\":\"' + d.kty + '\",';a += '\"k\":\"' + d.k + '\"}';\n      }\n    }\n  }var b = rstrtohex(a);var c = KJUR.crypto.Util.hashHex(b, \"sha256\");var e = hextob64u(c);return e;\n};KJUR.jws.IntDate = {};KJUR.jws.IntDate.get = function (c) {\n  var b = KJUR.jws.IntDate,\n      d = b.getNow,\n      a = b.getZulu;if (c == \"now\") {\n    return d();\n  } else {\n    if (c == \"now + 1hour\") {\n      return d() + 60 * 60;\n    } else {\n      if (c == \"now + 1day\") {\n        return d() + 60 * 60 * 24;\n      } else {\n        if (c == \"now + 1month\") {\n          return d() + 60 * 60 * 24 * 30;\n        } else {\n          if (c == \"now + 1year\") {\n            return d() + 60 * 60 * 24 * 365;\n          } else {\n            if (c.match(/Z$/)) {\n              return a(c);\n            } else {\n              if (c.match(/^[0-9]+$/)) {\n                return parseInt(c);\n              }\n            }\n          }\n        }\n      }\n    }\n  }throw \"unsupported format: \" + c;\n};KJUR.jws.IntDate.getZulu = function (a) {\n  return zulutosec(a);\n};KJUR.jws.IntDate.getNow = function () {\n  var a = ~~(new Date() / 1000);return a;\n};KJUR.jws.IntDate.intDate2UTCString = function (a) {\n  var b = new Date(a * 1000);return b.toUTCString();\n};KJUR.jws.IntDate.intDate2Zulu = function (e) {\n  var i = new Date(e * 1000),\n      h = (\"0000\" + i.getUTCFullYear()).slice(-4),\n      g = (\"00\" + (i.getUTCMonth() + 1)).slice(-2),\n      b = (\"00\" + i.getUTCDate()).slice(-2),\n      a = (\"00\" + i.getUTCHours()).slice(-2),\n      c = (\"00\" + i.getUTCMinutes()).slice(-2),\n      f = (\"00\" + i.getUTCSeconds()).slice(-2);return h + g + b + a + c + f + \"Z\";\n};\nexports.SecureRandom = SecureRandom;\nexports.rng_seed_time = rng_seed_time;\nexports.BigInteger = BigInteger;\nexports.RSAKey = RSAKey;\nvar EDSA = KJUR.crypto.EDSA;\nexports.EDSA = EDSA;\nvar DSA = KJUR.crypto.DSA;\nexports.DSA = DSA;\nvar Signature = KJUR.crypto.Signature;\nexports.Signature = Signature;\nvar MessageDigest = KJUR.crypto.MessageDigest;\nexports.MessageDigest = MessageDigest;\nvar Mac = KJUR.crypto.Mac;\nexports.Mac = Mac;\nvar Cipher = KJUR.crypto.Cipher;\nexports.Cipher = Cipher;\nexports.KEYUTIL = KEYUTIL;\nexports.ASN1HEX = ASN1HEX;\nexports.X509 = X509;\nexports.CryptoJS = CryptoJS;\n\n// ext/base64.js\n\nexports.b64tohex = b64tohex;\nexports.b64toBA = b64toBA;\n\n// base64x.js\n\nexports.stoBA = stoBA;\nexports.BAtos = BAtos;\nexports.BAtohex = BAtohex;\nexports.stohex = stohex;\nexports.stob64 = stob64;\nexports.stob64u = stob64u;\nexports.b64utos = b64utos;\nexports.b64tob64u = b64tob64u;\nexports.b64utob64 = b64utob64;\nexports.hex2b64 = hex2b64;\nexports.hextob64u = hextob64u;\nexports.b64utohex = b64utohex;\nexports.utf8tob64u = utf8tob64u;\nexports.b64utoutf8 = b64utoutf8;\nexports.utf8tob64 = utf8tob64;\nexports.b64toutf8 = b64toutf8;\nexports.utf8tohex = utf8tohex;\nexports.hextoutf8 = hextoutf8;\nexports.hextorstr = hextorstr;\nexports.rstrtohex = rstrtohex;\nexports.hextob64 = hextob64;\nexports.hextob64nl = hextob64nl;\nexports.b64nltohex = b64nltohex;\nexports.hextopem = hextopem;\nexports.pemtohex = pemtohex;\nexports.hextoArrayBuffer = hextoArrayBuffer;\nexports.ArrayBuffertohex = ArrayBuffertohex;\nexports.zulutomsec = zulutomsec;\nexports.zulutosec = zulutosec;\nexports.zulutodate = zulutodate;\nexports.datetozulu = datetozulu;\nexports.uricmptohex = uricmptohex;\nexports.hextouricmp = hextouricmp;\nexports.ipv6tohex = ipv6tohex;\nexports.hextoipv6 = hextoipv6;\nexports.hextoip = hextoip;\nexports.iptohex = iptohex;\nexports.encodeURIComponentAll = encodeURIComponentAll;\nexports.newline_toUnix = newline_toUnix;\nexports.newline_toDos = newline_toDos;\nexports.hextoposhex = hextoposhex;\nexports.intarystrtohex = intarystrtohex;\nexports.strdiffidx = strdiffidx;\n\n// name spaces\n\nexports.KJUR = KJUR;\n\nvar _crypto = KJUR.crypto;\nexports.crypto = _crypto;\nvar _KJUR = KJUR;\nvar asn1 = _KJUR.asn1;\nexports.asn1 = asn1;\nvar _KJUR2 = KJUR;\nvar jws = _KJUR2.jws;\nexports.jws = jws;\nvar _KJUR3 = KJUR;\nvar lang = _KJUR3.lang;\nexports.lang = lang;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/buffer/index.js */ \"./node_modules/buffer/index.js\").Buffer))\n\n/***/ }),\n\n/***/ \"./node_modules/babel-polyfill/lib/index.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/babel-polyfill/lib/index.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {\n\n__webpack_require__(/*! core-js/shim */ \"./node_modules/core-js/shim.js\");\n\n__webpack_require__(/*! regenerator-runtime/runtime */ \"./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js\");\n\n__webpack_require__(/*! core-js/fn/regexp/escape */ \"./node_modules/core-js/fn/regexp/escape.js\");\n\nif (global._babelPolyfill) {\n  throw new Error(\"only one instance of babel-polyfill is allowed\");\n}\nglobal._babelPolyfill = true;\n\nvar DEFINE_PROPERTY = \"defineProperty\";\nfunction define(O, key, value) {\n  O[key] || Object[DEFINE_PROPERTY](O, key, {\n    writable: true,\n    configurable: true,\n    value: value\n  });\n}\n\ndefine(String.prototype, \"padLeft\", \"\".padStart);\ndefine(String.prototype, \"padRight\", \"\".padEnd);\n\n\"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill\".split(\",\").forEach(function (key) {\n  [][key] && define(Array, key, Function.call.bind([][key]));\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js\":\n/*!*********************************************************************************!*\\\n  !*** ./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js ***!\n  \\*********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(global) {/**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * https://raw.github.com/facebook/regenerator/master/LICENSE file. An\n * additional grant of patent rights can be found in the PATENTS file in\n * the same directory.\n */\n\n!(function(global) {\n  \"use strict\";\n\n  var Op = Object.prototype;\n  var hasOwn = Op.hasOwnProperty;\n  var undefined; // More compressible than void 0.\n  var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n  var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n  var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n  var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n  var inModule = typeof module === \"object\";\n  var runtime = global.regeneratorRuntime;\n  if (runtime) {\n    if (inModule) {\n      // If regeneratorRuntime is defined globally and we're in a module,\n      // make the exports object identical to regeneratorRuntime.\n      module.exports = runtime;\n    }\n    // Don't bother evaluating the rest of this file if the runtime was\n    // already defined globally.\n    return;\n  }\n\n  // Define the runtime globally (as expected by generated code) as either\n  // module.exports (if we're in a module) or a new, empty object.\n  runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n  function wrap(innerFn, outerFn, self, tryLocsList) {\n    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n    var generator = Object.create(protoGenerator.prototype);\n    var context = new Context(tryLocsList || []);\n\n    // The ._invoke method unifies the implementations of the .next,\n    // .throw, and .return methods.\n    generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n    return generator;\n  }\n  runtime.wrap = wrap;\n\n  // Try/catch helper to minimize deoptimizations. Returns a completion\n  // record like context.tryEntries[i].completion. This interface could\n  // have been (and was previously) designed to take a closure to be\n  // invoked without arguments, but in all the cases we care about we\n  // already have an existing method we want to call, so there's no need\n  // to create a new function object. We can even get away with assuming\n  // the method takes exactly one argument, since that happens to be true\n  // in every case, so we don't have to touch the arguments object. The\n  // only additional allocation required is the completion record, which\n  // has a stable shape and so hopefully should be cheap to allocate.\n  function tryCatch(fn, obj, arg) {\n    try {\n      return { type: \"normal\", arg: fn.call(obj, arg) };\n    } catch (err) {\n      return { type: \"throw\", arg: err };\n    }\n  }\n\n  var GenStateSuspendedStart = \"suspendedStart\";\n  var GenStateSuspendedYield = \"suspendedYield\";\n  var GenStateExecuting = \"executing\";\n  var GenStateCompleted = \"completed\";\n\n  // Returning this object from the innerFn has the same effect as\n  // breaking out of the dispatch switch statement.\n  var ContinueSentinel = {};\n\n  // Dummy constructor functions that we use as the .constructor and\n  // .constructor.prototype properties for functions that return Generator\n  // objects. For full spec compliance, you may wish to configure your\n  // minifier not to mangle the names of these two functions.\n  function Generator() {}\n  function GeneratorFunction() {}\n  function GeneratorFunctionPrototype() {}\n\n  // This is a polyfill for %IteratorPrototype% for environments that\n  // don't natively support it.\n  var IteratorPrototype = {};\n  IteratorPrototype[iteratorSymbol] = function () {\n    return this;\n  };\n\n  var getProto = Object.getPrototypeOf;\n  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n  if (NativeIteratorPrototype &&\n      NativeIteratorPrototype !== Op &&\n      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n    // This environment has a native %IteratorPrototype%; use it instead\n    // of the polyfill.\n    IteratorPrototype = NativeIteratorPrototype;\n  }\n\n  var Gp = GeneratorFunctionPrototype.prototype =\n    Generator.prototype = Object.create(IteratorPrototype);\n  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n  GeneratorFunctionPrototype.constructor = GeneratorFunction;\n  GeneratorFunctionPrototype[toStringTagSymbol] =\n    GeneratorFunction.displayName = \"GeneratorFunction\";\n\n  // Helper for defining the .next, .throw, and .return methods of the\n  // Iterator interface in terms of a single ._invoke method.\n  function defineIteratorMethods(prototype) {\n    [\"next\", \"throw\", \"return\"].forEach(function(method) {\n      prototype[method] = function(arg) {\n        return this._invoke(method, arg);\n      };\n    });\n  }\n\n  runtime.isGeneratorFunction = function(genFun) {\n    var ctor = typeof genFun === \"function\" && genFun.constructor;\n    return ctor\n      ? ctor === GeneratorFunction ||\n        // For the native GeneratorFunction constructor, the best we can\n        // do is to check its .name property.\n        (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n      : false;\n  };\n\n  runtime.mark = function(genFun) {\n    if (Object.setPrototypeOf) {\n      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n    } else {\n      genFun.__proto__ = GeneratorFunctionPrototype;\n      if (!(toStringTagSymbol in genFun)) {\n        genFun[toStringTagSymbol] = \"GeneratorFunction\";\n      }\n    }\n    genFun.prototype = Object.create(Gp);\n    return genFun;\n  };\n\n  // Within the body of any async function, `await x` is transformed to\n  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n  // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n  // meant to be awaited.\n  runtime.awrap = function(arg) {\n    return { __await: arg };\n  };\n\n  function AsyncIterator(generator) {\n    function invoke(method, arg, resolve, reject) {\n      var record = tryCatch(generator[method], generator, arg);\n      if (record.type === \"throw\") {\n        reject(record.arg);\n      } else {\n        var result = record.arg;\n        var value = result.value;\n        if (value &&\n            typeof value === \"object\" &&\n            hasOwn.call(value, \"__await\")) {\n          return Promise.resolve(value.__await).then(function(value) {\n            invoke(\"next\", value, resolve, reject);\n          }, function(err) {\n            invoke(\"throw\", err, resolve, reject);\n          });\n        }\n\n        return Promise.resolve(value).then(function(unwrapped) {\n          // When a yielded Promise is resolved, its final value becomes\n          // the .value of the Promise<{value,done}> result for the\n          // current iteration. If the Promise is rejected, however, the\n          // result for this iteration will be rejected with the same\n          // reason. Note that rejections of yielded Promises are not\n          // thrown back into the generator function, as is the case\n          // when an awaited Promise is rejected. This difference in\n          // behavior between yield and await is important, because it\n          // allows the consumer to decide what to do with the yielded\n          // rejection (swallow it and continue, manually .throw it back\n          // into the generator, abandon iteration, whatever). With\n          // await, by contrast, there is no opportunity to examine the\n          // rejection reason outside the generator function, so the\n          // only option is to throw it from the await expression, and\n          // let the generator function handle the exception.\n          result.value = unwrapped;\n          resolve(result);\n        }, reject);\n      }\n    }\n\n    if (typeof global.process === \"object\" && global.process.domain) {\n      invoke = global.process.domain.bind(invoke);\n    }\n\n    var previousPromise;\n\n    function enqueue(method, arg) {\n      function callInvokeWithMethodAndArg() {\n        return new Promise(function(resolve, reject) {\n          invoke(method, arg, resolve, reject);\n        });\n      }\n\n      return previousPromise =\n        // If enqueue has been called before, then we want to wait until\n        // all previous Promises have been resolved before calling invoke,\n        // so that results are always delivered in the correct order. If\n        // enqueue has not been called before, then it is important to\n        // call invoke immediately, without waiting on a callback to fire,\n        // so that the async generator function has the opportunity to do\n        // any necessary setup in a predictable way. This predictability\n        // is why the Promise constructor synchronously invokes its\n        // executor callback, and why async functions synchronously\n        // execute code before the first await. Since we implement simple\n        // async functions in terms of async generators, it is especially\n        // important to get this right, even though it requires care.\n        previousPromise ? previousPromise.then(\n          callInvokeWithMethodAndArg,\n          // Avoid propagating failures to Promises returned by later\n          // invocations of the iterator.\n          callInvokeWithMethodAndArg\n        ) : callInvokeWithMethodAndArg();\n    }\n\n    // Define the unified helper method that is used to implement .next,\n    // .throw, and .return (see defineIteratorMethods).\n    this._invoke = enqueue;\n  }\n\n  defineIteratorMethods(AsyncIterator.prototype);\n  AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n    return this;\n  };\n  runtime.AsyncIterator = AsyncIterator;\n\n  // Note that simple async functions are implemented on top of\n  // AsyncIterator objects; they just return a Promise for the value of\n  // the final result produced by the iterator.\n  runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n    var iter = new AsyncIterator(\n      wrap(innerFn, outerFn, self, tryLocsList)\n    );\n\n    return runtime.isGeneratorFunction(outerFn)\n      ? iter // If outerFn is a generator, return the full iterator.\n      : iter.next().then(function(result) {\n          return result.done ? result.value : iter.next();\n        });\n  };\n\n  function makeInvokeMethod(innerFn, self, context) {\n    var state = GenStateSuspendedStart;\n\n    return function invoke(method, arg) {\n      if (state === GenStateExecuting) {\n        throw new Error(\"Generator is already running\");\n      }\n\n      if (state === GenStateCompleted) {\n        if (method === \"throw\") {\n          throw arg;\n        }\n\n        // Be forgiving, per 25.3.3.3.3 of the spec:\n        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n        return doneResult();\n      }\n\n      context.method = method;\n      context.arg = arg;\n\n      while (true) {\n        var delegate = context.delegate;\n        if (delegate) {\n          var delegateResult = maybeInvokeDelegate(delegate, context);\n          if (delegateResult) {\n            if (delegateResult === ContinueSentinel) continue;\n            return delegateResult;\n          }\n        }\n\n        if (context.method === \"next\") {\n          // Setting context._sent for legacy support of Babel's\n          // function.sent implementation.\n          context.sent = context._sent = context.arg;\n\n        } else if (context.method === \"throw\") {\n          if (state === GenStateSuspendedStart) {\n            state = GenStateCompleted;\n            throw context.arg;\n          }\n\n          context.dispatchException(context.arg);\n\n        } else if (context.method === \"return\") {\n          context.abrupt(\"return\", context.arg);\n        }\n\n        state = GenStateExecuting;\n\n        var record = tryCatch(innerFn, self, context);\n        if (record.type === \"normal\") {\n          // If an exception is thrown from innerFn, we leave state ===\n          // GenStateExecuting and loop back for another invocation.\n          state = context.done\n            ? GenStateCompleted\n            : GenStateSuspendedYield;\n\n          if (record.arg === ContinueSentinel) {\n            continue;\n          }\n\n          return {\n            value: record.arg,\n            done: context.done\n          };\n\n        } else if (record.type === \"throw\") {\n          state = GenStateCompleted;\n          // Dispatch the exception by looping back around to the\n          // context.dispatchException(context.arg) call above.\n          context.method = \"throw\";\n          context.arg = record.arg;\n        }\n      }\n    };\n  }\n\n  // Call delegate.iterator[context.method](context.arg) and handle the\n  // result, either by returning a { value, done } result from the\n  // delegate iterator, or by modifying context.method and context.arg,\n  // setting context.delegate to null, and returning the ContinueSentinel.\n  function maybeInvokeDelegate(delegate, context) {\n    var method = delegate.iterator[context.method];\n    if (method === undefined) {\n      // A .throw or .return when the delegate iterator has no .throw\n      // method always terminates the yield* loop.\n      context.delegate = null;\n\n      if (context.method === \"throw\") {\n        if (delegate.iterator.return) {\n          // If the delegate iterator has a return method, give it a\n          // chance to clean up.\n          context.method = \"return\";\n          context.arg = undefined;\n          maybeInvokeDelegate(delegate, context);\n\n          if (context.method === \"throw\") {\n            // If maybeInvokeDelegate(context) changed context.method from\n            // \"return\" to \"throw\", let that override the TypeError below.\n            return ContinueSentinel;\n          }\n        }\n\n        context.method = \"throw\";\n        context.arg = new TypeError(\n          \"The iterator does not provide a 'throw' method\");\n      }\n\n      return ContinueSentinel;\n    }\n\n    var record = tryCatch(method, delegate.iterator, context.arg);\n\n    if (record.type === \"throw\") {\n      context.method = \"throw\";\n      context.arg = record.arg;\n      context.delegate = null;\n      return ContinueSentinel;\n    }\n\n    var info = record.arg;\n\n    if (! info) {\n      context.method = \"throw\";\n      context.arg = new TypeError(\"iterator result is not an object\");\n      context.delegate = null;\n      return ContinueSentinel;\n    }\n\n    if (info.done) {\n      // Assign the result of the finished delegate to the temporary\n      // variable specified by delegate.resultName (see delegateYield).\n      context[delegate.resultName] = info.value;\n\n      // Resume execution at the desired location (see delegateYield).\n      context.next = delegate.nextLoc;\n\n      // If context.method was \"throw\" but the delegate handled the\n      // exception, let the outer generator proceed normally. If\n      // context.method was \"next\", forget context.arg since it has been\n      // \"consumed\" by the delegate iterator. If context.method was\n      // \"return\", allow the original .return call to continue in the\n      // outer generator.\n      if (context.method !== \"return\") {\n        context.method = \"next\";\n        context.arg = undefined;\n      }\n\n    } else {\n      // Re-yield the result returned by the delegate method.\n      return info;\n    }\n\n    // The delegate iterator is finished, so forget it and continue with\n    // the outer generator.\n    context.delegate = null;\n    return ContinueSentinel;\n  }\n\n  // Define Generator.prototype.{next,throw,return} in terms of the\n  // unified ._invoke helper method.\n  defineIteratorMethods(Gp);\n\n  Gp[toStringTagSymbol] = \"Generator\";\n\n  // A Generator should always return itself as the iterator object when the\n  // @@iterator function is called on it. Some browsers' implementations of the\n  // iterator prototype chain incorrectly implement this, causing the Generator\n  // object to not be returned from this call. This ensures that doesn't happen.\n  // See https://github.com/facebook/regenerator/issues/274 for more details.\n  Gp[iteratorSymbol] = function() {\n    return this;\n  };\n\n  Gp.toString = function() {\n    return \"[object Generator]\";\n  };\n\n  function pushTryEntry(locs) {\n    var entry = { tryLoc: locs[0] };\n\n    if (1 in locs) {\n      entry.catchLoc = locs[1];\n    }\n\n    if (2 in locs) {\n      entry.finallyLoc = locs[2];\n      entry.afterLoc = locs[3];\n    }\n\n    this.tryEntries.push(entry);\n  }\n\n  function resetTryEntry(entry) {\n    var record = entry.completion || {};\n    record.type = \"normal\";\n    delete record.arg;\n    entry.completion = record;\n  }\n\n  function Context(tryLocsList) {\n    // The root entry object (effectively a try statement without a catch\n    // or a finally block) gives us a place to store values thrown from\n    // locations where there is no enclosing try statement.\n    this.tryEntries = [{ tryLoc: \"root\" }];\n    tryLocsList.forEach(pushTryEntry, this);\n    this.reset(true);\n  }\n\n  runtime.keys = function(object) {\n    var keys = [];\n    for (var key in object) {\n      keys.push(key);\n    }\n    keys.reverse();\n\n    // Rather than returning an object with a next method, we keep\n    // things simple and return the next function itself.\n    return function next() {\n      while (keys.length) {\n        var key = keys.pop();\n        if (key in object) {\n          next.value = key;\n          next.done = false;\n          return next;\n        }\n      }\n\n      // To avoid creating an additional object, we just hang the .value\n      // and .done properties off the next function object itself. This\n      // also ensures that the minifier will not anonymize the function.\n      next.done = true;\n      return next;\n    };\n  };\n\n  function values(iterable) {\n    if (iterable) {\n      var iteratorMethod = iterable[iteratorSymbol];\n      if (iteratorMethod) {\n        return iteratorMethod.call(iterable);\n      }\n\n      if (typeof iterable.next === \"function\") {\n        return iterable;\n      }\n\n      if (!isNaN(iterable.length)) {\n        var i = -1, next = function next() {\n          while (++i < iterable.length) {\n            if (hasOwn.call(iterable, i)) {\n              next.value = iterable[i];\n              next.done = false;\n              return next;\n            }\n          }\n\n          next.value = undefined;\n          next.done = true;\n\n          return next;\n        };\n\n        return next.next = next;\n      }\n    }\n\n    // Return an iterator with no values.\n    return { next: doneResult };\n  }\n  runtime.values = values;\n\n  function doneResult() {\n    return { value: undefined, done: true };\n  }\n\n  Context.prototype = {\n    constructor: Context,\n\n    reset: function(skipTempReset) {\n      this.prev = 0;\n      this.next = 0;\n      // Resetting context._sent for legacy support of Babel's\n      // function.sent implementation.\n      this.sent = this._sent = undefined;\n      this.done = false;\n      this.delegate = null;\n\n      this.method = \"next\";\n      this.arg = undefined;\n\n      this.tryEntries.forEach(resetTryEntry);\n\n      if (!skipTempReset) {\n        for (var name in this) {\n          // Not sure about the optimal order of these conditions:\n          if (name.charAt(0) === \"t\" &&\n              hasOwn.call(this, name) &&\n              !isNaN(+name.slice(1))) {\n            this[name] = undefined;\n          }\n        }\n      }\n    },\n\n    stop: function() {\n      this.done = true;\n\n      var rootEntry = this.tryEntries[0];\n      var rootRecord = rootEntry.completion;\n      if (rootRecord.type === \"throw\") {\n        throw rootRecord.arg;\n      }\n\n      return this.rval;\n    },\n\n    dispatchException: function(exception) {\n      if (this.done) {\n        throw exception;\n      }\n\n      var context = this;\n      function handle(loc, caught) {\n        record.type = \"throw\";\n        record.arg = exception;\n        context.next = loc;\n\n        if (caught) {\n          // If the dispatched exception was caught by a catch block,\n          // then let that catch block handle the exception normally.\n          context.method = \"next\";\n          context.arg = undefined;\n        }\n\n        return !! caught;\n      }\n\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        var record = entry.completion;\n\n        if (entry.tryLoc === \"root\") {\n          // Exception thrown outside of any try block that could handle\n          // it, so set the completion value of the entire function to\n          // throw the exception.\n          return handle(\"end\");\n        }\n\n        if (entry.tryLoc <= this.prev) {\n          var hasCatch = hasOwn.call(entry, \"catchLoc\");\n          var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n          if (hasCatch && hasFinally) {\n            if (this.prev < entry.catchLoc) {\n              return handle(entry.catchLoc, true);\n            } else if (this.prev < entry.finallyLoc) {\n              return handle(entry.finallyLoc);\n            }\n\n          } else if (hasCatch) {\n            if (this.prev < entry.catchLoc) {\n              return handle(entry.catchLoc, true);\n            }\n\n          } else if (hasFinally) {\n            if (this.prev < entry.finallyLoc) {\n              return handle(entry.finallyLoc);\n            }\n\n          } else {\n            throw new Error(\"try statement without catch or finally\");\n          }\n        }\n      }\n    },\n\n    abrupt: function(type, arg) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.tryLoc <= this.prev &&\n            hasOwn.call(entry, \"finallyLoc\") &&\n            this.prev < entry.finallyLoc) {\n          var finallyEntry = entry;\n          break;\n        }\n      }\n\n      if (finallyEntry &&\n          (type === \"break\" ||\n           type === \"continue\") &&\n          finallyEntry.tryLoc <= arg &&\n          arg <= finallyEntry.finallyLoc) {\n        // Ignore the finally entry if control is not jumping to a\n        // location outside the try/catch block.\n        finallyEntry = null;\n      }\n\n      var record = finallyEntry ? finallyEntry.completion : {};\n      record.type = type;\n      record.arg = arg;\n\n      if (finallyEntry) {\n        this.method = \"next\";\n        this.next = finallyEntry.finallyLoc;\n        return ContinueSentinel;\n      }\n\n      return this.complete(record);\n    },\n\n    complete: function(record, afterLoc) {\n      if (record.type === \"throw\") {\n        throw record.arg;\n      }\n\n      if (record.type === \"break\" ||\n          record.type === \"continue\") {\n        this.next = record.arg;\n      } else if (record.type === \"return\") {\n        this.rval = this.arg = record.arg;\n        this.method = \"return\";\n        this.next = \"end\";\n      } else if (record.type === \"normal\" && afterLoc) {\n        this.next = afterLoc;\n      }\n\n      return ContinueSentinel;\n    },\n\n    finish: function(finallyLoc) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.finallyLoc === finallyLoc) {\n          this.complete(entry.completion, entry.afterLoc);\n          resetTryEntry(entry);\n          return ContinueSentinel;\n        }\n      }\n    },\n\n    \"catch\": function(tryLoc) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.tryLoc === tryLoc) {\n          var record = entry.completion;\n          if (record.type === \"throw\") {\n            var thrown = record.arg;\n            resetTryEntry(entry);\n          }\n          return thrown;\n        }\n      }\n\n      // The context.catch method must only be called with a location\n      // argument that corresponds to a known catch block.\n      throw new Error(\"illegal catch attempt\");\n    },\n\n    delegateYield: function(iterable, resultName, nextLoc) {\n      this.delegate = {\n        iterator: values(iterable),\n        resultName: resultName,\n        nextLoc: nextLoc\n      };\n\n      if (this.method === \"next\") {\n        // Deliberately forget the last sent value so that we don't\n        // accidentally pass it on to the delegate.\n        this.arg = undefined;\n      }\n\n      return ContinueSentinel;\n    }\n  };\n})(\n  // Among the various tricks for obtaining a reference to the global\n  // object, this seems to be the most reliable technique that does not\n  // use indirect eval (which violates Content Security Policy).\n  typeof global === \"object\" ? global :\n  typeof window === \"object\" ? window :\n  typeof self === \"object\" ? self : this\n);\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./node_modules/base64-js/index.js\":\n/*!*****************************************!*\\\n  !*** ./node_modules/base64-js/index.js ***!\n  \\*****************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  var validLen = b64.indexOf('=')\n  if (validLen === -1) validLen = len\n\n  var placeHoldersLen = validLen === len\n    ? 0\n    : 4 - (validLen % 4)\n\n  return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n  var tmp\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n\n  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n  var curByte = 0\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  var len = placeHoldersLen > 0\n    ? validLen - 4\n    : validLen\n\n  for (var i = 0; i < len; i += 4) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 18) |\n      (revLookup[b64.charCodeAt(i + 1)] << 12) |\n      (revLookup[b64.charCodeAt(i + 2)] << 6) |\n      revLookup[b64.charCodeAt(i + 3)]\n    arr[curByte++] = (tmp >> 16) & 0xFF\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 2) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 2) |\n      (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 1) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 10) |\n      (revLookup[b64.charCodeAt(i + 1)] << 4) |\n      (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] +\n    lookup[num >> 12 & 0x3F] +\n    lookup[num >> 6 & 0x3F] +\n    lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp =\n      ((uint8[i] << 16) & 0xFF0000) +\n      ((uint8[i + 1] << 8) & 0xFF00) +\n      (uint8[i + 2] & 0xFF)\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(\n      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n    ))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 2] +\n      lookup[(tmp << 4) & 0x3F] +\n      '=='\n    )\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 10] +\n      lookup[(tmp >> 4) & 0x3F] +\n      lookup[(tmp << 2) & 0x3F] +\n      '='\n    )\n  }\n\n  return parts.join('')\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/buffer/index.js\":\n/*!**************************************!*\\\n  !*** ./node_modules/buffer/index.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(/*! base64-js */ \"./node_modules/base64-js/index.js\")\nvar ieee754 = __webpack_require__(/*! ieee754 */ \"./node_modules/ieee754/index.js\")\nvar isArray = __webpack_require__(/*! isarray */ \"./node_modules/buffer/node_modules/isarray/index.js\")\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./node_modules/buffer/node_modules/isarray/index.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/buffer/node_modules/isarray/index.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/regexp/escape.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/fn/regexp/escape.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/core.regexp.escape */ \"./node_modules/core-js/modules/core.regexp.escape.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").RegExp.escape;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_a-function.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_a-function.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_a-number-value.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_a-number-value.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nmodule.exports = function (it, msg) {\n  if (typeof it != 'number' && cof(it) != 'Number') throw TypeError(msg);\n  return +it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_add-to-unscopables.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_add-to-unscopables.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.31 Array.prototype[@@unscopables]\nvar UNSCOPABLES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('unscopables');\nvar ArrayProto = Array.prototype;\nif (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(ArrayProto, UNSCOPABLES, {});\nmodule.exports = function (key) {\n  ArrayProto[UNSCOPABLES][key] = true;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_advance-string-index.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_advance-string-index.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n // `AdvanceStringIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-advancestringindex\nmodule.exports = function (S, index, unicode) {\n  return index + (unicode ? at(S, index).length : 1);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-instance.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-instance.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it, Constructor, name, forbiddenField) {\n  if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {\n    throw TypeError(name + ': incorrect invocation!');\n  } return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nmodule.exports = function (it) {\n  if (!isObject(it)) throw TypeError(it + ' is not an object!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-copy-within.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-copy-within.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)\n\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n\nmodule.exports = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {\n  var O = toObject(this);\n  var len = toLength(O.length);\n  var to = toAbsoluteIndex(target, len);\n  var from = toAbsoluteIndex(start, len);\n  var end = arguments.length > 2 ? arguments[2] : undefined;\n  var count = Math.min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);\n  var inc = 1;\n  if (from < to && to < from + count) {\n    inc = -1;\n    from += count - 1;\n    to += count - 1;\n  }\n  while (count-- > 0) {\n    if (from in O) O[to] = O[from];\n    else delete O[to];\n    to += inc;\n    from += inc;\n  } return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-fill.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-fill.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)\n\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nmodule.exports = function fill(value /* , start = 0, end = @length */) {\n  var O = toObject(this);\n  var length = toLength(O.length);\n  var aLen = arguments.length;\n  var index = toAbsoluteIndex(aLen > 1 ? arguments[1] : undefined, length);\n  var end = aLen > 2 ? arguments[2] : undefined;\n  var endPos = end === undefined ? length : toAbsoluteIndex(end, length);\n  while (endPos > index) O[index++] = value;\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-from-iterable.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-from-iterable.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\n\nmodule.exports = function (iter, ITERATOR) {\n  var result = [];\n  forOf(iter, false, result.push, result, ITERATOR);\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-includes.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-includes.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// false -> Array#indexOf\n// true  -> Array#includes\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nmodule.exports = function (IS_INCLUDES) {\n  return function ($this, el, fromIndex) {\n    var O = toIObject($this);\n    var length = toLength(O.length);\n    var index = toAbsoluteIndex(fromIndex, length);\n    var value;\n    // Array#includes uses SameValueZero equality algorithm\n    // eslint-disable-next-line no-self-compare\n    if (IS_INCLUDES && el != el) while (length > index) {\n      value = O[index++];\n      // eslint-disable-next-line no-self-compare\n      if (value != value) return true;\n    // Array#indexOf ignores holes, Array#includes - not\n    } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n      if (O[index] === el) return IS_INCLUDES || index || 0;\n    } return !IS_INCLUDES && -1;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-methods.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-methods.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 0 -> Array#forEach\n// 1 -> Array#map\n// 2 -> Array#filter\n// 3 -> Array#some\n// 4 -> Array#every\n// 5 -> Array#find\n// 6 -> Array#findIndex\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar asc = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\nmodule.exports = function (TYPE, $create) {\n  var IS_MAP = TYPE == 1;\n  var IS_FILTER = TYPE == 2;\n  var IS_SOME = TYPE == 3;\n  var IS_EVERY = TYPE == 4;\n  var IS_FIND_INDEX = TYPE == 6;\n  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;\n  var create = $create || asc;\n  return function ($this, callbackfn, that) {\n    var O = toObject($this);\n    var self = IObject(O);\n    var f = ctx(callbackfn, that, 3);\n    var length = toLength(self.length);\n    var index = 0;\n    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;\n    var val, res;\n    for (;length > index; index++) if (NO_HOLES || index in self) {\n      val = self[index];\n      res = f(val, index, O);\n      if (TYPE) {\n        if (IS_MAP) result[index] = res;   // map\n        else if (res) switch (TYPE) {\n          case 3: return true;             // some\n          case 5: return val;              // find\n          case 6: return index;            // findIndex\n          case 2: result.push(val);        // filter\n        } else if (IS_EVERY) return false; // every\n      }\n    }\n    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-reduce.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-reduce.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n\nmodule.exports = function (that, callbackfn, aLen, memo, isRight) {\n  aFunction(callbackfn);\n  var O = toObject(that);\n  var self = IObject(O);\n  var length = toLength(O.length);\n  var index = isRight ? length - 1 : 0;\n  var i = isRight ? -1 : 1;\n  if (aLen < 2) for (;;) {\n    if (index in self) {\n      memo = self[index];\n      index += i;\n      break;\n    }\n    index += i;\n    if (isRight ? index < 0 : length <= index) {\n      throw TypeError('Reduce of empty array with no initial value');\n    }\n  }\n  for (;isRight ? index >= 0 : length > index; index += i) if (index in self) {\n    memo = callbackfn(memo, self[index], index, O);\n  }\n  return memo;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-constructor.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-constructor.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (original) {\n  var C;\n  if (isArray(original)) {\n    C = original.constructor;\n    // cross-realm fallback\n    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;\n    if (isObject(C)) {\n      C = C[SPECIES];\n      if (C === null) C = undefined;\n    }\n  } return C === undefined ? Array : C;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-create.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-create.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 9.4.2.3 ArraySpeciesCreate(originalArray, length)\nvar speciesConstructor = __webpack_require__(/*! ./_array-species-constructor */ \"./node_modules/core-js/modules/_array-species-constructor.js\");\n\nmodule.exports = function (original, length) {\n  return new (speciesConstructor(original))(length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_bind.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_bind.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar arraySlice = [].slice;\nvar factories = {};\n\nvar construct = function (F, len, args) {\n  if (!(len in factories)) {\n    for (var n = [], i = 0; i < len; i++) n[i] = 'a[' + i + ']';\n    // eslint-disable-next-line no-new-func\n    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');\n  } return factories[len](F, args);\n};\n\nmodule.exports = Function.bind || function bind(that /* , ...args */) {\n  var fn = aFunction(this);\n  var partArgs = arraySlice.call(arguments, 1);\n  var bound = function (/* args... */) {\n    var args = partArgs.concat(arraySlice.call(arguments));\n    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);\n  };\n  if (isObject(fn.prototype)) bound.prototype = fn.prototype;\n  return bound;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_classof.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_classof.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n  try {\n    return it[key];\n  } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n  var O, T, B;\n  return it === undefined ? 'Undefined' : it === null ? 'Null'\n    // @@toStringTag case\n    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n    // builtinTag case\n    : ARG ? cof(O)\n    // ES3 arguments fallback\n    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_cof.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_cof.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = function (it) {\n  return toString.call(it).slice(8, -1);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection-strong.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection-strong.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar $iterDefine = __webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\");\nvar step = __webpack_require__(/*! ./_iter-step */ \"./node_modules/core-js/modules/_iter-step.js\");\nvar setSpecies = __webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar fastKey = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").fastKey;\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar SIZE = DESCRIPTORS ? '_s' : 'size';\n\nvar getEntry = function (that, key) {\n  // fast case\n  var index = fastKey(key);\n  var entry;\n  if (index !== 'F') return that._i[index];\n  // frozen object case\n  for (entry = that._f; entry; entry = entry.n) {\n    if (entry.k == key) return entry;\n  }\n};\n\nmodule.exports = {\n  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {\n    var C = wrapper(function (that, iterable) {\n      anInstance(that, C, NAME, '_i');\n      that._t = NAME;         // collection type\n      that._i = create(null); // index\n      that._f = undefined;    // first entry\n      that._l = undefined;    // last entry\n      that[SIZE] = 0;         // size\n      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);\n    });\n    redefineAll(C.prototype, {\n      // 23.1.3.1 Map.prototype.clear()\n      // 23.2.3.2 Set.prototype.clear()\n      clear: function clear() {\n        for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {\n          entry.r = true;\n          if (entry.p) entry.p = entry.p.n = undefined;\n          delete data[entry.i];\n        }\n        that._f = that._l = undefined;\n        that[SIZE] = 0;\n      },\n      // 23.1.3.3 Map.prototype.delete(key)\n      // 23.2.3.4 Set.prototype.delete(value)\n      'delete': function (key) {\n        var that = validate(this, NAME);\n        var entry = getEntry(that, key);\n        if (entry) {\n          var next = entry.n;\n          var prev = entry.p;\n          delete that._i[entry.i];\n          entry.r = true;\n          if (prev) prev.n = next;\n          if (next) next.p = prev;\n          if (that._f == entry) that._f = next;\n          if (that._l == entry) that._l = prev;\n          that[SIZE]--;\n        } return !!entry;\n      },\n      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)\n      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)\n      forEach: function forEach(callbackfn /* , that = undefined */) {\n        validate(this, NAME);\n        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);\n        var entry;\n        while (entry = entry ? entry.n : this._f) {\n          f(entry.v, entry.k, this);\n          // revert to the last existing entry\n          while (entry && entry.r) entry = entry.p;\n        }\n      },\n      // 23.1.3.7 Map.prototype.has(key)\n      // 23.2.3.7 Set.prototype.has(value)\n      has: function has(key) {\n        return !!getEntry(validate(this, NAME), key);\n      }\n    });\n    if (DESCRIPTORS) dP(C.prototype, 'size', {\n      get: function () {\n        return validate(this, NAME)[SIZE];\n      }\n    });\n    return C;\n  },\n  def: function (that, key, value) {\n    var entry = getEntry(that, key);\n    var prev, index;\n    // change existing entry\n    if (entry) {\n      entry.v = value;\n    // create new entry\n    } else {\n      that._l = entry = {\n        i: index = fastKey(key, true), // <- index\n        k: key,                        // <- key\n        v: value,                      // <- value\n        p: prev = that._l,             // <- previous entry\n        n: undefined,                  // <- next entry\n        r: false                       // <- removed\n      };\n      if (!that._f) that._f = entry;\n      if (prev) prev.n = entry;\n      that[SIZE]++;\n      // add to index\n      if (index !== 'F') that._i[index] = entry;\n    } return that;\n  },\n  getEntry: getEntry,\n  setStrong: function (C, NAME, IS_MAP) {\n    // add .keys, .values, .entries, [@@iterator]\n    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11\n    $iterDefine(C, NAME, function (iterated, kind) {\n      this._t = validate(iterated, NAME); // target\n      this._k = kind;                     // kind\n      this._l = undefined;                // previous\n    }, function () {\n      var that = this;\n      var kind = that._k;\n      var entry = that._l;\n      // revert to the last existing entry\n      while (entry && entry.r) entry = entry.p;\n      // get next entry\n      if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {\n        // or finish the iteration\n        that._t = undefined;\n        return step(1);\n      }\n      // return step by kind\n      if (kind == 'keys') return step(0, entry.k);\n      if (kind == 'values') return step(0, entry.v);\n      return step(0, [entry.k, entry.v]);\n    }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);\n\n    // add [@@species], 23.1.2.2, 23.2.2.2\n    setSpecies(NAME);\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection-to-json.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection-to-json.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar from = __webpack_require__(/*! ./_array-from-iterable */ \"./node_modules/core-js/modules/_array-from-iterable.js\");\nmodule.exports = function (NAME) {\n  return function toJSON() {\n    if (classof(this) != NAME) throw TypeError(NAME + \"#toJSON isn't generic\");\n    return from(this);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection-weak.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection-weak.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar getWeak = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").getWeak;\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar createArrayMethod = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\");\nvar $has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar arrayFind = createArrayMethod(5);\nvar arrayFindIndex = createArrayMethod(6);\nvar id = 0;\n\n// fallback for uncaught frozen keys\nvar uncaughtFrozenStore = function (that) {\n  return that._l || (that._l = new UncaughtFrozenStore());\n};\nvar UncaughtFrozenStore = function () {\n  this.a = [];\n};\nvar findUncaughtFrozen = function (store, key) {\n  return arrayFind(store.a, function (it) {\n    return it[0] === key;\n  });\n};\nUncaughtFrozenStore.prototype = {\n  get: function (key) {\n    var entry = findUncaughtFrozen(this, key);\n    if (entry) return entry[1];\n  },\n  has: function (key) {\n    return !!findUncaughtFrozen(this, key);\n  },\n  set: function (key, value) {\n    var entry = findUncaughtFrozen(this, key);\n    if (entry) entry[1] = value;\n    else this.a.push([key, value]);\n  },\n  'delete': function (key) {\n    var index = arrayFindIndex(this.a, function (it) {\n      return it[0] === key;\n    });\n    if (~index) this.a.splice(index, 1);\n    return !!~index;\n  }\n};\n\nmodule.exports = {\n  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {\n    var C = wrapper(function (that, iterable) {\n      anInstance(that, C, NAME, '_i');\n      that._t = NAME;      // collection type\n      that._i = id++;      // collection id\n      that._l = undefined; // leak store for uncaught frozen objects\n      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);\n    });\n    redefineAll(C.prototype, {\n      // 23.3.3.2 WeakMap.prototype.delete(key)\n      // 23.4.3.3 WeakSet.prototype.delete(value)\n      'delete': function (key) {\n        if (!isObject(key)) return false;\n        var data = getWeak(key);\n        if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key);\n        return data && $has(data, this._i) && delete data[this._i];\n      },\n      // 23.3.3.4 WeakMap.prototype.has(key)\n      // 23.4.3.4 WeakSet.prototype.has(value)\n      has: function has(key) {\n        if (!isObject(key)) return false;\n        var data = getWeak(key);\n        if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key);\n        return data && $has(data, this._i);\n      }\n    });\n    return C;\n  },\n  def: function (that, key, value) {\n    var data = getWeak(anObject(key), true);\n    if (data === true) uncaughtFrozenStore(that).set(key, value);\n    else data[that._i] = value;\n    return that;\n  },\n  ufstore: uncaughtFrozenStore\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar $iterDetect = __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ \"./node_modules/core-js/modules/_inherit-if-required.js\");\n\nmodule.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {\n  var Base = global[NAME];\n  var C = Base;\n  var ADDER = IS_MAP ? 'set' : 'add';\n  var proto = C && C.prototype;\n  var O = {};\n  var fixMethod = function (KEY) {\n    var fn = proto[KEY];\n    redefine(proto, KEY,\n      KEY == 'delete' ? function (a) {\n        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'has' ? function has(a) {\n        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'get' ? function get(a) {\n        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; }\n        : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; }\n    );\n  };\n  if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () {\n    new C().entries().next();\n  }))) {\n    // create collection constructor\n    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);\n    redefineAll(C.prototype, methods);\n    meta.NEED = true;\n  } else {\n    var instance = new C();\n    // early implementations not supports chaining\n    var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;\n    // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false\n    var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });\n    // most early implementations doesn't supports iterables, most modern - not close it correctly\n    var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new\n    // for early implementations -0 and +0 not the same\n    var BUGGY_ZERO = !IS_WEAK && fails(function () {\n      // V8 ~ Chromium 42- fails only with 5+ elements\n      var $instance = new C();\n      var index = 5;\n      while (index--) $instance[ADDER](index, index);\n      return !$instance.has(-0);\n    });\n    if (!ACCEPT_ITERABLES) {\n      C = wrapper(function (target, iterable) {\n        anInstance(target, C, NAME);\n        var that = inheritIfRequired(new Base(), target, C);\n        if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);\n        return that;\n      });\n      C.prototype = proto;\n      proto.constructor = C;\n    }\n    if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {\n      fixMethod('delete');\n      fixMethod('has');\n      IS_MAP && fixMethod('get');\n    }\n    if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);\n    // weak collections should not contains .clear method\n    if (IS_WEAK && proto.clear) delete proto.clear;\n  }\n\n  setToStringTag(C, NAME);\n\n  O[NAME] = C;\n  $export($export.G + $export.W + $export.F * (C != Base), O);\n\n  if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);\n\n  return C;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_core.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_core.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar core = module.exports = { version: '2.6.4' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_create-property.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_create-property.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\n\nmodule.exports = function (object, index, value) {\n  if (index in object) $defineProperty.f(object, index, createDesc(0, value));\n  else object[index] = value;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ctx.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_ctx.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// optional / simple context binding\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nmodule.exports = function (fn, that, length) {\n  aFunction(fn);\n  if (that === undefined) return fn;\n  switch (length) {\n    case 1: return function (a) {\n      return fn.call(that, a);\n    };\n    case 2: return function (a, b) {\n      return fn.call(that, a, b);\n    };\n    case 3: return function (a, b, c) {\n      return fn.call(that, a, b, c);\n    };\n  }\n  return function (/* ...args */) {\n    return fn.apply(that, arguments);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_date-to-iso-string.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_date-to-iso-string.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar getTime = Date.prototype.getTime;\nvar $toISOString = Date.prototype.toISOString;\n\nvar lz = function (num) {\n  return num > 9 ? num : '0' + num;\n};\n\n// PhantomJS / old WebKit has a broken implementations\nmodule.exports = (fails(function () {\n  return $toISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z';\n}) || !fails(function () {\n  $toISOString.call(new Date(NaN));\n})) ? function toISOString() {\n  if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value');\n  var d = this;\n  var y = d.getUTCFullYear();\n  var m = d.getUTCMilliseconds();\n  var s = y < 0 ? '-' : y > 9999 ? '+' : '';\n  return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +\n    '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +\n    'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +\n    ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';\n} : $toISOString;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_date-to-primitive.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_date-to-primitive.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar NUMBER = 'number';\n\nmodule.exports = function (hint) {\n  if (hint !== 'string' && hint !== NUMBER && hint !== 'default') throw TypeError('Incorrect hint');\n  return toPrimitive(anObject(this), hint != NUMBER);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_defined.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_defined.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n  if (it == undefined) throw TypeError(\"Can't call method on  \" + it);\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_descriptors.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_descriptors.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_dom-create.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_dom-create.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n  return is ? document.createElement(it) : {};\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_enum-bug-keys.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_enum-bug-keys.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// IE 8- don't enum bug keys\nmodule.exports = (\n  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_enum-keys.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_enum-keys.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// all enumerable object keys, includes symbols\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nmodule.exports = function (it) {\n  var result = getKeys(it);\n  var getSymbols = gOPS.f;\n  if (getSymbols) {\n    var symbols = getSymbols(it);\n    var isEnum = pIE.f;\n    var i = 0;\n    var key;\n    while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key);\n  } return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_export.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_export.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n  var IS_FORCED = type & $export.F;\n  var IS_GLOBAL = type & $export.G;\n  var IS_STATIC = type & $export.S;\n  var IS_PROTO = type & $export.P;\n  var IS_BIND = type & $export.B;\n  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n  var key, own, out, exp;\n  if (IS_GLOBAL) source = name;\n  for (key in source) {\n    // contains in native\n    own = !IS_FORCED && target && target[key] !== undefined;\n    // export native or passed\n    out = (own ? target : source)[key];\n    // bind timers to global for call from export context\n    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n    // extend global\n    if (target) redefine(target, key, out, type & $export.U);\n    // export\n    if (exports[key] != out) hide(exports, key, exp);\n    if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n  }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1;   // forced\n$export.G = 2;   // global\n$export.S = 4;   // static\n$export.P = 8;   // proto\n$export.B = 16;  // bind\n$export.W = 32;  // wrap\n$export.U = 64;  // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fails-is-regexp.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fails-is-regexp.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar MATCH = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('match');\nmodule.exports = function (KEY) {\n  var re = /./;\n  try {\n    '/./'[KEY](re);\n  } catch (e) {\n    try {\n      re[MATCH] = false;\n      return !'/./'[KEY](re);\n    } catch (f) { /* empty */ }\n  } return true;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fails.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fails.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return !!exec();\n  } catch (e) {\n    return true;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fix-re-wks.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fix-re-wks.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n__webpack_require__(/*! ./es6.regexp.exec */ \"./node_modules/core-js/modules/es6.regexp.exec.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar regexpExec = __webpack_require__(/*! ./_regexp-exec */ \"./node_modules/core-js/modules/_regexp-exec.js\");\n\nvar SPECIES = wks('species');\n\nvar REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {\n  // #replace needs built-in support for named groups.\n  // #match works fine because it just return the exec results, even if it has\n  // a \"grops\" property.\n  var re = /./;\n  re.exec = function () {\n    var result = [];\n    result.groups = { a: '7' };\n    return result;\n  };\n  return ''.replace(re, '$<a>') !== '7';\n});\n\nvar SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () {\n  // Chrome 51 has a buggy \"split\" implementation when RegExp#exec !== nativeExec\n  var re = /(?:)/;\n  var originalExec = re.exec;\n  re.exec = function () { return originalExec.apply(this, arguments); };\n  var result = 'ab'.split(re);\n  return result.length === 2 && result[0] === 'a' && result[1] === 'b';\n})();\n\nmodule.exports = function (KEY, length, exec) {\n  var SYMBOL = wks(KEY);\n\n  var DELEGATES_TO_SYMBOL = !fails(function () {\n    // String methods call symbol-named RegEp methods\n    var O = {};\n    O[SYMBOL] = function () { return 7; };\n    return ''[KEY](O) != 7;\n  });\n\n  var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !fails(function () {\n    // Symbol-named RegExp methods call .exec\n    var execCalled = false;\n    var re = /a/;\n    re.exec = function () { execCalled = true; return null; };\n    if (KEY === 'split') {\n      // RegExp[@@split] doesn't call the regex's exec method, but first creates\n      // a new one. We need to return the patched regex when creating the new one.\n      re.constructor = {};\n      re.constructor[SPECIES] = function () { return re; };\n    }\n    re[SYMBOL]('');\n    return !execCalled;\n  }) : undefined;\n\n  if (\n    !DELEGATES_TO_SYMBOL ||\n    !DELEGATES_TO_EXEC ||\n    (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||\n    (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)\n  ) {\n    var nativeRegExpMethod = /./[SYMBOL];\n    var fns = exec(\n      defined,\n      SYMBOL,\n      ''[KEY],\n      function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {\n        if (regexp.exec === regexpExec) {\n          if (DELEGATES_TO_SYMBOL && !forceStringMethod) {\n            // The native String method already delegates to @@method (this\n            // polyfilled function), leasing to infinite recursion.\n            // We avoid it by directly calling the native @@method method.\n            return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };\n          }\n          return { done: true, value: nativeMethod.call(str, regexp, arg2) };\n        }\n        return { done: false };\n      }\n    );\n    var strfn = fns[0];\n    var rxfn = fns[1];\n\n    redefine(String.prototype, KEY, strfn);\n    hide(RegExp.prototype, SYMBOL, length == 2\n      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n      // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n      ? function (string, arg) { return rxfn.call(string, this, arg); }\n      // 21.2.5.6 RegExp.prototype[@@match](string)\n      // 21.2.5.9 RegExp.prototype[@@search](string)\n      : function (string) { return rxfn.call(string, this); }\n    );\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_flags.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_flags.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 21.2.5.3 get RegExp.prototype.flags\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nmodule.exports = function () {\n  var that = anObject(this);\n  var result = '';\n  if (that.global) result += 'g';\n  if (that.ignoreCase) result += 'i';\n  if (that.multiline) result += 'm';\n  if (that.unicode) result += 'u';\n  if (that.sticky) result += 'y';\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_flatten-into-array.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_flatten-into-array.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar IS_CONCAT_SPREADABLE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('isConcatSpreadable');\n\nfunction flattenIntoArray(target, original, source, sourceLen, start, depth, mapper, thisArg) {\n  var targetIndex = start;\n  var sourceIndex = 0;\n  var mapFn = mapper ? ctx(mapper, thisArg, 3) : false;\n  var element, spreadable;\n\n  while (sourceIndex < sourceLen) {\n    if (sourceIndex in source) {\n      element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];\n\n      spreadable = false;\n      if (isObject(element)) {\n        spreadable = element[IS_CONCAT_SPREADABLE];\n        spreadable = spreadable !== undefined ? !!spreadable : isArray(element);\n      }\n\n      if (spreadable && depth > 0) {\n        targetIndex = flattenIntoArray(target, original, element, toLength(element.length), targetIndex, depth - 1) - 1;\n      } else {\n        if (targetIndex >= 0x1fffffffffffff) throw TypeError();\n        target[targetIndex] = element;\n      }\n\n      targetIndex++;\n    }\n    sourceIndex++;\n  }\n  return targetIndex;\n}\n\nmodule.exports = flattenIntoArray;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_for-of.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_for-of.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar call = __webpack_require__(/*! ./_iter-call */ \"./node_modules/core-js/modules/_iter-call.js\");\nvar isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\nvar BREAK = {};\nvar RETURN = {};\nvar exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {\n  var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);\n  var f = ctx(fn, that, entries ? 2 : 1);\n  var index = 0;\n  var length, step, iterator, result;\n  if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');\n  // fast case for arrays with default iterator\n  if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {\n    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n    if (result === BREAK || result === RETURN) return result;\n  } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {\n    result = call(iterator, f, step.value, entries);\n    if (result === BREAK || result === RETURN) return result;\n  }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_function-to-string.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_function-to-string.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('native-function-to-string', Function.toString);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_global.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_global.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n  ? window : typeof self != 'undefined' && self.Math == Math ? self\n  // eslint-disable-next-line no-new-func\n  : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_has.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_has.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n  return hasOwnProperty.call(it, key);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_hide.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_hide.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? function (object, key, value) {\n  return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n  object[key] = value;\n  return object;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_html.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_html.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\nmodule.exports = document && document.documentElement;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ie8-dom-define.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_ie8-dom-define.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_inherit-if-required.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_inherit-if-required.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar setPrototypeOf = __webpack_require__(/*! ./_set-proto */ \"./node_modules/core-js/modules/_set-proto.js\").set;\nmodule.exports = function (that, target, C) {\n  var S = target.constructor;\n  var P;\n  if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {\n    setPrototypeOf(that, P);\n  } return that;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_invoke.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_invoke.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function (fn, args, that) {\n  var un = that === undefined;\n  switch (args.length) {\n    case 0: return un ? fn()\n                      : fn.call(that);\n    case 1: return un ? fn(args[0])\n                      : fn.call(that, args[0]);\n    case 2: return un ? fn(args[0], args[1])\n                      : fn.call(that, args[0], args[1]);\n    case 3: return un ? fn(args[0], args[1], args[2])\n                      : fn.call(that, args[0], args[1], args[2]);\n    case 4: return un ? fn(args[0], args[1], args[2], args[3])\n                      : fn.call(that, args[0], args[1], args[2], args[3]);\n  } return fn.apply(that, args);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iobject.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iobject.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n  return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array-iter.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array-iter.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// check on default Array iterator\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar ArrayProto = Array.prototype;\n\nmodule.exports = function (it) {\n  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.2.2 IsArray(argument)\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nmodule.exports = Array.isArray || function isArray(arg) {\n  return cof(arg) == 'Array';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-integer.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-integer.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.3 Number.isInteger(number)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar floor = Math.floor;\nmodule.exports = function isInteger(it) {\n  return !isObject(it) && isFinite(it) && floor(it) === it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-regexp.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-regexp.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.2.8 IsRegExp(argument)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar MATCH = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('match');\nmodule.exports = function (it) {\n  var isRegExp;\n  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-call.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-call.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// call something on iterator step with safe closing on error\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nmodule.exports = function (iterator, fn, value, entries) {\n  try {\n    return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n  // 7.4.6 IteratorClose(iterator, completion)\n  } catch (e) {\n    var ret = iterator['return'];\n    if (ret !== undefined) anObject(ret.call(iterator));\n    throw e;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-create.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-create.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar descriptor = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\n__webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(IteratorPrototype, __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n  Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n  setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-define.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-define.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar $iterCreate = __webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n  $iterCreate(Constructor, NAME, next);\n  var getMethod = function (kind) {\n    if (!BUGGY && kind in proto) return proto[kind];\n    switch (kind) {\n      case KEYS: return function keys() { return new Constructor(this, kind); };\n      case VALUES: return function values() { return new Constructor(this, kind); };\n    } return function entries() { return new Constructor(this, kind); };\n  };\n  var TAG = NAME + ' Iterator';\n  var DEF_VALUES = DEFAULT == VALUES;\n  var VALUES_BUG = false;\n  var proto = Base.prototype;\n  var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n  var $default = $native || getMethod(DEFAULT);\n  var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n  var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n  var methods, key, IteratorPrototype;\n  // Fix native\n  if ($anyNative) {\n    IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n    if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n      // Set @@toStringTag to native iterators\n      setToStringTag(IteratorPrototype, TAG, true);\n      // fix for some old engines\n      if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n    }\n  }\n  // fix Array#{values, @@iterator}.name in V8 / FF\n  if (DEF_VALUES && $native && $native.name !== VALUES) {\n    VALUES_BUG = true;\n    $default = function values() { return $native.call(this); };\n  }\n  // Define iterator\n  if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n    hide(proto, ITERATOR, $default);\n  }\n  // Plug for library\n  Iterators[NAME] = $default;\n  Iterators[TAG] = returnThis;\n  if (DEFAULT) {\n    methods = {\n      values: DEF_VALUES ? $default : getMethod(VALUES),\n      keys: IS_SET ? $default : getMethod(KEYS),\n      entries: $entries\n    };\n    if (FORCED) for (key in methods) {\n      if (!(key in proto)) redefine(proto, key, methods[key]);\n    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n  }\n  return methods;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-detect.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-detect.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n  var riter = [7][ITERATOR]();\n  riter['return'] = function () { SAFE_CLOSING = true; };\n  // eslint-disable-next-line no-throw-literal\n  Array.from(riter, function () { throw 2; });\n} catch (e) { /* empty */ }\n\nmodule.exports = function (exec, skipClosing) {\n  if (!skipClosing && !SAFE_CLOSING) return false;\n  var safe = false;\n  try {\n    var arr = [7];\n    var iter = arr[ITERATOR]();\n    iter.next = function () { return { done: safe = true }; };\n    arr[ITERATOR] = function () { return iter; };\n    exec(arr);\n  } catch (e) { /* empty */ }\n  return safe;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-step.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-step.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (done, value) {\n  return { value: value, done: !!done };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iterators.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iterators.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = {};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_library.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_library.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = false;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-expm1.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-expm1.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 20.2.2.14 Math.expm1(x)\nvar $expm1 = Math.expm1;\nmodule.exports = (!$expm1\n  // Old FF bug\n  || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168\n  // Tor Browser bug\n  || $expm1(-2e-17) != -2e-17\n) ? function expm1(x) {\n  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;\n} : $expm1;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-fround.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-fround.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.16 Math.fround(x)\nvar sign = __webpack_require__(/*! ./_math-sign */ \"./node_modules/core-js/modules/_math-sign.js\");\nvar pow = Math.pow;\nvar EPSILON = pow(2, -52);\nvar EPSILON32 = pow(2, -23);\nvar MAX32 = pow(2, 127) * (2 - EPSILON32);\nvar MIN32 = pow(2, -126);\n\nvar roundTiesToEven = function (n) {\n  return n + 1 / EPSILON - 1 / EPSILON;\n};\n\nmodule.exports = Math.fround || function fround(x) {\n  var $abs = Math.abs(x);\n  var $sign = sign(x);\n  var a, result;\n  if ($abs < MIN32) return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;\n  a = (1 + EPSILON32 / EPSILON) * $abs;\n  result = a - (a - $abs);\n  // eslint-disable-next-line no-self-compare\n  if (result > MAX32 || result != result) return $sign * Infinity;\n  return $sign * result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-log1p.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-log1p.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 20.2.2.20 Math.log1p(x)\nmodule.exports = Math.log1p || function log1p(x) {\n  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-scale.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-scale.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nmodule.exports = Math.scale || function scale(x, inLow, inHigh, outLow, outHigh) {\n  if (\n    arguments.length === 0\n      // eslint-disable-next-line no-self-compare\n      || x != x\n      // eslint-disable-next-line no-self-compare\n      || inLow != inLow\n      // eslint-disable-next-line no-self-compare\n      || inHigh != inHigh\n      // eslint-disable-next-line no-self-compare\n      || outLow != outLow\n      // eslint-disable-next-line no-self-compare\n      || outHigh != outHigh\n  ) return NaN;\n  if (x === Infinity || x === -Infinity) return x;\n  return (x - inLow) * (outHigh - outLow) / (inHigh - inLow) + outLow;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-sign.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-sign.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 20.2.2.28 Math.sign(x)\nmodule.exports = Math.sign || function sign(x) {\n  // eslint-disable-next-line no-self-compare\n  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_meta.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_meta.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar META = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\")('meta');\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar setDesc = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar id = 0;\nvar isExtensible = Object.isExtensible || function () {\n  return true;\n};\nvar FREEZE = !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function (it) {\n  setDesc(it, META, { value: {\n    i: 'O' + ++id, // object ID\n    w: {}          // weak collections IDs\n  } });\n};\nvar fastKey = function (it, create) {\n  // return primitive with prefix\n  if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n  if (!has(it, META)) {\n    // can't set metadata to uncaught frozen object\n    if (!isExtensible(it)) return 'F';\n    // not necessary to add metadata\n    if (!create) return 'E';\n    // add missing metadata\n    setMeta(it);\n  // return object ID\n  } return it[META].i;\n};\nvar getWeak = function (it, create) {\n  if (!has(it, META)) {\n    // can't set metadata to uncaught frozen object\n    if (!isExtensible(it)) return true;\n    // not necessary to add metadata\n    if (!create) return false;\n    // add missing metadata\n    setMeta(it);\n  // return hash weak collections IDs\n  } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function (it) {\n  if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);\n  return it;\n};\nvar meta = module.exports = {\n  KEY: META,\n  NEED: false,\n  fastKey: fastKey,\n  getWeak: getWeak,\n  onFreeze: onFreeze\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_metadata.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_metadata.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Map = __webpack_require__(/*! ./es6.map */ \"./node_modules/core-js/modules/es6.map.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('metadata');\nvar store = shared.store || (shared.store = new (__webpack_require__(/*! ./es6.weak-map */ \"./node_modules/core-js/modules/es6.weak-map.js\"))());\n\nvar getOrCreateMetadataMap = function (target, targetKey, create) {\n  var targetMetadata = store.get(target);\n  if (!targetMetadata) {\n    if (!create) return undefined;\n    store.set(target, targetMetadata = new Map());\n  }\n  var keyMetadata = targetMetadata.get(targetKey);\n  if (!keyMetadata) {\n    if (!create) return undefined;\n    targetMetadata.set(targetKey, keyMetadata = new Map());\n  } return keyMetadata;\n};\nvar ordinaryHasOwnMetadata = function (MetadataKey, O, P) {\n  var metadataMap = getOrCreateMetadataMap(O, P, false);\n  return metadataMap === undefined ? false : metadataMap.has(MetadataKey);\n};\nvar ordinaryGetOwnMetadata = function (MetadataKey, O, P) {\n  var metadataMap = getOrCreateMetadataMap(O, P, false);\n  return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);\n};\nvar ordinaryDefineOwnMetadata = function (MetadataKey, MetadataValue, O, P) {\n  getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);\n};\nvar ordinaryOwnMetadataKeys = function (target, targetKey) {\n  var metadataMap = getOrCreateMetadataMap(target, targetKey, false);\n  var keys = [];\n  if (metadataMap) metadataMap.forEach(function (_, key) { keys.push(key); });\n  return keys;\n};\nvar toMetaKey = function (it) {\n  return it === undefined || typeof it == 'symbol' ? it : String(it);\n};\nvar exp = function (O) {\n  $export($export.S, 'Reflect', O);\n};\n\nmodule.exports = {\n  store: store,\n  map: getOrCreateMetadataMap,\n  has: ordinaryHasOwnMetadata,\n  get: ordinaryGetOwnMetadata,\n  set: ordinaryDefineOwnMetadata,\n  keys: ordinaryOwnMetadataKeys,\n  key: toMetaKey,\n  exp: exp\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_microtask.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_microtask.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar macrotask = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar Observer = global.MutationObserver || global.WebKitMutationObserver;\nvar process = global.process;\nvar Promise = global.Promise;\nvar isNode = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process';\n\nmodule.exports = function () {\n  var head, last, notify;\n\n  var flush = function () {\n    var parent, fn;\n    if (isNode && (parent = process.domain)) parent.exit();\n    while (head) {\n      fn = head.fn;\n      head = head.next;\n      try {\n        fn();\n      } catch (e) {\n        if (head) notify();\n        else last = undefined;\n        throw e;\n      }\n    } last = undefined;\n    if (parent) parent.enter();\n  };\n\n  // Node.js\n  if (isNode) {\n    notify = function () {\n      process.nextTick(flush);\n    };\n  // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339\n  } else if (Observer && !(global.navigator && global.navigator.standalone)) {\n    var toggle = true;\n    var node = document.createTextNode('');\n    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new\n    notify = function () {\n      node.data = toggle = !toggle;\n    };\n  // environments with maybe non-completely correct, but existent Promise\n  } else if (Promise && Promise.resolve) {\n    // Promise.resolve without an argument throws an error in LG WebOS 2\n    var promise = Promise.resolve(undefined);\n    notify = function () {\n      promise.then(flush);\n    };\n  // for other environments - macrotask based on:\n  // - setImmediate\n  // - MessageChannel\n  // - window.postMessag\n  // - onreadystatechange\n  // - setTimeout\n  } else {\n    notify = function () {\n      // strange IE + webpack dev server bug - use .call(global)\n      macrotask.call(global, flush);\n    };\n  }\n\n  return function (fn) {\n    var task = { fn: fn, next: undefined };\n    if (last) last.next = task;\n    if (!head) {\n      head = task;\n      notify();\n    } last = task;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_new-promise-capability.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_new-promise-capability.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 25.4.1.5 NewPromiseCapability(C)\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\n\nfunction PromiseCapability(C) {\n  var resolve, reject;\n  this.promise = new C(function ($$resolve, $$reject) {\n    if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n    resolve = $$resolve;\n    reject = $$reject;\n  });\n  this.resolve = aFunction(resolve);\n  this.reject = aFunction(reject);\n}\n\nmodule.exports.f = function (C) {\n  return new PromiseCapability(C);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-assign.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-assign.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  var A = {};\n  var B = {};\n  // eslint-disable-next-line no-undef\n  var S = Symbol();\n  var K = 'abcdefghijklmnopqrst';\n  A[S] = 7;\n  K.split('').forEach(function (k) { B[k] = k; });\n  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source) { // eslint-disable-line no-unused-vars\n  var T = toObject(target);\n  var aLen = arguments.length;\n  var index = 1;\n  var getSymbols = gOPS.f;\n  var isEnum = pIE.f;\n  while (aLen > index) {\n    var S = IObject(arguments[index++]);\n    var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);\n    var length = keys.length;\n    var j = 0;\n    var key;\n    while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];\n  } return T;\n} : $assign;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-create.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-create.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar dPs = __webpack_require__(/*! ./_object-dps */ \"./node_modules/core-js/modules/_object-dps.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n  // Thrash, waste and sodomy: IE GC bug\n  var iframe = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('iframe');\n  var i = enumBugKeys.length;\n  var lt = '<';\n  var gt = '>';\n  var iframeDocument;\n  iframe.style.display = 'none';\n  __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\").appendChild(iframe);\n  iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n  // createDict = iframe.contentWindow.Object;\n  // html.removeChild(iframe);\n  iframeDocument = iframe.contentWindow.document;\n  iframeDocument.open();\n  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n  iframeDocument.close();\n  createDict = iframeDocument.F;\n  while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n  return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n  var result;\n  if (O !== null) {\n    Empty[PROTOTYPE] = anObject(O);\n    result = new Empty();\n    Empty[PROTOTYPE] = null;\n    // add \"__proto__\" for Object.getPrototypeOf polyfill\n    result[IE_PROTO] = O;\n  } else result = createDict();\n  return Properties === undefined ? result : dPs(result, Properties);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dp.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dp.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ \"./node_modules/core-js/modules/_ie8-dom-define.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar dP = Object.defineProperty;\n\nexports.f = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n  anObject(O);\n  P = toPrimitive(P, true);\n  anObject(Attributes);\n  if (IE8_DOM_DEFINE) try {\n    return dP(O, P, Attributes);\n  } catch (e) { /* empty */ }\n  if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n  if ('value' in Attributes) O[P] = Attributes.value;\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dps.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dps.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\n\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperties : function defineProperties(O, Properties) {\n  anObject(O);\n  var keys = getKeys(Properties);\n  var length = keys.length;\n  var i = 0;\n  var P;\n  while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-forced-pam.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-forced-pam.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// Forced replacement prototype accessors methods\nmodule.exports = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\") || !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  var K = Math.random();\n  // In FF throws only define methods\n  // eslint-disable-next-line no-undef, no-useless-call\n  __defineSetter__.call(null, K, function () { /* empty */ });\n  delete __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\")[K];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gopd.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gopd.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ \"./node_modules/core-js/modules/_ie8-dom-define.js\");\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? gOPD : function getOwnPropertyDescriptor(O, P) {\n  O = toIObject(O);\n  P = toPrimitive(P, true);\n  if (IE8_DOM_DEFINE) try {\n    return gOPD(O, P);\n  } catch (e) { /* empty */ }\n  if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gopn-ext.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gopn-ext.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar toString = {}.toString;\n\nvar windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames\n  ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function (it) {\n  try {\n    return gOPN(it);\n  } catch (e) {\n    return windowNames.slice();\n  }\n};\n\nmodule.exports.f = function getOwnPropertyNames(it) {\n  return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gopn.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gopn.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = __webpack_require__(/*! ./_object-keys-internal */ \"./node_modules/core-js/modules/_object-keys-internal.js\");\nvar hiddenKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\").concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n  return $keys(O, hiddenKeys);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gops.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gops.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = Object.getOwnPropertySymbols;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gpo.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gpo.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n  O = toObject(O);\n  if (has(O, IE_PROTO)) return O[IE_PROTO];\n  if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n    return O.constructor.prototype;\n  } return O instanceof Object ? ObjectProto : null;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys-internal.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys-internal.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar arrayIndexOf = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(false);\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\n\nmodule.exports = function (object, names) {\n  var O = toIObject(object);\n  var i = 0;\n  var result = [];\n  var key;\n  for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n  // Don't enum bug & hidden keys\n  while (names.length > i) if (has(O, key = names[i++])) {\n    ~arrayIndexOf(result, key) || result.push(key);\n  }\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = __webpack_require__(/*! ./_object-keys-internal */ \"./node_modules/core-js/modules/_object-keys-internal.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\n\nmodule.exports = Object.keys || function keys(O) {\n  return $keys(O, enumBugKeys);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-pie.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-pie.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = {}.propertyIsEnumerable;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-sap.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-sap.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// most Object methods by ES6 should accept primitives\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nmodule.exports = function (KEY, exec) {\n  var fn = (core.Object || {})[KEY] || Object[KEY];\n  var exp = {};\n  exp[KEY] = exec(fn);\n  $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-to-array.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-to-array.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar isEnum = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\").f;\nmodule.exports = function (isEntries) {\n  return function (it) {\n    var O = toIObject(it);\n    var keys = getKeys(O);\n    var length = keys.length;\n    var i = 0;\n    var result = [];\n    var key;\n    while (length > i) if (isEnum.call(O, key = keys[i++])) {\n      result.push(isEntries ? [key, O[key]] : O[key]);\n    } return result;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_own-keys.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_own-keys.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// all object keys, includes non-enumerable and symbols\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar Reflect = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Reflect;\nmodule.exports = Reflect && Reflect.ownKeys || function ownKeys(it) {\n  var keys = gOPN.f(anObject(it));\n  var getSymbols = gOPS.f;\n  return getSymbols ? keys.concat(getSymbols(it)) : keys;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_parse-float.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_parse-float.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $parseFloat = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").parseFloat;\nvar $trim = __webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\").trim;\n\nmodule.exports = 1 / $parseFloat(__webpack_require__(/*! ./_string-ws */ \"./node_modules/core-js/modules/_string-ws.js\") + '-0') !== -Infinity ? function parseFloat(str) {\n  var string = $trim(String(str), 3);\n  var result = $parseFloat(string);\n  return result === 0 && string.charAt(0) == '-' ? -0 : result;\n} : $parseFloat;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_parse-int.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_parse-int.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $parseInt = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").parseInt;\nvar $trim = __webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\").trim;\nvar ws = __webpack_require__(/*! ./_string-ws */ \"./node_modules/core-js/modules/_string-ws.js\");\nvar hex = /^[-+]?0[xX]/;\n\nmodule.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix) {\n  var string = $trim(String(str), 3);\n  return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));\n} : $parseInt;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_perform.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_perform.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return { e: false, v: exec() };\n  } catch (e) {\n    return { e: true, v: e };\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_promise-resolve.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_promise-resolve.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar newPromiseCapability = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\n\nmodule.exports = function (C, x) {\n  anObject(C);\n  if (isObject(x) && x.constructor === C) return x;\n  var promiseCapability = newPromiseCapability.f(C);\n  var resolve = promiseCapability.resolve;\n  resolve(x);\n  return promiseCapability.promise;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_property-desc.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_property-desc.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (bitmap, value) {\n  return {\n    enumerable: !(bitmap & 1),\n    configurable: !(bitmap & 2),\n    writable: !(bitmap & 4),\n    value: value\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine-all.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine-all.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nmodule.exports = function (target, src, safe) {\n  for (var key in src) redefine(target, key, src[key], safe);\n  return target;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar SRC = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\")('src');\nvar $toString = __webpack_require__(/*! ./_function-to-string */ \"./node_modules/core-js/modules/_function-to-string.js\");\nvar TO_STRING = 'toString';\nvar TPL = ('' + $toString).split(TO_STRING);\n\n__webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").inspectSource = function (it) {\n  return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n  var isFunction = typeof val == 'function';\n  if (isFunction) has(val, 'name') || hide(val, 'name', key);\n  if (O[key] === val) return;\n  if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n  if (O === global) {\n    O[key] = val;\n  } else if (!safe) {\n    delete O[key];\n    hide(O, key, val);\n  } else if (O[key]) {\n    O[key] = val;\n  } else {\n    hide(O, key, val);\n  }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n  return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_regexp-exec-abstract.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar builtinExec = RegExp.prototype.exec;\n\n // `RegExpExec` abstract operation\n// https://tc39.github.io/ecma262/#sec-regexpexec\nmodule.exports = function (R, S) {\n  var exec = R.exec;\n  if (typeof exec === 'function') {\n    var result = exec.call(R, S);\n    if (typeof result !== 'object') {\n      throw new TypeError('RegExp exec method returned something other than an Object or null');\n    }\n    return result;\n  }\n  if (classof(R) !== 'RegExp') {\n    throw new TypeError('RegExp#exec called on incompatible receiver');\n  }\n  return builtinExec.call(R, S);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_regexp-exec.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_regexp-exec.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar regexpFlags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\n\nvar nativeExec = RegExp.prototype.exec;\n// This always refers to the native implementation, because the\n// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,\n// which loads this file before patching the method.\nvar nativeReplace = String.prototype.replace;\n\nvar patchedExec = nativeExec;\n\nvar LAST_INDEX = 'lastIndex';\n\nvar UPDATES_LAST_INDEX_WRONG = (function () {\n  var re1 = /a/,\n      re2 = /b*/g;\n  nativeExec.call(re1, 'a');\n  nativeExec.call(re2, 'a');\n  return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;\n})();\n\n// nonparticipating capturing group, copied from es5-shim's String#split patch.\nvar NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;\n\nvar PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;\n\nif (PATCH) {\n  patchedExec = function exec(str) {\n    var re = this;\n    var lastIndex, reCopy, match, i;\n\n    if (NPCG_INCLUDED) {\n      reCopy = new RegExp('^' + re.source + '$(?!\\\\s)', regexpFlags.call(re));\n    }\n    if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];\n\n    match = nativeExec.call(re, str);\n\n    if (UPDATES_LAST_INDEX_WRONG && match) {\n      re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;\n    }\n    if (NPCG_INCLUDED && match && match.length > 1) {\n      // Fix browsers whose `exec` methods don't consistently return `undefined`\n      // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/\n      // eslint-disable-next-line no-loop-func\n      nativeReplace.call(match[0], reCopy, function () {\n        for (i = 1; i < arguments.length - 2; i++) {\n          if (arguments[i] === undefined) match[i] = undefined;\n        }\n      });\n    }\n\n    return match;\n  };\n}\n\nmodule.exports = patchedExec;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_replacer.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_replacer.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (regExp, replace) {\n  var replacer = replace === Object(replace) ? function (part) {\n    return replace[part];\n  } : replace;\n  return function (it) {\n    return String(it).replace(regExp, replacer);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_same-value.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_same-value.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.2.9 SameValue(x, y)\nmodule.exports = Object.is || function is(x, y) {\n  // eslint-disable-next-line no-self-compare\n  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-collection-from.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-collection-from.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-setmap-offrom/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\n\nmodule.exports = function (COLLECTION) {\n  $export($export.S, COLLECTION, { from: function from(source /* , mapFn, thisArg */) {\n    var mapFn = arguments[1];\n    var mapping, A, n, cb;\n    aFunction(this);\n    mapping = mapFn !== undefined;\n    if (mapping) aFunction(mapFn);\n    if (source == undefined) return new this();\n    A = [];\n    if (mapping) {\n      n = 0;\n      cb = ctx(mapFn, arguments[2], 2);\n      forOf(source, false, function (nextItem) {\n        A.push(cb(nextItem, n++));\n      });\n    } else {\n      forOf(source, false, A.push, A);\n    }\n    return new this(A);\n  } });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-collection-of.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-collection-of.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-setmap-offrom/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\nmodule.exports = function (COLLECTION) {\n  $export($export.S, COLLECTION, { of: function of() {\n    var length = arguments.length;\n    var A = new Array(length);\n    while (length--) A[length] = arguments[length];\n    return new this(A);\n  } });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-proto.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-proto.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar check = function (O, proto) {\n  anObject(O);\n  if (!isObject(proto) && proto !== null) throw TypeError(proto + \": can't set as prototype!\");\n};\nmodule.exports = {\n  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line\n    function (test, buggy, set) {\n      try {\n        set = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\")(Function.call, __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f(Object.prototype, '__proto__').set, 2);\n        set(test, []);\n        buggy = !(test instanceof Array);\n      } catch (e) { buggy = true; }\n      return function setPrototypeOf(O, proto) {\n        check(O, proto);\n        if (buggy) O.__proto__ = proto;\n        else set(O, proto);\n        return O;\n      };\n    }({}, false) : undefined),\n  check: check\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-species.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-species.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (KEY) {\n  var C = global[KEY];\n  if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {\n    configurable: true,\n    get: function () { return this; }\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-to-string-tag.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-to-string-tag.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar def = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n  if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared-key.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared-key.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('keys');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nmodule.exports = function (key) {\n  return shared[key] || (shared[key] = uid(key));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n  return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n  version: core.version,\n  mode: __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\") ? 'pure' : 'global',\n  copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_species-constructor.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_species-constructor.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\nmodule.exports = function (O, D) {\n  var C = anObject(O).constructor;\n  var S;\n  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_strict-method.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_strict-method.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\n\nmodule.exports = function (method, arg) {\n  return !!method && fails(function () {\n    // eslint-disable-next-line no-useless-call\n    arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-at.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-at.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n// true  -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n  return function (that, pos) {\n    var s = String(defined(that));\n    var i = toInteger(pos);\n    var l = s.length;\n    var a, b;\n    if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n    a = s.charCodeAt(i);\n    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n      ? TO_STRING ? s.charAt(i) : a\n      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-context.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-context.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// helper for String#{startsWith, endsWith, includes}\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n\nmodule.exports = function (that, searchString, NAME) {\n  if (isRegExp(searchString)) throw TypeError('String#' + NAME + \" doesn't accept regex!\");\n  return String(defined(that));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-html.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-html.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar quot = /\"/g;\n// B.2.3.2.1 CreateHTML(string, tag, attribute, value)\nvar createHTML = function (string, tag, attribute, value) {\n  var S = String(defined(string));\n  var p1 = '<' + tag;\n  if (attribute !== '') p1 += ' ' + attribute + '=\"' + String(value).replace(quot, '&quot;') + '\"';\n  return p1 + '>' + S + '</' + tag + '>';\n};\nmodule.exports = function (NAME, exec) {\n  var O = {};\n  O[NAME] = exec(createHTML);\n  $export($export.P + $export.F * fails(function () {\n    var test = ''[NAME]('\"');\n    return test !== test.toLowerCase() || test.split('\"').length > 3;\n  }), 'String', O);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-pad.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-pad.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-string-pad-start-end\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar repeat = __webpack_require__(/*! ./_string-repeat */ \"./node_modules/core-js/modules/_string-repeat.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n\nmodule.exports = function (that, maxLength, fillString, left) {\n  var S = String(defined(that));\n  var stringLength = S.length;\n  var fillStr = fillString === undefined ? ' ' : String(fillString);\n  var intMaxLength = toLength(maxLength);\n  if (intMaxLength <= stringLength || fillStr == '') return S;\n  var fillLen = intMaxLength - stringLength;\n  var stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));\n  if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);\n  return left ? stringFiller + S : S + stringFiller;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-repeat.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-repeat.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n\nmodule.exports = function repeat(count) {\n  var str = String(defined(this));\n  var res = '';\n  var n = toInteger(count);\n  if (n < 0 || n == Infinity) throw RangeError(\"Count can't be negative\");\n  for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str;\n  return res;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-trim.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-trim.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar spaces = __webpack_require__(/*! ./_string-ws */ \"./node_modules/core-js/modules/_string-ws.js\");\nvar space = '[' + spaces + ']';\nvar non = '\\u200b\\u0085';\nvar ltrim = RegExp('^' + space + space + '*');\nvar rtrim = RegExp(space + space + '*$');\n\nvar exporter = function (KEY, exec, ALIAS) {\n  var exp = {};\n  var FORCE = fails(function () {\n    return !!spaces[KEY]() || non[KEY]() != non;\n  });\n  var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];\n  if (ALIAS) exp[ALIAS] = fn;\n  $export($export.P + $export.F * FORCE, 'String', exp);\n};\n\n// 1 -> String#trimLeft\n// 2 -> String#trimRight\n// 3 -> String#trim\nvar trim = exporter.trim = function (string, TYPE) {\n  string = String(defined(string));\n  if (TYPE & 1) string = string.replace(ltrim, '');\n  if (TYPE & 2) string = string.replace(rtrim, '');\n  return string;\n};\n\nmodule.exports = exporter;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-ws.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-ws.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' +\n  '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_task.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_task.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar html = __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\");\nvar cel = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar process = global.process;\nvar setTask = global.setImmediate;\nvar clearTask = global.clearImmediate;\nvar MessageChannel = global.MessageChannel;\nvar Dispatch = global.Dispatch;\nvar counter = 0;\nvar queue = {};\nvar ONREADYSTATECHANGE = 'onreadystatechange';\nvar defer, channel, port;\nvar run = function () {\n  var id = +this;\n  // eslint-disable-next-line no-prototype-builtins\n  if (queue.hasOwnProperty(id)) {\n    var fn = queue[id];\n    delete queue[id];\n    fn();\n  }\n};\nvar listener = function (event) {\n  run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif (!setTask || !clearTask) {\n  setTask = function setImmediate(fn) {\n    var args = [];\n    var i = 1;\n    while (arguments.length > i) args.push(arguments[i++]);\n    queue[++counter] = function () {\n      // eslint-disable-next-line no-new-func\n      invoke(typeof fn == 'function' ? fn : Function(fn), args);\n    };\n    defer(counter);\n    return counter;\n  };\n  clearTask = function clearImmediate(id) {\n    delete queue[id];\n  };\n  // Node.js 0.8-\n  if (__webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process') {\n    defer = function (id) {\n      process.nextTick(ctx(run, id, 1));\n    };\n  // Sphere (JS game engine) Dispatch API\n  } else if (Dispatch && Dispatch.now) {\n    defer = function (id) {\n      Dispatch.now(ctx(run, id, 1));\n    };\n  // Browsers with MessageChannel, includes WebWorkers\n  } else if (MessageChannel) {\n    channel = new MessageChannel();\n    port = channel.port2;\n    channel.port1.onmessage = listener;\n    defer = ctx(port.postMessage, port, 1);\n  // Browsers with postMessage, skip WebWorkers\n  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n  } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {\n    defer = function (id) {\n      global.postMessage(id + '', '*');\n    };\n    global.addEventListener('message', listener, false);\n  // IE8-\n  } else if (ONREADYSTATECHANGE in cel('script')) {\n    defer = function (id) {\n      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {\n        html.removeChild(this);\n        run.call(id);\n      };\n    };\n  // Rest old browsers\n  } else {\n    defer = function (id) {\n      setTimeout(ctx(run, id, 1), 0);\n    };\n  }\n}\nmodule.exports = {\n  set: setTask,\n  clear: clearTask\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-absolute-index.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-absolute-index.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n  index = toInteger(index);\n  return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-index.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-index.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/ecma262/#sec-toindex\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nmodule.exports = function (it) {\n  if (it === undefined) return 0;\n  var number = toInteger(it);\n  var length = toLength(number);\n  if (number !== length) throw RangeError('Wrong length!');\n  return length;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-integer.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-integer.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-iobject.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-iobject.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return IObject(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-length.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-length.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.15 ToLength\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar min = Math.min;\nmodule.exports = function (it) {\n  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.13 ToObject(argument)\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return Object(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-primitive.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-primitive.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n  if (!isObject(it)) return it;\n  var fn, val;\n  if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_typed-array.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_typed-array.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nif (__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\")) {\n  var LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\n  var global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\n  var fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\n  var $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n  var $typed = __webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\");\n  var $buffer = __webpack_require__(/*! ./_typed-buffer */ \"./node_modules/core-js/modules/_typed-buffer.js\");\n  var ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\n  var anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\n  var propertyDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\n  var hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\n  var redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\n  var toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\n  var toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n  var toIndex = __webpack_require__(/*! ./_to-index */ \"./node_modules/core-js/modules/_to-index.js\");\n  var toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\n  var toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\n  var has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\n  var classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\n  var isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n  var toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\n  var isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\n  var create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\n  var getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\n  var gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\n  var getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\n  var uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\n  var wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\n  var createArrayMethod = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\");\n  var createArrayIncludes = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\");\n  var speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\n  var ArrayIterators = __webpack_require__(/*! ./es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\n  var Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\n  var $iterDetect = __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\");\n  var setSpecies = __webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\");\n  var arrayFill = __webpack_require__(/*! ./_array-fill */ \"./node_modules/core-js/modules/_array-fill.js\");\n  var arrayCopyWithin = __webpack_require__(/*! ./_array-copy-within */ \"./node_modules/core-js/modules/_array-copy-within.js\");\n  var $DP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\n  var $GOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\n  var dP = $DP.f;\n  var gOPD = $GOPD.f;\n  var RangeError = global.RangeError;\n  var TypeError = global.TypeError;\n  var Uint8Array = global.Uint8Array;\n  var ARRAY_BUFFER = 'ArrayBuffer';\n  var SHARED_BUFFER = 'Shared' + ARRAY_BUFFER;\n  var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';\n  var PROTOTYPE = 'prototype';\n  var ArrayProto = Array[PROTOTYPE];\n  var $ArrayBuffer = $buffer.ArrayBuffer;\n  var $DataView = $buffer.DataView;\n  var arrayForEach = createArrayMethod(0);\n  var arrayFilter = createArrayMethod(2);\n  var arraySome = createArrayMethod(3);\n  var arrayEvery = createArrayMethod(4);\n  var arrayFind = createArrayMethod(5);\n  var arrayFindIndex = createArrayMethod(6);\n  var arrayIncludes = createArrayIncludes(true);\n  var arrayIndexOf = createArrayIncludes(false);\n  var arrayValues = ArrayIterators.values;\n  var arrayKeys = ArrayIterators.keys;\n  var arrayEntries = ArrayIterators.entries;\n  var arrayLastIndexOf = ArrayProto.lastIndexOf;\n  var arrayReduce = ArrayProto.reduce;\n  var arrayReduceRight = ArrayProto.reduceRight;\n  var arrayJoin = ArrayProto.join;\n  var arraySort = ArrayProto.sort;\n  var arraySlice = ArrayProto.slice;\n  var arrayToString = ArrayProto.toString;\n  var arrayToLocaleString = ArrayProto.toLocaleString;\n  var ITERATOR = wks('iterator');\n  var TAG = wks('toStringTag');\n  var TYPED_CONSTRUCTOR = uid('typed_constructor');\n  var DEF_CONSTRUCTOR = uid('def_constructor');\n  var ALL_CONSTRUCTORS = $typed.CONSTR;\n  var TYPED_ARRAY = $typed.TYPED;\n  var VIEW = $typed.VIEW;\n  var WRONG_LENGTH = 'Wrong length!';\n\n  var $map = createArrayMethod(1, function (O, length) {\n    return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length);\n  });\n\n  var LITTLE_ENDIAN = fails(function () {\n    // eslint-disable-next-line no-undef\n    return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\n  });\n\n  var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function () {\n    new Uint8Array(1).set({});\n  });\n\n  var toOffset = function (it, BYTES) {\n    var offset = toInteger(it);\n    if (offset < 0 || offset % BYTES) throw RangeError('Wrong offset!');\n    return offset;\n  };\n\n  var validate = function (it) {\n    if (isObject(it) && TYPED_ARRAY in it) return it;\n    throw TypeError(it + ' is not a typed array!');\n  };\n\n  var allocate = function (C, length) {\n    if (!(isObject(C) && TYPED_CONSTRUCTOR in C)) {\n      throw TypeError('It is not a typed array constructor!');\n    } return new C(length);\n  };\n\n  var speciesFromList = function (O, list) {\n    return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list);\n  };\n\n  var fromList = function (C, list) {\n    var index = 0;\n    var length = list.length;\n    var result = allocate(C, length);\n    while (length > index) result[index] = list[index++];\n    return result;\n  };\n\n  var addGetter = function (it, key, internal) {\n    dP(it, key, { get: function () { return this._d[internal]; } });\n  };\n\n  var $from = function from(source /* , mapfn, thisArg */) {\n    var O = toObject(source);\n    var aLen = arguments.length;\n    var mapfn = aLen > 1 ? arguments[1] : undefined;\n    var mapping = mapfn !== undefined;\n    var iterFn = getIterFn(O);\n    var i, length, values, result, step, iterator;\n    if (iterFn != undefined && !isArrayIter(iterFn)) {\n      for (iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++) {\n        values.push(step.value);\n      } O = values;\n    }\n    if (mapping && aLen > 2) mapfn = ctx(mapfn, arguments[2], 2);\n    for (i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++) {\n      result[i] = mapping ? mapfn(O[i], i) : O[i];\n    }\n    return result;\n  };\n\n  var $of = function of(/* ...items */) {\n    var index = 0;\n    var length = arguments.length;\n    var result = allocate(this, length);\n    while (length > index) result[index] = arguments[index++];\n    return result;\n  };\n\n  // iOS Safari 6.x fails here\n  var TO_LOCALE_BUG = !!Uint8Array && fails(function () { arrayToLocaleString.call(new Uint8Array(1)); });\n\n  var $toLocaleString = function toLocaleString() {\n    return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments);\n  };\n\n  var proto = {\n    copyWithin: function copyWithin(target, start /* , end */) {\n      return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined);\n    },\n    every: function every(callbackfn /* , thisArg */) {\n      return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    fill: function fill(value /* , start, end */) { // eslint-disable-line no-unused-vars\n      return arrayFill.apply(validate(this), arguments);\n    },\n    filter: function filter(callbackfn /* , thisArg */) {\n      return speciesFromList(this, arrayFilter(validate(this), callbackfn,\n        arguments.length > 1 ? arguments[1] : undefined));\n    },\n    find: function find(predicate /* , thisArg */) {\n      return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    findIndex: function findIndex(predicate /* , thisArg */) {\n      return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    forEach: function forEach(callbackfn /* , thisArg */) {\n      arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    indexOf: function indexOf(searchElement /* , fromIndex */) {\n      return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    includes: function includes(searchElement /* , fromIndex */) {\n      return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    join: function join(separator) { // eslint-disable-line no-unused-vars\n      return arrayJoin.apply(validate(this), arguments);\n    },\n    lastIndexOf: function lastIndexOf(searchElement /* , fromIndex */) { // eslint-disable-line no-unused-vars\n      return arrayLastIndexOf.apply(validate(this), arguments);\n    },\n    map: function map(mapfn /* , thisArg */) {\n      return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    reduce: function reduce(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars\n      return arrayReduce.apply(validate(this), arguments);\n    },\n    reduceRight: function reduceRight(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars\n      return arrayReduceRight.apply(validate(this), arguments);\n    },\n    reverse: function reverse() {\n      var that = this;\n      var length = validate(that).length;\n      var middle = Math.floor(length / 2);\n      var index = 0;\n      var value;\n      while (index < middle) {\n        value = that[index];\n        that[index++] = that[--length];\n        that[length] = value;\n      } return that;\n    },\n    some: function some(callbackfn /* , thisArg */) {\n      return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    sort: function sort(comparefn) {\n      return arraySort.call(validate(this), comparefn);\n    },\n    subarray: function subarray(begin, end) {\n      var O = validate(this);\n      var length = O.length;\n      var $begin = toAbsoluteIndex(begin, length);\n      return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))(\n        O.buffer,\n        O.byteOffset + $begin * O.BYTES_PER_ELEMENT,\n        toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - $begin)\n      );\n    }\n  };\n\n  var $slice = function slice(start, end) {\n    return speciesFromList(this, arraySlice.call(validate(this), start, end));\n  };\n\n  var $set = function set(arrayLike /* , offset */) {\n    validate(this);\n    var offset = toOffset(arguments[1], 1);\n    var length = this.length;\n    var src = toObject(arrayLike);\n    var len = toLength(src.length);\n    var index = 0;\n    if (len + offset > length) throw RangeError(WRONG_LENGTH);\n    while (index < len) this[offset + index] = src[index++];\n  };\n\n  var $iterators = {\n    entries: function entries() {\n      return arrayEntries.call(validate(this));\n    },\n    keys: function keys() {\n      return arrayKeys.call(validate(this));\n    },\n    values: function values() {\n      return arrayValues.call(validate(this));\n    }\n  };\n\n  var isTAIndex = function (target, key) {\n    return isObject(target)\n      && target[TYPED_ARRAY]\n      && typeof key != 'symbol'\n      && key in target\n      && String(+key) == String(key);\n  };\n  var $getDesc = function getOwnPropertyDescriptor(target, key) {\n    return isTAIndex(target, key = toPrimitive(key, true))\n      ? propertyDesc(2, target[key])\n      : gOPD(target, key);\n  };\n  var $setDesc = function defineProperty(target, key, desc) {\n    if (isTAIndex(target, key = toPrimitive(key, true))\n      && isObject(desc)\n      && has(desc, 'value')\n      && !has(desc, 'get')\n      && !has(desc, 'set')\n      // TODO: add validation descriptor w/o calling accessors\n      && !desc.configurable\n      && (!has(desc, 'writable') || desc.writable)\n      && (!has(desc, 'enumerable') || desc.enumerable)\n    ) {\n      target[key] = desc.value;\n      return target;\n    } return dP(target, key, desc);\n  };\n\n  if (!ALL_CONSTRUCTORS) {\n    $GOPD.f = $getDesc;\n    $DP.f = $setDesc;\n  }\n\n  $export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', {\n    getOwnPropertyDescriptor: $getDesc,\n    defineProperty: $setDesc\n  });\n\n  if (fails(function () { arrayToString.call({}); })) {\n    arrayToString = arrayToLocaleString = function toString() {\n      return arrayJoin.call(this);\n    };\n  }\n\n  var $TypedArrayPrototype$ = redefineAll({}, proto);\n  redefineAll($TypedArrayPrototype$, $iterators);\n  hide($TypedArrayPrototype$, ITERATOR, $iterators.values);\n  redefineAll($TypedArrayPrototype$, {\n    slice: $slice,\n    set: $set,\n    constructor: function () { /* noop */ },\n    toString: arrayToString,\n    toLocaleString: $toLocaleString\n  });\n  addGetter($TypedArrayPrototype$, 'buffer', 'b');\n  addGetter($TypedArrayPrototype$, 'byteOffset', 'o');\n  addGetter($TypedArrayPrototype$, 'byteLength', 'l');\n  addGetter($TypedArrayPrototype$, 'length', 'e');\n  dP($TypedArrayPrototype$, TAG, {\n    get: function () { return this[TYPED_ARRAY]; }\n  });\n\n  // eslint-disable-next-line max-statements\n  module.exports = function (KEY, BYTES, wrapper, CLAMPED) {\n    CLAMPED = !!CLAMPED;\n    var NAME = KEY + (CLAMPED ? 'Clamped' : '') + 'Array';\n    var GETTER = 'get' + KEY;\n    var SETTER = 'set' + KEY;\n    var TypedArray = global[NAME];\n    var Base = TypedArray || {};\n    var TAC = TypedArray && getPrototypeOf(TypedArray);\n    var FORCED = !TypedArray || !$typed.ABV;\n    var O = {};\n    var TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE];\n    var getter = function (that, index) {\n      var data = that._d;\n      return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN);\n    };\n    var setter = function (that, index, value) {\n      var data = that._d;\n      if (CLAMPED) value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff;\n      data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN);\n    };\n    var addElement = function (that, index) {\n      dP(that, index, {\n        get: function () {\n          return getter(this, index);\n        },\n        set: function (value) {\n          return setter(this, index, value);\n        },\n        enumerable: true\n      });\n    };\n    if (FORCED) {\n      TypedArray = wrapper(function (that, data, $offset, $length) {\n        anInstance(that, TypedArray, NAME, '_d');\n        var index = 0;\n        var offset = 0;\n        var buffer, byteLength, length, klass;\n        if (!isObject(data)) {\n          length = toIndex(data);\n          byteLength = length * BYTES;\n          buffer = new $ArrayBuffer(byteLength);\n        } else if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {\n          buffer = data;\n          offset = toOffset($offset, BYTES);\n          var $len = data.byteLength;\n          if ($length === undefined) {\n            if ($len % BYTES) throw RangeError(WRONG_LENGTH);\n            byteLength = $len - offset;\n            if (byteLength < 0) throw RangeError(WRONG_LENGTH);\n          } else {\n            byteLength = toLength($length) * BYTES;\n            if (byteLength + offset > $len) throw RangeError(WRONG_LENGTH);\n          }\n          length = byteLength / BYTES;\n        } else if (TYPED_ARRAY in data) {\n          return fromList(TypedArray, data);\n        } else {\n          return $from.call(TypedArray, data);\n        }\n        hide(that, '_d', {\n          b: buffer,\n          o: offset,\n          l: byteLength,\n          e: length,\n          v: new $DataView(buffer)\n        });\n        while (index < length) addElement(that, index++);\n      });\n      TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$);\n      hide(TypedArrayPrototype, 'constructor', TypedArray);\n    } else if (!fails(function () {\n      TypedArray(1);\n    }) || !fails(function () {\n      new TypedArray(-1); // eslint-disable-line no-new\n    }) || !$iterDetect(function (iter) {\n      new TypedArray(); // eslint-disable-line no-new\n      new TypedArray(null); // eslint-disable-line no-new\n      new TypedArray(1.5); // eslint-disable-line no-new\n      new TypedArray(iter); // eslint-disable-line no-new\n    }, true)) {\n      TypedArray = wrapper(function (that, data, $offset, $length) {\n        anInstance(that, TypedArray, NAME);\n        var klass;\n        // `ws` module bug, temporarily remove validation length for Uint8Array\n        // https://github.com/websockets/ws/pull/645\n        if (!isObject(data)) return new Base(toIndex(data));\n        if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {\n          return $length !== undefined\n            ? new Base(data, toOffset($offset, BYTES), $length)\n            : $offset !== undefined\n              ? new Base(data, toOffset($offset, BYTES))\n              : new Base(data);\n        }\n        if (TYPED_ARRAY in data) return fromList(TypedArray, data);\n        return $from.call(TypedArray, data);\n      });\n      arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function (key) {\n        if (!(key in TypedArray)) hide(TypedArray, key, Base[key]);\n      });\n      TypedArray[PROTOTYPE] = TypedArrayPrototype;\n      if (!LIBRARY) TypedArrayPrototype.constructor = TypedArray;\n    }\n    var $nativeIterator = TypedArrayPrototype[ITERATOR];\n    var CORRECT_ITER_NAME = !!$nativeIterator\n      && ($nativeIterator.name == 'values' || $nativeIterator.name == undefined);\n    var $iterator = $iterators.values;\n    hide(TypedArray, TYPED_CONSTRUCTOR, true);\n    hide(TypedArrayPrototype, TYPED_ARRAY, NAME);\n    hide(TypedArrayPrototype, VIEW, true);\n    hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray);\n\n    if (CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)) {\n      dP(TypedArrayPrototype, TAG, {\n        get: function () { return NAME; }\n      });\n    }\n\n    O[NAME] = TypedArray;\n\n    $export($export.G + $export.W + $export.F * (TypedArray != Base), O);\n\n    $export($export.S, NAME, {\n      BYTES_PER_ELEMENT: BYTES\n    });\n\n    $export($export.S + $export.F * fails(function () { Base.of.call(TypedArray, 1); }), NAME, {\n      from: $from,\n      of: $of\n    });\n\n    if (!(BYTES_PER_ELEMENT in TypedArrayPrototype)) hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES);\n\n    $export($export.P, NAME, proto);\n\n    setSpecies(NAME);\n\n    $export($export.P + $export.F * FORCED_SET, NAME, { set: $set });\n\n    $export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators);\n\n    if (!LIBRARY && TypedArrayPrototype.toString != arrayToString) TypedArrayPrototype.toString = arrayToString;\n\n    $export($export.P + $export.F * fails(function () {\n      new TypedArray(1).slice();\n    }), NAME, { slice: $slice });\n\n    $export($export.P + $export.F * (fails(function () {\n      return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString();\n    }) || !fails(function () {\n      TypedArrayPrototype.toLocaleString.call([1, 2]);\n    })), NAME, { toLocaleString: $toLocaleString });\n\n    Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator;\n    if (!LIBRARY && !CORRECT_ITER_NAME) hide(TypedArrayPrototype, ITERATOR, $iterator);\n  };\n} else module.exports = function () { /* empty */ };\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_typed-buffer.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_typed-buffer.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar $typed = __webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toIndex = __webpack_require__(/*! ./_to-index */ \"./node_modules/core-js/modules/_to-index.js\");\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar arrayFill = __webpack_require__(/*! ./_array-fill */ \"./node_modules/core-js/modules/_array-fill.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar ARRAY_BUFFER = 'ArrayBuffer';\nvar DATA_VIEW = 'DataView';\nvar PROTOTYPE = 'prototype';\nvar WRONG_LENGTH = 'Wrong length!';\nvar WRONG_INDEX = 'Wrong index!';\nvar $ArrayBuffer = global[ARRAY_BUFFER];\nvar $DataView = global[DATA_VIEW];\nvar Math = global.Math;\nvar RangeError = global.RangeError;\n// eslint-disable-next-line no-shadow-restricted-names\nvar Infinity = global.Infinity;\nvar BaseBuffer = $ArrayBuffer;\nvar abs = Math.abs;\nvar pow = Math.pow;\nvar floor = Math.floor;\nvar log = Math.log;\nvar LN2 = Math.LN2;\nvar BUFFER = 'buffer';\nvar BYTE_LENGTH = 'byteLength';\nvar BYTE_OFFSET = 'byteOffset';\nvar $BUFFER = DESCRIPTORS ? '_b' : BUFFER;\nvar $LENGTH = DESCRIPTORS ? '_l' : BYTE_LENGTH;\nvar $OFFSET = DESCRIPTORS ? '_o' : BYTE_OFFSET;\n\n// IEEE754 conversions based on https://github.com/feross/ieee754\nfunction packIEEE754(value, mLen, nBytes) {\n  var buffer = new Array(nBytes);\n  var eLen = nBytes * 8 - mLen - 1;\n  var eMax = (1 << eLen) - 1;\n  var eBias = eMax >> 1;\n  var rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0;\n  var i = 0;\n  var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;\n  var e, m, c;\n  value = abs(value);\n  // eslint-disable-next-line no-self-compare\n  if (value != value || value === Infinity) {\n    // eslint-disable-next-line no-self-compare\n    m = value != value ? 1 : 0;\n    e = eMax;\n  } else {\n    e = floor(log(value) / LN2);\n    if (value * (c = pow(2, -e)) < 1) {\n      e--;\n      c *= 2;\n    }\n    if (e + eBias >= 1) {\n      value += rt / c;\n    } else {\n      value += rt * pow(2, 1 - eBias);\n    }\n    if (value * c >= 2) {\n      e++;\n      c /= 2;\n    }\n    if (e + eBias >= eMax) {\n      m = 0;\n      e = eMax;\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * pow(2, mLen);\n      e = e + eBias;\n    } else {\n      m = value * pow(2, eBias - 1) * pow(2, mLen);\n      e = 0;\n    }\n  }\n  for (; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8);\n  e = e << mLen | m;\n  eLen += mLen;\n  for (; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8);\n  buffer[--i] |= s * 128;\n  return buffer;\n}\nfunction unpackIEEE754(buffer, mLen, nBytes) {\n  var eLen = nBytes * 8 - mLen - 1;\n  var eMax = (1 << eLen) - 1;\n  var eBias = eMax >> 1;\n  var nBits = eLen - 7;\n  var i = nBytes - 1;\n  var s = buffer[i--];\n  var e = s & 127;\n  var m;\n  s >>= 7;\n  for (; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8);\n  m = e & (1 << -nBits) - 1;\n  e >>= -nBits;\n  nBits += mLen;\n  for (; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);\n  if (e === 0) {\n    e = 1 - eBias;\n  } else if (e === eMax) {\n    return m ? NaN : s ? -Infinity : Infinity;\n  } else {\n    m = m + pow(2, mLen);\n    e = e - eBias;\n  } return (s ? -1 : 1) * m * pow(2, e - mLen);\n}\n\nfunction unpackI32(bytes) {\n  return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];\n}\nfunction packI8(it) {\n  return [it & 0xff];\n}\nfunction packI16(it) {\n  return [it & 0xff, it >> 8 & 0xff];\n}\nfunction packI32(it) {\n  return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff];\n}\nfunction packF64(it) {\n  return packIEEE754(it, 52, 8);\n}\nfunction packF32(it) {\n  return packIEEE754(it, 23, 4);\n}\n\nfunction addGetter(C, key, internal) {\n  dP(C[PROTOTYPE], key, { get: function () { return this[internal]; } });\n}\n\nfunction get(view, bytes, index, isLittleEndian) {\n  var numIndex = +index;\n  var intIndex = toIndex(numIndex);\n  if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);\n  var store = view[$BUFFER]._b;\n  var start = intIndex + view[$OFFSET];\n  var pack = store.slice(start, start + bytes);\n  return isLittleEndian ? pack : pack.reverse();\n}\nfunction set(view, bytes, index, conversion, value, isLittleEndian) {\n  var numIndex = +index;\n  var intIndex = toIndex(numIndex);\n  if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);\n  var store = view[$BUFFER]._b;\n  var start = intIndex + view[$OFFSET];\n  var pack = conversion(+value);\n  for (var i = 0; i < bytes; i++) store[start + i] = pack[isLittleEndian ? i : bytes - i - 1];\n}\n\nif (!$typed.ABV) {\n  $ArrayBuffer = function ArrayBuffer(length) {\n    anInstance(this, $ArrayBuffer, ARRAY_BUFFER);\n    var byteLength = toIndex(length);\n    this._b = arrayFill.call(new Array(byteLength), 0);\n    this[$LENGTH] = byteLength;\n  };\n\n  $DataView = function DataView(buffer, byteOffset, byteLength) {\n    anInstance(this, $DataView, DATA_VIEW);\n    anInstance(buffer, $ArrayBuffer, DATA_VIEW);\n    var bufferLength = buffer[$LENGTH];\n    var offset = toInteger(byteOffset);\n    if (offset < 0 || offset > bufferLength) throw RangeError('Wrong offset!');\n    byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);\n    if (offset + byteLength > bufferLength) throw RangeError(WRONG_LENGTH);\n    this[$BUFFER] = buffer;\n    this[$OFFSET] = offset;\n    this[$LENGTH] = byteLength;\n  };\n\n  if (DESCRIPTORS) {\n    addGetter($ArrayBuffer, BYTE_LENGTH, '_l');\n    addGetter($DataView, BUFFER, '_b');\n    addGetter($DataView, BYTE_LENGTH, '_l');\n    addGetter($DataView, BYTE_OFFSET, '_o');\n  }\n\n  redefineAll($DataView[PROTOTYPE], {\n    getInt8: function getInt8(byteOffset) {\n      return get(this, 1, byteOffset)[0] << 24 >> 24;\n    },\n    getUint8: function getUint8(byteOffset) {\n      return get(this, 1, byteOffset)[0];\n    },\n    getInt16: function getInt16(byteOffset /* , littleEndian */) {\n      var bytes = get(this, 2, byteOffset, arguments[1]);\n      return (bytes[1] << 8 | bytes[0]) << 16 >> 16;\n    },\n    getUint16: function getUint16(byteOffset /* , littleEndian */) {\n      var bytes = get(this, 2, byteOffset, arguments[1]);\n      return bytes[1] << 8 | bytes[0];\n    },\n    getInt32: function getInt32(byteOffset /* , littleEndian */) {\n      return unpackI32(get(this, 4, byteOffset, arguments[1]));\n    },\n    getUint32: function getUint32(byteOffset /* , littleEndian */) {\n      return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0;\n    },\n    getFloat32: function getFloat32(byteOffset /* , littleEndian */) {\n      return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4);\n    },\n    getFloat64: function getFloat64(byteOffset /* , littleEndian */) {\n      return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8);\n    },\n    setInt8: function setInt8(byteOffset, value) {\n      set(this, 1, byteOffset, packI8, value);\n    },\n    setUint8: function setUint8(byteOffset, value) {\n      set(this, 1, byteOffset, packI8, value);\n    },\n    setInt16: function setInt16(byteOffset, value /* , littleEndian */) {\n      set(this, 2, byteOffset, packI16, value, arguments[2]);\n    },\n    setUint16: function setUint16(byteOffset, value /* , littleEndian */) {\n      set(this, 2, byteOffset, packI16, value, arguments[2]);\n    },\n    setInt32: function setInt32(byteOffset, value /* , littleEndian */) {\n      set(this, 4, byteOffset, packI32, value, arguments[2]);\n    },\n    setUint32: function setUint32(byteOffset, value /* , littleEndian */) {\n      set(this, 4, byteOffset, packI32, value, arguments[2]);\n    },\n    setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) {\n      set(this, 4, byteOffset, packF32, value, arguments[2]);\n    },\n    setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) {\n      set(this, 8, byteOffset, packF64, value, arguments[2]);\n    }\n  });\n} else {\n  if (!fails(function () {\n    $ArrayBuffer(1);\n  }) || !fails(function () {\n    new $ArrayBuffer(-1); // eslint-disable-line no-new\n  }) || fails(function () {\n    new $ArrayBuffer(); // eslint-disable-line no-new\n    new $ArrayBuffer(1.5); // eslint-disable-line no-new\n    new $ArrayBuffer(NaN); // eslint-disable-line no-new\n    return $ArrayBuffer.name != ARRAY_BUFFER;\n  })) {\n    $ArrayBuffer = function ArrayBuffer(length) {\n      anInstance(this, $ArrayBuffer);\n      return new BaseBuffer(toIndex(length));\n    };\n    var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE];\n    for (var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j;) {\n      if (!((key = keys[j++]) in $ArrayBuffer)) hide($ArrayBuffer, key, BaseBuffer[key]);\n    }\n    if (!LIBRARY) ArrayBufferProto.constructor = $ArrayBuffer;\n  }\n  // iOS Safari 7.x bug\n  var view = new $DataView(new $ArrayBuffer(2));\n  var $setInt8 = $DataView[PROTOTYPE].setInt8;\n  view.setInt8(0, 2147483648);\n  view.setInt8(1, 2147483649);\n  if (view.getInt8(0) || !view.getInt8(1)) redefineAll($DataView[PROTOTYPE], {\n    setInt8: function setInt8(byteOffset, value) {\n      $setInt8.call(this, byteOffset, value << 24 >> 24);\n    },\n    setUint8: function setUint8(byteOffset, value) {\n      $setInt8.call(this, byteOffset, value << 24 >> 24);\n    }\n  }, true);\n}\nsetToStringTag($ArrayBuffer, ARRAY_BUFFER);\nsetToStringTag($DataView, DATA_VIEW);\nhide($DataView[PROTOTYPE], $typed.VIEW, true);\nexports[ARRAY_BUFFER] = $ArrayBuffer;\nexports[DATA_VIEW] = $DataView;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_typed.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_typed.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar TYPED = uid('typed_array');\nvar VIEW = uid('view');\nvar ABV = !!(global.ArrayBuffer && global.DataView);\nvar CONSTR = ABV;\nvar i = 0;\nvar l = 9;\nvar Typed;\n\nvar TypedArrayConstructors = (\n  'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array'\n).split(',');\n\nwhile (i < l) {\n  if (Typed = global[TypedArrayConstructors[i++]]) {\n    hide(Typed.prototype, TYPED, true);\n    hide(Typed.prototype, VIEW, true);\n  } else CONSTR = false;\n}\n\nmodule.exports = {\n  ABV: ABV,\n  CONSTR: CONSTR,\n  TYPED: TYPED,\n  VIEW: VIEW\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_uid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_uid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_user-agent.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_user-agent.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_validate-collection.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_validate-collection.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nmodule.exports = function (it, TYPE) {\n  if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks-define.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks-define.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar wksExt = __webpack_require__(/*! ./_wks-ext */ \"./node_modules/core-js/modules/_wks-ext.js\");\nvar defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nmodule.exports = function (name) {\n  var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});\n  if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks-ext.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks-ext.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nexports.f = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar store = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('wks');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar Symbol = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n  return store[name] || (store[name] =\n    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/core.get-iterator-method.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/core.get-iterator-method.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nmodule.exports = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").getIteratorMethod = function (it) {\n  if (it != undefined) return it[ITERATOR]\n    || it['@@iterator']\n    || Iterators[classof(it)];\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/core.regexp.escape.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/core.regexp.escape.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/benjamingr/RexExp.escape\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $re = __webpack_require__(/*! ./_replacer */ \"./node_modules/core-js/modules/_replacer.js\")(/[\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\n$export($export.S, 'RegExp', { escape: function escape(it) { return $re(it); } });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.copy-within.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.copy-within.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Array', { copyWithin: __webpack_require__(/*! ./_array-copy-within */ \"./node_modules/core-js/modules/_array-copy-within.js\") });\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('copyWithin');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.every.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.every.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $every = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(4);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].every, true), 'Array', {\n  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])\n  every: function every(callbackfn /* , thisArg */) {\n    return $every(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.fill.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.fill.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Array', { fill: __webpack_require__(/*! ./_array-fill */ \"./node_modules/core-js/modules/_array-fill.js\") });\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('fill');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.filter.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.filter.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $filter = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(2);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].filter, true), 'Array', {\n  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])\n  filter: function filter(callbackfn /* , thisArg */) {\n    return $filter(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.find-index.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.find-index.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $find = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(6);\nvar KEY = 'findIndex';\nvar forced = true;\n// Shouldn't skip holes\nif (KEY in []) Array(1)[KEY](function () { forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  findIndex: function findIndex(callbackfn /* , that = undefined */) {\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")(KEY);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.find.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.find.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $find = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(5);\nvar KEY = 'find';\nvar forced = true;\n// Shouldn't skip holes\nif (KEY in []) Array(1)[KEY](function () { forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  find: function find(callbackfn /* , that = undefined */) {\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")(KEY);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.for-each.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.for-each.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $forEach = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(0);\nvar STRICT = __webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].forEach, true);\n\n$export($export.P + $export.F * !STRICT, 'Array', {\n  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])\n  forEach: function forEach(callbackfn /* , thisArg */) {\n    return $forEach(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.from.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.from.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar call = __webpack_require__(/*! ./_iter-call */ \"./node_modules/core-js/modules/_iter-call.js\");\nvar isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar createProperty = __webpack_require__(/*! ./_create-property */ \"./node_modules/core-js/modules/_create-property.js\");\nvar getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\n\n$export($export.S + $export.F * !__webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\")(function (iter) { Array.from(iter); }), 'Array', {\n  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)\n  from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {\n    var O = toObject(arrayLike);\n    var C = typeof this == 'function' ? this : Array;\n    var aLen = arguments.length;\n    var mapfn = aLen > 1 ? arguments[1] : undefined;\n    var mapping = mapfn !== undefined;\n    var index = 0;\n    var iterFn = getIterFn(O);\n    var length, result, step, iterator;\n    if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);\n    // if object isn't iterable or it's array with default iterator - use simple case\n    if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) {\n      for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {\n        createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);\n      }\n    } else {\n      length = toLength(O.length);\n      for (result = new C(length); length > index; index++) {\n        createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);\n      }\n    }\n    result.length = index;\n    return result;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.index-of.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.index-of.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $indexOf = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(false);\nvar $native = [].indexOf;\nvar NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0;\n\n$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")($native)), 'Array', {\n  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])\n  indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {\n    return NEGATIVE_ZERO\n      // convert -0 to +0\n      ? $native.apply(this, arguments) || 0\n      : $indexOf(this, searchElement, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.is-array.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.is-array.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Array', { isArray: __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.iterator.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.iterator.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar addToUnscopables = __webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\");\nvar step = __webpack_require__(/*! ./_iter-step */ \"./node_modules/core-js/modules/_iter-step.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = __webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(Array, 'Array', function (iterated, kind) {\n  this._t = toIObject(iterated); // target\n  this._i = 0;                   // next index\n  this._k = kind;                // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var kind = this._k;\n  var index = this._i++;\n  if (!O || index >= O.length) {\n    this._t = undefined;\n    return step(1);\n  }\n  if (kind == 'keys') return step(0, index);\n  if (kind == 'values') return step(0, O[index]);\n  return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.join.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.join.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.13 Array.prototype.join(separator)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar arrayJoin = [].join;\n\n// fallback for not array-like strings\n$export($export.P + $export.F * (__webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\") != Object || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")(arrayJoin)), 'Array', {\n  join: function join(separator) {\n    return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.last-index-of.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.last-index-of.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar $native = [].lastIndexOf;\nvar NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0;\n\n$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")($native)), 'Array', {\n  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])\n  lastIndexOf: function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {\n    // convert -0 to +0\n    if (NEGATIVE_ZERO) return $native.apply(this, arguments) || 0;\n    var O = toIObject(this);\n    var length = toLength(O.length);\n    var index = length - 1;\n    if (arguments.length > 1) index = Math.min(index, toInteger(arguments[1]));\n    if (index < 0) index = length + index;\n    for (;index >= 0; index--) if (index in O) if (O[index] === searchElement) return index || 0;\n    return -1;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.map.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.map.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $map = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(1);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].map, true), 'Array', {\n  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])\n  map: function map(callbackfn /* , thisArg */) {\n    return $map(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.of.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.of.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar createProperty = __webpack_require__(/*! ./_create-property */ \"./node_modules/core-js/modules/_create-property.js\");\n\n// WebKit Array.of isn't generic\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  function F() { /* empty */ }\n  return !(Array.of.call(F) instanceof F);\n}), 'Array', {\n  // 22.1.2.3 Array.of( ...items)\n  of: function of(/* ...args */) {\n    var index = 0;\n    var aLen = arguments.length;\n    var result = new (typeof this == 'function' ? this : Array)(aLen);\n    while (aLen > index) createProperty(result, index, arguments[index++]);\n    result.length = aLen;\n    return result;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.reduce-right.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.reduce-right.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $reduce = __webpack_require__(/*! ./_array-reduce */ \"./node_modules/core-js/modules/_array-reduce.js\");\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].reduceRight, true), 'Array', {\n  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])\n  reduceRight: function reduceRight(callbackfn /* , initialValue */) {\n    return $reduce(this, callbackfn, arguments.length, arguments[1], true);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.reduce.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.reduce.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $reduce = __webpack_require__(/*! ./_array-reduce */ \"./node_modules/core-js/modules/_array-reduce.js\");\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].reduce, true), 'Array', {\n  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])\n  reduce: function reduce(callbackfn /* , initialValue */) {\n    return $reduce(this, callbackfn, arguments.length, arguments[1], false);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.slice.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.slice.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar html = __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar arraySlice = [].slice;\n\n// fallback for not array-like ES3 strings and DOM objects\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  if (html) arraySlice.call(html);\n}), 'Array', {\n  slice: function slice(begin, end) {\n    var len = toLength(this.length);\n    var klass = cof(this);\n    end = end === undefined ? len : end;\n    if (klass == 'Array') return arraySlice.call(this, begin, end);\n    var start = toAbsoluteIndex(begin, len);\n    var upTo = toAbsoluteIndex(end, len);\n    var size = toLength(upTo - start);\n    var cloned = new Array(size);\n    var i = 0;\n    for (; i < size; i++) cloned[i] = klass == 'String'\n      ? this.charAt(start + i)\n      : this[start + i];\n    return cloned;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.some.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.some.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $some = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(3);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].some, true), 'Array', {\n  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])\n  some: function some(callbackfn /* , thisArg */) {\n    return $some(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.sort.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.sort.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar $sort = [].sort;\nvar test = [1, 2, 3];\n\n$export($export.P + $export.F * (fails(function () {\n  // IE8-\n  test.sort(undefined);\n}) || !fails(function () {\n  // V8 bug\n  test.sort(null);\n  // Old WebKit\n}) || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")($sort)), 'Array', {\n  // 22.1.3.25 Array.prototype.sort(comparefn)\n  sort: function sort(comparefn) {\n    return comparefn === undefined\n      ? $sort.call(toObject(this))\n      : $sort.call(toObject(this), aFunction(comparefn));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.species.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.species.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")('Array');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.now.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.now.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.3.3.1 / 15.9.4.4 Date.now()\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Date', { now: function () { return new Date().getTime(); } });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-iso-string.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-iso-string.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toISOString = __webpack_require__(/*! ./_date-to-iso-string */ \"./node_modules/core-js/modules/_date-to-iso-string.js\");\n\n// PhantomJS / old WebKit has a broken implementations\n$export($export.P + $export.F * (Date.prototype.toISOString !== toISOString), 'Date', {\n  toISOString: toISOString\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-json.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-json.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return new Date(NaN).toJSON() !== null\n    || Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1;\n}), 'Date', {\n  // eslint-disable-next-line no-unused-vars\n  toJSON: function toJSON(key) {\n    var O = toObject(this);\n    var pv = toPrimitive(O);\n    return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-primitive.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-primitive.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar TO_PRIMITIVE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toPrimitive');\nvar proto = Date.prototype;\n\nif (!(TO_PRIMITIVE in proto)) __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(proto, TO_PRIMITIVE, __webpack_require__(/*! ./_date-to-primitive */ \"./node_modules/core-js/modules/_date-to-primitive.js\"));\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-string.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-string.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar DateProto = Date.prototype;\nvar INVALID_DATE = 'Invalid Date';\nvar TO_STRING = 'toString';\nvar $toString = DateProto[TO_STRING];\nvar getTime = DateProto.getTime;\nif (new Date(NaN) + '' != INVALID_DATE) {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(DateProto, TO_STRING, function toString() {\n    var value = getTime.call(this);\n    // eslint-disable-next-line no-self-compare\n    return value === value ? $toString.call(this) : INVALID_DATE;\n  });\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.bind.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.bind.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Function', { bind: __webpack_require__(/*! ./_bind */ \"./node_modules/core-js/modules/_bind.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.has-instance.js\":\n/*!*******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.has-instance.js ***!\n  \\*******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar HAS_INSTANCE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('hasInstance');\nvar FunctionProto = Function.prototype;\n// 19.2.3.6 Function.prototype[@@hasInstance](V)\nif (!(HAS_INSTANCE in FunctionProto)) __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f(FunctionProto, HAS_INSTANCE, { value: function (O) {\n  if (typeof this != 'function' || !isObject(O)) return false;\n  if (!isObject(this.prototype)) return O instanceof this;\n  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:\n  while (O = getPrototypeOf(O)) if (this.prototype === O) return true;\n  return false;\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.name.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.name.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar FProto = Function.prototype;\nvar nameRE = /^\\s*function ([^ (]*)/;\nvar NAME = 'name';\n\n// 19.2.4.2 name\nNAME in FProto || __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && dP(FProto, NAME, {\n  configurable: true,\n  get: function () {\n    try {\n      return ('' + this).match(nameRE)[1];\n    } catch (e) {\n      return '';\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.map.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.map.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar strong = __webpack_require__(/*! ./_collection-strong */ \"./node_modules/core-js/modules/_collection-strong.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar MAP = 'Map';\n\n// 23.1 Map Objects\nmodule.exports = __webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(MAP, function (get) {\n  return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.1.3.6 Map.prototype.get(key)\n  get: function get(key) {\n    var entry = strong.getEntry(validate(this, MAP), key);\n    return entry && entry.v;\n  },\n  // 23.1.3.9 Map.prototype.set(key, value)\n  set: function set(key, value) {\n    return strong.def(validate(this, MAP), key === 0 ? 0 : key, value);\n  }\n}, strong, true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.acosh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.acosh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.3 Math.acosh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar log1p = __webpack_require__(/*! ./_math-log1p */ \"./node_modules/core-js/modules/_math-log1p.js\");\nvar sqrt = Math.sqrt;\nvar $acosh = Math.acosh;\n\n$export($export.S + $export.F * !($acosh\n  // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509\n  && Math.floor($acosh(Number.MAX_VALUE)) == 710\n  // Tor Browser bug: Math.acosh(Infinity) -> NaN\n  && $acosh(Infinity) == Infinity\n), 'Math', {\n  acosh: function acosh(x) {\n    return (x = +x) < 1 ? NaN : x > 94906265.62425156\n      ? Math.log(x) + Math.LN2\n      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.asinh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.asinh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.5 Math.asinh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $asinh = Math.asinh;\n\nfunction asinh(x) {\n  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));\n}\n\n// Tor Browser bug: Math.asinh(0) -> -0\n$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', { asinh: asinh });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.atanh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.atanh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.7 Math.atanh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $atanh = Math.atanh;\n\n// Tor Browser bug: Math.atanh(-0) -> 0\n$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {\n  atanh: function atanh(x) {\n    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.cbrt.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.cbrt.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.9 Math.cbrt(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar sign = __webpack_require__(/*! ./_math-sign */ \"./node_modules/core-js/modules/_math-sign.js\");\n\n$export($export.S, 'Math', {\n  cbrt: function cbrt(x) {\n    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.clz32.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.clz32.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.11 Math.clz32(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  clz32: function clz32(x) {\n    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.cosh.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.cosh.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.12 Math.cosh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar exp = Math.exp;\n\n$export($export.S, 'Math', {\n  cosh: function cosh(x) {\n    return (exp(x = +x) + exp(-x)) / 2;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.expm1.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.expm1.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.14 Math.expm1(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $expm1 = __webpack_require__(/*! ./_math-expm1 */ \"./node_modules/core-js/modules/_math-expm1.js\");\n\n$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', { expm1: $expm1 });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.fround.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.fround.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.16 Math.fround(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { fround: __webpack_require__(/*! ./_math-fround */ \"./node_modules/core-js/modules/_math-fround.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.hypot.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.hypot.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar abs = Math.abs;\n\n$export($export.S, 'Math', {\n  hypot: function hypot(value1, value2) { // eslint-disable-line no-unused-vars\n    var sum = 0;\n    var i = 0;\n    var aLen = arguments.length;\n    var larg = 0;\n    var arg, div;\n    while (i < aLen) {\n      arg = abs(arguments[i++]);\n      if (larg < arg) {\n        div = larg / arg;\n        sum = sum * div * div + 1;\n        larg = arg;\n      } else if (arg > 0) {\n        div = arg / larg;\n        sum += div * div;\n      } else sum += arg;\n    }\n    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.imul.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.imul.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.18 Math.imul(x, y)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $imul = Math.imul;\n\n// some WebKit versions fails with big numbers, some has wrong arity\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;\n}), 'Math', {\n  imul: function imul(x, y) {\n    var UINT16 = 0xffff;\n    var xn = +x;\n    var yn = +y;\n    var xl = UINT16 & xn;\n    var yl = UINT16 & yn;\n    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.log10.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.log10.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.21 Math.log10(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  log10: function log10(x) {\n    return Math.log(x) * Math.LOG10E;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.log1p.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.log1p.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.20 Math.log1p(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { log1p: __webpack_require__(/*! ./_math-log1p */ \"./node_modules/core-js/modules/_math-log1p.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.log2.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.log2.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.22 Math.log2(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  log2: function log2(x) {\n    return Math.log(x) / Math.LN2;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.sign.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.sign.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.28 Math.sign(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { sign: __webpack_require__(/*! ./_math-sign */ \"./node_modules/core-js/modules/_math-sign.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.sinh.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.sinh.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.30 Math.sinh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar expm1 = __webpack_require__(/*! ./_math-expm1 */ \"./node_modules/core-js/modules/_math-expm1.js\");\nvar exp = Math.exp;\n\n// V8 near Chromium 38 has a problem with very small numbers\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return !Math.sinh(-2e-17) != -2e-17;\n}), 'Math', {\n  sinh: function sinh(x) {\n    return Math.abs(x = +x) < 1\n      ? (expm1(x) - expm1(-x)) / 2\n      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.tanh.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.tanh.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.33 Math.tanh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar expm1 = __webpack_require__(/*! ./_math-expm1 */ \"./node_modules/core-js/modules/_math-expm1.js\");\nvar exp = Math.exp;\n\n$export($export.S, 'Math', {\n  tanh: function tanh(x) {\n    var a = expm1(x = +x);\n    var b = expm1(-x);\n    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.trunc.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.trunc.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.34 Math.trunc(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  trunc: function trunc(it) {\n    return (it > 0 ? Math.floor : Math.ceil)(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.constructor.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.constructor.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ \"./node_modules/core-js/modules/_inherit-if-required.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar $trim = __webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\").trim;\nvar NUMBER = 'Number';\nvar $Number = global[NUMBER];\nvar Base = $Number;\nvar proto = $Number.prototype;\n// Opera ~12 has broken Object#toString\nvar BROKEN_COF = cof(__webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\")(proto)) == NUMBER;\nvar TRIM = 'trim' in String.prototype;\n\n// 7.1.3 ToNumber(argument)\nvar toNumber = function (argument) {\n  var it = toPrimitive(argument, false);\n  if (typeof it == 'string' && it.length > 2) {\n    it = TRIM ? it.trim() : $trim(it, 3);\n    var first = it.charCodeAt(0);\n    var third, radix, maxCode;\n    if (first === 43 || first === 45) {\n      third = it.charCodeAt(2);\n      if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix\n    } else if (first === 48) {\n      switch (it.charCodeAt(1)) {\n        case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i\n        case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i\n        default: return +it;\n      }\n      for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {\n        code = digits.charCodeAt(i);\n        // parseInt parses a string to a first unavailable symbol\n        // but ToNumber should return NaN if a string contains unavailable symbols\n        if (code < 48 || code > maxCode) return NaN;\n      } return parseInt(digits, radix);\n    }\n  } return +it;\n};\n\nif (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {\n  $Number = function Number(value) {\n    var it = arguments.length < 1 ? 0 : value;\n    var that = this;\n    return that instanceof $Number\n      // check on 1..constructor(foo) case\n      && (BROKEN_COF ? fails(function () { proto.valueOf.call(that); }) : cof(that) != NUMBER)\n        ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);\n  };\n  for (var keys = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? gOPN(Base) : (\n    // ES3:\n    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +\n    // ES6 (in case, if modules with ES6 Number statics required before):\n    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +\n    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'\n  ).split(','), j = 0, key; keys.length > j; j++) {\n    if (has(Base, key = keys[j]) && !has($Number, key)) {\n      dP($Number, key, gOPD(Base, key));\n    }\n  }\n  $Number.prototype = proto;\n  proto.constructor = $Number;\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(global, NUMBER, $Number);\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.epsilon.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.epsilon.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.1 Number.EPSILON\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { EPSILON: Math.pow(2, -52) });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-finite.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-finite.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.2 Number.isFinite(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar _isFinite = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").isFinite;\n\n$export($export.S, 'Number', {\n  isFinite: function isFinite(it) {\n    return typeof it == 'number' && _isFinite(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-integer.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-integer.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.3 Number.isInteger(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { isInteger: __webpack_require__(/*! ./_is-integer */ \"./node_modules/core-js/modules/_is-integer.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-nan.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-nan.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.4 Number.isNaN(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', {\n  isNaN: function isNaN(number) {\n    // eslint-disable-next-line no-self-compare\n    return number != number;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-safe-integer.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-safe-integer.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.5 Number.isSafeInteger(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isInteger = __webpack_require__(/*! ./_is-integer */ \"./node_modules/core-js/modules/_is-integer.js\");\nvar abs = Math.abs;\n\n$export($export.S, 'Number', {\n  isSafeInteger: function isSafeInteger(number) {\n    return isInteger(number) && abs(number) <= 0x1fffffffffffff;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.max-safe-integer.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.max-safe-integer.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.6 Number.MAX_SAFE_INTEGER\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.min-safe-integer.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.min-safe-integer.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.10 Number.MIN_SAFE_INTEGER\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.parse-float.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.parse-float.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseFloat = __webpack_require__(/*! ./_parse-float */ \"./node_modules/core-js/modules/_parse-float.js\");\n// 20.1.2.12 Number.parseFloat(string)\n$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', { parseFloat: $parseFloat });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.parse-int.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.parse-int.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseInt = __webpack_require__(/*! ./_parse-int */ \"./node_modules/core-js/modules/_parse-int.js\");\n// 20.1.2.13 Number.parseInt(string, radix)\n$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', { parseInt: $parseInt });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.to-fixed.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.to-fixed.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar aNumberValue = __webpack_require__(/*! ./_a-number-value */ \"./node_modules/core-js/modules/_a-number-value.js\");\nvar repeat = __webpack_require__(/*! ./_string-repeat */ \"./node_modules/core-js/modules/_string-repeat.js\");\nvar $toFixed = 1.0.toFixed;\nvar floor = Math.floor;\nvar data = [0, 0, 0, 0, 0, 0];\nvar ERROR = 'Number.toFixed: incorrect invocation!';\nvar ZERO = '0';\n\nvar multiply = function (n, c) {\n  var i = -1;\n  var c2 = c;\n  while (++i < 6) {\n    c2 += n * data[i];\n    data[i] = c2 % 1e7;\n    c2 = floor(c2 / 1e7);\n  }\n};\nvar divide = function (n) {\n  var i = 6;\n  var c = 0;\n  while (--i >= 0) {\n    c += data[i];\n    data[i] = floor(c / n);\n    c = (c % n) * 1e7;\n  }\n};\nvar numToString = function () {\n  var i = 6;\n  var s = '';\n  while (--i >= 0) {\n    if (s !== '' || i === 0 || data[i] !== 0) {\n      var t = String(data[i]);\n      s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;\n    }\n  } return s;\n};\nvar pow = function (x, n, acc) {\n  return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);\n};\nvar log = function (x) {\n  var n = 0;\n  var x2 = x;\n  while (x2 >= 4096) {\n    n += 12;\n    x2 /= 4096;\n  }\n  while (x2 >= 2) {\n    n += 1;\n    x2 /= 2;\n  } return n;\n};\n\n$export($export.P + $export.F * (!!$toFixed && (\n  0.00008.toFixed(3) !== '0.000' ||\n  0.9.toFixed(0) !== '1' ||\n  1.255.toFixed(2) !== '1.25' ||\n  1000000000000000128.0.toFixed(0) !== '1000000000000000128'\n) || !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  // V8 ~ Android 4.3-\n  $toFixed.call({});\n})), 'Number', {\n  toFixed: function toFixed(fractionDigits) {\n    var x = aNumberValue(this, ERROR);\n    var f = toInteger(fractionDigits);\n    var s = '';\n    var m = ZERO;\n    var e, z, j, k;\n    if (f < 0 || f > 20) throw RangeError(ERROR);\n    // eslint-disable-next-line no-self-compare\n    if (x != x) return 'NaN';\n    if (x <= -1e21 || x >= 1e21) return String(x);\n    if (x < 0) {\n      s = '-';\n      x = -x;\n    }\n    if (x > 1e-21) {\n      e = log(x * pow(2, 69, 1)) - 69;\n      z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);\n      z *= 0x10000000000000;\n      e = 52 - e;\n      if (e > 0) {\n        multiply(0, z);\n        j = f;\n        while (j >= 7) {\n          multiply(1e7, 0);\n          j -= 7;\n        }\n        multiply(pow(10, j, 1), 0);\n        j = e - 1;\n        while (j >= 23) {\n          divide(1 << 23);\n          j -= 23;\n        }\n        divide(1 << j);\n        multiply(1, 1);\n        divide(2);\n        m = numToString();\n      } else {\n        multiply(0, z);\n        multiply(1 << -e, 0);\n        m = numToString() + repeat.call(ZERO, f);\n      }\n    }\n    if (f > 0) {\n      k = m.length;\n      m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));\n    } else {\n      m = s + m;\n    } return m;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.to-precision.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.to-precision.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar aNumberValue = __webpack_require__(/*! ./_a-number-value */ \"./node_modules/core-js/modules/_a-number-value.js\");\nvar $toPrecision = 1.0.toPrecision;\n\n$export($export.P + $export.F * ($fails(function () {\n  // IE7-\n  return $toPrecision.call(1, undefined) !== '1';\n}) || !$fails(function () {\n  // V8 ~ Android 4.3-\n  $toPrecision.call({});\n})), 'Number', {\n  toPrecision: function toPrecision(precision) {\n    var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');\n    return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.assign.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.assign.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.1 Object.assign(target, source)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S + $export.F, 'Object', { assign: __webpack_require__(/*! ./_object-assign */ \"./node_modules/core-js/modules/_object-assign.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.create.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.create.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\n$export($export.S, 'Object', { create: __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.define-properties.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.define-properties.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n// 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)\n$export($export.S + $export.F * !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\"), 'Object', { defineProperties: __webpack_require__(/*! ./_object-dps */ \"./node_modules/core-js/modules/_object-dps.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.define-property.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.define-property.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)\n$export($export.S + $export.F * !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\"), 'Object', { defineProperty: __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.freeze.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.freeze.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.5 Object.freeze(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").onFreeze;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('freeze', function ($freeze) {\n  return function freeze(it) {\n    return $freeze && isObject(it) ? $freeze(meta(it)) : it;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js\":\n/*!********************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js ***!\n  \\********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar $getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('getOwnPropertyDescriptor', function () {\n  return function getOwnPropertyDescriptor(it, key) {\n    return $getOwnPropertyDescriptor(toIObject(it), key);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.get-own-property-names.js\":\n/*!***************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.get-own-property-names.js ***!\n  \\***************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.7 Object.getOwnPropertyNames(O)\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('getOwnPropertyNames', function () {\n  return __webpack_require__(/*! ./_object-gopn-ext */ \"./node_modules/core-js/modules/_object-gopn-ext.js\").f;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.get-prototype-of.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.get-prototype-of.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.9 Object.getPrototypeOf(O)\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar $getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('getPrototypeOf', function () {\n  return function getPrototypeOf(it) {\n    return $getPrototypeOf(toObject(it));\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is-extensible.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is-extensible.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.11 Object.isExtensible(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('isExtensible', function ($isExtensible) {\n  return function isExtensible(it) {\n    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is-frozen.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is-frozen.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.12 Object.isFrozen(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('isFrozen', function ($isFrozen) {\n  return function isFrozen(it) {\n    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is-sealed.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is-sealed.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.13 Object.isSealed(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('isSealed', function ($isSealed) {\n  return function isSealed(it) {\n    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.10 Object.is(value1, value2)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n$export($export.S, 'Object', { is: __webpack_require__(/*! ./_same-value */ \"./node_modules/core-js/modules/_same-value.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.keys.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.keys.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.14 Object.keys(O)\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar $keys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('keys', function () {\n  return function keys(it) {\n    return $keys(toObject(it));\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.prevent-extensions.js\":\n/*!***********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.prevent-extensions.js ***!\n  \\***********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.15 Object.preventExtensions(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").onFreeze;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('preventExtensions', function ($preventExtensions) {\n  return function preventExtensions(it) {\n    return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.seal.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.seal.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.17 Object.seal(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").onFreeze;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('seal', function ($seal) {\n  return function seal(it) {\n    return $seal && isObject(it) ? $seal(meta(it)) : it;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.set-prototype-of.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.set-prototype-of.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.19 Object.setPrototypeOf(O, proto)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n$export($export.S, 'Object', { setPrototypeOf: __webpack_require__(/*! ./_set-proto */ \"./node_modules/core-js/modules/_set-proto.js\").set });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.to-string.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.to-string.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.3.6 Object.prototype.toString()\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar test = {};\ntest[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag')] = 'z';\nif (test + '' != '[object z]') {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(Object.prototype, 'toString', function toString() {\n    return '[object ' + classof(this) + ']';\n  }, true);\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.parse-float.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.parse-float.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseFloat = __webpack_require__(/*! ./_parse-float */ \"./node_modules/core-js/modules/_parse-float.js\");\n// 18.2.4 parseFloat(string)\n$export($export.G + $export.F * (parseFloat != $parseFloat), { parseFloat: $parseFloat });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.parse-int.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.parse-int.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseInt = __webpack_require__(/*! ./_parse-int */ \"./node_modules/core-js/modules/_parse-int.js\");\n// 18.2.5 parseInt(string, radix)\n$export($export.G + $export.F * (parseInt != $parseInt), { parseInt: $parseInt });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.promise.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.promise.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar task = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar newPromiseCapabilityModule = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\nvar perform = __webpack_require__(/*! ./_perform */ \"./node_modules/core-js/modules/_perform.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\nvar promiseResolve = __webpack_require__(/*! ./_promise-resolve */ \"./node_modules/core-js/modules/_promise-resolve.js\");\nvar PROMISE = 'Promise';\nvar TypeError = global.TypeError;\nvar process = global.process;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8 || '';\nvar $Promise = global[PROMISE];\nvar isNode = classof(process) == 'process';\nvar empty = function () { /* empty */ };\nvar Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;\nvar newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;\n\nvar USE_NATIVE = !!function () {\n  try {\n    // correct subclassing with @@species support\n    var promise = $Promise.resolve(1);\n    var FakePromise = (promise.constructor = {})[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species')] = function (exec) {\n      exec(empty, empty);\n    };\n    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n    return (isNode || typeof PromiseRejectionEvent == 'function')\n      && promise.then(empty) instanceof FakePromise\n      // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables\n      // https://bugs.chromium.org/p/chromium/issues/detail?id=830565\n      // we can't detect it synchronously, so just check versions\n      && v8.indexOf('6.6') !== 0\n      && userAgent.indexOf('Chrome/66') === -1;\n  } catch (e) { /* empty */ }\n}();\n\n// helpers\nvar isThenable = function (it) {\n  var then;\n  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar notify = function (promise, isReject) {\n  if (promise._n) return;\n  promise._n = true;\n  var chain = promise._c;\n  microtask(function () {\n    var value = promise._v;\n    var ok = promise._s == 1;\n    var i = 0;\n    var run = function (reaction) {\n      var handler = ok ? reaction.ok : reaction.fail;\n      var resolve = reaction.resolve;\n      var reject = reaction.reject;\n      var domain = reaction.domain;\n      var result, then, exited;\n      try {\n        if (handler) {\n          if (!ok) {\n            if (promise._h == 2) onHandleUnhandled(promise);\n            promise._h = 1;\n          }\n          if (handler === true) result = value;\n          else {\n            if (domain) domain.enter();\n            result = handler(value); // may throw\n            if (domain) {\n              domain.exit();\n              exited = true;\n            }\n          }\n          if (result === reaction.promise) {\n            reject(TypeError('Promise-chain cycle'));\n          } else if (then = isThenable(result)) {\n            then.call(result, resolve, reject);\n          } else resolve(result);\n        } else reject(value);\n      } catch (e) {\n        if (domain && !exited) domain.exit();\n        reject(e);\n      }\n    };\n    while (chain.length > i) run(chain[i++]); // variable length - can't use forEach\n    promise._c = [];\n    promise._n = false;\n    if (isReject && !promise._h) onUnhandled(promise);\n  });\n};\nvar onUnhandled = function (promise) {\n  task.call(global, function () {\n    var value = promise._v;\n    var unhandled = isUnhandled(promise);\n    var result, handler, console;\n    if (unhandled) {\n      result = perform(function () {\n        if (isNode) {\n          process.emit('unhandledRejection', value, promise);\n        } else if (handler = global.onunhandledrejection) {\n          handler({ promise: promise, reason: value });\n        } else if ((console = global.console) && console.error) {\n          console.error('Unhandled promise rejection', value);\n        }\n      });\n      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n      promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n    } promise._a = undefined;\n    if (unhandled && result.e) throw result.v;\n  });\n};\nvar isUnhandled = function (promise) {\n  return promise._h !== 1 && (promise._a || promise._c).length === 0;\n};\nvar onHandleUnhandled = function (promise) {\n  task.call(global, function () {\n    var handler;\n    if (isNode) {\n      process.emit('rejectionHandled', promise);\n    } else if (handler = global.onrejectionhandled) {\n      handler({ promise: promise, reason: promise._v });\n    }\n  });\n};\nvar $reject = function (value) {\n  var promise = this;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  promise._v = value;\n  promise._s = 2;\n  if (!promise._a) promise._a = promise._c.slice();\n  notify(promise, true);\n};\nvar $resolve = function (value) {\n  var promise = this;\n  var then;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  try {\n    if (promise === value) throw TypeError(\"Promise can't be resolved itself\");\n    if (then = isThenable(value)) {\n      microtask(function () {\n        var wrapper = { _w: promise, _d: false }; // wrap\n        try {\n          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n        } catch (e) {\n          $reject.call(wrapper, e);\n        }\n      });\n    } else {\n      promise._v = value;\n      promise._s = 1;\n      notify(promise, false);\n    }\n  } catch (e) {\n    $reject.call({ _w: promise, _d: false }, e); // wrap\n  }\n};\n\n// constructor polyfill\nif (!USE_NATIVE) {\n  // 25.4.3.1 Promise(executor)\n  $Promise = function Promise(executor) {\n    anInstance(this, $Promise, PROMISE, '_h');\n    aFunction(executor);\n    Internal.call(this);\n    try {\n      executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n    } catch (err) {\n      $reject.call(this, err);\n    }\n  };\n  // eslint-disable-next-line no-unused-vars\n  Internal = function Promise(executor) {\n    this._c = [];             // <- awaiting reactions\n    this._a = undefined;      // <- checked in isUnhandled reactions\n    this._s = 0;              // <- state\n    this._d = false;          // <- done\n    this._v = undefined;      // <- value\n    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n    this._n = false;          // <- notify\n  };\n  Internal.prototype = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\")($Promise.prototype, {\n    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n    then: function then(onFulfilled, onRejected) {\n      var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n      reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n      reaction.fail = typeof onRejected == 'function' && onRejected;\n      reaction.domain = isNode ? process.domain : undefined;\n      this._c.push(reaction);\n      if (this._a) this._a.push(reaction);\n      if (this._s) notify(this, false);\n      return reaction.promise;\n    },\n    // 25.4.5.1 Promise.prototype.catch(onRejected)\n    'catch': function (onRejected) {\n      return this.then(undefined, onRejected);\n    }\n  });\n  OwnPromiseCapability = function () {\n    var promise = new Internal();\n    this.promise = promise;\n    this.resolve = ctx($resolve, promise, 1);\n    this.reject = ctx($reject, promise, 1);\n  };\n  newPromiseCapabilityModule.f = newPromiseCapability = function (C) {\n    return C === $Promise || C === Wrapper\n      ? new OwnPromiseCapability(C)\n      : newGenericPromiseCapability(C);\n  };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });\n__webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\")($Promise, PROMISE);\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")(PROMISE);\nWrapper = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\")[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n  // 25.4.4.5 Promise.reject(r)\n  reject: function reject(r) {\n    var capability = newPromiseCapability(this);\n    var $$reject = capability.reject;\n    $$reject(r);\n    return capability.promise;\n  }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n  // 25.4.4.6 Promise.resolve(x)\n  resolve: function resolve(x) {\n    return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);\n  }\n});\n$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\")(function (iter) {\n  $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n  // 25.4.4.1 Promise.all(iterable)\n  all: function all(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var resolve = capability.resolve;\n    var reject = capability.reject;\n    var result = perform(function () {\n      var values = [];\n      var index = 0;\n      var remaining = 1;\n      forOf(iterable, false, function (promise) {\n        var $index = index++;\n        var alreadyCalled = false;\n        values.push(undefined);\n        remaining++;\n        C.resolve(promise).then(function (value) {\n          if (alreadyCalled) return;\n          alreadyCalled = true;\n          values[$index] = value;\n          --remaining || resolve(values);\n        }, reject);\n      });\n      --remaining || resolve(values);\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  },\n  // 25.4.4.4 Promise.race(iterable)\n  race: function race(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var reject = capability.reject;\n    var result = perform(function () {\n      forOf(iterable, false, function (promise) {\n        C.resolve(promise).then(capability.resolve, reject);\n      });\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.apply.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.apply.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar rApply = (__webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Reflect || {}).apply;\nvar fApply = Function.apply;\n// MS Edge argumentsList argument is optional\n$export($export.S + $export.F * !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  rApply(function () { /* empty */ });\n}), 'Reflect', {\n  apply: function apply(target, thisArgument, argumentsList) {\n    var T = aFunction(target);\n    var L = anObject(argumentsList);\n    return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.construct.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.construct.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar bind = __webpack_require__(/*! ./_bind */ \"./node_modules/core-js/modules/_bind.js\");\nvar rConstruct = (__webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Reflect || {}).construct;\n\n// MS Edge supports only 2 arguments and argumentsList argument is optional\n// FF Nightly sets third argument as `new.target`, but does not create `this` from it\nvar NEW_TARGET_BUG = fails(function () {\n  function F() { /* empty */ }\n  return !(rConstruct(function () { /* empty */ }, [], F) instanceof F);\n});\nvar ARGS_BUG = !fails(function () {\n  rConstruct(function () { /* empty */ });\n});\n\n$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {\n  construct: function construct(Target, args /* , newTarget */) {\n    aFunction(Target);\n    anObject(args);\n    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);\n    if (ARGS_BUG && !NEW_TARGET_BUG) return rConstruct(Target, args, newTarget);\n    if (Target == newTarget) {\n      // w/o altered newTarget, optimization for 0-4 arguments\n      switch (args.length) {\n        case 0: return new Target();\n        case 1: return new Target(args[0]);\n        case 2: return new Target(args[0], args[1]);\n        case 3: return new Target(args[0], args[1], args[2]);\n        case 4: return new Target(args[0], args[1], args[2], args[3]);\n      }\n      // w/o altered newTarget, lot of arguments case\n      var $args = [null];\n      $args.push.apply($args, args);\n      return new (bind.apply(Target, $args))();\n    }\n    // with altered newTarget, not support built-in constructors\n    var proto = newTarget.prototype;\n    var instance = create(isObject(proto) ? proto : Object.prototype);\n    var result = Function.apply.call(Target, instance, args);\n    return isObject(result) ? result : instance;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.define-property.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.define-property.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\n\n// MS Edge has broken Reflect.defineProperty - throwing instead of returning false\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  // eslint-disable-next-line no-undef\n  Reflect.defineProperty(dP.f({}, 1, { value: 1 }), 1, { value: 2 });\n}), 'Reflect', {\n  defineProperty: function defineProperty(target, propertyKey, attributes) {\n    anObject(target);\n    propertyKey = toPrimitive(propertyKey, true);\n    anObject(attributes);\n    try {\n      dP.f(target, propertyKey, attributes);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.delete-property.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.delete-property.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.4 Reflect.deleteProperty(target, propertyKey)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\n$export($export.S, 'Reflect', {\n  deleteProperty: function deleteProperty(target, propertyKey) {\n    var desc = gOPD(anObject(target), propertyKey);\n    return desc && !desc.configurable ? false : delete target[propertyKey];\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.enumerate.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.enumerate.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 26.1.5 Reflect.enumerate(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar Enumerate = function (iterated) {\n  this._t = anObject(iterated); // target\n  this._i = 0;                  // next index\n  var keys = this._k = [];      // keys\n  var key;\n  for (key in iterated) keys.push(key);\n};\n__webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\")(Enumerate, 'Object', function () {\n  var that = this;\n  var keys = that._k;\n  var key;\n  do {\n    if (that._i >= keys.length) return { value: undefined, done: true };\n  } while (!((key = keys[that._i++]) in that._t));\n  return { value: key, done: false };\n});\n\n$export($export.S, 'Reflect', {\n  enumerate: function enumerate(target) {\n    return new Enumerate(target);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js\":\n/*!*********************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js ***!\n  \\*********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\n$export($export.S, 'Reflect', {\n  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey) {\n    return gOPD.f(anObject(target), propertyKey);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.get-prototype-of.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.get-prototype-of.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.8 Reflect.getPrototypeOf(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar getProto = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\n$export($export.S, 'Reflect', {\n  getPrototypeOf: function getPrototypeOf(target) {\n    return getProto(anObject(target));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.get.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.get.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.6 Reflect.get(target, propertyKey [, receiver])\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\nfunction get(target, propertyKey /* , receiver */) {\n  var receiver = arguments.length < 3 ? target : arguments[2];\n  var desc, proto;\n  if (anObject(target) === receiver) return target[propertyKey];\n  if (desc = gOPD.f(target, propertyKey)) return has(desc, 'value')\n    ? desc.value\n    : desc.get !== undefined\n      ? desc.get.call(receiver)\n      : undefined;\n  if (isObject(proto = getPrototypeOf(target))) return get(proto, propertyKey, receiver);\n}\n\n$export($export.S, 'Reflect', { get: get });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.has.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.has.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.9 Reflect.has(target, propertyKey)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Reflect', {\n  has: function has(target, propertyKey) {\n    return propertyKey in target;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.is-extensible.js\":\n/*!*******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.is-extensible.js ***!\n  \\*******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.10 Reflect.isExtensible(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar $isExtensible = Object.isExtensible;\n\n$export($export.S, 'Reflect', {\n  isExtensible: function isExtensible(target) {\n    anObject(target);\n    return $isExtensible ? $isExtensible(target) : true;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.own-keys.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.own-keys.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.11 Reflect.ownKeys(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Reflect', { ownKeys: __webpack_require__(/*! ./_own-keys */ \"./node_modules/core-js/modules/_own-keys.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.prevent-extensions.js\":\n/*!************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.prevent-extensions.js ***!\n  \\************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.12 Reflect.preventExtensions(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar $preventExtensions = Object.preventExtensions;\n\n$export($export.S, 'Reflect', {\n  preventExtensions: function preventExtensions(target) {\n    anObject(target);\n    try {\n      if ($preventExtensions) $preventExtensions(target);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.set-prototype-of.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.set-prototype-of.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.14 Reflect.setPrototypeOf(target, proto)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar setProto = __webpack_require__(/*! ./_set-proto */ \"./node_modules/core-js/modules/_set-proto.js\");\n\nif (setProto) $export($export.S, 'Reflect', {\n  setPrototypeOf: function setPrototypeOf(target, proto) {\n    setProto.check(target, proto);\n    try {\n      setProto.set(target, proto);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.set.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.set.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\nfunction set(target, propertyKey, V /* , receiver */) {\n  var receiver = arguments.length < 4 ? target : arguments[3];\n  var ownDesc = gOPD.f(anObject(target), propertyKey);\n  var existingDescriptor, proto;\n  if (!ownDesc) {\n    if (isObject(proto = getPrototypeOf(target))) {\n      return set(proto, propertyKey, V, receiver);\n    }\n    ownDesc = createDesc(0);\n  }\n  if (has(ownDesc, 'value')) {\n    if (ownDesc.writable === false || !isObject(receiver)) return false;\n    if (existingDescriptor = gOPD.f(receiver, propertyKey)) {\n      if (existingDescriptor.get || existingDescriptor.set || existingDescriptor.writable === false) return false;\n      existingDescriptor.value = V;\n      dP.f(receiver, propertyKey, existingDescriptor);\n    } else dP.f(receiver, propertyKey, createDesc(0, V));\n    return true;\n  }\n  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);\n}\n\n$export($export.S, 'Reflect', { set: set });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.constructor.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.constructor.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ \"./node_modules/core-js/modules/_inherit-if-required.js\");\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar $flags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\nvar $RegExp = global.RegExp;\nvar Base = $RegExp;\nvar proto = $RegExp.prototype;\nvar re1 = /a/g;\nvar re2 = /a/g;\n// \"new\" creates a new object, old webkit buggy here\nvar CORRECT_NEW = new $RegExp(re1) !== re1;\n\nif (__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && (!CORRECT_NEW || __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  re2[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('match')] = false;\n  // RegExp constructor can alter flags and IsRegExp works correct with @@match\n  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';\n}))) {\n  $RegExp = function RegExp(p, f) {\n    var tiRE = this instanceof $RegExp;\n    var piRE = isRegExp(p);\n    var fiU = f === undefined;\n    return !tiRE && piRE && p.constructor === $RegExp && fiU ? p\n      : inheritIfRequired(CORRECT_NEW\n        ? new Base(piRE && !fiU ? p.source : p, f)\n        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)\n      , tiRE ? this : proto, $RegExp);\n  };\n  var proxy = function (key) {\n    key in $RegExp || dP($RegExp, key, {\n      configurable: true,\n      get: function () { return Base[key]; },\n      set: function (it) { Base[key] = it; }\n    });\n  };\n  for (var keys = gOPN(Base), i = 0; keys.length > i;) proxy(keys[i++]);\n  proto.constructor = $RegExp;\n  $RegExp.prototype = proto;\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(global, 'RegExp', $RegExp);\n}\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")('RegExp');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.exec.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.exec.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar regexpExec = __webpack_require__(/*! ./_regexp-exec */ \"./node_modules/core-js/modules/_regexp-exec.js\");\n__webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\")({\n  target: 'RegExp',\n  proto: true,\n  forced: regexpExec !== /./.exec\n}, {\n  exec: regexpExec\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.flags.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.flags.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 21.2.5.3 get RegExp.prototype.flags()\nif (__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && /./g.flags != 'g') __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f(RegExp.prototype, 'flags', {\n  configurable: true,\n  get: __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\")\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.match.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.match.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar advanceStringIndex = __webpack_require__(/*! ./_advance-string-index */ \"./node_modules/core-js/modules/_advance-string-index.js\");\nvar regExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\n\n// @@match logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('match', 1, function (defined, MATCH, $match, maybeCallNative) {\n  return [\n    // `String.prototype.match` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.match\n    function match(regexp) {\n      var O = defined(this);\n      var fn = regexp == undefined ? undefined : regexp[MATCH];\n      return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));\n    },\n    // `RegExp.prototype[@@match]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match\n    function (regexp) {\n      var res = maybeCallNative($match, regexp, this);\n      if (res.done) return res.value;\n      var rx = anObject(regexp);\n      var S = String(this);\n      if (!rx.global) return regExpExec(rx, S);\n      var fullUnicode = rx.unicode;\n      rx.lastIndex = 0;\n      var A = [];\n      var n = 0;\n      var result;\n      while ((result = regExpExec(rx, S)) !== null) {\n        var matchStr = String(result[0]);\n        A[n] = matchStr;\n        if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n        n++;\n      }\n      return n === 0 ? null : A;\n    }\n  ];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.replace.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.replace.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar advanceStringIndex = __webpack_require__(/*! ./_advance-string-index */ \"./node_modules/core-js/modules/_advance-string-index.js\");\nvar regExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\nvar max = Math.max;\nvar min = Math.min;\nvar floor = Math.floor;\nvar SUBSTITUTION_SYMBOLS = /\\$([$&`']|\\d\\d?|<[^>]*>)/g;\nvar SUBSTITUTION_SYMBOLS_NO_NAMED = /\\$([$&`']|\\d\\d?)/g;\n\nvar maybeToString = function (it) {\n  return it === undefined ? it : String(it);\n};\n\n// @@replace logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {\n  return [\n    // `String.prototype.replace` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.replace\n    function replace(searchValue, replaceValue) {\n      var O = defined(this);\n      var fn = searchValue == undefined ? undefined : searchValue[REPLACE];\n      return fn !== undefined\n        ? fn.call(searchValue, O, replaceValue)\n        : $replace.call(String(O), searchValue, replaceValue);\n    },\n    // `RegExp.prototype[@@replace]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace\n    function (regexp, replaceValue) {\n      var res = maybeCallNative($replace, regexp, this, replaceValue);\n      if (res.done) return res.value;\n\n      var rx = anObject(regexp);\n      var S = String(this);\n      var functionalReplace = typeof replaceValue === 'function';\n      if (!functionalReplace) replaceValue = String(replaceValue);\n      var global = rx.global;\n      if (global) {\n        var fullUnicode = rx.unicode;\n        rx.lastIndex = 0;\n      }\n      var results = [];\n      while (true) {\n        var result = regExpExec(rx, S);\n        if (result === null) break;\n        results.push(result);\n        if (!global) break;\n        var matchStr = String(result[0]);\n        if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n      }\n      var accumulatedResult = '';\n      var nextSourcePosition = 0;\n      for (var i = 0; i < results.length; i++) {\n        result = results[i];\n        var matched = String(result[0]);\n        var position = max(min(toInteger(result.index), S.length), 0);\n        var captures = [];\n        // NOTE: This is equivalent to\n        //   captures = result.slice(1).map(maybeToString)\n        // but for some reason `nativeSlice.call(result, 1, result.length)` (called in\n        // the slice polyfill when slicing native arrays) \"doesn't work\" in safari 9 and\n        // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.\n        for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));\n        var namedCaptures = result.groups;\n        if (functionalReplace) {\n          var replacerArgs = [matched].concat(captures, position, S);\n          if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);\n          var replacement = String(replaceValue.apply(undefined, replacerArgs));\n        } else {\n          replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);\n        }\n        if (position >= nextSourcePosition) {\n          accumulatedResult += S.slice(nextSourcePosition, position) + replacement;\n          nextSourcePosition = position + matched.length;\n        }\n      }\n      return accumulatedResult + S.slice(nextSourcePosition);\n    }\n  ];\n\n    // https://tc39.github.io/ecma262/#sec-getsubstitution\n  function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {\n    var tailPos = position + matched.length;\n    var m = captures.length;\n    var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;\n    if (namedCaptures !== undefined) {\n      namedCaptures = toObject(namedCaptures);\n      symbols = SUBSTITUTION_SYMBOLS;\n    }\n    return $replace.call(replacement, symbols, function (match, ch) {\n      var capture;\n      switch (ch.charAt(0)) {\n        case '$': return '$';\n        case '&': return matched;\n        case '`': return str.slice(0, position);\n        case \"'\": return str.slice(tailPos);\n        case '<':\n          capture = namedCaptures[ch.slice(1, -1)];\n          break;\n        default: // \\d\\d?\n          var n = +ch;\n          if (n === 0) return match;\n          if (n > m) {\n            var f = floor(n / 10);\n            if (f === 0) return match;\n            if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);\n            return match;\n          }\n          capture = captures[n - 1];\n      }\n      return capture === undefined ? '' : capture;\n    });\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.search.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.search.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar sameValue = __webpack_require__(/*! ./_same-value */ \"./node_modules/core-js/modules/_same-value.js\");\nvar regExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\n\n// @@search logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('search', 1, function (defined, SEARCH, $search, maybeCallNative) {\n  return [\n    // `String.prototype.search` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.search\n    function search(regexp) {\n      var O = defined(this);\n      var fn = regexp == undefined ? undefined : regexp[SEARCH];\n      return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));\n    },\n    // `RegExp.prototype[@@search]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search\n    function (regexp) {\n      var res = maybeCallNative($search, regexp, this);\n      if (res.done) return res.value;\n      var rx = anObject(regexp);\n      var S = String(this);\n      var previousLastIndex = rx.lastIndex;\n      if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0;\n      var result = regExpExec(rx, S);\n      if (!sameValue(rx.lastIndex, previousLastIndex)) rx.lastIndex = previousLastIndex;\n      return result === null ? -1 : result.index;\n    }\n  ];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.split.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.split.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar advanceStringIndex = __webpack_require__(/*! ./_advance-string-index */ \"./node_modules/core-js/modules/_advance-string-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar callRegExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\nvar regexpExec = __webpack_require__(/*! ./_regexp-exec */ \"./node_modules/core-js/modules/_regexp-exec.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar $min = Math.min;\nvar $push = [].push;\nvar $SPLIT = 'split';\nvar LENGTH = 'length';\nvar LAST_INDEX = 'lastIndex';\nvar MAX_UINT32 = 0xffffffff;\n\n// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError\nvar SUPPORTS_Y = !fails(function () { RegExp(MAX_UINT32, 'y'); });\n\n// @@split logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('split', 2, function (defined, SPLIT, $split, maybeCallNative) {\n  var internalSplit;\n  if (\n    'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||\n    'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||\n    'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||\n    '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||\n    '.'[$SPLIT](/()()/)[LENGTH] > 1 ||\n    ''[$SPLIT](/.?/)[LENGTH]\n  ) {\n    // based on es5-shim implementation, need to rework it\n    internalSplit = function (separator, limit) {\n      var string = String(this);\n      if (separator === undefined && limit === 0) return [];\n      // If `separator` is not a regex, use native split\n      if (!isRegExp(separator)) return $split.call(string, separator, limit);\n      var output = [];\n      var flags = (separator.ignoreCase ? 'i' : '') +\n                  (separator.multiline ? 'm' : '') +\n                  (separator.unicode ? 'u' : '') +\n                  (separator.sticky ? 'y' : '');\n      var lastLastIndex = 0;\n      var splitLimit = limit === undefined ? MAX_UINT32 : limit >>> 0;\n      // Make `global` and avoid `lastIndex` issues by working with a copy\n      var separatorCopy = new RegExp(separator.source, flags + 'g');\n      var match, lastIndex, lastLength;\n      while (match = regexpExec.call(separatorCopy, string)) {\n        lastIndex = separatorCopy[LAST_INDEX];\n        if (lastIndex > lastLastIndex) {\n          output.push(string.slice(lastLastIndex, match.index));\n          if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));\n          lastLength = match[0][LENGTH];\n          lastLastIndex = lastIndex;\n          if (output[LENGTH] >= splitLimit) break;\n        }\n        if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop\n      }\n      if (lastLastIndex === string[LENGTH]) {\n        if (lastLength || !separatorCopy.test('')) output.push('');\n      } else output.push(string.slice(lastLastIndex));\n      return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;\n    };\n  // Chakra, V8\n  } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {\n    internalSplit = function (separator, limit) {\n      return separator === undefined && limit === 0 ? [] : $split.call(this, separator, limit);\n    };\n  } else {\n    internalSplit = $split;\n  }\n\n  return [\n    // `String.prototype.split` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.split\n    function split(separator, limit) {\n      var O = defined(this);\n      var splitter = separator == undefined ? undefined : separator[SPLIT];\n      return splitter !== undefined\n        ? splitter.call(separator, O, limit)\n        : internalSplit.call(String(O), separator, limit);\n    },\n    // `RegExp.prototype[@@split]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split\n    //\n    // NOTE: This cannot be properly polyfilled in engines that don't support\n    // the 'y' flag.\n    function (regexp, limit) {\n      var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== $split);\n      if (res.done) return res.value;\n\n      var rx = anObject(regexp);\n      var S = String(this);\n      var C = speciesConstructor(rx, RegExp);\n\n      var unicodeMatching = rx.unicode;\n      var flags = (rx.ignoreCase ? 'i' : '') +\n                  (rx.multiline ? 'm' : '') +\n                  (rx.unicode ? 'u' : '') +\n                  (SUPPORTS_Y ? 'y' : 'g');\n\n      // ^(? + rx + ) is needed, in combination with some S slicing, to\n      // simulate the 'y' flag.\n      var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);\n      var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n      if (lim === 0) return [];\n      if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];\n      var p = 0;\n      var q = 0;\n      var A = [];\n      while (q < S.length) {\n        splitter.lastIndex = SUPPORTS_Y ? q : 0;\n        var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));\n        var e;\n        if (\n          z === null ||\n          (e = $min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p\n        ) {\n          q = advanceStringIndex(S, q, unicodeMatching);\n        } else {\n          A.push(S.slice(p, q));\n          if (A.length === lim) return A;\n          for (var i = 1; i <= z.length - 1; i++) {\n            A.push(z[i]);\n            if (A.length === lim) return A;\n          }\n          q = p = e;\n        }\n      }\n      A.push(S.slice(p));\n      return A;\n    }\n  ];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.to-string.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.to-string.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n__webpack_require__(/*! ./es6.regexp.flags */ \"./node_modules/core-js/modules/es6.regexp.flags.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar $flags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar TO_STRING = 'toString';\nvar $toString = /./[TO_STRING];\n\nvar define = function (fn) {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(RegExp.prototype, TO_STRING, fn, true);\n};\n\n// 21.2.5.14 RegExp.prototype.toString()\nif (__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () { return $toString.call({ source: 'a', flags: 'b' }) != '/a/b'; })) {\n  define(function toString() {\n    var R = anObject(this);\n    return '/'.concat(R.source, '/',\n      'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);\n  });\n// FF44- RegExp#toString has a wrong name\n} else if ($toString.name != TO_STRING) {\n  define(function toString() {\n    return $toString.call(this);\n  });\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.set.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.set.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar strong = __webpack_require__(/*! ./_collection-strong */ \"./node_modules/core-js/modules/_collection-strong.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar SET = 'Set';\n\n// 23.2 Set Objects\nmodule.exports = __webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(SET, function (get) {\n  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.2.3.1 Set.prototype.add(value)\n  add: function add(value) {\n    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);\n  }\n}, strong);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.anchor.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.anchor.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.2 String.prototype.anchor(name)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('anchor', function (createHTML) {\n  return function anchor(name) {\n    return createHTML(this, 'a', 'name', name);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.big.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.big.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.3 String.prototype.big()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('big', function (createHTML) {\n  return function big() {\n    return createHTML(this, 'big', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.blink.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.blink.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.4 String.prototype.blink()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('blink', function (createHTML) {\n  return function blink() {\n    return createHTML(this, 'blink', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.bold.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.bold.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.5 String.prototype.bold()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('bold', function (createHTML) {\n  return function bold() {\n    return createHTML(this, 'b', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.code-point-at.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.code-point-at.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(false);\n$export($export.P, 'String', {\n  // 21.1.3.3 String.prototype.codePointAt(pos)\n  codePointAt: function codePointAt(pos) {\n    return $at(this, pos);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.ends-with.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.ends-with.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar context = __webpack_require__(/*! ./_string-context */ \"./node_modules/core-js/modules/_string-context.js\");\nvar ENDS_WITH = 'endsWith';\nvar $endsWith = ''[ENDS_WITH];\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ \"./node_modules/core-js/modules/_fails-is-regexp.js\")(ENDS_WITH), 'String', {\n  endsWith: function endsWith(searchString /* , endPosition = @length */) {\n    var that = context(this, searchString, ENDS_WITH);\n    var endPosition = arguments.length > 1 ? arguments[1] : undefined;\n    var len = toLength(that.length);\n    var end = endPosition === undefined ? len : Math.min(toLength(endPosition), len);\n    var search = String(searchString);\n    return $endsWith\n      ? $endsWith.call(that, search, end)\n      : that.slice(end - search.length, end) === search;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.fixed.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.fixed.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.6 String.prototype.fixed()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('fixed', function (createHTML) {\n  return function fixed() {\n    return createHTML(this, 'tt', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.fontcolor.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.fontcolor.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.7 String.prototype.fontcolor(color)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('fontcolor', function (createHTML) {\n  return function fontcolor(color) {\n    return createHTML(this, 'font', 'color', color);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.fontsize.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.fontsize.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.8 String.prototype.fontsize(size)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('fontsize', function (createHTML) {\n  return function fontsize(size) {\n    return createHTML(this, 'font', 'size', size);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.from-code-point.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.from-code-point.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar fromCharCode = String.fromCharCode;\nvar $fromCodePoint = String.fromCodePoint;\n\n// length should be 1, old FF problem\n$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {\n  // 21.1.2.2 String.fromCodePoint(...codePoints)\n  fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars\n    var res = [];\n    var aLen = arguments.length;\n    var i = 0;\n    var code;\n    while (aLen > i) {\n      code = +arguments[i++];\n      if (toAbsoluteIndex(code, 0x10ffff) !== code) throw RangeError(code + ' is not a valid code point');\n      res.push(code < 0x10000\n        ? fromCharCode(code)\n        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)\n      );\n    } return res.join('');\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.includes.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.includes.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 21.1.3.7 String.prototype.includes(searchString, position = 0)\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar context = __webpack_require__(/*! ./_string-context */ \"./node_modules/core-js/modules/_string-context.js\");\nvar INCLUDES = 'includes';\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ \"./node_modules/core-js/modules/_fails-is-regexp.js\")(INCLUDES), 'String', {\n  includes: function includes(searchString /* , position = 0 */) {\n    return !!~context(this, searchString, INCLUDES)\n      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.italics.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.italics.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.9 String.prototype.italics()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('italics', function (createHTML) {\n  return function italics() {\n    return createHTML(this, 'i', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.iterator.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.iterator.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\n__webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(String, 'String', function (iterated) {\n  this._t = String(iterated); // target\n  this._i = 0;                // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var index = this._i;\n  var point;\n  if (index >= O.length) return { value: undefined, done: true };\n  point = $at(O, index);\n  this._i += point.length;\n  return { value: point, done: false };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.link.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.link.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.10 String.prototype.link(url)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('link', function (createHTML) {\n  return function link(url) {\n    return createHTML(this, 'a', 'href', url);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.raw.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.raw.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n\n$export($export.S, 'String', {\n  // 21.1.2.4 String.raw(callSite, ...substitutions)\n  raw: function raw(callSite) {\n    var tpl = toIObject(callSite.raw);\n    var len = toLength(tpl.length);\n    var aLen = arguments.length;\n    var res = [];\n    var i = 0;\n    while (len > i) {\n      res.push(String(tpl[i++]));\n      if (i < aLen) res.push(String(arguments[i]));\n    } return res.join('');\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.repeat.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.repeat.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'String', {\n  // 21.1.3.13 String.prototype.repeat(count)\n  repeat: __webpack_require__(/*! ./_string-repeat */ \"./node_modules/core-js/modules/_string-repeat.js\")\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.small.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.small.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.11 String.prototype.small()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('small', function (createHTML) {\n  return function small() {\n    return createHTML(this, 'small', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.starts-with.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.starts-with.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 21.1.3.18 String.prototype.startsWith(searchString [, position ])\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar context = __webpack_require__(/*! ./_string-context */ \"./node_modules/core-js/modules/_string-context.js\");\nvar STARTS_WITH = 'startsWith';\nvar $startsWith = ''[STARTS_WITH];\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ \"./node_modules/core-js/modules/_fails-is-regexp.js\")(STARTS_WITH), 'String', {\n  startsWith: function startsWith(searchString /* , position = 0 */) {\n    var that = context(this, searchString, STARTS_WITH);\n    var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length));\n    var search = String(searchString);\n    return $startsWith\n      ? $startsWith.call(that, search, index)\n      : that.slice(index, index + search.length) === search;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.strike.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.strike.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.12 String.prototype.strike()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('strike', function (createHTML) {\n  return function strike() {\n    return createHTML(this, 'strike', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.sub.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.sub.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.13 String.prototype.sub()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('sub', function (createHTML) {\n  return function sub() {\n    return createHTML(this, 'sub', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.sup.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.sup.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.14 String.prototype.sup()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('sup', function (createHTML) {\n  return function sup() {\n    return createHTML(this, 'sup', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.trim.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.trim.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 21.1.3.25 String.prototype.trim()\n__webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\")('trim', function ($trim) {\n  return function trim() {\n    return $trim(this, 3);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.symbol.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.symbol.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// ECMAScript 6 symbols shim\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar META = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").KEY;\nvar $fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar wksExt = __webpack_require__(/*! ./_wks-ext */ \"./node_modules/core-js/modules/_wks-ext.js\");\nvar wksDefine = __webpack_require__(/*! ./_wks-define */ \"./node_modules/core-js/modules/_wks-define.js\");\nvar enumKeys = __webpack_require__(/*! ./_enum-keys */ \"./node_modules/core-js/modules/_enum-keys.js\");\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar _create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar gOPNExt = __webpack_require__(/*! ./_object-gopn-ext */ \"./node_modules/core-js/modules/_object-gopn-ext.js\");\nvar $GOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar $DP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar $keys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPD = $GOPD.f;\nvar dP = $DP.f;\nvar gOPN = gOPNExt.f;\nvar $Symbol = global.Symbol;\nvar $JSON = global.JSON;\nvar _stringify = $JSON && $JSON.stringify;\nvar PROTOTYPE = 'prototype';\nvar HIDDEN = wks('_hidden');\nvar TO_PRIMITIVE = wks('toPrimitive');\nvar isEnum = {}.propertyIsEnumerable;\nvar SymbolRegistry = shared('symbol-registry');\nvar AllSymbols = shared('symbols');\nvar OPSymbols = shared('op-symbols');\nvar ObjectProto = Object[PROTOTYPE];\nvar USE_NATIVE = typeof $Symbol == 'function';\nvar QObject = global.QObject;\n// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173\nvar setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;\n\n// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\nvar setSymbolDesc = DESCRIPTORS && $fails(function () {\n  return _create(dP({}, 'a', {\n    get: function () { return dP(this, 'a', { value: 7 }).a; }\n  })).a != 7;\n}) ? function (it, key, D) {\n  var protoDesc = gOPD(ObjectProto, key);\n  if (protoDesc) delete ObjectProto[key];\n  dP(it, key, D);\n  if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc);\n} : dP;\n\nvar wrap = function (tag) {\n  var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);\n  sym._k = tag;\n  return sym;\n};\n\nvar isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) {\n  return typeof it == 'symbol';\n} : function (it) {\n  return it instanceof $Symbol;\n};\n\nvar $defineProperty = function defineProperty(it, key, D) {\n  if (it === ObjectProto) $defineProperty(OPSymbols, key, D);\n  anObject(it);\n  key = toPrimitive(key, true);\n  anObject(D);\n  if (has(AllSymbols, key)) {\n    if (!D.enumerable) {\n      if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {}));\n      it[HIDDEN][key] = true;\n    } else {\n      if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;\n      D = _create(D, { enumerable: createDesc(0, false) });\n    } return setSymbolDesc(it, key, D);\n  } return dP(it, key, D);\n};\nvar $defineProperties = function defineProperties(it, P) {\n  anObject(it);\n  var keys = enumKeys(P = toIObject(P));\n  var i = 0;\n  var l = keys.length;\n  var key;\n  while (l > i) $defineProperty(it, key = keys[i++], P[key]);\n  return it;\n};\nvar $create = function create(it, P) {\n  return P === undefined ? _create(it) : $defineProperties(_create(it), P);\n};\nvar $propertyIsEnumerable = function propertyIsEnumerable(key) {\n  var E = isEnum.call(this, key = toPrimitive(key, true));\n  if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false;\n  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;\n};\nvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) {\n  it = toIObject(it);\n  key = toPrimitive(key, true);\n  if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return;\n  var D = gOPD(it, key);\n  if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true;\n  return D;\n};\nvar $getOwnPropertyNames = function getOwnPropertyNames(it) {\n  var names = gOPN(toIObject(it));\n  var result = [];\n  var i = 0;\n  var key;\n  while (names.length > i) {\n    if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key);\n  } return result;\n};\nvar $getOwnPropertySymbols = function getOwnPropertySymbols(it) {\n  var IS_OP = it === ObjectProto;\n  var names = gOPN(IS_OP ? OPSymbols : toIObject(it));\n  var result = [];\n  var i = 0;\n  var key;\n  while (names.length > i) {\n    if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]);\n  } return result;\n};\n\n// 19.4.1.1 Symbol([description])\nif (!USE_NATIVE) {\n  $Symbol = function Symbol() {\n    if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!');\n    var tag = uid(arguments.length > 0 ? arguments[0] : undefined);\n    var $set = function (value) {\n      if (this === ObjectProto) $set.call(OPSymbols, value);\n      if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;\n      setSymbolDesc(this, tag, createDesc(1, value));\n    };\n    if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set });\n    return wrap(tag);\n  };\n  redefine($Symbol[PROTOTYPE], 'toString', function toString() {\n    return this._k;\n  });\n\n  $GOPD.f = $getOwnPropertyDescriptor;\n  $DP.f = $defineProperty;\n  __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f = gOPNExt.f = $getOwnPropertyNames;\n  __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\").f = $propertyIsEnumerable;\n  __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\").f = $getOwnPropertySymbols;\n\n  if (DESCRIPTORS && !__webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\")) {\n    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);\n  }\n\n  wksExt.f = function (name) {\n    return wrap(wks(name));\n  };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol });\n\nfor (var es6Symbols = (\n  // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14\n  'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'\n).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]);\n\nfor (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]);\n\n$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {\n  // 19.4.2.1 Symbol.for(key)\n  'for': function (key) {\n    return has(SymbolRegistry, key += '')\n      ? SymbolRegistry[key]\n      : SymbolRegistry[key] = $Symbol(key);\n  },\n  // 19.4.2.5 Symbol.keyFor(sym)\n  keyFor: function keyFor(sym) {\n    if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!');\n    for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key;\n  },\n  useSetter: function () { setter = true; },\n  useSimple: function () { setter = false; }\n});\n\n$export($export.S + $export.F * !USE_NATIVE, 'Object', {\n  // 19.1.2.2 Object.create(O [, Properties])\n  create: $create,\n  // 19.1.2.4 Object.defineProperty(O, P, Attributes)\n  defineProperty: $defineProperty,\n  // 19.1.2.3 Object.defineProperties(O, Properties)\n  defineProperties: $defineProperties,\n  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\n  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,\n  // 19.1.2.7 Object.getOwnPropertyNames(O)\n  getOwnPropertyNames: $getOwnPropertyNames,\n  // 19.1.2.8 Object.getOwnPropertySymbols(O)\n  getOwnPropertySymbols: $getOwnPropertySymbols\n});\n\n// 24.3.2 JSON.stringify(value [, replacer [, space]])\n$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () {\n  var S = $Symbol();\n  // MS Edge converts symbol values to JSON as {}\n  // WebKit converts symbol values to JSON as null\n  // V8 throws on boxed symbols\n  return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}';\n})), 'JSON', {\n  stringify: function stringify(it) {\n    var args = [it];\n    var i = 1;\n    var replacer, $replacer;\n    while (arguments.length > i) args.push(arguments[i++]);\n    $replacer = replacer = args[1];\n    if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined\n    if (!isArray(replacer)) replacer = function (key, value) {\n      if (typeof $replacer == 'function') value = $replacer.call(this, key, value);\n      if (!isSymbol(value)) return value;\n    };\n    args[1] = replacer;\n    return _stringify.apply($JSON, args);\n  }\n});\n\n// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)\n$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);\n// 19.4.3.5 Symbol.prototype[@@toStringTag]\nsetToStringTag($Symbol, 'Symbol');\n// 20.2.1.9 Math[@@toStringTag]\nsetToStringTag(Math, 'Math', true);\n// 24.3.3 JSON[@@toStringTag]\nsetToStringTag(global.JSON, 'JSON', true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.array-buffer.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.array-buffer.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $typed = __webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\");\nvar buffer = __webpack_require__(/*! ./_typed-buffer */ \"./node_modules/core-js/modules/_typed-buffer.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar ArrayBuffer = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").ArrayBuffer;\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar $ArrayBuffer = buffer.ArrayBuffer;\nvar $DataView = buffer.DataView;\nvar $isView = $typed.ABV && ArrayBuffer.isView;\nvar $slice = $ArrayBuffer.prototype.slice;\nvar VIEW = $typed.VIEW;\nvar ARRAY_BUFFER = 'ArrayBuffer';\n\n$export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), { ArrayBuffer: $ArrayBuffer });\n\n$export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, {\n  // 24.1.3.1 ArrayBuffer.isView(arg)\n  isView: function isView(it) {\n    return $isView && $isView(it) || isObject(it) && VIEW in it;\n  }\n});\n\n$export($export.P + $export.U + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return !new $ArrayBuffer(2).slice(1, undefined).byteLength;\n}), ARRAY_BUFFER, {\n  // 24.1.4.3 ArrayBuffer.prototype.slice(start, end)\n  slice: function slice(start, end) {\n    if ($slice !== undefined && end === undefined) return $slice.call(anObject(this), start); // FF fix\n    var len = anObject(this).byteLength;\n    var first = toAbsoluteIndex(start, len);\n    var fin = toAbsoluteIndex(end === undefined ? len : end, len);\n    var result = new (speciesConstructor(this, $ArrayBuffer))(toLength(fin - first));\n    var viewS = new $DataView(this);\n    var viewT = new $DataView(result);\n    var index = 0;\n    while (first < fin) {\n      viewT.setUint8(index++, viewS.getUint8(first++));\n    } return result;\n  }\n});\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")(ARRAY_BUFFER);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.data-view.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.data-view.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n$export($export.G + $export.W + $export.F * !__webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\").ABV, {\n  DataView: __webpack_require__(/*! ./_typed-buffer */ \"./node_modules/core-js/modules/_typed-buffer.js\").DataView\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.float32-array.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.float32-array.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Float32', 4, function (init) {\n  return function Float32Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.float64-array.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.float64-array.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Float64', 8, function (init) {\n  return function Float64Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.int16-array.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.int16-array.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Int16', 2, function (init) {\n  return function Int16Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.int32-array.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.int32-array.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Int32', 4, function (init) {\n  return function Int32Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.int8-array.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.int8-array.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Int8', 1, function (init) {\n  return function Int8Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint16-array.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint16-array.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint16', 2, function (init) {\n  return function Uint16Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint32-array.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint32-array.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint32', 4, function (init) {\n  return function Uint32Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint8-array.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint8-array.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint8', 1, function (init) {\n  return function Uint8Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js\":\n/*!***********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js ***!\n  \\***********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint8', 1, function (init) {\n  return function Uint8ClampedArray(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n}, true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.weak-map.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.weak-map.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar each = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(0);\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\");\nvar assign = __webpack_require__(/*! ./_object-assign */ \"./node_modules/core-js/modules/_object-assign.js\");\nvar weak = __webpack_require__(/*! ./_collection-weak */ \"./node_modules/core-js/modules/_collection-weak.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar NATIVE_WEAK_MAP = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar IS_IE11 = !global.ActiveXObject && 'ActiveXObject' in global;\nvar WEAK_MAP = 'WeakMap';\nvar getWeak = meta.getWeak;\nvar isExtensible = Object.isExtensible;\nvar uncaughtFrozenStore = weak.ufstore;\nvar InternalMap;\n\nvar wrapper = function (get) {\n  return function WeakMap() {\n    return get(this, arguments.length > 0 ? arguments[0] : undefined);\n  };\n};\n\nvar methods = {\n  // 23.3.3.3 WeakMap.prototype.get(key)\n  get: function get(key) {\n    if (isObject(key)) {\n      var data = getWeak(key);\n      if (data === true) return uncaughtFrozenStore(validate(this, WEAK_MAP)).get(key);\n      return data ? data[this._i] : undefined;\n    }\n  },\n  // 23.3.3.5 WeakMap.prototype.set(key, value)\n  set: function set(key, value) {\n    return weak.def(validate(this, WEAK_MAP), key, value);\n  }\n};\n\n// 23.3 WeakMap Objects\nvar $WeakMap = module.exports = __webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(WEAK_MAP, wrapper, methods, weak, true, true);\n\n// IE11 WeakMap frozen keys fix\nif (NATIVE_WEAK_MAP && IS_IE11) {\n  InternalMap = weak.getConstructor(wrapper, WEAK_MAP);\n  assign(InternalMap.prototype, methods);\n  meta.NEED = true;\n  each(['delete', 'has', 'get', 'set'], function (key) {\n    var proto = $WeakMap.prototype;\n    var method = proto[key];\n    redefine(proto, key, function (a, b) {\n      // store frozen objects on internal weakmap shim\n      if (isObject(a) && !isExtensible(a)) {\n        if (!this._f) this._f = new InternalMap();\n        var result = this._f[key](a, b);\n        return key == 'set' ? this : result;\n      // store all the rest on native weakmap\n      } return method.call(this, a, b);\n    });\n  });\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.weak-set.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.weak-set.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar weak = __webpack_require__(/*! ./_collection-weak */ \"./node_modules/core-js/modules/_collection-weak.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar WEAK_SET = 'WeakSet';\n\n// 23.4 WeakSet Objects\n__webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(WEAK_SET, function (get) {\n  return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.4.3.1 WeakSet.prototype.add(value)\n  add: function add(value) {\n    return weak.def(validate(this, WEAK_SET), value, true);\n  }\n}, weak, false, true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.array.flat-map.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.array.flat-map.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatMap\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar flattenIntoArray = __webpack_require__(/*! ./_flatten-into-array */ \"./node_modules/core-js/modules/_flatten-into-array.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar arraySpeciesCreate = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\n\n$export($export.P, 'Array', {\n  flatMap: function flatMap(callbackfn /* , thisArg */) {\n    var O = toObject(this);\n    var sourceLen, A;\n    aFunction(callbackfn);\n    sourceLen = toLength(O.length);\n    A = arraySpeciesCreate(O, 0);\n    flattenIntoArray(A, O, O, sourceLen, 0, 1, callbackfn, arguments[1]);\n    return A;\n  }\n});\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('flatMap');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.array.flatten.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.array.flatten.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatten\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar flattenIntoArray = __webpack_require__(/*! ./_flatten-into-array */ \"./node_modules/core-js/modules/_flatten-into-array.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar arraySpeciesCreate = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\n\n$export($export.P, 'Array', {\n  flatten: function flatten(/* depthArg = 1 */) {\n    var depthArg = arguments[0];\n    var O = toObject(this);\n    var sourceLen = toLength(O.length);\n    var A = arraySpeciesCreate(O, 0);\n    flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toInteger(depthArg));\n    return A;\n  }\n});\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('flatten');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.array.includes.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.array.includes.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/Array.prototype.includes\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $includes = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(true);\n\n$export($export.P, 'Array', {\n  includes: function includes(el /* , fromIndex = 0 */) {\n    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('includes');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.asap.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.asap.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar process = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").process;\nvar isNode = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process';\n\n$export($export.G, {\n  asap: function asap(fn) {\n    var domain = isNode && process.domain;\n    microtask(domain ? domain.bind(fn) : fn);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.error.is-error.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.error.is-error.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/ljharb/proposal-is-error\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\n\n$export($export.S, 'Error', {\n  isError: function isError(it) {\n    return cof(it) === 'Error';\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.global.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.global.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-global\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.G, { global: __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.map.from.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.map.from.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-map.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('Map');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.map.of.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.map.of.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-map.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('Map');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.map.to-json.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.map.to-json.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P + $export.R, 'Map', { toJSON: __webpack_require__(/*! ./_collection-to-json */ \"./node_modules/core-js/modules/_collection-to-json.js\")('Map') });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.clamp.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.clamp.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  clamp: function clamp(x, lower, upper) {\n    return Math.min(upper, Math.max(lower, x));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.deg-per-rad.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.deg-per-rad.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { DEG_PER_RAD: Math.PI / 180 });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.degrees.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.degrees.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar RAD_PER_DEG = 180 / Math.PI;\n\n$export($export.S, 'Math', {\n  degrees: function degrees(radians) {\n    return radians * RAD_PER_DEG;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.fscale.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.fscale.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar scale = __webpack_require__(/*! ./_math-scale */ \"./node_modules/core-js/modules/_math-scale.js\");\nvar fround = __webpack_require__(/*! ./_math-fround */ \"./node_modules/core-js/modules/_math-fround.js\");\n\n$export($export.S, 'Math', {\n  fscale: function fscale(x, inLow, inHigh, outLow, outHigh) {\n    return fround(scale(x, inLow, inHigh, outLow, outHigh));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.iaddh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.iaddh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  iaddh: function iaddh(x0, x1, y0, y1) {\n    var $x0 = x0 >>> 0;\n    var $x1 = x1 >>> 0;\n    var $y0 = y0 >>> 0;\n    return $x1 + (y1 >>> 0) + (($x0 & $y0 | ($x0 | $y0) & ~($x0 + $y0 >>> 0)) >>> 31) | 0;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.imulh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.imulh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  imulh: function imulh(u, v) {\n    var UINT16 = 0xffff;\n    var $u = +u;\n    var $v = +v;\n    var u0 = $u & UINT16;\n    var v0 = $v & UINT16;\n    var u1 = $u >> 16;\n    var v1 = $v >> 16;\n    var t = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);\n    return u1 * v1 + (t >> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >> 16);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.isubh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.isubh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  isubh: function isubh(x0, x1, y0, y1) {\n    var $x0 = x0 >>> 0;\n    var $x1 = x1 >>> 0;\n    var $y0 = y0 >>> 0;\n    return $x1 - (y1 >>> 0) - ((~$x0 & $y0 | ~($x0 ^ $y0) & $x0 - $y0 >>> 0) >>> 31) | 0;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.rad-per-deg.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.rad-per-deg.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { RAD_PER_DEG: 180 / Math.PI });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.radians.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.radians.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar DEG_PER_RAD = Math.PI / 180;\n\n$export($export.S, 'Math', {\n  radians: function radians(degrees) {\n    return degrees * DEG_PER_RAD;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.scale.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.scale.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { scale: __webpack_require__(/*! ./_math-scale */ \"./node_modules/core-js/modules/_math-scale.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.signbit.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.signbit.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// http://jfbastien.github.io/papers/Math.signbit.html\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { signbit: function signbit(x) {\n  // eslint-disable-next-line no-self-compare\n  return (x = +x) != x ? x : x == 0 ? 1 / x == Infinity : x > 0;\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.umulh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.umulh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  umulh: function umulh(u, v) {\n    var UINT16 = 0xffff;\n    var $u = +u;\n    var $v = +v;\n    var u0 = $u & UINT16;\n    var v0 = $v & UINT16;\n    var u1 = $u >>> 16;\n    var v1 = $v >>> 16;\n    var t = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);\n    return u1 * v1 + (t >>> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >>> 16);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.define-getter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.define-getter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar $defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\n\n// B.2.2.2 Object.prototype.__defineGetter__(P, getter)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __defineGetter__: function __defineGetter__(P, getter) {\n    $defineProperty.f(toObject(this), P, { get: aFunction(getter), enumerable: true, configurable: true });\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.define-setter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.define-setter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar $defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\n\n// B.2.2.3 Object.prototype.__defineSetter__(P, setter)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __defineSetter__: function __defineSetter__(P, setter) {\n    $defineProperty.f(toObject(this), P, { set: aFunction(setter), enumerable: true, configurable: true });\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.entries.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.entries.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-object-values-entries\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $entries = __webpack_require__(/*! ./_object-to-array */ \"./node_modules/core-js/modules/_object-to-array.js\")(true);\n\n$export($export.S, 'Object', {\n  entries: function entries(it) {\n    return $entries(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js\":\n/*!*********************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js ***!\n  \\*********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-object-getownpropertydescriptors\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar ownKeys = __webpack_require__(/*! ./_own-keys */ \"./node_modules/core-js/modules/_own-keys.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar createProperty = __webpack_require__(/*! ./_create-property */ \"./node_modules/core-js/modules/_create-property.js\");\n\n$export($export.S, 'Object', {\n  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {\n    var O = toIObject(object);\n    var getDesc = gOPD.f;\n    var keys = ownKeys(O);\n    var result = {};\n    var i = 0;\n    var key, desc;\n    while (keys.length > i) {\n      desc = getDesc(O, key = keys[i++]);\n      if (desc !== undefined) createProperty(result, key, desc);\n    }\n    return result;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.lookup-getter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.lookup-getter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\n\n// B.2.2.4 Object.prototype.__lookupGetter__(P)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __lookupGetter__: function __lookupGetter__(P) {\n    var O = toObject(this);\n    var K = toPrimitive(P, true);\n    var D;\n    do {\n      if (D = getOwnPropertyDescriptor(O, K)) return D.get;\n    } while (O = getPrototypeOf(O));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.lookup-setter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.lookup-setter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\n\n// B.2.2.5 Object.prototype.__lookupSetter__(P)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __lookupSetter__: function __lookupSetter__(P) {\n    var O = toObject(this);\n    var K = toPrimitive(P, true);\n    var D;\n    do {\n      if (D = getOwnPropertyDescriptor(O, K)) return D.set;\n    } while (O = getPrototypeOf(O));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.values.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.values.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-object-values-entries\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $values = __webpack_require__(/*! ./_object-to-array */ \"./node_modules/core-js/modules/_object-to-array.js\")(false);\n\n$export($export.S, 'Object', {\n  values: function values(it) {\n    return $values(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.observable.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.observable.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/zenparsing/es-observable\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar OBSERVABLE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('observable');\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar RETURN = forOf.RETURN;\n\nvar getMethod = function (fn) {\n  return fn == null ? undefined : aFunction(fn);\n};\n\nvar cleanupSubscription = function (subscription) {\n  var cleanup = subscription._c;\n  if (cleanup) {\n    subscription._c = undefined;\n    cleanup();\n  }\n};\n\nvar subscriptionClosed = function (subscription) {\n  return subscription._o === undefined;\n};\n\nvar closeSubscription = function (subscription) {\n  if (!subscriptionClosed(subscription)) {\n    subscription._o = undefined;\n    cleanupSubscription(subscription);\n  }\n};\n\nvar Subscription = function (observer, subscriber) {\n  anObject(observer);\n  this._c = undefined;\n  this._o = observer;\n  observer = new SubscriptionObserver(this);\n  try {\n    var cleanup = subscriber(observer);\n    var subscription = cleanup;\n    if (cleanup != null) {\n      if (typeof cleanup.unsubscribe === 'function') cleanup = function () { subscription.unsubscribe(); };\n      else aFunction(cleanup);\n      this._c = cleanup;\n    }\n  } catch (e) {\n    observer.error(e);\n    return;\n  } if (subscriptionClosed(this)) cleanupSubscription(this);\n};\n\nSubscription.prototype = redefineAll({}, {\n  unsubscribe: function unsubscribe() { closeSubscription(this); }\n});\n\nvar SubscriptionObserver = function (subscription) {\n  this._s = subscription;\n};\n\nSubscriptionObserver.prototype = redefineAll({}, {\n  next: function next(value) {\n    var subscription = this._s;\n    if (!subscriptionClosed(subscription)) {\n      var observer = subscription._o;\n      try {\n        var m = getMethod(observer.next);\n        if (m) return m.call(observer, value);\n      } catch (e) {\n        try {\n          closeSubscription(subscription);\n        } finally {\n          throw e;\n        }\n      }\n    }\n  },\n  error: function error(value) {\n    var subscription = this._s;\n    if (subscriptionClosed(subscription)) throw value;\n    var observer = subscription._o;\n    subscription._o = undefined;\n    try {\n      var m = getMethod(observer.error);\n      if (!m) throw value;\n      value = m.call(observer, value);\n    } catch (e) {\n      try {\n        cleanupSubscription(subscription);\n      } finally {\n        throw e;\n      }\n    } cleanupSubscription(subscription);\n    return value;\n  },\n  complete: function complete(value) {\n    var subscription = this._s;\n    if (!subscriptionClosed(subscription)) {\n      var observer = subscription._o;\n      subscription._o = undefined;\n      try {\n        var m = getMethod(observer.complete);\n        value = m ? m.call(observer, value) : undefined;\n      } catch (e) {\n        try {\n          cleanupSubscription(subscription);\n        } finally {\n          throw e;\n        }\n      } cleanupSubscription(subscription);\n      return value;\n    }\n  }\n});\n\nvar $Observable = function Observable(subscriber) {\n  anInstance(this, $Observable, 'Observable', '_f')._f = aFunction(subscriber);\n};\n\nredefineAll($Observable.prototype, {\n  subscribe: function subscribe(observer) {\n    return new Subscription(observer, this._f);\n  },\n  forEach: function forEach(fn) {\n    var that = this;\n    return new (core.Promise || global.Promise)(function (resolve, reject) {\n      aFunction(fn);\n      var subscription = that.subscribe({\n        next: function (value) {\n          try {\n            return fn(value);\n          } catch (e) {\n            reject(e);\n            subscription.unsubscribe();\n          }\n        },\n        error: reject,\n        complete: resolve\n      });\n    });\n  }\n});\n\nredefineAll($Observable, {\n  from: function from(x) {\n    var C = typeof this === 'function' ? this : $Observable;\n    var method = getMethod(anObject(x)[OBSERVABLE]);\n    if (method) {\n      var observable = anObject(method.call(x));\n      return observable.constructor === C ? observable : new C(function (observer) {\n        return observable.subscribe(observer);\n      });\n    }\n    return new C(function (observer) {\n      var done = false;\n      microtask(function () {\n        if (!done) {\n          try {\n            if (forOf(x, false, function (it) {\n              observer.next(it);\n              if (done) return RETURN;\n            }) === RETURN) return;\n          } catch (e) {\n            if (done) throw e;\n            observer.error(e);\n            return;\n          } observer.complete();\n        }\n      });\n      return function () { done = true; };\n    });\n  },\n  of: function of() {\n    for (var i = 0, l = arguments.length, items = new Array(l); i < l;) items[i] = arguments[i++];\n    return new (typeof this === 'function' ? this : $Observable)(function (observer) {\n      var done = false;\n      microtask(function () {\n        if (!done) {\n          for (var j = 0; j < items.length; ++j) {\n            observer.next(items[j]);\n            if (done) return;\n          } observer.complete();\n        }\n      });\n      return function () { done = true; };\n    });\n  }\n});\n\nhide($Observable.prototype, OBSERVABLE, function () { return this; });\n\n$export($export.G, { Observable: $Observable });\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")('Observable');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.promise.finally.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.promise.finally.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// https://github.com/tc39/proposal-promise-finally\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar promiseResolve = __webpack_require__(/*! ./_promise-resolve */ \"./node_modules/core-js/modules/_promise-resolve.js\");\n\n$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) {\n  var C = speciesConstructor(this, core.Promise || global.Promise);\n  var isFunction = typeof onFinally == 'function';\n  return this.then(\n    isFunction ? function (x) {\n      return promiseResolve(C, onFinally()).then(function () { return x; });\n    } : onFinally,\n    isFunction ? function (e) {\n      return promiseResolve(C, onFinally()).then(function () { throw e; });\n    } : onFinally\n  );\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.promise.try.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.promise.try.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/proposal-promise-try\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar newPromiseCapability = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\nvar perform = __webpack_require__(/*! ./_perform */ \"./node_modules/core-js/modules/_perform.js\");\n\n$export($export.S, 'Promise', { 'try': function (callbackfn) {\n  var promiseCapability = newPromiseCapability.f(this);\n  var result = perform(callbackfn);\n  (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v);\n  return promiseCapability.promise;\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.define-metadata.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.define-metadata.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toMetaKey = metadata.key;\nvar ordinaryDefineOwnMetadata = metadata.set;\n\nmetadata.exp({ defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey) {\n  ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.delete-metadata.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.delete-metadata.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toMetaKey = metadata.key;\nvar getOrCreateMetadataMap = metadata.map;\nvar store = metadata.store;\n\nmetadata.exp({ deleteMetadata: function deleteMetadata(metadataKey, target /* , targetKey */) {\n  var targetKey = arguments.length < 3 ? undefined : toMetaKey(arguments[2]);\n  var metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false);\n  if (metadataMap === undefined || !metadataMap['delete'](metadataKey)) return false;\n  if (metadataMap.size) return true;\n  var targetMetadata = store.get(target);\n  targetMetadata['delete'](targetKey);\n  return !!targetMetadata.size || store['delete'](target);\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js\":\n/*!***********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js ***!\n  \\***********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Set = __webpack_require__(/*! ./es6.set */ \"./node_modules/core-js/modules/es6.set.js\");\nvar from = __webpack_require__(/*! ./_array-from-iterable */ \"./node_modules/core-js/modules/_array-from-iterable.js\");\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ordinaryOwnMetadataKeys = metadata.keys;\nvar toMetaKey = metadata.key;\n\nvar ordinaryMetadataKeys = function (O, P) {\n  var oKeys = ordinaryOwnMetadataKeys(O, P);\n  var parent = getPrototypeOf(O);\n  if (parent === null) return oKeys;\n  var pKeys = ordinaryMetadataKeys(parent, P);\n  return pKeys.length ? oKeys.length ? from(new Set(oKeys.concat(pKeys))) : pKeys : oKeys;\n};\n\nmetadata.exp({ getMetadataKeys: function getMetadataKeys(target /* , targetKey */) {\n  return ordinaryMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-metadata.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-metadata.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ordinaryHasOwnMetadata = metadata.has;\nvar ordinaryGetOwnMetadata = metadata.get;\nvar toMetaKey = metadata.key;\n\nvar ordinaryGetMetadata = function (MetadataKey, O, P) {\n  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);\n  if (hasOwn) return ordinaryGetOwnMetadata(MetadataKey, O, P);\n  var parent = getPrototypeOf(O);\n  return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined;\n};\n\nmetadata.exp({ getMetadata: function getMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryGetMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js\":\n/*!***************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js ***!\n  \\***************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar ordinaryOwnMetadataKeys = metadata.keys;\nvar toMetaKey = metadata.key;\n\nmetadata.exp({ getOwnMetadataKeys: function getOwnMetadataKeys(target /* , targetKey */) {\n  return ordinaryOwnMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-own-metadata.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar ordinaryGetOwnMetadata = metadata.get;\nvar toMetaKey = metadata.key;\n\nmetadata.exp({ getOwnMetadata: function getOwnMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryGetOwnMetadata(metadataKey, anObject(target)\n    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.has-metadata.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.has-metadata.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ordinaryHasOwnMetadata = metadata.has;\nvar toMetaKey = metadata.key;\n\nvar ordinaryHasMetadata = function (MetadataKey, O, P) {\n  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);\n  if (hasOwn) return true;\n  var parent = getPrototypeOf(O);\n  return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false;\n};\n\nmetadata.exp({ hasMetadata: function hasMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryHasMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.has-own-metadata.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.has-own-metadata.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar ordinaryHasOwnMetadata = metadata.has;\nvar toMetaKey = metadata.key;\n\nmetadata.exp({ hasOwnMetadata: function hasOwnMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryHasOwnMetadata(metadataKey, anObject(target)\n    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.metadata.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.metadata.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar toMetaKey = $metadata.key;\nvar ordinaryDefineOwnMetadata = $metadata.set;\n\n$metadata.exp({ metadata: function metadata(metadataKey, metadataValue) {\n  return function decorator(target, targetKey) {\n    ordinaryDefineOwnMetadata(\n      metadataKey, metadataValue,\n      (targetKey !== undefined ? anObject : aFunction)(target),\n      toMetaKey(targetKey)\n    );\n  };\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.set.from.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.set.from.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-set.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('Set');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.set.of.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.set.of.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-set.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('Set');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.set.to-json.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.set.to-json.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P + $export.R, 'Set', { toJSON: __webpack_require__(/*! ./_collection-to-json */ \"./node_modules/core-js/modules/_collection-to-json.js\")('Set') });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.at.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.at.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/mathiasbynens/String.prototype.at\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n$export($export.P, 'String', {\n  at: function at(pos) {\n    return $at(this, pos);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.match-all.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.match-all.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/String.prototype.matchAll/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar getFlags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\nvar RegExpProto = RegExp.prototype;\n\nvar $RegExpStringIterator = function (regexp, string) {\n  this._r = regexp;\n  this._s = string;\n};\n\n__webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\")($RegExpStringIterator, 'RegExp String', function next() {\n  var match = this._r.exec(this._s);\n  return { value: match, done: match === null };\n});\n\n$export($export.P, 'String', {\n  matchAll: function matchAll(regexp) {\n    defined(this);\n    if (!isRegExp(regexp)) throw TypeError(regexp + ' is not a regexp!');\n    var S = String(this);\n    var flags = 'flags' in RegExpProto ? String(regexp.flags) : getFlags.call(regexp);\n    var rx = new RegExp(regexp.source, ~flags.indexOf('g') ? flags : 'g' + flags);\n    rx.lastIndex = toLength(regexp.lastIndex);\n    return new $RegExpStringIterator(rx, S);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.pad-end.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.pad-end.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/proposal-string-pad-start-end\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $pad = __webpack_require__(/*! ./_string-pad */ \"./node_modules/core-js/modules/_string-pad.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\n\n// https://github.com/zloirock/core-js/issues/280\n$export($export.P + $export.F * /Version\\/10\\.\\d+(\\.\\d+)? Safari\\//.test(userAgent), 'String', {\n  padEnd: function padEnd(maxLength /* , fillString = ' ' */) {\n    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.pad-start.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.pad-start.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/proposal-string-pad-start-end\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $pad = __webpack_require__(/*! ./_string-pad */ \"./node_modules/core-js/modules/_string-pad.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\n\n// https://github.com/zloirock/core-js/issues/280\n$export($export.P + $export.F * /Version\\/10\\.\\d+(\\.\\d+)? Safari\\//.test(userAgent), 'String', {\n  padStart: function padStart(maxLength /* , fillString = ' ' */) {\n    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.trim-left.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.trim-left.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/sebmarkbage/ecmascript-string-left-right-trim\n__webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\")('trimLeft', function ($trim) {\n  return function trimLeft() {\n    return $trim(this, 1);\n  };\n}, 'trimStart');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.trim-right.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.trim-right.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/sebmarkbage/ecmascript-string-left-right-trim\n__webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\")('trimRight', function ($trim) {\n  return function trimRight() {\n    return $trim(this, 2);\n  };\n}, 'trimEnd');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.symbol.async-iterator.js\":\n/*!*******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.symbol.async-iterator.js ***!\n  \\*******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_wks-define */ \"./node_modules/core-js/modules/_wks-define.js\")('asyncIterator');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.symbol.observable.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.symbol.observable.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_wks-define */ \"./node_modules/core-js/modules/_wks-define.js\")('observable');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.system.global.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.system.global.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-global\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'System', { global: __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-map.from.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-map.from.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('WeakMap');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-map.of.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-map.of.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('WeakMap');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-set.from.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-set.from.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('WeakSet');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-set.of.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-set.of.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('WeakSet');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.dom.iterable.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.dom.iterable.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $iterators = __webpack_require__(/*! ./es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar ITERATOR = wks('iterator');\nvar TO_STRING_TAG = wks('toStringTag');\nvar ArrayValues = Iterators.Array;\n\nvar DOMIterables = {\n  CSSRuleList: true, // TODO: Not spec compliant, should be false.\n  CSSStyleDeclaration: false,\n  CSSValueList: false,\n  ClientRectList: false,\n  DOMRectList: false,\n  DOMStringList: false,\n  DOMTokenList: true,\n  DataTransferItemList: false,\n  FileList: false,\n  HTMLAllCollection: false,\n  HTMLCollection: false,\n  HTMLFormElement: false,\n  HTMLSelectElement: false,\n  MediaList: true, // TODO: Not spec compliant, should be false.\n  MimeTypeArray: false,\n  NamedNodeMap: false,\n  NodeList: true,\n  PaintRequestList: false,\n  Plugin: false,\n  PluginArray: false,\n  SVGLengthList: false,\n  SVGNumberList: false,\n  SVGPathSegList: false,\n  SVGPointList: false,\n  SVGStringList: false,\n  SVGTransformList: false,\n  SourceBufferList: false,\n  StyleSheetList: true, // TODO: Not spec compliant, should be false.\n  TextTrackCueList: false,\n  TextTrackList: false,\n  TouchList: false\n};\n\nfor (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {\n  var NAME = collections[i];\n  var explicit = DOMIterables[NAME];\n  var Collection = global[NAME];\n  var proto = Collection && Collection.prototype;\n  var key;\n  if (proto) {\n    if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);\n    if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n    Iterators[NAME] = ArrayValues;\n    if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);\n  }\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.immediate.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.immediate.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $task = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\");\n$export($export.G + $export.B, {\n  setImmediate: $task.set,\n  clearImmediate: $task.clear\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.timers.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.timers.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// ie9- setTimeout & setInterval additional parameters fix\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\nvar slice = [].slice;\nvar MSIE = /MSIE .\\./.test(userAgent); // <- dirty ie9- check\nvar wrap = function (set) {\n  return function (fn, time /* , ...args */) {\n    var boundArgs = arguments.length > 2;\n    var args = boundArgs ? slice.call(arguments, 2) : false;\n    return set(boundArgs ? function () {\n      // eslint-disable-next-line no-new-func\n      (typeof fn == 'function' ? fn : Function(fn)).apply(this, args);\n    } : fn, time);\n  };\n};\n$export($export.G + $export.B + $export.F * MSIE, {\n  setTimeout: wrap(global.setTimeout),\n  setInterval: wrap(global.setInterval)\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/shim.js\":\n/*!**************************************!*\\\n  !*** ./node_modules/core-js/shim.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./modules/es6.symbol */ \"./node_modules/core-js/modules/es6.symbol.js\");\n__webpack_require__(/*! ./modules/es6.object.create */ \"./node_modules/core-js/modules/es6.object.create.js\");\n__webpack_require__(/*! ./modules/es6.object.define-property */ \"./node_modules/core-js/modules/es6.object.define-property.js\");\n__webpack_require__(/*! ./modules/es6.object.define-properties */ \"./node_modules/core-js/modules/es6.object.define-properties.js\");\n__webpack_require__(/*! ./modules/es6.object.get-own-property-descriptor */ \"./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js\");\n__webpack_require__(/*! ./modules/es6.object.get-prototype-of */ \"./node_modules/core-js/modules/es6.object.get-prototype-of.js\");\n__webpack_require__(/*! ./modules/es6.object.keys */ \"./node_modules/core-js/modules/es6.object.keys.js\");\n__webpack_require__(/*! ./modules/es6.object.get-own-property-names */ \"./node_modules/core-js/modules/es6.object.get-own-property-names.js\");\n__webpack_require__(/*! ./modules/es6.object.freeze */ \"./node_modules/core-js/modules/es6.object.freeze.js\");\n__webpack_require__(/*! ./modules/es6.object.seal */ \"./node_modules/core-js/modules/es6.object.seal.js\");\n__webpack_require__(/*! ./modules/es6.object.prevent-extensions */ \"./node_modules/core-js/modules/es6.object.prevent-extensions.js\");\n__webpack_require__(/*! ./modules/es6.object.is-frozen */ \"./node_modules/core-js/modules/es6.object.is-frozen.js\");\n__webpack_require__(/*! ./modules/es6.object.is-sealed */ \"./node_modules/core-js/modules/es6.object.is-sealed.js\");\n__webpack_require__(/*! ./modules/es6.object.is-extensible */ \"./node_modules/core-js/modules/es6.object.is-extensible.js\");\n__webpack_require__(/*! ./modules/es6.object.assign */ \"./node_modules/core-js/modules/es6.object.assign.js\");\n__webpack_require__(/*! ./modules/es6.object.is */ \"./node_modules/core-js/modules/es6.object.is.js\");\n__webpack_require__(/*! ./modules/es6.object.set-prototype-of */ \"./node_modules/core-js/modules/es6.object.set-prototype-of.js\");\n__webpack_require__(/*! ./modules/es6.object.to-string */ \"./node_modules/core-js/modules/es6.object.to-string.js\");\n__webpack_require__(/*! ./modules/es6.function.bind */ \"./node_modules/core-js/modules/es6.function.bind.js\");\n__webpack_require__(/*! ./modules/es6.function.name */ \"./node_modules/core-js/modules/es6.function.name.js\");\n__webpack_require__(/*! ./modules/es6.function.has-instance */ \"./node_modules/core-js/modules/es6.function.has-instance.js\");\n__webpack_require__(/*! ./modules/es6.parse-int */ \"./node_modules/core-js/modules/es6.parse-int.js\");\n__webpack_require__(/*! ./modules/es6.parse-float */ \"./node_modules/core-js/modules/es6.parse-float.js\");\n__webpack_require__(/*! ./modules/es6.number.constructor */ \"./node_modules/core-js/modules/es6.number.constructor.js\");\n__webpack_require__(/*! ./modules/es6.number.to-fixed */ \"./node_modules/core-js/modules/es6.number.to-fixed.js\");\n__webpack_require__(/*! ./modules/es6.number.to-precision */ \"./node_modules/core-js/modules/es6.number.to-precision.js\");\n__webpack_require__(/*! ./modules/es6.number.epsilon */ \"./node_modules/core-js/modules/es6.number.epsilon.js\");\n__webpack_require__(/*! ./modules/es6.number.is-finite */ \"./node_modules/core-js/modules/es6.number.is-finite.js\");\n__webpack_require__(/*! ./modules/es6.number.is-integer */ \"./node_modules/core-js/modules/es6.number.is-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.is-nan */ \"./node_modules/core-js/modules/es6.number.is-nan.js\");\n__webpack_require__(/*! ./modules/es6.number.is-safe-integer */ \"./node_modules/core-js/modules/es6.number.is-safe-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.max-safe-integer */ \"./node_modules/core-js/modules/es6.number.max-safe-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.min-safe-integer */ \"./node_modules/core-js/modules/es6.number.min-safe-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.parse-float */ \"./node_modules/core-js/modules/es6.number.parse-float.js\");\n__webpack_require__(/*! ./modules/es6.number.parse-int */ \"./node_modules/core-js/modules/es6.number.parse-int.js\");\n__webpack_require__(/*! ./modules/es6.math.acosh */ \"./node_modules/core-js/modules/es6.math.acosh.js\");\n__webpack_require__(/*! ./modules/es6.math.asinh */ \"./node_modules/core-js/modules/es6.math.asinh.js\");\n__webpack_require__(/*! ./modules/es6.math.atanh */ \"./node_modules/core-js/modules/es6.math.atanh.js\");\n__webpack_require__(/*! ./modules/es6.math.cbrt */ \"./node_modules/core-js/modules/es6.math.cbrt.js\");\n__webpack_require__(/*! ./modules/es6.math.clz32 */ \"./node_modules/core-js/modules/es6.math.clz32.js\");\n__webpack_require__(/*! ./modules/es6.math.cosh */ \"./node_modules/core-js/modules/es6.math.cosh.js\");\n__webpack_require__(/*! ./modules/es6.math.expm1 */ \"./node_modules/core-js/modules/es6.math.expm1.js\");\n__webpack_require__(/*! ./modules/es6.math.fround */ \"./node_modules/core-js/modules/es6.math.fround.js\");\n__webpack_require__(/*! ./modules/es6.math.hypot */ \"./node_modules/core-js/modules/es6.math.hypot.js\");\n__webpack_require__(/*! ./modules/es6.math.imul */ \"./node_modules/core-js/modules/es6.math.imul.js\");\n__webpack_require__(/*! ./modules/es6.math.log10 */ \"./node_modules/core-js/modules/es6.math.log10.js\");\n__webpack_require__(/*! ./modules/es6.math.log1p */ \"./node_modules/core-js/modules/es6.math.log1p.js\");\n__webpack_require__(/*! ./modules/es6.math.log2 */ \"./node_modules/core-js/modules/es6.math.log2.js\");\n__webpack_require__(/*! ./modules/es6.math.sign */ \"./node_modules/core-js/modules/es6.math.sign.js\");\n__webpack_require__(/*! ./modules/es6.math.sinh */ \"./node_modules/core-js/modules/es6.math.sinh.js\");\n__webpack_require__(/*! ./modules/es6.math.tanh */ \"./node_modules/core-js/modules/es6.math.tanh.js\");\n__webpack_require__(/*! ./modules/es6.math.trunc */ \"./node_modules/core-js/modules/es6.math.trunc.js\");\n__webpack_require__(/*! ./modules/es6.string.from-code-point */ \"./node_modules/core-js/modules/es6.string.from-code-point.js\");\n__webpack_require__(/*! ./modules/es6.string.raw */ \"./node_modules/core-js/modules/es6.string.raw.js\");\n__webpack_require__(/*! ./modules/es6.string.trim */ \"./node_modules/core-js/modules/es6.string.trim.js\");\n__webpack_require__(/*! ./modules/es6.string.iterator */ \"./node_modules/core-js/modules/es6.string.iterator.js\");\n__webpack_require__(/*! ./modules/es6.string.code-point-at */ \"./node_modules/core-js/modules/es6.string.code-point-at.js\");\n__webpack_require__(/*! ./modules/es6.string.ends-with */ \"./node_modules/core-js/modules/es6.string.ends-with.js\");\n__webpack_require__(/*! ./modules/es6.string.includes */ \"./node_modules/core-js/modules/es6.string.includes.js\");\n__webpack_require__(/*! ./modules/es6.string.repeat */ \"./node_modules/core-js/modules/es6.string.repeat.js\");\n__webpack_require__(/*! ./modules/es6.string.starts-with */ \"./node_modules/core-js/modules/es6.string.starts-with.js\");\n__webpack_require__(/*! ./modules/es6.string.anchor */ \"./node_modules/core-js/modules/es6.string.anchor.js\");\n__webpack_require__(/*! ./modules/es6.string.big */ \"./node_modules/core-js/modules/es6.string.big.js\");\n__webpack_require__(/*! ./modules/es6.string.blink */ \"./node_modules/core-js/modules/es6.string.blink.js\");\n__webpack_require__(/*! ./modules/es6.string.bold */ \"./node_modules/core-js/modules/es6.string.bold.js\");\n__webpack_require__(/*! ./modules/es6.string.fixed */ \"./node_modules/core-js/modules/es6.string.fixed.js\");\n__webpack_require__(/*! ./modules/es6.string.fontcolor */ \"./node_modules/core-js/modules/es6.string.fontcolor.js\");\n__webpack_require__(/*! ./modules/es6.string.fontsize */ \"./node_modules/core-js/modules/es6.string.fontsize.js\");\n__webpack_require__(/*! ./modules/es6.string.italics */ \"./node_modules/core-js/modules/es6.string.italics.js\");\n__webpack_require__(/*! ./modules/es6.string.link */ \"./node_modules/core-js/modules/es6.string.link.js\");\n__webpack_require__(/*! ./modules/es6.string.small */ \"./node_modules/core-js/modules/es6.string.small.js\");\n__webpack_require__(/*! ./modules/es6.string.strike */ \"./node_modules/core-js/modules/es6.string.strike.js\");\n__webpack_require__(/*! ./modules/es6.string.sub */ \"./node_modules/core-js/modules/es6.string.sub.js\");\n__webpack_require__(/*! ./modules/es6.string.sup */ \"./node_modules/core-js/modules/es6.string.sup.js\");\n__webpack_require__(/*! ./modules/es6.date.now */ \"./node_modules/core-js/modules/es6.date.now.js\");\n__webpack_require__(/*! ./modules/es6.date.to-json */ \"./node_modules/core-js/modules/es6.date.to-json.js\");\n__webpack_require__(/*! ./modules/es6.date.to-iso-string */ \"./node_modules/core-js/modules/es6.date.to-iso-string.js\");\n__webpack_require__(/*! ./modules/es6.date.to-string */ \"./node_modules/core-js/modules/es6.date.to-string.js\");\n__webpack_require__(/*! ./modules/es6.date.to-primitive */ \"./node_modules/core-js/modules/es6.date.to-primitive.js\");\n__webpack_require__(/*! ./modules/es6.array.is-array */ \"./node_modules/core-js/modules/es6.array.is-array.js\");\n__webpack_require__(/*! ./modules/es6.array.from */ \"./node_modules/core-js/modules/es6.array.from.js\");\n__webpack_require__(/*! ./modules/es6.array.of */ \"./node_modules/core-js/modules/es6.array.of.js\");\n__webpack_require__(/*! ./modules/es6.array.join */ \"./node_modules/core-js/modules/es6.array.join.js\");\n__webpack_require__(/*! ./modules/es6.array.slice */ \"./node_modules/core-js/modules/es6.array.slice.js\");\n__webpack_require__(/*! ./modules/es6.array.sort */ \"./node_modules/core-js/modules/es6.array.sort.js\");\n__webpack_require__(/*! ./modules/es6.array.for-each */ \"./node_modules/core-js/modules/es6.array.for-each.js\");\n__webpack_require__(/*! ./modules/es6.array.map */ \"./node_modules/core-js/modules/es6.array.map.js\");\n__webpack_require__(/*! ./modules/es6.array.filter */ \"./node_modules/core-js/modules/es6.array.filter.js\");\n__webpack_require__(/*! ./modules/es6.array.some */ \"./node_modules/core-js/modules/es6.array.some.js\");\n__webpack_require__(/*! ./modules/es6.array.every */ \"./node_modules/core-js/modules/es6.array.every.js\");\n__webpack_require__(/*! ./modules/es6.array.reduce */ \"./node_modules/core-js/modules/es6.array.reduce.js\");\n__webpack_require__(/*! ./modules/es6.array.reduce-right */ \"./node_modules/core-js/modules/es6.array.reduce-right.js\");\n__webpack_require__(/*! ./modules/es6.array.index-of */ \"./node_modules/core-js/modules/es6.array.index-of.js\");\n__webpack_require__(/*! ./modules/es6.array.last-index-of */ \"./node_modules/core-js/modules/es6.array.last-index-of.js\");\n__webpack_require__(/*! ./modules/es6.array.copy-within */ \"./node_modules/core-js/modules/es6.array.copy-within.js\");\n__webpack_require__(/*! ./modules/es6.array.fill */ \"./node_modules/core-js/modules/es6.array.fill.js\");\n__webpack_require__(/*! ./modules/es6.array.find */ \"./node_modules/core-js/modules/es6.array.find.js\");\n__webpack_require__(/*! ./modules/es6.array.find-index */ \"./node_modules/core-js/modules/es6.array.find-index.js\");\n__webpack_require__(/*! ./modules/es6.array.species */ \"./node_modules/core-js/modules/es6.array.species.js\");\n__webpack_require__(/*! ./modules/es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\n__webpack_require__(/*! ./modules/es6.regexp.constructor */ \"./node_modules/core-js/modules/es6.regexp.constructor.js\");\n__webpack_require__(/*! ./modules/es6.regexp.exec */ \"./node_modules/core-js/modules/es6.regexp.exec.js\");\n__webpack_require__(/*! ./modules/es6.regexp.to-string */ \"./node_modules/core-js/modules/es6.regexp.to-string.js\");\n__webpack_require__(/*! ./modules/es6.regexp.flags */ \"./node_modules/core-js/modules/es6.regexp.flags.js\");\n__webpack_require__(/*! ./modules/es6.regexp.match */ \"./node_modules/core-js/modules/es6.regexp.match.js\");\n__webpack_require__(/*! ./modules/es6.regexp.replace */ \"./node_modules/core-js/modules/es6.regexp.replace.js\");\n__webpack_require__(/*! ./modules/es6.regexp.search */ \"./node_modules/core-js/modules/es6.regexp.search.js\");\n__webpack_require__(/*! ./modules/es6.regexp.split */ \"./node_modules/core-js/modules/es6.regexp.split.js\");\n__webpack_require__(/*! ./modules/es6.promise */ \"./node_modules/core-js/modules/es6.promise.js\");\n__webpack_require__(/*! ./modules/es6.map */ \"./node_modules/core-js/modules/es6.map.js\");\n__webpack_require__(/*! ./modules/es6.set */ \"./node_modules/core-js/modules/es6.set.js\");\n__webpack_require__(/*! ./modules/es6.weak-map */ \"./node_modules/core-js/modules/es6.weak-map.js\");\n__webpack_require__(/*! ./modules/es6.weak-set */ \"./node_modules/core-js/modules/es6.weak-set.js\");\n__webpack_require__(/*! ./modules/es6.typed.array-buffer */ \"./node_modules/core-js/modules/es6.typed.array-buffer.js\");\n__webpack_require__(/*! ./modules/es6.typed.data-view */ \"./node_modules/core-js/modules/es6.typed.data-view.js\");\n__webpack_require__(/*! ./modules/es6.typed.int8-array */ \"./node_modules/core-js/modules/es6.typed.int8-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint8-array */ \"./node_modules/core-js/modules/es6.typed.uint8-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint8-clamped-array */ \"./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.int16-array */ \"./node_modules/core-js/modules/es6.typed.int16-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint16-array */ \"./node_modules/core-js/modules/es6.typed.uint16-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.int32-array */ \"./node_modules/core-js/modules/es6.typed.int32-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint32-array */ \"./node_modules/core-js/modules/es6.typed.uint32-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.float32-array */ \"./node_modules/core-js/modules/es6.typed.float32-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.float64-array */ \"./node_modules/core-js/modules/es6.typed.float64-array.js\");\n__webpack_require__(/*! ./modules/es6.reflect.apply */ \"./node_modules/core-js/modules/es6.reflect.apply.js\");\n__webpack_require__(/*! ./modules/es6.reflect.construct */ \"./node_modules/core-js/modules/es6.reflect.construct.js\");\n__webpack_require__(/*! ./modules/es6.reflect.define-property */ \"./node_modules/core-js/modules/es6.reflect.define-property.js\");\n__webpack_require__(/*! ./modules/es6.reflect.delete-property */ \"./node_modules/core-js/modules/es6.reflect.delete-property.js\");\n__webpack_require__(/*! ./modules/es6.reflect.enumerate */ \"./node_modules/core-js/modules/es6.reflect.enumerate.js\");\n__webpack_require__(/*! ./modules/es6.reflect.get */ \"./node_modules/core-js/modules/es6.reflect.get.js\");\n__webpack_require__(/*! ./modules/es6.reflect.get-own-property-descriptor */ \"./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js\");\n__webpack_require__(/*! ./modules/es6.reflect.get-prototype-of */ \"./node_modules/core-js/modules/es6.reflect.get-prototype-of.js\");\n__webpack_require__(/*! ./modules/es6.reflect.has */ \"./node_modules/core-js/modules/es6.reflect.has.js\");\n__webpack_require__(/*! ./modules/es6.reflect.is-extensible */ \"./node_modules/core-js/modules/es6.reflect.is-extensible.js\");\n__webpack_require__(/*! ./modules/es6.reflect.own-keys */ \"./node_modules/core-js/modules/es6.reflect.own-keys.js\");\n__webpack_require__(/*! ./modules/es6.reflect.prevent-extensions */ \"./node_modules/core-js/modules/es6.reflect.prevent-extensions.js\");\n__webpack_require__(/*! ./modules/es6.reflect.set */ \"./node_modules/core-js/modules/es6.reflect.set.js\");\n__webpack_require__(/*! ./modules/es6.reflect.set-prototype-of */ \"./node_modules/core-js/modules/es6.reflect.set-prototype-of.js\");\n__webpack_require__(/*! ./modules/es7.array.includes */ \"./node_modules/core-js/modules/es7.array.includes.js\");\n__webpack_require__(/*! ./modules/es7.array.flat-map */ \"./node_modules/core-js/modules/es7.array.flat-map.js\");\n__webpack_require__(/*! ./modules/es7.array.flatten */ \"./node_modules/core-js/modules/es7.array.flatten.js\");\n__webpack_require__(/*! ./modules/es7.string.at */ \"./node_modules/core-js/modules/es7.string.at.js\");\n__webpack_require__(/*! ./modules/es7.string.pad-start */ \"./node_modules/core-js/modules/es7.string.pad-start.js\");\n__webpack_require__(/*! ./modules/es7.string.pad-end */ \"./node_modules/core-js/modules/es7.string.pad-end.js\");\n__webpack_require__(/*! ./modules/es7.string.trim-left */ \"./node_modules/core-js/modules/es7.string.trim-left.js\");\n__webpack_require__(/*! ./modules/es7.string.trim-right */ \"./node_modules/core-js/modules/es7.string.trim-right.js\");\n__webpack_require__(/*! ./modules/es7.string.match-all */ \"./node_modules/core-js/modules/es7.string.match-all.js\");\n__webpack_require__(/*! ./modules/es7.symbol.async-iterator */ \"./node_modules/core-js/modules/es7.symbol.async-iterator.js\");\n__webpack_require__(/*! ./modules/es7.symbol.observable */ \"./node_modules/core-js/modules/es7.symbol.observable.js\");\n__webpack_require__(/*! ./modules/es7.object.get-own-property-descriptors */ \"./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js\");\n__webpack_require__(/*! ./modules/es7.object.values */ \"./node_modules/core-js/modules/es7.object.values.js\");\n__webpack_require__(/*! ./modules/es7.object.entries */ \"./node_modules/core-js/modules/es7.object.entries.js\");\n__webpack_require__(/*! ./modules/es7.object.define-getter */ \"./node_modules/core-js/modules/es7.object.define-getter.js\");\n__webpack_require__(/*! ./modules/es7.object.define-setter */ \"./node_modules/core-js/modules/es7.object.define-setter.js\");\n__webpack_require__(/*! ./modules/es7.object.lookup-getter */ \"./node_modules/core-js/modules/es7.object.lookup-getter.js\");\n__webpack_require__(/*! ./modules/es7.object.lookup-setter */ \"./node_modules/core-js/modules/es7.object.lookup-setter.js\");\n__webpack_require__(/*! ./modules/es7.map.to-json */ \"./node_modules/core-js/modules/es7.map.to-json.js\");\n__webpack_require__(/*! ./modules/es7.set.to-json */ \"./node_modules/core-js/modules/es7.set.to-json.js\");\n__webpack_require__(/*! ./modules/es7.map.of */ \"./node_modules/core-js/modules/es7.map.of.js\");\n__webpack_require__(/*! ./modules/es7.set.of */ \"./node_modules/core-js/modules/es7.set.of.js\");\n__webpack_require__(/*! ./modules/es7.weak-map.of */ \"./node_modules/core-js/modules/es7.weak-map.of.js\");\n__webpack_require__(/*! ./modules/es7.weak-set.of */ \"./node_modules/core-js/modules/es7.weak-set.of.js\");\n__webpack_require__(/*! ./modules/es7.map.from */ \"./node_modules/core-js/modules/es7.map.from.js\");\n__webpack_require__(/*! ./modules/es7.set.from */ \"./node_modules/core-js/modules/es7.set.from.js\");\n__webpack_require__(/*! ./modules/es7.weak-map.from */ \"./node_modules/core-js/modules/es7.weak-map.from.js\");\n__webpack_require__(/*! ./modules/es7.weak-set.from */ \"./node_modules/core-js/modules/es7.weak-set.from.js\");\n__webpack_require__(/*! ./modules/es7.global */ \"./node_modules/core-js/modules/es7.global.js\");\n__webpack_require__(/*! ./modules/es7.system.global */ \"./node_modules/core-js/modules/es7.system.global.js\");\n__webpack_require__(/*! ./modules/es7.error.is-error */ \"./node_modules/core-js/modules/es7.error.is-error.js\");\n__webpack_require__(/*! ./modules/es7.math.clamp */ \"./node_modules/core-js/modules/es7.math.clamp.js\");\n__webpack_require__(/*! ./modules/es7.math.deg-per-rad */ \"./node_modules/core-js/modules/es7.math.deg-per-rad.js\");\n__webpack_require__(/*! ./modules/es7.math.degrees */ \"./node_modules/core-js/modules/es7.math.degrees.js\");\n__webpack_require__(/*! ./modules/es7.math.fscale */ \"./node_modules/core-js/modules/es7.math.fscale.js\");\n__webpack_require__(/*! ./modules/es7.math.iaddh */ \"./node_modules/core-js/modules/es7.math.iaddh.js\");\n__webpack_require__(/*! ./modules/es7.math.isubh */ \"./node_modules/core-js/modules/es7.math.isubh.js\");\n__webpack_require__(/*! ./modules/es7.math.imulh */ \"./node_modules/core-js/modules/es7.math.imulh.js\");\n__webpack_require__(/*! ./modules/es7.math.rad-per-deg */ \"./node_modules/core-js/modules/es7.math.rad-per-deg.js\");\n__webpack_require__(/*! ./modules/es7.math.radians */ \"./node_modules/core-js/modules/es7.math.radians.js\");\n__webpack_require__(/*! ./modules/es7.math.scale */ \"./node_modules/core-js/modules/es7.math.scale.js\");\n__webpack_require__(/*! ./modules/es7.math.umulh */ \"./node_modules/core-js/modules/es7.math.umulh.js\");\n__webpack_require__(/*! ./modules/es7.math.signbit */ \"./node_modules/core-js/modules/es7.math.signbit.js\");\n__webpack_require__(/*! ./modules/es7.promise.finally */ \"./node_modules/core-js/modules/es7.promise.finally.js\");\n__webpack_require__(/*! ./modules/es7.promise.try */ \"./node_modules/core-js/modules/es7.promise.try.js\");\n__webpack_require__(/*! ./modules/es7.reflect.define-metadata */ \"./node_modules/core-js/modules/es7.reflect.define-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.delete-metadata */ \"./node_modules/core-js/modules/es7.reflect.delete-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-metadata */ \"./node_modules/core-js/modules/es7.reflect.get-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-metadata-keys */ \"./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-own-metadata */ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-own-metadata-keys */ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js\");\n__webpack_require__(/*! ./modules/es7.reflect.has-metadata */ \"./node_modules/core-js/modules/es7.reflect.has-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.has-own-metadata */ \"./node_modules/core-js/modules/es7.reflect.has-own-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.metadata */ \"./node_modules/core-js/modules/es7.reflect.metadata.js\");\n__webpack_require__(/*! ./modules/es7.asap */ \"./node_modules/core-js/modules/es7.asap.js\");\n__webpack_require__(/*! ./modules/es7.observable */ \"./node_modules/core-js/modules/es7.observable.js\");\n__webpack_require__(/*! ./modules/web.timers */ \"./node_modules/core-js/modules/web.timers.js\");\n__webpack_require__(/*! ./modules/web.immediate */ \"./node_modules/core-js/modules/web.immediate.js\");\n__webpack_require__(/*! ./modules/web.dom.iterable */ \"./node_modules/core-js/modules/web.dom.iterable.js\");\nmodule.exports = __webpack_require__(/*! ./modules/_core */ \"./node_modules/core-js/modules/_core.js\");\n\n\n/***/ }),\n\n/***/ \"./node_modules/ieee754/index.js\":\n/*!***************************************!*\\\n  !*** ./node_modules/ieee754/index.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = ((value * c) - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/bytesToUuid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/bytesToUuid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n  byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n  var i = offset || 0;\n  var bth = byteToHex;\n  // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n  return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/rng-browser.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/rng-browser.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// Unique ID creation requires a high quality random # generator.  In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API.  We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n                      (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n  // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n  var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n  module.exports = function whatwgRNG() {\n    getRandomValues(rnds8);\n    return rnds8;\n  };\n} else {\n  // Math.random()-based (RNG)\n  //\n  // If all else fails, use Math.random().  It's fast, but is of unspecified\n  // quality.\n  var rnds = new Array(16);\n\n  module.exports = function mathRNG() {\n    for (var i = 0, r; i < 16; i++) {\n      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n      rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n    }\n\n    return rnds;\n  };\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/v4.js\":\n/*!*********************************!*\\\n  !*** ./node_modules/uuid/v4.js ***!\n  \\*********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar rng = __webpack_require__(/*! ./lib/rng */ \"./node_modules/uuid/lib/rng-browser.js\");\nvar bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ \"./node_modules/uuid/lib/bytesToUuid.js\");\n\nfunction v4(options, buf, offset) {\n  var i = buf && offset || 0;\n\n  if (typeof(options) == 'string') {\n    buf = options === 'binary' ? new Array(16) : null;\n    options = null;\n  }\n  options = options || {};\n\n  var rnds = options.random || (options.rng || rng)();\n\n  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n  rnds[6] = (rnds[6] & 0x0f) | 0x40;\n  rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n  // Copy bytes to buffer, if provided\n  if (buf) {\n    for (var ii = 0; ii < 16; ++ii) {\n      buf[i + ii] = rnds[ii];\n    }\n  }\n\n  return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n\n\n/***/ }),\n\n/***/ \"./node_modules/webpack/buildin/global.js\":\n/*!***********************************!*\\\n  !*** (webpack)/buildin/global.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n/***/ }),\n\n/***/ \"./src/AccessTokenEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/AccessTokenEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AccessTokenEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Timer = __webpack_require__(/*! ./Timer.js */ \"./src/Timer.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60; // seconds\n\nvar AccessTokenEvents = exports.AccessTokenEvents = function () {\n    function AccessTokenEvents() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$accessTokenExpir2 = _ref.accessTokenExpiringTimer,\n            accessTokenExpiringTimer = _ref$accessTokenExpir2 === undefined ? new _Timer.Timer(\"Access token expiring\") : _ref$accessTokenExpir2,\n            _ref$accessTokenExpir3 = _ref.accessTokenExpiredTimer,\n            accessTokenExpiredTimer = _ref$accessTokenExpir3 === undefined ? new _Timer.Timer(\"Access token expired\") : _ref$accessTokenExpir3;\n\n        _classCallCheck(this, AccessTokenEvents);\n\n        this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        this._accessTokenExpiring = accessTokenExpiringTimer;\n        this._accessTokenExpired = accessTokenExpiredTimer;\n    }\n\n    AccessTokenEvents.prototype.load = function load(container) {\n        // only register events if there's an access token and it has an expiration\n        if (container.access_token && container.expires_in !== undefined) {\n            var duration = container.expires_in;\n            _Log.Log.debug(\"AccessTokenEvents.load: access token present, remaining duration:\", duration);\n\n            if (duration > 0) {\n                // only register expiring if we still have time\n                var expiring = duration - this._accessTokenExpiringNotificationTime;\n                if (expiring <= 0) {\n                    expiring = 1;\n                }\n\n                _Log.Log.debug(\"AccessTokenEvents.load: registering expiring timer in:\", expiring);\n                this._accessTokenExpiring.init(expiring);\n            } else {\n                _Log.Log.debug(\"AccessTokenEvents.load: canceling existing expiring timer becase we're past expiration.\");\n                this._accessTokenExpiring.cancel();\n            }\n\n            // if it's negative, it will still fire\n            var expired = duration + 1;\n            _Log.Log.debug(\"AccessTokenEvents.load: registering expired timer in:\", expired);\n            this._accessTokenExpired.init(expired);\n        } else {\n            this._accessTokenExpiring.cancel();\n            this._accessTokenExpired.cancel();\n        }\n    };\n\n    AccessTokenEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"AccessTokenEvents.unload: canceling existing access token timers\");\n        this._accessTokenExpiring.cancel();\n        this._accessTokenExpired.cancel();\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpiring = function addAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpiring = function removeAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.removeHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpired = function addAccessTokenExpired(cb) {\n        this._accessTokenExpired.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpired = function removeAccessTokenExpired(cb) {\n        this._accessTokenExpired.removeHandler(cb);\n    };\n\n    return AccessTokenEvents;\n}();\n\n/***/ }),\n\n/***/ \"./src/CheckSessionIFrame.js\":\n/*!***********************************!*\\\n  !*** ./src/CheckSessionIFrame.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CheckSessionIFrame = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultInterval = 2000;\n\nvar CheckSessionIFrame = exports.CheckSessionIFrame = function () {\n    function CheckSessionIFrame(callback, client_id, url, interval) {\n        var stopOnError = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n\n        _classCallCheck(this, CheckSessionIFrame);\n\n        this._callback = callback;\n        this._client_id = client_id;\n        this._url = url;\n        this._interval = interval || DefaultInterval;\n        this._stopOnError = stopOnError;\n\n        var idx = url.indexOf(\"/\", url.indexOf(\"//\") + 2);\n        this._frame_origin = url.substr(0, idx);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        this._frame.src = url;\n    }\n\n    CheckSessionIFrame.prototype.load = function load() {\n        var _this = this;\n\n        return new Promise(function (resolve) {\n            _this._frame.onload = function () {\n                resolve();\n            };\n\n            window.document.body.appendChild(_this._frame);\n            _this._boundMessageEvent = _this._message.bind(_this);\n            window.addEventListener(\"message\", _this._boundMessageEvent, false);\n        });\n    };\n\n    CheckSessionIFrame.prototype._message = function _message(e) {\n        if (e.origin === this._frame_origin && e.source === this._frame.contentWindow) {\n            if (e.data === \"error\") {\n                _Log.Log.error(\"CheckSessionIFrame: error message from check session op iframe\");\n                if (this._stopOnError) {\n                    this.stop();\n                }\n            } else if (e.data === \"changed\") {\n                _Log.Log.debug(\"CheckSessionIFrame: changed message from check session op iframe\");\n                this.stop();\n                this._callback();\n            } else {\n                _Log.Log.debug(\"CheckSessionIFrame: \" + e.data + \" message from check session op iframe\");\n            }\n        }\n    };\n\n    CheckSessionIFrame.prototype.start = function start(session_state) {\n        var _this2 = this;\n\n        if (this._session_state !== session_state) {\n            _Log.Log.debug(\"CheckSessionIFrame.start\");\n\n            this.stop();\n\n            this._session_state = session_state;\n\n            var send = function send() {\n                _this2._frame.contentWindow.postMessage(_this2._client_id + \" \" + _this2._session_state, _this2._frame_origin);\n            };\n\n            // trigger now\n            send();\n\n            // and setup timer\n            this._timer = window.setInterval(send, this._interval);\n        }\n    };\n\n    CheckSessionIFrame.prototype.stop = function stop() {\n        this._session_state = null;\n\n        if (this._timer) {\n            _Log.Log.debug(\"CheckSessionIFrame.stop\");\n\n            window.clearInterval(this._timer);\n            this._timer = null;\n        }\n    };\n\n    return CheckSessionIFrame;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaIFrameNavigator.js\":\n/*!***************************************!*\\\n  !*** ./src/CordovaIFrameNavigator.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaIFrameNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaIFrameNavigator = exports.CordovaIFrameNavigator = function () {\n    function CordovaIFrameNavigator() {\n        _classCallCheck(this, CordovaIFrameNavigator);\n    }\n\n    CordovaIFrameNavigator.prototype.prepare = function prepare(params) {\n        params.popupWindowFeatures = 'hidden=yes';\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaIFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupNavigator.js\":\n/*!**************************************!*\\\n  !*** ./src/CordovaPopupNavigator.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaPopupNavigator = exports.CordovaPopupNavigator = function () {\n    function CordovaPopupNavigator() {\n        _classCallCheck(this, CordovaPopupNavigator);\n    }\n\n    CordovaPopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaPopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupWindow.js\":\n/*!***********************************!*\\\n  !*** ./src/CordovaPopupWindow.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultPopupFeatures = 'location=no,toolbar=no,zoom=no';\nvar DefaultPopupTarget = \"_blank\";\n\nvar CordovaPopupWindow = exports.CordovaPopupWindow = function () {\n    function CordovaPopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, CordovaPopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this.features = params.popupWindowFeatures || DefaultPopupFeatures;\n        this.target = params.popupWindowTarget || DefaultPopupTarget;\n\n        this.redirect_uri = params.startUrl;\n        _Log.Log.debug(\"CordovaPopupWindow.ctor: redirect_uri: \" + this.redirect_uri);\n    }\n\n    CordovaPopupWindow.prototype._isInAppBrowserInstalled = function _isInAppBrowserInstalled(cordovaMetadata) {\n        return [\"cordova-plugin-inappbrowser\", \"cordova-plugin-inappbrowser.inappbrowser\", \"org.apache.cordova.inappbrowser\"].some(function (name) {\n            return cordovaMetadata.hasOwnProperty(name);\n        });\n    };\n\n    CordovaPopupWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            if (!window.cordova) {\n                return this._error(\"cordova is undefined\");\n            }\n\n            var cordovaMetadata = window.cordova.require(\"cordova/plugin_list\").metadata;\n            if (this._isInAppBrowserInstalled(cordovaMetadata) === false) {\n                return this._error(\"InAppBrowser plugin not found\");\n            }\n            this._popup = cordova.InAppBrowser.open(params.url, this.target, this.features);\n            if (this._popup) {\n                _Log.Log.debug(\"CordovaPopupWindow.navigate: popup successfully created\");\n\n                this._exitCallbackEvent = this._exitCallback.bind(this);\n                this._loadStartCallbackEvent = this._loadStartCallback.bind(this);\n\n                this._popup.addEventListener(\"exit\", this._exitCallbackEvent, false);\n                this._popup.addEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            } else {\n                this._error(\"Error opening popup window\");\n            }\n        }\n        return this.promise;\n    };\n\n    CordovaPopupWindow.prototype._loadStartCallback = function _loadStartCallback(event) {\n        if (event.url.indexOf(this.redirect_uri) === 0) {\n            this._success({ url: event.url });\n        }\n    };\n\n    CordovaPopupWindow.prototype._exitCallback = function _exitCallback(message) {\n        this._error(message);\n    };\n\n    CordovaPopupWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"CordovaPopupWindow: Successful response from cordova popup window\");\n        this._resolve(data);\n    };\n\n    CordovaPopupWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    CordovaPopupWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    CordovaPopupWindow.prototype._cleanup = function _cleanup() {\n        if (this._popup) {\n            _Log.Log.debug(\"CordovaPopupWindow: cleaning up popup\");\n            this._popup.removeEventListener(\"exit\", this._exitCallbackEvent, false);\n            this._popup.removeEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    _createClass(CordovaPopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return CordovaPopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/ErrorResponse.js\":\n/*!******************************!*\\\n  !*** ./src/ErrorResponse.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.ErrorResponse = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ErrorResponse = exports.ErrorResponse = function (_Error) {\n        _inherits(ErrorResponse, _Error);\n\n        function ErrorResponse() {\n                var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n                    error = _ref.error,\n                    error_description = _ref.error_description,\n                    error_uri = _ref.error_uri,\n                    state = _ref.state,\n                    session_state = _ref.session_state;\n\n                _classCallCheck(this, ErrorResponse);\n\n                if (!error) {\n                        _Log.Log.error(\"No error passed to ErrorResponse\");\n                        throw new Error(\"error\");\n                }\n\n                var _this = _possibleConstructorReturn(this, _Error.call(this, error_description || error));\n\n                _this.name = \"ErrorResponse\";\n\n                _this.error = error;\n                _this.error_description = error_description;\n                _this.error_uri = error_uri;\n\n                _this.state = state;\n                _this.session_state = session_state;\n                return _this;\n        }\n\n        return ErrorResponse;\n}(Error);\n\n/***/ }),\n\n/***/ \"./src/Event.js\":\n/*!**********************!*\\\n  !*** ./src/Event.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Event = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar Event = exports.Event = function () {\n    function Event(name) {\n        _classCallCheck(this, Event);\n\n        this._name = name;\n        this._callbacks = [];\n    }\n\n    Event.prototype.addHandler = function addHandler(cb) {\n        this._callbacks.push(cb);\n    };\n\n    Event.prototype.removeHandler = function removeHandler(cb) {\n        var idx = this._callbacks.findIndex(function (item) {\n            return item === cb;\n        });\n        if (idx >= 0) {\n            this._callbacks.splice(idx, 1);\n        }\n    };\n\n    Event.prototype.raise = function raise() {\n        _Log.Log.debug(\"Event: Raising event: \" + this._name);\n        for (var i = 0; i < this._callbacks.length; i++) {\n            var _callbacks;\n\n            (_callbacks = this._callbacks)[i].apply(_callbacks, arguments);\n        }\n    };\n\n    return Event;\n}();\n\n/***/ }),\n\n/***/ \"./src/Global.js\":\n/*!***********************!*\\\n  !*** ./src/Global.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar timer = {\n    setInterval: function (_setInterval) {\n        function setInterval(_x, _x2) {\n            return _setInterval.apply(this, arguments);\n        }\n\n        setInterval.toString = function () {\n            return _setInterval.toString();\n        };\n\n        return setInterval;\n    }(function (cb, duration) {\n        return setInterval(cb, duration);\n    }),\n    clearInterval: function (_clearInterval) {\n        function clearInterval(_x3) {\n            return _clearInterval.apply(this, arguments);\n        }\n\n        clearInterval.toString = function () {\n            return _clearInterval.toString();\n        };\n\n        return clearInterval;\n    }(function (handle) {\n        return clearInterval(handle);\n    })\n};\n\nvar testing = false;\nvar request = null;\n\nvar Global = exports.Global = function () {\n    function Global() {\n        _classCallCheck(this, Global);\n    }\n\n    Global._testing = function _testing() {\n        testing = true;\n    };\n\n    Global.setXMLHttpRequest = function setXMLHttpRequest(newRequest) {\n        request = newRequest;\n    };\n\n    _createClass(Global, null, [{\n        key: 'location',\n        get: function get() {\n            if (!testing) {\n                return location;\n            }\n        }\n    }, {\n        key: 'localStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return localStorage;\n            }\n        }\n    }, {\n        key: 'sessionStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return sessionStorage;\n            }\n        }\n    }, {\n        key: 'XMLHttpRequest',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return request || XMLHttpRequest;\n            }\n        }\n    }, {\n        key: 'timer',\n        get: function get() {\n            if (!testing) {\n                return timer;\n            }\n        }\n    }]);\n\n    return Global;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameNavigator.js\":\n/*!********************************!*\\\n  !*** ./src/IFrameNavigator.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _IFrameWindow = __webpack_require__(/*! ./IFrameWindow.js */ \"./src/IFrameWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar IFrameNavigator = exports.IFrameNavigator = function () {\n    function IFrameNavigator() {\n        _classCallCheck(this, IFrameNavigator);\n    }\n\n    IFrameNavigator.prototype.prepare = function prepare(params) {\n        var frame = new _IFrameWindow.IFrameWindow(params);\n        return Promise.resolve(frame);\n    };\n\n    IFrameNavigator.prototype.callback = function callback(url) {\n        _Log.Log.debug(\"IFrameNavigator.callback\");\n\n        try {\n            _IFrameWindow.IFrameWindow.notifyParent(url);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return IFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameWindow.js\":\n/*!*****************************!*\\\n  !*** ./src/IFrameWindow.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultTimeout = 10000;\n\nvar IFrameWindow = exports.IFrameWindow = function () {\n    function IFrameWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, IFrameWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this._boundMessageEvent = this._message.bind(this);\n        window.addEventListener(\"message\", this._boundMessageEvent, false);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        window.document.body.appendChild(this._frame);\n    }\n\n    IFrameWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            var timeout = params.silentRequestTimeout || DefaultTimeout;\n            _Log.Log.debug(\"IFrameWindow.navigate: Using timeout of:\", timeout);\n            this._timer = window.setTimeout(this._timeout.bind(this), timeout);\n            this._frame.src = params.url;\n        }\n\n        return this.promise;\n    };\n\n    IFrameWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"IFrameWindow: Successful response from frame window\");\n        this._resolve(data);\n    };\n\n    IFrameWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    IFrameWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    IFrameWindow.prototype._cleanup = function _cleanup() {\n        if (this._frame) {\n            _Log.Log.debug(\"IFrameWindow: cleanup\");\n\n            window.removeEventListener(\"message\", this._boundMessageEvent, false);\n            window.clearTimeout(this._timer);\n            window.document.body.removeChild(this._frame);\n\n            this._timer = null;\n            this._frame = null;\n            this._boundMessageEvent = null;\n        }\n    };\n\n    IFrameWindow.prototype._timeout = function _timeout() {\n        _Log.Log.debug(\"IFrameWindow.timeout\");\n        this._error(\"Frame window timed out\");\n    };\n\n    IFrameWindow.prototype._message = function _message(e) {\n        _Log.Log.debug(\"IFrameWindow.message\");\n\n        if (this._timer && e.origin === this._origin && e.source === this._frame.contentWindow) {\n            var url = e.data;\n            if (url) {\n                this._success({ url: url });\n            } else {\n                this._error(\"Invalid response from frame\");\n            }\n        }\n    };\n\n    IFrameWindow.notifyParent = function notifyParent(url) {\n        _Log.Log.debug(\"IFrameWindow.notifyParent\");\n        if (window.frameElement) {\n            url = url || window.location.href;\n            if (url) {\n                _Log.Log.debug(\"IFrameWindow.notifyParent: posting url message to parent\");\n                window.parent.postMessage(url, location.protocol + \"//\" + location.host);\n            }\n        }\n    };\n\n    _createClass(IFrameWindow, [{\n        key: \"promise\",\n        get: function get() {\n            return this._promise;\n        }\n    }, {\n        key: \"_origin\",\n        get: function get() {\n            return location.protocol + \"//\" + location.host;\n        }\n    }]);\n\n    return IFrameWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/InMemoryWebStorage.js\":\n/*!***********************************!*\\\n  !*** ./src/InMemoryWebStorage.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.InMemoryWebStorage = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar InMemoryWebStorage = exports.InMemoryWebStorage = function () {\n    function InMemoryWebStorage() {\n        _classCallCheck(this, InMemoryWebStorage);\n\n        this._data = {};\n    }\n\n    InMemoryWebStorage.prototype.getItem = function getItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.getItem\", key);\n        return this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.setItem = function setItem(key, value) {\n        _Log.Log.debug(\"InMemoryWebStorage.setItem\", key);\n        this._data[key] = value;\n    };\n\n    InMemoryWebStorage.prototype.removeItem = function removeItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.removeItem\", key);\n        delete this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.key = function key(index) {\n        return Object.getOwnPropertyNames(this._data)[index];\n    };\n\n    _createClass(InMemoryWebStorage, [{\n        key: \"length\",\n        get: function get() {\n            return Object.getOwnPropertyNames(this._data).length;\n        }\n    }]);\n\n    return InMemoryWebStorage;\n}();\n\n/***/ }),\n\n/***/ \"./src/JoseUtil.js\":\n/*!*************************!*\\\n  !*** ./src/JoseUtil.js ***!\n  \\*************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.JoseUtil = undefined;\n\nvar _jsrsasign = __webpack_require__(/*! ./crypto/jsrsasign */ \"./src/crypto/jsrsasign.js\");\n\nvar _JoseUtilImpl = __webpack_require__(/*! ./JoseUtilImpl */ \"./src/JoseUtilImpl.js\");\n\nvar _JoseUtilImpl2 = _interopRequireDefault(_JoseUtilImpl);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar JoseUtil = exports.JoseUtil = (0, _JoseUtilImpl2.default)({ jws: _jsrsasign.jws, KeyUtil: _jsrsasign.KeyUtil, X509: _jsrsasign.X509, crypto: _jsrsasign.crypto, hextob64u: _jsrsasign.hextob64u, b64tohex: _jsrsasign.b64tohex, AllowedSigningAlgs: _jsrsasign.AllowedSigningAlgs });\n\n/***/ }),\n\n/***/ \"./src/JoseUtilImpl.js\":\n/*!*****************************!*\\\n  !*** ./src/JoseUtilImpl.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.default = getJoseUtil;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nfunction getJoseUtil(_ref) {\n    var jws = _ref.jws,\n        KeyUtil = _ref.KeyUtil,\n        X509 = _ref.X509,\n        crypto = _ref.crypto,\n        hextob64u = _ref.hextob64u,\n        b64tohex = _ref.b64tohex,\n        AllowedSigningAlgs = _ref.AllowedSigningAlgs;\n\n    return function () {\n        function JoseUtil() {\n            _classCallCheck(this, JoseUtil);\n        }\n\n        JoseUtil.parseJwt = function parseJwt(jwt) {\n            _Log.Log.debug(\"JoseUtil.parseJwt\");\n            try {\n                var token = jws.JWS.parse(jwt);\n                return {\n                    header: token.headerObj,\n                    payload: token.payloadObj\n                };\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.validateJwt = function validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n            _Log.Log.debug(\"JoseUtil.validateJwt\");\n\n            try {\n                if (key.kty === \"RSA\") {\n                    if (key.e && key.n) {\n                        key = KeyUtil.getKey(key);\n                    } else if (key.x5c && key.x5c.length) {\n                        var hex = b64tohex(key.x5c[0]);\n                        key = X509.getPublicKeyFromCertHex(hex);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: RSA key missing key material\", key);\n                        return Promise.reject(new Error(\"RSA key missing key material\"));\n                    }\n                } else if (key.kty === \"EC\") {\n                    if (key.crv && key.x && key.y) {\n                        key = KeyUtil.getKey(key);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: EC key missing key material\", key);\n                        return Promise.reject(new Error(\"EC key missing key material\"));\n                    }\n                } else {\n                    _Log.Log.error(\"JoseUtil.validateJwt: Unsupported key type\", key && key.kty);\n                    return Promise.reject(new Error( true && key.kty));\n                }\n\n                return JoseUtil._validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive);\n            } catch (e) {\n                _Log.Log.error(e && e.message || e);\n                return Promise.reject(\"JWT validation failed\");\n            }\n        };\n\n        JoseUtil.validateJwtAttributes = function validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive) {\n            if (!clockSkew) {\n                clockSkew = 0;\n            }\n\n            if (!now) {\n                now = parseInt(Date.now() / 1000);\n            }\n\n            var payload = JoseUtil.parseJwt(jwt).payload;\n\n            if (!payload.iss) {\n                _Log.Log.error(\"JoseUtil._validateJwt: issuer was not provided\");\n                return Promise.reject(new Error(\"issuer was not provided\"));\n            }\n            if (payload.iss !== issuer) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid issuer in token\", payload.iss);\n                return Promise.reject(new Error(\"Invalid issuer in token: \" + payload.iss));\n            }\n\n            if (!payload.aud) {\n                _Log.Log.error(\"JoseUtil._validateJwt: aud was not provided\");\n                return Promise.reject(new Error(\"aud was not provided\"));\n            }\n            var validAudience = payload.aud === audience || Array.isArray(payload.aud) && payload.aud.indexOf(audience) >= 0;\n            if (!validAudience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid audience in token\", payload.aud);\n                return Promise.reject(new Error(\"Invalid audience in token: \" + payload.aud));\n            }\n            if (payload.azp && payload.azp !== audience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid azp in token\", payload.azp);\n                return Promise.reject(new Error(\"Invalid azp in token: \" + payload.azp));\n            }\n\n            if (!timeInsensitive) {\n                var lowerNow = now + clockSkew;\n                var upperNow = now - clockSkew;\n\n                if (!payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat was not provided\");\n                    return Promise.reject(new Error(\"iat was not provided\"));\n                }\n                if (lowerNow < payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat is in the future\", payload.iat);\n                    return Promise.reject(new Error(\"iat is in the future: \" + payload.iat));\n                }\n\n                if (payload.nbf && lowerNow < payload.nbf) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: nbf is in the future\", payload.nbf);\n                    return Promise.reject(new Error(\"nbf is in the future: \" + payload.nbf));\n                }\n\n                if (!payload.exp) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp was not provided\");\n                    return Promise.reject(new Error(\"exp was not provided\"));\n                }\n                if (payload.exp < upperNow) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp is in the past\", payload.exp);\n                    return Promise.reject(new Error(\"exp is in the past:\" + payload.exp));\n                }\n            }\n\n            return Promise.resolve(payload);\n        };\n\n        JoseUtil._validateJwt = function _validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n\n            return JoseUtil.validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive).then(function (payload) {\n                try {\n                    if (!jws.JWS.verify(jwt, key, AllowedSigningAlgs)) {\n                        _Log.Log.error(\"JoseUtil._validateJwt: signature validation failed\");\n                        return Promise.reject(new Error(\"signature validation failed\"));\n                    }\n\n                    return payload;\n                } catch (e) {\n                    _Log.Log.error(e && e.message || e);\n                    return Promise.reject(new Error(\"signature validation failed\"));\n                }\n            });\n        };\n\n        JoseUtil.hashString = function hashString(value, alg) {\n            try {\n                return crypto.Util.hashString(value, alg);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.hexToBase64Url = function hexToBase64Url(value) {\n            try {\n                return hextob64u(value);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        return JoseUtil;\n    }();\n}\nmodule.exports = exports[\"default\"];\n\n/***/ }),\n\n/***/ \"./src/JsonService.js\":\n/*!****************************!*\\\n  !*** ./src/JsonService.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.JsonService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar JsonService = exports.JsonService = function () {\n    function JsonService() {\n        var additionalContentTypes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var jwtHandler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n\n        _classCallCheck(this, JsonService);\n\n        if (additionalContentTypes && Array.isArray(additionalContentTypes)) {\n            this._contentTypes = additionalContentTypes.slice();\n        } else {\n            this._contentTypes = [];\n        }\n        this._contentTypes.push('application/json');\n        if (jwtHandler) {\n            this._contentTypes.push('application/jwt');\n        }\n\n        this._XMLHttpRequest = XMLHttpRequestCtor;\n        this._jwtHandler = jwtHandler;\n    }\n\n    JsonService.prototype.getJson = function getJson(url, token) {\n        var _this = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.getJson: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.getJson, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this._XMLHttpRequest();\n            req.open('GET', url);\n\n            var allowedContentTypes = _this._contentTypes;\n            var jwtHandler = _this._jwtHandler;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.getJson: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found == \"application/jwt\") {\n                            jwtHandler(req).then(resolve, reject);\n                            return;\n                        }\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.getJson: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                } else {\n                    reject(Error(req.statusText + \" (\" + req.status + \")\"));\n                }\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.getJson: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            if (token) {\n                _Log.Log.debug(\"JsonService.getJson: token passed, setting Authorization header\");\n                req.setRequestHeader(\"Authorization\", \"Bearer \" + token);\n            }\n\n            req.send();\n        });\n    };\n\n    JsonService.prototype.postForm = function postForm(url, payload) {\n        var _this2 = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.postForm: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.postForm, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this2._XMLHttpRequest();\n            req.open('POST', url);\n\n            var allowedContentTypes = _this2._contentTypes;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.postForm: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                    return;\n                }\n\n                if (req.status === 400) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                var payload = JSON.parse(req.responseText);\n                                if (payload && payload.error) {\n                                    _Log.Log.error(\"JsonService.postForm: Error from server: \", payload.error);\n                                    reject(new Error(payload.error));\n                                    return;\n                                }\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n                }\n\n                reject(Error(req.statusText + \" (\" + req.status + \")\"));\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.postForm: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            var body = \"\";\n            for (var key in payload) {\n\n                var value = payload[key];\n\n                if (value) {\n\n                    if (body.length > 0) {\n                        body += \"&\";\n                    }\n\n                    body += encodeURIComponent(key);\n                    body += \"=\";\n                    body += encodeURIComponent(value);\n                }\n            }\n\n            req.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            req.send(body);\n        });\n    };\n\n    return JsonService;\n}();\n\n/***/ }),\n\n/***/ \"./src/Log.js\":\n/*!********************!*\\\n  !*** ./src/Log.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar nopLogger = {\n    debug: function debug() {},\n    info: function info() {},\n    warn: function warn() {},\n    error: function error() {}\n};\n\nvar NONE = 0;\nvar ERROR = 1;\nvar WARN = 2;\nvar INFO = 3;\nvar DEBUG = 4;\n\nvar logger = void 0;\nvar level = void 0;\n\nvar Log = exports.Log = function () {\n    function Log() {\n        _classCallCheck(this, Log);\n    }\n\n    Log.reset = function reset() {\n        level = INFO;\n        logger = nopLogger;\n    };\n\n    Log.debug = function debug() {\n        if (level >= DEBUG) {\n            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n                args[_key] = arguments[_key];\n            }\n\n            logger.debug.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.info = function info() {\n        if (level >= INFO) {\n            for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n                args[_key2] = arguments[_key2];\n            }\n\n            logger.info.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.warn = function warn() {\n        if (level >= WARN) {\n            for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n                args[_key3] = arguments[_key3];\n            }\n\n            logger.warn.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.error = function error() {\n        if (level >= ERROR) {\n            for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n                args[_key4] = arguments[_key4];\n            }\n\n            logger.error.apply(logger, Array.from(args));\n        }\n    };\n\n    _createClass(Log, null, [{\n        key: \"NONE\",\n        get: function get() {\n            return NONE;\n        }\n    }, {\n        key: \"ERROR\",\n        get: function get() {\n            return ERROR;\n        }\n    }, {\n        key: \"WARN\",\n        get: function get() {\n            return WARN;\n        }\n    }, {\n        key: \"INFO\",\n        get: function get() {\n            return INFO;\n        }\n    }, {\n        key: \"DEBUG\",\n        get: function get() {\n            return DEBUG;\n        }\n    }, {\n        key: \"level\",\n        get: function get() {\n            return level;\n        },\n        set: function set(value) {\n            if (NONE <= value && value <= DEBUG) {\n                level = value;\n            } else {\n                throw new Error(\"Invalid log level\");\n            }\n        }\n    }, {\n        key: \"logger\",\n        get: function get() {\n            return logger;\n        },\n        set: function set(value) {\n            if (!value.debug && value.info) {\n                // just to stay backwards compat. can remove in 2.0\n                value.debug = value.info;\n            }\n\n            if (value.debug && value.info && value.warn && value.error) {\n                logger = value;\n            } else {\n                throw new Error(\"Invalid logger\");\n            }\n        }\n    }]);\n\n    return Log;\n}();\n\nLog.reset();\n\n/***/ }),\n\n/***/ \"./src/MetadataService.js\":\n/*!********************************!*\\\n  !*** ./src/MetadataService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.MetadataService = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar MetadataService = exports.MetadataService = function () {\n    function MetadataService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n\n        _classCallCheck(this, MetadataService);\n\n        if (!settings) {\n            _Log.Log.error(\"MetadataService: No settings passed to MetadataService\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(['application/jwk-set+json']);\n    }\n\n    MetadataService.prototype.getMetadata = function getMetadata() {\n        var _this = this;\n\n        if (this._settings.metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: Returning metadata from settings\");\n            return Promise.resolve(this._settings.metadata);\n        }\n\n        if (!this.metadataUrl) {\n            _Log.Log.error(\"MetadataService.getMetadata: No authority or metadataUrl configured on settings\");\n            return Promise.reject(new Error(\"No authority or metadataUrl configured on settings\"));\n        }\n\n        _Log.Log.debug(\"MetadataService.getMetadata: getting metadata from\", this.metadataUrl);\n\n        return this._jsonService.getJson(this.metadataUrl).then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: json received\");\n            _this._settings.metadata = metadata;\n            return metadata;\n        });\n    };\n\n    MetadataService.prototype.getIssuer = function getIssuer() {\n        return this._getMetadataProperty(\"issuer\");\n    };\n\n    MetadataService.prototype.getAuthorizationEndpoint = function getAuthorizationEndpoint() {\n        return this._getMetadataProperty(\"authorization_endpoint\");\n    };\n\n    MetadataService.prototype.getUserInfoEndpoint = function getUserInfoEndpoint() {\n        return this._getMetadataProperty(\"userinfo_endpoint\");\n    };\n\n    MetadataService.prototype.getTokenEndpoint = function getTokenEndpoint() {\n        var optional = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n        return this._getMetadataProperty(\"token_endpoint\", optional);\n    };\n\n    MetadataService.prototype.getCheckSessionIframe = function getCheckSessionIframe() {\n        return this._getMetadataProperty(\"check_session_iframe\", true);\n    };\n\n    MetadataService.prototype.getEndSessionEndpoint = function getEndSessionEndpoint() {\n        return this._getMetadataProperty(\"end_session_endpoint\", true);\n    };\n\n    MetadataService.prototype.getRevocationEndpoint = function getRevocationEndpoint() {\n        return this._getMetadataProperty(\"revocation_endpoint\", true);\n    };\n\n    MetadataService.prototype.getKeysEndpoint = function getKeysEndpoint() {\n        return this._getMetadataProperty(\"jwks_uri\", true);\n    };\n\n    MetadataService.prototype._getMetadataProperty = function _getMetadataProperty(name) {\n        var optional = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n        _Log.Log.debug(\"MetadataService.getMetadataProperty for: \" + name);\n\n        return this.getMetadata().then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadataProperty: metadata recieved\");\n\n            if (metadata[name] === undefined) {\n\n                if (optional === true) {\n                    _Log.Log.warn(\"MetadataService.getMetadataProperty: Metadata does not contain optional property \" + name);\n                    return undefined;\n                } else {\n                    _Log.Log.error(\"MetadataService.getMetadataProperty: Metadata does not contain property \" + name);\n                    throw new Error(\"Metadata does not contain property \" + name);\n                }\n            }\n\n            return metadata[name];\n        });\n    };\n\n    MetadataService.prototype.getSigningKeys = function getSigningKeys() {\n        var _this2 = this;\n\n        if (this._settings.signingKeys) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: Returning signingKeys from settings\");\n            return Promise.resolve(this._settings.signingKeys);\n        }\n\n        return this._getMetadataProperty(\"jwks_uri\").then(function (jwks_uri) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: jwks_uri received\", jwks_uri);\n\n            return _this2._jsonService.getJson(jwks_uri).then(function (keySet) {\n                _Log.Log.debug(\"MetadataService.getSigningKeys: key set received\", keySet);\n\n                if (!keySet.keys) {\n                    _Log.Log.error(\"MetadataService.getSigningKeys: Missing keys on keyset\");\n                    throw new Error(\"Missing keys on keyset\");\n                }\n\n                _this2._settings.signingKeys = keySet.keys;\n                return _this2._settings.signingKeys;\n            });\n        });\n    };\n\n    _createClass(MetadataService, [{\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                if (this._settings.metadataUrl) {\n                    this._metadataUrl = this._settings.metadataUrl;\n                } else {\n                    this._metadataUrl = this._settings.authority;\n\n                    if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                        if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                            this._metadataUrl += '/';\n                        }\n                        this._metadataUrl += OidcMetadataUrlPath;\n                    }\n                }\n            }\n\n            return this._metadataUrl;\n        }\n    }]);\n\n    return MetadataService;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClient.js\":\n/*!***************************!*\\\n  !*** ./src/OidcClient.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClient = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nvar _SigninResponse = __webpack_require__(/*! ./SigninResponse.js */ \"./src/SigninResponse.js\");\n\nvar _SignoutRequest = __webpack_require__(/*! ./SignoutRequest.js */ \"./src/SignoutRequest.js\");\n\nvar _SignoutResponse = __webpack_require__(/*! ./SignoutResponse.js */ \"./src/SignoutResponse.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcClient = exports.OidcClient = function () {\n    function OidcClient() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        _classCallCheck(this, OidcClient);\n\n        if (settings instanceof _OidcClientSettings.OidcClientSettings) {\n            this._settings = settings;\n        } else {\n            this._settings = new _OidcClientSettings.OidcClientSettings(settings);\n        }\n    }\n\n    OidcClient.prototype.createSigninRequest = function createSigninRequest() {\n        var _this = this;\n\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            redirect_uri = _ref.redirect_uri,\n            data = _ref.data,\n            state = _ref.state,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            response_mode = _ref.response_mode,\n            extraQueryParams = _ref.extraQueryParams,\n            extraTokenParams = _ref.extraTokenParams,\n            request_type = _ref.request_type,\n            skipUserInfo = _ref.skipUserInfo;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSigninRequest\");\n\n        var client_id = this._settings.client_id;\n        response_type = response_type || this._settings.response_type;\n        scope = scope || this._settings.scope;\n        redirect_uri = redirect_uri || this._settings.redirect_uri;\n\n        // id_token_hint, login_hint aren't allowed on _settings\n        prompt = prompt || this._settings.prompt;\n        display = display || this._settings.display;\n        max_age = max_age || this._settings.max_age;\n        ui_locales = ui_locales || this._settings.ui_locales;\n        acr_values = acr_values || this._settings.acr_values;\n        resource = resource || this._settings.resource;\n        response_mode = response_mode || this._settings.response_mode;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n        extraTokenParams = extraTokenParams || this._settings.extraTokenParams;\n\n        var authority = this._settings.authority;\n\n        if (_SigninRequest.SigninRequest.isCode(response_type) && response_type !== \"code\") {\n            return Promise.reject(new Error(\"OpenID Connect hybrid flow is not supported\"));\n        }\n\n        return this._metadataService.getAuthorizationEndpoint().then(function (url) {\n            _Log.Log.debug(\"OidcClient.createSigninRequest: Received authorization endpoint\", url);\n\n            var signinRequest = new _SigninRequest.SigninRequest({\n                url: url,\n                client_id: client_id,\n                redirect_uri: redirect_uri,\n                response_type: response_type,\n                scope: scope,\n                data: data || state,\n                authority: authority,\n                prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values,\n                resource: resource, request: request, request_uri: request_uri, extraQueryParams: extraQueryParams, extraTokenParams: extraTokenParams, request_type: request_type, response_mode: response_mode,\n                client_secret: _this._settings.client_secret,\n                skipUserInfo: skipUserInfo\n            });\n\n            var signinState = signinRequest.state;\n            stateStore = stateStore || _this._stateStore;\n\n            return stateStore.set(signinState.id, signinState.toStorageString()).then(function () {\n                return signinRequest;\n            });\n        });\n    };\n\n    OidcClient.prototype.readSigninResponseState = function readSigninResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSigninResponseState\");\n\n        var useQuery = this._settings.response_mode === \"query\" || !this._settings.response_mode && _SigninRequest.SigninRequest.isCode(this._settings.response_type);\n        var delimiter = useQuery ? \"?\" : \"#\";\n\n        var response = new _SigninResponse.SigninResponse(url, delimiter);\n\n        if (!response.state) {\n            _Log.Log.error(\"OidcClient.readSigninResponseState: No state in response\");\n            return Promise.reject(new Error(\"No state in response\"));\n        }\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n\n        return stateApi(response.state).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSigninResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _SigninState.SigninState.fromStorageString(storedStateString);\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSigninResponse = function processSigninResponse(url, stateStore) {\n        var _this2 = this;\n\n        _Log.Log.debug(\"OidcClient.processSigninResponse\");\n\n        return this.readSigninResponseState(url, stateStore, true).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            _Log.Log.debug(\"OidcClient.processSigninResponse: Received state from storage; validating response\");\n            return _this2._validator.validateSigninResponse(state, response);\n        });\n    };\n\n    OidcClient.prototype.createSignoutRequest = function createSignoutRequest() {\n        var _this3 = this;\n\n        var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id_token_hint = _ref3.id_token_hint,\n            data = _ref3.data,\n            state = _ref3.state,\n            post_logout_redirect_uri = _ref3.post_logout_redirect_uri,\n            extraQueryParams = _ref3.extraQueryParams,\n            request_type = _ref3.request_type;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSignoutRequest\");\n\n        post_logout_redirect_uri = post_logout_redirect_uri || this._settings.post_logout_redirect_uri;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n\n        return this._metadataService.getEndSessionEndpoint().then(function (url) {\n            if (!url) {\n                _Log.Log.error(\"OidcClient.createSignoutRequest: No end session endpoint url returned\");\n                throw new Error(\"no end session endpoint\");\n            }\n\n            _Log.Log.debug(\"OidcClient.createSignoutRequest: Received end session endpoint\", url);\n\n            var request = new _SignoutRequest.SignoutRequest({\n                url: url,\n                id_token_hint: id_token_hint,\n                post_logout_redirect_uri: post_logout_redirect_uri,\n                data: data || state,\n                extraQueryParams: extraQueryParams,\n                request_type: request_type\n            });\n\n            var signoutState = request.state;\n            if (signoutState) {\n                _Log.Log.debug(\"OidcClient.createSignoutRequest: Signout request has state to persist\");\n\n                stateStore = stateStore || _this3._stateStore;\n                stateStore.set(signoutState.id, signoutState.toStorageString());\n            }\n\n            return request;\n        });\n    };\n\n    OidcClient.prototype.readSignoutResponseState = function readSignoutResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSignoutResponseState\");\n\n        var response = new _SignoutResponse.SignoutResponse(url);\n        if (!response.state) {\n            _Log.Log.debug(\"OidcClient.readSignoutResponseState: No state in response\");\n\n            if (response.error) {\n                _Log.Log.warn(\"OidcClient.readSignoutResponseState: Response was error: \", response.error);\n                return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n            }\n\n            return Promise.resolve({ undefined: undefined, response: response });\n        }\n\n        var stateKey = response.state;\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n        return stateApi(stateKey).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSignoutResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _State.State.fromStorageString(storedStateString);\n\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSignoutResponse = function processSignoutResponse(url, stateStore) {\n        var _this4 = this;\n\n        _Log.Log.debug(\"OidcClient.processSignoutResponse\");\n\n        return this.readSignoutResponseState(url, stateStore, true).then(function (_ref4) {\n            var state = _ref4.state,\n                response = _ref4.response;\n\n            if (state) {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: Received state from storage; validating response\");\n                return _this4._validator.validateSignoutResponse(state, response);\n            } else {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: No state from storage; skipping validating response\");\n                return response;\n            }\n        });\n    };\n\n    OidcClient.prototype.clearStaleState = function clearStaleState(stateStore) {\n        _Log.Log.debug(\"OidcClient.clearStaleState\");\n\n        stateStore = stateStore || this._stateStore;\n\n        return _State.State.clearStaleState(stateStore, this.settings.staleStateAge);\n    };\n\n    _createClass(OidcClient, [{\n        key: '_stateStore',\n        get: function get() {\n            return this.settings.stateStore;\n        }\n    }, {\n        key: '_validator',\n        get: function get() {\n            return this.settings.validator;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this.settings.metadataService;\n        }\n    }, {\n        key: 'settings',\n        get: function get() {\n            return this._settings;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n    }]);\n\n    return OidcClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClientSettings.js\":\n/*!***********************************!*\\\n  !*** ./src/OidcClientSettings.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClientSettings = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _ResponseValidator = __webpack_require__(/*! ./ResponseValidator.js */ \"./src/ResponseValidator.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar DefaultResponseType = \"id_token\";\nvar DefaultScope = \"openid\";\nvar DefaultStaleStateAge = 60 * 15; // seconds\nvar DefaultClockSkewInSeconds = 60 * 5;\n\nvar OidcClientSettings = exports.OidcClientSettings = function () {\n    function OidcClientSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            authority = _ref.authority,\n            metadataUrl = _ref.metadataUrl,\n            metadata = _ref.metadata,\n            signingKeys = _ref.signingKeys,\n            client_id = _ref.client_id,\n            client_secret = _ref.client_secret,\n            _ref$response_type = _ref.response_type,\n            response_type = _ref$response_type === undefined ? DefaultResponseType : _ref$response_type,\n            _ref$scope = _ref.scope,\n            scope = _ref$scope === undefined ? DefaultScope : _ref$scope,\n            redirect_uri = _ref.redirect_uri,\n            post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            _ref$filterProtocolCl = _ref.filterProtocolClaims,\n            filterProtocolClaims = _ref$filterProtocolCl === undefined ? true : _ref$filterProtocolCl,\n            _ref$loadUserInfo = _ref.loadUserInfo,\n            loadUserInfo = _ref$loadUserInfo === undefined ? true : _ref$loadUserInfo,\n            _ref$staleStateAge = _ref.staleStateAge,\n            staleStateAge = _ref$staleStateAge === undefined ? DefaultStaleStateAge : _ref$staleStateAge,\n            _ref$clockSkew = _ref.clockSkew,\n            clockSkew = _ref$clockSkew === undefined ? DefaultClockSkewInSeconds : _ref$clockSkew,\n            _ref$userInfoJwtIssue = _ref.userInfoJwtIssuer,\n            userInfoJwtIssuer = _ref$userInfoJwtIssue === undefined ? 'OP' : _ref$userInfoJwtIssue,\n            _ref$stateStore = _ref.stateStore,\n            stateStore = _ref$stateStore === undefined ? new _WebStorageStateStore.WebStorageStateStore() : _ref$stateStore,\n            _ref$ResponseValidato = _ref.ResponseValidatorCtor,\n            ResponseValidatorCtor = _ref$ResponseValidato === undefined ? _ResponseValidator.ResponseValidator : _ref$ResponseValidato,\n            _ref$MetadataServiceC = _ref.MetadataServiceCtor,\n            MetadataServiceCtor = _ref$MetadataServiceC === undefined ? _MetadataService.MetadataService : _ref$MetadataServiceC,\n            _ref$extraQueryParams = _ref.extraQueryParams,\n            extraQueryParams = _ref$extraQueryParams === undefined ? {} : _ref$extraQueryParams,\n            _ref$extraTokenParams = _ref.extraTokenParams,\n            extraTokenParams = _ref$extraTokenParams === undefined ? {} : _ref$extraTokenParams;\n\n        _classCallCheck(this, OidcClientSettings);\n\n        this._authority = authority;\n        this._metadataUrl = metadataUrl;\n        this._metadata = metadata;\n        this._signingKeys = signingKeys;\n\n        this._client_id = client_id;\n        this._client_secret = client_secret;\n        this._response_type = response_type;\n        this._scope = scope;\n        this._redirect_uri = redirect_uri;\n        this._post_logout_redirect_uri = post_logout_redirect_uri;\n\n        this._prompt = prompt;\n        this._display = display;\n        this._max_age = max_age;\n        this._ui_locales = ui_locales;\n        this._acr_values = acr_values;\n        this._resource = resource;\n        this._response_mode = response_mode;\n\n        this._filterProtocolClaims = !!filterProtocolClaims;\n        this._loadUserInfo = !!loadUserInfo;\n        this._staleStateAge = staleStateAge;\n        this._clockSkew = clockSkew;\n        this._userInfoJwtIssuer = userInfoJwtIssuer;\n\n        this._stateStore = stateStore;\n        this._validator = new ResponseValidatorCtor(this);\n        this._metadataService = new MetadataServiceCtor(this);\n\n        this._extraQueryParams = (typeof extraQueryParams === 'undefined' ? 'undefined' : _typeof(extraQueryParams)) === 'object' ? extraQueryParams : {};\n        this._extraTokenParams = (typeof extraTokenParams === 'undefined' ? 'undefined' : _typeof(extraTokenParams)) === 'object' ? extraTokenParams : {};\n    }\n\n    // client config\n\n\n    _createClass(OidcClientSettings, [{\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        },\n        set: function set(value) {\n            if (!this._client_id) {\n                // one-time set only\n                this._client_id = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_client_id: client_id has already been assigned.\");\n                throw new Error(\"client_id has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'response_type',\n        get: function get() {\n            return this._response_type;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'post_logout_redirect_uri',\n        get: function get() {\n            return this._post_logout_redirect_uri;\n        }\n\n        // optional protocol params\n\n    }, {\n        key: 'prompt',\n        get: function get() {\n            return this._prompt;\n        }\n    }, {\n        key: 'display',\n        get: function get() {\n            return this._display;\n        }\n    }, {\n        key: 'max_age',\n        get: function get() {\n            return this._max_age;\n        }\n    }, {\n        key: 'ui_locales',\n        get: function get() {\n            return this._ui_locales;\n        }\n    }, {\n        key: 'acr_values',\n        get: function get() {\n            return this._acr_values;\n        }\n    }, {\n        key: 'resource',\n        get: function get() {\n            return this._resource;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n\n        // metadata\n\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        },\n        set: function set(value) {\n            if (!this._authority) {\n                // one-time set only\n                this._authority = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_authority: authority has already been assigned.\");\n                throw new Error(\"authority has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                this._metadataUrl = this.authority;\n\n                if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                    if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                        this._metadataUrl += '/';\n                    }\n                    this._metadataUrl += OidcMetadataUrlPath;\n                }\n            }\n\n            return this._metadataUrl;\n        }\n\n        // settable/cachable metadata values\n\n    }, {\n        key: 'metadata',\n        get: function get() {\n            return this._metadata;\n        },\n        set: function set(value) {\n            this._metadata = value;\n        }\n    }, {\n        key: 'signingKeys',\n        get: function get() {\n            return this._signingKeys;\n        },\n        set: function set(value) {\n            this._signingKeys = value;\n        }\n\n        // behavior flags\n\n    }, {\n        key: 'filterProtocolClaims',\n        get: function get() {\n            return this._filterProtocolClaims;\n        }\n    }, {\n        key: 'loadUserInfo',\n        get: function get() {\n            return this._loadUserInfo;\n        }\n    }, {\n        key: 'staleStateAge',\n        get: function get() {\n            return this._staleStateAge;\n        }\n    }, {\n        key: 'clockSkew',\n        get: function get() {\n            return this._clockSkew;\n        }\n    }, {\n        key: 'userInfoJwtIssuer',\n        get: function get() {\n            return this._userInfoJwtIssuer;\n        }\n    }, {\n        key: 'stateStore',\n        get: function get() {\n            return this._stateStore;\n        }\n    }, {\n        key: 'validator',\n        get: function get() {\n            return this._validator;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n\n        // extra query params\n\n    }, {\n        key: 'extraQueryParams',\n        get: function get() {\n            return this._extraQueryParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraQueryParams = value;\n            } else {\n                this._extraQueryParams = {};\n            }\n        }\n\n        // extra token params\n\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraTokenParams = value;\n            } else {\n                this._extraTokenParams = {};\n            }\n        }\n    }]);\n\n    return OidcClientSettings;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupNavigator.js\":\n/*!*******************************!*\\\n  !*** ./src/PopupNavigator.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _PopupWindow = __webpack_require__(/*! ./PopupWindow.js */ \"./src/PopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar PopupNavigator = exports.PopupNavigator = function () {\n    function PopupNavigator() {\n        _classCallCheck(this, PopupNavigator);\n    }\n\n    PopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _PopupWindow.PopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    PopupNavigator.prototype.callback = function callback(url, keepOpen, delimiter) {\n        _Log.Log.debug(\"PopupNavigator.callback\");\n\n        try {\n            _PopupWindow.PopupWindow.notifyOpener(url, keepOpen, delimiter);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return PopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupWindow.js\":\n/*!****************************!*\\\n  !*** ./src/PopupWindow.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar CheckForPopupClosedInterval = 500;\nvar DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;';\n//const DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;resizable=yes';\n\nvar DefaultPopupTarget = \"_blank\";\n\nvar PopupWindow = exports.PopupWindow = function () {\n    function PopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, PopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        var target = params.popupWindowTarget || DefaultPopupTarget;\n        var features = params.popupWindowFeatures || DefaultPopupFeatures;\n\n        this._popup = window.open('', target, features);\n        if (this._popup) {\n            _Log.Log.debug(\"PopupWindow.ctor: popup successfully created\");\n            this._checkForPopupClosedTimer = window.setInterval(this._checkForPopupClosed.bind(this), CheckForPopupClosedInterval);\n        }\n    }\n\n    PopupWindow.prototype.navigate = function navigate(params) {\n        if (!this._popup) {\n            this._error(\"PopupWindow.navigate: Error opening popup window\");\n        } else if (!params || !params.url) {\n            this._error(\"PopupWindow.navigate: no url provided\");\n            this._error(\"No url provided\");\n        } else {\n            _Log.Log.debug(\"PopupWindow.navigate: Setting URL in popup\");\n\n            this._id = params.id;\n            if (this._id) {\n                window[\"popupCallback_\" + params.id] = this._callback.bind(this);\n            }\n\n            this._popup.focus();\n            this._popup.window.location = params.url;\n        }\n\n        return this.promise;\n    };\n\n    PopupWindow.prototype._success = function _success(data) {\n        _Log.Log.debug(\"PopupWindow.callback: Successful response from popup window\");\n\n        this._cleanup();\n        this._resolve(data);\n    };\n\n    PopupWindow.prototype._error = function _error(message) {\n        _Log.Log.error(\"PopupWindow.error: \", message);\n\n        this._cleanup();\n        this._reject(new Error(message));\n    };\n\n    PopupWindow.prototype.close = function close() {\n        this._cleanup(false);\n    };\n\n    PopupWindow.prototype._cleanup = function _cleanup(keepOpen) {\n        _Log.Log.debug(\"PopupWindow.cleanup\");\n\n        window.clearInterval(this._checkForPopupClosedTimer);\n        this._checkForPopupClosedTimer = null;\n\n        delete window[\"popupCallback_\" + this._id];\n\n        if (this._popup && !keepOpen) {\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    PopupWindow.prototype._checkForPopupClosed = function _checkForPopupClosed() {\n        if (!this._popup || this._popup.closed) {\n            this._error(\"Popup window closed\");\n        }\n    };\n\n    PopupWindow.prototype._callback = function _callback(url, keepOpen) {\n        this._cleanup(keepOpen);\n\n        if (url) {\n            _Log.Log.debug(\"PopupWindow.callback success\");\n            this._success({ url: url });\n        } else {\n            _Log.Log.debug(\"PopupWindow.callback: Invalid response from popup\");\n            this._error(\"Invalid response from popup\");\n        }\n    };\n\n    PopupWindow.notifyOpener = function notifyOpener(url, keepOpen, delimiter) {\n        if (window.opener) {\n            url = url || window.location.href;\n            if (url) {\n                var data = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n                if (data.state) {\n                    var name = \"popupCallback_\" + data.state;\n                    var callback = window.opener[name];\n                    if (callback) {\n                        _Log.Log.debug(\"PopupWindow.notifyOpener: passing url message to opener\");\n                        callback(url, keepOpen);\n                    } else {\n                        _Log.Log.warn(\"PopupWindow.notifyOpener: no matching callback found on opener\");\n                    }\n                } else {\n                    _Log.Log.warn(\"PopupWindow.notifyOpener: no state found in response url\");\n                }\n            }\n        } else {\n            _Log.Log.warn(\"PopupWindow.notifyOpener: no window.opener. Can't complete notification.\");\n        }\n    };\n\n    _createClass(PopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return PopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/RedirectNavigator.js\":\n/*!**********************************!*\\\n  !*** ./src/RedirectNavigator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.RedirectNavigator = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar RedirectNavigator = exports.RedirectNavigator = function () {\n    function RedirectNavigator() {\n        _classCallCheck(this, RedirectNavigator);\n    }\n\n    RedirectNavigator.prototype.prepare = function prepare() {\n        return Promise.resolve(this);\n    };\n\n    RedirectNavigator.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            _Log.Log.error(\"RedirectNavigator.navigate: No url provided\");\n            return Promise.reject(new Error(\"No url provided\"));\n        }\n\n        if (params.useReplaceToNavigate) {\n            window.location.replace(params.url);\n        } else {\n            window.location = params.url;\n        }\n\n        return Promise.resolve();\n    };\n\n    _createClass(RedirectNavigator, [{\n        key: \"url\",\n        get: function get() {\n            return window.location.href;\n        }\n    }]);\n\n    return RedirectNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/ResponseValidator.js\":\n/*!**********************************!*\\\n  !*** ./src/ResponseValidator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.ResponseValidator = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _UserInfoService = __webpack_require__(/*! ./UserInfoService.js */ \"./src/UserInfoService.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ProtocolClaims = [\"nonce\", \"at_hash\", \"iat\", \"nbf\", \"exp\", \"aud\", \"iss\", \"c_hash\"];\n\nvar ResponseValidator = exports.ResponseValidator = function () {\n    function ResponseValidator(settings) {\n        var MetadataServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _MetadataService.MetadataService;\n        var UserInfoServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _UserInfoService.UserInfoService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n\n        _classCallCheck(this, ResponseValidator);\n\n        if (!settings) {\n            _Log.Log.error(\"ResponseValidator.ctor: No settings passed to ResponseValidator\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._userInfoService = new UserInfoServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n        this._tokenClient = new TokenClientCtor(this._settings);\n    }\n\n    ResponseValidator.prototype.validateSigninResponse = function validateSigninResponse(state, response) {\n        var _this = this;\n\n        _Log.Log.debug(\"ResponseValidator.validateSigninResponse\");\n\n        return this._processSigninParams(state, response).then(function (response) {\n            _Log.Log.debug(\"ResponseValidator.validateSigninResponse: state processed\");\n            return _this._validateTokens(state, response).then(function (response) {\n                _Log.Log.debug(\"ResponseValidator.validateSigninResponse: tokens validated\");\n                return _this._processClaims(state, response).then(function (response) {\n                    _Log.Log.debug(\"ResponseValidator.validateSigninResponse: claims processed\");\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype.validateSignoutResponse = function validateSignoutResponse(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator.validateSignoutResponse: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator.validateSignoutResponse: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator.validateSignoutResponse: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processSigninParams = function _processSigninParams(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        if (!state.client_id) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No client_id on state\");\n            return Promise.reject(new Error(\"No client_id on state\"));\n        }\n\n        if (!state.authority) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No authority on state\");\n            return Promise.reject(new Error(\"No authority on state\"));\n        }\n\n        // this allows the authority to be loaded from the signin state\n        if (!this._settings.authority) {\n            this._settings.authority = state.authority;\n        }\n        // ensure we're using the correct authority if the authority is not loaded from signin state\n        else if (this._settings.authority && this._settings.authority !== state.authority) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: authority mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"authority mismatch on settings vs. signin state\"));\n            }\n        // this allows the client_id to be loaded from the signin state\n        if (!this._settings.client_id) {\n            this._settings.client_id = state.client_id;\n        }\n        // ensure we're using the correct client_id if the client_id is not loaded from signin state\n        else if (this._settings.client_id && this._settings.client_id !== state.client_id) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: client_id mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"client_id mismatch on settings vs. signin state\"));\n            }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator._processSigninParams: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator._processSigninParams: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        if (state.nonce && !response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting id_token in response\");\n            return Promise.reject(new Error(\"No id_token in response\"));\n        }\n\n        if (!state.nonce && response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting id_token in response\");\n            return Promise.reject(new Error(\"Unexpected id_token in response\"));\n        }\n\n        if (state.code_verifier && !response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting code in response\");\n            return Promise.reject(new Error(\"No code in response\"));\n        }\n\n        if (!state.code_verifier && response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting code in response\");\n            return Promise.reject(new Error(\"Unexpected code in response\"));\n        }\n\n        if (!response.scope) {\n            // if there's no scope on the response, then assume all scopes granted (per-spec) and copy over scopes from original request\n            response.scope = state.scope;\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processClaims = function _processClaims(state, response) {\n        var _this2 = this;\n\n        if (response.isOpenIdConnect) {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is OIDC, processing claims\");\n\n            response.profile = this._filterProtocolClaims(response.profile);\n\n            if (state.skipUserInfo !== true && this._settings.loadUserInfo && response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._processClaims: loading user info\");\n\n                return this._userInfoService.getClaims(response.access_token).then(function (claims) {\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received from user info endpoint\");\n\n                    if (claims.sub !== response.profile.sub) {\n                        _Log.Log.error(\"ResponseValidator._processClaims: sub from user info endpoint does not match sub in access_token\");\n                        return Promise.reject(new Error(\"sub from user info endpoint does not match sub in access_token\"));\n                    }\n\n                    response.profile = _this2._mergeClaims(response.profile, claims);\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received, updated profile:\", response.profile);\n\n                    return response;\n                });\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processClaims: not loading user info\");\n            }\n        } else {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is not OIDC, not processing claims\");\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._mergeClaims = function _mergeClaims(claims1, claims2) {\n        var result = Object.assign({}, claims1);\n\n        for (var name in claims2) {\n            var values = claims2[name];\n            if (!Array.isArray(values)) {\n                values = [values];\n            }\n\n            for (var i = 0; i < values.length; i++) {\n                var value = values[i];\n                if (!result[name]) {\n                    result[name] = value;\n                } else if (Array.isArray(result[name])) {\n                    if (result[name].indexOf(value) < 0) {\n                        result[name].push(value);\n                    }\n                } else if (result[name] !== value) {\n                    if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                        result[name] = this._mergeClaims(result[name], value);\n                    } else {\n                        result[name] = [result[name], value];\n                    }\n                }\n            }\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._filterProtocolClaims = function _filterProtocolClaims(claims) {\n        _Log.Log.debug(\"ResponseValidator._filterProtocolClaims, incoming claims:\", claims);\n\n        var result = Object.assign({}, claims);\n\n        if (this._settings._filterProtocolClaims) {\n            ProtocolClaims.forEach(function (type) {\n                delete result[type];\n            });\n\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims filtered\", result);\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims not filtered\");\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._validateTokens = function _validateTokens(state, response) {\n        if (response.code) {\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating code\");\n            return this._processCode(state, response);\n        }\n\n        if (response.id_token) {\n            if (response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token and access_token\");\n                return this._validateIdTokenAndAccessToken(state, response);\n            }\n\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token\");\n            return this._validateIdToken(state, response);\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateTokens: No code to process or id_token to validate\");\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processCode = function _processCode(state, response) {\n        var _this3 = this;\n\n        var request = {\n            client_id: state.client_id,\n            client_secret: state.client_secret,\n            code: response.code,\n            redirect_uri: state.redirect_uri,\n            code_verifier: state.code_verifier\n        };\n\n        if (state.extraTokenParams && _typeof(state.extraTokenParams) === 'object') {\n            Object.assign(request, state.extraTokenParams);\n        }\n\n        return this._tokenClient.exchangeCode(request).then(function (tokenResponse) {\n\n            for (var key in tokenResponse) {\n                response[key] = tokenResponse[key];\n            }\n\n            if (response.id_token) {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, processing id_token\");\n                return _this3._validateIdTokenAttributes(state, response);\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, returning response\");\n            }\n\n            return response;\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAttributes = function _validateIdTokenAttributes(state, response) {\n        var _this4 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n\n            var audience = state.client_id;\n            var clockSkewInSeconds = _this4._settings.clockSkew;\n            _Log.Log.debug(\"ResponseValidator._validateIdTokenAttributes: Validaing JWT attributes; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n            return _this4._joseUtil.validateJwtAttributes(response.id_token, issuer, audience, clockSkewInSeconds).then(function (payload) {\n\n                if (state.nonce && state.nonce !== payload.nonce) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: Invalid nonce in id_token\");\n                    return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n                }\n\n                if (!payload.sub) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: No sub present in id_token\");\n                    return Promise.reject(new Error(\"No sub present in id_token\"));\n                }\n\n                response.profile = payload;\n                return response;\n            });\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAndAccessToken = function _validateIdTokenAndAccessToken(state, response) {\n        var _this5 = this;\n\n        return this._validateIdToken(state, response).then(function (response) {\n            return _this5._validateAccessToken(response);\n        });\n    };\n\n    ResponseValidator.prototype._validateIdToken = function _validateIdToken(state, response) {\n        var _this6 = this;\n\n        if (!state.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: No nonce on state\");\n            return Promise.reject(new Error(\"No nonce on state\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header || !jwt.payload) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        if (state.nonce !== jwt.payload.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Invalid nonce in id_token\");\n            return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n        }\n\n        var kid = jwt.header.kid;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            _Log.Log.debug(\"ResponseValidator._validateIdToken: Received issuer\");\n\n            return _this6._metadataService.getSigningKeys().then(function (keys) {\n                if (!keys) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No signing keys from metadata\");\n                    return Promise.reject(new Error(\"No signing keys from metadata\"));\n                }\n\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Received signing keys\");\n                var key = void 0;\n                if (!kid) {\n                    keys = _this6._filterByAlg(keys, jwt.header.alg);\n\n                    if (keys.length > 1) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No kid found in id_token and more than one key found in metadata\");\n                        return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                    } else {\n                        // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                        // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                        key = keys[0];\n                    }\n                } else {\n                    key = keys.filter(function (key) {\n                        return key.kid === kid;\n                    })[0];\n                }\n\n                if (!key) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No key matching kid or alg found in signing keys\");\n                    return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                }\n\n                var audience = state.client_id;\n\n                var clockSkewInSeconds = _this6._settings.clockSkew;\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                return _this6._joseUtil.validateJwt(response.id_token, key, issuer, audience, clockSkewInSeconds).then(function () {\n                    _Log.Log.debug(\"ResponseValidator._validateIdToken: JWT validation successful\");\n\n                    if (!jwt.payload.sub) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No sub present in id_token\");\n                        return Promise.reject(new Error(\"No sub present in id_token\"));\n                    }\n\n                    response.profile = jwt.payload;\n\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    ResponseValidator.prototype._validateAccessToken = function _validateAccessToken(response) {\n        if (!response.profile) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No profile loaded from id_token\");\n            return Promise.reject(new Error(\"No profile loaded from id_token\"));\n        }\n\n        if (!response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No at_hash in id_token\");\n            return Promise.reject(new Error(\"No at_hash in id_token\"));\n        }\n\n        if (!response.id_token) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No id_token\");\n            return Promise.reject(new Error(\"No id_token\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        var hashAlg = jwt.header.alg;\n        if (!hashAlg || hashAlg.length !== 5) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var hashBits = hashAlg.substr(2, 3);\n        if (!hashBits) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        hashBits = parseInt(hashBits);\n        if (hashBits !== 256 && hashBits !== 384 && hashBits !== 512) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var sha = \"sha\" + hashBits;\n        var hash = this._joseUtil.hashString(response.access_token, sha);\n        if (!hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: access_token hash failed:\", sha);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        var left = hash.substr(0, hash.length / 2);\n        var left_b64u = this._joseUtil.hexToBase64Url(left);\n        if (left_b64u !== response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to validate at_hash\", left_b64u, response.profile.at_hash);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateAccessToken: success\");\n\n        return Promise.resolve(response);\n    };\n\n    return ResponseValidator;\n}();\n\n/***/ }),\n\n/***/ \"./src/SessionMonitor.js\":\n/*!*******************************!*\\\n  !*** ./src/SessionMonitor.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SessionMonitor = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar SessionMonitor = exports.SessionMonitor = function () {\n    function SessionMonitor(userManager) {\n        var _this = this;\n\n        var CheckSessionIFrameCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _CheckSessionIFrame.CheckSessionIFrame;\n        var timer = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global.timer;\n\n        _classCallCheck(this, SessionMonitor);\n\n        if (!userManager) {\n            _Log.Log.error(\"SessionMonitor.ctor: No user manager passed to SessionMonitor\");\n            throw new Error(\"userManager\");\n        }\n\n        this._userManager = userManager;\n        this._CheckSessionIFrameCtor = CheckSessionIFrameCtor;\n        this._timer = timer;\n\n        this._userManager.events.addUserLoaded(this._start.bind(this));\n        this._userManager.events.addUserUnloaded(this._stop.bind(this));\n\n        this._userManager.getUser().then(function (user) {\n            // doing this manually here since calling getUser \n            // doesn't trigger load event.\n            if (user) {\n                _this._start(user);\n            } else if (_this._settings.monitorAnonymousSession) {\n                _this._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a ctor\n                    _Log.Log.error(\"SessionMonitor ctor: error from querySessionStatus:\", err.message);\n                });\n            }\n        }).catch(function (err) {\n            // catch to suppress errors since we're in a ctor\n            _Log.Log.error(\"SessionMonitor ctor: error from getUser:\", err.message);\n        });\n    }\n\n    SessionMonitor.prototype._start = function _start(user) {\n        var _this2 = this;\n\n        var session_state = user.session_state;\n\n        if (session_state) {\n            if (user.profile) {\n                this._sub = user.profile.sub;\n                this._sid = user.profile.sid;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", sub:\", this._sub);\n            } else {\n                this._sub = undefined;\n                this._sid = undefined;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", anonymous user\");\n            }\n\n            if (!this._checkSessionIFrame) {\n                this._metadataService.getCheckSessionIframe().then(function (url) {\n                    if (url) {\n                        _Log.Log.debug(\"SessionMonitor._start: Initializing check session iframe\");\n\n                        var client_id = _this2._client_id;\n                        var interval = _this2._checkSessionInterval;\n                        var stopOnError = _this2._stopCheckSessionOnError;\n\n                        _this2._checkSessionIFrame = new _this2._CheckSessionIFrameCtor(_this2._callback.bind(_this2), client_id, url, interval, stopOnError);\n                        _this2._checkSessionIFrame.load().then(function () {\n                            _this2._checkSessionIFrame.start(session_state);\n                        });\n                    } else {\n                        _Log.Log.warn(\"SessionMonitor._start: No check session iframe found in the metadata\");\n                    }\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in non-promise callback\n                    _Log.Log.error(\"SessionMonitor._start: Error from getCheckSessionIframe:\", err.message);\n                });\n            } else {\n                this._checkSessionIFrame.start(session_state);\n            }\n        }\n    };\n\n    SessionMonitor.prototype._stop = function _stop() {\n        var _this3 = this;\n\n        this._sub = undefined;\n        this._sid = undefined;\n\n        if (this._checkSessionIFrame) {\n            _Log.Log.debug(\"SessionMonitor._stop\");\n            this._checkSessionIFrame.stop();\n        }\n\n        if (this._settings.monitorAnonymousSession) {\n            // using a timer to delay re-initialization to avoid race conditions during signout\n            var timerHandle = this._timer.setInterval(function () {\n                _this3._timer.clearInterval(timerHandle);\n\n                _this3._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this3._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a callback\n                    _Log.Log.error(\"SessionMonitor: error from querySessionStatus:\", err.message);\n                });\n            }, 1000);\n        }\n    };\n\n    SessionMonitor.prototype._callback = function _callback() {\n        var _this4 = this;\n\n        this._userManager.querySessionStatus().then(function (session) {\n            var raiseEvent = true;\n\n            if (session) {\n                if (session.sub === _this4._sub) {\n                    raiseEvent = false;\n                    _this4._checkSessionIFrame.start(session.session_state);\n\n                    if (session.sid === _this4._sid) {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:\", session.session_state);\n                    } else {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:\", session.session_state);\n                        _this4._userManager.events._raiseUserSessionChanged();\n                    }\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: Different subject signed into OP:\", session.sub);\n                }\n            } else {\n                _Log.Log.debug(\"SessionMonitor._callback: Subject no longer signed into OP\");\n            }\n\n            if (raiseEvent) {\n                if (_this4._sub) {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed out event\");\n                    _this4._userManager.events._raiseUserSignedOut();\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed in event\");\n                    _this4._userManager.events._raiseUserSignedIn();\n                }\n            }\n        }).catch(function (err) {\n            if (_this4._sub) {\n                _Log.Log.debug(\"SessionMonitor._callback: Error calling queryCurrentSigninSession; raising signed out event\", err.message);\n                _this4._userManager.events._raiseUserSignedOut();\n            }\n        });\n    };\n\n    _createClass(SessionMonitor, [{\n        key: '_settings',\n        get: function get() {\n            return this._userManager.settings;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this._userManager.metadataService;\n        }\n    }, {\n        key: '_client_id',\n        get: function get() {\n            return this._settings.client_id;\n        }\n    }, {\n        key: '_checkSessionInterval',\n        get: function get() {\n            return this._settings.checkSessionInterval;\n        }\n    }, {\n        key: '_stopCheckSessionOnError',\n        get: function get() {\n            return this._settings.stopCheckSessionOnError;\n        }\n    }]);\n\n    return SessionMonitor;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninRequest.js\":\n/*!******************************!*\\\n  !*** ./src/SigninRequest.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninRequest = exports.SigninRequest = function () {\n    function SigninRequest(_ref) {\n        var url = _ref.url,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            authority = _ref.authority,\n            data = _ref.data,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            extraQueryParams = _ref.extraQueryParams,\n            request_type = _ref.request_type,\n            client_secret = _ref.client_secret,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninRequest);\n\n        if (!url) {\n            _Log.Log.error(\"SigninRequest.ctor: No url passed\");\n            throw new Error(\"url\");\n        }\n        if (!client_id) {\n            _Log.Log.error(\"SigninRequest.ctor: No client_id passed\");\n            throw new Error(\"client_id\");\n        }\n        if (!redirect_uri) {\n            _Log.Log.error(\"SigninRequest.ctor: No redirect_uri passed\");\n            throw new Error(\"redirect_uri\");\n        }\n        if (!response_type) {\n            _Log.Log.error(\"SigninRequest.ctor: No response_type passed\");\n            throw new Error(\"response_type\");\n        }\n        if (!scope) {\n            _Log.Log.error(\"SigninRequest.ctor: No scope passed\");\n            throw new Error(\"scope\");\n        }\n        if (!authority) {\n            _Log.Log.error(\"SigninRequest.ctor: No authority passed\");\n            throw new Error(\"authority\");\n        }\n\n        var oidc = SigninRequest.isOidc(response_type);\n        var code = SigninRequest.isCode(response_type);\n\n        if (!response_mode) {\n            response_mode = SigninRequest.isCode(response_type) ? \"query\" : null;\n        }\n\n        this.state = new _SigninState.SigninState({ nonce: oidc,\n            data: data, client_id: client_id, authority: authority, redirect_uri: redirect_uri,\n            code_verifier: code,\n            request_type: request_type, response_mode: response_mode,\n            client_secret: client_secret, scope: scope, extraTokenParams: extraTokenParams, skipUserInfo: skipUserInfo });\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"client_id\", client_id);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"redirect_uri\", redirect_uri);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"response_type\", response_type);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"scope\", scope);\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        if (oidc) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"nonce\", this.state.nonce);\n        }\n        if (code) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge\", this.state.code_challenge);\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge_method\", \"S256\");\n        }\n\n        var optional = { prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values, resource: resource, request: request, request_uri: request_uri, response_mode: response_mode };\n        for (var key in optional) {\n            if (optional[key]) {\n                url = _UrlUtility.UrlUtility.addQueryParam(url, key, optional[key]);\n            }\n        }\n\n        for (var _key in extraQueryParams) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, _key, extraQueryParams[_key]);\n        }\n\n        this.url = url;\n    }\n\n    SigninRequest.isOidc = function isOidc(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"id_token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isOAuth = function isOAuth(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isCode = function isCode(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"code\";\n        });\n        return !!result[0];\n    };\n\n    return SigninRequest;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninResponse.js\":\n/*!*******************************!*\\\n  !*** ./src/SigninResponse.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninResponse = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcScope = \"openid\";\n\nvar SigninResponse = exports.SigninResponse = function () {\n    function SigninResponse(url) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n\n        _classCallCheck(this, SigninResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.code = values.code;\n        this.state = values.state;\n        this.id_token = values.id_token;\n        this.session_state = values.session_state;\n        this.access_token = values.access_token;\n        this.token_type = values.token_type;\n        this.scope = values.scope;\n        this.profile = undefined; // will be set from ResponseValidator\n\n        this.expires_in = values.expires_in;\n    }\n\n    _createClass(SigninResponse, [{\n        key: \"expires_in\",\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: \"expired\",\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: \"scopes\",\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }, {\n        key: \"isOpenIdConnect\",\n        get: function get() {\n            return this.scopes.indexOf(OidcScope) >= 0 || !!this.id_token;\n        }\n    }]);\n\n    return SigninResponse;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninState.js\":\n/*!****************************!*\\\n  !*** ./src/SigninState.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninState = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _State2 = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninState = exports.SigninState = function (_State) {\n    _inherits(SigninState, _State);\n\n    function SigninState() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            nonce = _ref.nonce,\n            authority = _ref.authority,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            code_verifier = _ref.code_verifier,\n            response_mode = _ref.response_mode,\n            client_secret = _ref.client_secret,\n            scope = _ref.scope,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninState);\n\n        var _this = _possibleConstructorReturn(this, _State.call(this, arguments[0]));\n\n        if (nonce === true) {\n            _this._nonce = (0, _random2.default)();\n        } else if (nonce) {\n            _this._nonce = nonce;\n        }\n\n        if (code_verifier === true) {\n            // random() produces 32 length\n            _this._code_verifier = (0, _random2.default)() + (0, _random2.default)() + (0, _random2.default)();\n        } else if (code_verifier) {\n            _this._code_verifier = code_verifier;\n        }\n\n        if (_this.code_verifier) {\n            var hash = _JoseUtil.JoseUtil.hashString(_this.code_verifier, \"SHA256\");\n            _this._code_challenge = _JoseUtil.JoseUtil.hexToBase64Url(hash);\n        }\n\n        _this._redirect_uri = redirect_uri;\n        _this._authority = authority;\n        _this._client_id = client_id;\n        _this._response_mode = response_mode;\n        _this._client_secret = client_secret;\n        _this._scope = scope;\n        _this._extraTokenParams = extraTokenParams;\n        _this._skipUserInfo = skipUserInfo;\n        return _this;\n    }\n\n    SigninState.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"SigninState.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type,\n            nonce: this.nonce,\n            code_verifier: this.code_verifier,\n            redirect_uri: this.redirect_uri,\n            authority: this.authority,\n            client_id: this.client_id,\n            response_mode: this.response_mode,\n            client_secret: this.client_secret,\n            scope: this.scope,\n            extraTokenParams: this.extraTokenParams,\n            skipUserInfo: this.skipUserInfo\n        });\n    };\n\n    SigninState.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"SigninState.fromStorageString\");\n        var data = JSON.parse(storageString);\n        return new SigninState(data);\n    };\n\n    _createClass(SigninState, [{\n        key: 'nonce',\n        get: function get() {\n            return this._nonce;\n        }\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        }\n    }, {\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'code_verifier',\n        get: function get() {\n            return this._code_verifier;\n        }\n    }, {\n        key: 'code_challenge',\n        get: function get() {\n            return this._code_challenge;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        }\n    }, {\n        key: 'skipUserInfo',\n        get: function get() {\n            return this._skipUserInfo;\n        }\n    }]);\n\n    return SigninState;\n}(_State2.State);\n\n/***/ }),\n\n/***/ \"./src/SignoutRequest.js\":\n/*!*******************************!*\\\n  !*** ./src/SignoutRequest.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SignoutRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutRequest = exports.SignoutRequest = function SignoutRequest(_ref) {\n    var url = _ref.url,\n        id_token_hint = _ref.id_token_hint,\n        post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n        data = _ref.data,\n        extraQueryParams = _ref.extraQueryParams,\n        request_type = _ref.request_type;\n\n    _classCallCheck(this, SignoutRequest);\n\n    if (!url) {\n        _Log.Log.error(\"SignoutRequest.ctor: No url passed\");\n        throw new Error(\"url\");\n    }\n\n    if (id_token_hint) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"id_token_hint\", id_token_hint);\n    }\n\n    if (post_logout_redirect_uri) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"post_logout_redirect_uri\", post_logout_redirect_uri);\n\n        if (data) {\n            this.state = new _State.State({ data: data, request_type: request_type });\n\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        }\n    }\n\n    for (var key in extraQueryParams) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, key, extraQueryParams[key]);\n    }\n\n    this.url = url;\n};\n\n/***/ }),\n\n/***/ \"./src/SignoutResponse.js\":\n/*!********************************!*\\\n  !*** ./src/SignoutResponse.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.SignoutResponse = undefined;\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutResponse = exports.SignoutResponse = function SignoutResponse(url) {\n        _classCallCheck(this, SignoutResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, \"?\");\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.state = values.state;\n};\n\n/***/ }),\n\n/***/ \"./src/SilentRenewService.js\":\n/*!***********************************!*\\\n  !*** ./src/SilentRenewService.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SilentRenewService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SilentRenewService = exports.SilentRenewService = function () {\n    function SilentRenewService(userManager) {\n        _classCallCheck(this, SilentRenewService);\n\n        this._userManager = userManager;\n    }\n\n    SilentRenewService.prototype.start = function start() {\n        if (!this._callback) {\n            this._callback = this._tokenExpiring.bind(this);\n            this._userManager.events.addAccessTokenExpiring(this._callback);\n\n            // this will trigger loading of the user so the expiring events can be initialized\n            this._userManager.getUser().then(function (user) {\n                // deliberate nop\n            }).catch(function (err) {\n                // catch to suppress errors since we're in a ctor\n                _Log.Log.error(\"SilentRenewService.start: Error from getUser:\", err.message);\n            });\n        }\n    };\n\n    SilentRenewService.prototype.stop = function stop() {\n        if (this._callback) {\n            this._userManager.events.removeAccessTokenExpiring(this._callback);\n            delete this._callback;\n        }\n    };\n\n    SilentRenewService.prototype._tokenExpiring = function _tokenExpiring() {\n        var _this = this;\n\n        this._userManager.signinSilent().then(function (user) {\n            _Log.Log.debug(\"SilentRenewService._tokenExpiring: Silent token renewal successful\");\n        }, function (err) {\n            _Log.Log.error(\"SilentRenewService._tokenExpiring: Error from signinSilent:\", err.message);\n            _this._userManager.events._raiseSilentRenewError(err);\n        });\n    };\n\n    return SilentRenewService;\n}();\n\n/***/ }),\n\n/***/ \"./src/State.js\":\n/*!**********************!*\\\n  !*** ./src/State.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.State = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar State = exports.State = function () {\n    function State() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id = _ref.id,\n            data = _ref.data,\n            created = _ref.created,\n            request_type = _ref.request_type;\n\n        _classCallCheck(this, State);\n\n        this._id = id || (0, _random2.default)();\n        this._data = data;\n\n        if (typeof created === 'number' && created > 0) {\n            this._created = created;\n        } else {\n            this._created = parseInt(Date.now() / 1000);\n        }\n        this._request_type = request_type;\n    }\n\n    State.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"State.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type\n        });\n    };\n\n    State.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"State.fromStorageString\");\n        return new State(JSON.parse(storageString));\n    };\n\n    State.clearStaleState = function clearStaleState(storage, age) {\n\n        var cutoff = Date.now() / 1000 - age;\n\n        return storage.getAllKeys().then(function (keys) {\n            _Log.Log.debug(\"State.clearStaleState: got keys\", keys);\n\n            var promises = [];\n\n            var _loop = function _loop(i) {\n                var key = keys[i];\n                p = storage.get(key).then(function (item) {\n                    var remove = false;\n\n                    if (item) {\n                        try {\n                            var state = State.fromStorageString(item);\n\n                            _Log.Log.debug(\"State.clearStaleState: got item from key: \", key, state.created);\n\n                            if (state.created <= cutoff) {\n                                remove = true;\n                            }\n                        } catch (e) {\n                            _Log.Log.error(\"State.clearStaleState: Error parsing state for key\", key, e.message);\n                            remove = true;\n                        }\n                    } else {\n                        _Log.Log.debug(\"State.clearStaleState: no item in storage for key: \", key);\n                        remove = true;\n                    }\n\n                    if (remove) {\n                        _Log.Log.debug(\"State.clearStaleState: removed item for key: \", key);\n                        return storage.remove(key);\n                    }\n                });\n\n\n                promises.push(p);\n            };\n\n            for (var i = 0; i < keys.length; i++) {\n                var p;\n\n                _loop(i);\n            }\n\n            _Log.Log.debug(\"State.clearStaleState: waiting on promise count:\", promises.length);\n            return Promise.all(promises);\n        });\n    };\n\n    _createClass(State, [{\n        key: 'id',\n        get: function get() {\n            return this._id;\n        }\n    }, {\n        key: 'data',\n        get: function get() {\n            return this._data;\n        }\n    }, {\n        key: 'created',\n        get: function get() {\n            return this._created;\n        }\n    }, {\n        key: 'request_type',\n        get: function get() {\n            return this._request_type;\n        }\n    }]);\n\n    return State;\n}();\n\n/***/ }),\n\n/***/ \"./src/Timer.js\":\n/*!**********************!*\\\n  !*** ./src/Timer.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Timer = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _Event2 = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TimerDuration = 5; // seconds\n\nvar Timer = exports.Timer = function (_Event) {\n    _inherits(Timer, _Event);\n\n    function Timer(name) {\n        var timer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.timer;\n        var nowFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n\n        _classCallCheck(this, Timer);\n\n        var _this = _possibleConstructorReturn(this, _Event.call(this, name));\n\n        _this._timer = timer;\n\n        if (nowFunc) {\n            _this._nowFunc = nowFunc;\n        } else {\n            _this._nowFunc = function () {\n                return Date.now() / 1000;\n            };\n        }\n        return _this;\n    }\n\n    Timer.prototype.init = function init(duration) {\n        if (duration <= 0) {\n            duration = 1;\n        }\n        duration = parseInt(duration);\n\n        var expiration = this.now + duration;\n        if (this.expiration === expiration && this._timerHandle) {\n            // no need to reinitialize to same expiration, so bail out\n            _Log.Log.debug(\"Timer.init timer \" + this._name + \" skipping initialization since already initialized for expiration:\", this.expiration);\n            return;\n        }\n\n        this.cancel();\n\n        _Log.Log.debug(\"Timer.init timer \" + this._name + \" for duration:\", duration);\n        this._expiration = expiration;\n\n        // we're using a fairly short timer and then checking the expiration in the\n        // callback to handle scenarios where the browser device sleeps, and then\n        // the timers end up getting delayed.\n        var timerDuration = TimerDuration;\n        if (duration < timerDuration) {\n            timerDuration = duration;\n        }\n        this._timerHandle = this._timer.setInterval(this._callback.bind(this), timerDuration * 1000);\n    };\n\n    Timer.prototype.cancel = function cancel() {\n        if (this._timerHandle) {\n            _Log.Log.debug(\"Timer.cancel: \", this._name);\n            this._timer.clearInterval(this._timerHandle);\n            this._timerHandle = null;\n        }\n    };\n\n    Timer.prototype._callback = function _callback() {\n        var diff = this._expiration - this.now;\n        _Log.Log.debug(\"Timer.callback; \" + this._name + \" timer expires in:\", diff);\n\n        if (this._expiration <= this.now) {\n            this.cancel();\n            _Event.prototype.raise.call(this);\n        }\n    };\n\n    _createClass(Timer, [{\n        key: 'now',\n        get: function get() {\n            return parseInt(this._nowFunc());\n        }\n    }, {\n        key: 'expiration',\n        get: function get() {\n            return this._expiration;\n        }\n    }]);\n\n    return Timer;\n}(_Event2.Event);\n\n/***/ }),\n\n/***/ \"./src/TokenClient.js\":\n/*!****************************!*\\\n  !*** ./src/TokenClient.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenClient = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TokenClient = exports.TokenClient = function () {\n    function TokenClient(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenClient.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor();\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenClient.prototype.exchangeCode = function exchangeCode() {\n        var _this = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"authorization_code\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.redirect_uri = args.redirect_uri || this._settings.redirect_uri;\n\n        if (!args.code) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code passed\");\n            return Promise.reject(new Error(\"A code is required\"));\n        }\n        if (!args.redirect_uri) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No redirect_uri passed\");\n            return Promise.reject(new Error(\"A redirect_uri is required\"));\n        }\n        if (!args.code_verifier) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code_verifier passed\");\n            return Promise.reject(new Error(\"A code_verifier is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeCode: Received token endpoint\");\n\n            return _this._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeCode: response received\");\n                return response;\n            });\n        });\n    };\n\n    TokenClient.prototype.exchangeRefreshToken = function exchangeRefreshToken() {\n        var _this2 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"refresh_token\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.client_secret = args.client_secret || this._settings.client_secret;\n\n        if (!args.refresh_token) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No refresh_token passed\");\n            return Promise.reject(new Error(\"A refresh_token is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeRefreshToken: Received token endpoint\");\n\n            return _this2._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeRefreshToken: response received\");\n                return response;\n            });\n        });\n    };\n\n    return TokenClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/TokenRevocationClient.js\":\n/*!**************************************!*\\\n  !*** ./src/TokenRevocationClient.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenRevocationClient = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar AccessTokenTypeHint = \"access_token\";\nvar RefreshTokenTypeHint = \"refresh_token\";\n\nvar TokenRevocationClient = exports.TokenRevocationClient = function () {\n    function TokenRevocationClient(settings) {\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenRevocationClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenRevocationClient.ctor: No settings provided\");\n            throw new Error(\"No settings provided.\");\n        }\n\n        this._settings = settings;\n        this._XMLHttpRequestCtor = XMLHttpRequestCtor;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenRevocationClient.prototype.revoke = function revoke(token, required) {\n        var _this = this;\n\n        var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : \"access_token\";\n\n        if (!token) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: No token provided\");\n            throw new Error(\"No token provided.\");\n        }\n\n        if (type !== AccessTokenTypeHint && type != RefreshTokenTypeHint) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: Invalid token type\");\n            throw new Error(\"Invalid token type.\");\n        }\n\n        return this._metadataService.getRevocationEndpoint().then(function (url) {\n            if (!url) {\n                if (required) {\n                    _Log.Log.error(\"TokenRevocationClient.revoke: Revocation not supported\");\n                    throw new Error(\"Revocation not supported\");\n                }\n\n                // not required, so don't error and just return\n                return;\n            }\n\n            _Log.Log.debug(\"TokenRevocationClient.revoke: Revoking \" + type);\n            var client_id = _this._settings.client_id;\n            var client_secret = _this._settings.client_secret;\n            return _this._revoke(url, client_id, client_secret, token, type);\n        });\n    };\n\n    TokenRevocationClient.prototype._revoke = function _revoke(url, client_id, client_secret, token, type) {\n        var _this2 = this;\n\n        return new Promise(function (resolve, reject) {\n\n            var xhr = new _this2._XMLHttpRequestCtor();\n            xhr.open(\"POST\", url);\n\n            xhr.onload = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: HTTP response received, status\", xhr.status);\n\n                if (xhr.status === 200) {\n                    resolve();\n                } else {\n                    reject(Error(xhr.statusText + \" (\" + xhr.status + \")\"));\n                }\n            };\n            xhr.onerror = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: Network Error.\");\n                reject(\"Network Error\");\n            };\n\n            var body = \"client_id=\" + encodeURIComponent(client_id);\n            if (client_secret) {\n                body += \"&client_secret=\" + encodeURIComponent(client_secret);\n            }\n            body += \"&token_type_hint=\" + encodeURIComponent(type);\n            body += \"&token=\" + encodeURIComponent(token);\n\n            xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            xhr.send(body);\n        });\n    };\n\n    return TokenRevocationClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/UrlUtility.js\":\n/*!***************************!*\\\n  !*** ./src/UrlUtility.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UrlUtility = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UrlUtility = exports.UrlUtility = function () {\n    function UrlUtility() {\n        _classCallCheck(this, UrlUtility);\n    }\n\n    UrlUtility.addQueryParam = function addQueryParam(url, name, value) {\n        if (url.indexOf('?') < 0) {\n            url += \"?\";\n        }\n\n        if (url[url.length - 1] !== \"?\") {\n            url += \"&\";\n        }\n\n        url += encodeURIComponent(name);\n        url += \"=\";\n        url += encodeURIComponent(value);\n\n        return url;\n    };\n\n    UrlUtility.parseUrlFragment = function parseUrlFragment(value) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n        var global = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global;\n\n        if (typeof value !== 'string') {\n            value = global.location.href;\n        }\n\n        var idx = value.lastIndexOf(delimiter);\n        if (idx >= 0) {\n            value = value.substr(idx + 1);\n        }\n\n        if (delimiter === \"?\") {\n            // if we're doing query, then strip off hash fragment before we parse\n            idx = value.indexOf('#');\n            if (idx >= 0) {\n                value = value.substr(0, idx);\n            }\n        }\n\n        var params = {},\n            regex = /([^&=]+)=([^&]*)/g,\n            m;\n\n        var counter = 0;\n        while (m = regex.exec(value)) {\n            params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);\n            if (counter++ > 50) {\n                _Log.Log.error(\"UrlUtility.parseUrlFragment: response exceeded expected number of parameters\", value);\n                return {\n                    error: \"Response exceeded expected number of parameters\"\n                };\n            }\n        }\n\n        for (var prop in params) {\n            return params;\n        }\n\n        return {};\n    };\n\n    return UrlUtility;\n}();\n\n/***/ }),\n\n/***/ \"./src/User.js\":\n/*!*********************!*\\\n  !*** ./src/User.js ***!\n  \\*********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.User = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar User = exports.User = function () {\n    function User(_ref) {\n        var id_token = _ref.id_token,\n            session_state = _ref.session_state,\n            access_token = _ref.access_token,\n            refresh_token = _ref.refresh_token,\n            token_type = _ref.token_type,\n            scope = _ref.scope,\n            profile = _ref.profile,\n            expires_at = _ref.expires_at,\n            state = _ref.state;\n\n        _classCallCheck(this, User);\n\n        this.id_token = id_token;\n        this.session_state = session_state;\n        this.access_token = access_token;\n        this.refresh_token = refresh_token;\n        this.token_type = token_type;\n        this.scope = scope;\n        this.profile = profile;\n        this.expires_at = expires_at;\n        this.state = state;\n    }\n\n    User.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"User.toStorageString\");\n        return JSON.stringify({\n            id_token: this.id_token,\n            session_state: this.session_state,\n            access_token: this.access_token,\n            refresh_token: this.refresh_token,\n            token_type: this.token_type,\n            scope: this.scope,\n            profile: this.profile,\n            expires_at: this.expires_at\n        });\n    };\n\n    User.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"User.fromStorageString\");\n        return new User(JSON.parse(storageString));\n    };\n\n    _createClass(User, [{\n        key: 'expires_in',\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: 'expired',\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: 'scopes',\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }]);\n\n    return User;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserInfoService.js\":\n/*!********************************!*\\\n  !*** ./src/UserInfoService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserInfoService = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserInfoService = exports.UserInfoService = function () {\n    function UserInfoService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserInfoService);\n\n        if (!settings) {\n            _Log.Log.error(\"UserInfoService.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(undefined, undefined, this._getClaimsFromJwt.bind(this));\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n    }\n\n    UserInfoService.prototype.getClaims = function getClaims(token) {\n        var _this = this;\n\n        if (!token) {\n            _Log.Log.error(\"UserInfoService.getClaims: No token passed\");\n            return Promise.reject(new Error(\"A token is required\"));\n        }\n\n        return this._metadataService.getUserInfoEndpoint().then(function (url) {\n            _Log.Log.debug(\"UserInfoService.getClaims: received userinfo url\", url);\n\n            return _this._jsonService.getJson(url, token).then(function (claims) {\n                _Log.Log.debug(\"UserInfoService.getClaims: claims received\", claims);\n                return claims;\n            });\n        });\n    };\n\n    UserInfoService.prototype._getClaimsFromJwt = function _getClaimsFromJwt(req) {\n        var _this2 = this;\n\n        try {\n            var jwt = this._joseUtil.parseJwt(req.responseText);\n            if (!jwt || !jwt.header || !jwt.payload) {\n                _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Failed to parse JWT\", jwt);\n                return Promise.reject(new Error(\"Failed to parse id_token\"));\n            }\n\n            var kid = jwt.header.kid;\n\n            var issuerPromise = void 0;\n            switch (this._settings.userInfoJwtIssuer) {\n                case 'OP':\n                    issuerPromise = this._metadataService.getIssuer();\n                    break;\n                case 'ANY':\n                    issuerPromise = Promise.resolve(jwt.payload.iss);\n                    break;\n                default:\n                    issuerPromise = Promise.resolve(this._settings.userInfoJwtIssuer);\n                    break;\n            }\n\n            return issuerPromise.then(function (issuer) {\n                _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received issuer:\" + issuer);\n\n                return _this2._metadataService.getSigningKeys().then(function (keys) {\n                    if (!keys) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No signing keys from metadata\");\n                        return Promise.reject(new Error(\"No signing keys from metadata\"));\n                    }\n\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received signing keys\");\n                    var key = void 0;\n                    if (!kid) {\n                        keys = _this2._filterByAlg(keys, jwt.header.alg);\n\n                        if (keys.length > 1) {\n                            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No kid found in id_token and more than one key found in metadata\");\n                            return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                        } else {\n                            // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                            // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                            key = keys[0];\n                        }\n                    } else {\n                        key = keys.filter(function (key) {\n                            return key.kid === kid;\n                        })[0];\n                    }\n\n                    if (!key) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No key matching kid or alg found in signing keys\");\n                        return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                    }\n\n                    var audience = _this2._settings.client_id;\n\n                    var clockSkewInSeconds = _this2._settings.clockSkew;\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                    return _this2._joseUtil.validateJwt(req.responseText, key, issuer, audience, clockSkewInSeconds, undefined, true).then(function () {\n                        _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: JWT validation successful\");\n                        return jwt.payload;\n                    });\n                });\n            });\n            return;\n        } catch (e) {\n            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Error parsing JWT response\", e.message);\n            reject(e);\n            return;\n        }\n    };\n\n    UserInfoService.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"UserInfoService._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    return UserInfoService;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserManager.js\":\n/*!****************************!*\\\n  !*** ./src/UserManager.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManager = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClient2 = __webpack_require__(/*! ./OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _UserManagerSettings = __webpack_require__(/*! ./UserManagerSettings.js */ \"./src/UserManagerSettings.js\");\n\nvar _User = __webpack_require__(/*! ./User.js */ \"./src/User.js\");\n\nvar _UserManagerEvents = __webpack_require__(/*! ./UserManagerEvents.js */ \"./src/UserManagerEvents.js\");\n\nvar _SilentRenewService = __webpack_require__(/*! ./SilentRenewService.js */ \"./src/SilentRenewService.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManager = exports.UserManager = function (_OidcClient) {\n    _inherits(UserManager, _OidcClient);\n\n    function UserManager() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n        var SilentRenewServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _SilentRenewService.SilentRenewService;\n        var SessionMonitorCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _SessionMonitor.SessionMonitor;\n        var TokenRevocationClientCtor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _TokenRevocationClient.TokenRevocationClient;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n        var joseUtil = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserManager);\n\n        if (!(settings instanceof _UserManagerSettings.UserManagerSettings)) {\n            settings = new _UserManagerSettings.UserManagerSettings(settings);\n        }\n\n        var _this = _possibleConstructorReturn(this, _OidcClient.call(this, settings));\n\n        _this._events = new _UserManagerEvents.UserManagerEvents(settings);\n        _this._silentRenewService = new SilentRenewServiceCtor(_this);\n\n        // order is important for the following properties; these services depend upon the events.\n        if (_this.settings.automaticSilentRenew) {\n            _Log.Log.debug(\"UserManager.ctor: automaticSilentRenew is configured, setting up silent renew\");\n            _this.startSilentRenew();\n        }\n\n        if (_this.settings.monitorSession) {\n            _Log.Log.debug(\"UserManager.ctor: monitorSession is configured, setting up session monitor\");\n            _this._sessionMonitor = new SessionMonitorCtor(_this);\n        }\n\n        _this._tokenRevocationClient = new TokenRevocationClientCtor(_this._settings);\n        _this._tokenClient = new TokenClientCtor(_this._settings);\n        _this._joseUtil = joseUtil;\n        return _this;\n    }\n\n    UserManager.prototype.getUser = function getUser() {\n        var _this2 = this;\n\n        return this._loadUser().then(function (user) {\n            if (user) {\n                _Log.Log.info(\"UserManager.getUser: user loaded\");\n\n                _this2._events.load(user, false);\n\n                return user;\n            } else {\n                _Log.Log.info(\"UserManager.getUser: user not found in storage\");\n                return null;\n            }\n        });\n    };\n\n    UserManager.prototype.removeUser = function removeUser() {\n        var _this3 = this;\n\n        return this.storeUser(null).then(function () {\n            _Log.Log.info(\"UserManager.removeUser: user removed from storage\");\n            _this3._events.unload();\n        });\n    };\n\n    UserManager.prototype.signinRedirect = function signinRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:r\";\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signinStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signinRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signinRedirectCallback = function signinRedirectCallback(url) {\n        return this._signinEnd(url || this._redirectNavigator.url).then(function (user) {\n            if (user.profile && user.profile.sub) {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: successful, signed in sub: \", user.profile.sub);\n            } else {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: no sub\");\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopup = function signinPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:p\";\n        var url = args.redirect_uri || this.settings.popup_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinPopup: No popup_redirect_uri or redirect_uri configured\");\n            return Promise.reject(new Error(\"No popup_redirect_uri or redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.display = \"popup\";\n\n        return this._signin(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopup: signinPopup successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopup: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopupCallback = function signinPopupCallback(url) {\n        return this._signinCallback(url, this._popupNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: no sub\");\n                }\n            }\n\n            return user;\n        }).catch(function (err) {\n            _Log.Log.error( true && err.message);\n        });\n    };\n\n    UserManager.prototype.signinSilent = function signinSilent() {\n        var _this4 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\";\n        // first determine if we have a refresh token, or need to use iframe\n        return this._loadUser().then(function (user) {\n            if (user && user.refresh_token) {\n                args.refresh_token = user.refresh_token;\n                return _this4._useRefreshToken(args);\n            } else {\n                args.id_token_hint = args.id_token_hint || _this4.settings.includeIdTokenInSilentRenew && user && user.id_token;\n                if (user && _this4._settings.validateSubOnSilentRenew) {\n                    _Log.Log.debug(\"UserManager.signinSilent, subject prior to silent renew: \", user.profile.sub);\n                    args.current_sub = user.profile.sub;\n                }\n                return _this4._signinSilentIframe(args);\n            }\n        });\n    };\n\n    UserManager.prototype._useRefreshToken = function _useRefreshToken() {\n        var _this5 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        return this._tokenClient.exchangeRefreshToken(args).then(function (result) {\n            if (!result) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No response returned from token endpoint\");\n                return Promise.reject(\"No response returned from token endpoint\");\n            }\n            if (!result.access_token) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No access token returned from token endpoint\");\n                return Promise.reject(\"No access token returned from token endpoint\");\n            }\n\n            return _this5._loadUser().then(function (user) {\n                if (user) {\n                    var idTokenValidation = Promise.resolve();\n                    if (result.id_token) {\n                        idTokenValidation = _this5._validateIdTokenFromTokenRefreshToken(user.profile, result.id_token);\n                    }\n\n                    return idTokenValidation.then(function () {\n                        _Log.Log.debug(\"UserManager._useRefreshToken: refresh token response success\");\n                        user.id_token = result.id_token;\n                        user.access_token = result.access_token;\n                        user.refresh_token = result.refresh_token || user.refresh_token;\n                        user.expires_in = result.expires_in;\n\n                        return _this5.storeUser(user).then(function () {\n                            _this5._events.load(user);\n                            return user;\n                        });\n                    });\n                } else {\n                    return null;\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._validateIdTokenFromTokenRefreshToken = function _validateIdTokenFromTokenRefreshToken(profile, id_token) {\n        var _this6 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            return _this6._joseUtil.validateJwtAttributes(id_token, issuer, _this6._settings.client_id, _this6._settings.clockSkew).then(function (payload) {\n                if (!payload) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: Failed to validate id_token\");\n                    return Promise.reject(new Error(\"Failed to validate id_token\"));\n                }\n                if (payload.sub !== profile.sub) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: sub in id_token does not match current sub\");\n                    return Promise.reject(new Error(\"sub in id_token does not match current sub\"));\n                }\n                if (payload.auth_time && payload.auth_time !== profile.auth_time) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: auth_time in id_token does not match original auth_time\");\n                    return Promise.reject(new Error(\"auth_time in id_token does not match original auth_time\"));\n                }\n                if (payload.azp && payload.azp !== profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp in id_token does not match original azp\");\n                    return Promise.reject(new Error(\"azp in id_token does not match original azp\"));\n                }\n                if (!payload.azp && profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp not in id_token, but present in original id_token\");\n                    return Promise.reject(new Error(\"azp not in id_token, but present in original id_token\"));\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._signinSilentIframe = function _signinSilentIframe() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinSilent: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = args.prompt || \"none\";\n\n        return this._signin(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilent: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilent: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinSilentCallback = function signinSilentCallback(url) {\n        return this._signinCallback(url, this._iframeNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinCallback = function signinCallback(url) {\n        var _this7 = this;\n\n        return this.readSigninResponseState(url).then(function (_ref) {\n            var state = _ref.state,\n                response = _ref.response;\n\n            if (state.request_type === \"si:r\") {\n                return _this7.signinRedirectCallback(url);\n            }\n            if (state.request_type === \"si:p\") {\n                return _this7.signinPopupCallback(url);\n            }\n            if (state.request_type === \"si:s\") {\n                return _this7.signinSilentCallback(url);\n            }\n            return Promise.reject(new Error(\"invalid response_type in state\"));\n        });\n    };\n\n    UserManager.prototype.signoutCallback = function signoutCallback(url, keepOpen) {\n        var _this8 = this;\n\n        return this.readSignoutResponseState(url).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            if (state) {\n                if (state.request_type === \"so:r\") {\n                    return _this8.signoutRedirectCallback(url);\n                }\n                if (state.request_type === \"so:p\") {\n                    return _this8.signoutPopupCallback(url, keepOpen);\n                }\n                return Promise.reject(new Error(\"invalid response_type in state\"));\n            }\n            return response;\n        });\n    };\n\n    UserManager.prototype.querySessionStatus = function querySessionStatus() {\n        var _this9 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\"; // this acts like a signin silent\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.querySessionStatus: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = \"none\";\n        args.response_type = args.response_type || this.settings.query_status_response_type;\n        args.scope = args.scope || \"openid\";\n        args.skipUserInfo = true;\n\n        return this._signinStart(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (navResponse) {\n            return _this9.processSigninResponse(navResponse.url).then(function (signinResponse) {\n                _Log.Log.debug(\"UserManager.querySessionStatus: got signin response\");\n\n                if (signinResponse.session_state && signinResponse.profile.sub) {\n                    _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for sub: \", signinResponse.profile.sub);\n                    return {\n                        session_state: signinResponse.session_state,\n                        sub: signinResponse.profile.sub,\n                        sid: signinResponse.profile.sid\n                    };\n                } else {\n                    _Log.Log.info(\"querySessionStatus successful, user not authenticated\");\n                }\n            }).catch(function (err) {\n                if (err.session_state && _this9.settings.monitorAnonymousSession) {\n                    if (err.message == \"login_required\" || err.message == \"consent_required\" || err.message == \"interaction_required\" || err.message == \"account_selection_required\") {\n                        _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for anonymous user\");\n                        return {\n                            session_state: err.session_state\n                        };\n                    }\n                }\n\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signin = function _signin(args, navigator) {\n        var _this10 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signinStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this10._signinEnd(navResponse.url, args);\n        });\n    };\n\n    UserManager.prototype._signinStart = function _signinStart(args, navigator) {\n        var _this11 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signinStart: got navigator window handle\");\n\n            return _this11.createSigninRequest(args).then(function (signinRequest) {\n                _Log.Log.debug(\"UserManager._signinStart: got signin request\");\n\n                navigatorParams.url = signinRequest.url;\n                navigatorParams.id = signinRequest.state.id;\n\n                return handle.navigate(navigatorParams);\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signinStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signinEnd = function _signinEnd(url) {\n        var _this12 = this;\n\n        var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n        return this.processSigninResponse(url).then(function (signinResponse) {\n            _Log.Log.debug(\"UserManager._signinEnd: got signin response\");\n\n            var user = new _User.User(signinResponse);\n\n            if (args.current_sub) {\n                if (args.current_sub !== user.profile.sub) {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user does not match user returned from signin. sub from signin: \", user.profile.sub);\n                    return Promise.reject(new Error(\"login_required\"));\n                } else {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user matches user returned from signin\");\n                }\n            }\n\n            return _this12.storeUser(user).then(function () {\n                _Log.Log.debug(\"UserManager._signinEnd: user stored\");\n\n                _this12._events.load(user);\n\n                return user;\n            });\n        });\n    };\n\n    UserManager.prototype._signinCallback = function _signinCallback(url, navigator) {\n        _Log.Log.debug(\"UserManager._signinCallback\");\n        return navigator.callback(url);\n    };\n\n    UserManager.prototype.signoutRedirect = function signoutRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:r\";\n        var postLogoutRedirectUri = args.post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        if (postLogoutRedirectUri) {\n            args.post_logout_redirect_uri = postLogoutRedirectUri;\n        }\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signoutStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signoutRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutRedirectCallback = function signoutRedirectCallback(url) {\n        return this._signoutEnd(url || this._redirectNavigator.url).then(function (response) {\n            _Log.Log.info(\"UserManager.signoutRedirectCallback: successful\");\n            return response;\n        });\n    };\n\n    UserManager.prototype.signoutPopup = function signoutPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:p\";\n        var url = args.post_logout_redirect_uri || this.settings.popup_post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        args.post_logout_redirect_uri = url;\n        args.display = \"popup\";\n        if (args.post_logout_redirect_uri) {\n            // we're putting a dummy entry in here because we\n            // need a unique id from the state for notification\n            // to the parent window, which is necessary if we\n            // plan to return back to the client after signout\n            // and so we can close the popup after signout\n            args.state = args.state || {};\n        }\n\n        return this._signout(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopup: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutPopupCallback = function signoutPopupCallback(url, keepOpen) {\n        if (typeof keepOpen === 'undefined' && typeof url === 'boolean') {\n            keepOpen = url;\n            url = null;\n        }\n\n        var delimiter = '?';\n        return this._popupNavigator.callback(url, keepOpen, delimiter).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopupCallback: successful\");\n        });\n    };\n\n    UserManager.prototype._signout = function _signout(args, navigator) {\n        var _this13 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signoutStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this13._signoutEnd(navResponse.url);\n        });\n    };\n\n    UserManager.prototype._signoutStart = function _signoutStart() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var _this14 = this;\n\n        var navigator = arguments[1];\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signoutStart: got navigator window handle\");\n\n            return _this14._loadUser().then(function (user) {\n                _Log.Log.debug(\"UserManager._signoutStart: loaded current user from storage\");\n\n                var revokePromise = _this14._settings.revokeAccessTokenOnSignout ? _this14._revokeInternal(user) : Promise.resolve();\n                return revokePromise.then(function () {\n\n                    var id_token = args.id_token_hint || user && user.id_token;\n                    if (id_token) {\n                        _Log.Log.debug(\"UserManager._signoutStart: Setting id_token into signout request\");\n                        args.id_token_hint = id_token;\n                    }\n\n                    return _this14.removeUser().then(function () {\n                        _Log.Log.debug(\"UserManager._signoutStart: user removed, creating signout request\");\n\n                        return _this14.createSignoutRequest(args).then(function (signoutRequest) {\n                            _Log.Log.debug(\"UserManager._signoutStart: got signout request\");\n\n                            navigatorParams.url = signoutRequest.url;\n                            if (signoutRequest.state) {\n                                navigatorParams.id = signoutRequest.state.id;\n                            }\n                            return handle.navigate(navigatorParams);\n                        });\n                    });\n                });\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signoutStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signoutEnd = function _signoutEnd(url) {\n        return this.processSignoutResponse(url).then(function (signoutResponse) {\n            _Log.Log.debug(\"UserManager._signoutEnd: got signout response\");\n\n            return signoutResponse;\n        });\n    };\n\n    UserManager.prototype.revokeAccessToken = function revokeAccessToken() {\n        var _this15 = this;\n\n        return this._loadUser().then(function (user) {\n            return _this15._revokeInternal(user, true).then(function (success) {\n                if (success) {\n                    _Log.Log.debug(\"UserManager.revokeAccessToken: removing token properties from user and re-storing\");\n\n                    user.access_token = null;\n                    user.refresh_token = null;\n                    user.expires_at = null;\n                    user.token_type = null;\n\n                    return _this15.storeUser(user).then(function () {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: user stored\");\n                        _this15._events.load(user);\n                    });\n                }\n            });\n        }).then(function () {\n            _Log.Log.info(\"UserManager.revokeAccessToken: access token revoked successfully\");\n        });\n    };\n\n    UserManager.prototype._revokeInternal = function _revokeInternal(user, required) {\n        var _this16 = this;\n\n        if (user) {\n            var access_token = user.access_token;\n            var refresh_token = user.refresh_token;\n\n            return this._revokeAccessTokenInternal(access_token, required).then(function (atSuccess) {\n                return _this16._revokeRefreshTokenInternal(refresh_token, required).then(function (rtSuccess) {\n                    if (!atSuccess && !rtSuccess) {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: no need to revoke due to no token(s), or JWT format\");\n                    }\n\n                    return atSuccess || rtSuccess;\n                });\n            });\n        }\n\n        return Promise.resolve(false);\n    };\n\n    UserManager.prototype._revokeAccessTokenInternal = function _revokeAccessTokenInternal(access_token, required) {\n        // check for JWT vs. reference token\n        if (!access_token || access_token.indexOf('.') >= 0) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(access_token, required).then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype._revokeRefreshTokenInternal = function _revokeRefreshTokenInternal(refresh_token, required) {\n        if (!refresh_token) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(refresh_token, required, \"refresh_token\").then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype.startSilentRenew = function startSilentRenew() {\n        this._silentRenewService.start();\n    };\n\n    UserManager.prototype.stopSilentRenew = function stopSilentRenew() {\n        this._silentRenewService.stop();\n    };\n\n    UserManager.prototype._loadUser = function _loadUser() {\n        return this._userStore.get(this._userStoreKey).then(function (storageString) {\n            if (storageString) {\n                _Log.Log.debug(\"UserManager._loadUser: user storageString loaded\");\n                return _User.User.fromStorageString(storageString);\n            }\n\n            _Log.Log.debug(\"UserManager._loadUser: no user storageString\");\n            return null;\n        });\n    };\n\n    UserManager.prototype.storeUser = function storeUser(user) {\n        if (user) {\n            _Log.Log.debug(\"UserManager.storeUser: storing user\");\n\n            var storageString = user.toStorageString();\n            return this._userStore.set(this._userStoreKey, storageString);\n        } else {\n            _Log.Log.debug(\"storeUser.storeUser: removing user\");\n            return this._userStore.remove(this._userStoreKey);\n        }\n    };\n\n    _createClass(UserManager, [{\n        key: '_redirectNavigator',\n        get: function get() {\n            return this.settings.redirectNavigator;\n        }\n    }, {\n        key: '_popupNavigator',\n        get: function get() {\n            return this.settings.popupNavigator;\n        }\n    }, {\n        key: '_iframeNavigator',\n        get: function get() {\n            return this.settings.iframeNavigator;\n        }\n    }, {\n        key: '_userStore',\n        get: function get() {\n            return this.settings.userStore;\n        }\n    }, {\n        key: 'events',\n        get: function get() {\n            return this._events;\n        }\n    }, {\n        key: '_userStoreKey',\n        get: function get() {\n            return 'user:' + this.settings.authority + ':' + this.settings.client_id;\n        }\n    }]);\n\n    return UserManager;\n}(_OidcClient2.OidcClient);\n\n/***/ }),\n\n/***/ \"./src/UserManagerEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/UserManagerEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _AccessTokenEvents2 = __webpack_require__(/*! ./AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _Event = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManagerEvents = exports.UserManagerEvents = function (_AccessTokenEvents) {\n    _inherits(UserManagerEvents, _AccessTokenEvents);\n\n    function UserManagerEvents(settings) {\n        _classCallCheck(this, UserManagerEvents);\n\n        var _this = _possibleConstructorReturn(this, _AccessTokenEvents.call(this, settings));\n\n        _this._userLoaded = new _Event.Event(\"User loaded\");\n        _this._userUnloaded = new _Event.Event(\"User unloaded\");\n        _this._silentRenewError = new _Event.Event(\"Silent renew error\");\n        _this._userSignedIn = new _Event.Event(\"User signed in\");\n        _this._userSignedOut = new _Event.Event(\"User signed out\");\n        _this._userSessionChanged = new _Event.Event(\"User session changed\");\n        return _this;\n    }\n\n    UserManagerEvents.prototype.load = function load(user) {\n        var raiseEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n        _Log.Log.debug(\"UserManagerEvents.load\");\n        _AccessTokenEvents.prototype.load.call(this, user);\n        if (raiseEvent) {\n            this._userLoaded.raise(user);\n        }\n    };\n\n    UserManagerEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"UserManagerEvents.unload\");\n        _AccessTokenEvents.prototype.unload.call(this);\n        this._userUnloaded.raise();\n    };\n\n    UserManagerEvents.prototype.addUserLoaded = function addUserLoaded(cb) {\n        this._userLoaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserLoaded = function removeUserLoaded(cb) {\n        this._userLoaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addUserUnloaded = function addUserUnloaded(cb) {\n        this._userUnloaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserUnloaded = function removeUserUnloaded(cb) {\n        this._userUnloaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addSilentRenewError = function addSilentRenewError(cb) {\n        this._silentRenewError.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeSilentRenewError = function removeSilentRenewError(cb) {\n        this._silentRenewError.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseSilentRenewError = function _raiseSilentRenewError(e) {\n        _Log.Log.debug(\"UserManagerEvents._raiseSilentRenewError\", e.message);\n        this._silentRenewError.raise(e);\n    };\n\n    UserManagerEvents.prototype.addUserSignedIn = function addUserSignedIn(cb) {\n        this._userSignedIn.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedIn = function removeUserSignedIn(cb) {\n        this._userSignedIn.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedIn = function _raiseUserSignedIn() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedIn\");\n        this._userSignedIn.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSignedOut = function addUserSignedOut(cb) {\n        this._userSignedOut.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedOut = function removeUserSignedOut(cb) {\n        this._userSignedOut.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedOut = function _raiseUserSignedOut() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedOut\");\n        this._userSignedOut.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSessionChanged = function addUserSessionChanged(cb) {\n        this._userSessionChanged.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSessionChanged = function removeUserSessionChanged(cb) {\n        this._userSessionChanged.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSessionChanged = function _raiseUserSessionChanged() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSessionChanged\");\n        this._userSessionChanged.raise();\n    };\n\n    return UserManagerEvents;\n}(_AccessTokenEvents2.AccessTokenEvents);\n\n/***/ }),\n\n/***/ \"./src/UserManagerSettings.js\":\n/*!************************************!*\\\n  !*** ./src/UserManagerSettings.js ***!\n  \\************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerSettings = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings2 = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _RedirectNavigator = __webpack_require__(/*! ./RedirectNavigator.js */ \"./src/RedirectNavigator.js\");\n\nvar _PopupNavigator = __webpack_require__(/*! ./PopupNavigator.js */ \"./src/PopupNavigator.js\");\n\nvar _IFrameNavigator = __webpack_require__(/*! ./IFrameNavigator.js */ \"./src/IFrameNavigator.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60;\nvar DefaultCheckSessionInterval = 2000;\n\nvar UserManagerSettings = exports.UserManagerSettings = function (_OidcClientSettings) {\n    _inherits(UserManagerSettings, _OidcClientSettings);\n\n    function UserManagerSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            popup_redirect_uri = _ref.popup_redirect_uri,\n            popup_post_logout_redirect_uri = _ref.popup_post_logout_redirect_uri,\n            popupWindowFeatures = _ref.popupWindowFeatures,\n            popupWindowTarget = _ref.popupWindowTarget,\n            silent_redirect_uri = _ref.silent_redirect_uri,\n            silentRequestTimeout = _ref.silentRequestTimeout,\n            _ref$automaticSilentR = _ref.automaticSilentRenew,\n            automaticSilentRenew = _ref$automaticSilentR === undefined ? false : _ref$automaticSilentR,\n            _ref$validateSubOnSil = _ref.validateSubOnSilentRenew,\n            validateSubOnSilentRenew = _ref$validateSubOnSil === undefined ? false : _ref$validateSubOnSil,\n            _ref$includeIdTokenIn = _ref.includeIdTokenInSilentRenew,\n            includeIdTokenInSilentRenew = _ref$includeIdTokenIn === undefined ? true : _ref$includeIdTokenIn,\n            _ref$monitorSession = _ref.monitorSession,\n            monitorSession = _ref$monitorSession === undefined ? true : _ref$monitorSession,\n            _ref$monitorAnonymous = _ref.monitorAnonymousSession,\n            monitorAnonymousSession = _ref$monitorAnonymous === undefined ? false : _ref$monitorAnonymous,\n            _ref$checkSessionInte = _ref.checkSessionInterval,\n            checkSessionInterval = _ref$checkSessionInte === undefined ? DefaultCheckSessionInterval : _ref$checkSessionInte,\n            _ref$stopCheckSession = _ref.stopCheckSessionOnError,\n            stopCheckSessionOnError = _ref$stopCheckSession === undefined ? true : _ref$stopCheckSession,\n            query_status_response_type = _ref.query_status_response_type,\n            _ref$revokeAccessToke = _ref.revokeAccessTokenOnSignout,\n            revokeAccessTokenOnSignout = _ref$revokeAccessToke === undefined ? false : _ref$revokeAccessToke,\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$redirectNavigato = _ref.redirectNavigator,\n            redirectNavigator = _ref$redirectNavigato === undefined ? new _RedirectNavigator.RedirectNavigator() : _ref$redirectNavigato,\n            _ref$popupNavigator = _ref.popupNavigator,\n            popupNavigator = _ref$popupNavigator === undefined ? new _PopupNavigator.PopupNavigator() : _ref$popupNavigator,\n            _ref$iframeNavigator = _ref.iframeNavigator,\n            iframeNavigator = _ref$iframeNavigator === undefined ? new _IFrameNavigator.IFrameNavigator() : _ref$iframeNavigator,\n            _ref$userStore = _ref.userStore,\n            userStore = _ref$userStore === undefined ? new _WebStorageStateStore.WebStorageStateStore({ store: _Global.Global.sessionStorage }) : _ref$userStore;\n\n        _classCallCheck(this, UserManagerSettings);\n\n        var _this = _possibleConstructorReturn(this, _OidcClientSettings.call(this, arguments[0]));\n\n        _this._popup_redirect_uri = popup_redirect_uri;\n        _this._popup_post_logout_redirect_uri = popup_post_logout_redirect_uri;\n        _this._popupWindowFeatures = popupWindowFeatures;\n        _this._popupWindowTarget = popupWindowTarget;\n\n        _this._silent_redirect_uri = silent_redirect_uri;\n        _this._silentRequestTimeout = silentRequestTimeout;\n        _this._automaticSilentRenew = automaticSilentRenew;\n        _this._validateSubOnSilentRenew = validateSubOnSilentRenew;\n        _this._includeIdTokenInSilentRenew = includeIdTokenInSilentRenew;\n        _this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        _this._monitorSession = monitorSession;\n        _this._monitorAnonymousSession = monitorAnonymousSession;\n        _this._checkSessionInterval = checkSessionInterval;\n        _this._stopCheckSessionOnError = stopCheckSessionOnError;\n        if (query_status_response_type) {\n            _this._query_status_response_type = query_status_response_type;\n        } else if (arguments[0] && arguments[0].response_type) {\n            _this._query_status_response_type = _SigninRequest.SigninRequest.isOidc(arguments[0].response_type) ? \"id_token\" : \"code\";\n        } else {\n            _this._query_status_response_type = \"id_token\";\n        }\n        _this._revokeAccessTokenOnSignout = revokeAccessTokenOnSignout;\n\n        _this._redirectNavigator = redirectNavigator;\n        _this._popupNavigator = popupNavigator;\n        _this._iframeNavigator = iframeNavigator;\n\n        _this._userStore = userStore;\n        return _this;\n    }\n\n    _createClass(UserManagerSettings, [{\n        key: 'popup_redirect_uri',\n        get: function get() {\n            return this._popup_redirect_uri;\n        }\n    }, {\n        key: 'popup_post_logout_redirect_uri',\n        get: function get() {\n            return this._popup_post_logout_redirect_uri;\n        }\n    }, {\n        key: 'popupWindowFeatures',\n        get: function get() {\n            return this._popupWindowFeatures;\n        }\n    }, {\n        key: 'popupWindowTarget',\n        get: function get() {\n            return this._popupWindowTarget;\n        }\n    }, {\n        key: 'silent_redirect_uri',\n        get: function get() {\n            return this._silent_redirect_uri;\n        }\n    }, {\n        key: 'silentRequestTimeout',\n        get: function get() {\n            return this._silentRequestTimeout;\n        }\n    }, {\n        key: 'automaticSilentRenew',\n        get: function get() {\n            return this._automaticSilentRenew;\n        }\n    }, {\n        key: 'validateSubOnSilentRenew',\n        get: function get() {\n            return this._validateSubOnSilentRenew;\n        }\n    }, {\n        key: 'includeIdTokenInSilentRenew',\n        get: function get() {\n            return this._includeIdTokenInSilentRenew;\n        }\n    }, {\n        key: 'accessTokenExpiringNotificationTime',\n        get: function get() {\n            return this._accessTokenExpiringNotificationTime;\n        }\n    }, {\n        key: 'monitorSession',\n        get: function get() {\n            return this._monitorSession;\n        }\n    }, {\n        key: 'monitorAnonymousSession',\n        get: function get() {\n            return this._monitorAnonymousSession;\n        }\n    }, {\n        key: 'checkSessionInterval',\n        get: function get() {\n            return this._checkSessionInterval;\n        }\n    }, {\n        key: 'stopCheckSessionOnError',\n        get: function get() {\n            return this._stopCheckSessionOnError;\n        }\n    }, {\n        key: 'query_status_response_type',\n        get: function get() {\n            return this._query_status_response_type;\n        }\n    }, {\n        key: 'revokeAccessTokenOnSignout',\n        get: function get() {\n            return this._revokeAccessTokenOnSignout;\n        }\n    }, {\n        key: 'redirectNavigator',\n        get: function get() {\n            return this._redirectNavigator;\n        }\n    }, {\n        key: 'popupNavigator',\n        get: function get() {\n            return this._popupNavigator;\n        }\n    }, {\n        key: 'iframeNavigator',\n        get: function get() {\n            return this._iframeNavigator;\n        }\n    }, {\n        key: 'userStore',\n        get: function get() {\n            return this._userStore;\n        }\n    }]);\n\n    return UserManagerSettings;\n}(_OidcClientSettings2.OidcClientSettings);\n\n/***/ }),\n\n/***/ \"./src/WebStorageStateStore.js\":\n/*!*************************************!*\\\n  !*** ./src/WebStorageStateStore.js ***!\n  \\*************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.WebStorageStateStore = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar WebStorageStateStore = exports.WebStorageStateStore = function () {\n    function WebStorageStateStore() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$prefix = _ref.prefix,\n            prefix = _ref$prefix === undefined ? \"oidc.\" : _ref$prefix,\n            _ref$store = _ref.store,\n            store = _ref$store === undefined ? _Global.Global.localStorage : _ref$store;\n\n        _classCallCheck(this, WebStorageStateStore);\n\n        this._store = store;\n        this._prefix = prefix;\n    }\n\n    WebStorageStateStore.prototype.set = function set(key, value) {\n        _Log.Log.debug(\"WebStorageStateStore.set\", key);\n\n        key = this._prefix + key;\n\n        this._store.setItem(key, value);\n\n        return Promise.resolve();\n    };\n\n    WebStorageStateStore.prototype.get = function get(key) {\n        _Log.Log.debug(\"WebStorageStateStore.get\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.remove = function remove(key) {\n        _Log.Log.debug(\"WebStorageStateStore.remove\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n        this._store.removeItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.getAllKeys = function getAllKeys() {\n        _Log.Log.debug(\"WebStorageStateStore.getAllKeys\");\n\n        var keys = [];\n\n        for (var index = 0; index < this._store.length; index++) {\n            var key = this._store.key(index);\n\n            if (key.indexOf(this._prefix) === 0) {\n                keys.push(key.substr(this._prefix.length));\n            }\n        }\n\n        return Promise.resolve(keys);\n    };\n\n    return WebStorageStateStore;\n}();\n\n/***/ }),\n\n/***/ \"./src/crypto/jsrsasign.js\":\n/*!*********************************!*\\\n  !*** ./src/crypto/jsrsasign.js ***!\n  \\*********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AllowedSigningAlgs = exports.b64tohex = exports.hextob64u = exports.crypto = exports.X509 = exports.KeyUtil = exports.jws = undefined;\n\nvar _jsrsasign = __webpack_require__(/*! ../../jsrsasign/dist/jsrsasign.js */ \"./jsrsasign/dist/jsrsasign.js\");\n\nvar AllowedSigningAlgs = ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'ES256', 'ES384', 'ES512'];\n\nexports.jws = _jsrsasign.jws;\nexports.KeyUtil = _jsrsasign.KEYUTIL;\nexports.X509 = _jsrsasign.X509;\nexports.crypto = _jsrsasign.crypto;\nexports.hextob64u = _jsrsasign.hextob64u;\nexports.b64tohex = _jsrsasign.b64tohex;\nexports.AllowedSigningAlgs = AllowedSigningAlgs;\n\n/***/ }),\n\n/***/ \"./src/random.js\":\n/*!***********************!*\\\n  !*** ./src/random.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = random;\n\nvar _v = __webpack_require__(/*! uuid/v4 */ \"./node_modules/uuid/v4.js\");\n\nvar _v2 = _interopRequireDefault(_v);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Generates RFC4122 version 4 guid ()\n */\n\nfunction random() {\n  return (0, _v2.default)().replace(/-/g, '');\n}\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./version.js\":\n/*!********************!*\\\n  !*** ./version.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nvar Version = \"1.10.1\";exports.Version = Version;\n\n/***/ }),\n\n/***/ 0:\n/*!***************************************!*\\\n  !*** multi babel-polyfill ./index.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! babel-polyfill */\"./node_modules/babel-polyfill/lib/index.js\");\nmodule.exports = __webpack_require__(/*! ./index.js */\"./index.js\");\n\n\n/***/ })\n\n/******/ });\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9PaWRjL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL09pZGMvLi9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vanNyc2FzaWduL2Rpc3QvanNyc2FzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbGliL2luZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vcmVnZXhwL2VzY2FwZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1udW1iZXItdmFsdWUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYWR2YW5jZS1zdHJpbmctaW5kZXguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLWluc3RhbmNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWNvcHktd2l0aGluLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1maWxsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1mcm9tLWl0ZXJhYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1pbmNsdWRlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktcmVkdWNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYmluZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi10by1qc29uLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXdlYWsuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvcmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kYXRlLXRvLWlzby1zdHJpbmcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RhdGUtdG8tcHJpbWl0aXZlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1idWcta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1rZXlzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLWlzLXJlZ2V4cC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZpeC1yZS13a3MuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZsYWdzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mbGF0dGVuLWludG8tYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZnVuY3Rpb24tdG8tc3RyaW5nLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWludGVnZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtcmVnZXhwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWZyb3VuZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1sb2cxcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zY2FsZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWljcm90YXNrLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19uZXctcHJvbWlzZS1jYXBhYmlsaXR5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1mb3JjZWQtcGFtLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4tZXh0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXNhcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXRvLWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vd24ta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGFyc2UtZmxvYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWludC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGVyZm9ybS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvbWlzZS1yZXNvbHZlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWdleHAtZXhlYy1hYnN0cmFjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVnZXhwLWV4ZWMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlcGxhY2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zYW1lLXZhbHVlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtY29sbGVjdGlvbi1mcm9tLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtY29sbGVjdGlvbi1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC1rZXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWF0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctY29udGV4dC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1wYWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1yZXBlYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy10cmltLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctd3MuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWFic29sdXRlLWluZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWJ1ZmZlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3VpZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdXNlci1hZ2VudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdmFsaWRhdGUtY29sbGVjdGlvbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWV4dC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9jb3JlLnJlZ2V4cC5lc2NhcGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmNvcHktd2l0aGluLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5ldmVyeS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsdGVyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLWluZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5mb3ItZWFjaC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZnJvbS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaW5kZXgtb2YuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmlzLWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuam9pbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubGFzdC1pbmRleC1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubWFwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlLXJpZ2h0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNsaWNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zb21lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zb3J0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLm5vdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1pc28tc3RyaW5nLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLWpzb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tcHJpbWl0aXZlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLXN0cmluZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZnVuY3Rpb24uaGFzLWluc3RhbmNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYWNvc2guanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYXNpbmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYXRhbmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguY2JydC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jbHozMi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jb3NoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmV4cG0xLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmZyb3VuZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5oeXBvdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5pbXVsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzEwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzFwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguc2lnbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5zaW5oLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnRhbmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgudHJ1bmMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmVwc2lsb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1maW5pdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1pbnRlZ2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtbmFuLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtc2FmZS1pbnRlZ2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIubWF4LXNhZmUtaW50ZWdlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLm1pbi1zYWZlLWludGVnZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnBhcnNlLWludC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnRvLWZpeGVkLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIudG8tcHJlY2lzaW9uLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5kZWZpbmUtcHJvcGVydHkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5mcmVlemUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LW5hbWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LXByb3RvdHlwZS1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLWV4dGVuc2libGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1mcm96ZW4uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1zZWFsZWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmtleXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5wcmV2ZW50LWV4dGVuc2lvbnMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3Quc2V0LXByb3RvdHlwZS1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtZmxvYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnBhcnNlLWludC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5hcHBseS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5jb25zdHJ1Y3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVmaW5lLXByb3BlcnR5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlbGV0ZS1wcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5lbnVtZXJhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0Lmhhcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5pcy1leHRlbnNpYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0Lm93bi1rZXlzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnByZXZlbnQtZXh0ZW5zaW9ucy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5zZXQtcHJvdG90eXBlLW9mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLmNvbnN0cnVjdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuZXhlYy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLmZsYWdzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAubWF0Y2guanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5yZXBsYWNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuc2VhcmNoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuc3BsaXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC50by1zdHJpbmcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnNldC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJpZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJsaW5rLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuYm9sZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmNvZGUtcG9pbnQtYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5lbmRzLXdpdGguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5maXhlZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRjb2xvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRzaXplLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZnJvbS1jb2RlLXBvaW50LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaW5jbHVkZXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGFsaWNzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5saW5rLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcucmF3LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcucmVwZWF0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc21hbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdGFydHMtd2l0aC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN0cmlrZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN1Yi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN1cC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN5bWJvbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuYXJyYXktYnVmZmVyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5kYXRhLXZpZXcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0MzItYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0NjQtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmludDE2LWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQzMi1hcnJheS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50OC1hcnJheS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDE2LWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50MzItYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQ4LWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi53ZWFrLW1hcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1zZXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LmFycmF5LmZsYXQtbWFwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hcnJheS5mbGF0dGVuLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuYXNhcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuZXJyb3IuaXMtZXJyb3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lmdsb2JhbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWFwLmZyb20uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hcC5vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWFwLnRvLWpzb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguY2xhbXAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguZGVnLXBlci1yYWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguZGVncmVlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5mc2NhbGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaWFkZGguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaW11bGguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaXN1YmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGgucmFkLXBlci1kZWcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGgucmFkaWFucy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5zY2FsZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5zaWduYml0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXRoLnVtdWxoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QuZGVmaW5lLWdldHRlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5lbnRyaWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9ycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5sb29rdXAtc2V0dGVyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QudmFsdWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYnNlcnZhYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5wcm9taXNlLmZpbmFsbHkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnByb21pc2UudHJ5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlZmluZS1tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5kZWxldGUtbWV0YWRhdGEuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLWtleXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1vd24tbWV0YWRhdGEta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0Lmhhcy1tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5oYXMtb3duLW1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0Lm1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zZXQuZnJvbS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc2V0Lm9mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zZXQudG8tanNvbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLmF0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcubWF0Y2gtYWxsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tbGVmdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tcmlnaHQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5bWJvbC5hc3luYy1pdGVyYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3ltYm9sLm9ic2VydmFibGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LndlYWstbWFwLmZyb20uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LndlYWstbWFwLm9mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy53ZWFrLXNldC5mcm9tLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy53ZWFrLXNldC5vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL3dlYi5pbW1lZGlhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLnRpbWVycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvc2hpbS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy91dWlkL2xpYi9ieXRlc1RvVXVpZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9PaWRjLyh3ZWJwYWNrKS9idWlsZGluL2dsb2JhbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0FjY2Vzc1Rva2VuRXZlbnRzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvQ2hlY2tTZXNzaW9uSUZyYW1lLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvQ29yZG92YUlGcmFtZU5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0NvcmRvdmFQb3B1cE5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0NvcmRvdmFQb3B1cFdpbmRvdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0Vycm9yUmVzcG9uc2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9FdmVudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0dsb2JhbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0lGcmFtZU5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0lGcmFtZVdpbmRvdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0luTWVtb3J5V2ViU3RvcmFnZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0pvc2VVdGlsLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSm9zZVV0aWxJbXBsLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSnNvblNlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Mb2cuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9NZXRhZGF0YVNlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9PaWRjQ2xpZW50LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvT2lkY0NsaWVudFNldHRpbmdzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvUG9wdXBOYXZpZ2F0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Qb3B1cFdpbmRvdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1JlZGlyZWN0TmF2aWdhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvUmVzcG9uc2VWYWxpZGF0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TZXNzaW9uTW9uaXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpZ25pblJlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWduaW5SZXNwb25zZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpZ25pblN0YXRlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2lnbm91dFJlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWdub3V0UmVzcG9uc2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWxlbnRSZW5ld1NlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TdGF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1RpbWVyLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVG9rZW5DbGllbnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Ub2tlblJldm9jYXRpb25DbGllbnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9VcmxVdGlsaXR5LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXNlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VzZXJJbmZvU2VydmljZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VzZXJNYW5hZ2VyLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXNlck1hbmFnZXJFdmVudHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Vc2VyTWFuYWdlclNldHRpbmdzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9jcnlwdG8vanNyc2FzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvcmFuZG9tLmpzIiwid2VicGFjazovL09pZGMvLi92ZXJzaW9uLmpzIl0sIm5hbWVzIjpbIlZlcnNpb24iLCJMb2ciLCJPaWRjQ2xpZW50IiwiT2lkY0NsaWVudFNldHRpbmdzIiwiV2ViU3RvcmFnZVN0YXRlU3RvcmUiLCJJbk1lbW9yeVdlYlN0b3JhZ2UiLCJVc2VyTWFuYWdlciIsIkFjY2Vzc1Rva2VuRXZlbnRzIiwiTWV0YWRhdGFTZXJ2aWNlIiwiQ29yZG92YVBvcHVwTmF2aWdhdG9yIiwiQ29yZG92YUlGcmFtZU5hdmlnYXRvciIsIkNoZWNrU2Vzc2lvbklGcmFtZSIsIlRva2VuUmV2b2NhdGlvbkNsaWVudCIsIlNlc3Npb25Nb25pdG9yIiwiR2xvYmFsIiwiVXNlciIsIm5hdmlnYXRvciIsInVzZXJBZ2VudCIsIndpbmRvdyIsIllBSE9PIiwidW5kZWZpbmVkIiwibGFuZyIsImV4dGVuZCIsImciLCJoIiwiZiIsIkVycm9yIiwiZCIsInByb3RvdHlwZSIsImNvbnN0cnVjdG9yIiwic3VwZXJjbGFzcyIsIk9iamVjdCIsImIiLCJlIiwiYyIsInRlc3QiLCJqIiwiaSIsImxlbmd0aCIsImwiLCJrIiwiYSIsIkNyeXB0b0pTIiwibGliIiwiQmFzZSIsIm4iLCJwIiwibyIsIm1peEluIiwiaGFzT3duUHJvcGVydHkiLCJpbml0IiwiJHN1cGVyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJjcmVhdGUiLCJ0b1N0cmluZyIsImNsb25lIiwiV29yZEFycmF5Iiwid29yZHMiLCJzaWdCeXRlcyIsInN0cmluZ2lmeSIsImNvbmNhdCIsInQiLCJxIiwicyIsImNsYW1wIiwiciIsImNlaWwiLCJjYWxsIiwic2xpY2UiLCJyYW5kb20iLCJwdXNoIiwibSIsImVuYyIsIkhleCIsImpvaW4iLCJwYXJzZSIsInBhcnNlSW50Iiwic3Vic3RyIiwiTGF0aW4xIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiY2hhckNvZGVBdCIsIlV0ZjgiLCJkZWNvZGVVUklDb21wb25lbnQiLCJlc2NhcGUiLCJ1bmVzY2FwZSIsImVuY29kZVVSSUNvbXBvbmVudCIsIkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0iLCJyZXNldCIsIl9kYXRhIiwiX25EYXRhQnl0ZXMiLCJfYXBwZW5kIiwiX3Byb2Nlc3MiLCJ3IiwieCIsImJsb2NrU2l6ZSIsInYiLCJ1IiwibWF4IiwiX21pbkJ1ZmZlclNpemUiLCJtaW4iLCJfZG9Qcm9jZXNzQmxvY2siLCJzcGxpY2UiLCJIYXNoZXIiLCJjZmciLCJfZG9SZXNldCIsInVwZGF0ZSIsImZpbmFsaXplIiwiX2RvRmluYWxpemUiLCJfY3JlYXRlSGVscGVyIiwiX2NyZWF0ZUhtYWNIZWxwZXIiLCJITUFDIiwiYWxnbyIsIk1hdGgiLCJ4NjQiLCJXb3JkIiwiaGlnaCIsImxvdyIsInRvWDMyIiwiQmFzZTY0IiwiX21hcCIsImNoYXJBdCIsImluZGV4T2YiLCJzcXJ0IiwicG93IiwiU0hBMjU2IiwiX2hhc2giLCJmbG9vciIsIkhtYWNTSEEyNTYiLCJUIiwiZWEiLCJTSEE1MTIiLCJGIiwiRyIsIkgiLCJJIiwiSiIsIlgiLCJLIiwiWSIsIkwiLCJaIiwiTSIsIiQiLCJOIiwiYWEiLCJPIiwiYmEiLCJQIiwiY2EiLCJRIiwieiIsIkEiLCJ5IiwiVSIsIkIiLCJSIiwiQyIsIlMiLCJEIiwiViIsIkUiLCJXIiwiZmEiLCJkYSIsIkhtYWNTSEE1MTIiLCJTSEEzODQiLCJIbWFjU0hBMzg0IiwiYjY0bWFwIiwiYjY0cGFkIiwiaGV4MmI2NCIsInN1YnN0cmluZyIsImI2NHRvaGV4IiwiaW50MmNoYXIiLCJiNjR0b0JBIiwiQXJyYXkiLCJkYml0cyIsImNhbmFyeSIsImpfbG0iLCJCaWdJbnRlZ2VyIiwiZnJvbU51bWJlciIsImZyb21TdHJpbmciLCJuYmkiLCJhbTEiLCJhbTIiLCJhbTMiLCJhcHBOYW1lIiwiYW0iLCJEQiIsIkRNIiwiRFYiLCJCSV9GUCIsIkZWIiwiRjEiLCJGMiIsIkJJX1JNIiwiQklfUkMiLCJyciIsInZ2IiwiaW50QXQiLCJibnBDb3B5VG8iLCJibnBGcm9tSW50IiwibmJ2IiwiZnJvbUludCIsImJucEZyb21TdHJpbmciLCJmcm9tUmFkaXgiLCJaRVJPIiwic3ViVG8iLCJibnBDbGFtcCIsImJuVG9TdHJpbmciLCJuZWdhdGUiLCJ0b1JhZGl4IiwiYm5OZWdhdGUiLCJibkFicyIsImJuQ29tcGFyZVRvIiwibmJpdHMiLCJibkJpdExlbmd0aCIsImJucERMU2hpZnRUbyIsImJucERSU2hpZnRUbyIsImJucExTaGlmdFRvIiwiYm5wUlNoaWZ0VG8iLCJibnBTdWJUbyIsImJucE11bHRpcGx5VG8iLCJhYnMiLCJibnBTcXVhcmVUbyIsImJucERpdlJlbVRvIiwiY29weVRvIiwibFNoaWZ0VG8iLCJkbFNoaWZ0VG8iLCJjb21wYXJlVG8iLCJPTkUiLCJkclNoaWZ0VG8iLCJyU2hpZnRUbyIsImJuTW9kIiwiZGl2UmVtVG8iLCJDbGFzc2ljIiwiY0NvbnZlcnQiLCJtb2QiLCJjUmV2ZXJ0IiwiY1JlZHVjZSIsImNNdWxUbyIsIm11bHRpcGx5VG8iLCJyZWR1Y2UiLCJjU3FyVG8iLCJzcXVhcmVUbyIsImNvbnZlcnQiLCJyZXZlcnQiLCJtdWxUbyIsInNxclRvIiwiYm5wSW52RGlnaXQiLCJNb250Z29tZXJ5IiwibXAiLCJpbnZEaWdpdCIsIm1wbCIsIm1waCIsInVtIiwibXQyIiwibW9udENvbnZlcnQiLCJtb250UmV2ZXJ0IiwibW9udFJlZHVjZSIsIm1vbnRTcXJUbyIsIm1vbnRNdWxUbyIsImJucElzRXZlbiIsImJucEV4cCIsImJuTW9kUG93SW50IiwiaXNFdmVuIiwiZXhwIiwiYml0TGVuZ3RoIiwibW9kUG93SW50IiwiYm5DbG9uZSIsImJuSW50VmFsdWUiLCJibkJ5dGVWYWx1ZSIsImJuU2hvcnRWYWx1ZSIsImJucENodW5rU2l6ZSIsIkxOMiIsImxvZyIsImJuU2lnTnVtIiwiYm5wVG9SYWRpeCIsInNpZ251bSIsImNodW5rU2l6ZSIsImludFZhbHVlIiwiYm5wRnJvbVJhZGl4IiwiZE11bHRpcGx5IiwiZEFkZE9mZnNldCIsImJucEZyb21OdW1iZXIiLCJ0ZXN0Qml0IiwiYml0d2lzZVRvIiwic2hpZnRMZWZ0Iiwib3Bfb3IiLCJpc1Byb2JhYmxlUHJpbWUiLCJuZXh0Qnl0ZXMiLCJiblRvQnl0ZUFycmF5IiwiYm5FcXVhbHMiLCJibk1pbiIsImJuTWF4IiwiYm5wQml0d2lzZVRvIiwib3BfYW5kIiwiYm5BbmQiLCJibk9yIiwib3BfeG9yIiwiYm5Yb3IiLCJvcF9hbmRub3QiLCJibkFuZE5vdCIsImJuTm90IiwiYm5TaGlmdExlZnQiLCJiblNoaWZ0UmlnaHQiLCJsYml0IiwiYm5HZXRMb3dlc3RTZXRCaXQiLCJjYml0IiwiYm5CaXRDb3VudCIsImJuVGVzdEJpdCIsImJucENoYW5nZUJpdCIsImJuU2V0Qml0IiwiY2hhbmdlQml0IiwiYm5DbGVhckJpdCIsImJuRmxpcEJpdCIsImJucEFkZFRvIiwiYm5BZGQiLCJhZGRUbyIsImJuU3VidHJhY3QiLCJibk11bHRpcGx5IiwiYm5TcXVhcmUiLCJibkRpdmlkZSIsImJuUmVtYWluZGVyIiwiYm5EaXZpZGVBbmRSZW1haW5kZXIiLCJibnBETXVsdGlwbHkiLCJibnBEQWRkT2Zmc2V0IiwiTnVsbEV4cCIsIm5Ob3AiLCJuTXVsVG8iLCJuU3FyVG8iLCJiblBvdyIsImJucE11bHRpcGx5TG93ZXJUbyIsImJucE11bHRpcGx5VXBwZXJUbyIsIkJhcnJldHQiLCJyMiIsInEzIiwibXUiLCJkaXZpZGUiLCJiYXJyZXR0Q29udmVydCIsImJhcnJldHRSZXZlcnQiLCJiYXJyZXR0UmVkdWNlIiwibXVsdGlwbHlVcHBlclRvIiwibXVsdGlwbHlMb3dlclRvIiwiYmFycmV0dFNxclRvIiwiYmFycmV0dE11bFRvIiwiYm5Nb2RQb3ciLCJibkdDRCIsImdldExvd2VzdFNldEJpdCIsImJucE1vZEludCIsImJuTW9kSW52ZXJzZSIsInN1YnRyYWN0IiwiYWRkIiwibG93cHJpbWVzIiwibHBsaW0iLCJibklzUHJvYmFibGVQcmltZSIsIm1vZEludCIsIm1pbGxlclJhYmluIiwiYm5wTWlsbGVyUmFiaW4iLCJzaGlmdFJpZ2h0IiwibW9kUG93IiwiYnl0ZVZhbHVlIiwic2hvcnRWYWx1ZSIsInRvQnl0ZUFycmF5IiwiZXF1YWxzIiwiYW5kIiwib3IiLCJ4b3IiLCJhbmROb3QiLCJub3QiLCJiaXRDb3VudCIsInNldEJpdCIsImNsZWFyQml0IiwiZmxpcEJpdCIsIm11bHRpcGx5IiwicmVtYWluZGVyIiwiZGl2aWRlQW5kUmVtYWluZGVyIiwibW9kSW52ZXJzZSIsImdjZCIsInNxdWFyZSIsIkFyY2ZvdXIiLCJBUkM0aW5pdCIsIkFSQzRuZXh0IiwibmV4dCIsInBybmdfbmV3c3RhdGUiLCJybmdfcHNpemUiLCJybmdfc3RhdGUiLCJybmdfcG9vbCIsInJuZ19wcHRyIiwicm5nX3NlZWRfaW50Iiwicm5nX3NlZWRfdGltZSIsIkRhdGUiLCJnZXRUaW1lIiwiY3J5cHRvIiwibXNDcnlwdG8iLCJnZXRSYW5kb21WYWx1ZXMiLCJ1YSIsIlVpbnQ4QXJyYXkiLCJhcHBWZXJzaW9uIiwicm5nX2dldF9ieXRlIiwicm5nX2dldF9ieXRlcyIsIlNlY3VyZVJhbmRvbSIsInBhcnNlQmlnSW50IiwibGluZWJyayIsImJ5dGUySGV4IiwicGtjczFwYWQyIiwib2FlcF9tZ2YxX2FyciIsIm9hZXBfcGFkIiwiS0pVUiIsIk1lc3NhZ2VEaWdlc3QiLCJVdGlsIiwiZ2V0Q2Fub25pY2FsQWxnTmFtZSIsImdldEhhc2hMZW5ndGgiLCJoZXh0b3JzdHIiLCJoYXNoSGV4IiwicnN0cnRvaGV4IiwiUlNBS2V5IiwiZG1wMSIsImRtcTEiLCJjb2VmZiIsIlJTQVNldFB1YmxpYyIsImlzUHVibGljIiwiaXNQcml2YXRlIiwiUlNBRG9QdWJsaWMiLCJSU0FFbmNyeXB0IiwiZG9QdWJsaWMiLCJSU0FFbmNyeXB0T0FFUCIsInNldFB1YmxpYyIsImVuY3J5cHQiLCJlbmNyeXB0T0FFUCIsInR5cGUiLCJFQ0ZpZWxkRWxlbWVudEZwIiwiZmVGcEVxdWFscyIsImZlRnBUb0JpZ0ludGVnZXIiLCJmZUZwTmVnYXRlIiwiZmVGcEFkZCIsInRvQmlnSW50ZWdlciIsImZlRnBTdWJ0cmFjdCIsImZlRnBNdWx0aXBseSIsImZlRnBTcXVhcmUiLCJmZUZwRGl2aWRlIiwiRUNQb2ludEZwIiwiY3VydmUiLCJ6aW52IiwicG9pbnRGcEdldFgiLCJmcm9tQmlnSW50ZWdlciIsInBvaW50RnBHZXRZIiwicG9pbnRGcEVxdWFscyIsImlzSW5maW5pdHkiLCJwb2ludEZwSXNJbmZpbml0eSIsInBvaW50RnBOZWdhdGUiLCJwb2ludEZwQWRkIiwidHdpY2UiLCJnZXRJbmZpbml0eSIsInBvaW50RnBUd2ljZSIsInBvaW50RnBNdWx0aXBseSIsInBvaW50RnBNdWx0aXBseVR3byIsImdldFgiLCJnZXRZIiwibXVsdGlwbHlUd28iLCJFQ0N1cnZlRnAiLCJpbmZpbml0eSIsImN1cnZlRnBHZXRRIiwiY3VydmVGcEdldEEiLCJjdXJ2ZUZwR2V0QiIsImN1cnZlRnBFcXVhbHMiLCJjdXJ2ZUZwR2V0SW5maW5pdHkiLCJjdXJ2ZUZwRnJvbUJpZ0ludGVnZXIiLCJjdXJ2ZUZwRGVjb2RlUG9pbnRIZXgiLCJnZXRRIiwiZ2V0QSIsImdldEIiLCJkZWNvZGVQb2ludEhleCIsImdldEJ5dGVMZW5ndGgiLCJnZXRFbmNvZGVkIiwidG9CeXRlQXJyYXlVbnNpZ25lZCIsInVuc2hpZnQiLCJkZWNvZGVGcm9tIiwiZGVjb2RlRnJvbUhleCIsImFkZDJEIiwidHdpY2UyRCIsInZhbHVlT2YiLCJtdWx0aXBseTJEIiwiaXNPbkN1cnZlIiwidmFsaWRhdGUiLCJqc29uUGFyc2UiLCJSZWdFeHAiLCJtYXRjaCIsInJlcGxhY2UiLCJzaGlmdCIsImFzbjEiLCJBU04xVXRpbCIsImludGVnZXJUb0J5dGVIZXgiLCJiaWdJbnRUb01pblR3b3NDb21wbGVtZW50c0hleCIsImdldFBFTVN0cmluZ0Zyb21IZXgiLCJoZXh0b3BlbSIsIm5ld09iamVjdCIsIkRFUkJvb2xlYW4iLCJERVJJbnRlZ2VyIiwiREVSQml0U3RyaW5nIiwiREVST2N0ZXRTdHJpbmciLCJERVJOdWxsIiwiREVST2JqZWN0SWRlbnRpZmllciIsIkRFUkVudW1lcmF0ZWQiLCJERVJVVEY4U3RyaW5nIiwiREVSTnVtZXJpY1N0cmluZyIsIkRFUlByaW50YWJsZVN0cmluZyIsIkRFUlRlbGV0ZXhTdHJpbmciLCJERVJJQTVTdHJpbmciLCJERVJVVENUaW1lIiwiREVSR2VuZXJhbGl6ZWRUaW1lIiwiREVSU2VxdWVuY2UiLCJERVJTZXQiLCJERVJUYWdnZWRPYmplY3QiLCJrZXlzIiwiYXJyYXkiLCJ0YWciLCJleHBsaWNpdCIsIm9iaiIsImpzb25Ub0FTTjFIRVgiLCJnZXRFbmNvZGVkSGV4Iiwib2lkSGV4VG9JbnQiLCJvaWRJbnRUb0hleCIsInNwbGl0IiwiQVNOMU9iamVjdCIsImdldExlbmd0aEhleEZyb21WYWx1ZSIsImhWIiwiaFRMViIsImlzTW9kaWZpZWQiLCJnZXRGcmVzaFZhbHVlSGV4IiwiaEwiLCJoVCIsImdldFZhbHVlSGV4IiwiREVSQWJzdHJhY3RTdHJpbmciLCJnZXRTdHJpbmciLCJzZXRTdHJpbmciLCJ1dGY4dG9oZXgiLCJ0b0xvd2VyQ2FzZSIsInNldFN0cmluZ0hleCIsInN0ciIsImhleCIsIkRFUkFic3RyYWN0VGltZSIsImxvY2FsRGF0ZVRvVVRDIiwidXRjIiwiZ2V0VGltZXpvbmVPZmZzZXQiLCJmb3JtYXREYXRlIiwiemVyb1BhZGRpbmciLCJnZXRGdWxsWWVhciIsImdldE1vbnRoIiwiZ2V0RGF0ZSIsImdldEhvdXJzIiwiZ2V0TWludXRlcyIsImdldFNlY29uZHMiLCJnZXRNaWxsaXNlY29uZHMiLCJzdG9oZXgiLCJzZXRCeURhdGVWYWx1ZSIsIlVUQyIsInNldEJ5RGF0ZSIsIkRFUkFic3RyYWN0U3RydWN0dXJlZCIsInNldEJ5QVNOMU9iamVjdEFycmF5IiwiYXNuMUFycmF5IiwiYXBwZW5kQVNOMU9iamVjdCIsInNldEJ5QmlnSW50ZWdlciIsInNldEJ5SW50ZWdlciIsInNldFZhbHVlSGV4IiwiYmlnaW50Iiwic2V0SGV4VmFsdWVJbmNsdWRpbmdVbnVzZWRCaXRzIiwic2V0VW51c2VkQml0c0FuZEhleFZhbHVlIiwic2V0QnlCaW5hcnlTdHJpbmciLCJzZXRCeUJvb2xlYW5BcnJheSIsIm5ld0ZhbHNlQXJyYXkiLCJiaW4iLCJzZXRWYWx1ZU9pZFN0cmluZyIsInNldFZhbHVlTmFtZSIsIng1MDkiLCJPSUQiLCJuYW1lMm9pZCIsIm9pZCIsIm5hbWUiLCJkYXRlIiwid2l0aE1pbGxpcyIsIm1pbGxpcyIsInNvcnRGbGFnIiwic29ydCIsInNvcnRmbGFnIiwiaXNFeHBsaWNpdCIsImFzbjFPYmplY3QiLCJzZXRBU04xT2JqZWN0IiwiQVNOMUhFWCIsImdldExibGVuIiwiZ2V0TCIsImdldFZibGVuIiwiZ2V0VmlkeCIsImdldFYiLCJnZXRUTFYiLCJnZXROZXh0U2libGluZ0lkeCIsImdldENoaWxkSWR4IiwiZ2V0TnRoQ2hpbGRJZHgiLCJnZXRJZHhieUxpc3QiLCJnZXRUTFZieUxpc3QiLCJnZXRWYnlMaXN0IiwiaGV4dG9vaWRzdHIiLCJkdW1wIiwib21taXRfbG9uZ19vY3RldCIsImlzQVNOMUhFWCIsIm9pZDJuYW1lIiwiaGV4dG91dGY4Iiwib2lkbmFtZSIsIkpTT04iLCJ4NTA5RXh0TmFtZSIsImlzSGV4IiwiQmFzZTY0eCIsInN0b0JBIiwiQkF0b3MiLCJCQXRvaGV4Iiwic3RvYjY0Iiwic3RvYjY0dSIsImI2NHRvYjY0dSIsImI2NHV0b3MiLCJiNjR1dG9iNjQiLCJoZXh0b2I2NHUiLCJiNjR1dG9oZXgiLCJ1dGY4dG9iNjR1IiwiYjY0dXRvdXRmOCIsIkJ1ZmZlciIsInVyaWNtcHRvaGV4IiwiZW5jb2RlVVJJQ29tcG9uZW50QWxsIiwiaGV4dG91cmljbXAiLCJ1dGY4dG9iNjQiLCJiNjR0b3V0ZjgiLCJoZXh0b2I2NCIsImhleHRvYjY0bmwiLCJiNjRubHRvaGV4IiwicGVtdG9oZXgiLCJoZXh0b0FycmF5QnVmZmVyIiwiQXJyYXlCdWZmZXIiLCJEYXRhVmlldyIsInNldFVpbnQ4IiwiQXJyYXlCdWZmZXJ0b2hleCIsImJ5dGVMZW5ndGgiLCJnZXRVaW50OCIsInp1bHV0b21zZWMiLCJ6dWx1dG9zZWMiLCJ6dWx1dG9kYXRlIiwiZGF0ZXRvenVsdSIsImdldFVUQ0Z1bGxZZWFyIiwiZ2V0VVRDTW9udGgiLCJnZXRVVENEYXRlIiwiZ2V0VVRDSG91cnMiLCJnZXRVVENNaW51dGVzIiwiZ2V0VVRDU2Vjb25kcyIsImdldFVUQ01pbGxpc2Vjb25kcyIsImlwdjZ0b2hleCIsInJlcGVhdCIsImhleHRvaXB2NiIsImhleHRvaXAiLCJpcHRvaGV4IiwibmV3bGluZV90b1VuaXgiLCJuZXdsaW5lX3RvRG9zIiwiaXNJbnRlZ2VyIiwiaXNCYXNlNjQiLCJpc0Jhc2U2NFVSTCIsImlzSW50ZWdlckFycmF5IiwiaGV4dG9wb3NoZXgiLCJpbnRhcnlzdHJ0b2hleCIsIm1hcCIsInN0cmRpZmZpZHgiLCJESUdFU1RJTkZPSEVBRCIsInNoYTEiLCJzaGEyMjQiLCJzaGEyNTYiLCJzaGEzODQiLCJzaGE1MTIiLCJtZDIiLCJtZDUiLCJyaXBlbWQxNjAiLCJERUZBVUxUUFJPVklERVIiLCJobWFjbWQ1IiwiaG1hY3NoYTEiLCJobWFjc2hhMjI0IiwiaG1hY3NoYTI1NiIsImhtYWNzaGEzODQiLCJobWFjc2hhNTEyIiwiaG1hY3JpcGVtZDE2MCIsIk1ENXdpdGhSU0EiLCJTSEExd2l0aFJTQSIsIlNIQTIyNHdpdGhSU0EiLCJTSEEyNTZ3aXRoUlNBIiwiU0hBMzg0d2l0aFJTQSIsIlNIQTUxMndpdGhSU0EiLCJSSVBFTUQxNjB3aXRoUlNBIiwiTUQ1d2l0aEVDRFNBIiwiU0hBMXdpdGhFQ0RTQSIsIlNIQTIyNHdpdGhFQ0RTQSIsIlNIQTI1NndpdGhFQ0RTQSIsIlNIQTM4NHdpdGhFQ0RTQSIsIlNIQTUxMndpdGhFQ0RTQSIsIlJJUEVNRDE2MHdpdGhFQ0RTQSIsIlNIQTF3aXRoRFNBIiwiU0hBMjI0d2l0aERTQSIsIlNIQTI1NndpdGhEU0EiLCJNRDV3aXRoUlNBYW5kTUdGMSIsIlNIQTF3aXRoUlNBYW5kTUdGMSIsIlNIQTIyNHdpdGhSU0FhbmRNR0YxIiwiU0hBMjU2d2l0aFJTQWFuZE1HRjEiLCJTSEEzODR3aXRoUlNBYW5kTUdGMSIsIlNIQTUxMndpdGhSU0FhbmRNR0YxIiwiUklQRU1EMTYwd2l0aFJTQWFuZE1HRjEiLCJDUllQVE9KU01FU1NBR0VESUdFU1ROQU1FIiwiTUQ1IiwiU0hBMSIsIlNIQTIyNCIsIlJJUEVNRDE2MCIsImdldERpZ2VzdEluZm9IZXgiLCJnZXRQYWRkZWREaWdlc3RJbmZvSGV4IiwiaGFzaFN0cmluZyIsImFsZyIsImRpZ2VzdFN0cmluZyIsImRpZ2VzdEhleCIsInByb3YiLCJzaGEyNTZIZXgiLCJzaGE1MTJIZXgiLCJTRUNVUkVSQU5ET01HRU4iLCJnZXRSYW5kb21IZXhPZk5ieXRlcyIsImdldFJhbmRvbUJpZ0ludGVnZXJPZk5ieXRlcyIsImdldFJhbmRvbUhleE9mTmJpdHMiLCJnZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYml0cyIsImdldFJhbmRvbUJpZ0ludGVnZXJaZXJvVG9NYXgiLCJnZXRSYW5kb21CaWdJbnRlZ2VyTWluVG9NYXgiLCJzZXRBbGdBbmRQcm92aWRlciIsIm1kIiwidXBkYXRlU3RyaW5nIiwidXBkYXRlSGV4IiwiZGlnZXN0Iiwic2pjbCIsImhhc2giLCJjb2RlYyIsInRvQml0cyIsImZyb21CaXRzIiwiYWxnTmFtZSIsInByb3ZOYW1lIiwiSEFTSExFTkdUSCIsIk1hYyIsImFsZ1Byb3YiLCJtYWMiLCJwYXNzIiwiZG9GaW5hbCIsImRvRmluYWxTdHJpbmciLCJkb0ZpbmFsSGV4Iiwic2V0UGFzc3dvcmQiLCJ1dGY4IiwicnN0ciIsImI2NCIsImI2NHUiLCJTaWduYXR1cmUiLCJfc2V0QWxnTmFtZXMiLCJtZEFsZ05hbWUiLCJwdWJrZXlBbGdOYW1lIiwiX3plcm9QYWRkaW5nT2ZTaWduYXR1cmUiLCJLRVlVVElMIiwiZ2V0S2V5IiwicHJ2S2V5Iiwic3RhdGUiLCJwdWJLZXkiLCJzaWduIiwic0hhc2hIZXgiLCJlY3BydmhleCIsImVjY3VydmVuYW1lIiwiRUNEU0EiLCJoU2lnbiIsInNpZ25IZXgiLCJzaWduV2l0aE1lc3NhZ2VIYXNoUFNTIiwicHNzU2FsdExlbiIsInNpZ25XaXRoTWVzc2FnZUhhc2giLCJEU0EiLCJzaWduU3RyaW5nIiwidmVyaWZ5IiwiZWNwdWJoZXgiLCJ2ZXJpZnlIZXgiLCJ2ZXJpZnlXaXRoTWVzc2FnZUhhc2hQU1MiLCJ2ZXJpZnlXaXRoTWVzc2FnZUhhc2giLCJhbGdQcm92TmFtZSIsImluaXRQYXJhbXMiLCJwc3NzYWx0bGVuIiwicHJ2a2V5cGVtIiwicHJ2a2V5cGFzIiwiQ2lwaGVyIiwiZ2V0QWxnQnlLZXlBbmROYW1lIiwiZGVjcnlwdCIsImRlY3J5cHRPQUVQIiwib2lkaGV4Mm5hbWUiLCJnZXRCaWdSYW5kb20iLCJzZXROYW1lZEN1cnZlIiwiZWNwYXJhbXMiLCJFQ1BhcmFtZXRlckRCIiwiZ2V0QnlOYW1lIiwicHJ2S2V5SGV4IiwicHViS2V5SGV4IiwiY3VydmVOYW1lIiwic2V0UHJpdmF0ZUtleUhleCIsInNldFB1YmxpY0tleUhleCIsImdldFB1YmxpY0tleVhZSGV4Iiwia2V5bGVuIiwiZ2V0U2hvcnROSVNUUEN1cnZlTmFtZSIsImdlbmVyYXRlS2V5UGFpckhleCIsImJpUlNTaWdUb0FTTjFTaWciLCJmcm9tQnl0ZUFycmF5VW5zaWduZWQiLCJzZXJpYWxpemVTaWciLCJwYXJzZVNpZ0hleCIsInZlcmlmeVJhdyIsIkJpdGNvaW4iLCJpc0FycmF5IiwicGFyc2VTaWciLCJ0b0J5dGVBcnJheVNpZ25lZCIsInBhcnNlU2lnQ29tcGFjdCIsInJlYWRQS0NTNVBydktleUhleCIsImdldE5hbWUiLCJyZWFkUEtDUzhQcnZLZXlIZXgiLCJyZWFkUEtDUzhQdWJLZXlIZXgiLCJyZWFkQ2VydFB1YktleUhleCIsInBydiIsInB1YiIsInBhcnNlU2lnSGV4SW5IZXhSUyIsImFzbjFTaWdUb0NvbmNhdFNpZyIsImNvbmNhdFNpZ1RvQVNOMVNpZyIsImhleFJTU2lnVG9BU04xU2lnIiwicmVnaXN0IiwiQUVTIiwiVHJpcGxlREVTIiwiREVTIiwia2V5IiwiaXYiLCJjaXBoZXJ0ZXh0IiwicHJvYyIsImVwcm9jIiwiaXZsZW4iLCJjaXBoZXIiLCJpdnNhbHQiLCJkYXRhIiwia2V5aGV4IiwiaXZoZXgiLCJ2ZXJzaW9uIiwicGFyc2VQS0NTNVBFTSIsImdldEtleUFuZFVudXNlZEl2QnlQYXNzY29kZUFuZEl2c2FsdCIsImRlY3J5cHRLZXlCNjQiLCJnZXREZWNyeXB0ZWRLZXlIZXgiLCJnZXRFbmNyeXB0ZWRQS0NTNVBFTUZyb21QcnZLZXlIZXgiLCJ0b1VwcGVyQ2FzZSIsInBhcnNlSGV4T2ZFbmNyeXB0ZWRQS0NTOCIsImVuY3J5cHRpb25TY2hlbWVBbGciLCJlbmNyeXB0aW9uU2NoZW1lSVYiLCJwYmtkZjJTYWx0IiwicGJrZGYySXRlciIsImdldFBCS0RGMktleUhleEZyb21QYXJhbSIsIlBCS0RGMiIsImtleVNpemUiLCJpdGVyYXRpb25zIiwiX2dldFBsYWluUEtDUzhIZXhGcm9tRW5jcnlwdGVkUEtDUzhQRU0iLCJnZXRLZXlGcm9tRW5jcnlwdGVkUEtDUzhQRU0iLCJnZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhIZXgiLCJwYXJzZVBsYWluUHJpdmF0ZVBLQ1M4SGV4IiwiYWxncGFyYW0iLCJhbGdvaWQiLCJrZXlpZHgiLCJnZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhQRU0iLCJfZ2V0S2V5RnJvbVB1YmxpY1BLQ1M4SGV4IiwicGFyc2VQdWJsaWNSYXdSU0FLZXlIZXgiLCJwYXJzZVB1YmxpY1BLQ1M4SGV4IiwieHkiLCJrdHkiLCJkcCIsImRxIiwiY28iLCJxaSIsInNldFByaXZhdGVFeCIsInNldFByaXZhdGUiLCJjcnYiLCJYNTA5IiwiZ2V0UHVibGljS2V5RnJvbUNlcnRIZXgiLCJnZXRQdWJsaWNLZXlGcm9tQ2VydFBFTSIsImdlbmVyYXRlS2V5cGFpciIsImdlbmVyYXRlIiwicHJ2S2V5T2JqIiwicHViS2V5T2JqIiwiZ2V0UEVNIiwiU3ViamVjdFB1YmxpY0tleUluZm8iLCJzZXEiLCJvY3RzdHIiLCJiaXRzdHIiLCJnZXRLZXlGcm9tQ1NSUEVNIiwiZ2V0S2V5RnJvbUNTUkhleCIsInBhcnNlQ1NSSGV4IiwicDhwdWJrZXloZXgiLCJnZXRKV0tGcm9tS2V5IiwiZ2V0UG9zQXJyYXlPZkNoaWxkcmVuRnJvbUhleCIsImdldEhleFZhbHVlQXJyYXlPZkNoaWxkcmVuRnJvbUhleCIsInJlYWRQcml2YXRlS2V5RnJvbVBFTVN0cmluZyIsInJlYWRQS0NTNVB1YktleUhleCIsInJlYWRDZXJ0SGV4IiwiZ2V0UHVibGljS2V5SGV4IiwiX1JFX0hFWERFQ09OTFkiLCJjb21waWxlIiwiX3JzYXNpZ25fZ2V0SGV4UGFkZGVkRGlnZXN0SW5mb0ZvclN0cmluZyIsImRvUHJpdmF0ZSIsInBzc19tZ2YxX3N0ciIsInNpZ25QU1MiLCJfcnNhc2lnbl9nZXREZWNyeXB0U2lnbmF0dXJlQkkiLCJfcnNhc2lnbl9nZXRIZXhEaWdlc3RJbmZvRnJvbVNpZyIsIl9yc2FzaWduX2dldEFsZ05hbWVBbmRIYXNoRnJvbUhleERpc2dlc3RJbmZvIiwidmVyaWZ5UFNTIiwiU0FMVF9MRU5fSExFTiIsIlNBTFRfTEVOX01BWCIsIlNBTFRfTEVOX1JFQ09WRVIiLCJmb2Zmc2V0IiwiYUV4dEluZm8iLCJnZXRWZXJzaW9uIiwiZ2V0U2VyaWFsTnVtYmVySGV4IiwiZ2V0U2lnbmF0dXJlQWxnb3JpdGhtRmllbGQiLCJnZXRJc3N1ZXJIZXgiLCJnZXRJc3N1ZXJTdHJpbmciLCJoZXgyZG4iLCJnZXRTdWJqZWN0SGV4IiwiZ2V0U3ViamVjdFN0cmluZyIsImdldE5vdEJlZm9yZSIsImdldE5vdEFmdGVyIiwiZ2V0UHVibGljS2V5SWR4IiwiZ2V0UHVibGljS2V5Q29udGVudElkeCIsImdldFB1YmxpY0tleSIsImdldFNpZ25hdHVyZUFsZ29yaXRobU5hbWUiLCJnZXRTaWduYXR1cmVWYWx1ZUhleCIsInZlcmlmeVNpZ25hdHVyZSIsInBhcnNlRXh0IiwiY3JpdGljYWwiLCJ2aWR4IiwiZ2V0RXh0SW5mbyIsImdldEV4dEJhc2ljQ29uc3RyYWludHMiLCJjQSIsInBhdGhMZW4iLCJnZXRFeHRLZXlVc2FnZUJpbiIsImdldEV4dEtleVVzYWdlU3RyaW5nIiwiS0VZVVNBR0VfTkFNRSIsImdldEV4dFN1YmplY3RLZXlJZGVudGlmaWVyIiwiZ2V0RXh0QXV0aG9yaXR5S2V5SWRlbnRpZmllciIsImtpZCIsImdldEV4dEV4dEtleVVzYWdlTmFtZSIsImdldEV4dFN1YmplY3RBbHROYW1lIiwiZ2V0RXh0U3ViamVjdEFsdE5hbWUyIiwiZ2V0RXh0Q1JMRGlzdHJpYnV0aW9uUG9pbnRzVVJJIiwiZ2V0RXh0QUlBSW5mbyIsIm9jc3AiLCJjYWlzc3VlciIsImdldEV4dENlcnRpZmljYXRlUG9saWNpZXMiLCJpZCIsImNwcyIsInVub3RpY2UiLCJyZWFkQ2VydFBFTSIsImdldEluZm8iLCJoZXgycmRuIiwiaGV4MmF0dHJUeXBlVmFsdWUiLCJvaWQyYXR5cGUiLCJnZXRQdWJsaWNLZXlJbmZvUHJvcE9mQ2VydFBFTSIsImp3cyIsIkpXUyIsImlzU2FmZUpTT05TdHJpbmciLCJwYXJzZUpXUyIsInBhcnNlZEpXUyIsInNpZ3ZhbEgiLCJoZWFkQjY0VSIsInBheWxvYWRCNjRVIiwic2lndmFsQjY0VSIsInNpIiwic2lndmFsQkkiLCJoZWFkUyIsInBheWxvYWRTIiwicmVhZFNhZmVKU09OU3RyaW5nIiwiandzYWxnMnNpZ2FsZyIsImhBU04xU2lnIiwiaGVhZGVyT2JqIiwicGF5bG9hZE9iaiIsImhlYWRlclBQIiwicGF5bG9hZFBQIiwic2lnSGV4IiwidmVyaWZ5SldUIiwiaW5BcnJheSIsImluY2x1ZGVkQXJyYXkiLCJpc3MiLCJzdWIiLCJhdWQiLCJJbnREYXRlIiwiZ2V0Tm93IiwidmVyaWZ5QXQiLCJncmFjZVBlcmlvZCIsIm5iZiIsImlhdCIsImp0aSIsIkhTMjU2IiwiSFMzODQiLCJIUzUxMiIsIlJTMjU2IiwiUlMzODQiLCJSUzUxMiIsIkVTMjU2IiwiRVMzODQiLCJQUzI1NiIsIlBTMzg0IiwiUFM1MTIiLCJub25lIiwiZ2V0RW5jb2RlZFNpZ25hdHVyZVZhbHVlRnJvbUpXUyIsImdldEpXS3RodW1icHJpbnQiLCJnZXQiLCJnZXRadWx1IiwiaW50RGF0ZTJVVENTdHJpbmciLCJ0b1VUQ1N0cmluZyIsImludERhdGUyWnVsdSIsIkVEU0EiLCJfY3J5cHRvIiwiRGVmYXVsdEFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lIiwiYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUiLCJhY2Nlc3NUb2tlbkV4cGlyaW5nVGltZXIiLCJUaW1lciIsImFjY2Vzc1Rva2VuRXhwaXJlZFRpbWVyIiwiX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lIiwiX2FjY2Vzc1Rva2VuRXhwaXJpbmciLCJfYWNjZXNzVG9rZW5FeHBpcmVkIiwibG9hZCIsImNvbnRhaW5lciIsImFjY2Vzc190b2tlbiIsImV4cGlyZXNfaW4iLCJkdXJhdGlvbiIsImRlYnVnIiwiZXhwaXJpbmciLCJjYW5jZWwiLCJleHBpcmVkIiwidW5sb2FkIiwiYWRkQWNjZXNzVG9rZW5FeHBpcmluZyIsImNiIiwiYWRkSGFuZGxlciIsInJlbW92ZUFjY2Vzc1Rva2VuRXhwaXJpbmciLCJyZW1vdmVIYW5kbGVyIiwiYWRkQWNjZXNzVG9rZW5FeHBpcmVkIiwicmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmVkIiwiRGVmYXVsdEludGVydmFsIiwiY2FsbGJhY2siLCJjbGllbnRfaWQiLCJ1cmwiLCJpbnRlcnZhbCIsInN0b3BPbkVycm9yIiwiX2NhbGxiYWNrIiwiX2NsaWVudF9pZCIsIl91cmwiLCJfaW50ZXJ2YWwiLCJfc3RvcE9uRXJyb3IiLCJpZHgiLCJfZnJhbWVfb3JpZ2luIiwiX2ZyYW1lIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50Iiwic3R5bGUiLCJ2aXNpYmlsaXR5IiwicG9zaXRpb24iLCJkaXNwbGF5Iiwid2lkdGgiLCJoZWlnaHQiLCJzcmMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm9ubG9hZCIsImJvZHkiLCJhcHBlbmRDaGlsZCIsIl9ib3VuZE1lc3NhZ2VFdmVudCIsIl9tZXNzYWdlIiwiYmluZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJvcmlnaW4iLCJzb3VyY2UiLCJjb250ZW50V2luZG93IiwiZXJyb3IiLCJzdG9wIiwic3RhcnQiLCJzZXNzaW9uX3N0YXRlIiwiX3Nlc3Npb25fc3RhdGUiLCJzZW5kIiwicG9zdE1lc3NhZ2UiLCJfdGltZXIiLCJzZXRJbnRlcnZhbCIsImNsZWFySW50ZXJ2YWwiLCJwcmVwYXJlIiwicGFyYW1zIiwicG9wdXBXaW5kb3dGZWF0dXJlcyIsInBvcHVwIiwiQ29yZG92YVBvcHVwV2luZG93IiwiRGVmYXVsdFBvcHVwRmVhdHVyZXMiLCJEZWZhdWx0UG9wdXBUYXJnZXQiLCJfcHJvbWlzZSIsInJlamVjdCIsIl9yZXNvbHZlIiwiX3JlamVjdCIsImZlYXR1cmVzIiwidGFyZ2V0IiwicG9wdXBXaW5kb3dUYXJnZXQiLCJyZWRpcmVjdF91cmkiLCJzdGFydFVybCIsIl9pc0luQXBwQnJvd3Nlckluc3RhbGxlZCIsImNvcmRvdmFNZXRhZGF0YSIsInNvbWUiLCJuYXZpZ2F0ZSIsIl9lcnJvciIsImNvcmRvdmEiLCJyZXF1aXJlIiwibWV0YWRhdGEiLCJfcG9wdXAiLCJJbkFwcEJyb3dzZXIiLCJvcGVuIiwiX2V4aXRDYWxsYmFja0V2ZW50IiwiX2V4aXRDYWxsYmFjayIsIl9sb2FkU3RhcnRDYWxsYmFja0V2ZW50IiwiX2xvYWRTdGFydENhbGxiYWNrIiwicHJvbWlzZSIsImV2ZW50IiwiX3N1Y2Nlc3MiLCJtZXNzYWdlIiwiX2NsZWFudXAiLCJjbG9zZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJFcnJvclJlc3BvbnNlIiwiZXJyb3JfZGVzY3JpcHRpb24iLCJlcnJvcl91cmkiLCJFdmVudCIsIl9uYW1lIiwiX2NhbGxiYWNrcyIsImZpbmRJbmRleCIsIml0ZW0iLCJyYWlzZSIsInRpbWVyIiwiaGFuZGxlIiwidGVzdGluZyIsInJlcXVlc3QiLCJfdGVzdGluZyIsInNldFhNTEh0dHBSZXF1ZXN0IiwibmV3UmVxdWVzdCIsImxvY2F0aW9uIiwibG9jYWxTdG9yYWdlIiwic2Vzc2lvblN0b3JhZ2UiLCJYTUxIdHRwUmVxdWVzdCIsIklGcmFtZU5hdmlnYXRvciIsImZyYW1lIiwiSUZyYW1lV2luZG93Iiwibm90aWZ5UGFyZW50IiwiRGVmYXVsdFRpbWVvdXQiLCJ0aW1lb3V0Iiwic2lsZW50UmVxdWVzdFRpbWVvdXQiLCJzZXRUaW1lb3V0IiwiX3RpbWVvdXQiLCJjbGVhclRpbWVvdXQiLCJyZW1vdmVDaGlsZCIsIl9vcmlnaW4iLCJmcmFtZUVsZW1lbnQiLCJocmVmIiwicGFyZW50IiwicHJvdG9jb2wiLCJob3N0IiwiZ2V0SXRlbSIsInNldEl0ZW0iLCJ2YWx1ZSIsInJlbW92ZUl0ZW0iLCJpbmRleCIsImdldE93blByb3BlcnR5TmFtZXMiLCJKb3NlVXRpbCIsIktleVV0aWwiLCJBbGxvd2VkU2lnbmluZ0FsZ3MiLCJnZXRKb3NlVXRpbCIsInBhcnNlSnd0Iiwiand0IiwidG9rZW4iLCJoZWFkZXIiLCJwYXlsb2FkIiwidmFsaWRhdGVKd3QiLCJpc3N1ZXIiLCJhdWRpZW5jZSIsImNsb2NrU2tldyIsIm5vdyIsInRpbWVJbnNlbnNpdGl2ZSIsIng1YyIsIl92YWxpZGF0ZUp3dCIsInZhbGlkYXRlSnd0QXR0cmlidXRlcyIsInZhbGlkQXVkaWVuY2UiLCJhenAiLCJsb3dlck5vdyIsInVwcGVyTm93IiwidGhlbiIsImhleFRvQmFzZTY0VXJsIiwiSnNvblNlcnZpY2UiLCJhZGRpdGlvbmFsQ29udGVudFR5cGVzIiwiWE1MSHR0cFJlcXVlc3RDdG9yIiwiand0SGFuZGxlciIsIl9jb250ZW50VHlwZXMiLCJfWE1MSHR0cFJlcXVlc3QiLCJfand0SGFuZGxlciIsImdldEpzb24iLCJyZXEiLCJhbGxvd2VkQ29udGVudFR5cGVzIiwic3RhdHVzIiwiY29udGVudFR5cGUiLCJnZXRSZXNwb25zZUhlYWRlciIsImZvdW5kIiwiZmluZCIsInN0YXJ0c1dpdGgiLCJyZXNwb25zZVRleHQiLCJzdGF0dXNUZXh0Iiwib25lcnJvciIsInNldFJlcXVlc3RIZWFkZXIiLCJwb3N0Rm9ybSIsIm5vcExvZ2dlciIsImluZm8iLCJ3YXJuIiwiTk9ORSIsIkVSUk9SIiwiV0FSTiIsIklORk8iLCJERUJVRyIsImxvZ2dlciIsImxldmVsIiwiYXJncyIsImZyb20iLCJPaWRjTWV0YWRhdGFVcmxQYXRoIiwic2V0dGluZ3MiLCJKc29uU2VydmljZUN0b3IiLCJfc2V0dGluZ3MiLCJfanNvblNlcnZpY2UiLCJnZXRNZXRhZGF0YSIsIm1ldGFkYXRhVXJsIiwiZ2V0SXNzdWVyIiwiX2dldE1ldGFkYXRhUHJvcGVydHkiLCJnZXRBdXRob3JpemF0aW9uRW5kcG9pbnQiLCJnZXRVc2VySW5mb0VuZHBvaW50IiwiZ2V0VG9rZW5FbmRwb2ludCIsIm9wdGlvbmFsIiwiZ2V0Q2hlY2tTZXNzaW9uSWZyYW1lIiwiZ2V0RW5kU2Vzc2lvbkVuZHBvaW50IiwiZ2V0UmV2b2NhdGlvbkVuZHBvaW50IiwiZ2V0S2V5c0VuZHBvaW50IiwiZ2V0U2lnbmluZ0tleXMiLCJzaWduaW5nS2V5cyIsImp3a3NfdXJpIiwia2V5U2V0IiwiX21ldGFkYXRhVXJsIiwiYXV0aG9yaXR5IiwiY3JlYXRlU2lnbmluUmVxdWVzdCIsInJlc3BvbnNlX3R5cGUiLCJzY29wZSIsInByb21wdCIsIm1heF9hZ2UiLCJ1aV9sb2NhbGVzIiwiaWRfdG9rZW5faGludCIsImxvZ2luX2hpbnQiLCJhY3JfdmFsdWVzIiwicmVzb3VyY2UiLCJyZXF1ZXN0X3VyaSIsInJlc3BvbnNlX21vZGUiLCJleHRyYVF1ZXJ5UGFyYW1zIiwiZXh0cmFUb2tlblBhcmFtcyIsInJlcXVlc3RfdHlwZSIsInNraXBVc2VySW5mbyIsInN0YXRlU3RvcmUiLCJTaWduaW5SZXF1ZXN0IiwiaXNDb2RlIiwiX21ldGFkYXRhU2VydmljZSIsInNpZ25pblJlcXVlc3QiLCJjbGllbnRfc2VjcmV0Iiwic2lnbmluU3RhdGUiLCJfc3RhdGVTdG9yZSIsInNldCIsInRvU3RvcmFnZVN0cmluZyIsInJlYWRTaWduaW5SZXNwb25zZVN0YXRlIiwicmVtb3ZlU3RhdGUiLCJ1c2VRdWVyeSIsImRlbGltaXRlciIsInJlc3BvbnNlIiwiU2lnbmluUmVzcG9uc2UiLCJzdGF0ZUFwaSIsInJlbW92ZSIsInN0b3JlZFN0YXRlU3RyaW5nIiwiU2lnbmluU3RhdGUiLCJmcm9tU3RvcmFnZVN0cmluZyIsInByb2Nlc3NTaWduaW5SZXNwb25zZSIsIl92YWxpZGF0b3IiLCJ2YWxpZGF0ZVNpZ25pblJlc3BvbnNlIiwiY3JlYXRlU2lnbm91dFJlcXVlc3QiLCJwb3N0X2xvZ291dF9yZWRpcmVjdF91cmkiLCJTaWdub3V0UmVxdWVzdCIsInNpZ25vdXRTdGF0ZSIsInJlYWRTaWdub3V0UmVzcG9uc2VTdGF0ZSIsIlNpZ25vdXRSZXNwb25zZSIsInN0YXRlS2V5IiwiU3RhdGUiLCJwcm9jZXNzU2lnbm91dFJlc3BvbnNlIiwidmFsaWRhdGVTaWdub3V0UmVzcG9uc2UiLCJjbGVhclN0YWxlU3RhdGUiLCJzdGFsZVN0YXRlQWdlIiwidmFsaWRhdG9yIiwibWV0YWRhdGFTZXJ2aWNlIiwiRGVmYXVsdFJlc3BvbnNlVHlwZSIsIkRlZmF1bHRTY29wZSIsIkRlZmF1bHRTdGFsZVN0YXRlQWdlIiwiRGVmYXVsdENsb2NrU2tld0luU2Vjb25kcyIsImZpbHRlclByb3RvY29sQ2xhaW1zIiwibG9hZFVzZXJJbmZvIiwidXNlckluZm9Kd3RJc3N1ZXIiLCJSZXNwb25zZVZhbGlkYXRvckN0b3IiLCJSZXNwb25zZVZhbGlkYXRvciIsIk1ldGFkYXRhU2VydmljZUN0b3IiLCJfYXV0aG9yaXR5IiwiX21ldGFkYXRhIiwiX3NpZ25pbmdLZXlzIiwiX2NsaWVudF9zZWNyZXQiLCJfcmVzcG9uc2VfdHlwZSIsIl9zY29wZSIsIl9yZWRpcmVjdF91cmkiLCJfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIiwiX3Byb21wdCIsIl9kaXNwbGF5IiwiX21heF9hZ2UiLCJfdWlfbG9jYWxlcyIsIl9hY3JfdmFsdWVzIiwiX3Jlc291cmNlIiwiX3Jlc3BvbnNlX21vZGUiLCJfZmlsdGVyUHJvdG9jb2xDbGFpbXMiLCJfbG9hZFVzZXJJbmZvIiwiX3N0YWxlU3RhdGVBZ2UiLCJfY2xvY2tTa2V3IiwiX3VzZXJJbmZvSnd0SXNzdWVyIiwiX2V4dHJhUXVlcnlQYXJhbXMiLCJfZXh0cmFUb2tlblBhcmFtcyIsIlBvcHVwTmF2aWdhdG9yIiwiUG9wdXBXaW5kb3ciLCJrZWVwT3BlbiIsIm5vdGlmeU9wZW5lciIsIkNoZWNrRm9yUG9wdXBDbG9zZWRJbnRlcnZhbCIsIl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIiLCJfY2hlY2tGb3JQb3B1cENsb3NlZCIsIl9pZCIsImZvY3VzIiwiY2xvc2VkIiwib3BlbmVyIiwiVXJsVXRpbGl0eSIsInBhcnNlVXJsRnJhZ21lbnQiLCJSZWRpcmVjdE5hdmlnYXRvciIsInVzZVJlcGxhY2VUb05hdmlnYXRlIiwiUHJvdG9jb2xDbGFpbXMiLCJVc2VySW5mb1NlcnZpY2VDdG9yIiwiVXNlckluZm9TZXJ2aWNlIiwiam9zZVV0aWwiLCJUb2tlbkNsaWVudEN0b3IiLCJUb2tlbkNsaWVudCIsIl91c2VySW5mb1NlcnZpY2UiLCJfam9zZVV0aWwiLCJfdG9rZW5DbGllbnQiLCJfcHJvY2Vzc1NpZ25pblBhcmFtcyIsIl92YWxpZGF0ZVRva2VucyIsIl9wcm9jZXNzQ2xhaW1zIiwibm9uY2UiLCJpZF90b2tlbiIsImNvZGVfdmVyaWZpZXIiLCJjb2RlIiwiaXNPcGVuSWRDb25uZWN0IiwicHJvZmlsZSIsImdldENsYWltcyIsImNsYWltcyIsIl9tZXJnZUNsYWltcyIsImNsYWltczEiLCJjbGFpbXMyIiwicmVzdWx0IiwiYXNzaWduIiwidmFsdWVzIiwiZm9yRWFjaCIsIl9wcm9jZXNzQ29kZSIsIl92YWxpZGF0ZUlkVG9rZW5BbmRBY2Nlc3NUb2tlbiIsIl92YWxpZGF0ZUlkVG9rZW4iLCJleGNoYW5nZUNvZGUiLCJ0b2tlblJlc3BvbnNlIiwiX3ZhbGlkYXRlSWRUb2tlbkF0dHJpYnV0ZXMiLCJjbG9ja1NrZXdJblNlY29uZHMiLCJfdmFsaWRhdGVBY2Nlc3NUb2tlbiIsIl9maWx0ZXJCeUFsZyIsImZpbHRlciIsImF0X2hhc2giLCJoYXNoQWxnIiwiaGFzaEJpdHMiLCJzaGEiLCJsZWZ0IiwibGVmdF9iNjR1IiwidXNlck1hbmFnZXIiLCJDaGVja1Nlc3Npb25JRnJhbWVDdG9yIiwiX3VzZXJNYW5hZ2VyIiwiX0NoZWNrU2Vzc2lvbklGcmFtZUN0b3IiLCJldmVudHMiLCJhZGRVc2VyTG9hZGVkIiwiX3N0YXJ0IiwiYWRkVXNlclVubG9hZGVkIiwiX3N0b3AiLCJnZXRVc2VyIiwidXNlciIsIm1vbml0b3JBbm9ueW1vdXNTZXNzaW9uIiwicXVlcnlTZXNzaW9uU3RhdHVzIiwidG1wVXNlciIsInNlc3Npb24iLCJzaWQiLCJjYXRjaCIsImVyciIsIl9zdWIiLCJfc2lkIiwiX2NoZWNrU2Vzc2lvbklGcmFtZSIsIl9jaGVja1Nlc3Npb25JbnRlcnZhbCIsIl9zdG9wQ2hlY2tTZXNzaW9uT25FcnJvciIsInRpbWVySGFuZGxlIiwicmFpc2VFdmVudCIsIl9yYWlzZVVzZXJTZXNzaW9uQ2hhbmdlZCIsIl9yYWlzZVVzZXJTaWduZWRPdXQiLCJfcmFpc2VVc2VyU2lnbmVkSW4iLCJjaGVja1Nlc3Npb25JbnRlcnZhbCIsInN0b3BDaGVja1Nlc3Npb25PbkVycm9yIiwib2lkYyIsImlzT2lkYyIsImFkZFF1ZXJ5UGFyYW0iLCJjb2RlX2NoYWxsZW5nZSIsImlzT0F1dGgiLCJPaWRjU2NvcGUiLCJ0b2tlbl90eXBlIiwiZXhwaXJlc19hdCIsInNjb3BlcyIsIl9ub25jZSIsIl9jb2RlX3ZlcmlmaWVyIiwiX2NvZGVfY2hhbGxlbmdlIiwiX3NraXBVc2VySW5mbyIsImNyZWF0ZWQiLCJzdG9yYWdlU3RyaW5nIiwiU2lsZW50UmVuZXdTZXJ2aWNlIiwiX3Rva2VuRXhwaXJpbmciLCJzaWduaW5TaWxlbnQiLCJfcmFpc2VTaWxlbnRSZW5ld0Vycm9yIiwiX2NyZWF0ZWQiLCJfcmVxdWVzdF90eXBlIiwic3RvcmFnZSIsImFnZSIsImN1dG9mZiIsImdldEFsbEtleXMiLCJwcm9taXNlcyIsImFsbCIsIlRpbWVyRHVyYXRpb24iLCJub3dGdW5jIiwiX25vd0Z1bmMiLCJleHBpcmF0aW9uIiwiX3RpbWVySGFuZGxlIiwiX2V4cGlyYXRpb24iLCJ0aW1lckR1cmF0aW9uIiwiZGlmZiIsImdyYW50X3R5cGUiLCJleGNoYW5nZVJlZnJlc2hUb2tlbiIsInJlZnJlc2hfdG9rZW4iLCJBY2Nlc3NUb2tlblR5cGVIaW50IiwiUmVmcmVzaFRva2VuVHlwZUhpbnQiLCJfWE1MSHR0cFJlcXVlc3RDdG9yIiwicmV2b2tlIiwicmVxdWlyZWQiLCJfcmV2b2tlIiwieGhyIiwiZ2xvYmFsIiwibGFzdEluZGV4T2YiLCJyZWdleCIsImNvdW50ZXIiLCJleGVjIiwicHJvcCIsIl9nZXRDbGFpbXNGcm9tSnd0IiwiaXNzdWVyUHJvbWlzZSIsIlNpbGVudFJlbmV3U2VydmljZUN0b3IiLCJTZXNzaW9uTW9uaXRvckN0b3IiLCJUb2tlblJldm9jYXRpb25DbGllbnRDdG9yIiwiVXNlck1hbmFnZXJTZXR0aW5ncyIsIl9ldmVudHMiLCJVc2VyTWFuYWdlckV2ZW50cyIsIl9zaWxlbnRSZW5ld1NlcnZpY2UiLCJhdXRvbWF0aWNTaWxlbnRSZW5ldyIsInN0YXJ0U2lsZW50UmVuZXciLCJtb25pdG9yU2Vzc2lvbiIsIl9zZXNzaW9uTW9uaXRvciIsIl90b2tlblJldm9jYXRpb25DbGllbnQiLCJfbG9hZFVzZXIiLCJyZW1vdmVVc2VyIiwic3RvcmVVc2VyIiwic2lnbmluUmVkaXJlY3QiLCJuYXZQYXJhbXMiLCJfc2lnbmluU3RhcnQiLCJfcmVkaXJlY3ROYXZpZ2F0b3IiLCJzaWduaW5SZWRpcmVjdENhbGxiYWNrIiwiX3NpZ25pbkVuZCIsInNpZ25pblBvcHVwIiwicG9wdXBfcmVkaXJlY3RfdXJpIiwiX3NpZ25pbiIsIl9wb3B1cE5hdmlnYXRvciIsInNpZ25pblBvcHVwQ2FsbGJhY2siLCJfc2lnbmluQ2FsbGJhY2siLCJfdXNlUmVmcmVzaFRva2VuIiwiaW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3IiwidmFsaWRhdGVTdWJPblNpbGVudFJlbmV3IiwiY3VycmVudF9zdWIiLCJfc2lnbmluU2lsZW50SWZyYW1lIiwiaWRUb2tlblZhbGlkYXRpb24iLCJfdmFsaWRhdGVJZFRva2VuRnJvbVRva2VuUmVmcmVzaFRva2VuIiwiYXV0aF90aW1lIiwic2lsZW50X3JlZGlyZWN0X3VyaSIsIl9pZnJhbWVOYXZpZ2F0b3IiLCJzaWduaW5TaWxlbnRDYWxsYmFjayIsInNpZ25pbkNhbGxiYWNrIiwic2lnbm91dENhbGxiYWNrIiwic2lnbm91dFJlZGlyZWN0Q2FsbGJhY2siLCJzaWdub3V0UG9wdXBDYWxsYmFjayIsInF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlIiwibmF2UmVzcG9uc2UiLCJzaWduaW5SZXNwb25zZSIsIm5hdmlnYXRvclBhcmFtcyIsInNpZ25vdXRSZWRpcmVjdCIsInBvc3RMb2dvdXRSZWRpcmVjdFVyaSIsIl9zaWdub3V0U3RhcnQiLCJfc2lnbm91dEVuZCIsInNpZ25vdXRQb3B1cCIsInBvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIl9zaWdub3V0IiwicmV2b2tlUHJvbWlzZSIsInJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0IiwiX3Jldm9rZUludGVybmFsIiwic2lnbm91dFJlcXVlc3QiLCJzaWdub3V0UmVzcG9uc2UiLCJyZXZva2VBY2Nlc3NUb2tlbiIsInN1Y2Nlc3MiLCJfcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbCIsIl9yZXZva2VSZWZyZXNoVG9rZW5JbnRlcm5hbCIsImF0U3VjY2VzcyIsInJ0U3VjY2VzcyIsInN0b3BTaWxlbnRSZW5ldyIsIl91c2VyU3RvcmUiLCJfdXNlclN0b3JlS2V5IiwicmVkaXJlY3ROYXZpZ2F0b3IiLCJwb3B1cE5hdmlnYXRvciIsImlmcmFtZU5hdmlnYXRvciIsInVzZXJTdG9yZSIsIl91c2VyTG9hZGVkIiwiX3VzZXJVbmxvYWRlZCIsIl9zaWxlbnRSZW5ld0Vycm9yIiwiX3VzZXJTaWduZWRJbiIsIl91c2VyU2lnbmVkT3V0IiwiX3VzZXJTZXNzaW9uQ2hhbmdlZCIsInJlbW92ZVVzZXJMb2FkZWQiLCJyZW1vdmVVc2VyVW5sb2FkZWQiLCJhZGRTaWxlbnRSZW5ld0Vycm9yIiwicmVtb3ZlU2lsZW50UmVuZXdFcnJvciIsImFkZFVzZXJTaWduZWRJbiIsInJlbW92ZVVzZXJTaWduZWRJbiIsImFkZFVzZXJTaWduZWRPdXQiLCJyZW1vdmVVc2VyU2lnbmVkT3V0IiwiYWRkVXNlclNlc3Npb25DaGFuZ2VkIiwicmVtb3ZlVXNlclNlc3Npb25DaGFuZ2VkIiwiRGVmYXVsdENoZWNrU2Vzc2lvbkludGVydmFsIiwic3RvcmUiLCJfcG9wdXBfcmVkaXJlY3RfdXJpIiwiX3BvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIl9wb3B1cFdpbmRvd0ZlYXR1cmVzIiwiX3BvcHVwV2luZG93VGFyZ2V0IiwiX3NpbGVudF9yZWRpcmVjdF91cmkiLCJfc2lsZW50UmVxdWVzdFRpbWVvdXQiLCJfYXV0b21hdGljU2lsZW50UmVuZXciLCJfdmFsaWRhdGVTdWJPblNpbGVudFJlbmV3IiwiX2luY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyIsIl9tb25pdG9yU2Vzc2lvbiIsIl9tb25pdG9yQW5vbnltb3VzU2Vzc2lvbiIsIl9xdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZSIsIl9yZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCIsInByZWZpeCIsIl9zdG9yZSIsIl9wcmVmaXgiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrREFBMEMsZ0NBQWdDO0FBQzFFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0VBQXdELGtCQUFrQjtBQUMxRTtBQUNBLHlEQUFpRCxjQUFjO0FBQy9EOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBeUMsaUNBQWlDO0FBQzFFLHdIQUFnSCxtQkFBbUIsRUFBRTtBQUNySTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUEyQiwwQkFBMEIsRUFBRTtBQUN2RCx5Q0FBaUMsZUFBZTtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4REFBc0QsK0RBQStEOztBQUVySDtBQUNBOzs7QUFHQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDL0VBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQW5CQTtBQUNBOztrQkFvQmU7QUFDWEEsNkJBRFc7QUFFWEMsaUJBRlc7QUFHWEMsc0NBSFc7QUFJWEMsOERBSlc7QUFLWEMsb0VBTFc7QUFNWEMsOERBTlc7QUFPWEMseUNBUFc7QUFRWEMsMkRBUlc7QUFTWEMscURBVFc7QUFVWEMsdUVBVlc7QUFXWEMsMEVBWFc7QUFZWEMsOERBWlc7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QUNBLFlBQVk7QUFDWjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EsV0FBVztBQUNYOztBQUVBO0FBQ0E7QUFDQSx3Q0FBd0MsV0FBVztBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsU0FBUztBQUNUO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQ0FBb0MsY0FBYztBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDLGtCQUFrQjtBQUNuRDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7O0FBRUE7QUFDQSxZQUFZO0FBQ1o7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw4Q0FBOEMsUUFBUTtBQUN0RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSw4Q0FBOEMsUUFBUTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7OztBQy90Qlk7O0FBRVo7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyxTQUFTO0FBQzNDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBMEMsVUFBVTtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFWTs7QUFFWixhQUFhLG1CQUFPLENBQUMsb0RBQVc7QUFDaEMsY0FBYyxtQkFBTyxDQUFDLGdEQUFTO0FBQy9CLGNBQWMsbUJBQU8sQ0FBQyxvRUFBUzs7QUFFL0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtREFBbUQ7QUFDeEU7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixVQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLGlCQUFpQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsRUFBRTtBQUNsRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZUFBZTtBQUN2QztBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBLHFCQUFxQixlQUFlO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVEQUF1RCxPQUFPO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1REFBdUQsT0FBTztBQUM5RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFF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O0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTCxtREFBbUQ7QUFDbkQ7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTCxvQ0FBb0M7QUFDcEM7QUFDQSxLQUFLO0FBQ0wsd0VBQXdFO0FBQ3hFO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsOERBQThEO0FBQzlEO0FBQ0EsS0FBSztBQUNMLHdFQUF3RTtBQUN4RTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUgseUJBQXlCLHNCQUFzQixFQUFFLEVBQUU7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNENBQTRDO0FBQzVDO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFdBQVc7QUFDbkI7QUFDQTtBQUNBLFFBQVEsVUFBVTtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsV0FBVztBQUNuQjtBQUNBO0FBQ0E7QUFDQSxRQUFRLFdBQVc7QUFDbkI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlCQUF5QixtQkFBbUIsdUJBQXVCLEVBQUUsRUFBRTtBQUN2RTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixXQUFXO0FBQzVCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FB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QWtEO0FBQzFELG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsd0hBQTZDO0FBQ3JELG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsZ0hBQXlDO0FBQ2pELG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsd0dBQXFDO0FBQzdDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEdBQXNDO0FBQzlDLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsMEdBQXNDO0FBQzlDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsNEVBQXVCO0FBQy9CLG1CQUFPLENBQUMsb0VBQW1CO0FBQzNCLG1CQUFPLENBQUMsb0VBQW1CO0FBQzNCLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsZ0hBQXlDO0FBQ2pELG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsb0lBQW1EO0FBQzNELG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsd0dBQXFDO0FBQzdDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsa0hBQTBDO0FBQ2xELG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsd0dBQXFDO0FBQzdDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsb0lBQW1EO0FBQzNELG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsMEVBQXNCO0FBQzlCLG1CQUFPLENBQUMsMEVBQXNCO0FBQzlCLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEVBQXNCO0FBQzlCLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsZ0hBQXlDO0FBQ2pELG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsd0hBQTZDO0FBQ3JELG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1C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QXpFLENBQTNCOztRQUdJaE4sRyxHQUFBQSxjO1FBQ0ErTSxPLEdBQUFBLGtCO1FBQ0FuUyxJLEdBQUFBLGU7UUFDQXBlLE0sR0FBQUEsaUI7UUFDQW1PLFMsR0FBQUEsb0I7UUFDQWhjLFEsR0FBQUEsbUI7UUFDQXErQixrQixHQUFBQSxrQjs7Ozs7Ozs7Ozs7Ozs7Ozs7a0JDTG9CNWtDLE07O0FBTnhCOzs7Ozs7QUFFQTs7OztBQUllLFNBQVNBLE1BQVQsR0FBa0I7QUFDL0IsU0FBTyxtQkFBUW1hLE9BQVIsQ0FBZ0IsSUFBaEIsRUFBc0IsRUFBdEIsQ0FBUDtBQUNEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNSRCxJQUFNemUsVUFBVSxRQUFoQixDLFFBQWtDQSxPLEdBQUFBLE8iLCJmaWxlIjoib2lkYy1jbGllbnQuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL3NyYy9Mb2cuanMnO1xyXG5pbXBvcnQgeyBPaWRjQ2xpZW50IH0gZnJvbSAnLi9zcmMvT2lkY0NsaWVudC5qcyc7XHJcbmltcG9ydCB7IE9pZGNDbGllbnRTZXR0aW5ncyB9IGZyb20gJy4vc3JjL09pZGNDbGllbnRTZXR0aW5ncy5qcyc7XHJcbmltcG9ydCB7IFdlYlN0b3JhZ2VTdGF0ZVN0b3JlIH0gZnJvbSAnLi9zcmMvV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMnO1xyXG5pbXBvcnQgeyBJbk1lbW9yeVdlYlN0b3JhZ2UgfSBmcm9tICcuL3NyYy9Jbk1lbW9yeVdlYlN0b3JhZ2UuanMnO1xyXG5pbXBvcnQgeyBVc2VyTWFuYWdlciB9IGZyb20gJy4vc3JjL1VzZXJNYW5hZ2VyLmpzJztcclxuaW1wb3J0IHsgQWNjZXNzVG9rZW5FdmVudHMgfSBmcm9tICcuL3NyYy9BY2Nlc3NUb2tlbkV2ZW50cy5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vc3JjL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IENvcmRvdmFQb3B1cE5hdmlnYXRvciB9IGZyb20gJy4vc3JjL0NvcmRvdmFQb3B1cE5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IENvcmRvdmFJRnJhbWVOYXZpZ2F0b3IgfSBmcm9tICcuL3NyYy9Db3Jkb3ZhSUZyYW1lTmF2aWdhdG9yLmpzJztcclxuaW1wb3J0IHsgQ2hlY2tTZXNzaW9uSUZyYW1lIH0gZnJvbSAnLi9zcmMvQ2hlY2tTZXNzaW9uSUZyYW1lLmpzJztcclxuaW1wb3J0IHsgVG9rZW5SZXZvY2F0aW9uQ2xpZW50IH0gZnJvbSAnLi9zcmMvVG9rZW5SZXZvY2F0aW9uQ2xpZW50LmpzJztcclxuaW1wb3J0IHsgU2Vzc2lvbk1vbml0b3IgfSBmcm9tICcuL3NyYy9TZXNzaW9uTW9uaXRvci5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vc3JjL0dsb2JhbC5qcyc7XHJcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuL3NyYy9Vc2VyLmpzJztcclxuXHJcbmltcG9ydCB7IFZlcnNpb24gfSBmcm9tICcuL3ZlcnNpb24uanMnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgVmVyc2lvbixcclxuICAgIExvZyxcclxuICAgIE9pZGNDbGllbnQsXHJcbiAgICBPaWRjQ2xpZW50U2V0dGluZ3MsXHJcbiAgICBXZWJTdG9yYWdlU3RhdGVTdG9yZSxcclxuICAgIEluTWVtb3J5V2ViU3RvcmFnZSxcclxuICAgIFVzZXJNYW5hZ2VyLFxyXG4gICAgQWNjZXNzVG9rZW5FdmVudHMsXHJcbiAgICBNZXRhZGF0YVNlcnZpY2UsXHJcbiAgICBDb3Jkb3ZhUG9wdXBOYXZpZ2F0b3IsXHJcbiAgICBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yLFxyXG4gICAgQ2hlY2tTZXNzaW9uSUZyYW1lLFxyXG4gICAgVG9rZW5SZXZvY2F0aW9uQ2xpZW50LFxyXG4gICAgU2Vzc2lvbk1vbml0b3IsXHJcbiAgICBHbG9iYWwsXHJcbiAgICBVc2VyXHJcbn07XHJcbiIsIi8qXHJcbiAqIGpzcnNhc2lnbihhbGwpIDguMC4xMiAoMjAxOC0wNC0yMikgKGMpIDIwMTAtMjAxOCBLZW5qaSBVcnVzaGltYSB8IGtqdXIuZ2l0aHViLmNvbS9qc3JzYXNpZ24vbGljZW5zZVxyXG4gKi9cclxuXHJcbnZhciBuYXZpZ2F0b3IgPSB7fTtcclxubmF2aWdhdG9yLnVzZXJBZ2VudCA9IGZhbHNlO1xyXG5cclxudmFyIHdpbmRvdyA9IHt9O1xyXG5cbi8qIVxyXG5Db3B5cmlnaHQgKGMpIDIwMTEsIFlhaG9vISBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbkNvZGUgbGljZW5zZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlOlxyXG5odHRwOi8vZGV2ZWxvcGVyLnlhaG9vLmNvbS95dWkvbGljZW5zZS5odG1sXHJcbnZlcnNpb246IDIuOS4wXHJcbiovXHJcbmlmKFlBSE9PPT09dW5kZWZpbmVkKXt2YXIgWUFIT089e319WUFIT08ubGFuZz17ZXh0ZW5kOmZ1bmN0aW9uKGcsaCxmKXtpZighaHx8IWcpe3Rocm93IG5ldyBFcnJvcihcIllBSE9PLmxhbmcuZXh0ZW5kIGZhaWxlZCwgcGxlYXNlIGNoZWNrIHRoYXQgYWxsIGRlcGVuZGVuY2llcyBhcmUgaW5jbHVkZWQuXCIpfXZhciBkPWZ1bmN0aW9uKCl7fTtkLnByb3RvdHlwZT1oLnByb3RvdHlwZTtnLnByb3RvdHlwZT1uZXcgZCgpO2cucHJvdG90eXBlLmNvbnN0cnVjdG9yPWc7Zy5zdXBlcmNsYXNzPWgucHJvdG90eXBlO2lmKGgucHJvdG90eXBlLmNvbnN0cnVjdG9yPT1PYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yKXtoLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1ofWlmKGYpe3ZhciBiO2ZvcihiIGluIGYpe2cucHJvdG90eXBlW2JdPWZbYl19dmFyIGU9ZnVuY3Rpb24oKXt9LGM9W1widG9TdHJpbmdcIixcInZhbHVlT2ZcIl07dHJ5e2lmKC9NU0lFLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKXtlPWZ1bmN0aW9uKGosaSl7Zm9yKGI9MDtiPGMubGVuZ3RoO2I9YisxKXt2YXIgbD1jW2JdLGs9aVtsXTtpZih0eXBlb2Ygaz09PVwiZnVuY3Rpb25cIiYmayE9T2JqZWN0LnByb3RvdHlwZVtsXSl7altsXT1rfX19fX1jYXRjaChhKXt9ZShnLnByb3RvdHlwZSxmKX19fTtcbi8qISBDcnlwdG9KUyB2My4xLjIgY29yZS1maXguanNcclxuICogY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbiAqIChjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKiBjb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiAqIFRISVMgSVMgRklYIG9mICdjb3JlLmpzJyB0byBmaXggSG1hYyBpc3N1ZS5cclxuICogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvaXNzdWVzL2RldGFpbD9pZD04NFxyXG4gKiBodHRwczovL2NyeXB0by1qcy5nb29nbGVjb2RlLmNvbS9zdm4taGlzdG9yeS9yNjY3L2JyYW5jaGVzLzMueC9zcmMvY29yZS5qc1xyXG4gKi9cclxudmFyIENyeXB0b0pTPUNyeXB0b0pTfHwoZnVuY3Rpb24oZSxnKXt2YXIgYT17fTt2YXIgYj1hLmxpYj17fTt2YXIgaj1iLkJhc2U9KGZ1bmN0aW9uKCl7ZnVuY3Rpb24gbigpe31yZXR1cm57ZXh0ZW5kOmZ1bmN0aW9uKHApe24ucHJvdG90eXBlPXRoaXM7dmFyIG89bmV3IG4oKTtpZihwKXtvLm1peEluKHApfWlmKCFvLmhhc093blByb3BlcnR5KFwiaW5pdFwiKSl7by5pbml0PWZ1bmN0aW9uKCl7by4kc3VwZXIuaW5pdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fW8uaW5pdC5wcm90b3R5cGU9bztvLiRzdXBlcj10aGlzO3JldHVybiBvfSxjcmVhdGU6ZnVuY3Rpb24oKXt2YXIgbz10aGlzLmV4dGVuZCgpO28uaW5pdC5hcHBseShvLGFyZ3VtZW50cyk7cmV0dXJuIG99LGluaXQ6ZnVuY3Rpb24oKXt9LG1peEluOmZ1bmN0aW9uKHApe2Zvcih2YXIgbyBpbiBwKXtpZihwLmhhc093blByb3BlcnR5KG8pKXt0aGlzW29dPXBbb119fWlmKHAuaGFzT3duUHJvcGVydHkoXCJ0b1N0cmluZ1wiKSl7dGhpcy50b1N0cmluZz1wLnRvU3RyaW5nfX0sY2xvbmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pbml0LnByb3RvdHlwZS5leHRlbmQodGhpcyl9fX0oKSk7dmFyIGw9Yi5Xb3JkQXJyYXk9ai5leHRlbmQoe2luaXQ6ZnVuY3Rpb24obyxuKXtvPXRoaXMud29yZHM9b3x8W107aWYobiE9Zyl7dGhpcy5zaWdCeXRlcz1ufWVsc2V7dGhpcy5zaWdCeXRlcz1vLmxlbmd0aCo0fX0sdG9TdHJpbmc6ZnVuY3Rpb24obil7cmV0dXJuKG58fGgpLnN0cmluZ2lmeSh0aGlzKX0sY29uY2F0OmZ1bmN0aW9uKHQpe3ZhciBxPXRoaXMud29yZHM7dmFyIHA9dC53b3Jkczt2YXIgbj10aGlzLnNpZ0J5dGVzO3ZhciBzPXQuc2lnQnl0ZXM7dGhpcy5jbGFtcCgpO2lmKG4lNCl7Zm9yKHZhciByPTA7cjxzO3IrKyl7dmFyIG89KHBbcj4+PjJdPj4+KDI0LShyJTQpKjgpKSYyNTU7cVsobityKT4+PjJdfD1vPDwoMjQtKChuK3IpJTQpKjgpfX1lbHNle2Zvcih2YXIgcj0wO3I8cztyKz00KXtxWyhuK3IpPj4+Ml09cFtyPj4+Ml19fXRoaXMuc2lnQnl0ZXMrPXM7cmV0dXJuIHRoaXN9LGNsYW1wOmZ1bmN0aW9uKCl7dmFyIG89dGhpcy53b3Jkczt2YXIgbj10aGlzLnNpZ0J5dGVzO29bbj4+PjJdJj00Mjk0OTY3Mjk1PDwoMzItKG4lNCkqOCk7by5sZW5ndGg9ZS5jZWlsKG4vNCl9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIG49ai5jbG9uZS5jYWxsKHRoaXMpO24ud29yZHM9dGhpcy53b3Jkcy5zbGljZSgwKTtyZXR1cm4gbn0scmFuZG9tOmZ1bmN0aW9uKHApe3ZhciBvPVtdO2Zvcih2YXIgbj0wO248cDtuKz00KXtvLnB1c2goKGUucmFuZG9tKCkqNDI5NDk2NzI5Nil8MCl9cmV0dXJuIG5ldyBsLmluaXQobyxwKX19KTt2YXIgbT1hLmVuYz17fTt2YXIgaD1tLkhleD17c3RyaW5naWZ5OmZ1bmN0aW9uKHApe3ZhciByPXAud29yZHM7dmFyIG89cC5zaWdCeXRlczt2YXIgcT1bXTtmb3IodmFyIG49MDtuPG87bisrKXt2YXIgcz0ocltuPj4+Ml0+Pj4oMjQtKG4lNCkqOCkpJjI1NTtxLnB1c2goKHM+Pj40KS50b1N0cmluZygxNikpO3EucHVzaCgocyYxNSkudG9TdHJpbmcoMTYpKX1yZXR1cm4gcS5qb2luKFwiXCIpfSxwYXJzZTpmdW5jdGlvbihwKXt2YXIgbj1wLmxlbmd0aDt2YXIgcT1bXTtmb3IodmFyIG89MDtvPG47bys9Mil7cVtvPj4+M118PXBhcnNlSW50KHAuc3Vic3RyKG8sMiksMTYpPDwoMjQtKG8lOCkqNCl9cmV0dXJuIG5ldyBsLmluaXQocSxuLzIpfX07dmFyIGQ9bS5MYXRpbjE9e3N0cmluZ2lmeTpmdW5jdGlvbihxKXt2YXIgcj1xLndvcmRzO3ZhciBwPXEuc2lnQnl0ZXM7dmFyIG49W107Zm9yKHZhciBvPTA7bzxwO28rKyl7dmFyIHM9KHJbbz4+PjJdPj4+KDI0LShvJTQpKjgpKSYyNTU7bi5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUocykpfXJldHVybiBuLmpvaW4oXCJcIil9LHBhcnNlOmZ1bmN0aW9uKHApe3ZhciBuPXAubGVuZ3RoO3ZhciBxPVtdO2Zvcih2YXIgbz0wO288bjtvKyspe3Fbbz4+PjJdfD0ocC5jaGFyQ29kZUF0KG8pJjI1NSk8PCgyNC0obyU0KSo4KX1yZXR1cm4gbmV3IGwuaW5pdChxLG4pfX07dmFyIGM9bS5VdGY4PXtzdHJpbmdpZnk6ZnVuY3Rpb24obil7dHJ5e3JldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKGQuc3RyaW5naWZ5KG4pKSl9Y2F0Y2gobyl7dGhyb3cgbmV3IEVycm9yKFwiTWFsZm9ybWVkIFVURi04IGRhdGFcIil9fSxwYXJzZTpmdW5jdGlvbihuKXtyZXR1cm4gZC5wYXJzZSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQobikpKX19O3ZhciBpPWIuQnVmZmVyZWRCbG9ja0FsZ29yaXRobT1qLmV4dGVuZCh7cmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLl9kYXRhPW5ldyBsLmluaXQoKTt0aGlzLl9uRGF0YUJ5dGVzPTB9LF9hcHBlbmQ6ZnVuY3Rpb24obil7aWYodHlwZW9mIG49PVwic3RyaW5nXCIpe249Yy5wYXJzZShuKX10aGlzLl9kYXRhLmNvbmNhdChuKTt0aGlzLl9uRGF0YUJ5dGVzKz1uLnNpZ0J5dGVzfSxfcHJvY2VzczpmdW5jdGlvbih3KXt2YXIgcT10aGlzLl9kYXRhO3ZhciB4PXEud29yZHM7dmFyIG49cS5zaWdCeXRlczt2YXIgdD10aGlzLmJsb2NrU2l6ZTt2YXIgdj10KjQ7dmFyIHU9bi92O2lmKHcpe3U9ZS5jZWlsKHUpfWVsc2V7dT1lLm1heCgodXwwKS10aGlzLl9taW5CdWZmZXJTaXplLDApfXZhciBzPXUqdDt2YXIgcj1lLm1pbihzKjQsbik7aWYocyl7Zm9yKHZhciBwPTA7cDxzO3ArPXQpe3RoaXMuX2RvUHJvY2Vzc0Jsb2NrKHgscCl9dmFyIG89eC5zcGxpY2UoMCxzKTtxLnNpZ0J5dGVzLT1yfXJldHVybiBuZXcgbC5pbml0KG8scil9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIG49ai5jbG9uZS5jYWxsKHRoaXMpO24uX2RhdGE9dGhpcy5fZGF0YS5jbG9uZSgpO3JldHVybiBufSxfbWluQnVmZmVyU2l6ZTowfSk7dmFyIGY9Yi5IYXNoZXI9aS5leHRlbmQoe2NmZzpqLmV4dGVuZCgpLGluaXQ6ZnVuY3Rpb24obil7dGhpcy5jZmc9dGhpcy5jZmcuZXh0ZW5kKG4pO3RoaXMucmVzZXQoKX0scmVzZXQ6ZnVuY3Rpb24oKXtpLnJlc2V0LmNhbGwodGhpcyk7dGhpcy5fZG9SZXNldCgpfSx1cGRhdGU6ZnVuY3Rpb24obil7dGhpcy5fYXBwZW5kKG4pO3RoaXMuX3Byb2Nlc3MoKTtyZXR1cm4gdGhpc30sZmluYWxpemU6ZnVuY3Rpb24obil7aWYobil7dGhpcy5fYXBwZW5kKG4pfXZhciBvPXRoaXMuX2RvRmluYWxpemUoKTtyZXR1cm4gb30sYmxvY2tTaXplOjUxMi8zMixfY3JlYXRlSGVscGVyOmZ1bmN0aW9uKG4pe3JldHVybiBmdW5jdGlvbihwLG8pe3JldHVybiBuZXcgbi5pbml0KG8pLmZpbmFsaXplKHApfX0sX2NyZWF0ZUhtYWNIZWxwZXI6ZnVuY3Rpb24obil7cmV0dXJuIGZ1bmN0aW9uKHAsbyl7cmV0dXJuIG5ldyBrLkhNQUMuaW5pdChuLG8pLmZpbmFsaXplKHApfX19KTt2YXIgaz1hLmFsZ289e307cmV0dXJuIGF9KE1hdGgpKTtcbi8qXHJcbkNyeXB0b0pTIHYzLjEuMiB4NjQtY29yZS1taW4uanNcclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbihjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiovXHJcbihmdW5jdGlvbihnKXt2YXIgYT1DcnlwdG9KUyxmPWEubGliLGU9Zi5CYXNlLGg9Zi5Xb3JkQXJyYXksYT1hLng2ND17fTthLldvcmQ9ZS5leHRlbmQoe2luaXQ6ZnVuY3Rpb24oYixjKXt0aGlzLmhpZ2g9Yjt0aGlzLmxvdz1jfX0pO2EuV29yZEFycmF5PWUuZXh0ZW5kKHtpbml0OmZ1bmN0aW9uKGIsYyl7Yj10aGlzLndvcmRzPWJ8fFtdO3RoaXMuc2lnQnl0ZXM9YyE9Zz9jOjgqYi5sZW5ndGh9LHRvWDMyOmZ1bmN0aW9uKCl7Zm9yKHZhciBiPXRoaXMud29yZHMsYz1iLmxlbmd0aCxhPVtdLGQ9MDtkPGM7ZCsrKXt2YXIgZT1iW2RdO2EucHVzaChlLmhpZ2gpO2EucHVzaChlLmxvdyl9cmV0dXJuIGguY3JlYXRlKGEsdGhpcy5zaWdCeXRlcyl9LGNsb25lOmZ1bmN0aW9uKCl7Zm9yKHZhciBiPWUuY2xvbmUuY2FsbCh0aGlzKSxjPWIud29yZHM9dGhpcy53b3Jkcy5zbGljZSgwKSxhPWMubGVuZ3RoLGQ9MDtkPGE7ZCsrKWNbZF09Y1tkXS5jbG9uZSgpO3JldHVybiBifX0pfSkoKTtcclxuXG4vKlxyXG5DcnlwdG9KUyB2My4xLjIgZW5jLWJhc2U2NC5qc1xyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanNcclxuKGMpIDIwMDktMjAxMyBieSBKZWZmIE1vdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcclxuKi9cclxuKGZ1bmN0aW9uKCl7dmFyIGg9Q3J5cHRvSlMsaj1oLmxpYi5Xb3JkQXJyYXk7aC5lbmMuQmFzZTY0PXtzdHJpbmdpZnk6ZnVuY3Rpb24oYil7dmFyIGU9Yi53b3JkcyxmPWIuc2lnQnl0ZXMsYz10aGlzLl9tYXA7Yi5jbGFtcCgpO2I9W107Zm9yKHZhciBhPTA7YTxmO2ErPTMpZm9yKHZhciBkPShlW2E+Pj4yXT4+PjI0LTgqKGElNCkmMjU1KTw8MTZ8KGVbYSsxPj4+Ml0+Pj4yNC04KigoYSsxKSU0KSYyNTUpPDw4fGVbYSsyPj4+Ml0+Pj4yNC04KigoYSsyKSU0KSYyNTUsZz0wOzQ+ZyYmYSswLjc1Kmc8ZjtnKyspYi5wdXNoKGMuY2hhckF0KGQ+Pj42KigzLWcpJjYzKSk7aWYoZT1jLmNoYXJBdCg2NCkpZm9yKDtiLmxlbmd0aCU0OyliLnB1c2goZSk7cmV0dXJuIGIuam9pbihcIlwiKX0scGFyc2U6ZnVuY3Rpb24oYil7dmFyIGU9Yi5sZW5ndGgsZj10aGlzLl9tYXAsYz1mLmNoYXJBdCg2NCk7YyYmKGM9Yi5pbmRleE9mKGMpLC0xIT1jJiYoZT1jKSk7Zm9yKHZhciBjPVtdLGE9MCxkPTA7ZDxcclxuZTtkKyspaWYoZCU0KXt2YXIgZz1mLmluZGV4T2YoYi5jaGFyQXQoZC0xKSk8PDIqKGQlNCksaD1mLmluZGV4T2YoYi5jaGFyQXQoZCkpPj4+Ni0yKihkJTQpO2NbYT4+PjJdfD0oZ3xoKTw8MjQtOCooYSU0KTthKyt9cmV0dXJuIGouY3JlYXRlKGMsYSl9LF9tYXA6XCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwifX0pKCk7XHJcblxuLypcclxuQ3J5cHRvSlMgdjMuMS4yIHNoYTI1Ni1taW4uanNcclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbihjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiovXHJcbihmdW5jdGlvbihrKXtmb3IodmFyIGc9Q3J5cHRvSlMsaD1nLmxpYix2PWguV29yZEFycmF5LGo9aC5IYXNoZXIsaD1nLmFsZ28scz1bXSx0PVtdLHU9ZnVuY3Rpb24ocSl7cmV0dXJuIDQyOTQ5NjcyOTYqKHEtKHF8MCkpfDB9LGw9MixiPTA7NjQ+Yjspe3ZhciBkO2E6e2Q9bDtmb3IodmFyIHc9ay5zcXJ0KGQpLHI9MjtyPD13O3IrKylpZighKGQlcikpe2Q9ITE7YnJlYWsgYX1kPSEwfWQmJig4PmImJihzW2JdPXUoay5wb3cobCwwLjUpKSksdFtiXT11KGsucG93KGwsMS8zKSksYisrKTtsKyt9dmFyIG49W10saD1oLlNIQTI1Nj1qLmV4dGVuZCh7X2RvUmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLl9oYXNoPW5ldyB2LmluaXQocy5zbGljZSgwKSl9LF9kb1Byb2Nlc3NCbG9jazpmdW5jdGlvbihxLGgpe2Zvcih2YXIgYT10aGlzLl9oYXNoLndvcmRzLGM9YVswXSxkPWFbMV0sYj1hWzJdLGs9YVszXSxmPWFbNF0sZz1hWzVdLGo9YVs2XSxsPWFbN10sZT0wOzY0PmU7ZSsrKXtpZigxNj5lKW5bZV09XHJcbnFbaCtlXXwwO2Vsc2V7dmFyIG09bltlLTE1XSxwPW5bZS0yXTtuW2VdPSgobTw8MjV8bT4+PjcpXihtPDwxNHxtPj4+MTgpXm0+Pj4zKStuW2UtN10rKChwPDwxNXxwPj4+MTcpXihwPDwxM3xwPj4+MTkpXnA+Pj4xMCkrbltlLTE2XX1tPWwrKChmPDwyNnxmPj4+NileKGY8PDIxfGY+Pj4xMSleKGY8PDd8Zj4+PjI1KSkrKGYmZ15+ZiZqKSt0W2VdK25bZV07cD0oKGM8PDMwfGM+Pj4yKV4oYzw8MTl8Yz4+PjEzKV4oYzw8MTB8Yz4+PjIyKSkrKGMmZF5jJmJeZCZiKTtsPWo7aj1nO2c9ZjtmPWsrbXwwO2s9YjtiPWQ7ZD1jO2M9bStwfDB9YVswXT1hWzBdK2N8MDthWzFdPWFbMV0rZHwwO2FbMl09YVsyXStifDA7YVszXT1hWzNdK2t8MDthWzRdPWFbNF0rZnwwO2FbNV09YVs1XStnfDA7YVs2XT1hWzZdK2p8MDthWzddPWFbN10rbHwwfSxfZG9GaW5hbGl6ZTpmdW5jdGlvbigpe3ZhciBkPXRoaXMuX2RhdGEsYj1kLndvcmRzLGE9OCp0aGlzLl9uRGF0YUJ5dGVzLGM9OCpkLnNpZ0J5dGVzO1xyXG5iW2M+Pj41XXw9MTI4PDwyNC1jJTMyO2JbKGMrNjQ+Pj45PDw0KSsxNF09ay5mbG9vcihhLzQyOTQ5NjcyOTYpO2JbKGMrNjQ+Pj45PDw0KSsxNV09YTtkLnNpZ0J5dGVzPTQqYi5sZW5ndGg7dGhpcy5fcHJvY2VzcygpO3JldHVybiB0aGlzLl9oYXNofSxjbG9uZTpmdW5jdGlvbigpe3ZhciBiPWouY2xvbmUuY2FsbCh0aGlzKTtiLl9oYXNoPXRoaXMuX2hhc2guY2xvbmUoKTtyZXR1cm4gYn19KTtnLlNIQTI1Nj1qLl9jcmVhdGVIZWxwZXIoaCk7Zy5IbWFjU0hBMjU2PWouX2NyZWF0ZUhtYWNIZWxwZXIoaCl9KShNYXRoKTtcclxuXG4vKlxyXG5DcnlwdG9KUyB2My4xLjIgc2hhNTEyLW1pbi5qc1xyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanNcclxuKGMpIDIwMDktMjAxMyBieSBKZWZmIE1vdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcclxuKi9cclxuKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gYSgpe3JldHVybiBkLmNyZWF0ZS5hcHBseShkLGFyZ3VtZW50cyl9Zm9yKHZhciBuPUNyeXB0b0pTLHI9bi5saWIuSGFzaGVyLGU9bi54NjQsZD1lLldvcmQsVD1lLldvcmRBcnJheSxlPW4uYWxnbyxlYT1bYSgxMTE2MzUyNDA4LDM2MDk3Njc0NTgpLGEoMTg5OTQ0NzQ0MSw2MDI4OTE3MjUpLGEoMzA0OTMyMzQ3MSwzOTY0NDg0Mzk5KSxhKDM5MjEwMDk1NzMsMjE3MzI5NTU0OCksYSg5NjE5ODcxNjMsNDA4MTYyODQ3MiksYSgxNTA4OTcwOTkzLDMwNTM4MzQyNjUpLGEoMjQ1MzYzNTc0OCwyOTM3NjcxNTc5KSxhKDI4NzA3NjMyMjEsMzY2NDYwOTU2MCksYSgzNjI0MzgxMDgwLDI3MzQ4ODMzOTQpLGEoMzEwNTk4NDAxLDExNjQ5OTY1NDIpLGEoNjA3MjI1Mjc4LDEzMjM2MTA3NjQpLGEoMTQyNjg4MTk4NywzNTkwMzA0OTk0KSxhKDE5MjUwNzgzODgsNDA2ODE4MjM4MyksYSgyMTYyMDc4MjA2LDk5MTMzNjExMyksYSgyNjE0ODg4MTAzLDYzMzgwMzMxNyksXHJcbmEoMzI0ODIyMjU4MCwzNDc5Nzc0ODY4KSxhKDM4MzUzOTA0MDEsMjY2NjYxMzQ1OCksYSg0MDIyMjI0Nzc0LDk0NDcxMTEzOSksYSgyNjQzNDcwNzgsMjM0MTI2Mjc3MyksYSg2MDQ4MDc2MjgsMjAwNzgwMDkzMyksYSg3NzAyNTU5ODMsMTQ5NTk5MDkwMSksYSgxMjQ5MTUwMTIyLDE4NTY0MzEyMzUpLGEoMTU1NTA4MTY5MiwzMTc1MjE4MTMyKSxhKDE5OTYwNjQ5ODYsMjE5ODk1MDgzNyksYSgyNTU0MjIwODgyLDM5OTk3MTkzMzkpLGEoMjgyMTgzNDM0OSw3NjY3ODQwMTYpLGEoMjk1Mjk5NjgwOCwyNTY2NTk0ODc5KSxhKDMyMTAzMTM2NzEsMzIwMzMzNzk1NiksYSgzMzM2NTcxODkxLDEwMzQ0NTcwMjYpLGEoMzU4NDUyODcxMSwyNDY2OTQ4OTAxKSxhKDExMzkyNjk5MywzNzU4MzI2MzgzKSxhKDMzODI0MTg5NSwxNjg3MTc5MzYpLGEoNjY2MzA3MjA1LDExODgxNzk5NjQpLGEoNzczNTI5OTEyLDE1NDYwNDU3MzQpLGEoMTI5NDc1NzM3MiwxNTIyODA1NDg1KSxhKDEzOTYxODIyOTEsXHJcbjI2NDM4MzM4MjMpLGEoMTY5NTE4MzcwMCwyMzQzNTI3MzkwKSxhKDE5ODY2NjEwNTEsMTAxNDQ3NzQ4MCksYSgyMTc3MDI2MzUwLDEyMDY3NTkxNDIpLGEoMjQ1Njk1NjAzNywzNDQwNzc2MjcpLGEoMjczMDQ4NTkyMSwxMjkwODYzNDYwKSxhKDI4MjAzMDI0MTEsMzE1ODQ1NDI3MyksYSgzMjU5NzMwODAwLDM1MDU5NTI2NTcpLGEoMzM0NTc2NDc3MSwxMDYyMTcwMDgpLGEoMzUxNjA2NTgxNywzNjA2MDA4MzQ0KSxhKDM2MDAzNTI4MDQsMTQzMjcyNTc3NiksYSg0MDk0NTcxOTA5LDE0NjcwMzE1OTQpLGEoMjc1NDIzMzQ0LDg1MTE2OTcyMCksYSg0MzAyMjc3MzQsMzEwMDgyMzc1MiksYSg1MDY5NDg2MTYsMTM2MzI1ODE5NSksYSg2NTkwNjA1NTYsMzc1MDY4NTU5MyksYSg4ODM5OTc4NzcsMzc4NTA1MDI4MCksYSg5NTgxMzk1NzEsMzMxODMwNzQyNyksYSgxMzIyODIyMjE4LDM4MTI3MjM0MDMpLGEoMTUzNzAwMjA2MywyMDAzMDM0OTk1KSxhKDE3NDc4NzM3NzksMzYwMjAzNjg5OSksXHJcbmEoMTk1NTU2MjIyMiwxNTc1OTkwMDEyKSxhKDIwMjQxMDQ4MTUsMTEyNTU5MjkyOCksYSgyMjI3NzMwNDUyLDI3MTY5MDQzMDYpLGEoMjM2MTg1MjQyNCw0NDI3NzYwNDQpLGEoMjQyODQzNjQ3NCw1OTM2OTgzNDQpLGEoMjc1NjczNDE4NywzNzMzMTEwMjQ5KSxhKDMyMDQwMzE0NzksMjk5OTM1MTU3MyksYSgzMzI5MzI1Mjk4LDM4MTU5MjA0MjcpLGEoMzM5MTU2OTYxNCwzOTI4MzgzOTAwKSxhKDM1MTUyNjcyNzEsNTY2MjgwNzExKSxhKDM5NDAxODc2MDYsMzQ1NDA2OTUzNCksYSg0MTE4NjMwMjcxLDQwMDAyMzk5OTIpLGEoMTE2NDE4NDc0LDE5MTQxMzg1NTQpLGEoMTc0MjkyNDIxLDI3MzEwNTUyNzApLGEoMjg5MzgwMzU2LDMyMDM5OTMwMDYpLGEoNDYwMzkzMjY5LDMyMDYyMDMxNSksYSg2ODU0NzE3MzMsNTg3NDk2ODM2KSxhKDg1MjE0Mjk3MSwxMDg2NzkyODUxKSxhKDEwMTcwMzYyOTgsMzY1NTQzMTAwKSxhKDExMjYwMDA1ODAsMjYxODI5NzY3NiksYSgxMjg4MDMzNDcwLFxyXG4zNDA5ODU1MTU4KSxhKDE1MDE1MDU5NDgsNDIzNDUwOTg2NiksYSgxNjA3MTY3OTE1LDk4NzE2NzQ2OCksYSgxODE2NDAyMzE2LDEyNDYxODk1OTEpXSx2PVtdLHc9MDs4MD53O3crKyl2W3ddPWEoKTtlPWUuU0hBNTEyPXIuZXh0ZW5kKHtfZG9SZXNldDpmdW5jdGlvbigpe3RoaXMuX2hhc2g9bmV3IFQuaW5pdChbbmV3IGQuaW5pdCgxNzc5MDMzNzAzLDQwODkyMzU3MjApLG5ldyBkLmluaXQoMzE0NDEzNDI3NywyMjI3ODczNTk1KSxuZXcgZC5pbml0KDEwMTM5MDQyNDIsNDI3MTE3NTcyMyksbmV3IGQuaW5pdCgyNzczNDgwNzYyLDE1OTU3NTAxMjkpLG5ldyBkLmluaXQoMTM1OTg5MzExOSwyOTE3NTY1MTM3KSxuZXcgZC5pbml0KDI2MDA4MjI5MjQsNzI1NTExMTk5KSxuZXcgZC5pbml0KDUyODczNDYzNSw0MjE1Mzg5NTQ3KSxuZXcgZC5pbml0KDE1NDE0NTkyMjUsMzI3MDMzMjA5KV0pfSxfZG9Qcm9jZXNzQmxvY2s6ZnVuY3Rpb24oYSxkKXtmb3IodmFyIGY9dGhpcy5faGFzaC53b3JkcyxcclxuRj1mWzBdLGU9ZlsxXSxuPWZbMl0scj1mWzNdLEc9Zls0XSxIPWZbNV0sST1mWzZdLGY9Zls3XSx3PUYuaGlnaCxKPUYubG93LFg9ZS5oaWdoLEs9ZS5sb3csWT1uLmhpZ2gsTD1uLmxvdyxaPXIuaGlnaCxNPXIubG93LCQ9Ry5oaWdoLE49Ry5sb3csYWE9SC5oaWdoLE89SC5sb3csYmE9SS5oaWdoLFA9SS5sb3csY2E9Zi5oaWdoLFE9Zi5sb3csaz13LGc9Six6PVgseD1LLEE9WSx5PUwsVT1aLEI9TSxsPSQsaD1OLFI9YWEsQz1PLFM9YmEsRD1QLFY9Y2EsRT1RLG09MDs4MD5tO20rKyl7dmFyIHM9dlttXTtpZigxNj5tKXZhciBqPXMuaGlnaD1hW2QrMiptXXwwLGI9cy5sb3c9YVtkKzIqbSsxXXwwO2Vsc2V7dmFyIGo9dlttLTE1XSxiPWouaGlnaCxwPWoubG93LGo9KGI+Pj4xfHA8PDMxKV4oYj4+Pjh8cDw8MjQpXmI+Pj43LHA9KHA+Pj4xfGI8PDMxKV4ocD4+Pjh8Yjw8MjQpXihwPj4+N3xiPDwyNSksdT12W20tMl0sYj11LmhpZ2gsYz11Lmxvdyx1PShiPj4+MTl8Yzw8MTMpXihiPDxcclxuM3xjPj4+MjkpXmI+Pj42LGM9KGM+Pj4xOXxiPDwxMyleKGM8PDN8Yj4+PjI5KV4oYz4+PjZ8Yjw8MjYpLGI9dlttLTddLFc9Yi5oaWdoLHQ9dlttLTE2XSxxPXQuaGlnaCx0PXQubG93LGI9cCtiLmxvdyxqPWorVysoYj4+PjA8cD4+PjA/MTowKSxiPWIrYyxqPWordSsoYj4+PjA8Yz4+PjA/MTowKSxiPWIrdCxqPWorcSsoYj4+PjA8dD4+PjA/MTowKTtzLmhpZ2g9ajtzLmxvdz1ifXZhciBXPWwmUl5+bCZTLHQ9aCZDXn5oJkQscz1rJnpeayZBXnomQSxUPWcmeF5nJnleeCZ5LHA9KGs+Pj4yOHxnPDw0KV4oazw8MzB8Zz4+PjIpXihrPDwyNXxnPj4+NyksdT0oZz4+PjI4fGs8PDQpXihnPDwzMHxrPj4+MileKGc8PDI1fGs+Pj43KSxjPWVhW21dLGZhPWMuaGlnaCxkYT1jLmxvdyxjPUUrKChoPj4+MTR8bDw8MTgpXihoPj4+MTh8bDw8MTQpXihoPDwyM3xsPj4+OSkpLHE9VisoKGw+Pj4xNHxoPDwxOCleKGw+Pj4xOHxoPDwxNCleKGw8PDIzfGg+Pj45KSkrKGM+Pj4wPEU+Pj4wPzE6XHJcbjApLGM9Yyt0LHE9cStXKyhjPj4+MDx0Pj4+MD8xOjApLGM9YytkYSxxPXErZmErKGM+Pj4wPGRhPj4+MD8xOjApLGM9YytiLHE9cStqKyhjPj4+MDxiPj4+MD8xOjApLGI9dStULHM9cCtzKyhiPj4+MDx1Pj4+MD8xOjApLFY9UyxFPUQsUz1SLEQ9QyxSPWwsQz1oLGg9QitjfDAsbD1VK3ErKGg+Pj4wPEI+Pj4wPzE6MCl8MCxVPUEsQj15LEE9eix5PXgsej1rLHg9ZyxnPWMrYnwwLGs9cStzKyhnPj4+MDxjPj4+MD8xOjApfDB9Sj1GLmxvdz1KK2c7Ri5oaWdoPXcraysoSj4+PjA8Zz4+PjA/MTowKTtLPWUubG93PUsreDtlLmhpZ2g9WCt6KyhLPj4+MDx4Pj4+MD8xOjApO0w9bi5sb3c9TCt5O24uaGlnaD1ZK0ErKEw+Pj4wPHk+Pj4wPzE6MCk7TT1yLmxvdz1NK0I7ci5oaWdoPVorVSsoTT4+PjA8Qj4+PjA/MTowKTtOPUcubG93PU4raDtHLmhpZ2g9JCtsKyhOPj4+MDxoPj4+MD8xOjApO089SC5sb3c9TytDO0guaGlnaD1hYStSKyhPPj4+MDxDPj4+MD8xOjApO1A9SS5sb3c9UCtEO1xyXG5JLmhpZ2g9YmErUysoUD4+PjA8RD4+PjA/MTowKTtRPWYubG93PVErRTtmLmhpZ2g9Y2ErVisoUT4+PjA8RT4+PjA/MTowKX0sX2RvRmluYWxpemU6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLl9kYXRhLGQ9YS53b3JkcyxmPTgqdGhpcy5fbkRhdGFCeXRlcyxlPTgqYS5zaWdCeXRlcztkW2U+Pj41XXw9MTI4PDwyNC1lJTMyO2RbKGUrMTI4Pj4+MTA8PDUpKzMwXT1NYXRoLmZsb29yKGYvNDI5NDk2NzI5Nik7ZFsoZSsxMjg+Pj4xMDw8NSkrMzFdPWY7YS5zaWdCeXRlcz00KmQubGVuZ3RoO3RoaXMuX3Byb2Nlc3MoKTtyZXR1cm4gdGhpcy5faGFzaC50b1gzMigpfSxjbG9uZTpmdW5jdGlvbigpe3ZhciBhPXIuY2xvbmUuY2FsbCh0aGlzKTthLl9oYXNoPXRoaXMuX2hhc2guY2xvbmUoKTtyZXR1cm4gYX0sYmxvY2tTaXplOjMyfSk7bi5TSEE1MTI9ci5fY3JlYXRlSGVscGVyKGUpO24uSG1hY1NIQTUxMj1yLl9jcmVhdGVIbWFjSGVscGVyKGUpfSkoKTtcclxuXG4vKlxyXG5DcnlwdG9KUyB2My4xLjIgc2hhMzg0LW1pbi5qc1xyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanNcclxuKGMpIDIwMDktMjAxMyBieSBKZWZmIE1vdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcclxuKi9cclxuKGZ1bmN0aW9uKCl7dmFyIGM9Q3J5cHRvSlMsYT1jLng2NCxiPWEuV29yZCxlPWEuV29yZEFycmF5LGE9Yy5hbGdvLGQ9YS5TSEE1MTIsYT1hLlNIQTM4ND1kLmV4dGVuZCh7X2RvUmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLl9oYXNoPW5ldyBlLmluaXQoW25ldyBiLmluaXQoMzQxODA3MDM2NSwzMjM4MzcxMDMyKSxuZXcgYi5pbml0KDE2NTQyNzAyNTAsOTE0MTUwNjYzKSxuZXcgYi5pbml0KDI0Mzg1MjkzNzAsODEyNzAyOTk5KSxuZXcgYi5pbml0KDM1NTQ2MjM2MCw0MTQ0OTEyNjk3KSxuZXcgYi5pbml0KDE3MzE0MDU0MTUsNDI5MDc3NTg1NyksbmV3IGIuaW5pdCgyMzk0MTgwMjMxLDE3NTA2MDMwMjUpLG5ldyBiLmluaXQoMzY3NTAwODUyNSwxNjk0MDc2ODM5KSxuZXcgYi5pbml0KDEyMDMwNjI4MTMsMzIwNDA3NTQyOCldKX0sX2RvRmluYWxpemU6ZnVuY3Rpb24oKXt2YXIgYT1kLl9kb0ZpbmFsaXplLmNhbGwodGhpcyk7YS5zaWdCeXRlcy09MTY7cmV0dXJuIGF9fSk7Yy5TSEEzODQ9XHJcbmQuX2NyZWF0ZUhlbHBlcihhKTtjLkhtYWNTSEEzODQ9ZC5fY3JlYXRlSG1hY0hlbHBlcihhKX0pKCk7XHJcblxuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG52YXIgYjY0bWFwPVwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiO3ZhciBiNjRwYWQ9XCI9XCI7ZnVuY3Rpb24gaGV4MmI2NChkKXt2YXIgYjt2YXIgZTt2YXIgYT1cIlwiO2ZvcihiPTA7YiszPD1kLmxlbmd0aDtiKz0zKXtlPXBhcnNlSW50KGQuc3Vic3RyaW5nKGIsYiszKSwxNik7YSs9YjY0bWFwLmNoYXJBdChlPj42KStiNjRtYXAuY2hhckF0KGUmNjMpfWlmKGIrMT09ZC5sZW5ndGgpe2U9cGFyc2VJbnQoZC5zdWJzdHJpbmcoYixiKzEpLDE2KTthKz1iNjRtYXAuY2hhckF0KGU8PDIpfWVsc2V7aWYoYisyPT1kLmxlbmd0aCl7ZT1wYXJzZUludChkLnN1YnN0cmluZyhiLGIrMiksMTYpO2ErPWI2NG1hcC5jaGFyQXQoZT4+MikrYjY0bWFwLmNoYXJBdCgoZSYzKTw8NCl9fWlmKGI2NHBhZCl7d2hpbGUoKGEubGVuZ3RoJjMpPjApe2ErPWI2NHBhZH19cmV0dXJuIGF9ZnVuY3Rpb24gYjY0dG9oZXgoZil7dmFyIGQ9XCJcIjt2YXIgZTt2YXIgYj0wO3ZhciBjO3ZhciBhO2ZvcihlPTA7ZTxmLmxlbmd0aDsrK2Upe2lmKGYuY2hhckF0KGUpPT1iNjRwYWQpe2JyZWFrfWE9YjY0bWFwLmluZGV4T2YoZi5jaGFyQXQoZSkpO2lmKGE8MCl7Y29udGludWV9aWYoYj09MCl7ZCs9aW50MmNoYXIoYT4+Mik7Yz1hJjM7Yj0xfWVsc2V7aWYoYj09MSl7ZCs9aW50MmNoYXIoKGM8PDIpfChhPj40KSk7Yz1hJjE1O2I9Mn1lbHNle2lmKGI9PTIpe2QrPWludDJjaGFyKGMpO2QrPWludDJjaGFyKGE+PjIpO2M9YSYzO2I9M31lbHNle2QrPWludDJjaGFyKChjPDwyKXwoYT4+NCkpO2QrPWludDJjaGFyKGEmMTUpO2I9MH19fX1pZihiPT0xKXtkKz1pbnQyY2hhcihjPDwyKX1yZXR1cm4gZH1mdW5jdGlvbiBiNjR0b0JBKGUpe3ZhciBkPWI2NHRvaGV4KGUpO3ZhciBjO3ZhciBiPW5ldyBBcnJheSgpO2ZvcihjPTA7MipjPGQubGVuZ3RoOysrYyl7YltjXT1wYXJzZUludChkLnN1YnN0cmluZygyKmMsMipjKzIpLDE2KX1yZXR1cm4gYn07XG4vKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi9cclxuICovXHJcbnZhciBkYml0czt2YXIgY2FuYXJ5PTI0NDgzNzgxNDA5NDU5MDt2YXIgal9sbT0oKGNhbmFyeSYxNjc3NzIxNSk9PTE1NzE1MDcwKTtmdW5jdGlvbiBCaWdJbnRlZ2VyKGUsZCxmKXtpZihlIT1udWxsKXtpZihcIm51bWJlclwiPT10eXBlb2YgZSl7dGhpcy5mcm9tTnVtYmVyKGUsZCxmKX1lbHNle2lmKGQ9PW51bGwmJlwic3RyaW5nXCIhPXR5cGVvZiBlKXt0aGlzLmZyb21TdHJpbmcoZSwyNTYpfWVsc2V7dGhpcy5mcm9tU3RyaW5nKGUsZCl9fX19ZnVuY3Rpb24gbmJpKCl7cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKG51bGwpfWZ1bmN0aW9uIGFtMShmLGEsYixlLGgsZyl7d2hpbGUoLS1nPj0wKXt2YXIgZD1hKnRoaXNbZisrXStiW2VdK2g7aD1NYXRoLmZsb29yKGQvNjcxMDg4NjQpO2JbZSsrXT1kJjY3MTA4ODYzfXJldHVybiBofWZ1bmN0aW9uIGFtMihmLHEscixlLG8sYSl7dmFyIGs9cSYzMjc2NyxwPXE+PjE1O3doaWxlKC0tYT49MCl7dmFyIGQ9dGhpc1tmXSYzMjc2Nzt2YXIgZz10aGlzW2YrK10+PjE1O3ZhciBiPXAqZCtnKms7ZD1rKmQrKChiJjMyNzY3KTw8MTUpK3JbZV0rKG8mMTA3Mzc0MTgyMyk7bz0oZD4+PjMwKSsoYj4+PjE1KStwKmcrKG8+Pj4zMCk7cltlKytdPWQmMTA3Mzc0MTgyM31yZXR1cm4gb31mdW5jdGlvbiBhbTMoZixxLHIsZSxvLGEpe3ZhciBrPXEmMTYzODMscD1xPj4xNDt3aGlsZSgtLWE+PTApe3ZhciBkPXRoaXNbZl0mMTYzODM7dmFyIGc9dGhpc1tmKytdPj4xNDt2YXIgYj1wKmQrZyprO2Q9aypkKygoYiYxNjM4Myk8PDE0KStyW2VdK287bz0oZD4+MjgpKyhiPj4xNCkrcCpnO3JbZSsrXT1kJjI2ODQzNTQ1NX1yZXR1cm4gb31pZihqX2xtJiYobmF2aWdhdG9yLmFwcE5hbWU9PVwiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyXCIpKXtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbT1hbTI7ZGJpdHM9MzB9ZWxzZXtpZihqX2xtJiYobmF2aWdhdG9yLmFwcE5hbWUhPVwiTmV0c2NhcGVcIikpe0JpZ0ludGVnZXIucHJvdG90eXBlLmFtPWFtMTtkYml0cz0yNn1lbHNle0JpZ0ludGVnZXIucHJvdG90eXBlLmFtPWFtMztkYml0cz0yOH19QmlnSW50ZWdlci5wcm90b3R5cGUuREI9ZGJpdHM7QmlnSW50ZWdlci5wcm90b3R5cGUuRE09KCgxPDxkYml0cyktMSk7QmlnSW50ZWdlci5wcm90b3R5cGUuRFY9KDE8PGRiaXRzKTt2YXIgQklfRlA9NTI7QmlnSW50ZWdlci5wcm90b3R5cGUuRlY9TWF0aC5wb3coMixCSV9GUCk7QmlnSW50ZWdlci5wcm90b3R5cGUuRjE9QklfRlAtZGJpdHM7QmlnSW50ZWdlci5wcm90b3R5cGUuRjI9MipkYml0cy1CSV9GUDt2YXIgQklfUk09XCIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIjt2YXIgQklfUkM9bmV3IEFycmF5KCk7dmFyIHJyLHZ2O3JyPVwiMFwiLmNoYXJDb2RlQXQoMCk7Zm9yKHZ2PTA7dnY8PTk7Kyt2dil7QklfUkNbcnIrK109dnZ9cnI9XCJhXCIuY2hhckNvZGVBdCgwKTtmb3IodnY9MTA7dnY8MzY7Kyt2dil7QklfUkNbcnIrK109dnZ9cnI9XCJBXCIuY2hhckNvZGVBdCgwKTtmb3IodnY9MTA7dnY8MzY7Kyt2dil7QklfUkNbcnIrK109dnZ9ZnVuY3Rpb24gaW50MmNoYXIoYSl7cmV0dXJuIEJJX1JNLmNoYXJBdChhKX1mdW5jdGlvbiBpbnRBdChiLGEpe3ZhciBkPUJJX1JDW2IuY2hhckNvZGVBdChhKV07cmV0dXJuKGQ9PW51bGwpPy0xOmR9ZnVuY3Rpb24gYm5wQ29weVRvKGIpe2Zvcih2YXIgYT10aGlzLnQtMTthPj0wOy0tYSl7YlthXT10aGlzW2FdfWIudD10aGlzLnQ7Yi5zPXRoaXMuc31mdW5jdGlvbiBibnBGcm9tSW50KGEpe3RoaXMudD0xO3RoaXMucz0oYTwwKT8tMTowO2lmKGE+MCl7dGhpc1swXT1hfWVsc2V7aWYoYTwtMSl7dGhpc1swXT1hK3RoaXMuRFZ9ZWxzZXt0aGlzLnQ9MH19fWZ1bmN0aW9uIG5idihhKXt2YXIgYj1uYmkoKTtiLmZyb21JbnQoYSk7cmV0dXJuIGJ9ZnVuY3Rpb24gYm5wRnJvbVN0cmluZyhoLGMpe3ZhciBlO2lmKGM9PTE2KXtlPTR9ZWxzZXtpZihjPT04KXtlPTN9ZWxzZXtpZihjPT0yNTYpe2U9OH1lbHNle2lmKGM9PTIpe2U9MX1lbHNle2lmKGM9PTMyKXtlPTV9ZWxzZXtpZihjPT00KXtlPTJ9ZWxzZXt0aGlzLmZyb21SYWRpeChoLGMpO3JldHVybn19fX19fXRoaXMudD0wO3RoaXMucz0wO3ZhciBnPWgubGVuZ3RoLGQ9ZmFsc2UsZj0wO3doaWxlKC0tZz49MCl7dmFyIGE9KGU9PTgpP2hbZ10mMjU1OmludEF0KGgsZyk7aWYoYTwwKXtpZihoLmNoYXJBdChnKT09XCItXCIpe2Q9dHJ1ZX1jb250aW51ZX1kPWZhbHNlO2lmKGY9PTApe3RoaXNbdGhpcy50KytdPWF9ZWxzZXtpZihmK2U+dGhpcy5EQil7dGhpc1t0aGlzLnQtMV18PShhJigoMTw8KHRoaXMuREItZikpLTEpKTw8Zjt0aGlzW3RoaXMudCsrXT0oYT4+KHRoaXMuREItZikpfWVsc2V7dGhpc1t0aGlzLnQtMV18PWE8PGZ9fWYrPWU7aWYoZj49dGhpcy5EQil7Zi09dGhpcy5EQn19aWYoZT09OCYmKGhbMF0mMTI4KSE9MCl7dGhpcy5zPS0xO2lmKGY+MCl7dGhpc1t0aGlzLnQtMV18PSgoMTw8KHRoaXMuREItZikpLTEpPDxmfX10aGlzLmNsYW1wKCk7aWYoZCl7QmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyl9fWZ1bmN0aW9uIGJucENsYW1wKCl7dmFyIGE9dGhpcy5zJnRoaXMuRE07d2hpbGUodGhpcy50PjAmJnRoaXNbdGhpcy50LTFdPT1hKXstLXRoaXMudH19ZnVuY3Rpb24gYm5Ub1N0cmluZyhjKXtpZih0aGlzLnM8MCl7cmV0dXJuXCItXCIrdGhpcy5uZWdhdGUoKS50b1N0cmluZyhjKX12YXIgZTtpZihjPT0xNil7ZT00fWVsc2V7aWYoYz09OCl7ZT0zfWVsc2V7aWYoYz09Mil7ZT0xfWVsc2V7aWYoYz09MzIpe2U9NX1lbHNle2lmKGM9PTQpe2U9Mn1lbHNle3JldHVybiB0aGlzLnRvUmFkaXgoYyl9fX19fXZhciBnPSgxPDxlKS0xLGwsYT1mYWxzZSxoPVwiXCIsZj10aGlzLnQ7dmFyIGo9dGhpcy5EQi0oZip0aGlzLkRCKSVlO2lmKGYtLT4wKXtpZihqPHRoaXMuREImJihsPXRoaXNbZl0+PmopPjApe2E9dHJ1ZTtoPWludDJjaGFyKGwpfXdoaWxlKGY+PTApe2lmKGo8ZSl7bD0odGhpc1tmXSYoKDE8PGopLTEpKTw8KGUtaik7bHw9dGhpc1stLWZdPj4oais9dGhpcy5EQi1lKX1lbHNle2w9KHRoaXNbZl0+PihqLT1lKSkmZztpZihqPD0wKXtqKz10aGlzLkRCOy0tZn19aWYobD4wKXthPXRydWV9aWYoYSl7aCs9aW50MmNoYXIobCl9fX1yZXR1cm4gYT9oOlwiMFwifWZ1bmN0aW9uIGJuTmVnYXRlKCl7dmFyIGE9bmJpKCk7QmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsYSk7cmV0dXJuIGF9ZnVuY3Rpb24gYm5BYnMoKXtyZXR1cm4odGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpc31mdW5jdGlvbiBibkNvbXBhcmVUbyhiKXt2YXIgZD10aGlzLnMtYi5zO2lmKGQhPTApe3JldHVybiBkfXZhciBjPXRoaXMudDtkPWMtYi50O2lmKGQhPTApe3JldHVybih0aGlzLnM8MCk/LWQ6ZH13aGlsZSgtLWM+PTApe2lmKChkPXRoaXNbY10tYltjXSkhPTApe3JldHVybiBkfX1yZXR1cm4gMH1mdW5jdGlvbiBuYml0cyhhKXt2YXIgYz0xLGI7aWYoKGI9YT4+PjE2KSE9MCl7YT1iO2MrPTE2fWlmKChiPWE+PjgpIT0wKXthPWI7Yys9OH1pZigoYj1hPj40KSE9MCl7YT1iO2MrPTR9aWYoKGI9YT4+MikhPTApe2E9YjtjKz0yfWlmKChiPWE+PjEpIT0wKXthPWI7Yys9MX1yZXR1cm4gY31mdW5jdGlvbiBibkJpdExlbmd0aCgpe2lmKHRoaXMudDw9MCl7cmV0dXJuIDB9cmV0dXJuIHRoaXMuREIqKHRoaXMudC0xKStuYml0cyh0aGlzW3RoaXMudC0xXV4odGhpcy5zJnRoaXMuRE0pKX1mdW5jdGlvbiBibnBETFNoaWZ0VG8oYyxiKXt2YXIgYTtmb3IoYT10aGlzLnQtMTthPj0wOy0tYSl7YlthK2NdPXRoaXNbYV19Zm9yKGE9Yy0xO2E+PTA7LS1hKXtiW2FdPTB9Yi50PXRoaXMudCtjO2Iucz10aGlzLnN9ZnVuY3Rpb24gYm5wRFJTaGlmdFRvKGMsYil7Zm9yKHZhciBhPWM7YTx0aGlzLnQ7KythKXtiW2EtY109dGhpc1thXX1iLnQ9TWF0aC5tYXgodGhpcy50LWMsMCk7Yi5zPXRoaXMuc31mdW5jdGlvbiBibnBMU2hpZnRUbyhqLGUpe3ZhciBiPWoldGhpcy5EQjt2YXIgYT10aGlzLkRCLWI7dmFyIGc9KDE8PGEpLTE7dmFyIGY9TWF0aC5mbG9vcihqL3RoaXMuREIpLGg9KHRoaXMuczw8YikmdGhpcy5ETSxkO2ZvcihkPXRoaXMudC0xO2Q+PTA7LS1kKXtlW2QrZisxXT0odGhpc1tkXT4+YSl8aDtoPSh0aGlzW2RdJmcpPDxifWZvcihkPWYtMTtkPj0wOy0tZCl7ZVtkXT0wfWVbZl09aDtlLnQ9dGhpcy50K2YrMTtlLnM9dGhpcy5zO2UuY2xhbXAoKX1mdW5jdGlvbiBibnBSU2hpZnRUbyhnLGQpe2Qucz10aGlzLnM7dmFyIGU9TWF0aC5mbG9vcihnL3RoaXMuREIpO2lmKGU+PXRoaXMudCl7ZC50PTA7cmV0dXJufXZhciBiPWcldGhpcy5EQjt2YXIgYT10aGlzLkRCLWI7dmFyIGY9KDE8PGIpLTE7ZFswXT10aGlzW2VdPj5iO2Zvcih2YXIgYz1lKzE7Yzx0aGlzLnQ7KytjKXtkW2MtZS0xXXw9KHRoaXNbY10mZik8PGE7ZFtjLWVdPXRoaXNbY10+PmJ9aWYoYj4wKXtkW3RoaXMudC1lLTFdfD0odGhpcy5zJmYpPDxhfWQudD10aGlzLnQtZTtkLmNsYW1wKCl9ZnVuY3Rpb24gYm5wU3ViVG8oZCxmKXt2YXIgZT0wLGc9MCxiPU1hdGgubWluKGQudCx0aGlzLnQpO3doaWxlKGU8Yil7Zys9dGhpc1tlXS1kW2VdO2ZbZSsrXT1nJnRoaXMuRE07Zz4+PXRoaXMuREJ9aWYoZC50PHRoaXMudCl7Zy09ZC5zO3doaWxlKGU8dGhpcy50KXtnKz10aGlzW2VdO2ZbZSsrXT1nJnRoaXMuRE07Zz4+PXRoaXMuREJ9Zys9dGhpcy5zfWVsc2V7Zys9dGhpcy5zO3doaWxlKGU8ZC50KXtnLT1kW2VdO2ZbZSsrXT1nJnRoaXMuRE07Zz4+PXRoaXMuREJ9Zy09ZC5zfWYucz0oZzwwKT8tMTowO2lmKGc8LTEpe2ZbZSsrXT10aGlzLkRWK2d9ZWxzZXtpZihnPjApe2ZbZSsrXT1nfX1mLnQ9ZTtmLmNsYW1wKCl9ZnVuY3Rpb24gYm5wTXVsdGlwbHlUbyhjLGUpe3ZhciBiPXRoaXMuYWJzKCksZj1jLmFicygpO3ZhciBkPWIudDtlLnQ9ZCtmLnQ7d2hpbGUoLS1kPj0wKXtlW2RdPTB9Zm9yKGQ9MDtkPGYudDsrK2Qpe2VbZCtiLnRdPWIuYW0oMCxmW2RdLGUsZCwwLGIudCl9ZS5zPTA7ZS5jbGFtcCgpO2lmKHRoaXMucyE9Yy5zKXtCaWdJbnRlZ2VyLlpFUk8uc3ViVG8oZSxlKX19ZnVuY3Rpb24gYm5wU3F1YXJlVG8oZCl7dmFyIGE9dGhpcy5hYnMoKTt2YXIgYj1kLnQ9MiphLnQ7d2hpbGUoLS1iPj0wKXtkW2JdPTB9Zm9yKGI9MDtiPGEudC0xOysrYil7dmFyIGU9YS5hbShiLGFbYl0sZCwyKmIsMCwxKTtpZigoZFtiK2EudF0rPWEuYW0oYisxLDIqYVtiXSxkLDIqYisxLGUsYS50LWItMSkpPj1hLkRWKXtkW2IrYS50XS09YS5EVjtkW2IrYS50KzFdPTF9fWlmKGQudD4wKXtkW2QudC0xXSs9YS5hbShiLGFbYl0sZCwyKmIsMCwxKX1kLnM9MDtkLmNsYW1wKCl9ZnVuY3Rpb24gYm5wRGl2UmVtVG8obixoLGcpe3ZhciB3PW4uYWJzKCk7aWYody50PD0wKXtyZXR1cm59dmFyIGs9dGhpcy5hYnMoKTtpZihrLnQ8dy50KXtpZihoIT1udWxsKXtoLmZyb21JbnQoMCl9aWYoZyE9bnVsbCl7dGhpcy5jb3B5VG8oZyl9cmV0dXJufWlmKGc9PW51bGwpe2c9bmJpKCl9dmFyIGQ9bmJpKCksYT10aGlzLnMsbD1uLnM7dmFyIHY9dGhpcy5EQi1uYml0cyh3W3cudC0xXSk7aWYodj4wKXt3LmxTaGlmdFRvKHYsZCk7ay5sU2hpZnRUbyh2LGcpfWVsc2V7dy5jb3B5VG8oZCk7ay5jb3B5VG8oZyl9dmFyIHA9ZC50O3ZhciBiPWRbcC0xXTtpZihiPT0wKXtyZXR1cm59dmFyIG89YiooMTw8dGhpcy5GMSkrKChwPjEpP2RbcC0yXT4+dGhpcy5GMjowKTt2YXIgQT10aGlzLkZWL28sej0oMTw8dGhpcy5GMSkvbyx4PTE8PHRoaXMuRjI7dmFyIHU9Zy50LHM9dS1wLGY9KGg9PW51bGwpP25iaSgpOmg7ZC5kbFNoaWZ0VG8ocyxmKTtpZihnLmNvbXBhcmVUbyhmKT49MCl7Z1tnLnQrK109MTtnLnN1YlRvKGYsZyl9QmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHAsZik7Zi5zdWJUbyhkLGQpO3doaWxlKGQudDxwKXtkW2QudCsrXT0wfXdoaWxlKC0tcz49MCl7dmFyIGM9KGdbLS11XT09Yik/dGhpcy5ETTpNYXRoLmZsb29yKGdbdV0qQSsoZ1t1LTFdK3gpKnopO2lmKChnW3VdKz1kLmFtKDAsYyxnLHMsMCxwKSk8Yyl7ZC5kbFNoaWZ0VG8ocyxmKTtnLnN1YlRvKGYsZyk7d2hpbGUoZ1t1XTwtLWMpe2cuc3ViVG8oZixnKX19fWlmKGghPW51bGwpe2cuZHJTaGlmdFRvKHAsaCk7aWYoYSE9bCl7QmlnSW50ZWdlci5aRVJPLnN1YlRvKGgsaCl9fWcudD1wO2cuY2xhbXAoKTtpZih2PjApe2cuclNoaWZ0VG8odixnKX1pZihhPDApe0JpZ0ludGVnZXIuWkVSTy5zdWJUbyhnLGcpfX1mdW5jdGlvbiBibk1vZChiKXt2YXIgYz1uYmkoKTt0aGlzLmFicygpLmRpdlJlbVRvKGIsbnVsbCxjKTtpZih0aGlzLnM8MCYmYy5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKT4wKXtiLnN1YlRvKGMsYyl9cmV0dXJuIGN9ZnVuY3Rpb24gQ2xhc3NpYyhhKXt0aGlzLm09YX1mdW5jdGlvbiBjQ29udmVydChhKXtpZihhLnM8MHx8YS5jb21wYXJlVG8odGhpcy5tKT49MCl7cmV0dXJuIGEubW9kKHRoaXMubSl9ZWxzZXtyZXR1cm4gYX19ZnVuY3Rpb24gY1JldmVydChhKXtyZXR1cm4gYX1mdW5jdGlvbiBjUmVkdWNlKGEpe2EuZGl2UmVtVG8odGhpcy5tLG51bGwsYSl9ZnVuY3Rpb24gY011bFRvKGEsYyxiKXthLm11bHRpcGx5VG8oYyxiKTt0aGlzLnJlZHVjZShiKX1mdW5jdGlvbiBjU3FyVG8oYSxiKXthLnNxdWFyZVRvKGIpO3RoaXMucmVkdWNlKGIpfUNsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQ9Y0NvbnZlcnQ7Q2xhc3NpYy5wcm90b3R5cGUucmV2ZXJ0PWNSZXZlcnQ7Q2xhc3NpYy5wcm90b3R5cGUucmVkdWNlPWNSZWR1Y2U7Q2xhc3NpYy5wcm90b3R5cGUubXVsVG89Y011bFRvO0NsYXNzaWMucHJvdG90eXBlLnNxclRvPWNTcXJUbztmdW5jdGlvbiBibnBJbnZEaWdpdCgpe2lmKHRoaXMudDwxKXtyZXR1cm4gMH12YXIgYT10aGlzWzBdO2lmKChhJjEpPT0wKXtyZXR1cm4gMH12YXIgYj1hJjM7Yj0oYiooMi0oYSYxNSkqYikpJjE1O2I9KGIqKDItKGEmMjU1KSpiKSkmMjU1O2I9KGIqKDItKCgoYSY2NTUzNSkqYikmNjU1MzUpKSkmNjU1MzU7Yj0oYiooMi1hKmIldGhpcy5EVikpJXRoaXMuRFY7cmV0dXJuKGI+MCk/dGhpcy5EVi1iOi1ifWZ1bmN0aW9uIE1vbnRnb21lcnkoYSl7dGhpcy5tPWE7dGhpcy5tcD1hLmludkRpZ2l0KCk7dGhpcy5tcGw9dGhpcy5tcCYzMjc2Nzt0aGlzLm1waD10aGlzLm1wPj4xNTt0aGlzLnVtPSgxPDwoYS5EQi0xNSkpLTE7dGhpcy5tdDI9MiphLnR9ZnVuY3Rpb24gbW9udENvbnZlcnQoYSl7dmFyIGI9bmJpKCk7YS5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQsYik7Yi5kaXZSZW1Ubyh0aGlzLm0sbnVsbCxiKTtpZihhLnM8MCYmYi5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKT4wKXt0aGlzLm0uc3ViVG8oYixiKX1yZXR1cm4gYn1mdW5jdGlvbiBtb250UmV2ZXJ0KGEpe3ZhciBiPW5iaSgpO2EuY29weVRvKGIpO3RoaXMucmVkdWNlKGIpO3JldHVybiBifWZ1bmN0aW9uIG1vbnRSZWR1Y2UoYSl7d2hpbGUoYS50PD10aGlzLm10Mil7YVthLnQrK109MH1mb3IodmFyIGM9MDtjPHRoaXMubS50OysrYyl7dmFyIGI9YVtjXSYzMjc2Nzt2YXIgZD0oYip0aGlzLm1wbCsoKChiKnRoaXMubXBoKyhhW2NdPj4xNSkqdGhpcy5tcGwpJnRoaXMudW0pPDwxNSkpJmEuRE07Yj1jK3RoaXMubS50O2FbYl0rPXRoaXMubS5hbSgwLGQsYSxjLDAsdGhpcy5tLnQpO3doaWxlKGFbYl0+PWEuRFYpe2FbYl0tPWEuRFY7YVsrK2JdKyt9fWEuY2xhbXAoKTthLmRyU2hpZnRUbyh0aGlzLm0udCxhKTtpZihhLmNvbXBhcmVUbyh0aGlzLm0pPj0wKXthLnN1YlRvKHRoaXMubSxhKX19ZnVuY3Rpb24gbW9udFNxclRvKGEsYil7YS5zcXVhcmVUbyhiKTt0aGlzLnJlZHVjZShiKX1mdW5jdGlvbiBtb250TXVsVG8oYSxjLGIpe2EubXVsdGlwbHlUbyhjLGIpO3RoaXMucmVkdWNlKGIpfU1vbnRnb21lcnkucHJvdG90eXBlLmNvbnZlcnQ9bW9udENvbnZlcnQ7TW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0PW1vbnRSZXZlcnQ7TW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlPW1vbnRSZWR1Y2U7TW9udGdvbWVyeS5wcm90b3R5cGUubXVsVG89bW9udE11bFRvO01vbnRnb21lcnkucHJvdG90eXBlLnNxclRvPW1vbnRTcXJUbztmdW5jdGlvbiBibnBJc0V2ZW4oKXtyZXR1cm4oKHRoaXMudD4wKT8odGhpc1swXSYxKTp0aGlzLnMpPT0wfWZ1bmN0aW9uIGJucEV4cChoLGope2lmKGg+NDI5NDk2NzI5NXx8aDwxKXtyZXR1cm4gQmlnSW50ZWdlci5PTkV9dmFyIGY9bmJpKCksYT1uYmkoKSxkPWouY29udmVydCh0aGlzKSxjPW5iaXRzKGgpLTE7ZC5jb3B5VG8oZik7d2hpbGUoLS1jPj0wKXtqLnNxclRvKGYsYSk7aWYoKGgmKDE8PGMpKT4wKXtqLm11bFRvKGEsZCxmKX1lbHNle3ZhciBiPWY7Zj1hO2E9Yn19cmV0dXJuIGoucmV2ZXJ0KGYpfWZ1bmN0aW9uIGJuTW9kUG93SW50KGIsYSl7dmFyIGM7aWYoYjwyNTZ8fGEuaXNFdmVuKCkpe2M9bmV3IENsYXNzaWMoYSl9ZWxzZXtjPW5ldyBNb250Z29tZXJ5KGEpfXJldHVybiB0aGlzLmV4cChiLGMpfUJpZ0ludGVnZXIucHJvdG90eXBlLmNvcHlUbz1ibnBDb3B5VG87QmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbUludD1ibnBGcm9tSW50O0JpZ0ludGVnZXIucHJvdG90eXBlLmZyb21TdHJpbmc9Ym5wRnJvbVN0cmluZztCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGFtcD1ibnBDbGFtcDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5kbFNoaWZ0VG89Ym5wRExTaGlmdFRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmRyU2hpZnRUbz1ibnBEUlNoaWZ0VG87QmlnSW50ZWdlci5wcm90b3R5cGUubFNoaWZ0VG89Ym5wTFNoaWZ0VG87QmlnSW50ZWdlci5wcm90b3R5cGUuclNoaWZ0VG89Ym5wUlNoaWZ0VG87QmlnSW50ZWdlci5wcm90b3R5cGUuc3ViVG89Ym5wU3ViVG87QmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlUbz1ibnBNdWx0aXBseVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZVRvPWJucFNxdWFyZVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmRpdlJlbVRvPWJucERpdlJlbVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmludkRpZ2l0PWJucEludkRpZ2l0O0JpZ0ludGVnZXIucHJvdG90eXBlLmlzRXZlbj1ibnBJc0V2ZW47QmlnSW50ZWdlci5wcm90b3R5cGUuZXhwPWJucEV4cDtCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZz1iblRvU3RyaW5nO0JpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZT1ibk5lZ2F0ZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnM9Ym5BYnM7QmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvPWJuQ29tcGFyZVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aD1ibkJpdExlbmd0aDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2Q9Ym5Nb2Q7QmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50PWJuTW9kUG93SW50O0JpZ0ludGVnZXIuWkVSTz1uYnYoMCk7QmlnSW50ZWdlci5PTkU9bmJ2KDEpO1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG5mdW5jdGlvbiBibkNsb25lKCl7dmFyIGE9bmJpKCk7dGhpcy5jb3B5VG8oYSk7cmV0dXJuIGF9ZnVuY3Rpb24gYm5JbnRWYWx1ZSgpe2lmKHRoaXMuczwwKXtpZih0aGlzLnQ9PTEpe3JldHVybiB0aGlzWzBdLXRoaXMuRFZ9ZWxzZXtpZih0aGlzLnQ9PTApe3JldHVybiAtMX19fWVsc2V7aWYodGhpcy50PT0xKXtyZXR1cm4gdGhpc1swXX1lbHNle2lmKHRoaXMudD09MCl7cmV0dXJuIDB9fX1yZXR1cm4oKHRoaXNbMV0mKCgxPDwoMzItdGhpcy5EQikpLTEpKTw8dGhpcy5EQil8dGhpc1swXX1mdW5jdGlvbiBibkJ5dGVWYWx1ZSgpe3JldHVybih0aGlzLnQ9PTApP3RoaXMuczoodGhpc1swXTw8MjQpPj4yNH1mdW5jdGlvbiBiblNob3J0VmFsdWUoKXtyZXR1cm4odGhpcy50PT0wKT90aGlzLnM6KHRoaXNbMF08PDE2KT4+MTZ9ZnVuY3Rpb24gYm5wQ2h1bmtTaXplKGEpe3JldHVybiBNYXRoLmZsb29yKE1hdGguTE4yKnRoaXMuREIvTWF0aC5sb2coYSkpfWZ1bmN0aW9uIGJuU2lnTnVtKCl7aWYodGhpcy5zPDApe3JldHVybiAtMX1lbHNle2lmKHRoaXMudDw9MHx8KHRoaXMudD09MSYmdGhpc1swXTw9MCkpe3JldHVybiAwfWVsc2V7cmV0dXJuIDF9fX1mdW5jdGlvbiBibnBUb1JhZGl4KGMpe2lmKGM9PW51bGwpe2M9MTB9aWYodGhpcy5zaWdudW0oKT09MHx8YzwyfHxjPjM2KXtyZXR1cm5cIjBcIn12YXIgZj10aGlzLmNodW5rU2l6ZShjKTt2YXIgZT1NYXRoLnBvdyhjLGYpO3ZhciBpPW5idihlKSxqPW5iaSgpLGg9bmJpKCksZz1cIlwiO3RoaXMuZGl2UmVtVG8oaSxqLGgpO3doaWxlKGouc2lnbnVtKCk+MCl7Zz0oZStoLmludFZhbHVlKCkpLnRvU3RyaW5nKGMpLnN1YnN0cigxKStnO2ouZGl2UmVtVG8oaSxqLGgpfXJldHVybiBoLmludFZhbHVlKCkudG9TdHJpbmcoYykrZ31mdW5jdGlvbiBibnBGcm9tUmFkaXgobSxoKXt0aGlzLmZyb21JbnQoMCk7aWYoaD09bnVsbCl7aD0xMH12YXIgZj10aGlzLmNodW5rU2l6ZShoKTt2YXIgZz1NYXRoLnBvdyhoLGYpLGU9ZmFsc2UsYT0wLGw9MDtmb3IodmFyIGM9MDtjPG0ubGVuZ3RoOysrYyl7dmFyIGs9aW50QXQobSxjKTtpZihrPDApe2lmKG0uY2hhckF0KGMpPT1cIi1cIiYmdGhpcy5zaWdudW0oKT09MCl7ZT10cnVlfWNvbnRpbnVlfWw9aCpsK2s7aWYoKythPj1mKXt0aGlzLmRNdWx0aXBseShnKTt0aGlzLmRBZGRPZmZzZXQobCwwKTthPTA7bD0wfX1pZihhPjApe3RoaXMuZE11bHRpcGx5KE1hdGgucG93KGgsYSkpO3RoaXMuZEFkZE9mZnNldChsLDApfWlmKGUpe0JpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpfX1mdW5jdGlvbiBibnBGcm9tTnVtYmVyKGYsZSxoKXtpZihcIm51bWJlclwiPT10eXBlb2YgZSl7aWYoZjwyKXt0aGlzLmZyb21JbnQoMSl9ZWxzZXt0aGlzLmZyb21OdW1iZXIoZixoKTtpZighdGhpcy50ZXN0Qml0KGYtMSkpe3RoaXMuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChmLTEpLG9wX29yLHRoaXMpfWlmKHRoaXMuaXNFdmVuKCkpe3RoaXMuZEFkZE9mZnNldCgxLDApfXdoaWxlKCF0aGlzLmlzUHJvYmFibGVQcmltZShlKSl7dGhpcy5kQWRkT2Zmc2V0KDIsMCk7aWYodGhpcy5iaXRMZW5ndGgoKT5mKXt0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChmLTEpLHRoaXMpfX19fWVsc2V7dmFyIGQ9bmV3IEFycmF5KCksZz1mJjc7ZC5sZW5ndGg9KGY+PjMpKzE7ZS5uZXh0Qnl0ZXMoZCk7aWYoZz4wKXtkWzBdJj0oKDE8PGcpLTEpfWVsc2V7ZFswXT0wfXRoaXMuZnJvbVN0cmluZyhkLDI1Nil9fWZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKXt2YXIgYj10aGlzLnQsYz1uZXcgQXJyYXkoKTtjWzBdPXRoaXMuczt2YXIgZT10aGlzLkRCLShiKnRoaXMuREIpJTgsZixhPTA7aWYoYi0tPjApe2lmKGU8dGhpcy5EQiYmKGY9dGhpc1tiXT4+ZSkhPSh0aGlzLnMmdGhpcy5ETSk+PmUpe2NbYSsrXT1mfCh0aGlzLnM8PCh0aGlzLkRCLWUpKX13aGlsZShiPj0wKXtpZihlPDgpe2Y9KHRoaXNbYl0mKCgxPDxlKS0xKSk8PCg4LWUpO2Z8PXRoaXNbLS1iXT4+KGUrPXRoaXMuREItOCl9ZWxzZXtmPSh0aGlzW2JdPj4oZS09OCkpJjI1NTtpZihlPD0wKXtlKz10aGlzLkRCOy0tYn19aWYoKGYmMTI4KSE9MCl7Znw9LTI1Nn1pZihhPT0wJiYodGhpcy5zJjEyOCkhPShmJjEyOCkpeysrYX1pZihhPjB8fGYhPXRoaXMucyl7Y1thKytdPWZ9fX1yZXR1cm4gY31mdW5jdGlvbiBibkVxdWFscyhiKXtyZXR1cm4odGhpcy5jb21wYXJlVG8oYik9PTApfWZ1bmN0aW9uIGJuTWluKGIpe3JldHVybih0aGlzLmNvbXBhcmVUbyhiKTwwKT90aGlzOmJ9ZnVuY3Rpb24gYm5NYXgoYil7cmV0dXJuKHRoaXMuY29tcGFyZVRvKGIpPjApP3RoaXM6Yn1mdW5jdGlvbiBibnBCaXR3aXNlVG8oYyxoLGUpe3ZhciBkLGcsYj1NYXRoLm1pbihjLnQsdGhpcy50KTtmb3IoZD0wO2Q8YjsrK2Qpe2VbZF09aCh0aGlzW2RdLGNbZF0pfWlmKGMudDx0aGlzLnQpe2c9Yy5zJnRoaXMuRE07Zm9yKGQ9YjtkPHRoaXMudDsrK2Qpe2VbZF09aCh0aGlzW2RdLGcpfWUudD10aGlzLnR9ZWxzZXtnPXRoaXMucyZ0aGlzLkRNO2ZvcihkPWI7ZDxjLnQ7KytkKXtlW2RdPWgoZyxjW2RdKX1lLnQ9Yy50fWUucz1oKHRoaXMucyxjLnMpO2UuY2xhbXAoKX1mdW5jdGlvbiBvcF9hbmQoYSxiKXtyZXR1cm4gYSZifWZ1bmN0aW9uIGJuQW5kKGIpe3ZhciBjPW5iaSgpO3RoaXMuYml0d2lzZVRvKGIsb3BfYW5kLGMpO3JldHVybiBjfWZ1bmN0aW9uIG9wX29yKGEsYil7cmV0dXJuIGF8Yn1mdW5jdGlvbiBibk9yKGIpe3ZhciBjPW5iaSgpO3RoaXMuYml0d2lzZVRvKGIsb3Bfb3IsYyk7cmV0dXJuIGN9ZnVuY3Rpb24gb3BfeG9yKGEsYil7cmV0dXJuIGFeYn1mdW5jdGlvbiBiblhvcihiKXt2YXIgYz1uYmkoKTt0aGlzLmJpdHdpc2VUbyhiLG9wX3hvcixjKTtyZXR1cm4gY31mdW5jdGlvbiBvcF9hbmRub3QoYSxiKXtyZXR1cm4gYSZ+Yn1mdW5jdGlvbiBibkFuZE5vdChiKXt2YXIgYz1uYmkoKTt0aGlzLmJpdHdpc2VUbyhiLG9wX2FuZG5vdCxjKTtyZXR1cm4gY31mdW5jdGlvbiBibk5vdCgpe3ZhciBiPW5iaSgpO2Zvcih2YXIgYT0wO2E8dGhpcy50OysrYSl7YlthXT10aGlzLkRNJn50aGlzW2FdfWIudD10aGlzLnQ7Yi5zPX50aGlzLnM7cmV0dXJuIGJ9ZnVuY3Rpb24gYm5TaGlmdExlZnQoYil7dmFyIGE9bmJpKCk7aWYoYjwwKXt0aGlzLnJTaGlmdFRvKC1iLGEpfWVsc2V7dGhpcy5sU2hpZnRUbyhiLGEpfXJldHVybiBhfWZ1bmN0aW9uIGJuU2hpZnRSaWdodChiKXt2YXIgYT1uYmkoKTtpZihiPDApe3RoaXMubFNoaWZ0VG8oLWIsYSl9ZWxzZXt0aGlzLnJTaGlmdFRvKGIsYSl9cmV0dXJuIGF9ZnVuY3Rpb24gbGJpdChhKXtpZihhPT0wKXtyZXR1cm4gLTF9dmFyIGI9MDtpZigoYSY2NTUzNSk9PTApe2E+Pj0xNjtiKz0xNn1pZigoYSYyNTUpPT0wKXthPj49ODtiKz04fWlmKChhJjE1KT09MCl7YT4+PTQ7Yis9NH1pZigoYSYzKT09MCl7YT4+PTI7Yis9Mn1pZigoYSYxKT09MCl7KytifXJldHVybiBifWZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCl7Zm9yKHZhciBhPTA7YTx0aGlzLnQ7KythKXtpZih0aGlzW2FdIT0wKXtyZXR1cm4gYSp0aGlzLkRCK2xiaXQodGhpc1thXSl9fWlmKHRoaXMuczwwKXtyZXR1cm4gdGhpcy50KnRoaXMuREJ9cmV0dXJuIC0xfWZ1bmN0aW9uIGNiaXQoYSl7dmFyIGI9MDt3aGlsZShhIT0wKXthJj1hLTE7KytifXJldHVybiBifWZ1bmN0aW9uIGJuQml0Q291bnQoKXt2YXIgYz0wLGE9dGhpcy5zJnRoaXMuRE07Zm9yKHZhciBiPTA7Yjx0aGlzLnQ7KytiKXtjKz1jYml0KHRoaXNbYl1eYSl9cmV0dXJuIGN9ZnVuY3Rpb24gYm5UZXN0Qml0KGIpe3ZhciBhPU1hdGguZmxvb3IoYi90aGlzLkRCKTtpZihhPj10aGlzLnQpe3JldHVybih0aGlzLnMhPTApfXJldHVybigodGhpc1thXSYoMTw8KGIldGhpcy5EQikpKSE9MCl9ZnVuY3Rpb24gYm5wQ2hhbmdlQml0KGMsYil7dmFyIGE9QmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGMpO3RoaXMuYml0d2lzZVRvKGEsYixhKTtyZXR1cm4gYX1mdW5jdGlvbiBiblNldEJpdChhKXtyZXR1cm4gdGhpcy5jaGFuZ2VCaXQoYSxvcF9vcil9ZnVuY3Rpb24gYm5DbGVhckJpdChhKXtyZXR1cm4gdGhpcy5jaGFuZ2VCaXQoYSxvcF9hbmRub3QpfWZ1bmN0aW9uIGJuRmxpcEJpdChhKXtyZXR1cm4gdGhpcy5jaGFuZ2VCaXQoYSxvcF94b3IpfWZ1bmN0aW9uIGJucEFkZFRvKGQsZil7dmFyIGU9MCxnPTAsYj1NYXRoLm1pbihkLnQsdGhpcy50KTt3aGlsZShlPGIpe2crPXRoaXNbZV0rZFtlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWlmKGQudDx0aGlzLnQpe2crPWQuczt3aGlsZShlPHRoaXMudCl7Zys9dGhpc1tlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWcrPXRoaXMuc31lbHNle2crPXRoaXMuczt3aGlsZShlPGQudCl7Zys9ZFtlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWcrPWQuc31mLnM9KGc8MCk/LTE6MDtpZihnPjApe2ZbZSsrXT1nfWVsc2V7aWYoZzwtMSl7ZltlKytdPXRoaXMuRFYrZ319Zi50PWU7Zi5jbGFtcCgpfWZ1bmN0aW9uIGJuQWRkKGIpe3ZhciBjPW5iaSgpO3RoaXMuYWRkVG8oYixjKTtyZXR1cm4gY31mdW5jdGlvbiBiblN1YnRyYWN0KGIpe3ZhciBjPW5iaSgpO3RoaXMuc3ViVG8oYixjKTtyZXR1cm4gY31mdW5jdGlvbiBibk11bHRpcGx5KGIpe3ZhciBjPW5iaSgpO3RoaXMubXVsdGlwbHlUbyhiLGMpO3JldHVybiBjfWZ1bmN0aW9uIGJuU3F1YXJlKCl7dmFyIGE9bmJpKCk7dGhpcy5zcXVhcmVUbyhhKTtyZXR1cm4gYX1mdW5jdGlvbiBibkRpdmlkZShiKXt2YXIgYz1uYmkoKTt0aGlzLmRpdlJlbVRvKGIsYyxudWxsKTtyZXR1cm4gY31mdW5jdGlvbiBiblJlbWFpbmRlcihiKXt2YXIgYz1uYmkoKTt0aGlzLmRpdlJlbVRvKGIsbnVsbCxjKTtyZXR1cm4gY31mdW5jdGlvbiBibkRpdmlkZUFuZFJlbWFpbmRlcihiKXt2YXIgZD1uYmkoKSxjPW5iaSgpO3RoaXMuZGl2UmVtVG8oYixkLGMpO3JldHVybiBuZXcgQXJyYXkoZCxjKX1mdW5jdGlvbiBibnBETXVsdGlwbHkoYSl7dGhpc1t0aGlzLnRdPXRoaXMuYW0oMCxhLTEsdGhpcywwLDAsdGhpcy50KTsrK3RoaXMudDt0aGlzLmNsYW1wKCl9ZnVuY3Rpb24gYm5wREFkZE9mZnNldChiLGEpe2lmKGI9PTApe3JldHVybn13aGlsZSh0aGlzLnQ8PWEpe3RoaXNbdGhpcy50KytdPTB9dGhpc1thXSs9Yjt3aGlsZSh0aGlzW2FdPj10aGlzLkRWKXt0aGlzW2FdLT10aGlzLkRWO2lmKCsrYT49dGhpcy50KXt0aGlzW3RoaXMudCsrXT0wfSsrdGhpc1thXX19ZnVuY3Rpb24gTnVsbEV4cCgpe31mdW5jdGlvbiBuTm9wKGEpe3JldHVybiBhfWZ1bmN0aW9uIG5NdWxUbyhhLGMsYil7YS5tdWx0aXBseVRvKGMsYil9ZnVuY3Rpb24gblNxclRvKGEsYil7YS5zcXVhcmVUbyhiKX1OdWxsRXhwLnByb3RvdHlwZS5jb252ZXJ0PW5Ob3A7TnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0PW5Ob3A7TnVsbEV4cC5wcm90b3R5cGUubXVsVG89bk11bFRvO051bGxFeHAucHJvdG90eXBlLnNxclRvPW5TcXJUbztmdW5jdGlvbiBiblBvdyhhKXtyZXR1cm4gdGhpcy5leHAoYSxuZXcgTnVsbEV4cCgpKX1mdW5jdGlvbiBibnBNdWx0aXBseUxvd2VyVG8oYixmLGUpe3ZhciBkPU1hdGgubWluKHRoaXMudCtiLnQsZik7ZS5zPTA7ZS50PWQ7d2hpbGUoZD4wKXtlWy0tZF09MH12YXIgYztmb3IoYz1lLnQtdGhpcy50O2Q8YzsrK2Qpe2VbZCt0aGlzLnRdPXRoaXMuYW0oMCxiW2RdLGUsZCwwLHRoaXMudCl9Zm9yKGM9TWF0aC5taW4oYi50LGYpO2Q8YzsrK2Qpe3RoaXMuYW0oMCxiW2RdLGUsZCwwLGYtZCl9ZS5jbGFtcCgpfWZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhiLGUsZCl7LS1lO3ZhciBjPWQudD10aGlzLnQrYi50LWU7ZC5zPTA7d2hpbGUoLS1jPj0wKXtkW2NdPTB9Zm9yKGM9TWF0aC5tYXgoZS10aGlzLnQsMCk7YzxiLnQ7KytjKXtkW3RoaXMudCtjLWVdPXRoaXMuYW0oZS1jLGJbY10sZCwwLDAsdGhpcy50K2MtZSl9ZC5jbGFtcCgpO2QuZHJTaGlmdFRvKDEsZCl9ZnVuY3Rpb24gQmFycmV0dChhKXt0aGlzLnIyPW5iaSgpO3RoaXMucTM9bmJpKCk7QmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIqYS50LHRoaXMucjIpO3RoaXMubXU9dGhpcy5yMi5kaXZpZGUoYSk7dGhpcy5tPWF9ZnVuY3Rpb24gYmFycmV0dENvbnZlcnQoYSl7aWYoYS5zPDB8fGEudD4yKnRoaXMubS50KXtyZXR1cm4gYS5tb2QodGhpcy5tKX1lbHNle2lmKGEuY29tcGFyZVRvKHRoaXMubSk8MCl7cmV0dXJuIGF9ZWxzZXt2YXIgYj1uYmkoKTthLmNvcHlUbyhiKTt0aGlzLnJlZHVjZShiKTtyZXR1cm4gYn19fWZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoYSl7cmV0dXJuIGF9ZnVuY3Rpb24gYmFycmV0dFJlZHVjZShhKXthLmRyU2hpZnRUbyh0aGlzLm0udC0xLHRoaXMucjIpO2lmKGEudD50aGlzLm0udCsxKXthLnQ9dGhpcy5tLnQrMTthLmNsYW1wKCl9dGhpcy5tdS5tdWx0aXBseVVwcGVyVG8odGhpcy5yMix0aGlzLm0udCsxLHRoaXMucTMpO3RoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMyx0aGlzLm0udCsxLHRoaXMucjIpO3doaWxlKGEuY29tcGFyZVRvKHRoaXMucjIpPDApe2EuZEFkZE9mZnNldCgxLHRoaXMubS50KzEpfWEuc3ViVG8odGhpcy5yMixhKTt3aGlsZShhLmNvbXBhcmVUbyh0aGlzLm0pPj0wKXthLnN1YlRvKHRoaXMubSxhKX19ZnVuY3Rpb24gYmFycmV0dFNxclRvKGEsYil7YS5zcXVhcmVUbyhiKTt0aGlzLnJlZHVjZShiKX1mdW5jdGlvbiBiYXJyZXR0TXVsVG8oYSxjLGIpe2EubXVsdGlwbHlUbyhjLGIpO3RoaXMucmVkdWNlKGIpfUJhcnJldHQucHJvdG90eXBlLmNvbnZlcnQ9YmFycmV0dENvbnZlcnQ7QmFycmV0dC5wcm90b3R5cGUucmV2ZXJ0PWJhcnJldHRSZXZlcnQ7QmFycmV0dC5wcm90b3R5cGUucmVkdWNlPWJhcnJldHRSZWR1Y2U7QmFycmV0dC5wcm90b3R5cGUubXVsVG89YmFycmV0dE11bFRvO0JhcnJldHQucHJvdG90eXBlLnNxclRvPWJhcnJldHRTcXJUbztmdW5jdGlvbiBibk1vZFBvdyhxLGYpe3ZhciBvPXEuYml0TGVuZ3RoKCksaCxiPW5idigxKSx2O2lmKG88PTApe3JldHVybiBifWVsc2V7aWYobzwxOCl7aD0xfWVsc2V7aWYobzw0OCl7aD0zfWVsc2V7aWYobzwxNDQpe2g9NH1lbHNle2lmKG88NzY4KXtoPTV9ZWxzZXtoPTZ9fX19fWlmKG88OCl7dj1uZXcgQ2xhc3NpYyhmKX1lbHNle2lmKGYuaXNFdmVuKCkpe3Y9bmV3IEJhcnJldHQoZil9ZWxzZXt2PW5ldyBNb250Z29tZXJ5KGYpfX12YXIgcD1uZXcgQXJyYXkoKSxkPTMscz1oLTEsYT0oMTw8aCktMTtwWzFdPXYuY29udmVydCh0aGlzKTtpZihoPjEpe3ZhciBBPW5iaSgpO3Yuc3FyVG8ocFsxXSxBKTt3aGlsZShkPD1hKXtwW2RdPW5iaSgpO3YubXVsVG8oQSxwW2QtMl0scFtkXSk7ZCs9Mn19dmFyIGw9cS50LTEseCx1PXRydWUsYz1uYmkoKSx5O289bmJpdHMocVtsXSktMTt3aGlsZShsPj0wKXtpZihvPj1zKXt4PShxW2xdPj4oby1zKSkmYX1lbHNle3g9KHFbbF0mKCgxPDwobysxKSktMSkpPDwocy1vKTtpZihsPjApe3h8PXFbbC0xXT4+KHRoaXMuREIrby1zKX19ZD1oO3doaWxlKCh4JjEpPT0wKXt4Pj49MTstLWR9aWYoKG8tPWQpPDApe28rPXRoaXMuREI7LS1sfWlmKHUpe3BbeF0uY29weVRvKGIpO3U9ZmFsc2V9ZWxzZXt3aGlsZShkPjEpe3Yuc3FyVG8oYixjKTt2LnNxclRvKGMsYik7ZC09Mn1pZihkPjApe3Yuc3FyVG8oYixjKX1lbHNle3k9YjtiPWM7Yz15fXYubXVsVG8oYyxwW3hdLGIpfXdoaWxlKGw+PTAmJihxW2xdJigxPDxvKSk9PTApe3Yuc3FyVG8oYixjKTt5PWI7Yj1jO2M9eTtpZigtLW88MCl7bz10aGlzLkRCLTE7LS1sfX19cmV0dXJuIHYucmV2ZXJ0KGIpfWZ1bmN0aW9uIGJuR0NEKGMpe3ZhciBiPSh0aGlzLnM8MCk/dGhpcy5uZWdhdGUoKTp0aGlzLmNsb25lKCk7dmFyIGg9KGMuczwwKT9jLm5lZ2F0ZSgpOmMuY2xvbmUoKTtpZihiLmNvbXBhcmVUbyhoKTwwKXt2YXIgZT1iO2I9aDtoPWV9dmFyIGQ9Yi5nZXRMb3dlc3RTZXRCaXQoKSxmPWguZ2V0TG93ZXN0U2V0Qml0KCk7aWYoZjwwKXtyZXR1cm4gYn1pZihkPGYpe2Y9ZH1pZihmPjApe2IuclNoaWZ0VG8oZixiKTtoLnJTaGlmdFRvKGYsaCl9d2hpbGUoYi5zaWdudW0oKT4wKXtpZigoZD1iLmdldExvd2VzdFNldEJpdCgpKT4wKXtiLnJTaGlmdFRvKGQsYil9aWYoKGQ9aC5nZXRMb3dlc3RTZXRCaXQoKSk+MCl7aC5yU2hpZnRUbyhkLGgpfWlmKGIuY29tcGFyZVRvKGgpPj0wKXtiLnN1YlRvKGgsYik7Yi5yU2hpZnRUbygxLGIpfWVsc2V7aC5zdWJUbyhiLGgpO2guclNoaWZ0VG8oMSxoKX19aWYoZj4wKXtoLmxTaGlmdFRvKGYsaCl9cmV0dXJuIGh9ZnVuY3Rpb24gYm5wTW9kSW50KGUpe2lmKGU8PTApe3JldHVybiAwfXZhciBjPXRoaXMuRFYlZSxiPSh0aGlzLnM8MCk/ZS0xOjA7aWYodGhpcy50PjApe2lmKGM9PTApe2I9dGhpc1swXSVlfWVsc2V7Zm9yKHZhciBhPXRoaXMudC0xO2E+PTA7LS1hKXtiPShjKmIrdGhpc1thXSklZX19fXJldHVybiBifWZ1bmN0aW9uIGJuTW9kSW52ZXJzZShmKXt2YXIgaj1mLmlzRXZlbigpO2lmKCh0aGlzLmlzRXZlbigpJiZqKXx8Zi5zaWdudW0oKT09MCl7cmV0dXJuIEJpZ0ludGVnZXIuWkVST312YXIgaT1mLmNsb25lKCksaD10aGlzLmNsb25lKCk7dmFyIGc9bmJ2KDEpLGU9bmJ2KDApLGw9bmJ2KDApLGs9bmJ2KDEpO3doaWxlKGkuc2lnbnVtKCkhPTApe3doaWxlKGkuaXNFdmVuKCkpe2kuclNoaWZ0VG8oMSxpKTtpZihqKXtpZighZy5pc0V2ZW4oKXx8IWUuaXNFdmVuKCkpe2cuYWRkVG8odGhpcyxnKTtlLnN1YlRvKGYsZSl9Zy5yU2hpZnRUbygxLGcpfWVsc2V7aWYoIWUuaXNFdmVuKCkpe2Uuc3ViVG8oZixlKX19ZS5yU2hpZnRUbygxLGUpfXdoaWxlKGguaXNFdmVuKCkpe2guclNoaWZ0VG8oMSxoKTtpZihqKXtpZighbC5pc0V2ZW4oKXx8IWsuaXNFdmVuKCkpe2wuYWRkVG8odGhpcyxsKTtrLnN1YlRvKGYsayl9bC5yU2hpZnRUbygxLGwpfWVsc2V7aWYoIWsuaXNFdmVuKCkpe2suc3ViVG8oZixrKX19ay5yU2hpZnRUbygxLGspfWlmKGkuY29tcGFyZVRvKGgpPj0wKXtpLnN1YlRvKGgsaSk7aWYoail7Zy5zdWJUbyhsLGcpfWUuc3ViVG8oayxlKX1lbHNle2guc3ViVG8oaSxoKTtpZihqKXtsLnN1YlRvKGcsbCl9ay5zdWJUbyhlLGspfX1pZihoLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkhPTApe3JldHVybiBCaWdJbnRlZ2VyLlpFUk99aWYoay5jb21wYXJlVG8oZik+PTApe3JldHVybiBrLnN1YnRyYWN0KGYpfWlmKGsuc2lnbnVtKCk8MCl7ay5hZGRUbyhmLGspfWVsc2V7cmV0dXJuIGt9aWYoay5zaWdudW0oKTwwKXtyZXR1cm4gay5hZGQoZil9ZWxzZXtyZXR1cm4ga319dmFyIGxvd3ByaW1lcz1bMiwzLDUsNywxMSwxMywxNywxOSwyMywyOSwzMSwzNyw0MSw0Myw0Nyw1Myw1OSw2MSw2Nyw3MSw3Myw3OSw4Myw4OSw5NywxMDEsMTAzLDEwNywxMDksMTEzLDEyNywxMzEsMTM3LDEzOSwxNDksMTUxLDE1NywxNjMsMTY3LDE3MywxNzksMTgxLDE5MSwxOTMsMTk3LDE5OSwyMTEsMjIzLDIyNywyMjksMjMzLDIzOSwyNDEsMjUxLDI1NywyNjMsMjY5LDI3MSwyNzcsMjgxLDI4MywyOTMsMzA3LDMxMSwzMTMsMzE3LDMzMSwzMzcsMzQ3LDM0OSwzNTMsMzU5LDM2NywzNzMsMzc5LDM4MywzODksMzk3LDQwMSw0MDksNDE5LDQyMSw0MzEsNDMzLDQzOSw0NDMsNDQ5LDQ1Nyw0NjEsNDYzLDQ2Nyw0NzksNDg3LDQ5MSw0OTksNTAzLDUwOSw1MjEsNTIzLDU0MSw1NDcsNTU3LDU2Myw1NjksNTcxLDU3Nyw1ODcsNTkzLDU5OSw2MDEsNjA3LDYxMyw2MTcsNjE5LDYzMSw2NDEsNjQzLDY0Nyw2NTMsNjU5LDY2MSw2NzMsNjc3LDY4Myw2OTEsNzAxLDcwOSw3MTksNzI3LDczMyw3MzksNzQzLDc1MSw3NTcsNzYxLDc2OSw3NzMsNzg3LDc5Nyw4MDksODExLDgyMSw4MjMsODI3LDgyOSw4MzksODUzLDg1Nyw4NTksODYzLDg3Nyw4ODEsODgzLDg4Nyw5MDcsOTExLDkxOSw5MjksOTM3LDk0MSw5NDcsOTUzLDk2Nyw5NzEsOTc3LDk4Myw5OTEsOTk3XTt2YXIgbHBsaW09KDE8PDI2KS9sb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXTtmdW5jdGlvbiBibklzUHJvYmFibGVQcmltZShlKXt2YXIgZCxiPXRoaXMuYWJzKCk7aWYoYi50PT0xJiZiWzBdPD1sb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXSl7Zm9yKGQ9MDtkPGxvd3ByaW1lcy5sZW5ndGg7KytkKXtpZihiWzBdPT1sb3dwcmltZXNbZF0pe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9aWYoYi5pc0V2ZW4oKSl7cmV0dXJuIGZhbHNlfWQ9MTt3aGlsZShkPGxvd3ByaW1lcy5sZW5ndGgpe3ZhciBhPWxvd3ByaW1lc1tkXSxjPWQrMTt3aGlsZShjPGxvd3ByaW1lcy5sZW5ndGgmJmE8bHBsaW0pe2EqPWxvd3ByaW1lc1tjKytdfWE9Yi5tb2RJbnQoYSk7d2hpbGUoZDxjKXtpZihhJWxvd3ByaW1lc1tkKytdPT0wKXtyZXR1cm4gZmFsc2V9fX1yZXR1cm4gYi5taWxsZXJSYWJpbihlKX1mdW5jdGlvbiBibnBNaWxsZXJSYWJpbihmKXt2YXIgZz10aGlzLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTt2YXIgYz1nLmdldExvd2VzdFNldEJpdCgpO2lmKGM8PTApe3JldHVybiBmYWxzZX12YXIgaD1nLnNoaWZ0UmlnaHQoYyk7Zj0oZisxKT4+MTtpZihmPmxvd3ByaW1lcy5sZW5ndGgpe2Y9bG93cHJpbWVzLmxlbmd0aH12YXIgYj1uYmkoKTtmb3IodmFyIGU9MDtlPGY7KytlKXtiLmZyb21JbnQobG93cHJpbWVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSpsb3dwcmltZXMubGVuZ3RoKV0pO3ZhciBsPWIubW9kUG93KGgsdGhpcyk7aWYobC5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpIT0wJiZsLmNvbXBhcmVUbyhnKSE9MCl7dmFyIGQ9MTt3aGlsZShkKys8YyYmbC5jb21wYXJlVG8oZykhPTApe2w9bC5tb2RQb3dJbnQoMix0aGlzKTtpZihsLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSk9PTApe3JldHVybiBmYWxzZX19aWYobC5jb21wYXJlVG8oZykhPTApe3JldHVybiBmYWxzZX19fXJldHVybiB0cnVlfUJpZ0ludGVnZXIucHJvdG90eXBlLmNodW5rU2l6ZT1ibnBDaHVua1NpemU7QmlnSW50ZWdlci5wcm90b3R5cGUudG9SYWRpeD1ibnBUb1JhZGl4O0JpZ0ludGVnZXIucHJvdG90eXBlLmZyb21SYWRpeD1ibnBGcm9tUmFkaXg7QmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbU51bWJlcj1ibnBGcm9tTnVtYmVyO0JpZ0ludGVnZXIucHJvdG90eXBlLmJpdHdpc2VUbz1ibnBCaXR3aXNlVG87QmlnSW50ZWdlci5wcm90b3R5cGUuY2hhbmdlQml0PWJucENoYW5nZUJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGRUbz1ibnBBZGRUbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5kTXVsdGlwbHk9Ym5wRE11bHRpcGx5O0JpZ0ludGVnZXIucHJvdG90eXBlLmRBZGRPZmZzZXQ9Ym5wREFkZE9mZnNldDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseUxvd2VyVG89Ym5wTXVsdGlwbHlMb3dlclRvO0JpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VXBwZXJUbz1ibnBNdWx0aXBseVVwcGVyVG87QmlnSW50ZWdlci5wcm90b3R5cGUubW9kSW50PWJucE1vZEludDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5taWxsZXJSYWJpbj1ibnBNaWxsZXJSYWJpbjtCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbG9uZT1ibkNsb25lO0JpZ0ludGVnZXIucHJvdG90eXBlLmludFZhbHVlPWJuSW50VmFsdWU7QmlnSW50ZWdlci5wcm90b3R5cGUuYnl0ZVZhbHVlPWJuQnl0ZVZhbHVlO0JpZ0ludGVnZXIucHJvdG90eXBlLnNob3J0VmFsdWU9Ym5TaG9ydFZhbHVlO0JpZ0ludGVnZXIucHJvdG90eXBlLnNpZ251bT1iblNpZ051bTtCaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheT1iblRvQnl0ZUFycmF5O0JpZ0ludGVnZXIucHJvdG90eXBlLmVxdWFscz1ibkVxdWFscztCaWdJbnRlZ2VyLnByb3RvdHlwZS5taW49Ym5NaW47QmlnSW50ZWdlci5wcm90b3R5cGUubWF4PWJuTWF4O0JpZ0ludGVnZXIucHJvdG90eXBlLmFuZD1ibkFuZDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5vcj1ibk9yO0JpZ0ludGVnZXIucHJvdG90eXBlLnhvcj1iblhvcjtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmROb3Q9Ym5BbmROb3Q7QmlnSW50ZWdlci5wcm90b3R5cGUubm90PWJuTm90O0JpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0TGVmdD1iblNoaWZ0TGVmdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaGlmdFJpZ2h0PWJuU2hpZnRSaWdodDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5nZXRMb3dlc3RTZXRCaXQ9Ym5HZXRMb3dlc3RTZXRCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuYml0Q291bnQ9Ym5CaXRDb3VudDtCaWdJbnRlZ2VyLnByb3RvdHlwZS50ZXN0Qml0PWJuVGVzdEJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zZXRCaXQ9Ym5TZXRCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuY2xlYXJCaXQ9Ym5DbGVhckJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5mbGlwQml0PWJuRmxpcEJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGQ9Ym5BZGQ7QmlnSW50ZWdlci5wcm90b3R5cGUuc3VidHJhY3Q9Ym5TdWJ0cmFjdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseT1ibk11bHRpcGx5O0JpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZT1ibkRpdmlkZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5yZW1haW5kZXI9Ym5SZW1haW5kZXI7QmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlQW5kUmVtYWluZGVyPWJuRGl2aWRlQW5kUmVtYWluZGVyO0JpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvdz1ibk1vZFBvdztCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnZlcnNlPWJuTW9kSW52ZXJzZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5wb3c9Ym5Qb3c7QmlnSW50ZWdlci5wcm90b3R5cGUuZ2NkPWJuR0NEO0JpZ0ludGVnZXIucHJvdG90eXBlLmlzUHJvYmFibGVQcmltZT1ibklzUHJvYmFibGVQcmltZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmU9Ym5TcXVhcmU7XG4vKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi9cclxuICovXHJcbmZ1bmN0aW9uIEFyY2ZvdXIoKXt0aGlzLmk9MDt0aGlzLmo9MDt0aGlzLlM9bmV3IEFycmF5KCl9ZnVuY3Rpb24gQVJDNGluaXQoZCl7dmFyIGMsYSxiO2ZvcihjPTA7YzwyNTY7KytjKXt0aGlzLlNbY109Y31hPTA7Zm9yKGM9MDtjPDI1NjsrK2Mpe2E9KGErdGhpcy5TW2NdK2RbYyVkLmxlbmd0aF0pJjI1NTtiPXRoaXMuU1tjXTt0aGlzLlNbY109dGhpcy5TW2FdO3RoaXMuU1thXT1ifXRoaXMuaT0wO3RoaXMuaj0wfWZ1bmN0aW9uIEFSQzRuZXh0KCl7dmFyIGE7dGhpcy5pPSh0aGlzLmkrMSkmMjU1O3RoaXMuaj0odGhpcy5qK3RoaXMuU1t0aGlzLmldKSYyNTU7YT10aGlzLlNbdGhpcy5pXTt0aGlzLlNbdGhpcy5pXT10aGlzLlNbdGhpcy5qXTt0aGlzLlNbdGhpcy5qXT1hO3JldHVybiB0aGlzLlNbKGErdGhpcy5TW3RoaXMuaV0pJjI1NV19QXJjZm91ci5wcm90b3R5cGUuaW5pdD1BUkM0aW5pdDtBcmNmb3VyLnByb3RvdHlwZS5uZXh0PUFSQzRuZXh0O2Z1bmN0aW9uIHBybmdfbmV3c3RhdGUoKXtyZXR1cm4gbmV3IEFyY2ZvdXIoKX12YXIgcm5nX3BzaXplPTI1Njtcbi8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xyXG4gKi9cclxudmFyIHJuZ19zdGF0ZTt2YXIgcm5nX3Bvb2w7dmFyIHJuZ19wcHRyO2Z1bmN0aW9uIHJuZ19zZWVkX2ludChhKXtybmdfcG9vbFtybmdfcHB0cisrXV49YSYyNTU7cm5nX3Bvb2xbcm5nX3BwdHIrK11ePShhPj44KSYyNTU7cm5nX3Bvb2xbcm5nX3BwdHIrK11ePShhPj4xNikmMjU1O3JuZ19wb29sW3JuZ19wcHRyKytdXj0oYT4+MjQpJjI1NTtpZihybmdfcHB0cj49cm5nX3BzaXplKXtybmdfcHB0ci09cm5nX3BzaXplfX1mdW5jdGlvbiBybmdfc2VlZF90aW1lKCl7cm5nX3NlZWRfaW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKX1pZihybmdfcG9vbD09bnVsbCl7cm5nX3Bvb2w9bmV3IEFycmF5KCk7cm5nX3BwdHI9MDt2YXIgdDtpZih3aW5kb3chPT11bmRlZmluZWQmJih3aW5kb3cuY3J5cHRvIT09dW5kZWZpbmVkfHx3aW5kb3cubXNDcnlwdG8hPT11bmRlZmluZWQpKXt2YXIgY3J5cHRvPXdpbmRvdy5jcnlwdG98fHdpbmRvdy5tc0NyeXB0bztpZihjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKXt2YXIgdWE9bmV3IFVpbnQ4QXJyYXkoMzIpO2NyeXB0by5nZXRSYW5kb21WYWx1ZXModWEpO2Zvcih0PTA7dDwzMjsrK3Qpe3JuZ19wb29sW3JuZ19wcHRyKytdPXVhW3RdfX1lbHNle2lmKG5hdmlnYXRvci5hcHBOYW1lPT1cIk5ldHNjYXBlXCImJm5hdmlnYXRvci5hcHBWZXJzaW9uPFwiNVwiKXt2YXIgej13aW5kb3cuY3J5cHRvLnJhbmRvbSgzMik7Zm9yKHQ9MDt0PHoubGVuZ3RoOysrdCl7cm5nX3Bvb2xbcm5nX3BwdHIrK109ei5jaGFyQ29kZUF0KHQpJjI1NX19fX13aGlsZShybmdfcHB0cjxybmdfcHNpemUpe3Q9TWF0aC5mbG9vcig2NTUzNipNYXRoLnJhbmRvbSgpKTtybmdfcG9vbFtybmdfcHB0cisrXT10Pj4+ODtybmdfcG9vbFtybmdfcHB0cisrXT10JjI1NX1ybmdfcHB0cj0wO3JuZ19zZWVkX3RpbWUoKX1mdW5jdGlvbiBybmdfZ2V0X2J5dGUoKXtpZihybmdfc3RhdGU9PW51bGwpe3JuZ19zZWVkX3RpbWUoKTtybmdfc3RhdGU9cHJuZ19uZXdzdGF0ZSgpO3JuZ19zdGF0ZS5pbml0KHJuZ19wb29sKTtmb3Iocm5nX3BwdHI9MDtybmdfcHB0cjxybmdfcG9vbC5sZW5ndGg7KytybmdfcHB0cil7cm5nX3Bvb2xbcm5nX3BwdHJdPTB9cm5nX3BwdHI9MH1yZXR1cm4gcm5nX3N0YXRlLm5leHQoKX1mdW5jdGlvbiBybmdfZ2V0X2J5dGVzKGIpe3ZhciBhO2ZvcihhPTA7YTxiLmxlbmd0aDsrK2Epe2JbYV09cm5nX2dldF9ieXRlKCl9fWZ1bmN0aW9uIFNlY3VyZVJhbmRvbSgpe31TZWN1cmVSYW5kb20ucHJvdG90eXBlLm5leHRCeXRlcz1ybmdfZ2V0X2J5dGVzO1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG5mdW5jdGlvbiBwYXJzZUJpZ0ludChiLGEpe3JldHVybiBuZXcgQmlnSW50ZWdlcihiLGEpfWZ1bmN0aW9uIGxpbmVicmsoYyxkKXt2YXIgYT1cIlwiO3ZhciBiPTA7d2hpbGUoYitkPGMubGVuZ3RoKXthKz1jLnN1YnN0cmluZyhiLGIrZCkrXCJcXG5cIjtiKz1kfXJldHVybiBhK2Muc3Vic3RyaW5nKGIsYy5sZW5ndGgpfWZ1bmN0aW9uIGJ5dGUySGV4KGEpe2lmKGE8MTYpe3JldHVyblwiMFwiK2EudG9TdHJpbmcoMTYpfWVsc2V7cmV0dXJuIGEudG9TdHJpbmcoMTYpfX1mdW5jdGlvbiBwa2NzMXBhZDIoZSxoKXtpZihoPGUubGVuZ3RoKzExKXt0aHJvd1wiTWVzc2FnZSB0b28gbG9uZyBmb3IgUlNBXCI7cmV0dXJuIG51bGx9dmFyIGc9bmV3IEFycmF5KCk7dmFyIGQ9ZS5sZW5ndGgtMTt3aGlsZShkPj0wJiZoPjApe3ZhciBmPWUuY2hhckNvZGVBdChkLS0pO2lmKGY8MTI4KXtnWy0taF09Zn1lbHNle2lmKChmPjEyNykmJihmPDIwNDgpKXtnWy0taF09KGYmNjMpfDEyODtnWy0taF09KGY+PjYpfDE5Mn1lbHNle2dbLS1oXT0oZiY2Myl8MTI4O2dbLS1oXT0oKGY+PjYpJjYzKXwxMjg7Z1stLWhdPShmPj4xMil8MjI0fX19Z1stLWhdPTA7dmFyIGI9bmV3IFNlY3VyZVJhbmRvbSgpO3ZhciBhPW5ldyBBcnJheSgpO3doaWxlKGg+Mil7YVswXT0wO3doaWxlKGFbMF09PTApe2IubmV4dEJ5dGVzKGEpfWdbLS1oXT1hWzBdfWdbLS1oXT0yO2dbLS1oXT0wO3JldHVybiBuZXcgQmlnSW50ZWdlcihnKX1mdW5jdGlvbiBvYWVwX21nZjFfYXJyKGMsYSxlKXt2YXIgYj1cIlwiLGQ9MDt3aGlsZShiLmxlbmd0aDxhKXtiKz1lKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGMuY29uY2F0KFsoZCY0Mjc4MTkwMDgwKT4+MjQsKGQmMTY3MTE2ODApPj4xNiwoZCY2NTI4MCk+PjgsZCYyNTVdKSkpO2QrPTF9cmV0dXJuIGJ9ZnVuY3Rpb24gb2FlcF9wYWQocSxhLGYsbCl7dmFyIGM9S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdDt2YXIgbz1LSlVSLmNyeXB0by5VdGlsO3ZhciBiPW51bGw7aWYoIWYpe2Y9XCJzaGExXCJ9aWYodHlwZW9mIGY9PT1cInN0cmluZ1wiKXtiPWMuZ2V0Q2Fub25pY2FsQWxnTmFtZShmKTtsPWMuZ2V0SGFzaExlbmd0aChiKTtmPWZ1bmN0aW9uKGkpe3JldHVybiBoZXh0b3JzdHIoby5oYXNoSGV4KHJzdHJ0b2hleChpKSxiKSl9fWlmKHEubGVuZ3RoKzIqbCsyPmEpe3Rocm93XCJNZXNzYWdlIHRvbyBsb25nIGZvciBSU0FcIn12YXIgaz1cIlwiLGU7Zm9yKGU9MDtlPGEtcS5sZW5ndGgtMipsLTI7ZSs9MSl7ays9XCJcXHgwMFwifXZhciBoPWYoXCJcIikraytcIlxceDAxXCIrcTt2YXIgZz1uZXcgQXJyYXkobCk7bmV3IFNlY3VyZVJhbmRvbSgpLm5leHRCeXRlcyhnKTt2YXIgaj1vYWVwX21nZjFfYXJyKGcsaC5sZW5ndGgsZik7dmFyIHA9W107Zm9yKGU9MDtlPGgubGVuZ3RoO2UrPTEpe3BbZV09aC5jaGFyQ29kZUF0KGUpXmouY2hhckNvZGVBdChlKX12YXIgbT1vYWVwX21nZjFfYXJyKHAsZy5sZW5ndGgsZik7dmFyIGQ9WzBdO2ZvcihlPTA7ZTxnLmxlbmd0aDtlKz0xKXtkW2UrMV09Z1tlXV5tLmNoYXJDb2RlQXQoZSl9cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGQuY29uY2F0KHApKX1mdW5jdGlvbiBSU0FLZXkoKXt0aGlzLm49bnVsbDt0aGlzLmU9MDt0aGlzLmQ9bnVsbDt0aGlzLnA9bnVsbDt0aGlzLnE9bnVsbDt0aGlzLmRtcDE9bnVsbDt0aGlzLmRtcTE9bnVsbDt0aGlzLmNvZWZmPW51bGx9ZnVuY3Rpb24gUlNBU2V0UHVibGljKGIsYSl7dGhpcy5pc1B1YmxpYz10cnVlO3RoaXMuaXNQcml2YXRlPWZhbHNlO2lmKHR5cGVvZiBiIT09XCJzdHJpbmdcIil7dGhpcy5uPWI7dGhpcy5lPWF9ZWxzZXtpZihiIT1udWxsJiZhIT1udWxsJiZiLmxlbmd0aD4wJiZhLmxlbmd0aD4wKXt0aGlzLm49cGFyc2VCaWdJbnQoYiwxNik7dGhpcy5lPXBhcnNlSW50KGEsMTYpfWVsc2V7dGhyb3dcIkludmFsaWQgUlNBIHB1YmxpYyBrZXlcIn19fWZ1bmN0aW9uIFJTQURvUHVibGljKGEpe3JldHVybiBhLm1vZFBvd0ludCh0aGlzLmUsdGhpcy5uKX1mdW5jdGlvbiBSU0FFbmNyeXB0KGQpe3ZhciBhPXBrY3MxcGFkMihkLCh0aGlzLm4uYml0TGVuZ3RoKCkrNyk+PjMpO2lmKGE9PW51bGwpe3JldHVybiBudWxsfXZhciBlPXRoaXMuZG9QdWJsaWMoYSk7aWYoZT09bnVsbCl7cmV0dXJuIG51bGx9dmFyIGI9ZS50b1N0cmluZygxNik7aWYoKGIubGVuZ3RoJjEpPT0wKXtyZXR1cm4gYn1lbHNle3JldHVyblwiMFwiK2J9fWZ1bmN0aW9uIFJTQUVuY3J5cHRPQUVQKGYsZSxiKXt2YXIgYT1vYWVwX3BhZChmLCh0aGlzLm4uYml0TGVuZ3RoKCkrNyk+PjMsZSxiKTtpZihhPT1udWxsKXtyZXR1cm4gbnVsbH12YXIgZz10aGlzLmRvUHVibGljKGEpO2lmKGc9PW51bGwpe3JldHVybiBudWxsfXZhciBkPWcudG9TdHJpbmcoMTYpO2lmKChkLmxlbmd0aCYxKT09MCl7cmV0dXJuIGR9ZWxzZXtyZXR1cm5cIjBcIitkfX1SU0FLZXkucHJvdG90eXBlLmRvUHVibGljPVJTQURvUHVibGljO1JTQUtleS5wcm90b3R5cGUuc2V0UHVibGljPVJTQVNldFB1YmxpYztSU0FLZXkucHJvdG90eXBlLmVuY3J5cHQ9UlNBRW5jcnlwdDtSU0FLZXkucHJvdG90eXBlLmVuY3J5cHRPQUVQPVJTQUVuY3J5cHRPQUVQO1JTQUtleS5wcm90b3R5cGUudHlwZT1cIlJTQVwiO1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG5mdW5jdGlvbiBFQ0ZpZWxkRWxlbWVudEZwKGIsYSl7dGhpcy54PWE7dGhpcy5xPWJ9ZnVuY3Rpb24gZmVGcEVxdWFscyhhKXtpZihhPT10aGlzKXtyZXR1cm4gdHJ1ZX1yZXR1cm4odGhpcy5xLmVxdWFscyhhLnEpJiZ0aGlzLnguZXF1YWxzKGEueCkpfWZ1bmN0aW9uIGZlRnBUb0JpZ0ludGVnZXIoKXtyZXR1cm4gdGhpcy54fWZ1bmN0aW9uIGZlRnBOZWdhdGUoKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5uZWdhdGUoKS5tb2QodGhpcy5xKSl9ZnVuY3Rpb24gZmVGcEFkZChhKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5hZGQoYS50b0JpZ0ludGVnZXIoKSkubW9kKHRoaXMucSkpfWZ1bmN0aW9uIGZlRnBTdWJ0cmFjdChhKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5zdWJ0cmFjdChhLnRvQmlnSW50ZWdlcigpKS5tb2QodGhpcy5xKSl9ZnVuY3Rpb24gZmVGcE11bHRpcGx5KGEpe3JldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsdGhpcy54Lm11bHRpcGx5KGEudG9CaWdJbnRlZ2VyKCkpLm1vZCh0aGlzLnEpKX1mdW5jdGlvbiBmZUZwU3F1YXJlKCl7cmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLnguc3F1YXJlKCkubW9kKHRoaXMucSkpfWZ1bmN0aW9uIGZlRnBEaXZpZGUoYSl7cmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLngubXVsdGlwbHkoYS50b0JpZ0ludGVnZXIoKS5tb2RJbnZlcnNlKHRoaXMucSkpLm1vZCh0aGlzLnEpKX1FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5lcXVhbHM9ZmVGcEVxdWFscztFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS50b0JpZ0ludGVnZXI9ZmVGcFRvQmlnSW50ZWdlcjtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5uZWdhdGU9ZmVGcE5lZ2F0ZTtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5hZGQ9ZmVGcEFkZDtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5zdWJ0cmFjdD1mZUZwU3VidHJhY3Q7RUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUubXVsdGlwbHk9ZmVGcE11bHRpcGx5O0VDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLnNxdWFyZT1mZUZwU3F1YXJlO0VDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLmRpdmlkZT1mZUZwRGl2aWRlO2Z1bmN0aW9uIEVDUG9pbnRGcChjLGEsZCxiKXt0aGlzLmN1cnZlPWM7dGhpcy54PWE7dGhpcy55PWQ7aWYoYj09bnVsbCl7dGhpcy56PUJpZ0ludGVnZXIuT05FfWVsc2V7dGhpcy56PWJ9dGhpcy56aW52PW51bGx9ZnVuY3Rpb24gcG9pbnRGcEdldFgoKXtpZih0aGlzLnppbnY9PW51bGwpe3RoaXMuemludj10aGlzLnoubW9kSW52ZXJzZSh0aGlzLmN1cnZlLnEpfXJldHVybiB0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKHRoaXMueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnppbnYpLm1vZCh0aGlzLmN1cnZlLnEpKX1mdW5jdGlvbiBwb2ludEZwR2V0WSgpe2lmKHRoaXMuemludj09bnVsbCl7dGhpcy56aW52PXRoaXMuei5tb2RJbnZlcnNlKHRoaXMuY3VydmUucSl9cmV0dXJuIHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIodGhpcy55LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KHRoaXMuemludikubW9kKHRoaXMuY3VydmUucSkpfWZ1bmN0aW9uIHBvaW50RnBFcXVhbHMoYSl7aWYoYT09dGhpcyl7cmV0dXJuIHRydWV9aWYodGhpcy5pc0luZmluaXR5KCkpe3JldHVybiBhLmlzSW5maW5pdHkoKX1pZihhLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXMuaXNJbmZpbml0eSgpfXZhciBjLGI7Yz1hLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkoYS56KSkubW9kKHRoaXMuY3VydmUucSk7aWYoIWMuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTykpe3JldHVybiBmYWxzZX1iPWEueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShhLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTtyZXR1cm4gYi5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKX1mdW5jdGlvbiBwb2ludEZwSXNJbmZpbml0eSgpe2lmKCh0aGlzLng9PW51bGwpJiYodGhpcy55PT1udWxsKSl7cmV0dXJuIHRydWV9cmV0dXJuIHRoaXMuei5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSYmIXRoaXMueS50b0JpZ0ludGVnZXIoKS5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKX1mdW5jdGlvbiBwb2ludEZwTmVnYXRlKCl7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSx0aGlzLngsdGhpcy55Lm5lZ2F0ZSgpLHRoaXMueil9ZnVuY3Rpb24gcG9pbnRGcEFkZChsKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIGx9aWYobC5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzfXZhciBwPWwueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShsLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgbz1sLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkobC56KSkubW9kKHRoaXMuY3VydmUucSk7aWYoQmlnSW50ZWdlci5aRVJPLmVxdWFscyhvKSl7aWYoQmlnSW50ZWdlci5aRVJPLmVxdWFscyhwKSl7cmV0dXJuIHRoaXMudHdpY2UoKX1yZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBqPW5ldyBCaWdJbnRlZ2VyKFwiM1wiKTt2YXIgZT10aGlzLngudG9CaWdJbnRlZ2VyKCk7dmFyIG49dGhpcy55LnRvQmlnSW50ZWdlcigpO3ZhciBjPWwueC50b0JpZ0ludGVnZXIoKTt2YXIgaz1sLnkudG9CaWdJbnRlZ2VyKCk7dmFyIG09by5zcXVhcmUoKTt2YXIgaT1tLm11bHRpcGx5KG8pO3ZhciBkPWUubXVsdGlwbHkobSk7dmFyIGc9cC5zcXVhcmUoKS5tdWx0aXBseSh0aGlzLnopO3ZhciBhPWcuc3VidHJhY3QoZC5zaGlmdExlZnQoMSkpLm11bHRpcGx5KGwueikuc3VidHJhY3QoaSkubXVsdGlwbHkobykubW9kKHRoaXMuY3VydmUucSk7dmFyIGg9ZC5tdWx0aXBseShqKS5tdWx0aXBseShwKS5zdWJ0cmFjdChuLm11bHRpcGx5KGkpKS5zdWJ0cmFjdChnLm11bHRpcGx5KHApKS5tdWx0aXBseShsLnopLmFkZChwLm11bHRpcGx5KGkpKS5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgZj1pLm11bHRpcGx5KHRoaXMueikubXVsdGlwbHkobC56KS5tb2QodGhpcy5jdXJ2ZS5xKTtyZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLmN1cnZlLHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoYSksdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcihoKSxmKX1mdW5jdGlvbiBwb2ludEZwVHdpY2UoKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXN9aWYodGhpcy55LnRvQmlnSW50ZWdlcigpLnNpZ251bSgpPT0wKXtyZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBnPW5ldyBCaWdJbnRlZ2VyKFwiM1wiKTt2YXIgYz10aGlzLngudG9CaWdJbnRlZ2VyKCk7dmFyIGg9dGhpcy55LnRvQmlnSW50ZWdlcigpO3ZhciBlPWgubXVsdGlwbHkodGhpcy56KTt2YXIgaj1lLm11bHRpcGx5KGgpLm1vZCh0aGlzLmN1cnZlLnEpO3ZhciBpPXRoaXMuY3VydmUuYS50b0JpZ0ludGVnZXIoKTt2YXIgaz1jLnNxdWFyZSgpLm11bHRpcGx5KGcpO2lmKCFCaWdJbnRlZ2VyLlpFUk8uZXF1YWxzKGkpKXtrPWsuYWRkKHRoaXMuei5zcXVhcmUoKS5tdWx0aXBseShpKSl9az1rLm1vZCh0aGlzLmN1cnZlLnEpO3ZhciBiPWsuc3F1YXJlKCkuc3VidHJhY3QoYy5zaGlmdExlZnQoMykubXVsdGlwbHkoaikpLnNoaWZ0TGVmdCgxKS5tdWx0aXBseShlKS5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgZj1rLm11bHRpcGx5KGcpLm11bHRpcGx5KGMpLnN1YnRyYWN0KGouc2hpZnRMZWZ0KDEpKS5zaGlmdExlZnQoMikubXVsdGlwbHkoaikuc3VidHJhY3Qoay5zcXVhcmUoKS5tdWx0aXBseShrKSkubW9kKHRoaXMuY3VydmUucSk7dmFyIGQ9ZS5zcXVhcmUoKS5tdWx0aXBseShlKS5zaGlmdExlZnQoMykubW9kKHRoaXMuY3VydmUucSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSx0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKGIpLHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoZiksZCl9ZnVuY3Rpb24gcG9pbnRGcE11bHRpcGx5KGIpe2lmKHRoaXMuaXNJbmZpbml0eSgpKXtyZXR1cm4gdGhpc31pZihiLnNpZ251bSgpPT0wKXtyZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBnPWI7dmFyIGY9Zy5tdWx0aXBseShuZXcgQmlnSW50ZWdlcihcIjNcIikpO3ZhciBsPXRoaXMubmVnYXRlKCk7dmFyIGQ9dGhpczt2YXIgYztmb3IoYz1mLmJpdExlbmd0aCgpLTI7Yz4wOy0tYyl7ZD1kLnR3aWNlKCk7dmFyIGE9Zi50ZXN0Qml0KGMpO3ZhciBqPWcudGVzdEJpdChjKTtpZihhIT1qKXtkPWQuYWRkKGE/dGhpczpsKX19cmV0dXJuIGR9ZnVuY3Rpb24gcG9pbnRGcE11bHRpcGx5VHdvKGMsYSxiKXt2YXIgZDtpZihjLmJpdExlbmd0aCgpPmIuYml0TGVuZ3RoKCkpe2Q9Yy5iaXRMZW5ndGgoKS0xfWVsc2V7ZD1iLmJpdExlbmd0aCgpLTF9dmFyIGY9dGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpO3ZhciBlPXRoaXMuYWRkKGEpO3doaWxlKGQ+PTApe2Y9Zi50d2ljZSgpO2lmKGMudGVzdEJpdChkKSl7aWYoYi50ZXN0Qml0KGQpKXtmPWYuYWRkKGUpfWVsc2V7Zj1mLmFkZCh0aGlzKX19ZWxzZXtpZihiLnRlc3RCaXQoZCkpe2Y9Zi5hZGQoYSl9fS0tZH1yZXR1cm4gZn1FQ1BvaW50RnAucHJvdG90eXBlLmdldFg9cG9pbnRGcEdldFg7RUNQb2ludEZwLnByb3RvdHlwZS5nZXRZPXBvaW50RnBHZXRZO0VDUG9pbnRGcC5wcm90b3R5cGUuZXF1YWxzPXBvaW50RnBFcXVhbHM7RUNQb2ludEZwLnByb3RvdHlwZS5pc0luZmluaXR5PXBvaW50RnBJc0luZmluaXR5O0VDUG9pbnRGcC5wcm90b3R5cGUubmVnYXRlPXBvaW50RnBOZWdhdGU7RUNQb2ludEZwLnByb3RvdHlwZS5hZGQ9cG9pbnRGcEFkZDtFQ1BvaW50RnAucHJvdG90eXBlLnR3aWNlPXBvaW50RnBUd2ljZTtFQ1BvaW50RnAucHJvdG90eXBlLm11bHRpcGx5PXBvaW50RnBNdWx0aXBseTtFQ1BvaW50RnAucHJvdG90eXBlLm11bHRpcGx5VHdvPXBvaW50RnBNdWx0aXBseVR3bztmdW5jdGlvbiBFQ0N1cnZlRnAoZSxkLGMpe3RoaXMucT1lO3RoaXMuYT10aGlzLmZyb21CaWdJbnRlZ2VyKGQpO3RoaXMuYj10aGlzLmZyb21CaWdJbnRlZ2VyKGMpO3RoaXMuaW5maW5pdHk9bmV3IEVDUG9pbnRGcCh0aGlzLG51bGwsbnVsbCl9ZnVuY3Rpb24gY3VydmVGcEdldFEoKXtyZXR1cm4gdGhpcy5xfWZ1bmN0aW9uIGN1cnZlRnBHZXRBKCl7cmV0dXJuIHRoaXMuYX1mdW5jdGlvbiBjdXJ2ZUZwR2V0Qigpe3JldHVybiB0aGlzLmJ9ZnVuY3Rpb24gY3VydmVGcEVxdWFscyhhKXtpZihhPT10aGlzKXtyZXR1cm4gdHJ1ZX1yZXR1cm4odGhpcy5xLmVxdWFscyhhLnEpJiZ0aGlzLmEuZXF1YWxzKGEuYSkmJnRoaXMuYi5lcXVhbHMoYS5iKSl9ZnVuY3Rpb24gY3VydmVGcEdldEluZmluaXR5KCl7cmV0dXJuIHRoaXMuaW5maW5pdHl9ZnVuY3Rpb24gY3VydmVGcEZyb21CaWdJbnRlZ2VyKGEpe3JldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsYSl9ZnVuY3Rpb24gY3VydmVGcERlY29kZVBvaW50SGV4KGQpe3N3aXRjaChwYXJzZUludChkLnN1YnN0cigwLDIpLDE2KSl7Y2FzZSAwOnJldHVybiB0aGlzLmluZmluaXR5O2Nhc2UgMjpjYXNlIDM6cmV0dXJuIG51bGw7Y2FzZSA0OmNhc2UgNjpjYXNlIDc6dmFyIGE9KGQubGVuZ3RoLTIpLzI7dmFyIGM9ZC5zdWJzdHIoMixhKTt2YXIgYj1kLnN1YnN0cihhKzIsYSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcyx0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKGMsMTYpKSx0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKGIsMTYpKSk7ZGVmYXVsdDpyZXR1cm4gbnVsbH19RUNDdXJ2ZUZwLnByb3RvdHlwZS5nZXRRPWN1cnZlRnBHZXRRO0VDQ3VydmVGcC5wcm90b3R5cGUuZ2V0QT1jdXJ2ZUZwR2V0QTtFQ0N1cnZlRnAucHJvdG90eXBlLmdldEI9Y3VydmVGcEdldEI7RUNDdXJ2ZUZwLnByb3RvdHlwZS5lcXVhbHM9Y3VydmVGcEVxdWFscztFQ0N1cnZlRnAucHJvdG90eXBlLmdldEluZmluaXR5PWN1cnZlRnBHZXRJbmZpbml0eTtFQ0N1cnZlRnAucHJvdG90eXBlLmZyb21CaWdJbnRlZ2VyPWN1cnZlRnBGcm9tQmlnSW50ZWdlcjtFQ0N1cnZlRnAucHJvdG90eXBlLmRlY29kZVBvaW50SGV4PWN1cnZlRnBEZWNvZGVQb2ludEhleDtcbi8qISAoYykgU3RlZmFuIFRob21hcyB8IGh0dHBzOi8vZ2l0aHViLmNvbS9iaXRjb2luanMvYml0Y29pbmpzLWxpYlxyXG4gKi9cclxuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuZ2V0Qnl0ZUxlbmd0aD1mdW5jdGlvbigpe3JldHVybiBNYXRoLmZsb29yKCh0aGlzLnRvQmlnSW50ZWdlcigpLmJpdExlbmd0aCgpKzcpLzgpfTtFQ1BvaW50RnAucHJvdG90eXBlLmdldEVuY29kZWQ9ZnVuY3Rpb24oYyl7dmFyIGQ9ZnVuY3Rpb24oaCxmKXt2YXIgZz1oLnRvQnl0ZUFycmF5VW5zaWduZWQoKTtpZihmPGcubGVuZ3RoKXtnPWcuc2xpY2UoZy5sZW5ndGgtZil9ZWxzZXt3aGlsZShmPmcubGVuZ3RoKXtnLnVuc2hpZnQoMCl9fXJldHVybiBnfTt2YXIgYT10aGlzLmdldFgoKS50b0JpZ0ludGVnZXIoKTt2YXIgZT10aGlzLmdldFkoKS50b0JpZ0ludGVnZXIoKTt2YXIgYj1kKGEsMzIpO2lmKGMpe2lmKGUuaXNFdmVuKCkpe2IudW5zaGlmdCgyKX1lbHNle2IudW5zaGlmdCgzKX19ZWxzZXtiLnVuc2hpZnQoNCk7Yj1iLmNvbmNhdChkKGUsMzIpKX1yZXR1cm4gYn07RUNQb2ludEZwLmRlY29kZUZyb209ZnVuY3Rpb24oZyxjKXt2YXIgZj1jWzBdO3ZhciBlPWMubGVuZ3RoLTE7dmFyIGQ9Yy5zbGljZSgxLDErZS8yKTt2YXIgYj1jLnNsaWNlKDErZS8yLDErZSk7ZC51bnNoaWZ0KDApO2IudW5zaGlmdCgwKTt2YXIgYT1uZXcgQmlnSW50ZWdlcihkKTt2YXIgaD1uZXcgQmlnSW50ZWdlcihiKTtyZXR1cm4gbmV3IEVDUG9pbnRGcChnLGcuZnJvbUJpZ0ludGVnZXIoYSksZy5mcm9tQmlnSW50ZWdlcihoKSl9O0VDUG9pbnRGcC5kZWNvZGVGcm9tSGV4PWZ1bmN0aW9uKGcsYyl7dmFyIGY9Yy5zdWJzdHIoMCwyKTt2YXIgZT1jLmxlbmd0aC0yO3ZhciBkPWMuc3Vic3RyKDIsZS8yKTt2YXIgYj1jLnN1YnN0cigyK2UvMixlLzIpO3ZhciBhPW5ldyBCaWdJbnRlZ2VyKGQsMTYpO3ZhciBoPW5ldyBCaWdJbnRlZ2VyKGIsMTYpO3JldHVybiBuZXcgRUNQb2ludEZwKGcsZy5mcm9tQmlnSW50ZWdlcihhKSxnLmZyb21CaWdJbnRlZ2VyKGgpKX07RUNQb2ludEZwLnByb3RvdHlwZS5hZGQyRD1mdW5jdGlvbihjKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIGN9aWYoYy5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzfWlmKHRoaXMueC5lcXVhbHMoYy54KSl7aWYodGhpcy55LmVxdWFscyhjLnkpKXtyZXR1cm4gdGhpcy50d2ljZSgpfXJldHVybiB0aGlzLmN1cnZlLmdldEluZmluaXR5KCl9dmFyIGc9Yy54LnN1YnRyYWN0KHRoaXMueCk7dmFyIGU9Yy55LnN1YnRyYWN0KHRoaXMueSk7dmFyIGE9ZS5kaXZpZGUoZyk7dmFyIGQ9YS5zcXVhcmUoKS5zdWJ0cmFjdCh0aGlzLngpLnN1YnRyYWN0KGMueCk7dmFyIGY9YS5tdWx0aXBseSh0aGlzLnguc3VidHJhY3QoZCkpLnN1YnRyYWN0KHRoaXMueSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSxkLGYpfTtFQ1BvaW50RnAucHJvdG90eXBlLnR3aWNlMkQ9ZnVuY3Rpb24oKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXN9aWYodGhpcy55LnRvQmlnSW50ZWdlcigpLnNpZ251bSgpPT0wKXtyZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBiPXRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoQmlnSW50ZWdlci52YWx1ZU9mKDIpKTt2YXIgZT10aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKEJpZ0ludGVnZXIudmFsdWVPZigzKSk7dmFyIGE9dGhpcy54LnNxdWFyZSgpLm11bHRpcGx5KGUpLmFkZCh0aGlzLmN1cnZlLmEpLmRpdmlkZSh0aGlzLnkubXVsdGlwbHkoYikpO3ZhciBjPWEuc3F1YXJlKCkuc3VidHJhY3QodGhpcy54Lm11bHRpcGx5KGIpKTt2YXIgZD1hLm11bHRpcGx5KHRoaXMueC5zdWJ0cmFjdChjKSkuc3VidHJhY3QodGhpcy55KTtyZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLmN1cnZlLGMsZCl9O0VDUG9pbnRGcC5wcm90b3R5cGUubXVsdGlwbHkyRD1mdW5jdGlvbihiKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXN9aWYoYi5zaWdudW0oKT09MCl7cmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKX12YXIgZz1iO3ZhciBmPWcubXVsdGlwbHkobmV3IEJpZ0ludGVnZXIoXCIzXCIpKTt2YXIgbD10aGlzLm5lZ2F0ZSgpO3ZhciBkPXRoaXM7dmFyIGM7Zm9yKGM9Zi5iaXRMZW5ndGgoKS0yO2M+MDstLWMpe2Q9ZC50d2ljZSgpO3ZhciBhPWYudGVzdEJpdChjKTt2YXIgaj1nLnRlc3RCaXQoYyk7aWYoYSE9ail7ZD1kLmFkZDJEKGE/dGhpczpsKX19cmV0dXJuIGR9O0VDUG9pbnRGcC5wcm90b3R5cGUuaXNPbkN1cnZlPWZ1bmN0aW9uKCl7dmFyIGQ9dGhpcy5nZXRYKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGk9dGhpcy5nZXRZKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGY9dGhpcy5jdXJ2ZS5nZXRBKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGM9dGhpcy5jdXJ2ZS5nZXRCKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGg9dGhpcy5jdXJ2ZS5nZXRRKCk7dmFyIGU9aS5tdWx0aXBseShpKS5tb2QoaCk7dmFyIGc9ZC5tdWx0aXBseShkKS5tdWx0aXBseShkKS5hZGQoZi5tdWx0aXBseShkKSkuYWRkKGMpLm1vZChoKTtyZXR1cm4gZS5lcXVhbHMoZyl9O0VDUG9pbnRGcC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm5cIihcIit0aGlzLmdldFgoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygpK1wiLFwiK3RoaXMuZ2V0WSgpLnRvQmlnSW50ZWdlcigpLnRvU3RyaW5nKCkrXCIpXCJ9O0VDUG9pbnRGcC5wcm90b3R5cGUudmFsaWRhdGU9ZnVuY3Rpb24oKXt2YXIgYz10aGlzLmN1cnZlLmdldFEoKTtpZih0aGlzLmlzSW5maW5pdHkoKSl7dGhyb3cgbmV3IEVycm9yKFwiUG9pbnQgaXMgYXQgaW5maW5pdHkuXCIpfXZhciBhPXRoaXMuZ2V0WCgpLnRvQmlnSW50ZWdlcigpO3ZhciBiPXRoaXMuZ2V0WSgpLnRvQmlnSW50ZWdlcigpO2lmKGEuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKTwwfHxhLmNvbXBhcmVUbyhjLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSk+MCl7dGhyb3cgbmV3IEVycm9yKFwieCBjb29yZGluYXRlIG91dCBvZiBib3VuZHNcIil9aWYoYi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpPDB8fGIuY29tcGFyZVRvKGMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKT4wKXt0aHJvdyBuZXcgRXJyb3IoXCJ5IGNvb3JkaW5hdGUgb3V0IG9mIGJvdW5kc1wiKX1pZighdGhpcy5pc09uQ3VydmUoKSl7dGhyb3cgbmV3IEVycm9yKFwiUG9pbnQgaXMgbm90IG9uIHRoZSBjdXJ2ZS5cIil9aWYodGhpcy5tdWx0aXBseShjKS5pc0luZmluaXR5KCkpe3Rocm93IG5ldyBFcnJvcihcIlBvaW50IGlzIG5vdCBhIHNjYWxhciBtdWx0aXBsZSBvZiBHLlwiKX1yZXR1cm4gdHJ1ZX07XG4vKiEgTWlrZSBTYW11ZWwgKGMpIDIwMDkgfCBjb2RlLmdvb2dsZS5jb20vcC9qc29uLXNhbnMtZXZhbFxyXG4gKi9cclxudmFyIGpzb25QYXJzZT0oZnVuY3Rpb24oKXt2YXIgZT1cIig/Oi0/XFxcXGIoPzowfFsxLTldWzAtOV0qKSg/OlxcXFwuWzAtOV0rKT8oPzpbZUVdWystXT9bMC05XSspP1xcXFxiKVwiO3ZhciBqPScoPzpbXlxcXFwwLVxcXFx4MDhcXFxceDBhLVxcXFx4MWZcIlxcXFxcXFxcXXxcXFxcXFxcXCg/OltcIi9cXFxcXFxcXGJmbnJ0XXx1WzAtOUEtRmEtZl17NH0pKSc7dmFyIGk9Jyg/OlwiJytqKycqXCIpJzt2YXIgZD1uZXcgUmVnRXhwKFwiKD86ZmFsc2V8dHJ1ZXxudWxsfFtcXFxce1xcXFx9XFxcXFtcXFxcXV18XCIrZStcInxcIitpK1wiKVwiLFwiZ1wiKTt2YXIgaz1uZXcgUmVnRXhwKFwiXFxcXFxcXFwoPzooW151XSl8dSguezR9KSlcIixcImdcIik7dmFyIGc9eydcIic6J1wiJyxcIi9cIjpcIi9cIixcIlxcXFxcIjpcIlxcXFxcIixiOlwiXFxiXCIsZjpcIlxcZlwiLG46XCJcXG5cIixyOlwiXFxyXCIsdDpcIlxcdFwifTtmdW5jdGlvbiBoKGwsbSxuKXtyZXR1cm4gbT9nW21dOlN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQobiwxNikpfXZhciBjPW5ldyBTdHJpbmcoXCJcIik7dmFyIGE9XCJcXFxcXCI7dmFyIGY9e1wie1wiOk9iamVjdCxcIltcIjpBcnJheX07dmFyIGI9T2JqZWN0Lmhhc093blByb3BlcnR5O3JldHVybiBmdW5jdGlvbih1LHEpe3ZhciBwPXUubWF0Y2goZCk7dmFyIHg7dmFyIHY9cFswXTt2YXIgbD1mYWxzZTtpZihcIntcIj09PXYpe3g9e319ZWxzZXtpZihcIltcIj09PXYpe3g9W119ZWxzZXt4PVtdO2w9dHJ1ZX19dmFyIHQ7dmFyIHI9W3hdO2Zvcih2YXIgbz0xLWwsbT1wLmxlbmd0aDtvPG07KytvKXt2PXBbb107dmFyIHc7c3dpdGNoKHYuY2hhckNvZGVBdCgwKSl7ZGVmYXVsdDp3PXJbMF07d1t0fHx3Lmxlbmd0aF09Kyh2KTt0PXZvaWQgMDticmVhaztjYXNlIDM0OnY9di5zdWJzdHJpbmcoMSx2Lmxlbmd0aC0xKTtpZih2LmluZGV4T2YoYSkhPT0tMSl7dj12LnJlcGxhY2UoayxoKX13PXJbMF07aWYoIXQpe2lmKHcgaW5zdGFuY2VvZiBBcnJheSl7dD13Lmxlbmd0aH1lbHNle3Q9dnx8YzticmVha319d1t0XT12O3Q9dm9pZCAwO2JyZWFrO2Nhc2UgOTE6dz1yWzBdO3IudW5zaGlmdCh3W3R8fHcubGVuZ3RoXT1bXSk7dD12b2lkIDA7YnJlYWs7Y2FzZSA5MzpyLnNoaWZ0KCk7YnJlYWs7Y2FzZSAxMDI6dz1yWzBdO3dbdHx8dy5sZW5ndGhdPWZhbHNlO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTEwOnc9clswXTt3W3R8fHcubGVuZ3RoXT1udWxsO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTE2Onc9clswXTt3W3R8fHcubGVuZ3RoXT10cnVlO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTIzOnc9clswXTtyLnVuc2hpZnQod1t0fHx3Lmxlbmd0aF09e30pO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTI1OnIuc2hpZnQoKTticmVha319aWYobCl7aWYoci5sZW5ndGghPT0xKXt0aHJvdyBuZXcgRXJyb3IoKX14PXhbMF19ZWxzZXtpZihyLmxlbmd0aCl7dGhyb3cgbmV3IEVycm9yKCl9fWlmKHEpe3ZhciBzPWZ1bmN0aW9uKEMsQil7dmFyIEQ9Q1tCXTtpZihEJiZ0eXBlb2YgRD09PVwib2JqZWN0XCIpe3ZhciBuPW51bGw7Zm9yKHZhciB6IGluIEQpe2lmKGIuY2FsbChELHopJiZEIT09Qyl7dmFyIHk9cyhELHopO2lmKHkhPT12b2lkIDApe0Rbel09eX1lbHNle2lmKCFuKXtuPVtdfW4ucHVzaCh6KX19fWlmKG4pe2Zvcih2YXIgQT1uLmxlbmd0aDstLUE+PTA7KXtkZWxldGUgRFtuW0FdXX19fXJldHVybiBxLmNhbGwoQyxCLEQpfTt4PXMoe1wiXCI6eH0sXCJcIil9cmV0dXJuIHh9fSkoKTtcbmlmKHR5cGVvZiBLSlVSPT1cInVuZGVmaW5lZFwifHwhS0pVUil7S0pVUj17fX1pZih0eXBlb2YgS0pVUi5hc24xPT1cInVuZGVmaW5lZFwifHwhS0pVUi5hc24xKXtLSlVSLmFzbjE9e319S0pVUi5hc24xLkFTTjFVdGlsPW5ldyBmdW5jdGlvbigpe3RoaXMuaW50ZWdlclRvQnl0ZUhleD1mdW5jdGlvbihhKXt2YXIgYj1hLnRvU3RyaW5nKDE2KTtpZigoYi5sZW5ndGglMik9PTEpe2I9XCIwXCIrYn1yZXR1cm4gYn07dGhpcy5iaWdJbnRUb01pblR3b3NDb21wbGVtZW50c0hleD1mdW5jdGlvbihqKXt2YXIgZj1qLnRvU3RyaW5nKDE2KTtpZihmLnN1YnN0cigwLDEpIT1cIi1cIil7aWYoZi5sZW5ndGglMj09MSl7Zj1cIjBcIitmfWVsc2V7aWYoIWYubWF0Y2goL15bMC03XS8pKXtmPVwiMDBcIitmfX19ZWxzZXt2YXIgYT1mLnN1YnN0cigxKTt2YXIgZT1hLmxlbmd0aDtpZihlJTI9PTEpe2UrPTF9ZWxzZXtpZighZi5tYXRjaCgvXlswLTddLykpe2UrPTJ9fXZhciBnPVwiXCI7Zm9yKHZhciBkPTA7ZDxlO2QrKyl7Zys9XCJmXCJ9dmFyIGM9bmV3IEJpZ0ludGVnZXIoZywxNik7dmFyIGI9Yy54b3IoaikuYWRkKEJpZ0ludGVnZXIuT05FKTtmPWIudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14tLyxcIlwiKX1yZXR1cm4gZn07dGhpcy5nZXRQRU1TdHJpbmdGcm9tSGV4PWZ1bmN0aW9uKGEsYil7cmV0dXJuIGhleHRvcGVtKGEsYil9O3RoaXMubmV3T2JqZWN0PWZ1bmN0aW9uKGspe3ZhciBEPUtKVVIsbj1ELmFzbjEsej1uLkRFUkJvb2xlYW4sZT1uLkRFUkludGVnZXIscz1uLkRFUkJpdFN0cmluZyxoPW4uREVST2N0ZXRTdHJpbmcsdj1uLkRFUk51bGwsdz1uLkRFUk9iamVjdElkZW50aWZpZXIsbD1uLkRFUkVudW1lcmF0ZWQsZz1uLkRFUlVURjhTdHJpbmcsZj1uLkRFUk51bWVyaWNTdHJpbmcseT1uLkRFUlByaW50YWJsZVN0cmluZyx1PW4uREVSVGVsZXRleFN0cmluZyxwPW4uREVSSUE1U3RyaW5nLEM9bi5ERVJVVENUaW1lLGo9bi5ERVJHZW5lcmFsaXplZFRpbWUsbT1uLkRFUlNlcXVlbmNlLGM9bi5ERVJTZXQscj1uLkRFUlRhZ2dlZE9iamVjdCxvPW4uQVNOMVV0aWwubmV3T2JqZWN0O3ZhciB0PU9iamVjdC5rZXlzKGspO2lmKHQubGVuZ3RoIT0xKXt0aHJvd1wia2V5IG9mIHBhcmFtIHNoYWxsIGJlIG9ubHkgb25lLlwifXZhciBGPXRbMF07aWYoXCI6Ym9vbDppbnQ6Yml0c3RyOm9jdHN0cjpudWxsOm9pZDplbnVtOnV0ZjhzdHI6bnVtc3RyOnBybnN0cjp0ZWxzdHI6aWE1c3RyOnV0Y3RpbWU6Z2VudGltZTpzZXE6c2V0OnRhZzpcIi5pbmRleE9mKFwiOlwiK0YrXCI6XCIpPT0tMSl7dGhyb3dcInVuZGVmaW5lZCBrZXk6IFwiK0Z9aWYoRj09XCJib29sXCIpe3JldHVybiBuZXcgeihrW0ZdKX1pZihGPT1cImludFwiKXtyZXR1cm4gbmV3IGUoa1tGXSl9aWYoRj09XCJiaXRzdHJcIil7cmV0dXJuIG5ldyBzKGtbRl0pfWlmKEY9PVwib2N0c3RyXCIpe3JldHVybiBuZXcgaChrW0ZdKX1pZihGPT1cIm51bGxcIil7cmV0dXJuIG5ldyB2KGtbRl0pfWlmKEY9PVwib2lkXCIpe3JldHVybiBuZXcgdyhrW0ZdKX1pZihGPT1cImVudW1cIil7cmV0dXJuIG5ldyBsKGtbRl0pfWlmKEY9PVwidXRmOHN0clwiKXtyZXR1cm4gbmV3IGcoa1tGXSl9aWYoRj09XCJudW1zdHJcIil7cmV0dXJuIG5ldyBmKGtbRl0pfWlmKEY9PVwicHJuc3RyXCIpe3JldHVybiBuZXcgeShrW0ZdKX1pZihGPT1cInRlbHN0clwiKXtyZXR1cm4gbmV3IHUoa1tGXSl9aWYoRj09XCJpYTVzdHJcIil7cmV0dXJuIG5ldyBwKGtbRl0pfWlmKEY9PVwidXRjdGltZVwiKXtyZXR1cm4gbmV3IEMoa1tGXSl9aWYoRj09XCJnZW50aW1lXCIpe3JldHVybiBuZXcgaihrW0ZdKX1pZihGPT1cInNlcVwiKXt2YXIgZD1rW0ZdO3ZhciBFPVtdO2Zvcih2YXIgeD0wO3g8ZC5sZW5ndGg7eCsrKXt2YXIgQj1vKGRbeF0pO0UucHVzaChCKX1yZXR1cm4gbmV3IG0oe2FycmF5OkV9KX1pZihGPT1cInNldFwiKXt2YXIgZD1rW0ZdO3ZhciBFPVtdO2Zvcih2YXIgeD0wO3g8ZC5sZW5ndGg7eCsrKXt2YXIgQj1vKGRbeF0pO0UucHVzaChCKX1yZXR1cm4gbmV3IGMoe2FycmF5OkV9KX1pZihGPT1cInRhZ1wiKXt2YXIgQT1rW0ZdO2lmKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChBKT09PVwiW29iamVjdCBBcnJheV1cIiYmQS5sZW5ndGg9PTMpe3ZhciBxPW8oQVsyXSk7cmV0dXJuIG5ldyByKHt0YWc6QVswXSxleHBsaWNpdDpBWzFdLG9iajpxfSl9ZWxzZXt2YXIgYj17fTtpZihBLmV4cGxpY2l0IT09dW5kZWZpbmVkKXtiLmV4cGxpY2l0PUEuZXhwbGljaXR9aWYoQS50YWchPT11bmRlZmluZWQpe2IudGFnPUEudGFnfWlmKEEub2JqPT09dW5kZWZpbmVkKXt0aHJvd1wib2JqIHNoYWxsIGJlIHNwZWNpZmllZCBmb3IgJ3RhZycuXCJ9Yi5vYmo9byhBLm9iaik7cmV0dXJuIG5ldyByKGIpfX19O3RoaXMuanNvblRvQVNOMUhFWD1mdW5jdGlvbihiKXt2YXIgYT10aGlzLm5ld09iamVjdChiKTtyZXR1cm4gYS5nZXRFbmNvZGVkSGV4KCl9fTtLSlVSLmFzbjEuQVNOMVV0aWwub2lkSGV4VG9JbnQ9ZnVuY3Rpb24oYSl7dmFyIGo9XCJcIjt2YXIgaz1wYXJzZUludChhLnN1YnN0cigwLDIpLDE2KTt2YXIgZD1NYXRoLmZsb29yKGsvNDApO3ZhciBjPWslNDA7dmFyIGo9ZCtcIi5cIitjO3ZhciBlPVwiXCI7Zm9yKHZhciBmPTI7ZjxhLmxlbmd0aDtmKz0yKXt2YXIgZz1wYXJzZUludChhLnN1YnN0cihmLDIpLDE2KTt2YXIgaD0oXCIwMDAwMDAwMFwiK2cudG9TdHJpbmcoMikpLnNsaWNlKC04KTtlPWUraC5zdWJzdHIoMSw3KTtpZihoLnN1YnN0cigwLDEpPT1cIjBcIil7dmFyIGI9bmV3IEJpZ0ludGVnZXIoZSwyKTtqPWorXCIuXCIrYi50b1N0cmluZygxMCk7ZT1cIlwifX1yZXR1cm4gan07S0pVUi5hc24xLkFTTjFVdGlsLm9pZEludFRvSGV4PWZ1bmN0aW9uKGYpe3ZhciBlPWZ1bmN0aW9uKGEpe3ZhciBrPWEudG9TdHJpbmcoMTYpO2lmKGsubGVuZ3RoPT0xKXtrPVwiMFwiK2t9cmV0dXJuIGt9O3ZhciBkPWZ1bmN0aW9uKG8pe3ZhciBuPVwiXCI7dmFyIGs9bmV3IEJpZ0ludGVnZXIobywxMCk7dmFyIGE9ay50b1N0cmluZygyKTt2YXIgbD03LWEubGVuZ3RoJTc7aWYobD09Nyl7bD0wfXZhciBxPVwiXCI7Zm9yKHZhciBtPTA7bTxsO20rKyl7cSs9XCIwXCJ9YT1xK2E7Zm9yKHZhciBtPTA7bTxhLmxlbmd0aC0xO20rPTcpe3ZhciBwPWEuc3Vic3RyKG0sNyk7aWYobSE9YS5sZW5ndGgtNyl7cD1cIjFcIitwfW4rPWUocGFyc2VJbnQocCwyKSl9cmV0dXJuIG59O2lmKCFmLm1hdGNoKC9eWzAtOS5dKyQvKSl7dGhyb3dcIm1hbGZvcm1lZCBvaWQgc3RyaW5nOiBcIitmfXZhciBnPVwiXCI7dmFyIGI9Zi5zcGxpdChcIi5cIik7dmFyIGo9cGFyc2VJbnQoYlswXSkqNDArcGFyc2VJbnQoYlsxXSk7Zys9ZShqKTtiLnNwbGljZSgwLDIpO2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGg7YysrKXtnKz1kKGJbY10pfXJldHVybiBnfTtLSlVSLmFzbjEuQVNOMU9iamVjdD1mdW5jdGlvbigpe3ZhciBjPXRydWU7dmFyIGI9bnVsbDt2YXIgZD1cIjAwXCI7dmFyIGU9XCIwMFwiO3ZhciBhPVwiXCI7dGhpcy5nZXRMZW5ndGhIZXhGcm9tVmFsdWU9ZnVuY3Rpb24oKXtpZih0eXBlb2YgdGhpcy5oVj09XCJ1bmRlZmluZWRcInx8dGhpcy5oVj09bnVsbCl7dGhyb3dcInRoaXMuaFYgaXMgbnVsbCBvciB1bmRlZmluZWQuXCJ9aWYodGhpcy5oVi5sZW5ndGglMj09MSl7dGhyb3dcInZhbHVlIGhleCBtdXN0IGJlIGV2ZW4gbGVuZ3RoOiBuPVwiK2EubGVuZ3RoK1wiLHY9XCIrdGhpcy5oVn12YXIgaT10aGlzLmhWLmxlbmd0aC8yO3ZhciBoPWkudG9TdHJpbmcoMTYpO2lmKGgubGVuZ3RoJTI9PTEpe2g9XCIwXCIraH1pZihpPDEyOCl7cmV0dXJuIGh9ZWxzZXt2YXIgZz1oLmxlbmd0aC8yO2lmKGc+MTUpe3Rocm93XCJBU04uMSBsZW5ndGggdG9vIGxvbmcgdG8gcmVwcmVzZW50IGJ5IDh4OiBuID0gXCIraS50b1N0cmluZygxNil9dmFyIGY9MTI4K2c7cmV0dXJuIGYudG9TdHJpbmcoMTYpK2h9fTt0aGlzLmdldEVuY29kZWRIZXg9ZnVuY3Rpb24oKXtpZih0aGlzLmhUTFY9PW51bGx8fHRoaXMuaXNNb2RpZmllZCl7dGhpcy5oVj10aGlzLmdldEZyZXNoVmFsdWVIZXgoKTt0aGlzLmhMPXRoaXMuZ2V0TGVuZ3RoSGV4RnJvbVZhbHVlKCk7dGhpcy5oVExWPXRoaXMuaFQrdGhpcy5oTCt0aGlzLmhWO3RoaXMuaXNNb2RpZmllZD1mYWxzZX1yZXR1cm4gdGhpcy5oVExWfTt0aGlzLmdldFZhbHVlSGV4PWZ1bmN0aW9uKCl7dGhpcy5nZXRFbmNvZGVkSGV4KCk7cmV0dXJuIHRoaXMuaFZ9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVyblwiXCJ9fTtLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJpbmc9ZnVuY3Rpb24oYyl7S0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt2YXIgYj1udWxsO3ZhciBhPW51bGw7dGhpcy5nZXRTdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5zfTt0aGlzLnNldFN0cmluZz1mdW5jdGlvbihkKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLnM9ZDt0aGlzLmhWPXV0Zjh0b2hleCh0aGlzLnMpLnRvTG93ZXJDYXNlKCl9O3RoaXMuc2V0U3RyaW5nSGV4PWZ1bmN0aW9uKGQpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMucz1udWxsO3RoaXMuaFY9ZH07dGhpcy5nZXRGcmVzaFZhbHVlSGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaFZ9O2lmKHR5cGVvZiBjIT1cInVuZGVmaW5lZFwiKXtpZih0eXBlb2YgYz09XCJzdHJpbmdcIil7dGhpcy5zZXRTdHJpbmcoYyl9ZWxzZXtpZih0eXBlb2YgYy5zdHIhPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0U3RyaW5nKGMuc3RyKX1lbHNle2lmKHR5cGVvZiBjLmhleCE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRTdHJpbmdIZXgoYy5oZXgpfX19fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSQWJzdHJhY3RUaW1lPWZ1bmN0aW9uKGMpe0tKVVIuYXNuMS5ERVJBYnN0cmFjdFRpbWUuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3ZhciBiPW51bGw7dmFyIGE9bnVsbDt0aGlzLmxvY2FsRGF0ZVRvVVRDPWZ1bmN0aW9uKGYpe3V0Yz1mLmdldFRpbWUoKSsoZi5nZXRUaW1lem9uZU9mZnNldCgpKjYwMDAwKTt2YXIgZT1uZXcgRGF0ZSh1dGMpO3JldHVybiBlfTt0aGlzLmZvcm1hdERhdGU9ZnVuY3Rpb24obSxvLGUpe3ZhciBnPXRoaXMuemVyb1BhZGRpbmc7dmFyIG49dGhpcy5sb2NhbERhdGVUb1VUQyhtKTt2YXIgcD1TdHJpbmcobi5nZXRGdWxsWWVhcigpKTtpZihvPT1cInV0Y1wiKXtwPXAuc3Vic3RyKDIsMil9dmFyIGw9ZyhTdHJpbmcobi5nZXRNb250aCgpKzEpLDIpO3ZhciBxPWcoU3RyaW5nKG4uZ2V0RGF0ZSgpKSwyKTt2YXIgaD1nKFN0cmluZyhuLmdldEhvdXJzKCkpLDIpO3ZhciBpPWcoU3RyaW5nKG4uZ2V0TWludXRlcygpKSwyKTt2YXIgaj1nKFN0cmluZyhuLmdldFNlY29uZHMoKSksMik7dmFyIHI9cCtsK3EraCtpK2o7aWYoZT09PXRydWUpe3ZhciBmPW4uZ2V0TWlsbGlzZWNvbmRzKCk7aWYoZiE9MCl7dmFyIGs9ZyhTdHJpbmcoZiksMyk7az1rLnJlcGxhY2UoL1swXSskLyxcIlwiKTtyPXIrXCIuXCIra319cmV0dXJuIHIrXCJaXCJ9O3RoaXMuemVyb1BhZGRpbmc9ZnVuY3Rpb24oZSxkKXtpZihlLmxlbmd0aD49ZCl7cmV0dXJuIGV9cmV0dXJuIG5ldyBBcnJheShkLWUubGVuZ3RoKzEpLmpvaW4oXCIwXCIpK2V9O3RoaXMuZ2V0U3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuc307dGhpcy5zZXRTdHJpbmc9ZnVuY3Rpb24oZCl7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5zPWQ7dGhpcy5oVj1zdG9oZXgoZCl9O3RoaXMuc2V0QnlEYXRlVmFsdWU9ZnVuY3Rpb24oaCxqLGUsZCxmLGcpe3ZhciBpPW5ldyBEYXRlKERhdGUuVVRDKGgsai0xLGUsZCxmLGcsMCkpO3RoaXMuc2V0QnlEYXRlKGkpfTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJBYnN0cmFjdFRpbWUsS0pVUi5hc24xLkFTTjFPYmplY3QpO0tKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cnVjdHVyZWQ9ZnVuY3Rpb24oYil7S0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt2YXIgYT1udWxsO3RoaXMuc2V0QnlBU04xT2JqZWN0QXJyYXk9ZnVuY3Rpb24oYyl7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5hc24xQXJyYXk9Y307dGhpcy5hcHBlbmRBU04xT2JqZWN0PWZ1bmN0aW9uKGMpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMuYXNuMUFycmF5LnB1c2goYyl9O3RoaXMuYXNuMUFycmF5PW5ldyBBcnJheSgpO2lmKHR5cGVvZiBiIT1cInVuZGVmaW5lZFwiKXtpZih0eXBlb2YgYi5hcnJheSE9XCJ1bmRlZmluZWRcIil7dGhpcy5hc24xQXJyYXk9Yi5hcnJheX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJ1Y3R1cmVkLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSQm9vbGVhbj1mdW5jdGlvbigpe0tKVVIuYXNuMS5ERVJCb29sZWFuLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDFcIjt0aGlzLmhUTFY9XCIwMTAxZmZcIn07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkJvb2xlYW4sS0pVUi5hc24xLkFTTjFPYmplY3QpO0tKVVIuYXNuMS5ERVJJbnRlZ2VyPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJJbnRlZ2VyLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDJcIjt0aGlzLnNldEJ5QmlnSW50ZWdlcj1mdW5jdGlvbihiKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPUtKVVIuYXNuMS5BU04xVXRpbC5iaWdJbnRUb01pblR3b3NDb21wbGVtZW50c0hleChiKX07dGhpcy5zZXRCeUludGVnZXI9ZnVuY3Rpb24oYyl7dmFyIGI9bmV3IEJpZ0ludGVnZXIoU3RyaW5nKGMpLDEwKTt0aGlzLnNldEJ5QmlnSW50ZWdlcihiKX07dGhpcy5zZXRWYWx1ZUhleD1mdW5jdGlvbihiKXt0aGlzLmhWPWJ9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYSE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGEuYmlnaW50IT1cInVuZGVmaW5lZFwiKXt0aGlzLnNldEJ5QmlnSW50ZWdlcihhLmJpZ2ludCl9ZWxzZXtpZih0eXBlb2YgYVtcImludFwiXSE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUludGVnZXIoYVtcImludFwiXSl9ZWxzZXtpZih0eXBlb2YgYT09XCJudW1iZXJcIil7dGhpcy5zZXRCeUludGVnZXIoYSl9ZWxzZXtpZih0eXBlb2YgYS5oZXghPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0VmFsdWVIZXgoYS5oZXgpfX19fX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJJbnRlZ2VyLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSQml0U3RyaW5nPWZ1bmN0aW9uKGIpe2lmKGIhPT11bmRlZmluZWQmJnR5cGVvZiBiLm9iaiE9PVwidW5kZWZpbmVkXCIpe3ZhciBhPUtKVVIuYXNuMS5BU04xVXRpbC5uZXdPYmplY3QoYi5vYmopO2IuaGV4PVwiMDBcIithLmdldEVuY29kZWRIZXgoKX1LSlVSLmFzbjEuREVSQml0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDNcIjt0aGlzLnNldEhleFZhbHVlSW5jbHVkaW5nVW51c2VkQml0cz1mdW5jdGlvbihjKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPWN9O3RoaXMuc2V0VW51c2VkQml0c0FuZEhleFZhbHVlPWZ1bmN0aW9uKGMsZSl7aWYoYzwwfHw3PGMpe3Rocm93XCJ1bnVzZWQgYml0cyBzaGFsbCBiZSBmcm9tIDAgdG8gNzogdSA9IFwiK2N9dmFyIGQ9XCIwXCIrYzt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPWQrZX07dGhpcy5zZXRCeUJpbmFyeVN0cmluZz1mdW5jdGlvbihlKXtlPWUucmVwbGFjZSgvMCskLyxcIlwiKTt2YXIgZj04LWUubGVuZ3RoJTg7aWYoZj09OCl7Zj0wfWZvcih2YXIgZz0wO2c8PWY7ZysrKXtlKz1cIjBcIn12YXIgaj1cIlwiO2Zvcih2YXIgZz0wO2c8ZS5sZW5ndGgtMTtnKz04KXt2YXIgZD1lLnN1YnN0cihnLDgpO3ZhciBjPXBhcnNlSW50KGQsMikudG9TdHJpbmcoMTYpO2lmKGMubGVuZ3RoPT0xKXtjPVwiMFwiK2N9ais9Y310aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPVwiMFwiK2Yran07dGhpcy5zZXRCeUJvb2xlYW5BcnJheT1mdW5jdGlvbihlKXt2YXIgZD1cIlwiO2Zvcih2YXIgYz0wO2M8ZS5sZW5ndGg7YysrKXtpZihlW2NdPT10cnVlKXtkKz1cIjFcIn1lbHNle2QrPVwiMFwifX10aGlzLnNldEJ5QmluYXJ5U3RyaW5nKGQpfTt0aGlzLm5ld0ZhbHNlQXJyYXk9ZnVuY3Rpb24oZSl7dmFyIGM9bmV3IEFycmF5KGUpO2Zvcih2YXIgZD0wO2Q8ZTtkKyspe2NbZF09ZmFsc2V9cmV0dXJuIGN9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYiE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGI9PVwic3RyaW5nXCImJmIudG9Mb3dlckNhc2UoKS5tYXRjaCgvXlswLTlhLWZdKyQvKSl7dGhpcy5zZXRIZXhWYWx1ZUluY2x1ZGluZ1VudXNlZEJpdHMoYil9ZWxzZXtpZih0eXBlb2YgYi5oZXghPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0SGV4VmFsdWVJbmNsdWRpbmdVbnVzZWRCaXRzKGIuaGV4KX1lbHNle2lmKHR5cGVvZiBiLmJpbiE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUJpbmFyeVN0cmluZyhiLmJpbil9ZWxzZXtpZih0eXBlb2YgYi5hcnJheSE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUJvb2xlYW5BcnJheShiLmFycmF5KX19fX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSQml0U3RyaW5nLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVST2N0ZXRTdHJpbmc9ZnVuY3Rpb24oYil7aWYoYiE9PXVuZGVmaW5lZCYmdHlwZW9mIGIub2JqIT09XCJ1bmRlZmluZWRcIil7dmFyIGE9S0pVUi5hc24xLkFTTjFVdGlsLm5ld09iamVjdChiLm9iaik7Yi5oZXg9YS5nZXRFbmNvZGVkSGV4KCl9S0pVUi5hc24xLkRFUk9jdGV0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGIpO3RoaXMuaFQ9XCIwNFwifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVST2N0ZXRTdHJpbmcsS0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nKTtLSlVSLmFzbjEuREVSTnVsbD1mdW5jdGlvbigpe0tKVVIuYXNuMS5ERVJOdWxsLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDVcIjt0aGlzLmhUTFY9XCIwNTAwXCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJOdWxsLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVST2JqZWN0SWRlbnRpZmllcj1mdW5jdGlvbihjKXt2YXIgYj1mdW5jdGlvbihkKXt2YXIgZT1kLnRvU3RyaW5nKDE2KTtpZihlLmxlbmd0aD09MSl7ZT1cIjBcIitlfXJldHVybiBlfTt2YXIgYT1mdW5jdGlvbihrKXt2YXIgaj1cIlwiO3ZhciBlPW5ldyBCaWdJbnRlZ2VyKGssMTApO3ZhciBkPWUudG9TdHJpbmcoMik7dmFyIGY9Ny1kLmxlbmd0aCU3O2lmKGY9PTcpe2Y9MH12YXIgbT1cIlwiO2Zvcih2YXIgZz0wO2c8ZjtnKyspe20rPVwiMFwifWQ9bStkO2Zvcih2YXIgZz0wO2c8ZC5sZW5ndGgtMTtnKz03KXt2YXIgbD1kLnN1YnN0cihnLDcpO2lmKGchPWQubGVuZ3RoLTcpe2w9XCIxXCIrbH1qKz1iKHBhcnNlSW50KGwsMikpfXJldHVybiBqfTtLSlVSLmFzbjEuREVST2JqZWN0SWRlbnRpZmllci5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjA2XCI7dGhpcy5zZXRWYWx1ZUhleD1mdW5jdGlvbihkKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLnM9bnVsbDt0aGlzLmhWPWR9O3RoaXMuc2V0VmFsdWVPaWRTdHJpbmc9ZnVuY3Rpb24oZil7aWYoIWYubWF0Y2goL15bMC05Ll0rJC8pKXt0aHJvd1wibWFsZm9ybWVkIG9pZCBzdHJpbmc6IFwiK2Z9dmFyIGc9XCJcIjt2YXIgZD1mLnNwbGl0KFwiLlwiKTt2YXIgaj1wYXJzZUludChkWzBdKSo0MCtwYXJzZUludChkWzFdKTtnKz1iKGopO2Quc3BsaWNlKDAsMik7Zm9yKHZhciBlPTA7ZTxkLmxlbmd0aDtlKyspe2crPWEoZFtlXSl9dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5zPW51bGw7dGhpcy5oVj1nfTt0aGlzLnNldFZhbHVlTmFtZT1mdW5jdGlvbihlKXt2YXIgZD1LSlVSLmFzbjEueDUwOS5PSUQubmFtZTJvaWQoZSk7aWYoZCE9PVwiXCIpe3RoaXMuc2V0VmFsdWVPaWRTdHJpbmcoZCl9ZWxzZXt0aHJvd1wiREVST2JqZWN0SWRlbnRpZmllciBvaWROYW1lIHVuZGVmaW5lZDogXCIrZX19O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZihjIT09dW5kZWZpbmVkKXtpZih0eXBlb2YgYz09PVwic3RyaW5nXCIpe2lmKGMubWF0Y2goL15bMC0yXS5bMC05Ll0rJC8pKXt0aGlzLnNldFZhbHVlT2lkU3RyaW5nKGMpfWVsc2V7dGhpcy5zZXRWYWx1ZU5hbWUoYyl9fWVsc2V7aWYoYy5vaWQhPT11bmRlZmluZWQpe3RoaXMuc2V0VmFsdWVPaWRTdHJpbmcoYy5vaWQpfWVsc2V7aWYoYy5oZXghPT11bmRlZmluZWQpe3RoaXMuc2V0VmFsdWVIZXgoYy5oZXgpfWVsc2V7aWYoYy5uYW1lIT09dW5kZWZpbmVkKXt0aGlzLnNldFZhbHVlTmFtZShjLm5hbWUpfX19fX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJPYmplY3RJZGVudGlmaWVyLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSRW51bWVyYXRlZD1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSRW51bWVyYXRlZC5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjBhXCI7dGhpcy5zZXRCeUJpZ0ludGVnZXI9ZnVuY3Rpb24oYil7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5oVj1LSlVSLmFzbjEuQVNOMVV0aWwuYmlnSW50VG9NaW5Ud29zQ29tcGxlbWVudHNIZXgoYil9O3RoaXMuc2V0QnlJbnRlZ2VyPWZ1bmN0aW9uKGMpe3ZhciBiPW5ldyBCaWdJbnRlZ2VyKFN0cmluZyhjKSwxMCk7dGhpcy5zZXRCeUJpZ0ludGVnZXIoYil9O3RoaXMuc2V0VmFsdWVIZXg9ZnVuY3Rpb24oYil7dGhpcy5oVj1ifTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn07aWYodHlwZW9mIGEhPVwidW5kZWZpbmVkXCIpe2lmKHR5cGVvZiBhW1wiaW50XCJdIT1cInVuZGVmaW5lZFwiKXt0aGlzLnNldEJ5SW50ZWdlcihhW1wiaW50XCJdKX1lbHNle2lmKHR5cGVvZiBhPT1cIm51bWJlclwiKXt0aGlzLnNldEJ5SW50ZWdlcihhKX1lbHNle2lmKHR5cGVvZiBhLmhleCE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRWYWx1ZUhleChhLmhleCl9fX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSRW51bWVyYXRlZCxLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUlVURjhTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlVURjhTdHJpbmcuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjBjXCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJVVEY4U3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUk51bWVyaWNTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUk51bWVyaWNTdHJpbmcuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjEyXCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJOdW1lcmljU3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUlByaW50YWJsZVN0cmluZz1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSUHJpbnRhYmxlU3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIxM1wifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSUHJpbnRhYmxlU3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUlRlbGV0ZXhTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlRlbGV0ZXhTdHJpbmcuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjE0XCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJUZWxldGV4U3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUklBNVN0cmluZz1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSSUE1U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIxNlwifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSSUE1U3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUlVUQ1RpbWU9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlVUQ1RpbWUuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjE3XCI7dGhpcy5zZXRCeURhdGU9ZnVuY3Rpb24oYil7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5kYXRlPWI7dGhpcy5zPXRoaXMuZm9ybWF0RGF0ZSh0aGlzLmRhdGUsXCJ1dGNcIik7dGhpcy5oVj1zdG9oZXgodGhpcy5zKX07dGhpcy5nZXRGcmVzaFZhbHVlSGV4PWZ1bmN0aW9uKCl7aWYodHlwZW9mIHRoaXMuZGF0ZT09XCJ1bmRlZmluZWRcIiYmdHlwZW9mIHRoaXMucz09XCJ1bmRlZmluZWRcIil7dGhpcy5kYXRlPW5ldyBEYXRlKCk7dGhpcy5zPXRoaXMuZm9ybWF0RGF0ZSh0aGlzLmRhdGUsXCJ1dGNcIik7dGhpcy5oVj1zdG9oZXgodGhpcy5zKX1yZXR1cm4gdGhpcy5oVn07aWYoYSE9PXVuZGVmaW5lZCl7aWYoYS5zdHIhPT11bmRlZmluZWQpe3RoaXMuc2V0U3RyaW5nKGEuc3RyKX1lbHNle2lmKHR5cGVvZiBhPT1cInN0cmluZ1wiJiZhLm1hdGNoKC9eWzAtOV17MTJ9WiQvKSl7dGhpcy5zZXRTdHJpbmcoYSl9ZWxzZXtpZihhLmhleCE9PXVuZGVmaW5lZCl7dGhpcy5zZXRTdHJpbmdIZXgoYS5oZXgpfWVsc2V7aWYoYS5kYXRlIT09dW5kZWZpbmVkKXt0aGlzLnNldEJ5RGF0ZShhLmRhdGUpfX19fX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJVVENUaW1lLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFRpbWUpO0tKVVIuYXNuMS5ERVJHZW5lcmFsaXplZFRpbWU9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUkdlbmVyYWxpemVkVGltZS5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyxhKTt0aGlzLmhUPVwiMThcIjt0aGlzLndpdGhNaWxsaXM9ZmFsc2U7dGhpcy5zZXRCeURhdGU9ZnVuY3Rpb24oYil7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5kYXRlPWI7dGhpcy5zPXRoaXMuZm9ybWF0RGF0ZSh0aGlzLmRhdGUsXCJnZW5cIix0aGlzLndpdGhNaWxsaXMpO3RoaXMuaFY9c3RvaGV4KHRoaXMucyl9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe2lmKHRoaXMuZGF0ZT09PXVuZGVmaW5lZCYmdGhpcy5zPT09dW5kZWZpbmVkKXt0aGlzLmRhdGU9bmV3IERhdGUoKTt0aGlzLnM9dGhpcy5mb3JtYXREYXRlKHRoaXMuZGF0ZSxcImdlblwiLHRoaXMud2l0aE1pbGxpcyk7dGhpcy5oVj1zdG9oZXgodGhpcy5zKX1yZXR1cm4gdGhpcy5oVn07aWYoYSE9PXVuZGVmaW5lZCl7aWYoYS5zdHIhPT11bmRlZmluZWQpe3RoaXMuc2V0U3RyaW5nKGEuc3RyKX1lbHNle2lmKHR5cGVvZiBhPT1cInN0cmluZ1wiJiZhLm1hdGNoKC9eWzAtOV17MTR9WiQvKSl7dGhpcy5zZXRTdHJpbmcoYSl9ZWxzZXtpZihhLmhleCE9PXVuZGVmaW5lZCl7dGhpcy5zZXRTdHJpbmdIZXgoYS5oZXgpfWVsc2V7aWYoYS5kYXRlIT09dW5kZWZpbmVkKXt0aGlzLnNldEJ5RGF0ZShhLmRhdGUpfX19fWlmKGEubWlsbGlzPT09dHJ1ZSl7dGhpcy53aXRoTWlsbGlzPXRydWV9fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkdlbmVyYWxpemVkVGltZSxLSlVSLmFzbjEuREVSQWJzdHJhY3RUaW1lKTtLSlVSLmFzbjEuREVSU2VxdWVuY2U9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlNlcXVlbmNlLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIzMFwiO3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3ZhciBjPVwiXCI7Zm9yKHZhciBiPTA7Yjx0aGlzLmFzbjFBcnJheS5sZW5ndGg7YisrKXt2YXIgZD10aGlzLmFzbjFBcnJheVtiXTtjKz1kLmdldEVuY29kZWRIZXgoKX10aGlzLmhWPWM7cmV0dXJuIHRoaXMuaFZ9fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSU2VxdWVuY2UsS0pVUi5hc24xLkRFUkFic3RyYWN0U3RydWN0dXJlZCk7S0pVUi5hc24xLkRFUlNldD1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSU2V0LnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIzMVwiO3RoaXMuc29ydEZsYWc9dHJ1ZTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXt2YXIgYj1uZXcgQXJyYXkoKTtmb3IodmFyIGM9MDtjPHRoaXMuYXNuMUFycmF5Lmxlbmd0aDtjKyspe3ZhciBkPXRoaXMuYXNuMUFycmF5W2NdO2IucHVzaChkLmdldEVuY29kZWRIZXgoKSl9aWYodGhpcy5zb3J0RmxhZz09dHJ1ZSl7Yi5zb3J0KCl9dGhpcy5oVj1iLmpvaW4oXCJcIik7cmV0dXJuIHRoaXMuaFZ9O2lmKHR5cGVvZiBhIT1cInVuZGVmaW5lZFwiKXtpZih0eXBlb2YgYS5zb3J0ZmxhZyE9XCJ1bmRlZmluZWRcIiYmYS5zb3J0ZmxhZz09ZmFsc2Upe3RoaXMuc29ydEZsYWc9ZmFsc2V9fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUlNldCxLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJ1Y3R1cmVkKTtLSlVSLmFzbjEuREVSVGFnZ2VkT2JqZWN0PWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJUYWdnZWRPYmplY3Quc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3RoaXMuaFQ9XCJhMFwiO3RoaXMuaFY9XCJcIjt0aGlzLmlzRXhwbGljaXQ9dHJ1ZTt0aGlzLmFzbjFPYmplY3Q9bnVsbDt0aGlzLnNldEFTTjFPYmplY3Q9ZnVuY3Rpb24oYixjLGQpe3RoaXMuaFQ9Yzt0aGlzLmlzRXhwbGljaXQ9Yjt0aGlzLmFzbjFPYmplY3Q9ZDtpZih0aGlzLmlzRXhwbGljaXQpe3RoaXMuaFY9dGhpcy5hc24xT2JqZWN0LmdldEVuY29kZWRIZXgoKTt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZX1lbHNle3RoaXMuaFY9bnVsbDt0aGlzLmhUTFY9ZC5nZXRFbmNvZGVkSGV4KCk7dGhpcy5oVExWPXRoaXMuaFRMVi5yZXBsYWNlKC9eLi4vLGMpO3RoaXMuaXNNb2RpZmllZD1mYWxzZX19O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYSE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGEudGFnIT1cInVuZGVmaW5lZFwiKXt0aGlzLmhUPWEudGFnfWlmKHR5cGVvZiBhLmV4cGxpY2l0IT1cInVuZGVmaW5lZFwiKXt0aGlzLmlzRXhwbGljaXQ9YS5leHBsaWNpdH1pZih0eXBlb2YgYS5vYmohPVwidW5kZWZpbmVkXCIpe3RoaXMuYXNuMU9iamVjdD1hLm9iajt0aGlzLnNldEFTTjFPYmplY3QodGhpcy5pc0V4cGxpY2l0LHRoaXMuaFQsdGhpcy5hc24xT2JqZWN0KX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSVGFnZ2VkT2JqZWN0LEtKVVIuYXNuMS5BU04xT2JqZWN0KTtcbnZhciBBU04xSEVYPW5ldyBmdW5jdGlvbigpe307QVNOMUhFWC5nZXRMYmxlbj1mdW5jdGlvbihjLGEpe2lmKGMuc3Vic3RyKGErMiwxKSE9XCI4XCIpe3JldHVybiAxfXZhciBiPXBhcnNlSW50KGMuc3Vic3RyKGErMywxKSk7aWYoYj09MCl7cmV0dXJuIC0xfWlmKDA8YiYmYjwxMCl7cmV0dXJuIGIrMX1yZXR1cm4gLTJ9O0FTTjFIRVguZ2V0TD1mdW5jdGlvbihjLGIpe3ZhciBhPUFTTjFIRVguZ2V0TGJsZW4oYyxiKTtpZihhPDEpe3JldHVyblwiXCJ9cmV0dXJuIGMuc3Vic3RyKGIrMixhKjIpfTtBU04xSEVYLmdldFZibGVuPWZ1bmN0aW9uKGQsYSl7dmFyIGMsYjtjPUFTTjFIRVguZ2V0TChkLGEpO2lmKGM9PVwiXCIpe3JldHVybiAtMX1pZihjLnN1YnN0cigwLDEpPT09XCI4XCIpe2I9bmV3IEJpZ0ludGVnZXIoYy5zdWJzdHIoMiksMTYpfWVsc2V7Yj1uZXcgQmlnSW50ZWdlcihjLDE2KX1yZXR1cm4gYi5pbnRWYWx1ZSgpfTtBU04xSEVYLmdldFZpZHg9ZnVuY3Rpb24oYyxiKXt2YXIgYT1BU04xSEVYLmdldExibGVuKGMsYik7aWYoYTwwKXtyZXR1cm4gYX1yZXR1cm4gYisoYSsxKSoyfTtBU04xSEVYLmdldFY9ZnVuY3Rpb24oZCxhKXt2YXIgYz1BU04xSEVYLmdldFZpZHgoZCxhKTt2YXIgYj1BU04xSEVYLmdldFZibGVuKGQsYSk7cmV0dXJuIGQuc3Vic3RyKGMsYioyKX07QVNOMUhFWC5nZXRUTFY9ZnVuY3Rpb24oYixhKXtyZXR1cm4gYi5zdWJzdHIoYSwyKStBU04xSEVYLmdldEwoYixhKStBU04xSEVYLmdldFYoYixhKX07QVNOMUhFWC5nZXROZXh0U2libGluZ0lkeD1mdW5jdGlvbihkLGEpe3ZhciBjPUFTTjFIRVguZ2V0VmlkeChkLGEpO3ZhciBiPUFTTjFIRVguZ2V0VmJsZW4oZCxhKTtyZXR1cm4gYytiKjJ9O0FTTjFIRVguZ2V0Q2hpbGRJZHg9ZnVuY3Rpb24oZSxmKXt2YXIgaj1BU04xSEVYO3ZhciBnPW5ldyBBcnJheSgpO3ZhciBpPWouZ2V0VmlkeChlLGYpO2lmKGUuc3Vic3RyKGYsMik9PVwiMDNcIil7Zy5wdXNoKGkrMil9ZWxzZXtnLnB1c2goaSl9dmFyIGw9ai5nZXRWYmxlbihlLGYpO3ZhciBjPWk7dmFyIGQ9MDt3aGlsZSgxKXt2YXIgYj1qLmdldE5leHRTaWJsaW5nSWR4KGUsYyk7aWYoYj09bnVsbHx8KGItaT49KGwqMikpKXticmVha31pZihkPj0yMDApe2JyZWFrfWcucHVzaChiKTtjPWI7ZCsrfXJldHVybiBnfTtBU04xSEVYLmdldE50aENoaWxkSWR4PWZ1bmN0aW9uKGQsYixlKXt2YXIgYz1BU04xSEVYLmdldENoaWxkSWR4KGQsYik7cmV0dXJuIGNbZV19O0FTTjFIRVguZ2V0SWR4YnlMaXN0PWZ1bmN0aW9uKGUsZCxjLGkpe3ZhciBnPUFTTjFIRVg7dmFyIGYsYjtpZihjLmxlbmd0aD09MCl7aWYoaSE9PXVuZGVmaW5lZCl7aWYoZS5zdWJzdHIoZCwyKSE9PWkpe3Rocm93XCJjaGVja2luZyB0YWcgZG9lc24ndCBtYXRjaDogXCIrZS5zdWJzdHIoZCwyKStcIiE9XCIraX19cmV0dXJuIGR9Zj1jLnNoaWZ0KCk7Yj1nLmdldENoaWxkSWR4KGUsZCk7cmV0dXJuIGcuZ2V0SWR4YnlMaXN0KGUsYltmXSxjLGkpfTtBU04xSEVYLmdldFRMVmJ5TGlzdD1mdW5jdGlvbihkLGMsYixmKXt2YXIgZT1BU04xSEVYO3ZhciBhPWUuZ2V0SWR4YnlMaXN0KGQsYyxiKTtpZihhPT09dW5kZWZpbmVkKXt0aHJvd1wiY2FuJ3QgZmluZCBudGhMaXN0IG9iamVjdFwifWlmKGYhPT11bmRlZmluZWQpe2lmKGQuc3Vic3RyKGEsMikhPWYpe3Rocm93XCJjaGVja2luZyB0YWcgZG9lc24ndCBtYXRjaDogXCIrZC5zdWJzdHIoYSwyKStcIiE9XCIrZn19cmV0dXJuIGUuZ2V0VExWKGQsYSl9O0FTTjFIRVguZ2V0VmJ5TGlzdD1mdW5jdGlvbihlLGMsYixnLGkpe3ZhciBmPUFTTjFIRVg7dmFyIGEsZDthPWYuZ2V0SWR4YnlMaXN0KGUsYyxiLGcpO2lmKGE9PT11bmRlZmluZWQpe3Rocm93XCJjYW4ndCBmaW5kIG50aExpc3Qgb2JqZWN0XCJ9ZD1mLmdldFYoZSxhKTtpZihpPT09dHJ1ZSl7ZD1kLnN1YnN0cigyKX1yZXR1cm4gZH07QVNOMUhFWC5oZXh0b29pZHN0cj1mdW5jdGlvbihlKXt2YXIgaD1mdW5jdGlvbihiLGEpe2lmKGIubGVuZ3RoPj1hKXtyZXR1cm4gYn1yZXR1cm4gbmV3IEFycmF5KGEtYi5sZW5ndGgrMSkuam9pbihcIjBcIikrYn07dmFyIGw9W107dmFyIG89ZS5zdWJzdHIoMCwyKTt2YXIgZj1wYXJzZUludChvLDE2KTtsWzBdPW5ldyBTdHJpbmcoTWF0aC5mbG9vcihmLzQwKSk7bFsxXT1uZXcgU3RyaW5nKGYlNDApO3ZhciBtPWUuc3Vic3RyKDIpO3ZhciBrPVtdO2Zvcih2YXIgZz0wO2c8bS5sZW5ndGgvMjtnKyspe2sucHVzaChwYXJzZUludChtLnN1YnN0cihnKjIsMiksMTYpKX12YXIgaj1bXTt2YXIgZD1cIlwiO2Zvcih2YXIgZz0wO2c8ay5sZW5ndGg7ZysrKXtpZihrW2ddJjEyOCl7ZD1kK2goKGtbZ10mMTI3KS50b1N0cmluZygyKSw3KX1lbHNle2Q9ZCtoKChrW2ddJjEyNykudG9TdHJpbmcoMiksNyk7ai5wdXNoKG5ldyBTdHJpbmcocGFyc2VJbnQoZCwyKSkpO2Q9XCJcIn19dmFyIG49bC5qb2luKFwiLlwiKTtpZihqLmxlbmd0aD4wKXtuPW4rXCIuXCIrai5qb2luKFwiLlwiKX1yZXR1cm4gbn07QVNOMUhFWC5kdW1wPWZ1bmN0aW9uKHQsYyxsLGcpe3ZhciBwPUFTTjFIRVg7dmFyIGo9cC5nZXRWO3ZhciB5PXAuZHVtcDt2YXIgdz1wLmdldENoaWxkSWR4O3ZhciBlPXQ7aWYodCBpbnN0YW5jZW9mIEtKVVIuYXNuMS5BU04xT2JqZWN0KXtlPXQuZ2V0RW5jb2RlZEhleCgpfXZhciBxPWZ1bmN0aW9uKEEsaSl7aWYoQS5sZW5ndGg8PWkqMil7cmV0dXJuIEF9ZWxzZXt2YXIgdj1BLnN1YnN0cigwLGkpK1wiLi4odG90YWwgXCIrQS5sZW5ndGgvMitcImJ5dGVzKS4uXCIrQS5zdWJzdHIoQS5sZW5ndGgtaSxpKTtyZXR1cm4gdn19O2lmKGM9PT11bmRlZmluZWQpe2M9e29tbWl0X2xvbmdfb2N0ZXQ6MzJ9fWlmKGw9PT11bmRlZmluZWQpe2w9MH1pZihnPT09dW5kZWZpbmVkKXtnPVwiXCJ9dmFyIHg9Yy5vbW1pdF9sb25nX29jdGV0O2lmKGUuc3Vic3RyKGwsMik9PVwiMDFcIil7dmFyIGg9aihlLGwpO2lmKGg9PVwiMDBcIil7cmV0dXJuIGcrXCJCT09MRUFOIEZBTFNFXFxuXCJ9ZWxzZXtyZXR1cm4gZytcIkJPT0xFQU4gVFJVRVxcblwifX1pZihlLnN1YnN0cihsLDIpPT1cIjAyXCIpe3ZhciBoPWooZSxsKTtyZXR1cm4gZytcIklOVEVHRVIgXCIrcShoLHgpK1wiXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIwM1wiKXt2YXIgaD1qKGUsbCk7cmV0dXJuIGcrXCJCSVRTVFJJTkcgXCIrcShoLHgpK1wiXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIwNFwiKXt2YXIgaD1qKGUsbCk7aWYocC5pc0FTTjFIRVgoaCkpe3ZhciBrPWcrXCJPQ1RFVFNUUklORywgZW5jYXBzdWxhdGVzXFxuXCI7az1rK3koaCxjLDAsZytcIiAgXCIpO3JldHVybiBrfWVsc2V7cmV0dXJuIGcrXCJPQ1RFVFNUUklORyBcIitxKGgseCkrXCJcXG5cIn19aWYoZS5zdWJzdHIobCwyKT09XCIwNVwiKXtyZXR1cm4gZytcIk5VTExcXG5cIn1pZihlLnN1YnN0cihsLDIpPT1cIjA2XCIpe3ZhciBtPWooZSxsKTt2YXIgYT1LSlVSLmFzbjEuQVNOMVV0aWwub2lkSGV4VG9JbnQobSk7dmFyIG89S0pVUi5hc24xLng1MDkuT0lELm9pZDJuYW1lKGEpO3ZhciBiPWEucmVwbGFjZSgvXFwuL2csXCIgXCIpO2lmKG8hPVwiXCIpe3JldHVybiBnK1wiT2JqZWN0SWRlbnRpZmllciBcIitvK1wiIChcIitiK1wiKVxcblwifWVsc2V7cmV0dXJuIGcrXCJPYmplY3RJZGVudGlmaWVyIChcIitiK1wiKVxcblwifX1pZihlLnN1YnN0cihsLDIpPT1cIjBjXCIpe3JldHVybiBnK1wiVVRGOFN0cmluZyAnXCIraGV4dG91dGY4KGooZSxsKSkrXCInXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIxM1wiKXtyZXR1cm4gZytcIlByaW50YWJsZVN0cmluZyAnXCIraGV4dG91dGY4KGooZSxsKSkrXCInXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIxNFwiKXtyZXR1cm4gZytcIlRlbGV0ZXhTdHJpbmcgJ1wiK2hleHRvdXRmOChqKGUsbCkpK1wiJ1xcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMTZcIil7cmV0dXJuIGcrXCJJQTVTdHJpbmcgJ1wiK2hleHRvdXRmOChqKGUsbCkpK1wiJ1xcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMTdcIil7cmV0dXJuIGcrXCJVVENUaW1lIFwiK2hleHRvdXRmOChqKGUsbCkpK1wiXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIxOFwiKXtyZXR1cm4gZytcIkdlbmVyYWxpemVkVGltZSBcIitoZXh0b3V0ZjgoaihlLGwpKStcIlxcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMzBcIil7aWYoZS5zdWJzdHIobCw0KT09XCIzMDAwXCIpe3JldHVybiBnK1wiU0VRVUVOQ0Uge31cXG5cIn12YXIgaz1nK1wiU0VRVUVOQ0VcXG5cIjt2YXIgZD13KGUsbCk7dmFyIGY9YztpZigoZC5sZW5ndGg9PTJ8fGQubGVuZ3RoPT0zKSYmZS5zdWJzdHIoZFswXSwyKT09XCIwNlwiJiZlLnN1YnN0cihkW2QubGVuZ3RoLTFdLDIpPT1cIjA0XCIpe3ZhciBvPXAub2lkbmFtZShqKGUsZFswXSkpO3ZhciByPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoYykpO3IueDUwOUV4dE5hbWU9bztmPXJ9Zm9yKHZhciB1PTA7dTxkLmxlbmd0aDt1Kyspe2s9ayt5KGUsZixkW3VdLGcrXCIgIFwiKX1yZXR1cm4ga31pZihlLnN1YnN0cihsLDIpPT1cIjMxXCIpe3ZhciBrPWcrXCJTRVRcXG5cIjt2YXIgZD13KGUsbCk7Zm9yKHZhciB1PTA7dTxkLmxlbmd0aDt1Kyspe2s9ayt5KGUsYyxkW3VdLGcrXCIgIFwiKX1yZXR1cm4ga312YXIgej1wYXJzZUludChlLnN1YnN0cihsLDIpLDE2KTtpZigoeiYxMjgpIT0wKXt2YXIgbj16JjMxO2lmKCh6JjMyKSE9MCl7dmFyIGs9ZytcIltcIituK1wiXVxcblwiO3ZhciBkPXcoZSxsKTtmb3IodmFyIHU9MDt1PGQubGVuZ3RoO3UrKyl7az1rK3koZSxjLGRbdV0sZytcIiAgXCIpfXJldHVybiBrfWVsc2V7dmFyIGg9aihlLGwpO2lmKGguc3Vic3RyKDAsOCk9PVwiNjg3NDc0NzBcIil7aD1oZXh0b3V0ZjgoaCl9aWYoYy54NTA5RXh0TmFtZT09PVwic3ViamVjdEFsdE5hbWVcIiYmbj09Mil7aD1oZXh0b3V0ZjgoaCl9dmFyIGs9ZytcIltcIituK1wiXSBcIitoK1wiXFxuXCI7cmV0dXJuIGt9fXJldHVybiBnK1wiVU5LTk9XTihcIitlLnN1YnN0cihsLDIpK1wiKSBcIitqKGUsbCkrXCJcXG5cIn07QVNOMUhFWC5pc0FTTjFIRVg9ZnVuY3Rpb24oZSl7dmFyIGQ9QVNOMUhFWDtpZihlLmxlbmd0aCUyPT0xKXtyZXR1cm4gZmFsc2V9dmFyIGM9ZC5nZXRWYmxlbihlLDApO3ZhciBiPWUuc3Vic3RyKDAsMik7dmFyIGY9ZC5nZXRMKGUsMCk7dmFyIGE9ZS5sZW5ndGgtYi5sZW5ndGgtZi5sZW5ndGg7aWYoYT09YyoyKXtyZXR1cm4gdHJ1ZX1yZXR1cm4gZmFsc2V9O0FTTjFIRVgub2lkbmFtZT1mdW5jdGlvbihhKXt2YXIgYz1LSlVSLmFzbjE7aWYoS0pVUi5sYW5nLlN0cmluZy5pc0hleChhKSl7YT1jLkFTTjFVdGlsLm9pZEhleFRvSW50KGEpfXZhciBiPWMueDUwOS5PSUQub2lkMm5hbWUoYSk7aWYoYj09PVwiXCIpe2I9YX1yZXR1cm4gYn07XG52YXIgS0pVUjtpZih0eXBlb2YgS0pVUj09XCJ1bmRlZmluZWRcInx8IUtKVVIpe0tKVVI9e319aWYodHlwZW9mIEtKVVIubGFuZz09XCJ1bmRlZmluZWRcInx8IUtKVVIubGFuZyl7S0pVUi5sYW5nPXt9fUtKVVIubGFuZy5TdHJpbmc9ZnVuY3Rpb24oKXt9O2Z1bmN0aW9uIEJhc2U2NHgoKXt9ZnVuY3Rpb24gc3RvQkEoZCl7dmFyIGI9bmV3IEFycmF5KCk7Zm9yKHZhciBjPTA7YzxkLmxlbmd0aDtjKyspe2JbY109ZC5jaGFyQ29kZUF0KGMpfXJldHVybiBifWZ1bmN0aW9uIEJBdG9zKGIpe3ZhciBkPVwiXCI7Zm9yKHZhciBjPTA7YzxiLmxlbmd0aDtjKyspe2Q9ZCtTdHJpbmcuZnJvbUNoYXJDb2RlKGJbY10pfXJldHVybiBkfWZ1bmN0aW9uIEJBdG9oZXgoYil7dmFyIGU9XCJcIjtmb3IodmFyIGQ9MDtkPGIubGVuZ3RoO2QrKyl7dmFyIGM9YltkXS50b1N0cmluZygxNik7aWYoYy5sZW5ndGg9PTEpe2M9XCIwXCIrY31lPWUrY31yZXR1cm4gZX1mdW5jdGlvbiBzdG9oZXgoYSl7cmV0dXJuIEJBdG9oZXgoc3RvQkEoYSkpfWZ1bmN0aW9uIHN0b2I2NChhKXtyZXR1cm4gaGV4MmI2NChzdG9oZXgoYSkpfWZ1bmN0aW9uIHN0b2I2NHUoYSl7cmV0dXJuIGI2NHRvYjY0dShoZXgyYjY0KHN0b2hleChhKSkpfWZ1bmN0aW9uIGI2NHV0b3MoYSl7cmV0dXJuIEJBdG9zKGI2NHRvQkEoYjY0dXRvYjY0KGEpKSl9ZnVuY3Rpb24gYjY0dG9iNjR1KGEpe2E9YS5yZXBsYWNlKC9cXD0vZyxcIlwiKTthPWEucmVwbGFjZSgvXFwrL2csXCItXCIpO2E9YS5yZXBsYWNlKC9cXC8vZyxcIl9cIik7cmV0dXJuIGF9ZnVuY3Rpb24gYjY0dXRvYjY0KGEpe2lmKGEubGVuZ3RoJTQ9PTIpe2E9YStcIj09XCJ9ZWxzZXtpZihhLmxlbmd0aCU0PT0zKXthPWErXCI9XCJ9fWE9YS5yZXBsYWNlKC8tL2csXCIrXCIpO2E9YS5yZXBsYWNlKC9fL2csXCIvXCIpO3JldHVybiBhfWZ1bmN0aW9uIGhleHRvYjY0dShhKXtpZihhLmxlbmd0aCUyPT0xKXthPVwiMFwiK2F9cmV0dXJuIGI2NHRvYjY0dShoZXgyYjY0KGEpKX1mdW5jdGlvbiBiNjR1dG9oZXgoYSl7cmV0dXJuIGI2NHRvaGV4KGI2NHV0b2I2NChhKSl9dmFyIHV0Zjh0b2I2NHUsYjY0dXRvdXRmODtpZih0eXBlb2YgQnVmZmVyPT09XCJmdW5jdGlvblwiKXt1dGY4dG9iNjR1PWZ1bmN0aW9uKGEpe3JldHVybiBiNjR0b2I2NHUobmV3IEJ1ZmZlcihhLFwidXRmOFwiKS50b1N0cmluZyhcImJhc2U2NFwiKSl9O2I2NHV0b3V0Zjg9ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBCdWZmZXIoYjY0dXRvYjY0KGEpLFwiYmFzZTY0XCIpLnRvU3RyaW5nKFwidXRmOFwiKX19ZWxzZXt1dGY4dG9iNjR1PWZ1bmN0aW9uKGEpe3JldHVybiBoZXh0b2I2NHUodXJpY21wdG9oZXgoZW5jb2RlVVJJQ29tcG9uZW50QWxsKGEpKSl9O2I2NHV0b3V0Zjg9ZnVuY3Rpb24oYSl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChoZXh0b3VyaWNtcChiNjR1dG9oZXgoYSkpKX19ZnVuY3Rpb24gdXRmOHRvYjY0KGEpe3JldHVybiBoZXgyYjY0KHVyaWNtcHRvaGV4KGVuY29kZVVSSUNvbXBvbmVudEFsbChhKSkpfWZ1bmN0aW9uIGI2NHRvdXRmOChhKXtyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGhleHRvdXJpY21wKGI2NHRvaGV4KGEpKSl9ZnVuY3Rpb24gdXRmOHRvaGV4KGEpe3JldHVybiB1cmljbXB0b2hleChlbmNvZGVVUklDb21wb25lbnRBbGwoYSkpfWZ1bmN0aW9uIGhleHRvdXRmOChhKXtyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGhleHRvdXJpY21wKGEpKX1mdW5jdGlvbiBoZXh0b3JzdHIoYyl7dmFyIGI9XCJcIjtmb3IodmFyIGE9MDthPGMubGVuZ3RoLTE7YSs9Mil7Yis9U3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChjLnN1YnN0cihhLDIpLDE2KSl9cmV0dXJuIGJ9ZnVuY3Rpb24gcnN0cnRvaGV4KGMpe3ZhciBhPVwiXCI7Zm9yKHZhciBiPTA7YjxjLmxlbmd0aDtiKyspe2ErPShcIjBcIitjLmNoYXJDb2RlQXQoYikudG9TdHJpbmcoMTYpKS5zbGljZSgtMil9cmV0dXJuIGF9ZnVuY3Rpb24gaGV4dG9iNjQoYSl7cmV0dXJuIGhleDJiNjQoYSl9ZnVuY3Rpb24gaGV4dG9iNjRubChiKXt2YXIgYT1oZXh0b2I2NChiKTt2YXIgYz1hLnJlcGxhY2UoLyguezY0fSkvZyxcIiQxXFxyXFxuXCIpO2M9Yy5yZXBsYWNlKC9cXHJcXG4kLyxcIlwiKTtyZXR1cm4gY31mdW5jdGlvbiBiNjRubHRvaGV4KGIpe3ZhciBhPWIucmVwbGFjZSgvW14wLTlBLVphLXpcXC8rPV0qL2csXCJcIik7dmFyIGM9YjY0dG9oZXgoYSk7cmV0dXJuIGN9ZnVuY3Rpb24gaGV4dG9wZW0oYSxiKXt2YXIgYz1oZXh0b2I2NG5sKGEpO3JldHVyblwiLS0tLS1CRUdJTiBcIitiK1wiLS0tLS1cXHJcXG5cIitjK1wiXFxyXFxuLS0tLS1FTkQgXCIrYitcIi0tLS0tXFxyXFxuXCJ9ZnVuY3Rpb24gcGVtdG9oZXgoYSxiKXtpZihhLmluZGV4T2YoXCItLS0tLUJFR0lOIFwiKT09LTEpe3Rocm93XCJjYW4ndCBmaW5kIFBFTSBoZWFkZXI6IFwiK2J9aWYoYiE9PXVuZGVmaW5lZCl7YT1hLnJlcGxhY2UoXCItLS0tLUJFR0lOIFwiK2IrXCItLS0tLVwiLFwiXCIpO2E9YS5yZXBsYWNlKFwiLS0tLS1FTkQgXCIrYitcIi0tLS0tXCIsXCJcIil9ZWxzZXthPWEucmVwbGFjZSgvLS0tLS1CRUdJTiBbXi1dKy0tLS0tLyxcIlwiKTthPWEucmVwbGFjZSgvLS0tLS1FTkQgW14tXSstLS0tLS8sXCJcIil9cmV0dXJuIGI2NG5sdG9oZXgoYSl9ZnVuY3Rpb24gaGV4dG9BcnJheUJ1ZmZlcihkKXtpZihkLmxlbmd0aCUyIT0wKXt0aHJvd1wiaW5wdXQgaXMgbm90IGV2ZW4gbGVuZ3RoXCJ9aWYoZC5tYXRjaCgvXlswLTlBLUZhLWZdKyQvKT09bnVsbCl7dGhyb3dcImlucHV0IGlzIG5vdCBoZXhhZGVjaW1hbFwifXZhciBiPW5ldyBBcnJheUJ1ZmZlcihkLmxlbmd0aC8yKTt2YXIgYT1uZXcgRGF0YVZpZXcoYik7Zm9yKHZhciBjPTA7YzxkLmxlbmd0aC8yO2MrKyl7YS5zZXRVaW50OChjLHBhcnNlSW50KGQuc3Vic3RyKGMqMiwyKSwxNikpfXJldHVybiBifWZ1bmN0aW9uIEFycmF5QnVmZmVydG9oZXgoYil7dmFyIGQ9XCJcIjt2YXIgYT1uZXcgRGF0YVZpZXcoYik7Zm9yKHZhciBjPTA7YzxiLmJ5dGVMZW5ndGg7YysrKXtkKz0oXCIwMFwiK2EuZ2V0VWludDgoYykudG9TdHJpbmcoMTYpKS5zbGljZSgtMil9cmV0dXJuIGR9ZnVuY3Rpb24genVsdXRvbXNlYyhuKXt2YXIgbCxqLG0sZSxmLGksYixrO3ZhciBhLGgsZyxjO2M9bi5tYXRjaCgvXihcXGR7Mn18XFxkezR9KShcXGRcXGQpKFxcZFxcZCkoXFxkXFxkKShcXGRcXGQpKFxcZFxcZCkofFxcLlxcZCspWiQvKTtpZihjKXthPWNbMV07bD1wYXJzZUludChhKTtpZihhLmxlbmd0aD09PTIpe2lmKDUwPD1sJiZsPDEwMCl7bD0xOTAwK2x9ZWxzZXtpZigwPD1sJiZsPDUwKXtsPTIwMDArbH19fWo9cGFyc2VJbnQoY1syXSktMTttPXBhcnNlSW50KGNbM10pO2U9cGFyc2VJbnQoY1s0XSk7Zj1wYXJzZUludChjWzVdKTtpPXBhcnNlSW50KGNbNl0pO2I9MDtoPWNbN107aWYoaCE9PVwiXCIpe2c9KGguc3Vic3RyKDEpK1wiMDBcIikuc3Vic3RyKDAsMyk7Yj1wYXJzZUludChnKX1yZXR1cm4gRGF0ZS5VVEMobCxqLG0sZSxmLGksYil9dGhyb3dcInVuc3VwcG9ydGVkIHp1bHUgZm9ybWF0OiBcIitufWZ1bmN0aW9uIHp1bHV0b3NlYyhhKXt2YXIgYj16dWx1dG9tc2VjKGEpO3JldHVybiB+fihiLzEwMDApfWZ1bmN0aW9uIHp1bHV0b2RhdGUoYSl7cmV0dXJuIG5ldyBEYXRlKHp1bHV0b21zZWMoYSkpfWZ1bmN0aW9uIGRhdGV0b3p1bHUoZyxlLGYpe3ZhciBiO3ZhciBhPWcuZ2V0VVRDRnVsbFllYXIoKTtpZihlKXtpZihhPDE5NTB8fDIwNDk8YSl7dGhyb3dcIm5vdCBwcm9wZXIgeWVhciBmb3IgVVRDVGltZTogXCIrYX1iPShcIlwiK2EpLnNsaWNlKC0yKX1lbHNle2I9KFwiMDAwXCIrYSkuc2xpY2UoLTQpfWIrPShcIjBcIisoZy5nZXRVVENNb250aCgpKzEpKS5zbGljZSgtMik7Yis9KFwiMFwiK2cuZ2V0VVRDRGF0ZSgpKS5zbGljZSgtMik7Yis9KFwiMFwiK2cuZ2V0VVRDSG91cnMoKSkuc2xpY2UoLTIpO2IrPShcIjBcIitnLmdldFVUQ01pbnV0ZXMoKSkuc2xpY2UoLTIpO2IrPShcIjBcIitnLmdldFVUQ1NlY29uZHMoKSkuc2xpY2UoLTIpO2lmKGYpe3ZhciBjPWcuZ2V0VVRDTWlsbGlzZWNvbmRzKCk7aWYoYyE9PTApe2M9KFwiMDBcIitjKS5zbGljZSgtMyk7Yz1jLnJlcGxhY2UoLzArJC9nLFwiXCIpO2IrPVwiLlwiK2N9fWIrPVwiWlwiO3JldHVybiBifWZ1bmN0aW9uIHVyaWNtcHRvaGV4KGEpe3JldHVybiBhLnJlcGxhY2UoLyUvZyxcIlwiKX1mdW5jdGlvbiBoZXh0b3VyaWNtcChhKXtyZXR1cm4gYS5yZXBsYWNlKC8oLi4pL2csXCIlJDFcIil9ZnVuY3Rpb24gaXB2NnRvaGV4KGcpe3ZhciBiPVwibWFsZm9ybWVkIElQdjYgYWRkcmVzc1wiO2lmKCFnLm1hdGNoKC9eWzAtOUEtRmEtZjpdKyQvKSl7dGhyb3cgYn1nPWcudG9Mb3dlckNhc2UoKTt2YXIgZD1nLnNwbGl0KFwiOlwiKS5sZW5ndGgtMTtpZihkPDIpe3Rocm93IGJ9dmFyIGU9XCI6XCIucmVwZWF0KDctZCsyKTtnPWcucmVwbGFjZShcIjo6XCIsZSk7dmFyIGM9Zy5zcGxpdChcIjpcIik7aWYoYy5sZW5ndGghPTgpe3Rocm93IGJ9Zm9yKHZhciBmPTA7Zjw4O2YrKyl7Y1tmXT0oXCIwMDAwXCIrY1tmXSkuc2xpY2UoLTQpfXJldHVybiBjLmpvaW4oXCJcIil9ZnVuY3Rpb24gaGV4dG9pcHY2KGUpe2lmKCFlLm1hdGNoKC9eWzAtOUEtRmEtZl17MzJ9JC8pKXt0aHJvd1wibWFsZm9ybWVkIElQdjYgYWRkcmVzcyBvY3RldFwifWU9ZS50b0xvd2VyQ2FzZSgpO3ZhciBiPWUubWF0Y2goLy57MSw0fS9nKTtmb3IodmFyIGQ9MDtkPDg7ZCsrKXtiW2RdPWJbZF0ucmVwbGFjZSgvXjArLyxcIlwiKTtpZihiW2RdPT1cIlwiKXtiW2RdPVwiMFwifX1lPVwiOlwiK2Iuam9pbihcIjpcIikrXCI6XCI7dmFyIGM9ZS5tYXRjaCgvOigwOil7Mix9L2cpO2lmKGM9PT1udWxsKXtyZXR1cm4gZS5zbGljZSgxLC0xKX12YXIgZj1cIlwiO2Zvcih2YXIgZD0wO2Q8Yy5sZW5ndGg7ZCsrKXtpZihjW2RdLmxlbmd0aD5mLmxlbmd0aCl7Zj1jW2RdfX1lPWUucmVwbGFjZShmLFwiOjpcIik7cmV0dXJuIGUuc2xpY2UoMSwtMSl9ZnVuY3Rpb24gaGV4dG9pcChiKXt2YXIgZD1cIm1hbGZvcm1lZCBoZXggdmFsdWVcIjtpZighYi5tYXRjaCgvXihbMC05QS1GYS1mXVswLTlBLUZhLWZdKXsxLH0kLykpe3Rocm93IGR9aWYoYi5sZW5ndGg9PTgpe3ZhciBjO3RyeXtjPXBhcnNlSW50KGIuc3Vic3RyKDAsMiksMTYpK1wiLlwiK3BhcnNlSW50KGIuc3Vic3RyKDIsMiksMTYpK1wiLlwiK3BhcnNlSW50KGIuc3Vic3RyKDQsMiksMTYpK1wiLlwiK3BhcnNlSW50KGIuc3Vic3RyKDYsMiksMTYpO3JldHVybiBjfWNhdGNoKGEpe3Rocm93IGR9fWVsc2V7aWYoYi5sZW5ndGg9PTMyKXtyZXR1cm4gaGV4dG9pcHY2KGIpfWVsc2V7cmV0dXJuIGJ9fX1mdW5jdGlvbiBpcHRvaGV4KGYpe3ZhciBqPVwibWFsZm9ybWVkIElQIGFkZHJlc3NcIjtmPWYudG9Mb3dlckNhc2UoZik7aWYoZi5tYXRjaCgvXlswLTkuXSskLykpe3ZhciBiPWYuc3BsaXQoXCIuXCIpO2lmKGIubGVuZ3RoIT09NCl7dGhyb3cgan12YXIgZz1cIlwiO3RyeXtmb3IodmFyIGU9MDtlPDQ7ZSsrKXt2YXIgaD1wYXJzZUludChiW2VdKTtnKz0oXCIwXCIraC50b1N0cmluZygxNikpLnNsaWNlKC0yKX1yZXR1cm4gZ31jYXRjaChjKXt0aHJvdyBqfX1lbHNle2lmKGYubWF0Y2goL15bMC05YS1mOl0rJC8pJiZmLmluZGV4T2YoXCI6XCIpIT09LTEpe3JldHVybiBpcHY2dG9oZXgoZil9ZWxzZXt0aHJvdyBqfX19ZnVuY3Rpb24gZW5jb2RlVVJJQ29tcG9uZW50QWxsKGEpe3ZhciBkPWVuY29kZVVSSUNvbXBvbmVudChhKTt2YXIgYj1cIlwiO2Zvcih2YXIgYz0wO2M8ZC5sZW5ndGg7YysrKXtpZihkW2NdPT1cIiVcIil7Yj1iK2Quc3Vic3RyKGMsMyk7Yz1jKzJ9ZWxzZXtiPWIrXCIlXCIrc3RvaGV4KGRbY10pfX1yZXR1cm4gYn1mdW5jdGlvbiBuZXdsaW5lX3RvVW5peChhKXthPWEucmVwbGFjZSgvXFxyXFxuL21nLFwiXFxuXCIpO3JldHVybiBhfWZ1bmN0aW9uIG5ld2xpbmVfdG9Eb3MoYSl7YT1hLnJlcGxhY2UoL1xcclxcbi9tZyxcIlxcblwiKTthPWEucmVwbGFjZSgvXFxuL21nLFwiXFxyXFxuXCIpO3JldHVybiBhfUtKVVIubGFuZy5TdHJpbmcuaXNJbnRlZ2VyPWZ1bmN0aW9uKGEpe2lmKGEubWF0Y2goL15bMC05XSskLykpe3JldHVybiB0cnVlfWVsc2V7aWYoYS5tYXRjaCgvXi1bMC05XSskLykpe3JldHVybiB0cnVlfWVsc2V7cmV0dXJuIGZhbHNlfX19O0tKVVIubGFuZy5TdHJpbmcuaXNIZXg9ZnVuY3Rpb24oYSl7aWYoYS5sZW5ndGglMj09MCYmKGEubWF0Y2goL15bMC05YS1mXSskLyl8fGEubWF0Y2goL15bMC05QS1GXSskLykpKXtyZXR1cm4gdHJ1ZX1lbHNle3JldHVybiBmYWxzZX19O0tKVVIubGFuZy5TdHJpbmcuaXNCYXNlNjQ9ZnVuY3Rpb24oYSl7YT1hLnJlcGxhY2UoL1xccysvZyxcIlwiKTtpZihhLm1hdGNoKC9eWzAtOUEtWmEteitcXC9dKz17MCwzfSQvKSYmYS5sZW5ndGglND09MCl7cmV0dXJuIHRydWV9ZWxzZXtyZXR1cm4gZmFsc2V9fTtLSlVSLmxhbmcuU3RyaW5nLmlzQmFzZTY0VVJMPWZ1bmN0aW9uKGEpe2lmKGEubWF0Y2goL1srLz1dLykpe3JldHVybiBmYWxzZX1hPWI2NHV0b2I2NChhKTtyZXR1cm4gS0pVUi5sYW5nLlN0cmluZy5pc0Jhc2U2NChhKX07S0pVUi5sYW5nLlN0cmluZy5pc0ludGVnZXJBcnJheT1mdW5jdGlvbihhKXthPWEucmVwbGFjZSgvXFxzKy9nLFwiXCIpO2lmKGEubWF0Y2goL15cXFtbMC05LF0rXFxdJC8pKXtyZXR1cm4gdHJ1ZX1lbHNle3JldHVybiBmYWxzZX19O2Z1bmN0aW9uIGhleHRvcG9zaGV4KGEpe2lmKGEubGVuZ3RoJTI9PTEpe3JldHVyblwiMFwiK2F9aWYoYS5zdWJzdHIoMCwxKT5cIjdcIil7cmV0dXJuXCIwMFwiK2F9cmV0dXJuIGF9ZnVuY3Rpb24gaW50YXJ5c3RydG9oZXgoYil7Yj1iLnJlcGxhY2UoL15cXHMqXFxbXFxzKi8sXCJcIik7Yj1iLnJlcGxhY2UoL1xccypcXF1cXHMqJC8sXCJcIik7Yj1iLnJlcGxhY2UoL1xccyovZyxcIlwiKTt0cnl7dmFyIGM9Yi5zcGxpdCgvLC8pLm1hcChmdW5jdGlvbihnLGUsaCl7dmFyIGY9cGFyc2VJbnQoZyk7aWYoZjwwfHwyNTU8Zil7dGhyb3dcImludGVnZXIgbm90IGluIHJhbmdlIDAtMjU1XCJ9dmFyIGQ9KFwiMDBcIitmLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpO3JldHVybiBkfSkuam9pbihcIlwiKTtyZXR1cm4gY31jYXRjaChhKXt0aHJvd1wibWFsZm9ybWVkIGludGVnZXIgYXJyYXkgc3RyaW5nOiBcIithfX12YXIgc3RyZGlmZmlkeD1mdW5jdGlvbihjLGEpe3ZhciBkPWMubGVuZ3RoO2lmKGMubGVuZ3RoPmEubGVuZ3RoKXtkPWEubGVuZ3RofWZvcih2YXIgYj0wO2I8ZDtiKyspe2lmKGMuY2hhckNvZGVBdChiKSE9YS5jaGFyQ29kZUF0KGIpKXtyZXR1cm4gYn19aWYoYy5sZW5ndGghPWEubGVuZ3RoKXtyZXR1cm4gZH1yZXR1cm4gLTF9O1xuaWYodHlwZW9mIEtKVVI9PVwidW5kZWZpbmVkXCJ8fCFLSlVSKXtLSlVSPXt9fWlmKHR5cGVvZiBLSlVSLmNyeXB0bz09XCJ1bmRlZmluZWRcInx8IUtKVVIuY3J5cHRvKXtLSlVSLmNyeXB0bz17fX1LSlVSLmNyeXB0by5VdGlsPW5ldyBmdW5jdGlvbigpe3RoaXMuRElHRVNUSU5GT0hFQUQ9e3NoYTE6XCIzMDIxMzAwOTA2MDUyYjBlMDMwMjFhMDUwMDA0MTRcIixzaGEyMjQ6XCIzMDJkMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDQwNTAwMDQxY1wiLHNoYTI1NjpcIjMwMzEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMTA1MDAwNDIwXCIsc2hhMzg0OlwiMzA0MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAyMDUwMDA0MzBcIixzaGE1MTI6XCIzMDUxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDMwNTAwMDQ0MFwiLG1kMjpcIjMwMjAzMDBjMDYwODJhODY0ODg2ZjcwZDAyMDIwNTAwMDQxMFwiLG1kNTpcIjMwMjAzMDBjMDYwODJhODY0ODg2ZjcwZDAyMDUwNTAwMDQxMFwiLHJpcGVtZDE2MDpcIjMwMjEzMDA5MDYwNTJiMjQwMzAyMDEwNTAwMDQxNFwiLH07dGhpcy5ERUZBVUxUUFJPVklERVI9e21kNTpcImNyeXB0b2pzXCIsc2hhMTpcImNyeXB0b2pzXCIsc2hhMjI0OlwiY3J5cHRvanNcIixzaGEyNTY6XCJjcnlwdG9qc1wiLHNoYTM4NDpcImNyeXB0b2pzXCIsc2hhNTEyOlwiY3J5cHRvanNcIixyaXBlbWQxNjA6XCJjcnlwdG9qc1wiLGhtYWNtZDU6XCJjcnlwdG9qc1wiLGhtYWNzaGExOlwiY3J5cHRvanNcIixobWFjc2hhMjI0OlwiY3J5cHRvanNcIixobWFjc2hhMjU2OlwiY3J5cHRvanNcIixobWFjc2hhMzg0OlwiY3J5cHRvanNcIixobWFjc2hhNTEyOlwiY3J5cHRvanNcIixobWFjcmlwZW1kMTYwOlwiY3J5cHRvanNcIixNRDV3aXRoUlNBOlwiY3J5cHRvanMvanNyc2FcIixTSEExd2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMjI0d2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMjU2d2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMzg0d2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBNTEyd2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsUklQRU1EMTYwd2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsTUQ1d2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEExd2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEEyMjR3aXRoRUNEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTI1NndpdGhFQ0RTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMzg0d2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEE1MTJ3aXRoRUNEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFJJUEVNRDE2MHdpdGhFQ0RTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMXdpdGhEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTIyNHdpdGhEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTI1NndpdGhEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLE1ENXdpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixTSEExd2l0aFJTQWFuZE1HRjE6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTIyNHdpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixTSEEyNTZ3aXRoUlNBYW5kTUdGMTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMzg0d2l0aFJTQWFuZE1HRjE6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTUxMndpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixSSVBFTUQxNjB3aXRoUlNBYW5kTUdGMTpcImNyeXB0b2pzL2pzcnNhXCIsfTt0aGlzLkNSWVBUT0pTTUVTU0FHRURJR0VTVE5BTUU9e21kNTpDcnlwdG9KUy5hbGdvLk1ENSxzaGExOkNyeXB0b0pTLmFsZ28uU0hBMSxzaGEyMjQ6Q3J5cHRvSlMuYWxnby5TSEEyMjQsc2hhMjU2OkNyeXB0b0pTLmFsZ28uU0hBMjU2LHNoYTM4NDpDcnlwdG9KUy5hbGdvLlNIQTM4NCxzaGE1MTI6Q3J5cHRvSlMuYWxnby5TSEE1MTIscmlwZW1kMTYwOkNyeXB0b0pTLmFsZ28uUklQRU1EMTYwfTt0aGlzLmdldERpZ2VzdEluZm9IZXg9ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgdGhpcy5ESUdFU1RJTkZPSEVBRFtiXT09XCJ1bmRlZmluZWRcIil7dGhyb3dcImFsZyBub3Qgc3VwcG9ydGVkIGluIFV0aWwuRElHRVNUSU5GT0hFQUQ6IFwiK2J9cmV0dXJuIHRoaXMuRElHRVNUSU5GT0hFQURbYl0rYX07dGhpcy5nZXRQYWRkZWREaWdlc3RJbmZvSGV4PWZ1bmN0aW9uKGgsYSxqKXt2YXIgYz10aGlzLmdldERpZ2VzdEluZm9IZXgoaCxhKTt2YXIgZD1qLzQ7aWYoYy5sZW5ndGgrMjI+ZCl7dGhyb3dcImtleSBpcyB0b28gc2hvcnQgZm9yIFNpZ0FsZzoga2V5bGVuPVwiK2orXCIsXCIrYX12YXIgYj1cIjAwMDFcIjt2YXIgaz1cIjAwXCIrYzt2YXIgZz1cIlwiO3ZhciBsPWQtYi5sZW5ndGgtay5sZW5ndGg7Zm9yKHZhciBmPTA7ZjxsO2YrPTIpe2crPVwiZmZcIn12YXIgZT1iK2craztyZXR1cm4gZX07dGhpcy5oYXNoU3RyaW5nPWZ1bmN0aW9uKGEsYyl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpjfSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTt0aGlzLmhhc2hIZXg9ZnVuY3Rpb24oYixjKXt2YXIgYT1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOmN9KTtyZXR1cm4gYS5kaWdlc3RIZXgoYil9O3RoaXMuc2hhMT1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwic2hhMVwiLHByb3Y6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTt0aGlzLnNoYTI1Nj1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwic2hhMjU2XCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RTdHJpbmcoYSl9O3RoaXMuc2hhMjU2SGV4PWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0KHthbGc6XCJzaGEyNTZcIixwcm92OlwiY3J5cHRvanNcIn0pO3JldHVybiBiLmRpZ2VzdEhleChhKX07dGhpcy5zaGE1MTI9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpcInNoYTUxMlwiLHByb3Y6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTt0aGlzLnNoYTUxMkhleD1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwic2hhNTEyXCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RIZXgoYSl9fTtLSlVSLmNyeXB0by5VdGlsLm1kNT1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwibWQ1XCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RTdHJpbmcoYSl9O0tKVVIuY3J5cHRvLlV0aWwucmlwZW1kMTYwPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0KHthbGc6XCJyaXBlbWQxNjBcIixwcm92OlwiY3J5cHRvanNcIn0pO3JldHVybiBiLmRpZ2VzdFN0cmluZyhhKX07S0pVUi5jcnlwdG8uVXRpbC5TRUNVUkVSQU5ET01HRU49bmV3IFNlY3VyZVJhbmRvbSgpO0tKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tSGV4T2ZOYnl0ZXM9ZnVuY3Rpb24oYil7dmFyIGE9bmV3IEFycmF5KGIpO0tKVVIuY3J5cHRvLlV0aWwuU0VDVVJFUkFORE9NR0VOLm5leHRCeXRlcyhhKTtyZXR1cm4gQkF0b2hleChhKX07S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYnl0ZXM9ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKEtKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tSGV4T2ZOYnl0ZXMoYSksMTYpfTtLSlVSLmNyeXB0by5VdGlsLmdldFJhbmRvbUhleE9mTmJpdHM9ZnVuY3Rpb24oZCl7dmFyIGM9ZCU4O3ZhciBhPShkLWMpLzg7dmFyIGI9bmV3IEFycmF5KGErMSk7S0pVUi5jcnlwdG8uVXRpbC5TRUNVUkVSQU5ET01HRU4ubmV4dEJ5dGVzKGIpO2JbMF09KCgoMjU1PDxjKSYyNTUpXjI1NSkmYlswXTtyZXR1cm4gQkF0b2hleChiKX07S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYml0cz1mdW5jdGlvbihhKXtyZXR1cm4gbmV3IEJpZ0ludGVnZXIoS0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21IZXhPZk5iaXRzKGEpLDE2KX07S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyWmVyb1RvTWF4PWZ1bmN0aW9uKGIpe3ZhciBhPWIuYml0TGVuZ3RoKCk7d2hpbGUoMSl7dmFyIGM9S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYml0cyhhKTtpZihiLmNvbXBhcmVUbyhjKSE9LTEpe3JldHVybiBjfX19O0tKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tQmlnSW50ZWdlck1pblRvTWF4PWZ1bmN0aW9uKGUsYil7dmFyIGM9ZS5jb21wYXJlVG8oYik7aWYoYz09MSl7dGhyb3dcImJpTWluIGlzIGdyZWF0ZXIgdGhhbiBiaU1heFwifWlmKGM9PTApe3JldHVybiBlfXZhciBhPWIuc3VidHJhY3QoZSk7dmFyIGQ9S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyWmVyb1RvTWF4KGEpO3JldHVybiBkLmFkZChlKX07S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdD1mdW5jdGlvbihjKXt2YXIgYj1udWxsO3ZhciBhPW51bGw7dmFyIGQ9bnVsbDt0aGlzLnNldEFsZ0FuZFByb3ZpZGVyPWZ1bmN0aW9uKGcsZil7Zz1LSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0LmdldENhbm9uaWNhbEFsZ05hbWUoZyk7aWYoZyE9PW51bGwmJmY9PT11bmRlZmluZWQpe2Y9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJbZ119aWYoXCI6bWQ1OnNoYTE6c2hhMjI0OnNoYTI1NjpzaGEzODQ6c2hhNTEyOnJpcGVtZDE2MDpcIi5pbmRleE9mKGcpIT0tMSYmZj09XCJjcnlwdG9qc1wiKXt0cnl7dGhpcy5tZD1LSlVSLmNyeXB0by5VdGlsLkNSWVBUT0pTTUVTU0FHRURJR0VTVE5BTUVbZ10uY3JlYXRlKCl9Y2F0Y2goZSl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGFsZz1cIitnK1wiL1wiK2V9dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24oaCl7dGhpcy5tZC51cGRhdGUoaCl9O3RoaXMudXBkYXRlSGV4PWZ1bmN0aW9uKGgpe3ZhciBpPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoaCk7dGhpcy5tZC51cGRhdGUoaSl9O3RoaXMuZGlnZXN0PWZ1bmN0aW9uKCl7dmFyIGg9dGhpcy5tZC5maW5hbGl6ZSgpO3JldHVybiBoLnRvU3RyaW5nKENyeXB0b0pTLmVuYy5IZXgpfTt0aGlzLmRpZ2VzdFN0cmluZz1mdW5jdGlvbihoKXt0aGlzLnVwZGF0ZVN0cmluZyhoKTtyZXR1cm4gdGhpcy5kaWdlc3QoKX07dGhpcy5kaWdlc3RIZXg9ZnVuY3Rpb24oaCl7dGhpcy51cGRhdGVIZXgoaCk7cmV0dXJuIHRoaXMuZGlnZXN0KCl9fWlmKFwiOnNoYTI1NjpcIi5pbmRleE9mKGcpIT0tMSYmZj09XCJzamNsXCIpe3RyeXt0aGlzLm1kPW5ldyBzamNsLmhhc2guc2hhMjU2KCl9Y2F0Y2goZSl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGFsZz1cIitnK1wiL1wiK2V9dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24oaCl7dGhpcy5tZC51cGRhdGUoaCl9O3RoaXMudXBkYXRlSGV4PWZ1bmN0aW9uKGkpe3ZhciBoPXNqY2wuY29kZWMuaGV4LnRvQml0cyhpKTt0aGlzLm1kLnVwZGF0ZShoKX07dGhpcy5kaWdlc3Q9ZnVuY3Rpb24oKXt2YXIgaD10aGlzLm1kLmZpbmFsaXplKCk7cmV0dXJuIHNqY2wuY29kZWMuaGV4LmZyb21CaXRzKGgpfTt0aGlzLmRpZ2VzdFN0cmluZz1mdW5jdGlvbihoKXt0aGlzLnVwZGF0ZVN0cmluZyhoKTtyZXR1cm4gdGhpcy5kaWdlc3QoKX07dGhpcy5kaWdlc3RIZXg9ZnVuY3Rpb24oaCl7dGhpcy51cGRhdGVIZXgoaCk7cmV0dXJuIHRoaXMuZGlnZXN0KCl9fX07dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24oZSl7dGhyb3dcInVwZGF0ZVN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnTmFtZStcIi9cIit0aGlzLnByb3ZOYW1lfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihlKXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdOYW1lK1wiL1wiK3RoaXMucHJvdk5hbWV9O3RoaXMuZGlnZXN0PWZ1bmN0aW9uKCl7dGhyb3dcImRpZ2VzdCgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnTmFtZStcIi9cIit0aGlzLnByb3ZOYW1lfTt0aGlzLmRpZ2VzdFN0cmluZz1mdW5jdGlvbihlKXt0aHJvd1wiZGlnZXN0U3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdOYW1lK1wiL1wiK3RoaXMucHJvdk5hbWV9O3RoaXMuZGlnZXN0SGV4PWZ1bmN0aW9uKGUpe3Rocm93XCJkaWdlc3RIZXgoaGV4KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmFsZ05hbWUrXCIvXCIrdGhpcy5wcm92TmFtZX07aWYoYyE9PXVuZGVmaW5lZCl7aWYoYy5hbGchPT11bmRlZmluZWQpe3RoaXMuYWxnTmFtZT1jLmFsZztpZihjLnByb3Y9PT11bmRlZmluZWQpe3RoaXMucHJvdk5hbWU9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJbdGhpcy5hbGdOYW1lXX10aGlzLnNldEFsZ0FuZFByb3ZpZGVyKHRoaXMuYWxnTmFtZSx0aGlzLnByb3ZOYW1lKX19fTtLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0LmdldENhbm9uaWNhbEFsZ05hbWU9ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PT1cInN0cmluZ1wiKXthPWEudG9Mb3dlckNhc2UoKTthPWEucmVwbGFjZSgvLS8sXCJcIil9cmV0dXJuIGF9O0tKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3QuZ2V0SGFzaExlbmd0aD1mdW5jdGlvbihjKXt2YXIgYj1LSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0O3ZhciBhPWIuZ2V0Q2Fub25pY2FsQWxnTmFtZShjKTtpZihiLkhBU0hMRU5HVEhbYV09PT11bmRlZmluZWQpe3Rocm93XCJub3Qgc3VwcG9ydGVkIGFsZ29yaXRobTogXCIrY31yZXR1cm4gYi5IQVNITEVOR1RIW2FdfTtLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0LkhBU0hMRU5HVEg9e21kNToxNixzaGExOjIwLHNoYTIyNDoyOCxzaGEyNTY6MzIsc2hhMzg0OjQ4LHNoYTUxMjo2NCxyaXBlbWQxNjA6MjB9O0tKVVIuY3J5cHRvLk1hYz1mdW5jdGlvbihkKXt2YXIgZj1udWxsO3ZhciBjPW51bGw7dmFyIGE9bnVsbDt2YXIgZT1udWxsO3ZhciBiPW51bGw7dGhpcy5zZXRBbGdBbmRQcm92aWRlcj1mdW5jdGlvbihrLGkpe2s9ay50b0xvd2VyQ2FzZSgpO2lmKGs9PW51bGwpe2s9XCJobWFjc2hhMVwifWs9ay50b0xvd2VyQ2FzZSgpO2lmKGsuc3Vic3RyKDAsNCkhPVwiaG1hY1wiKXt0aHJvd1wic2V0QWxnQW5kUHJvdmlkZXIgdW5zdXBwb3J0ZWQgSE1BQyBhbGc6IFwiK2t9aWYoaT09PXVuZGVmaW5lZCl7aT1LSlVSLmNyeXB0by5VdGlsLkRFRkFVTFRQUk9WSURFUltrXX10aGlzLmFsZ1Byb3Y9aytcIi9cIitpO3ZhciBnPWsuc3Vic3RyKDQpO2lmKFwiOm1kNTpzaGExOnNoYTIyNDpzaGEyNTY6c2hhMzg0OnNoYTUxMjpyaXBlbWQxNjA6XCIuaW5kZXhPZihnKSE9LTEmJmk9PVwiY3J5cHRvanNcIil7dHJ5e3ZhciBqPUtKVVIuY3J5cHRvLlV0aWwuQ1JZUFRPSlNNRVNTQUdFRElHRVNUTkFNRVtnXTt0aGlzLm1hYz1DcnlwdG9KUy5hbGdvLkhNQUMuY3JlYXRlKGosdGhpcy5wYXNzKX1jYXRjaChoKXt0aHJvd1wic2V0QWxnQW5kUHJvdmlkZXIgaGFzaCBhbGcgc2V0IGZhaWwgaGFzaEFsZz1cIitnK1wiL1wiK2h9dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24obCl7dGhpcy5tYWMudXBkYXRlKGwpfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihsKXt2YXIgbT1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGwpO3RoaXMubWFjLnVwZGF0ZShtKX07dGhpcy5kb0ZpbmFsPWZ1bmN0aW9uKCl7dmFyIGw9dGhpcy5tYWMuZmluYWxpemUoKTtyZXR1cm4gbC50b1N0cmluZyhDcnlwdG9KUy5lbmMuSGV4KX07dGhpcy5kb0ZpbmFsU3RyaW5nPWZ1bmN0aW9uKGwpe3RoaXMudXBkYXRlU3RyaW5nKGwpO3JldHVybiB0aGlzLmRvRmluYWwoKX07dGhpcy5kb0ZpbmFsSGV4PWZ1bmN0aW9uKGwpe3RoaXMudXBkYXRlSGV4KGwpO3JldHVybiB0aGlzLmRvRmluYWwoKX19fTt0aGlzLnVwZGF0ZVN0cmluZz1mdW5jdGlvbihnKXt0aHJvd1widXBkYXRlU3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdQcm92fTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihnKXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdQcm92fTt0aGlzLmRvRmluYWw9ZnVuY3Rpb24oKXt0aHJvd1wiZGlnZXN0KCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdQcm92fTt0aGlzLmRvRmluYWxTdHJpbmc9ZnVuY3Rpb24oZyl7dGhyb3dcImRpZ2VzdFN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnUHJvdn07dGhpcy5kb0ZpbmFsSGV4PWZ1bmN0aW9uKGcpe3Rocm93XCJkaWdlc3RIZXgoaGV4KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmFsZ1Byb3Z9O3RoaXMuc2V0UGFzc3dvcmQ9ZnVuY3Rpb24oaCl7aWYodHlwZW9mIGg9PVwic3RyaW5nXCIpe3ZhciBnPWg7aWYoaC5sZW5ndGglMj09MXx8IWgubWF0Y2goL15bMC05QS1GYS1mXSskLykpe2c9cnN0cnRvaGV4KGgpfXRoaXMucGFzcz1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGcpO3JldHVybn1pZih0eXBlb2YgaCE9XCJvYmplY3RcIil7dGhyb3dcIktKVVIuY3J5cHRvLk1hYyB1bnN1cHBvcnRlZCBwYXNzd29yZCB0eXBlOiBcIitofXZhciBnPW51bGw7aWYoaC5oZXghPT11bmRlZmluZWQpe2lmKGguaGV4Lmxlbmd0aCUyIT0wfHwhaC5oZXgubWF0Y2goL15bMC05QS1GYS1mXSskLykpe3Rocm93XCJNYWM6IHdyb25nIGhleCBwYXNzd29yZDogXCIraC5oZXh9Zz1oLmhleH1pZihoLnV0ZjghPT11bmRlZmluZWQpe2c9dXRmOHRvaGV4KGgudXRmOCl9aWYoaC5yc3RyIT09dW5kZWZpbmVkKXtnPXJzdHJ0b2hleChoLnJzdHIpfWlmKGguYjY0IT09dW5kZWZpbmVkKXtnPWI2NHRvaGV4KGguYjY0KX1pZihoLmI2NHUhPT11bmRlZmluZWQpe2c9YjY0dXRvaGV4KGguYjY0dSl9aWYoZz09bnVsbCl7dGhyb3dcIktKVVIuY3J5cHRvLk1hYyB1bnN1cHBvcnRlZCBwYXNzd29yZCB0eXBlOiBcIitofXRoaXMucGFzcz1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGcpfTtpZihkIT09dW5kZWZpbmVkKXtpZihkLnBhc3MhPT11bmRlZmluZWQpe3RoaXMuc2V0UGFzc3dvcmQoZC5wYXNzKX1pZihkLmFsZyE9PXVuZGVmaW5lZCl7dGhpcy5hbGdOYW1lPWQuYWxnO2lmKGQucHJvdj09PXVuZGVmaW5lZCl7dGhpcy5wcm92TmFtZT1LSlVSLmNyeXB0by5VdGlsLkRFRkFVTFRQUk9WSURFUlt0aGlzLmFsZ05hbWVdfXRoaXMuc2V0QWxnQW5kUHJvdmlkZXIodGhpcy5hbGdOYW1lLHRoaXMucHJvdk5hbWUpfX19O0tKVVIuY3J5cHRvLlNpZ25hdHVyZT1mdW5jdGlvbihvKXt2YXIgcT1udWxsO3ZhciBuPW51bGw7dmFyIHI9bnVsbDt2YXIgYz1udWxsO3ZhciBsPW51bGw7dmFyIGQ9bnVsbDt2YXIgaz1udWxsO3ZhciBoPW51bGw7dmFyIHA9bnVsbDt2YXIgZT1udWxsO3ZhciBiPS0xO3ZhciBnPW51bGw7dmFyIGo9bnVsbDt2YXIgYT1udWxsO3ZhciBpPW51bGw7dmFyIGY9bnVsbDt0aGlzLl9zZXRBbGdOYW1lcz1mdW5jdGlvbigpe3ZhciBzPXRoaXMuYWxnTmFtZS5tYXRjaCgvXiguKyl3aXRoKC4rKSQvKTtpZihzKXt0aGlzLm1kQWxnTmFtZT1zWzFdLnRvTG93ZXJDYXNlKCk7dGhpcy5wdWJrZXlBbGdOYW1lPXNbMl0udG9Mb3dlckNhc2UoKX19O3RoaXMuX3plcm9QYWRkaW5nT2ZTaWduYXR1cmU9ZnVuY3Rpb24oeCx3KXt2YXIgdj1cIlwiO3ZhciB0PXcvNC14Lmxlbmd0aDtmb3IodmFyIHU9MDt1PHQ7dSsrKXt2PXYrXCIwXCJ9cmV0dXJuIHYreH07dGhpcy5zZXRBbGdBbmRQcm92aWRlcj1mdW5jdGlvbih1LHQpe3RoaXMuX3NldEFsZ05hbWVzKCk7aWYodCE9XCJjcnlwdG9qcy9qc3JzYVwiKXt0aHJvd1wicHJvdmlkZXIgbm90IHN1cHBvcnRlZDogXCIrdH1pZihcIjptZDU6c2hhMTpzaGEyMjQ6c2hhMjU2OnNoYTM4NDpzaGE1MTI6cmlwZW1kMTYwOlwiLmluZGV4T2YodGhpcy5tZEFsZ05hbWUpIT0tMSl7dHJ5e3RoaXMubWQ9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzp0aGlzLm1kQWxnTmFtZX0pfWNhdGNoKHMpe3Rocm93XCJzZXRBbGdBbmRQcm92aWRlciBoYXNoIGFsZyBzZXQgZmFpbCBhbGc9XCIrdGhpcy5tZEFsZ05hbWUrXCIvXCIrc310aGlzLmluaXQ9ZnVuY3Rpb24odyx4KXt2YXIgeT1udWxsO3RyeXtpZih4PT09dW5kZWZpbmVkKXt5PUtFWVVUSUwuZ2V0S2V5KHcpfWVsc2V7eT1LRVlVVElMLmdldEtleSh3LHgpfX1jYXRjaCh2KXt0aHJvd1wiaW5pdCBmYWlsZWQ6XCIrdn1pZih5LmlzUHJpdmF0ZT09PXRydWUpe3RoaXMucHJ2S2V5PXk7dGhpcy5zdGF0ZT1cIlNJR05cIn1lbHNle2lmKHkuaXNQdWJsaWM9PT10cnVlKXt0aGlzLnB1YktleT15O3RoaXMuc3RhdGU9XCJWRVJJRllcIn1lbHNle3Rocm93XCJpbml0IGZhaWxlZC46XCIreX19fTt0aGlzLnVwZGF0ZVN0cmluZz1mdW5jdGlvbih2KXt0aGlzLm1kLnVwZGF0ZVN0cmluZyh2KX07dGhpcy51cGRhdGVIZXg9ZnVuY3Rpb24odil7dGhpcy5tZC51cGRhdGVIZXgodil9O3RoaXMuc2lnbj1mdW5jdGlvbigpe3RoaXMuc0hhc2hIZXg9dGhpcy5tZC5kaWdlc3QoKTtpZih0eXBlb2YgdGhpcy5lY3BydmhleCE9XCJ1bmRlZmluZWRcIiYmdHlwZW9mIHRoaXMuZWNjdXJ2ZW5hbWUhPVwidW5kZWZpbmVkXCIpe3ZhciB2PW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6dGhpcy5lY2N1cnZlbmFtZX0pO3RoaXMuaFNpZ249di5zaWduSGV4KHRoaXMuc0hhc2hIZXgsdGhpcy5lY3BydmhleCl9ZWxzZXtpZih0aGlzLnBydktleSBpbnN0YW5jZW9mIFJTQUtleSYmdGhpcy5wdWJrZXlBbGdOYW1lPT09XCJyc2FhbmRtZ2YxXCIpe3RoaXMuaFNpZ249dGhpcy5wcnZLZXkuc2lnbldpdGhNZXNzYWdlSGFzaFBTUyh0aGlzLnNIYXNoSGV4LHRoaXMubWRBbGdOYW1lLHRoaXMucHNzU2FsdExlbil9ZWxzZXtpZih0aGlzLnBydktleSBpbnN0YW5jZW9mIFJTQUtleSYmdGhpcy5wdWJrZXlBbGdOYW1lPT09XCJyc2FcIil7dGhpcy5oU2lnbj10aGlzLnBydktleS5zaWduV2l0aE1lc3NhZ2VIYXNoKHRoaXMuc0hhc2hIZXgsdGhpcy5tZEFsZ05hbWUpfWVsc2V7aWYodGhpcy5wcnZLZXkgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5FQ0RTQSl7dGhpcy5oU2lnbj10aGlzLnBydktleS5zaWduV2l0aE1lc3NhZ2VIYXNoKHRoaXMuc0hhc2hIZXgpfWVsc2V7aWYodGhpcy5wcnZLZXkgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5EU0Epe3RoaXMuaFNpZ249dGhpcy5wcnZLZXkuc2lnbldpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4KX1lbHNle3Rocm93XCJTaWduYXR1cmU6IHVuc3VwcG9ydGVkIHByaXZhdGUga2V5IGFsZzogXCIrdGhpcy5wdWJrZXlBbGdOYW1lfX19fX1yZXR1cm4gdGhpcy5oU2lnbn07dGhpcy5zaWduU3RyaW5nPWZ1bmN0aW9uKHYpe3RoaXMudXBkYXRlU3RyaW5nKHYpO3JldHVybiB0aGlzLnNpZ24oKX07dGhpcy5zaWduSGV4PWZ1bmN0aW9uKHYpe3RoaXMudXBkYXRlSGV4KHYpO3JldHVybiB0aGlzLnNpZ24oKX07dGhpcy52ZXJpZnk9ZnVuY3Rpb24odil7dGhpcy5zSGFzaEhleD10aGlzLm1kLmRpZ2VzdCgpO2lmKHR5cGVvZiB0aGlzLmVjcHViaGV4IT1cInVuZGVmaW5lZFwiJiZ0eXBlb2YgdGhpcy5lY2N1cnZlbmFtZSE9XCJ1bmRlZmluZWRcIil7dmFyIHc9bmV3IEtKVVIuY3J5cHRvLkVDRFNBKHtjdXJ2ZTp0aGlzLmVjY3VydmVuYW1lfSk7cmV0dXJuIHcudmVyaWZ5SGV4KHRoaXMuc0hhc2hIZXgsdix0aGlzLmVjcHViaGV4KX1lbHNle2lmKHRoaXMucHViS2V5IGluc3RhbmNlb2YgUlNBS2V5JiZ0aGlzLnB1YmtleUFsZ05hbWU9PT1cInJzYWFuZG1nZjFcIil7cmV0dXJuIHRoaXMucHViS2V5LnZlcmlmeVdpdGhNZXNzYWdlSGFzaFBTUyh0aGlzLnNIYXNoSGV4LHYsdGhpcy5tZEFsZ05hbWUsdGhpcy5wc3NTYWx0TGVuKX1lbHNle2lmKHRoaXMucHViS2V5IGluc3RhbmNlb2YgUlNBS2V5JiZ0aGlzLnB1YmtleUFsZ05hbWU9PT1cInJzYVwiKXtyZXR1cm4gdGhpcy5wdWJLZXkudmVyaWZ5V2l0aE1lc3NhZ2VIYXNoKHRoaXMuc0hhc2hIZXgsdil9ZWxzZXtpZihLSlVSLmNyeXB0by5FQ0RTQSE9PXVuZGVmaW5lZCYmdGhpcy5wdWJLZXkgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5FQ0RTQSl7cmV0dXJuIHRoaXMucHViS2V5LnZlcmlmeVdpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4LHYpfWVsc2V7aWYoS0pVUi5jcnlwdG8uRFNBIT09dW5kZWZpbmVkJiZ0aGlzLnB1YktleSBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkRTQSl7cmV0dXJuIHRoaXMucHViS2V5LnZlcmlmeVdpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4LHYpfWVsc2V7dGhyb3dcIlNpZ25hdHVyZTogdW5zdXBwb3J0ZWQgcHVibGljIGtleSBhbGc6IFwiK3RoaXMucHVia2V5QWxnTmFtZX19fX19fX19O3RoaXMuaW5pdD1mdW5jdGlvbihzLHQpe3Rocm93XCJpbml0KGtleSwgcGFzcykgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnVwZGF0ZVN0cmluZz1mdW5jdGlvbihzKXt0aHJvd1widXBkYXRlU3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihzKXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnNpZ249ZnVuY3Rpb24oKXt0aHJvd1wic2lnbigpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy5zaWduU3RyaW5nPWZ1bmN0aW9uKHMpe3Rocm93XCJkaWdlc3RTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMuYWxnUHJvdk5hbWV9O3RoaXMuc2lnbkhleD1mdW5jdGlvbihzKXt0aHJvd1wiZGlnZXN0SGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnZlcmlmeT1mdW5jdGlvbihzKXt0aHJvd1widmVyaWZ5KGhTaWdWYWwpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy5pbml0UGFyYW1zPW87aWYobyE9PXVuZGVmaW5lZCl7aWYoby5hbGchPT11bmRlZmluZWQpe3RoaXMuYWxnTmFtZT1vLmFsZztpZihvLnByb3Y9PT11bmRlZmluZWQpe3RoaXMucHJvdk5hbWU9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJbdGhpcy5hbGdOYW1lXX1lbHNle3RoaXMucHJvdk5hbWU9by5wcm92fXRoaXMuYWxnUHJvdk5hbWU9dGhpcy5hbGdOYW1lK1wiOlwiK3RoaXMucHJvdk5hbWU7dGhpcy5zZXRBbGdBbmRQcm92aWRlcih0aGlzLmFsZ05hbWUsdGhpcy5wcm92TmFtZSk7dGhpcy5fc2V0QWxnTmFtZXMoKX1pZihvLnBzc3NhbHRsZW4hPT11bmRlZmluZWQpe3RoaXMucHNzU2FsdExlbj1vLnBzc3NhbHRsZW59aWYoby5wcnZrZXlwZW0hPT11bmRlZmluZWQpe2lmKG8ucHJ2a2V5cGFzIT09dW5kZWZpbmVkKXt0aHJvd1wiYm90aCBwcnZrZXlwZW0gYW5kIHBydmtleXBhcyBwYXJhbWV0ZXJzIG5vdCBzdXBwb3J0ZWRcIn1lbHNle3RyeXt2YXIgcT1LRVlVVElMLmdldEtleShvLnBydmtleXBlbSk7dGhpcy5pbml0KHEpfWNhdGNoKG0pe3Rocm93XCJmYXRhbCBlcnJvciB0byBsb2FkIHBlbSBwcml2YXRlIGtleTogXCIrbX19fX19O0tKVVIuY3J5cHRvLkNpcGhlcj1mdW5jdGlvbihhKXt9O0tKVVIuY3J5cHRvLkNpcGhlci5lbmNyeXB0PWZ1bmN0aW9uKGUsZixkKXtpZihmIGluc3RhbmNlb2YgUlNBS2V5JiZmLmlzUHVibGljKXt2YXIgYz1LSlVSLmNyeXB0by5DaXBoZXIuZ2V0QWxnQnlLZXlBbmROYW1lKGYsZCk7aWYoYz09PVwiUlNBXCIpe3JldHVybiBmLmVuY3J5cHQoZSl9aWYoYz09PVwiUlNBT0FFUFwiKXtyZXR1cm4gZi5lbmNyeXB0T0FFUChlLFwic2hhMVwiKX12YXIgYj1jLm1hdGNoKC9eUlNBT0FFUChcXGQrKSQvKTtpZihiIT09bnVsbCl7cmV0dXJuIGYuZW5jcnlwdE9BRVAoZSxcInNoYVwiK2JbMV0pfXRocm93XCJDaXBoZXIuZW5jcnlwdDogdW5zdXBwb3J0ZWQgYWxnb3JpdGhtIGZvciBSU0FLZXk6IFwiK2R9ZWxzZXt0aHJvd1wiQ2lwaGVyLmVuY3J5cHQ6IHVuc3VwcG9ydGVkIGtleSBvciBhbGdvcml0aG1cIn19O0tKVVIuY3J5cHRvLkNpcGhlci5kZWNyeXB0PWZ1bmN0aW9uKGUsZixkKXtpZihmIGluc3RhbmNlb2YgUlNBS2V5JiZmLmlzUHJpdmF0ZSl7dmFyIGM9S0pVUi5jcnlwdG8uQ2lwaGVyLmdldEFsZ0J5S2V5QW5kTmFtZShmLGQpO2lmKGM9PT1cIlJTQVwiKXtyZXR1cm4gZi5kZWNyeXB0KGUpfWlmKGM9PT1cIlJTQU9BRVBcIil7cmV0dXJuIGYuZGVjcnlwdE9BRVAoZSxcInNoYTFcIil9dmFyIGI9Yy5tYXRjaCgvXlJTQU9BRVAoXFxkKykkLyk7aWYoYiE9PW51bGwpe3JldHVybiBmLmRlY3J5cHRPQUVQKGUsXCJzaGFcIitiWzFdKX10aHJvd1wiQ2lwaGVyLmRlY3J5cHQ6IHVuc3VwcG9ydGVkIGFsZ29yaXRobSBmb3IgUlNBS2V5OiBcIitkfWVsc2V7dGhyb3dcIkNpcGhlci5kZWNyeXB0OiB1bnN1cHBvcnRlZCBrZXkgb3IgYWxnb3JpdGhtXCJ9fTtLSlVSLmNyeXB0by5DaXBoZXIuZ2V0QWxnQnlLZXlBbmROYW1lPWZ1bmN0aW9uKGIsYSl7aWYoYiBpbnN0YW5jZW9mIFJTQUtleSl7aWYoXCI6UlNBOlJTQU9BRVA6UlNBT0FFUDIyNDpSU0FPQUVQMjU2OlJTQU9BRVAzODQ6UlNBT0FFUDUxMjpcIi5pbmRleE9mKGEpIT0tMSl7cmV0dXJuIGF9aWYoYT09PW51bGx8fGE9PT11bmRlZmluZWQpe3JldHVyblwiUlNBXCJ9dGhyb3dcImdldEFsZ0J5S2V5QW5kTmFtZTogbm90IHN1cHBvcnRlZCBhbGdvcml0aG0gbmFtZSBmb3IgUlNBS2V5OiBcIithfXRocm93XCJnZXRBbGdCeUtleUFuZE5hbWU6IG5vdCBzdXBwb3J0ZWQgYWxnb3JpdGhtIG5hbWU6IFwiK2F9O0tKVVIuY3J5cHRvLk9JRD1uZXcgZnVuY3Rpb24oKXt0aGlzLm9pZGhleDJuYW1lPXtcIjJhODY0ODg2ZjcwZDAxMDEwMVwiOlwicnNhRW5jcnlwdGlvblwiLFwiMmE4NjQ4Y2UzZDAyMDFcIjpcImVjUHVibGljS2V5XCIsXCIyYTg2NDhjZTM4MDQwMVwiOlwiZHNhXCIsXCIyYTg2NDhjZTNkMDMwMTA3XCI6XCJzZWNwMjU2cjFcIixcIjJiODEwNDAwMWZcIjpcInNlY3AxOTJrMVwiLFwiMmI4MTA0MDAyMVwiOlwic2VjcDIyNHIxXCIsXCIyYjgxMDQwMDBhXCI6XCJzZWNwMjU2azFcIixcIjJiODEwNDAwMjNcIjpcInNlY3A1MjFyMVwiLFwiMmI4MTA0MDAyMlwiOlwic2VjcDM4NHIxXCIsXCIyYTg2NDhjZTM4MDQwM1wiOlwiU0hBMXdpdGhEU0FcIixcIjYwODY0ODAxNjUwMzA0MDMwMVwiOlwiU0hBMjI0d2l0aERTQVwiLFwiNjA4NjQ4MDE2NTAzMDQwMzAyXCI6XCJTSEEyNTZ3aXRoRFNBXCIsfX07XG5pZih0eXBlb2YgS0pVUj09XCJ1bmRlZmluZWRcInx8IUtKVVIpe0tKVVI9e319aWYodHlwZW9mIEtKVVIuY3J5cHRvPT1cInVuZGVmaW5lZFwifHwhS0pVUi5jcnlwdG8pe0tKVVIuY3J5cHRvPXt9fUtKVVIuY3J5cHRvLkVDRFNBPWZ1bmN0aW9uKGgpe3ZhciBlPVwic2VjcDI1NnIxXCI7dmFyIGc9bnVsbDt2YXIgYj1udWxsO3ZhciBmPW51bGw7dmFyIGE9bmV3IFNlY3VyZVJhbmRvbSgpO3ZhciBkPW51bGw7dGhpcy50eXBlPVwiRUNcIjt0aGlzLmlzUHJpdmF0ZT1mYWxzZTt0aGlzLmlzUHVibGljPWZhbHNlO2Z1bmN0aW9uIGMocyxvLHIsbil7dmFyIGo9TWF0aC5tYXgoby5iaXRMZW5ndGgoKSxuLmJpdExlbmd0aCgpKTt2YXIgdD1zLmFkZDJEKHIpO3ZhciBxPXMuY3VydmUuZ2V0SW5maW5pdHkoKTtmb3IodmFyIHA9ai0xO3A+PTA7LS1wKXtxPXEudHdpY2UyRCgpO3Euej1CaWdJbnRlZ2VyLk9ORTtpZihvLnRlc3RCaXQocCkpe2lmKG4udGVzdEJpdChwKSl7cT1xLmFkZDJEKHQpfWVsc2V7cT1xLmFkZDJEKHMpfX1lbHNle2lmKG4udGVzdEJpdChwKSl7cT1xLmFkZDJEKHIpfX19cmV0dXJuIHF9dGhpcy5nZXRCaWdSYW5kb209ZnVuY3Rpb24oaSl7cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGkuYml0TGVuZ3RoKCksYSkubW9kKGkuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKS5hZGQoQmlnSW50ZWdlci5PTkUpfTt0aGlzLnNldE5hbWVkQ3VydmU9ZnVuY3Rpb24oaSl7dGhpcy5lY3BhcmFtcz1LSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLmdldEJ5TmFtZShpKTt0aGlzLnBydktleUhleD1udWxsO3RoaXMucHViS2V5SGV4PW51bGw7dGhpcy5jdXJ2ZU5hbWU9aX07dGhpcy5zZXRQcml2YXRlS2V5SGV4PWZ1bmN0aW9uKGkpe3RoaXMuaXNQcml2YXRlPXRydWU7dGhpcy5wcnZLZXlIZXg9aX07dGhpcy5zZXRQdWJsaWNLZXlIZXg9ZnVuY3Rpb24oaSl7dGhpcy5pc1B1YmxpYz10cnVlO3RoaXMucHViS2V5SGV4PWl9O3RoaXMuZ2V0UHVibGljS2V5WFlIZXg9ZnVuY3Rpb24oKXt2YXIgaz10aGlzLnB1YktleUhleDtpZihrLnN1YnN0cigwLDIpIT09XCIwNFwiKXt0aHJvd1widGhpcyBtZXRob2Qgc3VwcG9ydHMgdW5jb21wcmVzc2VkIGZvcm1hdCgwNCkgb25seVwifXZhciBqPXRoaXMuZWNwYXJhbXMua2V5bGVuLzQ7aWYoay5sZW5ndGghPT0yK2oqMil7dGhyb3dcIm1hbGZvcm1lZCBwdWJsaWMga2V5IGhleCBsZW5ndGhcIn12YXIgaT17fTtpLng9ay5zdWJzdHIoMixqKTtpLnk9ay5zdWJzdHIoMitqKTtyZXR1cm4gaX07dGhpcy5nZXRTaG9ydE5JU1RQQ3VydmVOYW1lPWZ1bmN0aW9uKCl7dmFyIGk9dGhpcy5jdXJ2ZU5hbWU7aWYoaT09PVwic2VjcDI1NnIxXCJ8fGk9PT1cIk5JU1QgUC0yNTZcInx8aT09PVwiUC0yNTZcInx8aT09PVwicHJpbWUyNTZ2MVwiKXtyZXR1cm5cIlAtMjU2XCJ9aWYoaT09PVwic2VjcDM4NHIxXCJ8fGk9PT1cIk5JU1QgUC0zODRcInx8aT09PVwiUC0zODRcIil7cmV0dXJuXCJQLTM4NFwifXJldHVybiBudWxsfTt0aGlzLmdlbmVyYXRlS2V5UGFpckhleD1mdW5jdGlvbigpe3ZhciBrPXRoaXMuZWNwYXJhbXMubjt2YXIgbj10aGlzLmdldEJpZ1JhbmRvbShrKTt2YXIgbD10aGlzLmVjcGFyYW1zLkcubXVsdGlwbHkobik7dmFyIHE9bC5nZXRYKCkudG9CaWdJbnRlZ2VyKCk7dmFyIG89bC5nZXRZKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGk9dGhpcy5lY3BhcmFtcy5rZXlsZW4vNDt2YXIgbT0oXCIwMDAwMDAwMDAwXCIrbi50b1N0cmluZygxNikpLnNsaWNlKC1pKTt2YXIgcj0oXCIwMDAwMDAwMDAwXCIrcS50b1N0cmluZygxNikpLnNsaWNlKC1pKTt2YXIgcD0oXCIwMDAwMDAwMDAwXCIrby50b1N0cmluZygxNikpLnNsaWNlKC1pKTt2YXIgaj1cIjA0XCIrcitwO3RoaXMuc2V0UHJpdmF0ZUtleUhleChtKTt0aGlzLnNldFB1YmxpY0tleUhleChqKTtyZXR1cm57ZWNwcnZoZXg6bSxlY3B1YmhleDpqfX07dGhpcy5zaWduV2l0aE1lc3NhZ2VIYXNoPWZ1bmN0aW9uKGkpe3JldHVybiB0aGlzLnNpZ25IZXgoaSx0aGlzLnBydktleUhleCl9O3RoaXMuc2lnbkhleD1mdW5jdGlvbihvLGope3ZhciB0PW5ldyBCaWdJbnRlZ2VyKGosMTYpO3ZhciBsPXRoaXMuZWNwYXJhbXMubjt2YXIgcT1uZXcgQmlnSW50ZWdlcihvLDE2KTtkb3t2YXIgbT10aGlzLmdldEJpZ1JhbmRvbShsKTt2YXIgdT10aGlzLmVjcGFyYW1zLkc7dmFyIHA9dS5tdWx0aXBseShtKTt2YXIgaT1wLmdldFgoKS50b0JpZ0ludGVnZXIoKS5tb2QobCl9d2hpbGUoaS5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKTw9MCk7dmFyIHY9bS5tb2RJbnZlcnNlKGwpLm11bHRpcGx5KHEuYWRkKHQubXVsdGlwbHkoaSkpKS5tb2QobCk7cmV0dXJuIEtKVVIuY3J5cHRvLkVDRFNBLmJpUlNTaWdUb0FTTjFTaWcoaSx2KX07dGhpcy5zaWduPWZ1bmN0aW9uKG0sdSl7dmFyIHE9dTt2YXIgaj10aGlzLmVjcGFyYW1zLm47dmFyIHA9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobSk7ZG97dmFyIGw9dGhpcy5nZXRCaWdSYW5kb20oaik7dmFyIHQ9dGhpcy5lY3BhcmFtcy5HO3ZhciBvPXQubXVsdGlwbHkobCk7dmFyIGk9by5nZXRYKCkudG9CaWdJbnRlZ2VyKCkubW9kKGopfXdoaWxlKGkuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTyk8PTApO3ZhciB2PWwubW9kSW52ZXJzZShqKS5tdWx0aXBseShwLmFkZChxLm11bHRpcGx5KGkpKSkubW9kKGopO3JldHVybiB0aGlzLnNlcmlhbGl6ZVNpZyhpLHYpfTt0aGlzLnZlcmlmeVdpdGhNZXNzYWdlSGFzaD1mdW5jdGlvbihqLGkpe3JldHVybiB0aGlzLnZlcmlmeUhleChqLGksdGhpcy5wdWJLZXlIZXgpfTt0aGlzLnZlcmlmeUhleD1mdW5jdGlvbihtLGkscCl7dmFyIGwsajt2YXIgbz1LSlVSLmNyeXB0by5FQ0RTQS5wYXJzZVNpZ0hleChpKTtsPW8ucjtqPW8uczt2YXIgaztrPUVDUG9pbnRGcC5kZWNvZGVGcm9tSGV4KHRoaXMuZWNwYXJhbXMuY3VydmUscCk7dmFyIG49bmV3IEJpZ0ludGVnZXIobSwxNik7cmV0dXJuIHRoaXMudmVyaWZ5UmF3KG4sbCxqLGspfTt0aGlzLnZlcmlmeT1mdW5jdGlvbihvLHAsail7dmFyIGwsaTtpZihCaXRjb2luLlV0aWwuaXNBcnJheShwKSl7dmFyIG49dGhpcy5wYXJzZVNpZyhwKTtsPW4ucjtpPW4uc31lbHNle2lmKFwib2JqZWN0XCI9PT10eXBlb2YgcCYmcC5yJiZwLnMpe2w9cC5yO2k9cC5zfWVsc2V7dGhyb3dcIkludmFsaWQgdmFsdWUgZm9yIHNpZ25hdHVyZVwifX12YXIgaztpZihqIGluc3RhbmNlb2YgRUNQb2ludEZwKXtrPWp9ZWxzZXtpZihCaXRjb2luLlV0aWwuaXNBcnJheShqKSl7az1FQ1BvaW50RnAuZGVjb2RlRnJvbSh0aGlzLmVjcGFyYW1zLmN1cnZlLGopfWVsc2V7dGhyb3dcIkludmFsaWQgZm9ybWF0IGZvciBwdWJrZXkgdmFsdWUsIG11c3QgYmUgYnl0ZSBhcnJheSBvciBFQ1BvaW50RnBcIn19dmFyIG09QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobyk7cmV0dXJuIHRoaXMudmVyaWZ5UmF3KG0sbCxpLGspfTt0aGlzLnZlcmlmeVJhdz1mdW5jdGlvbihvLGksdyxtKXt2YXIgbD10aGlzLmVjcGFyYW1zLm47dmFyIHU9dGhpcy5lY3BhcmFtcy5HO2lmKGkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKTwwfHxpLmNvbXBhcmVUbyhsKT49MCl7cmV0dXJuIGZhbHNlfWlmKHcuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKTwwfHx3LmNvbXBhcmVUbyhsKT49MCl7cmV0dXJuIGZhbHNlfXZhciBwPXcubW9kSW52ZXJzZShsKTt2YXIgaz1vLm11bHRpcGx5KHApLm1vZChsKTt2YXIgaj1pLm11bHRpcGx5KHApLm1vZChsKTt2YXIgcT11Lm11bHRpcGx5KGspLmFkZChtLm11bHRpcGx5KGopKTt2YXIgdD1xLmdldFgoKS50b0JpZ0ludGVnZXIoKS5tb2QobCk7cmV0dXJuIHQuZXF1YWxzKGkpfTt0aGlzLnNlcmlhbGl6ZVNpZz1mdW5jdGlvbihrLGope3ZhciBsPWsudG9CeXRlQXJyYXlTaWduZWQoKTt2YXIgaT1qLnRvQnl0ZUFycmF5U2lnbmVkKCk7dmFyIG09W107bS5wdXNoKDIpO20ucHVzaChsLmxlbmd0aCk7bT1tLmNvbmNhdChsKTttLnB1c2goMik7bS5wdXNoKGkubGVuZ3RoKTttPW0uY29uY2F0KGkpO20udW5zaGlmdChtLmxlbmd0aCk7bS51bnNoaWZ0KDQ4KTtyZXR1cm4gbX07dGhpcy5wYXJzZVNpZz1mdW5jdGlvbihuKXt2YXIgbTtpZihuWzBdIT00OCl7dGhyb3cgbmV3IEVycm9yKFwiU2lnbmF0dXJlIG5vdCBhIHZhbGlkIERFUlNlcXVlbmNlXCIpfW09MjtpZihuW21dIT0yKXt0aHJvdyBuZXcgRXJyb3IoXCJGaXJzdCBlbGVtZW50IGluIHNpZ25hdHVyZSBtdXN0IGJlIGEgREVSSW50ZWdlclwiKX12YXIgbD1uLnNsaWNlKG0rMixtKzIrblttKzFdKTttKz0yK25bbSsxXTtpZihuW21dIT0yKXt0aHJvdyBuZXcgRXJyb3IoXCJTZWNvbmQgZWxlbWVudCBpbiBzaWduYXR1cmUgbXVzdCBiZSBhIERFUkludGVnZXJcIil9dmFyIGk9bi5zbGljZShtKzIsbSsyK25bbSsxXSk7bSs9MituW20rMV07dmFyIGs9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobCk7dmFyIGo9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQoaSk7cmV0dXJue3I6ayxzOmp9fTt0aGlzLnBhcnNlU2lnQ29tcGFjdD1mdW5jdGlvbihtKXtpZihtLmxlbmd0aCE9PTY1KXt0aHJvd1wiU2lnbmF0dXJlIGhhcyB0aGUgd3JvbmcgbGVuZ3RoXCJ9dmFyIGo9bVswXS0yNztpZihqPDB8fGo+Nyl7dGhyb3dcIkludmFsaWQgc2lnbmF0dXJlIHR5cGVcIn12YXIgbz10aGlzLmVjcGFyYW1zLm47dmFyIGw9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobS5zbGljZSgxLDMzKSkubW9kKG8pO3ZhciBrPUJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkKG0uc2xpY2UoMzMsNjUpKS5tb2Qobyk7cmV0dXJue3I6bCxzOmssaTpqfX07dGhpcy5yZWFkUEtDUzVQcnZLZXlIZXg9ZnVuY3Rpb24obCl7dmFyIG49QVNOMUhFWDt2YXIgbT1LSlVSLmNyeXB0by5FQ0RTQS5nZXROYW1lO3ZhciBwPW4uZ2V0VmJ5TGlzdDtpZihuLmlzQVNOMUhFWChsKT09PWZhbHNlKXt0aHJvd1wibm90IEFTTi4xIGhleCBzdHJpbmdcIn12YXIgaSxrLG87dHJ5e2k9cChsLDAsWzIsMF0sXCIwNlwiKTtrPXAobCwwLFsxXSxcIjA0XCIpO3RyeXtvPXAobCwwLFszLDBdLFwiMDNcIikuc3Vic3RyKDIpfWNhdGNoKGope319Y2F0Y2goail7dGhyb3dcIm1hbGZvcm1lZCBQS0NTIzEvNSBwbGFpbiBFQ0MgcHJpdmF0ZSBrZXlcIn10aGlzLmN1cnZlTmFtZT1tKGkpO2lmKHRoaXMuY3VydmVOYW1lPT09dW5kZWZpbmVkKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZVwifXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7dGhpcy5zZXRQdWJsaWNLZXlIZXgobyk7dGhpcy5zZXRQcml2YXRlS2V5SGV4KGspO3RoaXMuaXNQdWJsaWM9ZmFsc2V9O3RoaXMucmVhZFBLQ1M4UHJ2S2V5SGV4PWZ1bmN0aW9uKGwpe3ZhciBxPUFTTjFIRVg7dmFyIGk9S0pVUi5jcnlwdG8uRUNEU0EuZ2V0TmFtZTt2YXIgbj1xLmdldFZieUxpc3Q7aWYocS5pc0FTTjFIRVgobCk9PT1mYWxzZSl7dGhyb3dcIm5vdCBBU04uMSBoZXggc3RyaW5nXCJ9dmFyIGoscCxtLGs7dHJ5e2o9bihsLDAsWzEsMF0sXCIwNlwiKTtwPW4obCwwLFsxLDFdLFwiMDZcIik7bT1uKGwsMCxbMiwwLDFdLFwiMDRcIik7dHJ5e2s9bihsLDAsWzIsMCwyLDBdLFwiMDNcIikuc3Vic3RyKDIpfWNhdGNoKG8pe319Y2F0Y2gobyl7dGhyb3dcIm1hbGZvcm1lZCBQS0NTIzggcGxhaW4gRUNDIHByaXZhdGUga2V5XCJ9dGhpcy5jdXJ2ZU5hbWU9aShwKTtpZih0aGlzLmN1cnZlTmFtZT09PXVuZGVmaW5lZCl7dGhyb3dcInVuc3VwcG9ydGVkIGN1cnZlIG5hbWVcIn10aGlzLnNldE5hbWVkQ3VydmUodGhpcy5jdXJ2ZU5hbWUpO3RoaXMuc2V0UHVibGljS2V5SGV4KGspO3RoaXMuc2V0UHJpdmF0ZUtleUhleChtKTt0aGlzLmlzUHVibGljPWZhbHNlfTt0aGlzLnJlYWRQS0NTOFB1YktleUhleD1mdW5jdGlvbihsKXt2YXIgbj1BU04xSEVYO3ZhciBtPUtKVVIuY3J5cHRvLkVDRFNBLmdldE5hbWU7dmFyIHA9bi5nZXRWYnlMaXN0O2lmKG4uaXNBU04xSEVYKGwpPT09ZmFsc2Upe3Rocm93XCJub3QgQVNOLjEgaGV4IHN0cmluZ1wifXZhciBrLGksbzt0cnl7az1wKGwsMCxbMCwwXSxcIjA2XCIpO2k9cChsLDAsWzAsMV0sXCIwNlwiKTtvPXAobCwwLFsxXSxcIjAzXCIpLnN1YnN0cigyKX1jYXRjaChqKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1MjOCBFQ0MgcHVibGljIGtleVwifXRoaXMuY3VydmVOYW1lPW0oaSk7aWYodGhpcy5jdXJ2ZU5hbWU9PT1udWxsKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZVwifXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7dGhpcy5zZXRQdWJsaWNLZXlIZXgobyl9O3RoaXMucmVhZENlcnRQdWJLZXlIZXg9ZnVuY3Rpb24oayxwKXtpZihwIT09NSl7cD02fXZhciBtPUFTTjFIRVg7dmFyIGw9S0pVUi5jcnlwdG8uRUNEU0EuZ2V0TmFtZTt2YXIgbz1tLmdldFZieUxpc3Q7aWYobS5pc0FTTjFIRVgoayk9PT1mYWxzZSl7dGhyb3dcIm5vdCBBU04uMSBoZXggc3RyaW5nXCJ9dmFyIGksbjt0cnl7aT1vKGssMCxbMCxwLDAsMV0sXCIwNlwiKTtuPW8oaywwLFswLHAsMV0sXCIwM1wiKS5zdWJzdHIoMil9Y2F0Y2goail7dGhyb3dcIm1hbGZvcm1lZCBYLjUwOSBjZXJ0aWZpY2F0ZSBFQ0MgcHVibGljIGtleVwifXRoaXMuY3VydmVOYW1lPWwoaSk7aWYodGhpcy5jdXJ2ZU5hbWU9PT1udWxsKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZVwifXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7dGhpcy5zZXRQdWJsaWNLZXlIZXgobil9O2lmKGghPT11bmRlZmluZWQpe2lmKGguY3VydmUhPT11bmRlZmluZWQpe3RoaXMuY3VydmVOYW1lPWguY3VydmV9fWlmKHRoaXMuY3VydmVOYW1lPT09dW5kZWZpbmVkKXt0aGlzLmN1cnZlTmFtZT1lfXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7aWYoaCE9PXVuZGVmaW5lZCl7aWYoaC5wcnYhPT11bmRlZmluZWQpe3RoaXMuc2V0UHJpdmF0ZUtleUhleChoLnBydil9aWYoaC5wdWIhPT11bmRlZmluZWQpe3RoaXMuc2V0UHVibGljS2V5SGV4KGgucHViKX19fTtLSlVSLmNyeXB0by5FQ0RTQS5wYXJzZVNpZ0hleD1mdW5jdGlvbihhKXt2YXIgYj1LSlVSLmNyeXB0by5FQ0RTQS5wYXJzZVNpZ0hleEluSGV4UlMoYSk7dmFyIGQ9bmV3IEJpZ0ludGVnZXIoYi5yLDE2KTt2YXIgYz1uZXcgQmlnSW50ZWdlcihiLnMsMTYpO3JldHVybntyOmQsczpjfX07S0pVUi5jcnlwdG8uRUNEU0EucGFyc2VTaWdIZXhJbkhleFJTPWZ1bmN0aW9uKGYpe3ZhciBqPUFTTjFIRVg7dmFyIGk9ai5nZXRDaGlsZElkeDt2YXIgZz1qLmdldFY7aWYoZi5zdWJzdHIoMCwyKSE9XCIzMFwiKXt0aHJvd1wic2lnbmF0dXJlIGlzIG5vdCBhIEFTTi4xIHNlcXVlbmNlXCJ9dmFyIGg9aShmLDApO2lmKGgubGVuZ3RoIT0yKXt0aHJvd1wibnVtYmVyIG9mIHNpZ25hdHVyZSBBU04uMSBzZXF1ZW5jZSBlbGVtZW50cyBzZWVtIHdyb25nXCJ9dmFyIGU9aFswXTt2YXIgZD1oWzFdO2lmKGYuc3Vic3RyKGUsMikhPVwiMDJcIil7dGhyb3dcIjFzdCBpdGVtIG9mIHNlcXVlbmUgb2Ygc2lnbmF0dXJlIGlzIG5vdCBBU04uMSBpbnRlZ2VyXCJ9aWYoZi5zdWJzdHIoZCwyKSE9XCIwMlwiKXt0aHJvd1wiMm5kIGl0ZW0gb2Ygc2VxdWVuZSBvZiBzaWduYXR1cmUgaXMgbm90IEFTTi4xIGludGVnZXJcIn12YXIgYz1nKGYsZSk7dmFyIGI9ZyhmLGQpO3JldHVybntyOmMsczpifX07S0pVUi5jcnlwdG8uRUNEU0EuYXNuMVNpZ1RvQ29uY2F0U2lnPWZ1bmN0aW9uKGMpe3ZhciBkPUtKVVIuY3J5cHRvLkVDRFNBLnBhcnNlU2lnSGV4SW5IZXhSUyhjKTt2YXIgYj1kLnI7dmFyIGE9ZC5zO2lmKGIuc3Vic3RyKDAsMik9PVwiMDBcIiYmKGIubGVuZ3RoJTMyKT09Mil7Yj1iLnN1YnN0cigyKX1pZihhLnN1YnN0cigwLDIpPT1cIjAwXCImJihhLmxlbmd0aCUzMik9PTIpe2E9YS5zdWJzdHIoMil9aWYoKGIubGVuZ3RoJTMyKT09MzApe2I9XCIwMFwiK2J9aWYoKGEubGVuZ3RoJTMyKT09MzApe2E9XCIwMFwiK2F9aWYoYi5sZW5ndGglMzIhPTApe3Rocm93XCJ1bmtub3duIEVDRFNBIHNpZyByIGxlbmd0aCBlcnJvclwifWlmKGEubGVuZ3RoJTMyIT0wKXt0aHJvd1widW5rbm93biBFQ0RTQSBzaWcgcyBsZW5ndGggZXJyb3JcIn1yZXR1cm4gYithfTtLSlVSLmNyeXB0by5FQ0RTQS5jb25jYXRTaWdUb0FTTjFTaWc9ZnVuY3Rpb24oYSl7aWYoKCgoYS5sZW5ndGgvMikqOCklKDE2KjgpKSE9MCl7dGhyb3dcInVua25vd24gRUNEU0EgY29uY2F0aW5hdGVkIHItcyBzaWcgIGxlbmd0aCBlcnJvclwifXZhciBjPWEuc3Vic3RyKDAsYS5sZW5ndGgvMik7dmFyIGI9YS5zdWJzdHIoYS5sZW5ndGgvMik7cmV0dXJuIEtKVVIuY3J5cHRvLkVDRFNBLmhleFJTU2lnVG9BU04xU2lnKGMsYil9O0tKVVIuY3J5cHRvLkVDRFNBLmhleFJTU2lnVG9BU04xU2lnPWZ1bmN0aW9uKGIsYSl7dmFyIGQ9bmV3IEJpZ0ludGVnZXIoYiwxNik7dmFyIGM9bmV3IEJpZ0ludGVnZXIoYSwxNik7cmV0dXJuIEtKVVIuY3J5cHRvLkVDRFNBLmJpUlNTaWdUb0FTTjFTaWcoZCxjKX07S0pVUi5jcnlwdG8uRUNEU0EuYmlSU1NpZ1RvQVNOMVNpZz1mdW5jdGlvbihmLGQpe3ZhciBjPUtKVVIuYXNuMTt2YXIgYj1uZXcgYy5ERVJJbnRlZ2VyKHtiaWdpbnQ6Zn0pO3ZhciBhPW5ldyBjLkRFUkludGVnZXIoe2JpZ2ludDpkfSk7dmFyIGU9bmV3IGMuREVSU2VxdWVuY2Uoe2FycmF5OltiLGFdfSk7cmV0dXJuIGUuZ2V0RW5jb2RlZEhleCgpfTtLSlVSLmNyeXB0by5FQ0RTQS5nZXROYW1lPWZ1bmN0aW9uKGEpe2lmKGE9PT1cIjJhODY0OGNlM2QwMzAxMDdcIil7cmV0dXJuXCJzZWNwMjU2cjFcIn1pZihhPT09XCIyYjgxMDQwMDBhXCIpe3JldHVyblwic2VjcDI1NmsxXCJ9aWYoYT09PVwiMmI4MTA0MDAyMlwiKXtyZXR1cm5cInNlY3AzODRyMVwifWlmKFwifHNlY3AyNTZyMXxOSVNUIFAtMjU2fFAtMjU2fHByaW1lMjU2djF8XCIuaW5kZXhPZihhKSE9PS0xKXtyZXR1cm5cInNlY3AyNTZyMVwifWlmKFwifHNlY3AyNTZrMXxcIi5pbmRleE9mKGEpIT09LTEpe3JldHVyblwic2VjcDI1NmsxXCJ9aWYoXCJ8c2VjcDM4NHIxfE5JU1QgUC0zODR8UC0zODR8XCIuaW5kZXhPZihhKSE9PS0xKXtyZXR1cm5cInNlY3AzODRyMVwifXJldHVybiBudWxsfTtcbmlmKHR5cGVvZiBLSlVSPT1cInVuZGVmaW5lZFwifHwhS0pVUil7S0pVUj17fX1pZih0eXBlb2YgS0pVUi5jcnlwdG89PVwidW5kZWZpbmVkXCJ8fCFLSlVSLmNyeXB0byl7S0pVUi5jcnlwdG89e319S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQj1uZXcgZnVuY3Rpb24oKXt2YXIgYj17fTt2YXIgYz17fTtmdW5jdGlvbiBhKGQpe3JldHVybiBuZXcgQmlnSW50ZWdlcihkLDE2KX10aGlzLmdldEJ5TmFtZT1mdW5jdGlvbihlKXt2YXIgZD1lO2lmKHR5cGVvZiBjW2RdIT1cInVuZGVmaW5lZFwiKXtkPWNbZV19aWYodHlwZW9mIGJbZF0hPVwidW5kZWZpbmVkXCIpe3JldHVybiBiW2RdfXRocm93XCJ1bnJlZ2lzdGVyZWQgRUMgY3VydmUgbmFtZTogXCIrZH07dGhpcy5yZWdpc3Q9ZnVuY3Rpb24oQSxsLG8sZyxtLGUsaixmLGssdSxkLHgpe2JbQV09e307dmFyIHM9YShvKTt2YXIgej1hKGcpO3ZhciB5PWEobSk7dmFyIHQ9YShlKTt2YXIgdz1hKGopO3ZhciByPW5ldyBFQ0N1cnZlRnAocyx6LHkpO3ZhciBxPXIuZGVjb2RlUG9pbnRIZXgoXCIwNFwiK2Yrayk7YltBXVtcIm5hbWVcIl09QTtiW0FdW1wia2V5bGVuXCJdPWw7YltBXVtcImN1cnZlXCJdPXI7YltBXVtcIkdcIl09cTtiW0FdW1wiblwiXT10O2JbQV1bXCJoXCJdPXc7YltBXVtcIm9pZFwiXT1kO2JbQV1bXCJpbmZvXCJdPXg7Zm9yKHZhciB2PTA7djx1Lmxlbmd0aDt2Kyspe2NbdVt2XV09QX19fTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AxMjhyMVwiLDEyOCxcIkZGRkZGRkZERkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGXCIsXCJGRkZGRkZGREZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQ1wiLFwiRTg3NTc5QzExMDc5RjQzREQ4MjQ5OTNDMkNFRTVFRDNcIixcIkZGRkZGRkZFMDAwMDAwMDA3NUEzMEQxQjkwMzhBMTE1XCIsXCIxXCIsXCIxNjFGRjc1MjhCODk5QjJEMEMyODYwN0NBNTJDNUI4NlwiLFwiQ0Y1QUM4Mzk1QkFGRUIxM0MwMkRBMjkyRERFRDdBODNcIixbXSxcIlwiLFwic2VjcDEyOHIxIDogU0VDRyBjdXJ2ZSBvdmVyIGEgMTI4IGJpdCBwcmltZSBmaWVsZFwiKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AxNjBrMVwiLDE2MCxcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkFDNzNcIixcIjBcIixcIjdcIixcIjAxMDAwMDAwMDAwMDAwMDAwMDAwMDFCOEZBMTZERkFCOUFDQTE2QjZCM1wiLFwiMVwiLFwiM0I0QzM4MkNFMzdBQTE5MkE0MDE5RTc2MzAzNkY0RjVERDREN0VCQlwiLFwiOTM4Q0Y5MzUzMThGRENFRDZCQzI4Mjg2NTMxNzMzQzNGMDNDNEZFRVwiLFtdLFwiXCIsXCJzZWNwMTYwazEgOiBTRUNHIGN1cnZlIG92ZXIgYSAxNjAgYml0IHByaW1lIGZpZWxkXCIpO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDE2MHIxXCIsMTYwLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY3RkZGRkZGRlwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY3RkZGRkZGQ1wiLFwiMUM5N0JFRkM1NEJEN0E4QjY1QUNGODlGODFENEQ0QURDNTY1RkE0NVwiLFwiMDEwMDAwMDAwMDAwMDAwMDAwMDAwMUY0QzhGOTI3QUVEM0NBNzUyMjU3XCIsXCIxXCIsXCI0QTk2QjU2ODhFRjU3MzI4NDY2NDY5ODk2OEMzOEJCOTEzQ0JGQzgyXCIsXCIyM0E2Mjg1NTMxNjg5NDdENTlEQ0M5MTIwNDIzNTEzNzdBQzVGQjMyXCIsW10sXCJcIixcInNlY3AxNjByMSA6IFNFQ0cgY3VydmUgb3ZlciBhIDE2MCBiaXQgcHJpbWUgZmllbGRcIik7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMTkyazFcIiwxOTIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkVFMzdcIixcIjBcIixcIjNcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRTI2RjJGQzE3MEY2OTQ2NkE3NERFRkQ4RFwiLFwiMVwiLFwiREI0RkYxMEVDMDU3RTlBRTI2QjA3RDAyODBCN0Y0MzQxREE1RDFCMUVBRTA2QzdEXCIsXCI5QjJGMkY2RDlDNTYyOEE3ODQ0MTYzRDAxNUJFODYzNDQwODJBQTg4RDk1RTJGOURcIixbXSk7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMTkycjFcIiwxOTIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGRkZGRkZGRkZcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkZGRkZGRkZGQ1wiLFwiNjQyMTA1MTlFNTlDODBFNzBGQTdFOUFCNzIyNDMwNDlGRUI4REVFQ0MxNDZCOUIxXCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY5OURFRjgzNjE0NkJDOUIxQjREMjI4MzFcIixcIjFcIixcIjE4OERBODBFQjAzMDkwRjY3Q0JGMjBFQjQzQTE4ODAwRjRGRjBBRkQ4MkZGMTAxMlwiLFwiMDcxOTJCOTVGRkM4REE3ODYzMTAxMUVENkIyNENERDU3M0Y5NzdBMTFFNzk0ODExXCIsW10pO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDIyNHIxXCIsMjI0LFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkYwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFXCIsXCJCNDA1MEE4NTBDMDRCM0FCRjU0MTMyNTY1MDQ0QjBCN0Q3QkZEOEJBMjcwQjM5NDMyMzU1RkZCNFwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRjE2QTJFMEI4RjAzRTEzREQyOTQ1NUM1QzJBM0RcIixcIjFcIixcIkI3MEUwQ0JENkJCNEJGN0YzMjEzOTBCOTRBMDNDMUQzNTZDMjExMjIzNDMyODBENjExNUMxRDIxXCIsXCJCRDM3NjM4OEI1RjcyM0ZCNEMyMkRGRTZDRDQzNzVBMDVBMDc0NzY0NDRENTgxOTk4NTAwN0UzNFwiLFtdKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AyNTZrMVwiLDI1NixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZDMkZcIixcIjBcIixcIjdcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFQkFBRURDRTZBRjQ4QTAzQkJGRDI1RThDRDAzNjQxNDFcIixcIjFcIixcIjc5QkU2NjdFRjlEQ0JCQUM1NUEwNjI5NUNFODcwQjA3MDI5QkZDREIyRENFMjhEOTU5RjI4MTVCMTZGODE3OThcIixcIjQ4M0FEQTc3MjZBM0M0NjU1REE0RkJGQzBFMTEwOEE4RkQxN0I0NDhBNjg1NTQxOTlDNDdEMDhGRkIxMEQ0QjhcIixbXSk7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMjU2cjFcIiwyNTYsXCJGRkZGRkZGRjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGXCIsXCJGRkZGRkZGRjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZDXCIsXCI1QUM2MzVEOEFBM0E5M0U3QjNFQkJENTU3Njk4ODZCQzY1MUQwNkIwQ0M1M0IwRjYzQkNFM0MzRTI3RDI2MDRCXCIsXCJGRkZGRkZGRjAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkJDRTZGQUFEQTcxNzlFODRGM0I5Q0FDMkZDNjMyNTUxXCIsXCIxXCIsXCI2QjE3RDFGMkUxMkM0MjQ3RjhCQ0U2RTU2M0E0NDBGMjc3MDM3RDgxMkRFQjMzQTBGNEExMzk0NUQ4OThDMjk2XCIsXCI0RkUzNDJFMkZFMUE3RjlCOEVFN0VCNEE3QzBGOUUxNjJCQ0UzMzU3NkIzMTVFQ0VDQkI2NDA2ODM3QkY1MUY1XCIsW1wiTklTVCBQLTI1NlwiLFwiUC0yNTZcIixcInByaW1lMjU2djFcIl0pO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDM4NHIxXCIsMzg0LFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGMDAwMDAwMDAwMDAwMDAwMEZGRkZGRkZGXCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkYwMDAwMDAwMDAwMDAwMDAwRkZGRkZGRkNcIixcIkIzMzEyRkE3RTIzRUU3RTQ5ODhFMDU2QkUzRjgyRDE5MTgxRDlDNkVGRTgxNDExMjAzMTQwODhGNTAxMzg3NUFDNjU2Mzk4RDhBMkVEMTlEMkE4NUM4RUREM0VDMkFFRlwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQzc2MzREODFGNDM3MkRERjU4MUEwREIyNDhCMEE3N0FFQ0VDMTk2QUNDQzUyOTczXCIsXCIxXCIsXCJBQTg3Q0EyMkJFOEIwNTM3OEVCMUM3MUVGMzIwQUQ3NDZFMUQzQjYyOEJBNzlCOTg1OUY3NDFFMDgyNTQyQTM4NTUwMkYyNURCRjU1Mjk2QzNBNTQ1RTM4NzI3NjBBQjdcIixcIjM2MTdkZTRhOTYyNjJjNmY1ZDllOThiZjkyOTJkYzI5ZjhmNDFkYmQyODlhMTQ3Y2U5ZGEzMTEzYjVmMGI4YzAwYTYwYjFjZTFkN2U4MTlkN2E0MzFkN2M5MGVhMGU1ZlwiLFtcIk5JU1QgUC0zODRcIixcIlAtMzg0XCJdKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3A1MjFyMVwiLDUyMSxcIjFGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGXCIsXCIxRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQ1wiLFwiMDUxOTUzRUI5NjE4RTFDOUExRjkyOUEyMUEwQjY4NTQwRUVBMkRBNzI1Qjk5QjMxNUYzQjhCNDg5OTE4RUYxMDlFMTU2MTkzOTUxRUM3RTkzN0IxNjUyQzBCRDNCQjFCRjA3MzU3M0RGODgzRDJDMzRGMUVGNDUxRkQ0NkI1MDNGMDBcIixcIjFGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkE1MTg2ODc4M0JGMkY5NjZCN0ZDQzAxNDhGNzA5QTVEMDNCQjVDOUI4ODk5QzQ3QUVCQjZGQjcxRTkxMzg2NDA5XCIsXCIxXCIsXCJDNjg1OEUwNkI3MDQwNEU5Q0Q5RTNFQ0I2NjIzOTVCNDQyOUM2NDgxMzkwNTNGQjUyMUY4MjhBRjYwNkI0RDNEQkFBMTRCNUU3N0VGRTc1OTI4RkUxREMxMjdBMkZGQThERTMzNDhCM0MxODU2QTQyOUJGOTdFN0UzMUMyRTVCRDY2XCIsXCIwMTE4MzkyOTZhNzg5YTNiYzAwNDVjOGE1ZmI0MmM3ZDFiZDk5OGY1NDQ0OTU3OWI0NDY4MTdhZmJkMTcyNzNlNjYyYzk3ZWU3Mjk5NWVmNDI2NDBjNTUwYjkwMTNmYWQwNzYxMzUzYzcwODZhMjcyYzI0MDg4YmU5NDc2OWZkMTY2NTBcIixbXCJOSVNUIFAtNTIxXCIsXCJQLTUyMVwiXSk7XG52YXIgS0VZVVRJTD1mdW5jdGlvbigpe3ZhciBkPWZ1bmN0aW9uKHAscixxKXtyZXR1cm4gayhDcnlwdG9KUy5BRVMscCxyLHEpfTt2YXIgZT1mdW5jdGlvbihwLHIscSl7cmV0dXJuIGsoQ3J5cHRvSlMuVHJpcGxlREVTLHAscixxKX07dmFyIGE9ZnVuY3Rpb24ocCxyLHEpe3JldHVybiBrKENyeXB0b0pTLkRFUyxwLHIscSl9O3ZhciBrPWZ1bmN0aW9uKHMseCx1LHEpe3ZhciByPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoeCk7dmFyIHc9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh1KTt2YXIgcD1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHEpO3ZhciB0PXt9O3Qua2V5PXc7dC5pdj1wO3QuY2lwaGVydGV4dD1yO3ZhciB2PXMuZGVjcnlwdCh0LHcse2l2OnB9KTtyZXR1cm4gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkodil9O3ZhciBsPWZ1bmN0aW9uKHAscixxKXtyZXR1cm4gZyhDcnlwdG9KUy5BRVMscCxyLHEpfTt2YXIgbz1mdW5jdGlvbihwLHIscSl7cmV0dXJuIGcoQ3J5cHRvSlMuVHJpcGxlREVTLHAscixxKX07dmFyIGY9ZnVuY3Rpb24ocCxyLHEpe3JldHVybiBnKENyeXB0b0pTLkRFUyxwLHIscSl9O3ZhciBnPWZ1bmN0aW9uKHQseSx2LHEpe3ZhciBzPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoeSk7dmFyIHg9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh2KTt2YXIgcD1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHEpO3ZhciB3PXQuZW5jcnlwdChzLHgse2l2OnB9KTt2YXIgcj1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHcudG9TdHJpbmcoKSk7dmFyIHU9Q3J5cHRvSlMuZW5jLkJhc2U2NC5zdHJpbmdpZnkocik7cmV0dXJuIHV9O3ZhciBpPXtcIkFFUy0yNTYtQ0JDXCI6e3Byb2M6ZCxlcHJvYzpsLGtleWxlbjozMixpdmxlbjoxNn0sXCJBRVMtMTkyLUNCQ1wiOntwcm9jOmQsZXByb2M6bCxrZXlsZW46MjQsaXZsZW46MTZ9LFwiQUVTLTEyOC1DQkNcIjp7cHJvYzpkLGVwcm9jOmwsa2V5bGVuOjE2LGl2bGVuOjE2fSxcIkRFUy1FREUzLUNCQ1wiOntwcm9jOmUsZXByb2M6byxrZXlsZW46MjQsaXZsZW46OH0sXCJERVMtQ0JDXCI6e3Byb2M6YSxlcHJvYzpmLGtleWxlbjo4LGl2bGVuOjh9fTt2YXIgYz1mdW5jdGlvbihwKXtyZXR1cm4gaVtwXVtcInByb2NcIl19O3ZhciBtPWZ1bmN0aW9uKHApe3ZhciByPUNyeXB0b0pTLmxpYi5Xb3JkQXJyYXkucmFuZG9tKHApO3ZhciBxPUNyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHIpO3JldHVybiBxfTt2YXIgbj1mdW5jdGlvbih2KXt2YXIgdz17fTt2YXIgcT12Lm1hdGNoKG5ldyBSZWdFeHAoXCJERUstSW5mbzogKFteLF0rKSwoWzAtOUEtRmEtZl0rKVwiLFwibVwiKSk7aWYocSl7dy5jaXBoZXI9cVsxXTt3Lml2c2FsdD1xWzJdfXZhciBwPXYubWF0Y2gobmV3IFJlZ0V4cChcIi0tLS0tQkVHSU4gKFtBLVpdKykgUFJJVkFURSBLRVktLS0tLVwiKSk7aWYocCl7dy50eXBlPXBbMV19dmFyIHU9LTE7dmFyIHg9MDtpZih2LmluZGV4T2YoXCJcXHJcXG5cXHJcXG5cIikhPS0xKXt1PXYuaW5kZXhPZihcIlxcclxcblxcclxcblwiKTt4PTJ9aWYodi5pbmRleE9mKFwiXFxuXFxuXCIpIT0tMSl7dT12LmluZGV4T2YoXCJcXG5cXG5cIik7eD0xfXZhciB0PXYuaW5kZXhPZihcIi0tLS0tRU5EXCIpO2lmKHUhPS0xJiZ0IT0tMSl7dmFyIHI9di5zdWJzdHJpbmcodSt4KjIsdC14KTtyPXIucmVwbGFjZSgvXFxzKy9nLFwiXCIpO3cuZGF0YT1yfXJldHVybiB3fTt2YXIgaj1mdW5jdGlvbihxLHkscCl7dmFyIHY9cC5zdWJzdHJpbmcoMCwxNik7dmFyIHQ9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh2KTt2YXIgcj1DcnlwdG9KUy5lbmMuVXRmOC5wYXJzZSh5KTt2YXIgdT1pW3FdW1wia2V5bGVuXCJdK2lbcV1bXCJpdmxlblwiXTt2YXIgeD1cIlwiO3ZhciB3PW51bGw7Zm9yKDs7KXt2YXIgcz1DcnlwdG9KUy5hbGdvLk1ENS5jcmVhdGUoKTtpZih3IT1udWxsKXtzLnVwZGF0ZSh3KX1zLnVwZGF0ZShyKTtzLnVwZGF0ZSh0KTt3PXMuZmluYWxpemUoKTt4PXgrQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkodyk7aWYoeC5sZW5ndGg+PXUqMil7YnJlYWt9fXZhciB6PXt9O3oua2V5aGV4PXguc3Vic3RyKDAsaVtxXVtcImtleWxlblwiXSoyKTt6Lml2aGV4PXguc3Vic3RyKGlbcV1bXCJrZXlsZW5cIl0qMixpW3FdW1wiaXZsZW5cIl0qMik7cmV0dXJuIHp9O3ZhciBiPWZ1bmN0aW9uKHAsdixyLHcpe3ZhciBzPUNyeXB0b0pTLmVuYy5CYXNlNjQucGFyc2UocCk7dmFyIHE9Q3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkocyk7dmFyIHU9aVt2XVtcInByb2NcIl07dmFyIHQ9dShxLHIsdyk7cmV0dXJuIHR9O3ZhciBoPWZ1bmN0aW9uKHAscyxxLHUpe3ZhciByPWlbc11bXCJlcHJvY1wiXTt2YXIgdD1yKHAscSx1KTtyZXR1cm4gdH07cmV0dXJue3ZlcnNpb246XCIxLjAuMFwiLHBhcnNlUEtDUzVQRU06ZnVuY3Rpb24ocCl7cmV0dXJuIG4ocCl9LGdldEtleUFuZFVudXNlZEl2QnlQYXNzY29kZUFuZEl2c2FsdDpmdW5jdGlvbihxLHAscil7cmV0dXJuIGoocSxwLHIpfSxkZWNyeXB0S2V5QjY0OmZ1bmN0aW9uKHAscixxLHMpe3JldHVybiBiKHAscixxLHMpfSxnZXREZWNyeXB0ZWRLZXlIZXg6ZnVuY3Rpb24oeSx4KXt2YXIgcT1uKHkpO3ZhciB0PXEudHlwZTt2YXIgcj1xLmNpcGhlcjt2YXIgcD1xLml2c2FsdDt2YXIgcz1xLmRhdGE7dmFyIHc9aihyLHgscCk7dmFyIHY9dy5rZXloZXg7dmFyIHU9YihzLHIsdixwKTtyZXR1cm4gdX0sZ2V0RW5jcnlwdGVkUEtDUzVQRU1Gcm9tUHJ2S2V5SGV4OmZ1bmN0aW9uKHgscyxBLHQscil7dmFyIHA9XCJcIjtpZih0eXBlb2YgdD09XCJ1bmRlZmluZWRcInx8dD09bnVsbCl7dD1cIkFFUy0yNTYtQ0JDXCJ9aWYodHlwZW9mIGlbdF09PVwidW5kZWZpbmVkXCIpe3Rocm93XCJLRVlVVElMIHVuc3VwcG9ydGVkIGFsZ29yaXRobTogXCIrdH1pZih0eXBlb2Ygcj09XCJ1bmRlZmluZWRcInx8cj09bnVsbCl7dmFyIHY9aVt0XVtcIml2bGVuXCJdO3ZhciB1PW0odik7cj11LnRvVXBwZXJDYXNlKCl9dmFyIHo9aih0LEEscik7dmFyIHk9ei5rZXloZXg7dmFyIHc9aChzLHQseSxyKTt2YXIgcT13LnJlcGxhY2UoLyguezY0fSkvZyxcIiQxXFxyXFxuXCIpO3ZhciBwPVwiLS0tLS1CRUdJTiBcIit4K1wiIFBSSVZBVEUgS0VZLS0tLS1cXHJcXG5cIjtwKz1cIlByb2MtVHlwZTogNCxFTkNSWVBURURcXHJcXG5cIjtwKz1cIkRFSy1JbmZvOiBcIit0K1wiLFwiK3IrXCJcXHJcXG5cIjtwKz1cIlxcclxcblwiO3ArPXE7cCs9XCJcXHJcXG4tLS0tLUVORCBcIit4K1wiIFBSSVZBVEUgS0VZLS0tLS1cXHJcXG5cIjtyZXR1cm4gcH0scGFyc2VIZXhPZkVuY3J5cHRlZFBLQ1M4OmZ1bmN0aW9uKHkpe3ZhciBCPUFTTjFIRVg7dmFyIHo9Qi5nZXRDaGlsZElkeDt2YXIgdz1CLmdldFY7dmFyIHQ9e307dmFyIHI9eih5LDApO2lmKHIubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIGZvcm1hdDogU0VRVUVOQ0UoMCkuaXRlbXMgIT0gMjogXCIrci5sZW5ndGh9dC5jaXBoZXJ0ZXh0PXcoeSxyWzFdKTt2YXIgQT16KHksclswXSk7aWYoQS5sZW5ndGghPTIpe3Rocm93XCJtYWxmb3JtZWQgZm9ybWF0OiBTRVFVRU5DRSgwLjApLml0ZW1zICE9IDI6IFwiK0EubGVuZ3RofWlmKHcoeSxBWzBdKSE9XCIyYTg2NDg4NmY3MGQwMTA1MGRcIil7dGhyb3dcInRoaXMgb25seSBzdXBwb3J0cyBwa2NzNVBCRVMyXCJ9dmFyIHA9eih5LEFbMV0pO2lmKEEubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIGZvcm1hdDogU0VRVUVOQ0UoMC4wLjEpLml0ZW1zICE9IDI6IFwiK3AubGVuZ3RofXZhciBxPXooeSxwWzFdKTtpZihxLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQ6IFNFUVVFTkNFKDAuMC4xLjEpLml0ZW1zICE9IDI6IFwiK3EubGVuZ3RofWlmKHcoeSxxWzBdKSE9XCIyYTg2NDg4NmY3MGQwMzA3XCIpe3Rocm93XCJ0aGlzIG9ubHkgc3VwcG9ydHMgVHJpcGxlREVTXCJ9dC5lbmNyeXB0aW9uU2NoZW1lQWxnPVwiVHJpcGxlREVTXCI7dC5lbmNyeXB0aW9uU2NoZW1lSVY9dyh5LHFbMV0pO3ZhciBzPXooeSxwWzBdKTtpZihzLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQ6IFNFUVVFTkNFKDAuMC4xLjApLml0ZW1zICE9IDI6IFwiK3MubGVuZ3RofWlmKHcoeSxzWzBdKSE9XCIyYTg2NDg4NmY3MGQwMTA1MGNcIil7dGhyb3dcInRoaXMgb25seSBzdXBwb3J0cyBwa2NzNVBCS0RGMlwifXZhciB4PXooeSxzWzFdKTtpZih4Lmxlbmd0aDwyKXt0aHJvd1wibWFsZm9ybWVkIGZvcm1hdDogU0VRVUVOQ0UoMC4wLjEuMC4xKS5pdGVtcyA8IDI6IFwiK3gubGVuZ3RofXQucGJrZGYyU2FsdD13KHkseFswXSk7dmFyIHU9dyh5LHhbMV0pO3RyeXt0LnBia2RmMkl0ZXI9cGFyc2VJbnQodSwxNil9Y2F0Y2godil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQgcGJrZGYySXRlcjogXCIrdX1yZXR1cm4gdH0sZ2V0UEJLREYyS2V5SGV4RnJvbVBhcmFtOmZ1bmN0aW9uKHUscCl7dmFyIHQ9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh1LnBia2RmMlNhbHQpO3ZhciBxPXUucGJrZGYySXRlcjt2YXIgcz1DcnlwdG9KUy5QQktERjIocCx0LHtrZXlTaXplOjE5Mi8zMixpdGVyYXRpb25zOnF9KTt2YXIgcj1DcnlwdG9KUy5lbmMuSGV4LnN0cmluZ2lmeShzKTtyZXR1cm4gcn0sX2dldFBsYWluUEtDUzhIZXhGcm9tRW5jcnlwdGVkUEtDUzhQRU06ZnVuY3Rpb24oeCx5KXt2YXIgcj1wZW10b2hleCh4LFwiRU5DUllQVEVEIFBSSVZBVEUgS0VZXCIpO3ZhciBwPXRoaXMucGFyc2VIZXhPZkVuY3J5cHRlZFBLQ1M4KHIpO3ZhciB1PUtFWVVUSUwuZ2V0UEJLREYyS2V5SGV4RnJvbVBhcmFtKHAseSk7dmFyIHY9e307di5jaXBoZXJ0ZXh0PUNyeXB0b0pTLmVuYy5IZXgucGFyc2UocC5jaXBoZXJ0ZXh0KTt2YXIgdD1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHUpO3ZhciBzPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UocC5lbmNyeXB0aW9uU2NoZW1lSVYpO3ZhciB3PUNyeXB0b0pTLlRyaXBsZURFUy5kZWNyeXB0KHYsdCx7aXY6c30pO3ZhciBxPUNyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHcpO3JldHVybiBxfSxnZXRLZXlGcm9tRW5jcnlwdGVkUEtDUzhQRU06ZnVuY3Rpb24ocyxxKXt2YXIgcD10aGlzLl9nZXRQbGFpblBLQ1M4SGV4RnJvbUVuY3J5cHRlZFBLQ1M4UEVNKHMscSk7dmFyIHI9dGhpcy5nZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhIZXgocCk7cmV0dXJuIHJ9LHBhcnNlUGxhaW5Qcml2YXRlUEtDUzhIZXg6ZnVuY3Rpb24ocyl7dmFyIHY9QVNOMUhFWDt2YXIgdT12LmdldENoaWxkSWR4O3ZhciB0PXYuZ2V0Vjt2YXIgcT17fTtxLmFsZ3BhcmFtPW51bGw7aWYocy5zdWJzdHIoMCwyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIHBsYWluIFBLQ1M4IHByaXZhdGUga2V5KGNvZGU6MDAxKVwifXZhciByPXUocywwKTtpZihyLmxlbmd0aCE9Myl7dGhyb3dcIm1hbGZvcm1lZCBwbGFpbiBQS0NTOCBwcml2YXRlIGtleShjb2RlOjAwMilcIn1pZihzLnN1YnN0cihyWzFdLDIpIT1cIjMwXCIpe3Rocm93XCJtYWxmb3JtZWQgUEtDUzggcHJpdmF0ZSBrZXkoY29kZTowMDMpXCJ9dmFyIHA9dShzLHJbMV0pO2lmKHAubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHByaXZhdGUga2V5KGNvZGU6MDA0KVwifWlmKHMuc3Vic3RyKHBbMF0sMikhPVwiMDZcIil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwcml2YXRlIGtleShjb2RlOjAwNSlcIn1xLmFsZ29pZD10KHMscFswXSk7aWYocy5zdWJzdHIocFsxXSwyKT09XCIwNlwiKXtxLmFsZ3BhcmFtPXQocyxwWzFdKX1pZihzLnN1YnN0cihyWzJdLDIpIT1cIjA0XCIpe3Rocm93XCJtYWxmb3JtZWQgUEtDUzggcHJpdmF0ZSBrZXkoY29kZTowMDYpXCJ9cS5rZXlpZHg9di5nZXRWaWR4KHMsclsyXSk7cmV0dXJuIHF9LGdldEtleUZyb21QbGFpblByaXZhdGVQS0NTOFBFTTpmdW5jdGlvbihxKXt2YXIgcD1wZW10b2hleChxLFwiUFJJVkFURSBLRVlcIik7dmFyIHI9dGhpcy5nZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhIZXgocCk7cmV0dXJuIHJ9LGdldEtleUZyb21QbGFpblByaXZhdGVQS0NTOEhleDpmdW5jdGlvbihwKXt2YXIgcT10aGlzLnBhcnNlUGxhaW5Qcml2YXRlUEtDUzhIZXgocCk7dmFyIHI7aWYocS5hbGdvaWQ9PVwiMmE4NjQ4ODZmNzBkMDEwMTAxXCIpe3I9bmV3IFJTQUtleSgpfWVsc2V7aWYocS5hbGdvaWQ9PVwiMmE4NjQ4Y2UzODA0MDFcIil7cj1uZXcgS0pVUi5jcnlwdG8uRFNBKCl9ZWxzZXtpZihxLmFsZ29pZD09XCIyYTg2NDhjZTNkMDIwMVwiKXtyPW5ldyBLSlVSLmNyeXB0by5FQ0RTQSgpfWVsc2V7dGhyb3dcInVuc3VwcG9ydGVkIHByaXZhdGUga2V5IGFsZ29yaXRobVwifX19ci5yZWFkUEtDUzhQcnZLZXlIZXgocCk7cmV0dXJuIHJ9LF9nZXRLZXlGcm9tUHVibGljUEtDUzhIZXg6ZnVuY3Rpb24ocSl7dmFyIHA7dmFyIHI9QVNOMUhFWC5nZXRWYnlMaXN0KHEsMCxbMCwwXSxcIjA2XCIpO2lmKHI9PT1cIjJhODY0ODg2ZjcwZDAxMDEwMVwiKXtwPW5ldyBSU0FLZXkoKX1lbHNle2lmKHI9PT1cIjJhODY0OGNlMzgwNDAxXCIpe3A9bmV3IEtKVVIuY3J5cHRvLkRTQSgpfWVsc2V7aWYocj09PVwiMmE4NjQ4Y2UzZDAyMDFcIil7cD1uZXcgS0pVUi5jcnlwdG8uRUNEU0EoKX1lbHNle3Rocm93XCJ1bnN1cHBvcnRlZCBQS0NTIzggcHVibGljIGtleSBoZXhcIn19fXAucmVhZFBLQ1M4UHViS2V5SGV4KHEpO3JldHVybiBwfSxwYXJzZVB1YmxpY1Jhd1JTQUtleUhleDpmdW5jdGlvbihyKXt2YXIgdT1BU04xSEVYO3ZhciB0PXUuZ2V0Q2hpbGRJZHg7dmFyIHM9dS5nZXRWO3ZhciBwPXt9O2lmKHIuc3Vic3RyKDAsMikhPVwiMzBcIil7dGhyb3dcIm1hbGZvcm1lZCBSU0Ega2V5KGNvZGU6MDAxKVwifXZhciBxPXQociwwKTtpZihxLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBSU0Ega2V5KGNvZGU6MDAyKVwifWlmKHIuc3Vic3RyKHFbMF0sMikhPVwiMDJcIil7dGhyb3dcIm1hbGZvcm1lZCBSU0Ega2V5KGNvZGU6MDAzKVwifXAubj1zKHIscVswXSk7aWYoci5zdWJzdHIocVsxXSwyKSE9XCIwMlwiKXt0aHJvd1wibWFsZm9ybWVkIFJTQSBrZXkoY29kZTowMDQpXCJ9cC5lPXMocixxWzFdKTtyZXR1cm4gcH0scGFyc2VQdWJsaWNQS0NTOEhleDpmdW5jdGlvbih0KXt2YXIgdj1BU04xSEVYO3ZhciB1PXYuZ2V0Q2hpbGRJZHg7dmFyIHM9di5nZXRWO3ZhciBxPXt9O3EuYWxncGFyYW09bnVsbDt2YXIgcj11KHQsMCk7aWYoci5sZW5ndGghPTIpe3Rocm93XCJvdXRlciBERVJTZXF1ZW5jZSBzaGFsbCBoYXZlIDIgZWxlbWVudHM6IFwiK3IubGVuZ3RofXZhciB3PXJbMF07aWYodC5zdWJzdHIodywyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHB1YmxpYyBrZXkoY29kZTowMDEpXCJ9dmFyIHA9dSh0LHcpO2lmKHAubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHB1YmxpYyBrZXkoY29kZTowMDIpXCJ9aWYodC5zdWJzdHIocFswXSwyKSE9XCIwNlwiKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHB1YmxpYyBrZXkoY29kZTowMDMpXCJ9cS5hbGdvaWQ9cyh0LHBbMF0pO2lmKHQuc3Vic3RyKHBbMV0sMik9PVwiMDZcIil7cS5hbGdwYXJhbT1zKHQscFsxXSl9ZWxzZXtpZih0LnN1YnN0cihwWzFdLDIpPT1cIjMwXCIpe3EuYWxncGFyYW09e307cS5hbGdwYXJhbS5wPXYuZ2V0VmJ5TGlzdCh0LHBbMV0sWzBdLFwiMDJcIik7cS5hbGdwYXJhbS5xPXYuZ2V0VmJ5TGlzdCh0LHBbMV0sWzFdLFwiMDJcIik7cS5hbGdwYXJhbS5nPXYuZ2V0VmJ5TGlzdCh0LHBbMV0sWzJdLFwiMDJcIil9fWlmKHQuc3Vic3RyKHJbMV0sMikhPVwiMDNcIil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwdWJsaWMga2V5KGNvZGU6MDA0KVwifXEua2V5PXModCxyWzFdKS5zdWJzdHIoMik7cmV0dXJuIHF9LH19KCk7S0VZVVRJTC5nZXRLZXk9ZnVuY3Rpb24obCxrLG4pe3ZhciBHPUFTTjFIRVgsTD1HLmdldENoaWxkSWR4LHY9Ry5nZXRWLGQ9Ry5nZXRWYnlMaXN0LGM9S0pVUi5jcnlwdG8saT1jLkVDRFNBLEM9Yy5EU0Esdz1SU0FLZXksTT1wZW10b2hleCxGPUtFWVVUSUw7aWYodHlwZW9mIHchPVwidW5kZWZpbmVkXCImJmwgaW5zdGFuY2VvZiB3KXtyZXR1cm4gbH1pZih0eXBlb2YgaSE9XCJ1bmRlZmluZWRcIiYmbCBpbnN0YW5jZW9mIGkpe3JldHVybiBsfWlmKHR5cGVvZiBDIT1cInVuZGVmaW5lZFwiJiZsIGluc3RhbmNlb2YgQyl7cmV0dXJuIGx9aWYobC5jdXJ2ZSE9PXVuZGVmaW5lZCYmbC54eSE9PXVuZGVmaW5lZCYmbC5kPT09dW5kZWZpbmVkKXtyZXR1cm4gbmV3IGkoe3B1YjpsLnh5LGN1cnZlOmwuY3VydmV9KX1pZihsLmN1cnZlIT09dW5kZWZpbmVkJiZsLmQhPT11bmRlZmluZWQpe3JldHVybiBuZXcgaSh7cHJ2OmwuZCxjdXJ2ZTpsLmN1cnZlfSl9aWYobC5rdHk9PT11bmRlZmluZWQmJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQ9PT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQdWJsaWMobC5uLGwuZSk7cmV0dXJuIFB9aWYobC5rdHk9PT11bmRlZmluZWQmJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQhPT11bmRlZmluZWQmJmwucCE9PXVuZGVmaW5lZCYmbC5xIT09dW5kZWZpbmVkJiZsLmRwIT09dW5kZWZpbmVkJiZsLmRxIT09dW5kZWZpbmVkJiZsLmNvIT09dW5kZWZpbmVkJiZsLnFpPT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgdygpO1Auc2V0UHJpdmF0ZUV4KGwubixsLmUsbC5kLGwucCxsLnEsbC5kcCxsLmRxLGwuY28pO3JldHVybiBQfWlmKGwua3R5PT09dW5kZWZpbmVkJiZsLm4hPT11bmRlZmluZWQmJmwuZSE9PXVuZGVmaW5lZCYmbC5kIT09dW5kZWZpbmVkJiZsLnA9PT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQcml2YXRlKGwubixsLmUsbC5kKTtyZXR1cm4gUH1pZihsLnAhPT11bmRlZmluZWQmJmwucSE9PXVuZGVmaW5lZCYmbC5nIT09dW5kZWZpbmVkJiZsLnkhPT11bmRlZmluZWQmJmwueD09PXVuZGVmaW5lZCl7dmFyIFA9bmV3IEMoKTtQLnNldFB1YmxpYyhsLnAsbC5xLGwuZyxsLnkpO3JldHVybiBQfWlmKGwucCE9PXVuZGVmaW5lZCYmbC5xIT09dW5kZWZpbmVkJiZsLmchPT11bmRlZmluZWQmJmwueSE9PXVuZGVmaW5lZCYmbC54IT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgQygpO1Auc2V0UHJpdmF0ZShsLnAsbC5xLGwuZyxsLnksbC54KTtyZXR1cm4gUH1pZihsLmt0eT09PVwiUlNBXCImJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQ9PT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQdWJsaWMoYjY0dXRvaGV4KGwubiksYjY0dXRvaGV4KGwuZSkpO3JldHVybiBQfWlmKGwua3R5PT09XCJSU0FcIiYmbC5uIT09dW5kZWZpbmVkJiZsLmUhPT11bmRlZmluZWQmJmwuZCE9PXVuZGVmaW5lZCYmbC5wIT09dW5kZWZpbmVkJiZsLnEhPT11bmRlZmluZWQmJmwuZHAhPT11bmRlZmluZWQmJmwuZHEhPT11bmRlZmluZWQmJmwucWkhPT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQcml2YXRlRXgoYjY0dXRvaGV4KGwubiksYjY0dXRvaGV4KGwuZSksYjY0dXRvaGV4KGwuZCksYjY0dXRvaGV4KGwucCksYjY0dXRvaGV4KGwucSksYjY0dXRvaGV4KGwuZHApLGI2NHV0b2hleChsLmRxKSxiNjR1dG9oZXgobC5xaSkpO3JldHVybiBQfWlmKGwua3R5PT09XCJSU0FcIiYmbC5uIT09dW5kZWZpbmVkJiZsLmUhPT11bmRlZmluZWQmJmwuZCE9PXVuZGVmaW5lZCl7dmFyIFA9bmV3IHcoKTtQLnNldFByaXZhdGUoYjY0dXRvaGV4KGwubiksYjY0dXRvaGV4KGwuZSksYjY0dXRvaGV4KGwuZCkpO3JldHVybiBQfWlmKGwua3R5PT09XCJFQ1wiJiZsLmNydiE9PXVuZGVmaW5lZCYmbC54IT09dW5kZWZpbmVkJiZsLnkhPT11bmRlZmluZWQmJmwuZD09PXVuZGVmaW5lZCl7dmFyIGo9bmV3IGkoe2N1cnZlOmwuY3J2fSk7dmFyIHQ9ai5lY3BhcmFtcy5rZXlsZW4vNDt2YXIgQj0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueCkpLnNsaWNlKC10KTt2YXIgej0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueSkpLnNsaWNlKC10KTt2YXIgdT1cIjA0XCIrQit6O2ouc2V0UHVibGljS2V5SGV4KHUpO3JldHVybiBqfWlmKGwua3R5PT09XCJFQ1wiJiZsLmNydiE9PXVuZGVmaW5lZCYmbC54IT09dW5kZWZpbmVkJiZsLnkhPT11bmRlZmluZWQmJmwuZCE9PXVuZGVmaW5lZCl7dmFyIGo9bmV3IGkoe2N1cnZlOmwuY3J2fSk7dmFyIHQ9ai5lY3BhcmFtcy5rZXlsZW4vNDt2YXIgQj0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueCkpLnNsaWNlKC10KTt2YXIgej0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueSkpLnNsaWNlKC10KTt2YXIgdT1cIjA0XCIrQit6O3ZhciBiPShcIjAwMDAwMDAwMDBcIitiNjR1dG9oZXgobC5kKSkuc2xpY2UoLXQpO2ouc2V0UHVibGljS2V5SGV4KHUpO2ouc2V0UHJpdmF0ZUtleUhleChiKTtyZXR1cm4gan1pZihuPT09XCJwa2NzNXBydlwiKXt2YXIgSj1sLEc9QVNOMUhFWCxOLFA7Tj1MKEosMCk7aWYoTi5sZW5ndGg9PT05KXtQPW5ldyB3KCk7UC5yZWFkUEtDUzVQcnZLZXlIZXgoSil9ZWxzZXtpZihOLmxlbmd0aD09PTYpe1A9bmV3IEMoKTtQLnJlYWRQS0NTNVBydktleUhleChKKX1lbHNle2lmKE4ubGVuZ3RoPjImJkouc3Vic3RyKE5bMV0sMik9PT1cIjA0XCIpe1A9bmV3IGkoKTtQLnJlYWRQS0NTNVBydktleUhleChKKX1lbHNle3Rocm93XCJ1bnN1cHBvcnRlZCBQS0NTIzEvNSBoZXhhZGVjaW1hbCBrZXlcIn19fXJldHVybiBQfWlmKG49PT1cInBrY3M4cHJ2XCIpe3ZhciBQPUYuZ2V0S2V5RnJvbVBsYWluUHJpdmF0ZVBLQ1M4SGV4KGwpO3JldHVybiBQfWlmKG49PT1cInBrY3M4cHViXCIpe3JldHVybiBGLl9nZXRLZXlGcm9tUHVibGljUEtDUzhIZXgobCl9aWYobj09PVwieDUwOXB1YlwiKXtyZXR1cm4gWDUwOS5nZXRQdWJsaWNLZXlGcm9tQ2VydEhleChsKX1pZihsLmluZGV4T2YoXCItRU5EIENFUlRJRklDQVRFLVwiLDApIT0tMXx8bC5pbmRleE9mKFwiLUVORCBYNTA5IENFUlRJRklDQVRFLVwiLDApIT0tMXx8bC5pbmRleE9mKFwiLUVORCBUUlVTVEVEIENFUlRJRklDQVRFLVwiLDApIT0tMSl7cmV0dXJuIFg1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRQRU0obCl9aWYobC5pbmRleE9mKFwiLUVORCBQVUJMSUMgS0VZLVwiKSE9LTEpe3ZhciBPPXBlbXRvaGV4KGwsXCJQVUJMSUMgS0VZXCIpO3JldHVybiBGLl9nZXRLZXlGcm9tUHVibGljUEtDUzhIZXgoTyl9aWYobC5pbmRleE9mKFwiLUVORCBSU0EgUFJJVkFURSBLRVktXCIpIT0tMSYmbC5pbmRleE9mKFwiNCxFTkNSWVBURURcIik9PS0xKXt2YXIgbT1NKGwsXCJSU0EgUFJJVkFURSBLRVlcIik7cmV0dXJuIEYuZ2V0S2V5KG0sbnVsbCxcInBrY3M1cHJ2XCIpfWlmKGwuaW5kZXhPZihcIi1FTkQgRFNBIFBSSVZBVEUgS0VZLVwiKSE9LTEmJmwuaW5kZXhPZihcIjQsRU5DUllQVEVEXCIpPT0tMSl7dmFyIEk9TShsLFwiRFNBIFBSSVZBVEUgS0VZXCIpO3ZhciBFPWQoSSwwLFsxXSxcIjAyXCIpO3ZhciBEPWQoSSwwLFsyXSxcIjAyXCIpO3ZhciBLPWQoSSwwLFszXSxcIjAyXCIpO3ZhciByPWQoSSwwLFs0XSxcIjAyXCIpO3ZhciBzPWQoSSwwLFs1XSxcIjAyXCIpO3ZhciBQPW5ldyBDKCk7UC5zZXRQcml2YXRlKG5ldyBCaWdJbnRlZ2VyKEUsMTYpLG5ldyBCaWdJbnRlZ2VyKEQsMTYpLG5ldyBCaWdJbnRlZ2VyKEssMTYpLG5ldyBCaWdJbnRlZ2VyKHIsMTYpLG5ldyBCaWdJbnRlZ2VyKHMsMTYpKTtyZXR1cm4gUH1pZihsLmluZGV4T2YoXCItRU5EIFBSSVZBVEUgS0VZLVwiKSE9LTEpe3JldHVybiBGLmdldEtleUZyb21QbGFpblByaXZhdGVQS0NTOFBFTShsKX1pZihsLmluZGV4T2YoXCItRU5EIFJTQSBQUklWQVRFIEtFWS1cIikhPS0xJiZsLmluZGV4T2YoXCI0LEVOQ1JZUFRFRFwiKSE9LTEpe3ZhciBvPUYuZ2V0RGVjcnlwdGVkS2V5SGV4KGwsayk7dmFyIEg9bmV3IFJTQUtleSgpO0gucmVhZFBLQ1M1UHJ2S2V5SGV4KG8pO3JldHVybiBIfWlmKGwuaW5kZXhPZihcIi1FTkQgRUMgUFJJVkFURSBLRVktXCIpIT0tMSYmbC5pbmRleE9mKFwiNCxFTkNSWVBURURcIikhPS0xKXt2YXIgST1GLmdldERlY3J5cHRlZEtleUhleChsLGspO3ZhciBQPWQoSSwwLFsxXSxcIjA0XCIpO3ZhciBmPWQoSSwwLFsyLDBdLFwiMDZcIik7dmFyIEE9ZChJLDAsWzMsMF0sXCIwM1wiKS5zdWJzdHIoMik7dmFyIGU9XCJcIjtpZihLSlVSLmNyeXB0by5PSUQub2lkaGV4Mm5hbWVbZl0hPT11bmRlZmluZWQpe2U9S0pVUi5jcnlwdG8uT0lELm9pZGhleDJuYW1lW2ZdfWVsc2V7dGhyb3dcInVuZGVmaW5lZCBPSUQoaGV4KSBpbiBLSlVSLmNyeXB0by5PSUQ6IFwiK2Z9dmFyIGo9bmV3IGkoe2N1cnZlOmV9KTtqLnNldFB1YmxpY0tleUhleChBKTtqLnNldFByaXZhdGVLZXlIZXgoUCk7ai5pc1B1YmxpYz1mYWxzZTtyZXR1cm4gan1pZihsLmluZGV4T2YoXCItRU5EIERTQSBQUklWQVRFIEtFWS1cIikhPS0xJiZsLmluZGV4T2YoXCI0LEVOQ1JZUFRFRFwiKSE9LTEpe3ZhciBJPUYuZ2V0RGVjcnlwdGVkS2V5SGV4KGwsayk7dmFyIEU9ZChJLDAsWzFdLFwiMDJcIik7dmFyIEQ9ZChJLDAsWzJdLFwiMDJcIik7dmFyIEs9ZChJLDAsWzNdLFwiMDJcIik7dmFyIHI9ZChJLDAsWzRdLFwiMDJcIik7dmFyIHM9ZChJLDAsWzVdLFwiMDJcIik7dmFyIFA9bmV3IEMoKTtQLnNldFByaXZhdGUobmV3IEJpZ0ludGVnZXIoRSwxNiksbmV3IEJpZ0ludGVnZXIoRCwxNiksbmV3IEJpZ0ludGVnZXIoSywxNiksbmV3IEJpZ0ludGVnZXIociwxNiksbmV3IEJpZ0ludGVnZXIocywxNikpO3JldHVybiBQfWlmKGwuaW5kZXhPZihcIi1FTkQgRU5DUllQVEVEIFBSSVZBVEUgS0VZLVwiKSE9LTEpe3JldHVybiBGLmdldEtleUZyb21FbmNyeXB0ZWRQS0NTOFBFTShsLGspfXRocm93XCJub3Qgc3VwcG9ydGVkIGFyZ3VtZW50XCJ9O0tFWVVUSUwuZ2VuZXJhdGVLZXlwYWlyPWZ1bmN0aW9uKGEsYyl7aWYoYT09XCJSU0FcIil7dmFyIGI9Yzt2YXIgaD1uZXcgUlNBS2V5KCk7aC5nZW5lcmF0ZShiLFwiMTAwMDFcIik7aC5pc1ByaXZhdGU9dHJ1ZTtoLmlzUHVibGljPXRydWU7dmFyIGY9bmV3IFJTQUtleSgpO3ZhciBlPWgubi50b1N0cmluZygxNik7dmFyIGk9aC5lLnRvU3RyaW5nKDE2KTtmLnNldFB1YmxpYyhlLGkpO2YuaXNQcml2YXRlPWZhbHNlO2YuaXNQdWJsaWM9dHJ1ZTt2YXIgaz17fTtrLnBydktleU9iaj1oO2sucHViS2V5T2JqPWY7cmV0dXJuIGt9ZWxzZXtpZihhPT1cIkVDXCIpe3ZhciBkPWM7dmFyIGc9bmV3IEtKVVIuY3J5cHRvLkVDRFNBKHtjdXJ2ZTpkfSk7dmFyIGo9Zy5nZW5lcmF0ZUtleVBhaXJIZXgoKTt2YXIgaD1uZXcgS0pVUi5jcnlwdG8uRUNEU0Eoe2N1cnZlOmR9KTtoLnNldFB1YmxpY0tleUhleChqLmVjcHViaGV4KTtoLnNldFByaXZhdGVLZXlIZXgoai5lY3BydmhleCk7aC5pc1ByaXZhdGU9dHJ1ZTtoLmlzUHVibGljPWZhbHNlO3ZhciBmPW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6ZH0pO2Yuc2V0UHVibGljS2V5SGV4KGouZWNwdWJoZXgpO2YuaXNQcml2YXRlPWZhbHNlO2YuaXNQdWJsaWM9dHJ1ZTt2YXIgaz17fTtrLnBydktleU9iaj1oO2sucHViS2V5T2JqPWY7cmV0dXJuIGt9ZWxzZXt0aHJvd1widW5rbm93biBhbGdvcml0aG06IFwiK2F9fX07S0VZVVRJTC5nZXRQRU09ZnVuY3Rpb24oYixELHksbSxxLGope3ZhciBGPUtKVVIsaz1GLmFzbjEsej1rLkRFUk9iamVjdElkZW50aWZpZXIsZj1rLkRFUkludGVnZXIsbD1rLkFTTjFVdGlsLm5ld09iamVjdCxhPWsueDUwOSxDPWEuU3ViamVjdFB1YmxpY0tleUluZm8sZT1GLmNyeXB0byx1PWUuRFNBLHI9ZS5FQ0RTQSxuPVJTQUtleTtmdW5jdGlvbiBBKHMpe3ZhciBHPWwoe3NlcTpbe1wiaW50XCI6MH0se1wiaW50XCI6e2JpZ2ludDpzLm59fSx7XCJpbnRcIjpzLmV9LHtcImludFwiOntiaWdpbnQ6cy5kfX0se1wiaW50XCI6e2JpZ2ludDpzLnB9fSx7XCJpbnRcIjp7YmlnaW50OnMucX19LHtcImludFwiOntiaWdpbnQ6cy5kbXAxfX0se1wiaW50XCI6e2JpZ2ludDpzLmRtcTF9fSx7XCJpbnRcIjp7YmlnaW50OnMuY29lZmZ9fV19KTtyZXR1cm4gR31mdW5jdGlvbiBCKEcpe3ZhciBzPWwoe3NlcTpbe1wiaW50XCI6MX0se29jdHN0cjp7aGV4OkcucHJ2S2V5SGV4fX0se3RhZzpbXCJhMFwiLHRydWUse29pZDp7bmFtZTpHLmN1cnZlTmFtZX19XX0se3RhZzpbXCJhMVwiLHRydWUse2JpdHN0cjp7aGV4OlwiMDBcIitHLnB1YktleUhleH19XX1dfSk7cmV0dXJuIHN9ZnVuY3Rpb24geChzKXt2YXIgRz1sKHtzZXE6W3tcImludFwiOjB9LHtcImludFwiOntiaWdpbnQ6cy5wfX0se1wiaW50XCI6e2JpZ2ludDpzLnF9fSx7XCJpbnRcIjp7YmlnaW50OnMuZ319LHtcImludFwiOntiaWdpbnQ6cy55fX0se1wiaW50XCI6e2JpZ2ludDpzLnh9fV19KTtyZXR1cm4gR31pZigoKG4hPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiBuKXx8KHUhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiB1KXx8KHIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByKSkmJmIuaXNQdWJsaWM9PXRydWUmJihEPT09dW5kZWZpbmVkfHxEPT1cIlBLQ1M4UFVCXCIpKXt2YXIgRT1uZXcgQyhiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtyZXR1cm4gaGV4dG9wZW0odyxcIlBVQkxJQyBLRVlcIil9aWYoRD09XCJQS0NTMVBSVlwiJiZuIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgbiYmKHk9PT11bmRlZmluZWR8fHk9PW51bGwpJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIEU9QShiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtyZXR1cm4gaGV4dG9wZW0odyxcIlJTQSBQUklWQVRFIEtFWVwiKX1pZihEPT1cIlBLQ1MxUFJWXCImJnIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByJiYoeT09PXVuZGVmaW5lZHx8eT09bnVsbCkmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgaT1uZXcgeih7bmFtZTpiLmN1cnZlTmFtZX0pO3ZhciB2PWkuZ2V0RW5jb2RlZEhleCgpO3ZhciBoPUIoYik7dmFyIHQ9aC5nZXRFbmNvZGVkSGV4KCk7dmFyIHA9XCJcIjtwKz1oZXh0b3BlbSh2LFwiRUMgUEFSQU1FVEVSU1wiKTtwKz1oZXh0b3BlbSh0LFwiRUMgUFJJVkFURSBLRVlcIik7cmV0dXJuIHB9aWYoRD09XCJQS0NTMVBSVlwiJiZ1IT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgdSYmKHk9PT11bmRlZmluZWR8fHk9PW51bGwpJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIEU9eChiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtyZXR1cm4gaGV4dG9wZW0odyxcIkRTQSBQUklWQVRFIEtFWVwiKX1pZihEPT1cIlBLQ1M1UFJWXCImJm4hPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiBuJiYoeSE9PXVuZGVmaW5lZCYmeSE9bnVsbCkmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgRT1BKGIpO3ZhciB3PUUuZ2V0RW5jb2RlZEhleCgpO2lmKG09PT11bmRlZmluZWQpe209XCJERVMtRURFMy1DQkNcIn1yZXR1cm4gdGhpcy5nZXRFbmNyeXB0ZWRQS0NTNVBFTUZyb21QcnZLZXlIZXgoXCJSU0FcIix3LHksbSxqKX1pZihEPT1cIlBLQ1M1UFJWXCImJnIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByJiYoeSE9PXVuZGVmaW5lZCYmeSE9bnVsbCkmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgRT1CKGIpO3ZhciB3PUUuZ2V0RW5jb2RlZEhleCgpO2lmKG09PT11bmRlZmluZWQpe209XCJERVMtRURFMy1DQkNcIn1yZXR1cm4gdGhpcy5nZXRFbmNyeXB0ZWRQS0NTNVBFTUZyb21QcnZLZXlIZXgoXCJFQ1wiLHcseSxtLGopfWlmKEQ9PVwiUEtDUzVQUlZcIiYmdSE9PXVuZGVmaW5lZCYmYiBpbnN0YW5jZW9mIHUmJih5IT09dW5kZWZpbmVkJiZ5IT1udWxsKSYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBFPXgoYik7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7aWYobT09PXVuZGVmaW5lZCl7bT1cIkRFUy1FREUzLUNCQ1wifXJldHVybiB0aGlzLmdldEVuY3J5cHRlZFBLQ1M1UEVNRnJvbVBydktleUhleChcIkRTQVwiLHcseSxtLGopfXZhciBvPWZ1bmN0aW9uKEcscyl7dmFyIEk9YyhHLHMpO3ZhciBIPW5ldyBsKHtzZXE6W3tzZXE6W3tvaWQ6e25hbWU6XCJwa2NzNVBCRVMyXCJ9fSx7c2VxOlt7c2VxOlt7b2lkOntuYW1lOlwicGtjczVQQktERjJcIn19LHtzZXE6W3tvY3RzdHI6e2hleDpJLnBia2RmMlNhbHR9fSx7XCJpbnRcIjpJLnBia2RmMkl0ZXJ9XX1dfSx7c2VxOlt7b2lkOntuYW1lOlwiZGVzLUVERTMtQ0JDXCJ9fSx7b2N0c3RyOntoZXg6SS5lbmNyeXB0aW9uU2NoZW1lSVZ9fV19XX1dfSx7b2N0c3RyOntoZXg6SS5jaXBoZXJ0ZXh0fX1dfSk7cmV0dXJuIEguZ2V0RW5jb2RlZEhleCgpfTt2YXIgYz1mdW5jdGlvbihOLE8pe3ZhciBIPTEwMDt2YXIgTT1DcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSg4KTt2YXIgTD1cIkRFUy1FREUzLUNCQ1wiO3ZhciBzPUNyeXB0b0pTLmxpYi5Xb3JkQXJyYXkucmFuZG9tKDgpO3ZhciBJPUNyeXB0b0pTLlBCS0RGMihPLE0se2tleVNpemU6MTkyLzMyLGl0ZXJhdGlvbnM6SH0pO3ZhciBKPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoTik7dmFyIEs9Q3J5cHRvSlMuVHJpcGxlREVTLmVuY3J5cHQoSixJLHtpdjpzfSkrXCJcIjt2YXIgRz17fTtHLmNpcGhlcnRleHQ9SztHLnBia2RmMlNhbHQ9Q3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkoTSk7Ry5wYmtkZjJJdGVyPUg7Ry5lbmNyeXB0aW9uU2NoZW1lQWxnPUw7Ry5lbmNyeXB0aW9uU2NoZW1lSVY9Q3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkocyk7cmV0dXJuIEd9O2lmKEQ9PVwiUEtDUzhQUlZcIiYmbiE9dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgbiYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBnPUEoYik7dmFyIGQ9Zy5nZXRFbmNvZGVkSGV4KCk7dmFyIEU9bCh7c2VxOlt7XCJpbnRcIjowfSx7c2VxOlt7b2lkOntuYW1lOlwicnNhRW5jcnlwdGlvblwifX0se1wibnVsbFwiOnRydWV9XX0se29jdHN0cjp7aGV4OmR9fV19KTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtpZih5PT09dW5kZWZpbmVkfHx5PT1udWxsKXtyZXR1cm4gaGV4dG9wZW0odyxcIlBSSVZBVEUgS0VZXCIpfWVsc2V7dmFyIHQ9byh3LHkpO3JldHVybiBoZXh0b3BlbSh0LFwiRU5DUllQVEVEIFBSSVZBVEUgS0VZXCIpfX1pZihEPT1cIlBLQ1M4UFJWXCImJnIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIGc9bmV3IGwoe3NlcTpbe1wiaW50XCI6MX0se29jdHN0cjp7aGV4OmIucHJ2S2V5SGV4fX0se3RhZzpbXCJhMVwiLHRydWUse2JpdHN0cjp7aGV4OlwiMDBcIitiLnB1YktleUhleH19XX1dfSk7dmFyIGQ9Zy5nZXRFbmNvZGVkSGV4KCk7dmFyIEU9bCh7c2VxOlt7XCJpbnRcIjowfSx7c2VxOlt7b2lkOntuYW1lOlwiZWNQdWJsaWNLZXlcIn19LHtvaWQ6e25hbWU6Yi5jdXJ2ZU5hbWV9fV19LHtvY3RzdHI6e2hleDpkfX1dfSk7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7aWYoeT09PXVuZGVmaW5lZHx8eT09bnVsbCl7cmV0dXJuIGhleHRvcGVtKHcsXCJQUklWQVRFIEtFWVwiKX1lbHNle3ZhciB0PW8odyx5KTtyZXR1cm4gaGV4dG9wZW0odCxcIkVOQ1JZUFRFRCBQUklWQVRFIEtFWVwiKX19aWYoRD09XCJQS0NTOFBSVlwiJiZ1IT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgdSYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBnPW5ldyBmKHtiaWdpbnQ6Yi54fSk7dmFyIGQ9Zy5nZXRFbmNvZGVkSGV4KCk7dmFyIEU9bCh7c2VxOlt7XCJpbnRcIjowfSx7c2VxOlt7b2lkOntuYW1lOlwiZHNhXCJ9fSx7c2VxOlt7XCJpbnRcIjp7YmlnaW50OmIucH19LHtcImludFwiOntiaWdpbnQ6Yi5xfX0se1wiaW50XCI6e2JpZ2ludDpiLmd9fV19XX0se29jdHN0cjp7aGV4OmR9fV19KTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtpZih5PT09dW5kZWZpbmVkfHx5PT1udWxsKXtyZXR1cm4gaGV4dG9wZW0odyxcIlBSSVZBVEUgS0VZXCIpfWVsc2V7dmFyIHQ9byh3LHkpO3JldHVybiBoZXh0b3BlbSh0LFwiRU5DUllQVEVEIFBSSVZBVEUgS0VZXCIpfX10aHJvd1widW5zdXBwb3J0ZWQgb2JqZWN0IG5vciBmb3JtYXRcIn07S0VZVVRJTC5nZXRLZXlGcm9tQ1NSUEVNPWZ1bmN0aW9uKGIpe3ZhciBhPXBlbXRvaGV4KGIsXCJDRVJUSUZJQ0FURSBSRVFVRVNUXCIpO3ZhciBjPUtFWVVUSUwuZ2V0S2V5RnJvbUNTUkhleChhKTtyZXR1cm4gY307S0VZVVRJTC5nZXRLZXlGcm9tQ1NSSGV4PWZ1bmN0aW9uKGEpe3ZhciBjPUtFWVVUSUwucGFyc2VDU1JIZXgoYSk7dmFyIGI9S0VZVVRJTC5nZXRLZXkoYy5wOHB1YmtleWhleCxudWxsLFwicGtjczhwdWJcIik7cmV0dXJuIGJ9O0tFWVVUSUwucGFyc2VDU1JIZXg9ZnVuY3Rpb24oZCl7dmFyIGk9QVNOMUhFWDt2YXIgZj1pLmdldENoaWxkSWR4O3ZhciBjPWkuZ2V0VExWO3ZhciBiPXt9O3ZhciBnPWQ7aWYoZy5zdWJzdHIoMCwyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIENTUihjb2RlOjAwMSlcIn12YXIgZT1mKGcsMCk7aWYoZS5sZW5ndGg8MSl7dGhyb3dcIm1hbGZvcm1lZCBDU1IoY29kZTowMDIpXCJ9aWYoZy5zdWJzdHIoZVswXSwyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIENTUihjb2RlOjAwMylcIn12YXIgYT1mKGcsZVswXSk7aWYoYS5sZW5ndGg8Myl7dGhyb3dcIm1hbGZvcm1lZCBDU1IoY29kZTowMDQpXCJ9Yi5wOHB1YmtleWhleD1jKGcsYVsyXSk7cmV0dXJuIGJ9O0tFWVVUSUwuZ2V0SldLRnJvbUtleT1mdW5jdGlvbihkKXt2YXIgYj17fTtpZihkIGluc3RhbmNlb2YgUlNBS2V5JiZkLmlzUHJpdmF0ZSl7Yi5rdHk9XCJSU0FcIjtiLm49aGV4dG9iNjR1KGQubi50b1N0cmluZygxNikpO2IuZT1oZXh0b2I2NHUoZC5lLnRvU3RyaW5nKDE2KSk7Yi5kPWhleHRvYjY0dShkLmQudG9TdHJpbmcoMTYpKTtiLnA9aGV4dG9iNjR1KGQucC50b1N0cmluZygxNikpO2IucT1oZXh0b2I2NHUoZC5xLnRvU3RyaW5nKDE2KSk7Yi5kcD1oZXh0b2I2NHUoZC5kbXAxLnRvU3RyaW5nKDE2KSk7Yi5kcT1oZXh0b2I2NHUoZC5kbXExLnRvU3RyaW5nKDE2KSk7Yi5xaT1oZXh0b2I2NHUoZC5jb2VmZi50b1N0cmluZygxNikpO3JldHVybiBifWVsc2V7aWYoZCBpbnN0YW5jZW9mIFJTQUtleSYmZC5pc1B1YmxpYyl7Yi5rdHk9XCJSU0FcIjtiLm49aGV4dG9iNjR1KGQubi50b1N0cmluZygxNikpO2IuZT1oZXh0b2I2NHUoZC5lLnRvU3RyaW5nKDE2KSk7cmV0dXJuIGJ9ZWxzZXtpZihkIGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRUNEU0EmJmQuaXNQcml2YXRlKXt2YXIgYT1kLmdldFNob3J0TklTVFBDdXJ2ZU5hbWUoKTtpZihhIT09XCJQLTI1NlwiJiZhIT09XCJQLTM4NFwiKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZSBmb3IgSldUOiBcIithfXZhciBjPWQuZ2V0UHVibGljS2V5WFlIZXgoKTtiLmt0eT1cIkVDXCI7Yi5jcnY9YTtiLng9aGV4dG9iNjR1KGMueCk7Yi55PWhleHRvYjY0dShjLnkpO2IuZD1oZXh0b2I2NHUoZC5wcnZLZXlIZXgpO3JldHVybiBifWVsc2V7aWYoZCBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkVDRFNBJiZkLmlzUHVibGljKXt2YXIgYT1kLmdldFNob3J0TklTVFBDdXJ2ZU5hbWUoKTtpZihhIT09XCJQLTI1NlwiJiZhIT09XCJQLTM4NFwiKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZSBmb3IgSldUOiBcIithfXZhciBjPWQuZ2V0UHVibGljS2V5WFlIZXgoKTtiLmt0eT1cIkVDXCI7Yi5jcnY9YTtiLng9aGV4dG9iNjR1KGMueCk7Yi55PWhleHRvYjY0dShjLnkpO3JldHVybiBifX19fXRocm93XCJub3Qgc3VwcG9ydGVkIGtleSBvYmplY3RcIn07XG5SU0FLZXkuZ2V0UG9zQXJyYXlPZkNoaWxkcmVuRnJvbUhleD1mdW5jdGlvbihhKXtyZXR1cm4gQVNOMUhFWC5nZXRDaGlsZElkeChhLDApfTtSU0FLZXkuZ2V0SGV4VmFsdWVBcnJheU9mQ2hpbGRyZW5Gcm9tSGV4PWZ1bmN0aW9uKGYpe3ZhciBuPUFTTjFIRVg7dmFyIGk9bi5nZXRWO3ZhciBrPVJTQUtleS5nZXRQb3NBcnJheU9mQ2hpbGRyZW5Gcm9tSGV4KGYpO3ZhciBlPWkoZixrWzBdKTt2YXIgaj1pKGYsa1sxXSk7dmFyIGI9aShmLGtbMl0pO3ZhciBjPWkoZixrWzNdKTt2YXIgaD1pKGYsa1s0XSk7dmFyIGc9aShmLGtbNV0pO3ZhciBtPWkoZixrWzZdKTt2YXIgbD1pKGYsa1s3XSk7dmFyIGQ9aShmLGtbOF0pO3ZhciBrPW5ldyBBcnJheSgpO2sucHVzaChlLGosYixjLGgsZyxtLGwsZCk7cmV0dXJuIGt9O1JTQUtleS5wcm90b3R5cGUucmVhZFByaXZhdGVLZXlGcm9tUEVNU3RyaW5nPWZ1bmN0aW9uKGQpe3ZhciBjPXBlbXRvaGV4KGQpO3ZhciBiPVJTQUtleS5nZXRIZXhWYWx1ZUFycmF5T2ZDaGlsZHJlbkZyb21IZXgoYyk7dGhpcy5zZXRQcml2YXRlRXgoYlsxXSxiWzJdLGJbM10sYls0XSxiWzVdLGJbNl0sYls3XSxiWzhdKX07UlNBS2V5LnByb3RvdHlwZS5yZWFkUEtDUzVQcnZLZXlIZXg9ZnVuY3Rpb24oYyl7dmFyIGI9UlNBS2V5LmdldEhleFZhbHVlQXJyYXlPZkNoaWxkcmVuRnJvbUhleChjKTt0aGlzLnNldFByaXZhdGVFeChiWzFdLGJbMl0sYlszXSxiWzRdLGJbNV0sYls2XSxiWzddLGJbOF0pfTtSU0FLZXkucHJvdG90eXBlLnJlYWRQS0NTOFBydktleUhleD1mdW5jdGlvbihlKXt2YXIgYyxqLGwsYixhLGYsZCxrO3ZhciBtPUFTTjFIRVg7dmFyIGc9bS5nZXRWYnlMaXN0O2lmKG0uaXNBU04xSEVYKGUpPT09ZmFsc2Upe3Rocm93XCJub3QgQVNOLjEgaGV4IHN0cmluZ1wifXRyeXtjPWcoZSwwLFsyLDAsMV0sXCIwMlwiKTtqPWcoZSwwLFsyLDAsMl0sXCIwMlwiKTtsPWcoZSwwLFsyLDAsM10sXCIwMlwiKTtiPWcoZSwwLFsyLDAsNF0sXCIwMlwiKTthPWcoZSwwLFsyLDAsNV0sXCIwMlwiKTtmPWcoZSwwLFsyLDAsNl0sXCIwMlwiKTtkPWcoZSwwLFsyLDAsN10sXCIwMlwiKTtrPWcoZSwwLFsyLDAsOF0sXCIwMlwiKX1jYXRjaChpKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1MjOCBwbGFpbiBSU0EgcHJpdmF0ZSBrZXlcIn10aGlzLnNldFByaXZhdGVFeChjLGosbCxiLGEsZixkLGspfTtSU0FLZXkucHJvdG90eXBlLnJlYWRQS0NTNVB1YktleUhleD1mdW5jdGlvbihjKXt2YXIgZT1BU04xSEVYO3ZhciBiPWUuZ2V0VjtpZihlLmlzQVNOMUhFWChjKT09PWZhbHNlKXt0aHJvd1wia2V5SGV4IGlzIG5vdCBBU04uMSBoZXggc3RyaW5nXCJ9dmFyIGE9ZS5nZXRDaGlsZElkeChjLDApO2lmKGEubGVuZ3RoIT09Mnx8Yy5zdWJzdHIoYVswXSwyKSE9PVwiMDJcInx8Yy5zdWJzdHIoYVsxXSwyKSE9PVwiMDJcIil7dGhyb3dcIndyb25nIGhleCBmb3IgUEtDUyM1IHB1YmxpYyBrZXlcIn12YXIgZj1iKGMsYVswXSk7dmFyIGQ9YihjLGFbMV0pO3RoaXMuc2V0UHVibGljKGYsZCl9O1JTQUtleS5wcm90b3R5cGUucmVhZFBLQ1M4UHViS2V5SGV4PWZ1bmN0aW9uKGIpe3ZhciBjPUFTTjFIRVg7aWYoYy5pc0FTTjFIRVgoYik9PT1mYWxzZSl7dGhyb3dcIm5vdCBBU04uMSBoZXggc3RyaW5nXCJ9aWYoYy5nZXRUTFZieUxpc3QoYiwwLFswLDBdKSE9PVwiMDYwOTJhODY0ODg2ZjcwZDAxMDEwMVwiKXt0aHJvd1wibm90IFBLQ1M4IFJTQSBwdWJsaWMga2V5XCJ9dmFyIGE9Yy5nZXRUTFZieUxpc3QoYiwwLFsxLDBdKTt0aGlzLnJlYWRQS0NTNVB1YktleUhleChhKX07UlNBS2V5LnByb3RvdHlwZS5yZWFkQ2VydFB1YktleUhleD1mdW5jdGlvbihiLGQpe3ZhciBhLGM7YT1uZXcgWDUwOSgpO2EucmVhZENlcnRIZXgoYik7Yz1hLmdldFB1YmxpY0tleUhleCgpO3RoaXMucmVhZFBLQ1M4UHViS2V5SGV4KGMpfTtcbnZhciBfUkVfSEVYREVDT05MWT1uZXcgUmVnRXhwKFwiXCIpO19SRV9IRVhERUNPTkxZLmNvbXBpbGUoXCJbXjAtOWEtZl1cIixcImdpXCIpO2Z1bmN0aW9uIF9yc2FzaWduX2dldEhleFBhZGRlZERpZ2VzdEluZm9Gb3JTdHJpbmcoZCxlLGEpe3ZhciBiPWZ1bmN0aW9uKGYpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hTdHJpbmcoZixhKX07dmFyIGM9YihkKTtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5nZXRQYWRkZWREaWdlc3RJbmZvSGV4KGMsYSxlKX1mdW5jdGlvbiBfemVyb1BhZGRpbmdPZlNpZ25hdHVyZShlLGQpe3ZhciBjPVwiXCI7dmFyIGE9ZC80LWUubGVuZ3RoO2Zvcih2YXIgYj0wO2I8YTtiKyspe2M9YytcIjBcIn1yZXR1cm4gYytlfVJTQUtleS5wcm90b3R5cGUuc2lnbj1mdW5jdGlvbihkLGEpe3ZhciBiPWZ1bmN0aW9uKGUpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hTdHJpbmcoZSxhKX07dmFyIGM9YihkKTtyZXR1cm4gdGhpcy5zaWduV2l0aE1lc3NhZ2VIYXNoKGMsYSl9O1JTQUtleS5wcm90b3R5cGUuc2lnbldpdGhNZXNzYWdlSGFzaD1mdW5jdGlvbihlLGMpe3ZhciBmPUtKVVIuY3J5cHRvLlV0aWwuZ2V0UGFkZGVkRGlnZXN0SW5mb0hleChlLGMsdGhpcy5uLmJpdExlbmd0aCgpKTt2YXIgYj1wYXJzZUJpZ0ludChmLDE2KTt2YXIgZD10aGlzLmRvUHJpdmF0ZShiKTt2YXIgYT1kLnRvU3RyaW5nKDE2KTtyZXR1cm4gX3plcm9QYWRkaW5nT2ZTaWduYXR1cmUoYSx0aGlzLm4uYml0TGVuZ3RoKCkpfTtmdW5jdGlvbiBwc3NfbWdmMV9zdHIoYyxhLGUpe3ZhciBiPVwiXCIsZD0wO3doaWxlKGIubGVuZ3RoPGEpe2IrPWhleHRvcnN0cihlKHJzdHJ0b2hleChjK1N0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLFsoZCY0Mjc4MTkwMDgwKT4+MjQsKGQmMTY3MTE2ODApPj4xNiwoZCY2NTI4MCk+PjgsZCYyNTVdKSkpKTtkKz0xfXJldHVybiBifVJTQUtleS5wcm90b3R5cGUuc2lnblBTUz1mdW5jdGlvbihlLGEsZCl7dmFyIGM9ZnVuY3Rpb24oZil7cmV0dXJuIEtKVVIuY3J5cHRvLlV0aWwuaGFzaEhleChmLGEpfTt2YXIgYj1jKHJzdHJ0b2hleChlKSk7aWYoZD09PXVuZGVmaW5lZCl7ZD0tMX1yZXR1cm4gdGhpcy5zaWduV2l0aE1lc3NhZ2VIYXNoUFNTKGIsYSxkKX07UlNBS2V5LnByb3RvdHlwZS5zaWduV2l0aE1lc3NhZ2VIYXNoUFNTPWZ1bmN0aW9uKGwsYSxrKXt2YXIgYj1oZXh0b3JzdHIobCk7dmFyIGc9Yi5sZW5ndGg7dmFyIG09dGhpcy5uLmJpdExlbmd0aCgpLTE7dmFyIGM9TWF0aC5jZWlsKG0vOCk7dmFyIGQ7dmFyIG89ZnVuY3Rpb24oaSl7cmV0dXJuIEtKVVIuY3J5cHRvLlV0aWwuaGFzaEhleChpLGEpfTtpZihrPT09LTF8fGs9PT11bmRlZmluZWQpe2s9Z31lbHNle2lmKGs9PT0tMil7az1jLWctMn1lbHNle2lmKGs8LTIpe3Rocm93XCJpbnZhbGlkIHNhbHQgbGVuZ3RoXCJ9fX1pZihjPChnK2srMikpe3Rocm93XCJkYXRhIHRvbyBsb25nXCJ9dmFyIGY9XCJcIjtpZihrPjApe2Y9bmV3IEFycmF5KGspO25ldyBTZWN1cmVSYW5kb20oKS5uZXh0Qnl0ZXMoZik7Zj1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxmKX12YXIgbj1oZXh0b3JzdHIobyhyc3RydG9oZXgoXCJcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXCIrYitmKSkpO3ZhciBqPVtdO2ZvcihkPTA7ZDxjLWstZy0yO2QrPTEpe2pbZF09MH12YXIgZT1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxqKStcIlxceDAxXCIrZjt2YXIgaD1wc3NfbWdmMV9zdHIobixlLmxlbmd0aCxvKTt2YXIgcT1bXTtmb3IoZD0wO2Q8ZS5sZW5ndGg7ZCs9MSl7cVtkXT1lLmNoYXJDb2RlQXQoZCleaC5jaGFyQ29kZUF0KGQpfXZhciBwPSg2NTI4MD4+KDgqYy1tKSkmMjU1O3FbMF0mPX5wO2ZvcihkPTA7ZDxnO2QrKyl7cS5wdXNoKG4uY2hhckNvZGVBdChkKSl9cS5wdXNoKDE4OCk7cmV0dXJuIF96ZXJvUGFkZGluZ09mU2lnbmF0dXJlKHRoaXMuZG9Qcml2YXRlKG5ldyBCaWdJbnRlZ2VyKHEpKS50b1N0cmluZygxNiksdGhpcy5uLmJpdExlbmd0aCgpKX07ZnVuY3Rpb24gX3JzYXNpZ25fZ2V0RGVjcnlwdFNpZ25hdHVyZUJJKGEsZCxjKXt2YXIgYj1uZXcgUlNBS2V5KCk7Yi5zZXRQdWJsaWMoZCxjKTt2YXIgZT1iLmRvUHVibGljKGEpO3JldHVybiBlfWZ1bmN0aW9uIF9yc2FzaWduX2dldEhleERpZ2VzdEluZm9Gcm9tU2lnKGEsYyxiKXt2YXIgZT1fcnNhc2lnbl9nZXREZWNyeXB0U2lnbmF0dXJlQkkoYSxjLGIpO3ZhciBkPWUudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sXCJcIik7cmV0dXJuIGR9ZnVuY3Rpb24gX3JzYXNpZ25fZ2V0QWxnTmFtZUFuZEhhc2hGcm9tSGV4RGlzZ2VzdEluZm8oZil7Zm9yKHZhciBlIGluIEtKVVIuY3J5cHRvLlV0aWwuRElHRVNUSU5GT0hFQUQpe3ZhciBkPUtKVVIuY3J5cHRvLlV0aWwuRElHRVNUSU5GT0hFQURbZV07dmFyIGI9ZC5sZW5ndGg7aWYoZi5zdWJzdHJpbmcoMCxiKT09ZCl7dmFyIGM9W2UsZi5zdWJzdHJpbmcoYildO3JldHVybiBjfX1yZXR1cm5bXX1SU0FLZXkucHJvdG90eXBlLnZlcmlmeT1mdW5jdGlvbihmLGope2o9ai5yZXBsYWNlKF9SRV9IRVhERUNPTkxZLFwiXCIpO2o9ai5yZXBsYWNlKC9bIFxcbl0rL2csXCJcIik7dmFyIGI9cGFyc2VCaWdJbnQoaiwxNik7aWYoYi5iaXRMZW5ndGgoKT50aGlzLm4uYml0TGVuZ3RoKCkpe3JldHVybiAwfXZhciBpPXRoaXMuZG9QdWJsaWMoYik7dmFyIGU9aS50b1N0cmluZygxNikucmVwbGFjZSgvXjFmKzAwLyxcIlwiKTt2YXIgZz1fcnNhc2lnbl9nZXRBbGdOYW1lQW5kSGFzaEZyb21IZXhEaXNnZXN0SW5mbyhlKTtpZihnLmxlbmd0aD09MCl7cmV0dXJuIGZhbHNlfXZhciBkPWdbMF07dmFyIGg9Z1sxXTt2YXIgYT1mdW5jdGlvbihrKXtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5oYXNoU3RyaW5nKGssZCl9O3ZhciBjPWEoZik7cmV0dXJuKGg9PWMpfTtSU0FLZXkucHJvdG90eXBlLnZlcmlmeVdpdGhNZXNzYWdlSGFzaD1mdW5jdGlvbihlLGEpe2E9YS5yZXBsYWNlKF9SRV9IRVhERUNPTkxZLFwiXCIpO2E9YS5yZXBsYWNlKC9bIFxcbl0rL2csXCJcIik7dmFyIGI9cGFyc2VCaWdJbnQoYSwxNik7aWYoYi5iaXRMZW5ndGgoKT50aGlzLm4uYml0TGVuZ3RoKCkpe3JldHVybiAwfXZhciBoPXRoaXMuZG9QdWJsaWMoYik7dmFyIGc9aC50b1N0cmluZygxNikucmVwbGFjZSgvXjFmKzAwLyxcIlwiKTt2YXIgYz1fcnNhc2lnbl9nZXRBbGdOYW1lQW5kSGFzaEZyb21IZXhEaXNnZXN0SW5mbyhnKTtpZihjLmxlbmd0aD09MCl7cmV0dXJuIGZhbHNlfXZhciBkPWNbMF07dmFyIGY9Y1sxXTtyZXR1cm4oZj09ZSl9O1JTQUtleS5wcm90b3R5cGUudmVyaWZ5UFNTPWZ1bmN0aW9uKGMsYixhLGYpe3ZhciBlPWZ1bmN0aW9uKGcpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hIZXgoZyxhKX07dmFyIGQ9ZShyc3RydG9oZXgoYykpO2lmKGY9PT11bmRlZmluZWQpe2Y9LTF9cmV0dXJuIHRoaXMudmVyaWZ5V2l0aE1lc3NhZ2VIYXNoUFNTKGQsYixhLGYpfTtSU0FLZXkucHJvdG90eXBlLnZlcmlmeVdpdGhNZXNzYWdlSGFzaFBTUz1mdW5jdGlvbihmLHMsbCxjKXt2YXIgaz1uZXcgQmlnSW50ZWdlcihzLDE2KTtpZihrLmJpdExlbmd0aCgpPnRoaXMubi5iaXRMZW5ndGgoKSl7cmV0dXJuIGZhbHNlfXZhciByPWZ1bmN0aW9uKGkpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hIZXgoaSxsKX07dmFyIGo9aGV4dG9yc3RyKGYpO3ZhciBoPWoubGVuZ3RoO3ZhciBnPXRoaXMubi5iaXRMZW5ndGgoKS0xO3ZhciBtPU1hdGguY2VpbChnLzgpO3ZhciBxO2lmKGM9PT0tMXx8Yz09PXVuZGVmaW5lZCl7Yz1ofWVsc2V7aWYoYz09PS0yKXtjPW0taC0yfWVsc2V7aWYoYzwtMil7dGhyb3dcImludmFsaWQgc2FsdCBsZW5ndGhcIn19fWlmKG08KGgrYysyKSl7dGhyb3dcImRhdGEgdG9vIGxvbmdcIn12YXIgYT10aGlzLmRvUHVibGljKGspLnRvQnl0ZUFycmF5KCk7Zm9yKHE9MDtxPGEubGVuZ3RoO3ErPTEpe2FbcV0mPTI1NX13aGlsZShhLmxlbmd0aDxtKXthLnVuc2hpZnQoMCl9aWYoYVttLTFdIT09MTg4KXt0aHJvd1wiZW5jb2RlZCBtZXNzYWdlIGRvZXMgbm90IGVuZCBpbiAweGJjXCJ9YT1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxhKTt2YXIgZD1hLnN1YnN0cigwLG0taC0xKTt2YXIgZT1hLnN1YnN0cihkLmxlbmd0aCxoKTt2YXIgcD0oNjUyODA+Pig4Km0tZykpJjI1NTtpZigoZC5jaGFyQ29kZUF0KDApJnApIT09MCl7dGhyb3dcImJpdHMgYmV5b25kIGtleXNpemUgbm90IHplcm9cIn12YXIgbj1wc3NfbWdmMV9zdHIoZSxkLmxlbmd0aCxyKTt2YXIgbz1bXTtmb3IocT0wO3E8ZC5sZW5ndGg7cSs9MSl7b1txXT1kLmNoYXJDb2RlQXQocSlebi5jaGFyQ29kZUF0KHEpfW9bMF0mPX5wO3ZhciBiPW0taC1jLTI7Zm9yKHE9MDtxPGI7cSs9MSl7aWYob1txXSE9PTApe3Rocm93XCJsZWZ0bW9zdCBvY3RldHMgbm90IHplcm9cIn19aWYob1tiXSE9PTEpe3Rocm93XCIweDAxIG1hcmtlciBub3QgZm91bmRcIn1yZXR1cm4gZT09PWhleHRvcnN0cihyKHJzdHJ0b2hleChcIlxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcIitqK1N0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLG8uc2xpY2UoLWMpKSkpKX07UlNBS2V5LlNBTFRfTEVOX0hMRU49LTE7UlNBS2V5LlNBTFRfTEVOX01BWD0tMjtSU0FLZXkuU0FMVF9MRU5fUkVDT1ZFUj0tMjtcbmZ1bmN0aW9uIFg1MDkoKXt2YXIgaz1BU04xSEVYLGo9ay5nZXRDaGlsZElkeCxoPWsuZ2V0VixiPWsuZ2V0VExWLGY9ay5nZXRWYnlMaXN0LGM9ay5nZXRUTFZieUxpc3QsZz1rLmdldElkeGJ5TGlzdCxkPWsuZ2V0VmlkeCxpPWsub2lkbmFtZSxhPVg1MDksZT1wZW10b2hleDt0aGlzLmhleD1udWxsO3RoaXMudmVyc2lvbj0wO3RoaXMuZm9mZnNldD0wO3RoaXMuYUV4dEluZm89bnVsbDt0aGlzLmdldFZlcnNpb249ZnVuY3Rpb24oKXtpZih0aGlzLmhleD09PW51bGx8fHRoaXMudmVyc2lvbiE9PTApe3JldHVybiB0aGlzLnZlcnNpb259aWYoYyh0aGlzLmhleCwwLFswLDBdKSE9PVwiYTAwMzAyMDEwMlwiKXt0aGlzLnZlcnNpb249MTt0aGlzLmZvZmZzZXQ9LTE7cmV0dXJuIDF9dGhpcy52ZXJzaW9uPTM7cmV0dXJuIDN9O3RoaXMuZ2V0U2VyaWFsTnVtYmVySGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcy5oZXgsMCxbMCwxK3RoaXMuZm9mZnNldF0sXCIwMlwiKX07dGhpcy5nZXRTaWduYXR1cmVBbGdvcml0aG1GaWVsZD1mdW5jdGlvbigpe3JldHVybiBpKGYodGhpcy5oZXgsMCxbMCwyK3RoaXMuZm9mZnNldCwwXSxcIjA2XCIpKX07dGhpcy5nZXRJc3N1ZXJIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gYyh0aGlzLmhleCwwLFswLDMrdGhpcy5mb2Zmc2V0XSxcIjMwXCIpfTt0aGlzLmdldElzc3VlclN0cmluZz1mdW5jdGlvbigpe3JldHVybiBhLmhleDJkbih0aGlzLmdldElzc3VlckhleCgpKX07dGhpcy5nZXRTdWJqZWN0SGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGModGhpcy5oZXgsMCxbMCw1K3RoaXMuZm9mZnNldF0sXCIzMFwiKX07dGhpcy5nZXRTdWJqZWN0U3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIGEuaGV4MmRuKHRoaXMuZ2V0U3ViamVjdEhleCgpKX07dGhpcy5nZXROb3RCZWZvcmU9ZnVuY3Rpb24oKXt2YXIgbD1mKHRoaXMuaGV4LDAsWzAsNCt0aGlzLmZvZmZzZXQsMF0pO2w9bC5yZXBsYWNlKC8oLi4pL2csXCIlJDFcIik7bD1kZWNvZGVVUklDb21wb25lbnQobCk7cmV0dXJuIGx9O3RoaXMuZ2V0Tm90QWZ0ZXI9ZnVuY3Rpb24oKXt2YXIgbD1mKHRoaXMuaGV4LDAsWzAsNCt0aGlzLmZvZmZzZXQsMV0pO2w9bC5yZXBsYWNlKC8oLi4pL2csXCIlJDFcIik7bD1kZWNvZGVVUklDb21wb25lbnQobCk7cmV0dXJuIGx9O3RoaXMuZ2V0UHVibGljS2V5SGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGsuZ2V0VExWYnlMaXN0KHRoaXMuaGV4LDAsWzAsNit0aGlzLmZvZmZzZXRdLFwiMzBcIil9O3RoaXMuZ2V0UHVibGljS2V5SWR4PWZ1bmN0aW9uKCl7cmV0dXJuIGcodGhpcy5oZXgsMCxbMCw2K3RoaXMuZm9mZnNldF0sXCIzMFwiKX07dGhpcy5nZXRQdWJsaWNLZXlDb250ZW50SWR4PWZ1bmN0aW9uKCl7dmFyIGw9dGhpcy5nZXRQdWJsaWNLZXlJZHgoKTtyZXR1cm4gZyh0aGlzLmhleCxsLFsxLDBdLFwiMzBcIil9O3RoaXMuZ2V0UHVibGljS2V5PWZ1bmN0aW9uKCl7cmV0dXJuIEtFWVVUSUwuZ2V0S2V5KHRoaXMuZ2V0UHVibGljS2V5SGV4KCksbnVsbCxcInBrY3M4cHViXCIpfTt0aGlzLmdldFNpZ25hdHVyZUFsZ29yaXRobU5hbWU9ZnVuY3Rpb24oKXtyZXR1cm4gaShmKHRoaXMuaGV4LDAsWzEsMF0sXCIwNlwiKSl9O3RoaXMuZ2V0U2lnbmF0dXJlVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzLmhleCwwLFsyXSxcIjAzXCIsdHJ1ZSl9O3RoaXMudmVyaWZ5U2lnbmF0dXJlPWZ1bmN0aW9uKG4pe3ZhciBvPXRoaXMuZ2V0U2lnbmF0dXJlQWxnb3JpdGhtTmFtZSgpO3ZhciBsPXRoaXMuZ2V0U2lnbmF0dXJlVmFsdWVIZXgoKTt2YXIgbT1jKHRoaXMuaGV4LDAsWzBdLFwiMzBcIik7dmFyIHA9bmV3IEtKVVIuY3J5cHRvLlNpZ25hdHVyZSh7YWxnOm99KTtwLmluaXQobik7cC51cGRhdGVIZXgobSk7cmV0dXJuIHAudmVyaWZ5KGwpfTt0aGlzLnBhcnNlRXh0PWZ1bmN0aW9uKCl7aWYodGhpcy52ZXJzaW9uIT09Myl7cmV0dXJuIC0xfXZhciBwPWcodGhpcy5oZXgsMCxbMCw3LDBdLFwiMzBcIik7dmFyIG09aih0aGlzLmhleCxwKTt0aGlzLmFFeHRJbmZvPW5ldyBBcnJheSgpO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXt2YXIgcT17fTtxLmNyaXRpY2FsPWZhbHNlO3ZhciBsPWoodGhpcy5oZXgsbVtuXSk7dmFyIHI9MDtpZihsLmxlbmd0aD09PTMpe3EuY3JpdGljYWw9dHJ1ZTtyPTF9cS5vaWQ9ay5oZXh0b29pZHN0cihmKHRoaXMuaGV4LG1bbl0sWzBdLFwiMDZcIikpO3ZhciBvPWcodGhpcy5oZXgsbVtuXSxbMStyXSk7cS52aWR4PWQodGhpcy5oZXgsbyk7dGhpcy5hRXh0SW5mby5wdXNoKHEpfX07dGhpcy5nZXRFeHRJbmZvPWZ1bmN0aW9uKG4pe3ZhciBsPXRoaXMuYUV4dEluZm87dmFyIG89bjtpZighbi5tYXRjaCgvXlswLTkuXSskLykpe289S0pVUi5hc24xLng1MDkuT0lELm5hbWUyb2lkKG4pfWlmKG89PT1cIlwiKXtyZXR1cm4gdW5kZWZpbmVkfWZvcih2YXIgbT0wO208bC5sZW5ndGg7bSsrKXtpZihsW21dLm9pZD09PW8pe3JldHVybiBsW21dfX1yZXR1cm4gdW5kZWZpbmVkfTt0aGlzLmdldEV4dEJhc2ljQ29uc3RyYWludHM9ZnVuY3Rpb24oKXt2YXIgbj10aGlzLmdldEV4dEluZm8oXCJiYXNpY0NvbnN0cmFpbnRzXCIpO2lmKG49PT11bmRlZmluZWQpe3JldHVybiBufXZhciBsPWgodGhpcy5oZXgsbi52aWR4KTtpZihsPT09XCJcIil7cmV0dXJue319aWYobD09PVwiMDEwMWZmXCIpe3JldHVybntjQTp0cnVlfX1pZihsLnN1YnN0cigwLDgpPT09XCIwMTAxZmYwMlwiKXt2YXIgbz1oKGwsNik7dmFyIG09cGFyc2VJbnQobywxNik7cmV0dXJue2NBOnRydWUscGF0aExlbjptfX10aHJvd1wiYmFzaWNDb25zdHJhaW50cyBwYXJzZSBlcnJvclwifTt0aGlzLmdldEV4dEtleVVzYWdlQmluPWZ1bmN0aW9uKCl7dmFyIG89dGhpcy5nZXRFeHRJbmZvKFwia2V5VXNhZ2VcIik7aWYobz09PXVuZGVmaW5lZCl7cmV0dXJuXCJcIn12YXIgbT1oKHRoaXMuaGV4LG8udmlkeCk7aWYobS5sZW5ndGglMiE9MHx8bS5sZW5ndGg8PTIpe3Rocm93XCJtYWxmb3JtZWQga2V5IHVzYWdlIHZhbHVlXCJ9dmFyIGw9cGFyc2VJbnQobS5zdWJzdHIoMCwyKSk7dmFyIG49cGFyc2VJbnQobS5zdWJzdHIoMiksMTYpLnRvU3RyaW5nKDIpO3JldHVybiBuLnN1YnN0cigwLG4ubGVuZ3RoLWwpfTt0aGlzLmdldEV4dEtleVVzYWdlU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIG49dGhpcy5nZXRFeHRLZXlVc2FnZUJpbigpO3ZhciBsPW5ldyBBcnJheSgpO2Zvcih2YXIgbT0wO208bi5sZW5ndGg7bSsrKXtpZihuLnN1YnN0cihtLDEpPT1cIjFcIil7bC5wdXNoKFg1MDkuS0VZVVNBR0VfTkFNRVttXSl9fXJldHVybiBsLmpvaW4oXCIsXCIpfTt0aGlzLmdldEV4dFN1YmplY3RLZXlJZGVudGlmaWVyPWZ1bmN0aW9uKCl7dmFyIGw9dGhpcy5nZXRFeHRJbmZvKFwic3ViamVjdEtleUlkZW50aWZpZXJcIik7aWYobD09PXVuZGVmaW5lZCl7cmV0dXJuIGx9cmV0dXJuIGgodGhpcy5oZXgsbC52aWR4KX07dGhpcy5nZXRFeHRBdXRob3JpdHlLZXlJZGVudGlmaWVyPWZ1bmN0aW9uKCl7dmFyIHA9dGhpcy5nZXRFeHRJbmZvKFwiYXV0aG9yaXR5S2V5SWRlbnRpZmllclwiKTtpZihwPT09dW5kZWZpbmVkKXtyZXR1cm4gcH12YXIgbD17fTt2YXIgbz1iKHRoaXMuaGV4LHAudmlkeCk7dmFyIG09aihvLDApO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXtpZihvLnN1YnN0cihtW25dLDIpPT09XCI4MFwiKXtsLmtpZD1oKG8sbVtuXSl9fXJldHVybiBsfTt0aGlzLmdldEV4dEV4dEtleVVzYWdlTmFtZT1mdW5jdGlvbigpe3ZhciBwPXRoaXMuZ2V0RXh0SW5mbyhcImV4dEtleVVzYWdlXCIpO2lmKHA9PT11bmRlZmluZWQpe3JldHVybiBwfXZhciBsPW5ldyBBcnJheSgpO3ZhciBvPWIodGhpcy5oZXgscC52aWR4KTtpZihvPT09XCJcIil7cmV0dXJuIGx9dmFyIG09aihvLDApO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXtsLnB1c2goaShoKG8sbVtuXSkpKX1yZXR1cm4gbH07dGhpcy5nZXRFeHRTdWJqZWN0QWx0TmFtZT1mdW5jdGlvbigpe3ZhciBtPXRoaXMuZ2V0RXh0U3ViamVjdEFsdE5hbWUyKCk7dmFyIGw9bmV3IEFycmF5KCk7Zm9yKHZhciBuPTA7bjxtLmxlbmd0aDtuKyspe2lmKG1bbl1bMF09PT1cIkROU1wiKXtsLnB1c2gobVtuXVsxXSl9fXJldHVybiBsfTt0aGlzLmdldEV4dFN1YmplY3RBbHROYW1lMj1mdW5jdGlvbigpe3ZhciBwLHMscjt2YXIgcT10aGlzLmdldEV4dEluZm8oXCJzdWJqZWN0QWx0TmFtZVwiKTtpZihxPT09dW5kZWZpbmVkKXtyZXR1cm4gcX12YXIgbD1uZXcgQXJyYXkoKTt2YXIgbz1iKHRoaXMuaGV4LHEudmlkeCk7dmFyIG09aihvLDApO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXtyPW8uc3Vic3RyKG1bbl0sMik7cD1oKG8sbVtuXSk7aWYocj09PVwiODFcIil7cz1oZXh0b3V0ZjgocCk7bC5wdXNoKFtcIk1BSUxcIixzXSl9aWYocj09PVwiODJcIil7cz1oZXh0b3V0ZjgocCk7bC5wdXNoKFtcIkROU1wiLHNdKX1pZihyPT09XCI4NFwiKXtzPVg1MDkuaGV4MmRuKHAsMCk7bC5wdXNoKFtcIkROXCIsc10pfWlmKHI9PT1cIjg2XCIpe3M9aGV4dG91dGY4KHApO2wucHVzaChbXCJVUklcIixzXSl9aWYocj09PVwiODdcIil7cz1oZXh0b2lwKHApO2wucHVzaChbXCJJUFwiLHNdKX19cmV0dXJuIGx9O3RoaXMuZ2V0RXh0Q1JMRGlzdHJpYnV0aW9uUG9pbnRzVVJJPWZ1bmN0aW9uKCl7dmFyIHE9dGhpcy5nZXRFeHRJbmZvKFwiY1JMRGlzdHJpYnV0aW9uUG9pbnRzXCIpO2lmKHE9PT11bmRlZmluZWQpe3JldHVybiBxfXZhciBsPW5ldyBBcnJheSgpO3ZhciBtPWoodGhpcy5oZXgscS52aWR4KTtmb3IodmFyIG89MDtvPG0ubGVuZ3RoO28rKyl7dHJ5e3ZhciByPWYodGhpcy5oZXgsbVtvXSxbMCwwLDBdLFwiODZcIik7dmFyIHA9aGV4dG91dGY4KHIpO2wucHVzaChwKX1jYXRjaChuKXt9fXJldHVybiBsfTt0aGlzLmdldEV4dEFJQUluZm89ZnVuY3Rpb24oKXt2YXIgcD10aGlzLmdldEV4dEluZm8oXCJhdXRob3JpdHlJbmZvQWNjZXNzXCIpO2lmKHA9PT11bmRlZmluZWQpe3JldHVybiBwfXZhciBsPXtvY3NwOltdLGNhaXNzdWVyOltdfTt2YXIgbT1qKHRoaXMuaGV4LHAudmlkeCk7Zm9yKHZhciBuPTA7bjxtLmxlbmd0aDtuKyspe3ZhciBxPWYodGhpcy5oZXgsbVtuXSxbMF0sXCIwNlwiKTt2YXIgbz1mKHRoaXMuaGV4LG1bbl0sWzFdLFwiODZcIik7aWYocT09PVwiMmIwNjAxMDUwNTA3MzAwMVwiKXtsLm9jc3AucHVzaChoZXh0b3V0ZjgobykpfWlmKHE9PT1cIjJiMDYwMTA1MDUwNzMwMDJcIil7bC5jYWlzc3Vlci5wdXNoKGhleHRvdXRmOChvKSl9fXJldHVybiBsfTt0aGlzLmdldEV4dENlcnRpZmljYXRlUG9saWNpZXM9ZnVuY3Rpb24oKXt2YXIgbz10aGlzLmdldEV4dEluZm8oXCJjZXJ0aWZpY2F0ZVBvbGljaWVzXCIpO2lmKG89PT11bmRlZmluZWQpe3JldHVybiBvfXZhciBsPWIodGhpcy5oZXgsby52aWR4KTt2YXIgdT1bXTt2YXIgcz1qKGwsMCk7Zm9yKHZhciByPTA7cjxzLmxlbmd0aDtyKyspe3ZhciB0PXt9O3ZhciBuPWoobCxzW3JdKTt0LmlkPWkoaChsLG5bMF0pKTtpZihuLmxlbmd0aD09PTIpe3ZhciBtPWoobCxuWzFdKTtmb3IodmFyIHE9MDtxPG0ubGVuZ3RoO3ErKyl7dmFyIHA9ZihsLG1bcV0sWzBdLFwiMDZcIik7aWYocD09PVwiMmIwNjAxMDUwNTA3MDIwMVwiKXt0LmNwcz1oZXh0b3V0ZjgoZihsLG1bcV0sWzFdKSl9ZWxzZXtpZihwPT09XCIyYjA2MDEwNTA1MDcwMjAyXCIpe3QudW5vdGljZT1oZXh0b3V0ZjgoZihsLG1bcV0sWzEsMF0pKX19fX11LnB1c2godCl9cmV0dXJuIHV9O3RoaXMucmVhZENlcnRQRU09ZnVuY3Rpb24obCl7dGhpcy5yZWFkQ2VydEhleChlKGwpKX07dGhpcy5yZWFkQ2VydEhleD1mdW5jdGlvbihsKXt0aGlzLmhleD1sO3RoaXMuZ2V0VmVyc2lvbigpO3RyeXtnKHRoaXMuaGV4LDAsWzAsN10sXCJhM1wiKTt0aGlzLnBhcnNlRXh0KCl9Y2F0Y2gobSl7fX07dGhpcy5nZXRJbmZvPWZ1bmN0aW9uKCl7dmFyIG09WDUwOTt2YXIgQix1LHo7Qj1cIkJhc2ljIEZpZWxkc1xcblwiO0IrPVwiICBzZXJpYWwgbnVtYmVyOiBcIit0aGlzLmdldFNlcmlhbE51bWJlckhleCgpK1wiXFxuXCI7Qis9XCIgIHNpZ25hdHVyZSBhbGdvcml0aG06IFwiK3RoaXMuZ2V0U2lnbmF0dXJlQWxnb3JpdGhtRmllbGQoKStcIlxcblwiO0IrPVwiICBpc3N1ZXI6IFwiK3RoaXMuZ2V0SXNzdWVyU3RyaW5nKCkrXCJcXG5cIjtCKz1cIiAgbm90QmVmb3JlOiBcIit0aGlzLmdldE5vdEJlZm9yZSgpK1wiXFxuXCI7Qis9XCIgIG5vdEFmdGVyOiBcIit0aGlzLmdldE5vdEFmdGVyKCkrXCJcXG5cIjtCKz1cIiAgc3ViamVjdDogXCIrdGhpcy5nZXRTdWJqZWN0U3RyaW5nKCkrXCJcXG5cIjtCKz1cIiAgc3ViamVjdCBwdWJsaWMga2V5IGluZm86IFxcblwiO3U9dGhpcy5nZXRQdWJsaWNLZXkoKTtCKz1cIiAgICBrZXkgYWxnb3JpdGhtOiBcIit1LnR5cGUrXCJcXG5cIjtpZih1LnR5cGU9PT1cIlJTQVwiKXtCKz1cIiAgICBuPVwiK2hleHRvcG9zaGV4KHUubi50b1N0cmluZygxNikpLnN1YnN0cigwLDE2KStcIi4uLlxcblwiO0IrPVwiICAgIGU9XCIraGV4dG9wb3NoZXgodS5lLnRvU3RyaW5nKDE2KSkrXCJcXG5cIn16PXRoaXMuYUV4dEluZm87aWYoeiE9PXVuZGVmaW5lZCYmeiE9PW51bGwpe0IrPVwiWDUwOXYzIEV4dGVuc2lvbnM6XFxuXCI7Zm9yKHZhciByPTA7cjx6Lmxlbmd0aDtyKyspe3ZhciBuPXpbcl07dmFyIEE9S0pVUi5hc24xLng1MDkuT0lELm9pZDJuYW1lKG4ub2lkKTtpZihBPT09XCJcIil7QT1uLm9pZH12YXIgeD1cIlwiO2lmKG4uY3JpdGljYWw9PT10cnVlKXt4PVwiQ1JJVElDQUxcIn1CKz1cIiAgXCIrQStcIiBcIit4K1wiOlxcblwiO2lmKEE9PT1cImJhc2ljQ29uc3RyYWludHNcIil7dmFyIHY9dGhpcy5nZXRFeHRCYXNpY0NvbnN0cmFpbnRzKCk7aWYodi5jQT09PXVuZGVmaW5lZCl7Qis9XCIgICAge31cXG5cIn1lbHNle0IrPVwiICAgIGNBPXRydWVcIjtpZih2LnBhdGhMZW4hPT11bmRlZmluZWQpe0IrPVwiLCBwYXRoTGVuPVwiK3YucGF0aExlbn1CKz1cIlxcblwifX1lbHNle2lmKEE9PT1cImtleVVzYWdlXCIpe0IrPVwiICAgIFwiK3RoaXMuZ2V0RXh0S2V5VXNhZ2VTdHJpbmcoKStcIlxcblwifWVsc2V7aWYoQT09PVwic3ViamVjdEtleUlkZW50aWZpZXJcIil7Qis9XCIgICAgXCIrdGhpcy5nZXRFeHRTdWJqZWN0S2V5SWRlbnRpZmllcigpK1wiXFxuXCJ9ZWxzZXtpZihBPT09XCJhdXRob3JpdHlLZXlJZGVudGlmaWVyXCIpe3ZhciBsPXRoaXMuZ2V0RXh0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpO2lmKGwua2lkIT09dW5kZWZpbmVkKXtCKz1cIiAgICBraWQ9XCIrbC5raWQrXCJcXG5cIn19ZWxzZXtpZihBPT09XCJleHRLZXlVc2FnZVwiKXt2YXIgdz10aGlzLmdldEV4dEV4dEtleVVzYWdlTmFtZSgpO0IrPVwiICAgIFwiK3cuam9pbihcIiwgXCIpK1wiXFxuXCJ9ZWxzZXtpZihBPT09XCJzdWJqZWN0QWx0TmFtZVwiKXt2YXIgdD10aGlzLmdldEV4dFN1YmplY3RBbHROYW1lMigpO0IrPVwiICAgIFwiK3QrXCJcXG5cIn1lbHNle2lmKEE9PT1cImNSTERpc3RyaWJ1dGlvblBvaW50c1wiKXt2YXIgeT10aGlzLmdldEV4dENSTERpc3RyaWJ1dGlvblBvaW50c1VSSSgpO0IrPVwiICAgIFwiK3krXCJcXG5cIn1lbHNle2lmKEE9PT1cImF1dGhvcml0eUluZm9BY2Nlc3NcIil7dmFyIHA9dGhpcy5nZXRFeHRBSUFJbmZvKCk7aWYocC5vY3NwIT09dW5kZWZpbmVkKXtCKz1cIiAgICBvY3NwOiBcIitwLm9jc3Auam9pbihcIixcIikrXCJcXG5cIn1pZihwLmNhaXNzdWVyIT09dW5kZWZpbmVkKXtCKz1cIiAgICBjYWlzc3VlcjogXCIrcC5jYWlzc3Vlci5qb2luKFwiLFwiKStcIlxcblwifX1lbHNle2lmKEE9PT1cImNlcnRpZmljYXRlUG9saWNpZXNcIil7dmFyIG89dGhpcy5nZXRFeHRDZXJ0aWZpY2F0ZVBvbGljaWVzKCk7Zm9yKHZhciBxPTA7cTxvLmxlbmd0aDtxKyspe2lmKG9bcV0uaWQhPT11bmRlZmluZWQpe0IrPVwiICAgIHBvbGljeSBvaWQ6IFwiK29bcV0uaWQrXCJcXG5cIn1pZihvW3FdLmNwcyE9PXVuZGVmaW5lZCl7Qis9XCIgICAgY3BzOiBcIitvW3FdLmNwcytcIlxcblwifX19fX19fX19fX19fUIrPVwic2lnbmF0dXJlIGFsZ29yaXRobTogXCIrdGhpcy5nZXRTaWduYXR1cmVBbGdvcml0aG1OYW1lKCkrXCJcXG5cIjtCKz1cInNpZ25hdHVyZTogXCIrdGhpcy5nZXRTaWduYXR1cmVWYWx1ZUhleCgpLnN1YnN0cigwLDE2KStcIi4uLlxcblwiO3JldHVybiBCfX1YNTA5LmhleDJkbj1mdW5jdGlvbihmLGIpe2lmKGI9PT11bmRlZmluZWQpe2I9MH1pZihmLnN1YnN0cihiLDIpIT09XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIEROXCJ9dmFyIGM9bmV3IEFycmF5KCk7dmFyIGQ9QVNOMUhFWC5nZXRDaGlsZElkeChmLGIpO2Zvcih2YXIgZT0wO2U8ZC5sZW5ndGg7ZSsrKXtjLnB1c2goWDUwOS5oZXgycmRuKGYsZFtlXSkpfWM9Yy5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEucmVwbGFjZShcIi9cIixcIlxcXFwvXCIpfSk7cmV0dXJuXCIvXCIrYy5qb2luKFwiL1wiKX07WDUwOS5oZXgycmRuPWZ1bmN0aW9uKGYsYil7aWYoYj09PXVuZGVmaW5lZCl7Yj0wfWlmKGYuc3Vic3RyKGIsMikhPT1cIjMxXCIpe3Rocm93XCJtYWxmb3JtZWQgUkROXCJ9dmFyIGM9bmV3IEFycmF5KCk7dmFyIGQ9QVNOMUhFWC5nZXRDaGlsZElkeChmLGIpO2Zvcih2YXIgZT0wO2U8ZC5sZW5ndGg7ZSsrKXtjLnB1c2goWDUwOS5oZXgyYXR0clR5cGVWYWx1ZShmLGRbZV0pKX1jPWMubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBhLnJlcGxhY2UoXCIrXCIsXCJcXFxcK1wiKX0pO3JldHVybiBjLmpvaW4oXCIrXCIpfTtYNTA5LmhleDJhdHRyVHlwZVZhbHVlPWZ1bmN0aW9uKGQsaSl7dmFyIGo9QVNOMUhFWDt2YXIgaD1qLmdldFY7aWYoaT09PXVuZGVmaW5lZCl7aT0wfWlmKGQuc3Vic3RyKGksMikhPT1cIjMwXCIpe3Rocm93XCJtYWxmb3JtZWQgYXR0cmlidXRlIHR5cGUgYW5kIHZhbHVlXCJ9dmFyIGc9ai5nZXRDaGlsZElkeChkLGkpO2lmKGcubGVuZ3RoIT09Mnx8ZC5zdWJzdHIoZ1swXSwyKSE9PVwiMDZcIil7XCJtYWxmb3JtZWQgYXR0cmlidXRlIHR5cGUgYW5kIHZhbHVlXCJ9dmFyIGI9aChkLGdbMF0pO3ZhciBmPUtKVVIuYXNuMS5BU04xVXRpbC5vaWRIZXhUb0ludChiKTt2YXIgZT1LSlVSLmFzbjEueDUwOS5PSUQub2lkMmF0eXBlKGYpO3ZhciBhPWgoZCxnWzFdKTt2YXIgYz1oZXh0b3JzdHIoYSk7cmV0dXJuIGUrXCI9XCIrY307WDUwOS5nZXRQdWJsaWNLZXlGcm9tQ2VydEhleD1mdW5jdGlvbihiKXt2YXIgYT1uZXcgWDUwOSgpO2EucmVhZENlcnRIZXgoYik7cmV0dXJuIGEuZ2V0UHVibGljS2V5KCl9O1g1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRQRU09ZnVuY3Rpb24oYil7dmFyIGE9bmV3IFg1MDkoKTthLnJlYWRDZXJ0UEVNKGIpO3JldHVybiBhLmdldFB1YmxpY0tleSgpfTtYNTA5LmdldFB1YmxpY0tleUluZm9Qcm9wT2ZDZXJ0UEVNPWZ1bmN0aW9uKGMpe3ZhciBlPUFTTjFIRVg7dmFyIGc9ZS5nZXRWYnlMaXN0O3ZhciBiPXt9O3ZhciBhLGYsZDtiLmFsZ3BhcmFtPW51bGw7YT1uZXcgWDUwOSgpO2EucmVhZENlcnRQRU0oYyk7Zj1hLmdldFB1YmxpY0tleUhleCgpO2Iua2V5aGV4PWcoZiwwLFsxXSxcIjAzXCIpLnN1YnN0cigyKTtiLmFsZ29pZD1nKGYsMCxbMCwwXSxcIjA2XCIpO2lmKGIuYWxnb2lkPT09XCIyYTg2NDhjZTNkMDIwMVwiKXtiLmFsZ3BhcmFtPWcoZiwwLFswLDFdLFwiMDZcIil9cmV0dXJuIGJ9O1g1MDkuS0VZVVNBR0VfTkFNRT1bXCJkaWdpdGFsU2lnbmF0dXJlXCIsXCJub25SZXB1ZGlhdGlvblwiLFwia2V5RW5jaXBoZXJtZW50XCIsXCJkYXRhRW5jaXBoZXJtZW50XCIsXCJrZXlBZ3JlZW1lbnRcIixcImtleUNlcnRTaWduXCIsXCJjUkxTaWduXCIsXCJlbmNpcGhlck9ubHlcIixcImRlY2lwaGVyT25seVwiXTtcbmlmKHR5cGVvZiBLSlVSPT1cInVuZGVmaW5lZFwifHwhS0pVUil7S0pVUj17fX1pZih0eXBlb2YgS0pVUi5qd3M9PVwidW5kZWZpbmVkXCJ8fCFLSlVSLmp3cyl7S0pVUi5qd3M9e319S0pVUi5qd3MuSldTPWZ1bmN0aW9uKCl7dmFyIGI9S0pVUixhPWIuandzLkpXUyxjPWEuaXNTYWZlSlNPTlN0cmluZzt0aGlzLnBhcnNlSldTPWZ1bmN0aW9uKGcsail7aWYoKHRoaXMucGFyc2VkSldTIT09dW5kZWZpbmVkKSYmKGp8fCh0aGlzLnBhcnNlZEpXUy5zaWd2YWxIIT09dW5kZWZpbmVkKSkpe3JldHVybn12YXIgaT1nLm1hdGNoKC9eKFteLl0rKVxcLihbXi5dKylcXC4oW14uXSspJC8pO2lmKGk9PW51bGwpe3Rocm93XCJKV1Mgc2lnbmF0dXJlIGlzIG5vdCBhIGZvcm0gb2YgJ0hlYWQuUGF5bG9hZC5TaWdWYWx1ZScuXCJ9dmFyIGs9aVsxXTt2YXIgZT1pWzJdO3ZhciBsPWlbM107dmFyIG49aytcIi5cIitlO3RoaXMucGFyc2VkSldTPXt9O3RoaXMucGFyc2VkSldTLmhlYWRCNjRVPWs7dGhpcy5wYXJzZWRKV1MucGF5bG9hZEI2NFU9ZTt0aGlzLnBhcnNlZEpXUy5zaWd2YWxCNjRVPWw7dGhpcy5wYXJzZWRKV1Muc2k9bjtpZighail7dmFyIGg9YjY0dXRvaGV4KGwpO3ZhciBmPXBhcnNlQmlnSW50KGgsMTYpO3RoaXMucGFyc2VkSldTLnNpZ3ZhbEg9aDt0aGlzLnBhcnNlZEpXUy5zaWd2YWxCST1mfXZhciBkPWI2NHV0b3V0Zjgoayk7dmFyIG09YjY0dXRvdXRmOChlKTt0aGlzLnBhcnNlZEpXUy5oZWFkUz1kO3RoaXMucGFyc2VkSldTLnBheWxvYWRTPW07aWYoIWMoZCx0aGlzLnBhcnNlZEpXUyxcImhlYWRQXCIpKXt0aHJvd1wibWFsZm9ybWVkIEpTT04gc3RyaW5nIGZvciBKV1MgSGVhZDogXCIrZH19fTtLSlVSLmp3cy5KV1Muc2lnbj1mdW5jdGlvbihpLHYseSx6LGEpe3ZhciB3PUtKVVIsbT13Lmp3cyxxPW0uSldTLGc9cS5yZWFkU2FmZUpTT05TdHJpbmcscD1xLmlzU2FmZUpTT05TdHJpbmcsZD13LmNyeXB0byxrPWQuRUNEU0Esbz1kLk1hYyxjPWQuU2lnbmF0dXJlLHQ9SlNPTjt2YXIgcyxqLG47aWYodHlwZW9mIHYhPVwic3RyaW5nXCImJnR5cGVvZiB2IT1cIm9iamVjdFwiKXt0aHJvd1wic3BIZWFkZXIgbXVzdCBiZSBKU09OIHN0cmluZyBvciBvYmplY3Q6IFwiK3Z9aWYodHlwZW9mIHY9PVwib2JqZWN0XCIpe2o9djtzPXQuc3RyaW5naWZ5KGopfWlmKHR5cGVvZiB2PT1cInN0cmluZ1wiKXtzPXY7aWYoIXAocykpe3Rocm93XCJKV1MgSGVhZCBpcyBub3Qgc2FmZSBKU09OIHN0cmluZzogXCIrc31qPWcocyl9bj15O2lmKHR5cGVvZiB5PT1cIm9iamVjdFwiKXtuPXQuc3RyaW5naWZ5KHkpfWlmKChpPT1cIlwifHxpPT1udWxsKSYmai5hbGchPT11bmRlZmluZWQpe2k9ai5hbGd9aWYoKGkhPVwiXCImJmkhPW51bGwpJiZqLmFsZz09PXVuZGVmaW5lZCl7ai5hbGc9aTtzPXQuc3RyaW5naWZ5KGopfWlmKGkhPT1qLmFsZyl7dGhyb3dcImFsZyBhbmQgc0hlYWRlci5hbGcgZG9lc24ndCBtYXRjaDogXCIraStcIiE9XCIrai5hbGd9dmFyIHI9bnVsbDtpZihxLmp3c2FsZzJzaWdhbGdbaV09PT11bmRlZmluZWQpe3Rocm93XCJ1bnN1cHBvcnRlZCBhbGcgbmFtZTogXCIraX1lbHNle3I9cS5qd3NhbGcyc2lnYWxnW2ldfXZhciBlPXV0Zjh0b2I2NHUocyk7dmFyIGw9dXRmOHRvYjY0dShuKTt2YXIgYj1lK1wiLlwiK2w7dmFyIHg9XCJcIjtpZihyLnN1YnN0cigwLDQpPT1cIkhtYWNcIil7aWYoej09PXVuZGVmaW5lZCl7dGhyb3dcIm1hYyBrZXkgc2hhbGwgYmUgc3BlY2lmaWVkIGZvciBIUyogYWxnXCJ9dmFyIGg9bmV3IG8oe2FsZzpyLHByb3Y6XCJjcnlwdG9qc1wiLHBhc3M6en0pO2gudXBkYXRlU3RyaW5nKGIpO3g9aC5kb0ZpbmFsKCl9ZWxzZXtpZihyLmluZGV4T2YoXCJ3aXRoRUNEU0FcIikhPS0xKXt2YXIgZj1uZXcgYyh7YWxnOnJ9KTtmLmluaXQoeixhKTtmLnVwZGF0ZVN0cmluZyhiKTtoQVNOMVNpZz1mLnNpZ24oKTt4PUtKVVIuY3J5cHRvLkVDRFNBLmFzbjFTaWdUb0NvbmNhdFNpZyhoQVNOMVNpZyl9ZWxzZXtpZihyIT1cIm5vbmVcIil7dmFyIGY9bmV3IGMoe2FsZzpyfSk7Zi5pbml0KHosYSk7Zi51cGRhdGVTdHJpbmcoYik7eD1mLnNpZ24oKX19fXZhciB1PWhleHRvYjY0dSh4KTtyZXR1cm4gYitcIi5cIit1fTtLSlVSLmp3cy5KV1MudmVyaWZ5PWZ1bmN0aW9uKHcsQixuKXt2YXIgeD1LSlVSLHE9eC5qd3MsdD1xLkpXUyxpPXQucmVhZFNhZmVKU09OU3RyaW5nLGU9eC5jcnlwdG8scD1lLkVDRFNBLHM9ZS5NYWMsZD1lLlNpZ25hdHVyZSxtO2lmKHR5cGVvZiBSU0FLZXkhPT11bmRlZmluZWQpe209UlNBS2V5fXZhciB5PXcuc3BsaXQoXCIuXCIpO2lmKHkubGVuZ3RoIT09Myl7cmV0dXJuIGZhbHNlfXZhciBmPXlbMF07dmFyIHI9eVsxXTt2YXIgYz1mK1wiLlwiK3I7dmFyIEE9YjY0dXRvaGV4KHlbMl0pO3ZhciBsPWkoYjY0dXRvdXRmOCh5WzBdKSk7dmFyIGs9bnVsbDt2YXIgej1udWxsO2lmKGwuYWxnPT09dW5kZWZpbmVkKXt0aHJvd1wiYWxnb3JpdGhtIG5vdCBzcGVjaWZpZWQgaW4gaGVhZGVyXCJ9ZWxzZXtrPWwuYWxnO3o9ay5zdWJzdHIoMCwyKX1pZihuIT1udWxsJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobik9PT1cIltvYmplY3QgQXJyYXldXCImJm4ubGVuZ3RoPjApe3ZhciBiPVwiOlwiK24uam9pbihcIjpcIikrXCI6XCI7aWYoYi5pbmRleE9mKFwiOlwiK2srXCI6XCIpPT0tMSl7dGhyb3dcImFsZ29yaXRobSAnXCIraytcIicgbm90IGFjY2VwdGVkIGluIHRoZSBsaXN0XCJ9fWlmKGshPVwibm9uZVwiJiZCPT09bnVsbCl7dGhyb3dcImtleSBzaGFsbCBiZSBzcGVjaWZpZWQgdG8gdmVyaWZ5LlwifWlmKHR5cGVvZiBCPT1cInN0cmluZ1wiJiZCLmluZGV4T2YoXCItLS0tLUJFR0lOIFwiKSE9LTEpe0I9S0VZVVRJTC5nZXRLZXkoQil9aWYoej09XCJSU1wifHx6PT1cIlBTXCIpe2lmKCEoQiBpbnN0YW5jZW9mIG0pKXt0aHJvd1wia2V5IHNoYWxsIGJlIGEgUlNBS2V5IG9iaiBmb3IgUlMqIGFuZCBQUyogYWxnc1wifX1pZih6PT1cIkVTXCIpe2lmKCEoQiBpbnN0YW5jZW9mIHApKXt0aHJvd1wia2V5IHNoYWxsIGJlIGEgRUNEU0Egb2JqIGZvciBFUyogYWxnc1wifX1pZihrPT1cIm5vbmVcIil7fXZhciB1PW51bGw7aWYodC5qd3NhbGcyc2lnYWxnW2wuYWxnXT09PXVuZGVmaW5lZCl7dGhyb3dcInVuc3VwcG9ydGVkIGFsZyBuYW1lOiBcIitrfWVsc2V7dT10Lmp3c2FsZzJzaWdhbGdba119aWYodT09XCJub25lXCIpe3Rocm93XCJub3Qgc3VwcG9ydGVkXCJ9ZWxzZXtpZih1LnN1YnN0cigwLDQpPT1cIkhtYWNcIil7dmFyIG89bnVsbDtpZihCPT09dW5kZWZpbmVkKXt0aHJvd1wiaGV4YWRlY2ltYWwga2V5IHNoYWxsIGJlIHNwZWNpZmllZCBmb3IgSE1BQ1wifXZhciBqPW5ldyBzKHthbGc6dSxwYXNzOkJ9KTtqLnVwZGF0ZVN0cmluZyhjKTtvPWouZG9GaW5hbCgpO3JldHVybiBBPT1vfWVsc2V7aWYodS5pbmRleE9mKFwid2l0aEVDRFNBXCIpIT0tMSl7dmFyIGg9bnVsbDt0cnl7aD1wLmNvbmNhdFNpZ1RvQVNOMVNpZyhBKX1jYXRjaCh2KXtyZXR1cm4gZmFsc2V9dmFyIGc9bmV3IGQoe2FsZzp1fSk7Zy5pbml0KEIpO2cudXBkYXRlU3RyaW5nKGMpO3JldHVybiBnLnZlcmlmeShoKX1lbHNle3ZhciBnPW5ldyBkKHthbGc6dX0pO2cuaW5pdChCKTtnLnVwZGF0ZVN0cmluZyhjKTtyZXR1cm4gZy52ZXJpZnkoQSl9fX19O0tKVVIuandzLkpXUy5wYXJzZT1mdW5jdGlvbihnKXt2YXIgYz1nLnNwbGl0KFwiLlwiKTt2YXIgYj17fTt2YXIgZixlLGQ7aWYoYy5sZW5ndGghPTImJmMubGVuZ3RoIT0zKXt0aHJvd1wibWFsZm9ybWVkIHNKV1M6IHdyb25nIG51bWJlciBvZiAnLicgc3BsaXR0ZWQgZWxlbWVudHNcIn1mPWNbMF07ZT1jWzFdO2lmKGMubGVuZ3RoPT0zKXtkPWNbMl19Yi5oZWFkZXJPYmo9S0pVUi5qd3MuSldTLnJlYWRTYWZlSlNPTlN0cmluZyhiNjR1dG91dGY4KGYpKTtiLnBheWxvYWRPYmo9S0pVUi5qd3MuSldTLnJlYWRTYWZlSlNPTlN0cmluZyhiNjR1dG91dGY4KGUpKTtiLmhlYWRlclBQPUpTT04uc3RyaW5naWZ5KGIuaGVhZGVyT2JqLG51bGwsXCIgIFwiKTtpZihiLnBheWxvYWRPYmo9PW51bGwpe2IucGF5bG9hZFBQPWI2NHV0b3V0ZjgoZSl9ZWxzZXtiLnBheWxvYWRQUD1KU09OLnN0cmluZ2lmeShiLnBheWxvYWRPYmosbnVsbCxcIiAgXCIpfWlmKGQhPT11bmRlZmluZWQpe2Iuc2lnSGV4PWI2NHV0b2hleChkKX1yZXR1cm4gYn07S0pVUi5qd3MuSldTLnZlcmlmeUpXVD1mdW5jdGlvbihlLGwscil7dmFyIGQ9S0pVUixqPWQuandzLG89ai5KV1Msbj1vLnJlYWRTYWZlSlNPTlN0cmluZyxwPW8uaW5BcnJheSxmPW8uaW5jbHVkZWRBcnJheTt2YXIgaz1lLnNwbGl0KFwiLlwiKTt2YXIgYz1rWzBdO3ZhciBpPWtbMV07dmFyIHE9YytcIi5cIitpO3ZhciBtPWI2NHV0b2hleChrWzJdKTt2YXIgaD1uKGI2NHV0b3V0ZjgoYykpO3ZhciBnPW4oYjY0dXRvdXRmOChpKSk7aWYoaC5hbGc9PT11bmRlZmluZWQpe3JldHVybiBmYWxzZX1pZihyLmFsZz09PXVuZGVmaW5lZCl7dGhyb3dcImFjY2VwdEZpZWxkLmFsZyBzaGFsbCBiZSBzcGVjaWZpZWRcIn1pZighcChoLmFsZyxyLmFsZykpe3JldHVybiBmYWxzZX1pZihnLmlzcyE9PXVuZGVmaW5lZCYmdHlwZW9mIHIuaXNzPT09XCJvYmplY3RcIil7aWYoIXAoZy5pc3Msci5pc3MpKXtyZXR1cm4gZmFsc2V9fWlmKGcuc3ViIT09dW5kZWZpbmVkJiZ0eXBlb2Ygci5zdWI9PT1cIm9iamVjdFwiKXtpZighcChnLnN1YixyLnN1Yikpe3JldHVybiBmYWxzZX19aWYoZy5hdWQhPT11bmRlZmluZWQmJnR5cGVvZiByLmF1ZD09PVwib2JqZWN0XCIpe2lmKHR5cGVvZiBnLmF1ZD09XCJzdHJpbmdcIil7aWYoIXAoZy5hdWQsci5hdWQpKXtyZXR1cm4gZmFsc2V9fWVsc2V7aWYodHlwZW9mIGcuYXVkPT1cIm9iamVjdFwiKXtpZighZihnLmF1ZCxyLmF1ZCkpe3JldHVybiBmYWxzZX19fX12YXIgYj1qLkludERhdGUuZ2V0Tm93KCk7aWYoci52ZXJpZnlBdCE9PXVuZGVmaW5lZCYmdHlwZW9mIHIudmVyaWZ5QXQ9PT1cIm51bWJlclwiKXtiPXIudmVyaWZ5QXR9aWYoci5ncmFjZVBlcmlvZD09PXVuZGVmaW5lZHx8dHlwZW9mIHIuZ3JhY2VQZXJpb2QhPT1cIm51bWJlclwiKXtyLmdyYWNlUGVyaW9kPTB9aWYoZy5leHAhPT11bmRlZmluZWQmJnR5cGVvZiBnLmV4cD09XCJudW1iZXJcIil7aWYoZy5leHArci5ncmFjZVBlcmlvZDxiKXtyZXR1cm4gZmFsc2V9fWlmKGcubmJmIT09dW5kZWZpbmVkJiZ0eXBlb2YgZy5uYmY9PVwibnVtYmVyXCIpe2lmKGI8Zy5uYmYtci5ncmFjZVBlcmlvZCl7cmV0dXJuIGZhbHNlfX1pZihnLmlhdCE9PXVuZGVmaW5lZCYmdHlwZW9mIGcuaWF0PT1cIm51bWJlclwiKXtpZihiPGcuaWF0LXIuZ3JhY2VQZXJpb2Qpe3JldHVybiBmYWxzZX19aWYoZy5qdGkhPT11bmRlZmluZWQmJnIuanRpIT09dW5kZWZpbmVkKXtpZihnLmp0aSE9PXIuanRpKXtyZXR1cm4gZmFsc2V9fWlmKCFvLnZlcmlmeShlLGwsci5hbGcpKXtyZXR1cm4gZmFsc2V9cmV0dXJuIHRydWV9O0tKVVIuandzLkpXUy5pbmNsdWRlZEFycmF5PWZ1bmN0aW9uKGIsYSl7dmFyIGM9S0pVUi5qd3MuSldTLmluQXJyYXk7aWYoYj09PW51bGwpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYiE9PVwib2JqZWN0XCIpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYi5sZW5ndGghPT1cIm51bWJlclwiKXtyZXR1cm4gZmFsc2V9Zm9yKHZhciBkPTA7ZDxiLmxlbmd0aDtkKyspe2lmKCFjKGJbZF0sYSkpe3JldHVybiBmYWxzZX19cmV0dXJuIHRydWV9O0tKVVIuandzLkpXUy5pbkFycmF5PWZ1bmN0aW9uKGQsYil7aWYoYj09PW51bGwpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYiE9PVwib2JqZWN0XCIpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYi5sZW5ndGghPT1cIm51bWJlclwiKXtyZXR1cm4gZmFsc2V9Zm9yKHZhciBjPTA7YzxiLmxlbmd0aDtjKyspe2lmKGJbY109PWQpe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9O0tKVVIuandzLkpXUy5qd3NhbGcyc2lnYWxnPXtIUzI1NjpcIkhtYWNTSEEyNTZcIixIUzM4NDpcIkhtYWNTSEEzODRcIixIUzUxMjpcIkhtYWNTSEE1MTJcIixSUzI1NjpcIlNIQTI1NndpdGhSU0FcIixSUzM4NDpcIlNIQTM4NHdpdGhSU0FcIixSUzUxMjpcIlNIQTUxMndpdGhSU0FcIixFUzI1NjpcIlNIQTI1NndpdGhFQ0RTQVwiLEVTMzg0OlwiU0hBMzg0d2l0aEVDRFNBXCIsUFMyNTY6XCJTSEEyNTZ3aXRoUlNBYW5kTUdGMVwiLFBTMzg0OlwiU0hBMzg0d2l0aFJTQWFuZE1HRjFcIixQUzUxMjpcIlNIQTUxMndpdGhSU0FhbmRNR0YxXCIsbm9uZTpcIm5vbmVcIix9O0tKVVIuandzLkpXUy5pc1NhZmVKU09OU3RyaW5nPWZ1bmN0aW9uKGMsYixkKXt2YXIgZT1udWxsO3RyeXtlPWpzb25QYXJzZShjKTtpZih0eXBlb2YgZSE9XCJvYmplY3RcIil7cmV0dXJuIDB9aWYoZS5jb25zdHJ1Y3Rvcj09PUFycmF5KXtyZXR1cm4gMH1pZihiKXtiW2RdPWV9cmV0dXJuIDF9Y2F0Y2goYSl7cmV0dXJuIDB9fTtLSlVSLmp3cy5KV1MucmVhZFNhZmVKU09OU3RyaW5nPWZ1bmN0aW9uKGIpe3ZhciBjPW51bGw7dHJ5e2M9anNvblBhcnNlKGIpO2lmKHR5cGVvZiBjIT1cIm9iamVjdFwiKXtyZXR1cm4gbnVsbH1pZihjLmNvbnN0cnVjdG9yPT09QXJyYXkpe3JldHVybiBudWxsfXJldHVybiBjfWNhdGNoKGEpe3JldHVybiBudWxsfX07S0pVUi5qd3MuSldTLmdldEVuY29kZWRTaWduYXR1cmVWYWx1ZUZyb21KV1M9ZnVuY3Rpb24oYil7dmFyIGE9Yi5tYXRjaCgvXlteLl0rXFwuW14uXStcXC4oW14uXSspJC8pO2lmKGE9PW51bGwpe3Rocm93XCJKV1Mgc2lnbmF0dXJlIGlzIG5vdCBhIGZvcm0gb2YgJ0hlYWQuUGF5bG9hZC5TaWdWYWx1ZScuXCJ9cmV0dXJuIGFbMV19O0tKVVIuandzLkpXUy5nZXRKV0t0aHVtYnByaW50PWZ1bmN0aW9uKGQpe2lmKGQua3R5IT09XCJSU0FcIiYmZC5rdHkhPT1cIkVDXCImJmQua3R5IT09XCJvY3RcIil7dGhyb3dcInVuc3VwcG9ydGVkIGFsZ29yaXRobSBmb3IgSldLIFRodW1wcmludFwifXZhciBhPVwie1wiO2lmKGQua3R5PT09XCJSU0FcIil7aWYodHlwZW9mIGQubiE9XCJzdHJpbmdcInx8dHlwZW9mIGQuZSE9XCJzdHJpbmdcIil7dGhyb3dcIndyb25nIG4gYW5kIGUgdmFsdWUgZm9yIFJTQSBrZXlcIn1hKz0nXCJlXCI6XCInK2QuZSsnXCIsJzthKz0nXCJrdHlcIjpcIicrZC5rdHkrJ1wiLCc7YSs9J1wiblwiOlwiJytkLm4rJ1wifSd9ZWxzZXtpZihkLmt0eT09PVwiRUNcIil7aWYodHlwZW9mIGQuY3J2IT1cInN0cmluZ1wifHx0eXBlb2YgZC54IT1cInN0cmluZ1wifHx0eXBlb2YgZC55IT1cInN0cmluZ1wiKXt0aHJvd1wid3JvbmcgY3J2LCB4IGFuZCB5IHZhbHVlIGZvciBFQyBrZXlcIn1hKz0nXCJjcnZcIjpcIicrZC5jcnYrJ1wiLCc7YSs9J1wia3R5XCI6XCInK2Qua3R5KydcIiwnO2ErPSdcInhcIjpcIicrZC54KydcIiwnO2ErPSdcInlcIjpcIicrZC55KydcIn0nfWVsc2V7aWYoZC5rdHk9PT1cIm9jdFwiKXtpZih0eXBlb2YgZC5rIT1cInN0cmluZ1wiKXt0aHJvd1wid3JvbmcgayB2YWx1ZSBmb3Igb2N0KHN5bW1ldHJpYykga2V5XCJ9YSs9J1wia3R5XCI6XCInK2Qua3R5KydcIiwnO2ErPSdcImtcIjpcIicrZC5rKydcIn0nfX19dmFyIGI9cnN0cnRvaGV4KGEpO3ZhciBjPUtKVVIuY3J5cHRvLlV0aWwuaGFzaEhleChiLFwic2hhMjU2XCIpO3ZhciBlPWhleHRvYjY0dShjKTtyZXR1cm4gZX07S0pVUi5qd3MuSW50RGF0ZT17fTtLSlVSLmp3cy5JbnREYXRlLmdldD1mdW5jdGlvbihjKXt2YXIgYj1LSlVSLmp3cy5JbnREYXRlLGQ9Yi5nZXROb3csYT1iLmdldFp1bHU7aWYoYz09XCJub3dcIil7cmV0dXJuIGQoKX1lbHNle2lmKGM9PVwibm93ICsgMWhvdXJcIil7cmV0dXJuIGQoKSs2MCo2MH1lbHNle2lmKGM9PVwibm93ICsgMWRheVwiKXtyZXR1cm4gZCgpKzYwKjYwKjI0fWVsc2V7aWYoYz09XCJub3cgKyAxbW9udGhcIil7cmV0dXJuIGQoKSs2MCo2MCoyNCozMH1lbHNle2lmKGM9PVwibm93ICsgMXllYXJcIil7cmV0dXJuIGQoKSs2MCo2MCoyNCozNjV9ZWxzZXtpZihjLm1hdGNoKC9aJC8pKXtyZXR1cm4gYShjKX1lbHNle2lmKGMubWF0Y2goL15bMC05XSskLykpe3JldHVybiBwYXJzZUludChjKX19fX19fX10aHJvd1widW5zdXBwb3J0ZWQgZm9ybWF0OiBcIitjfTtLSlVSLmp3cy5JbnREYXRlLmdldFp1bHU9ZnVuY3Rpb24oYSl7cmV0dXJuIHp1bHV0b3NlYyhhKX07S0pVUi5qd3MuSW50RGF0ZS5nZXROb3c9ZnVuY3Rpb24oKXt2YXIgYT1+fihuZXcgRGF0ZSgpLzEwMDApO3JldHVybiBhfTtLSlVSLmp3cy5JbnREYXRlLmludERhdGUyVVRDU3RyaW5nPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBEYXRlKGEqMTAwMCk7cmV0dXJuIGIudG9VVENTdHJpbmcoKX07S0pVUi5qd3MuSW50RGF0ZS5pbnREYXRlMlp1bHU9ZnVuY3Rpb24oZSl7dmFyIGk9bmV3IERhdGUoZSoxMDAwKSxoPShcIjAwMDBcIitpLmdldFVUQ0Z1bGxZZWFyKCkpLnNsaWNlKC00KSxnPShcIjAwXCIrKGkuZ2V0VVRDTW9udGgoKSsxKSkuc2xpY2UoLTIpLGI9KFwiMDBcIitpLmdldFVUQ0RhdGUoKSkuc2xpY2UoLTIpLGE9KFwiMDBcIitpLmdldFVUQ0hvdXJzKCkpLnNsaWNlKC0yKSxjPShcIjAwXCIraS5nZXRVVENNaW51dGVzKCkpLnNsaWNlKC0yKSxmPShcIjAwXCIraS5nZXRVVENTZWNvbmRzKCkpLnNsaWNlKC0yKTtyZXR1cm4gaCtnK2IrYStjK2YrXCJaXCJ9O1xuZXhwb3J0IHsgU2VjdXJlUmFuZG9tIH07XHJcbmV4cG9ydCB7IHJuZ19zZWVkX3RpbWUgfTtcclxuXHJcbmV4cG9ydCB7IEJpZ0ludGVnZXIgfTtcclxuZXhwb3J0IHsgUlNBS2V5IH07XHJcbmV4cG9ydCBjb25zdCB7IEVEU0EgfSA9IEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBEU0EgfSA9IEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBTaWduYXR1cmUgfSA9IEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBNZXNzYWdlRGlnZXN0IH0gPSAgS0pVUi5jcnlwdG87XHJcbmV4cG9ydCBjb25zdCB7IE1hYyB9ID0gS0pVUi5jcnlwdG87XHJcbmV4cG9ydCBjb25zdCB7IENpcGhlciB9ID0gIEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgeyBLRVlVVElMIH07XHJcbmV4cG9ydCB7IEFTTjFIRVggfTtcclxuZXhwb3J0IHsgWDUwOSB9O1xyXG5leHBvcnQgeyBDcnlwdG9KUyB9O1xyXG5cclxuLy8gZXh0L2Jhc2U2NC5qc1xyXG5leHBvcnQgeyBiNjR0b2hleCB9O1xyXG5leHBvcnQgeyBiNjR0b0JBIH07XHJcblxyXG4vLyBiYXNlNjR4LmpzXHJcbmV4cG9ydCB7IHN0b0JBIH07XHJcbmV4cG9ydCB7IEJBdG9zIH07XHJcbmV4cG9ydCB7IEJBdG9oZXggfTtcclxuZXhwb3J0IHsgc3RvaGV4IH07XHJcbmV4cG9ydCB7IHN0b2I2NCB9O1xyXG5leHBvcnQgeyBzdG9iNjR1IH07XHJcbmV4cG9ydCB7IGI2NHV0b3MgfTtcclxuZXhwb3J0IHsgYjY0dG9iNjR1IH07XHJcbmV4cG9ydCB7IGI2NHV0b2I2NCB9O1xyXG5leHBvcnQgeyBoZXgyYjY0IH07XHJcbmV4cG9ydCB7IGhleHRvYjY0dSB9O1xyXG5leHBvcnQgeyBiNjR1dG9oZXggfTtcclxuZXhwb3J0IHsgdXRmOHRvYjY0dSB9O1xyXG5leHBvcnQgeyBiNjR1dG91dGY4IH07XHJcbmV4cG9ydCB7IHV0Zjh0b2I2NCB9O1xyXG5leHBvcnQgeyBiNjR0b3V0ZjggfTtcclxuZXhwb3J0IHsgdXRmOHRvaGV4IH07XHJcbmV4cG9ydCB7IGhleHRvdXRmOCB9O1xyXG5leHBvcnQgeyBoZXh0b3JzdHIgfTtcclxuZXhwb3J0IHsgcnN0cnRvaGV4IH07XHJcbmV4cG9ydCB7IGhleHRvYjY0IH07XHJcbmV4cG9ydCB7IGhleHRvYjY0bmwgfTtcclxuZXhwb3J0IHsgYjY0bmx0b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b3BlbSB9O1xyXG5leHBvcnQgeyBwZW10b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b0FycmF5QnVmZmVyIH07XHJcbmV4cG9ydCB7IEFycmF5QnVmZmVydG9oZXggfTtcclxuZXhwb3J0IHsgenVsdXRvbXNlYyB9O1xyXG5leHBvcnQgeyB6dWx1dG9zZWMgfTtcclxuZXhwb3J0IHsgenVsdXRvZGF0ZSB9O1xyXG5leHBvcnQgeyBkYXRldG96dWx1IH07XHJcbmV4cG9ydCB7IHVyaWNtcHRvaGV4IH07XHJcbmV4cG9ydCB7IGhleHRvdXJpY21wIH07XHJcbmV4cG9ydCB7IGlwdjZ0b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b2lwdjYgfTtcclxuZXhwb3J0IHsgaGV4dG9pcCB9O1xyXG5leHBvcnQgeyBpcHRvaGV4IH07XHJcbmV4cG9ydCB7IGVuY29kZVVSSUNvbXBvbmVudEFsbCB9O1xyXG5leHBvcnQgeyBuZXdsaW5lX3RvVW5peCB9O1xyXG5leHBvcnQgeyBuZXdsaW5lX3RvRG9zIH07XHJcbmV4cG9ydCB7IGhleHRvcG9zaGV4IH07XHJcbmV4cG9ydCB7IGludGFyeXN0cnRvaGV4IH07XHJcbmV4cG9ydCB7IHN0cmRpZmZpZHggfTtcclxuXHJcbi8vIG5hbWUgc3BhY2VzXHJcbmV4cG9ydCB7IEtKVVIgfTtcclxuY29uc3QgX2NyeXB0byA9ICBLSlVSLmNyeXB0bztcclxuZXhwb3J0IHsgX2NyeXB0byBhcyBjcnlwdG8gfTtcclxuZXhwb3J0IGNvbnN0IHsgYXNuMSB9ID0gS0pVUjtcclxuZXhwb3J0IGNvbnN0IHsgandzIH0gPSBLSlVSO1xyXG5leHBvcnQgY29uc3QgeyBsYW5nIH0gPSBLSlVSO1xyXG5cclxuXHJcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9zaGltXCIpO1xuXG5yZXF1aXJlKFwicmVnZW5lcmF0b3ItcnVudGltZS9ydW50aW1lXCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9yZWdleHAvZXNjYXBlXCIpO1xuXG5pZiAoZ2xvYmFsLl9iYWJlbFBvbHlmaWxsKSB7XG4gIHRocm93IG5ldyBFcnJvcihcIm9ubHkgb25lIGluc3RhbmNlIG9mIGJhYmVsLXBvbHlmaWxsIGlzIGFsbG93ZWRcIik7XG59XG5nbG9iYWwuX2JhYmVsUG9seWZpbGwgPSB0cnVlO1xuXG52YXIgREVGSU5FX1BST1BFUlRZID0gXCJkZWZpbmVQcm9wZXJ0eVwiO1xuZnVuY3Rpb24gZGVmaW5lKE8sIGtleSwgdmFsdWUpIHtcbiAgT1trZXldIHx8IE9iamVjdFtERUZJTkVfUFJPUEVSVFldKE8sIGtleSwge1xuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfSk7XG59XG5cbmRlZmluZShTdHJpbmcucHJvdG90eXBlLCBcInBhZExlZnRcIiwgXCJcIi5wYWRTdGFydCk7XG5kZWZpbmUoU3RyaW5nLnByb3RvdHlwZSwgXCJwYWRSaWdodFwiLCBcIlwiLnBhZEVuZCk7XG5cblwicG9wLHJldmVyc2Usc2hpZnQsa2V5cyx2YWx1ZXMsZW50cmllcyxpbmRleE9mLGV2ZXJ5LHNvbWUsZm9yRWFjaCxtYXAsZmlsdGVyLGZpbmQsZmluZEluZGV4LGluY2x1ZGVzLGpvaW4sc2xpY2UsY29uY2F0LHB1c2gsc3BsaWNlLHVuc2hpZnQsc29ydCxsYXN0SW5kZXhPZixyZWR1Y2UscmVkdWNlUmlnaHQsY29weVdpdGhpbixmaWxsXCIuc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICBbXVtrZXldICYmIGRlZmluZShBcnJheSwga2V5LCBGdW5jdGlvbi5jYWxsLmJpbmQoW11ba2V5XSkpO1xufSk7IiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS9mYWNlYm9vay9yZWdlbmVyYXRvci9tYXN0ZXIvTElDRU5TRSBmaWxlLiBBblxuICogYWRkaXRpb25hbCBncmFudCBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluXG4gKiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKi9cblxuIShmdW5jdGlvbihnbG9iYWwpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgdmFyIE9wID0gT2JqZWN0LnByb3RvdHlwZTtcbiAgdmFyIGhhc093biA9IE9wLmhhc093blByb3BlcnR5O1xuICB2YXIgdW5kZWZpbmVkOyAvLyBNb3JlIGNvbXByZXNzaWJsZSB0aGFuIHZvaWQgMC5cbiAgdmFyICRTeW1ib2wgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgPyBTeW1ib2wgOiB7fTtcbiAgdmFyIGl0ZXJhdG9yU3ltYm9sID0gJFN5bWJvbC5pdGVyYXRvciB8fCBcIkBAaXRlcmF0b3JcIjtcbiAgdmFyIGFzeW5jSXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLmFzeW5jSXRlcmF0b3IgfHwgXCJAQGFzeW5jSXRlcmF0b3JcIjtcbiAgdmFyIHRvU3RyaW5nVGFnU3ltYm9sID0gJFN5bWJvbC50b1N0cmluZ1RhZyB8fCBcIkBAdG9TdHJpbmdUYWdcIjtcblxuICB2YXIgaW5Nb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiO1xuICB2YXIgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWU7XG4gIGlmIChydW50aW1lKSB7XG4gICAgaWYgKGluTW9kdWxlKSB7XG4gICAgICAvLyBJZiByZWdlbmVyYXRvclJ1bnRpbWUgaXMgZGVmaW5lZCBnbG9iYWxseSBhbmQgd2UncmUgaW4gYSBtb2R1bGUsXG4gICAgICAvLyBtYWtlIHRoZSBleHBvcnRzIG9iamVjdCBpZGVudGljYWwgdG8gcmVnZW5lcmF0b3JSdW50aW1lLlxuICAgICAgbW9kdWxlLmV4cG9ydHMgPSBydW50aW1lO1xuICAgIH1cbiAgICAvLyBEb24ndCBib3RoZXIgZXZhbHVhdGluZyB0aGUgcmVzdCBvZiB0aGlzIGZpbGUgaWYgdGhlIHJ1bnRpbWUgd2FzXG4gICAgLy8gYWxyZWFkeSBkZWZpbmVkIGdsb2JhbGx5LlxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIERlZmluZSB0aGUgcnVudGltZSBnbG9iYWxseSAoYXMgZXhwZWN0ZWQgYnkgZ2VuZXJhdGVkIGNvZGUpIGFzIGVpdGhlclxuICAvLyBtb2R1bGUuZXhwb3J0cyAoaWYgd2UncmUgaW4gYSBtb2R1bGUpIG9yIGEgbmV3LCBlbXB0eSBvYmplY3QuXG4gIHJ1bnRpbWUgPSBnbG9iYWwucmVnZW5lcmF0b3JSdW50aW1lID0gaW5Nb2R1bGUgPyBtb2R1bGUuZXhwb3J0cyA6IHt9O1xuXG4gIGZ1bmN0aW9uIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBJZiBvdXRlckZuIHByb3ZpZGVkIGFuZCBvdXRlckZuLnByb3RvdHlwZSBpcyBhIEdlbmVyYXRvciwgdGhlbiBvdXRlckZuLnByb3RvdHlwZSBpbnN0YW5jZW9mIEdlbmVyYXRvci5cbiAgICB2YXIgcHJvdG9HZW5lcmF0b3IgPSBvdXRlckZuICYmIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yID8gb3V0ZXJGbiA6IEdlbmVyYXRvcjtcbiAgICB2YXIgZ2VuZXJhdG9yID0gT2JqZWN0LmNyZWF0ZShwcm90b0dlbmVyYXRvci5wcm90b3R5cGUpO1xuICAgIHZhciBjb250ZXh0ID0gbmV3IENvbnRleHQodHJ5TG9jc0xpc3QgfHwgW10pO1xuXG4gICAgLy8gVGhlIC5faW52b2tlIG1ldGhvZCB1bmlmaWVzIHRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcy5cbiAgICBnZW5lcmF0b3IuX2ludm9rZSA9IG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gZ2VuZXJhdG9yO1xuICB9XG4gIHJ1bnRpbWUud3JhcCA9IHdyYXA7XG5cbiAgLy8gVHJ5L2NhdGNoIGhlbHBlciB0byBtaW5pbWl6ZSBkZW9wdGltaXphdGlvbnMuIFJldHVybnMgYSBjb21wbGV0aW9uXG4gIC8vIHJlY29yZCBsaWtlIGNvbnRleHQudHJ5RW50cmllc1tpXS5jb21wbGV0aW9uLiBUaGlzIGludGVyZmFjZSBjb3VsZFxuICAvLyBoYXZlIGJlZW4gKGFuZCB3YXMgcHJldmlvdXNseSkgZGVzaWduZWQgdG8gdGFrZSBhIGNsb3N1cmUgdG8gYmVcbiAgLy8gaW52b2tlZCB3aXRob3V0IGFyZ3VtZW50cywgYnV0IGluIGFsbCB0aGUgY2FzZXMgd2UgY2FyZSBhYm91dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYW4gZXhpc3RpbmcgbWV0aG9kIHdlIHdhbnQgdG8gY2FsbCwgc28gdGhlcmUncyBubyBuZWVkXG4gIC8vIHRvIGNyZWF0ZSBhIG5ldyBmdW5jdGlvbiBvYmplY3QuIFdlIGNhbiBldmVuIGdldCBhd2F5IHdpdGggYXNzdW1pbmdcbiAgLy8gdGhlIG1ldGhvZCB0YWtlcyBleGFjdGx5IG9uZSBhcmd1bWVudCwgc2luY2UgdGhhdCBoYXBwZW5zIHRvIGJlIHRydWVcbiAgLy8gaW4gZXZlcnkgY2FzZSwgc28gd2UgZG9uJ3QgaGF2ZSB0byB0b3VjaCB0aGUgYXJndW1lbnRzIG9iamVjdC4gVGhlXG4gIC8vIG9ubHkgYWRkaXRpb25hbCBhbGxvY2F0aW9uIHJlcXVpcmVkIGlzIHRoZSBjb21wbGV0aW9uIHJlY29yZCwgd2hpY2hcbiAgLy8gaGFzIGEgc3RhYmxlIHNoYXBlIGFuZCBzbyBob3BlZnVsbHkgc2hvdWxkIGJlIGNoZWFwIHRvIGFsbG9jYXRlLlxuICBmdW5jdGlvbiB0cnlDYXRjaChmbiwgb2JqLCBhcmcpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJub3JtYWxcIiwgYXJnOiBmbi5jYWxsKG9iaiwgYXJnKSB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0aHJvd1wiLCBhcmc6IGVyciB9O1xuICAgIH1cbiAgfVxuXG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0ID0gXCJzdXNwZW5kZWRTdGFydFwiO1xuICB2YXIgR2VuU3RhdGVTdXNwZW5kZWRZaWVsZCA9IFwic3VzcGVuZGVkWWllbGRcIjtcbiAgdmFyIEdlblN0YXRlRXhlY3V0aW5nID0gXCJleGVjdXRpbmdcIjtcbiAgdmFyIEdlblN0YXRlQ29tcGxldGVkID0gXCJjb21wbGV0ZWRcIjtcblxuICAvLyBSZXR1cm5pbmcgdGhpcyBvYmplY3QgZnJvbSB0aGUgaW5uZXJGbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzXG4gIC8vIGJyZWFraW5nIG91dCBvZiB0aGUgZGlzcGF0Y2ggc3dpdGNoIHN0YXRlbWVudC5cbiAgdmFyIENvbnRpbnVlU2VudGluZWwgPSB7fTtcblxuICAvLyBEdW1teSBjb25zdHJ1Y3RvciBmdW5jdGlvbnMgdGhhdCB3ZSB1c2UgYXMgdGhlIC5jb25zdHJ1Y3RvciBhbmRcbiAgLy8gLmNvbnN0cnVjdG9yLnByb3RvdHlwZSBwcm9wZXJ0aWVzIGZvciBmdW5jdGlvbnMgdGhhdCByZXR1cm4gR2VuZXJhdG9yXG4gIC8vIG9iamVjdHMuIEZvciBmdWxsIHNwZWMgY29tcGxpYW5jZSwgeW91IG1heSB3aXNoIHRvIGNvbmZpZ3VyZSB5b3VyXG4gIC8vIG1pbmlmaWVyIG5vdCB0byBtYW5nbGUgdGhlIG5hbWVzIG9mIHRoZXNlIHR3byBmdW5jdGlvbnMuXG4gIGZ1bmN0aW9uIEdlbmVyYXRvcigpIHt9XG4gIGZ1bmN0aW9uIEdlbmVyYXRvckZ1bmN0aW9uKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUoKSB7fVxuXG4gIC8vIFRoaXMgaXMgYSBwb2x5ZmlsbCBmb3IgJUl0ZXJhdG9yUHJvdG90eXBlJSBmb3IgZW52aXJvbm1lbnRzIHRoYXRcbiAgLy8gZG9uJ3QgbmF0aXZlbHkgc3VwcG9ydCBpdC5cbiAgdmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG4gIEl0ZXJhdG9yUHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICB2YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG4gIHZhciBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvICYmIGdldFByb3RvKGdldFByb3RvKHZhbHVlcyhbXSkpKTtcbiAgaWYgKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICYmXG4gICAgICBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSAhPT0gT3AgJiZcbiAgICAgIGhhc093bi5jYWxsKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlLCBpdGVyYXRvclN5bWJvbCkpIHtcbiAgICAvLyBUaGlzIGVudmlyb25tZW50IGhhcyBhIG5hdGl2ZSAlSXRlcmF0b3JQcm90b3R5cGUlOyB1c2UgaXQgaW5zdGVhZFxuICAgIC8vIG9mIHRoZSBwb2x5ZmlsbC5cbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlO1xuICB9XG5cbiAgdmFyIEdwID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUucHJvdG90eXBlID1cbiAgICBHZW5lcmF0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG4gIEdlbmVyYXRvckZ1bmN0aW9uLnByb3RvdHlwZSA9IEdwLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb247XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlW3RvU3RyaW5nVGFnU3ltYm9sXSA9XG4gICAgR2VuZXJhdG9yRnVuY3Rpb24uZGlzcGxheU5hbWUgPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG5cbiAgLy8gSGVscGVyIGZvciBkZWZpbmluZyB0aGUgLm5leHQsIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcyBvZiB0aGVcbiAgLy8gSXRlcmF0b3IgaW50ZXJmYWNlIGluIHRlcm1zIG9mIGEgc2luZ2xlIC5faW52b2tlIG1ldGhvZC5cbiAgZnVuY3Rpb24gZGVmaW5lSXRlcmF0b3JNZXRob2RzKHByb3RvdHlwZSkge1xuICAgIFtcIm5leHRcIiwgXCJ0aHJvd1wiLCBcInJldHVyblwiXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgcHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbihhcmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludm9rZShtZXRob2QsIGFyZyk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcnVudGltZS5pc0dlbmVyYXRvckZ1bmN0aW9uID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgdmFyIGN0b3IgPSB0eXBlb2YgZ2VuRnVuID09PSBcImZ1bmN0aW9uXCIgJiYgZ2VuRnVuLmNvbnN0cnVjdG9yO1xuICAgIHJldHVybiBjdG9yXG4gICAgICA/IGN0b3IgPT09IEdlbmVyYXRvckZ1bmN0aW9uIHx8XG4gICAgICAgIC8vIEZvciB0aGUgbmF0aXZlIEdlbmVyYXRvckZ1bmN0aW9uIGNvbnN0cnVjdG9yLCB0aGUgYmVzdCB3ZSBjYW5cbiAgICAgICAgLy8gZG8gaXMgdG8gY2hlY2sgaXRzIC5uYW1lIHByb3BlcnR5LlxuICAgICAgICAoY3Rvci5kaXNwbGF5TmFtZSB8fCBjdG9yLm5hbWUpID09PSBcIkdlbmVyYXRvckZ1bmN0aW9uXCJcbiAgICAgIDogZmFsc2U7XG4gIH07XG5cbiAgcnVudGltZS5tYXJrID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGdlbkZ1biwgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZW5GdW4uX19wcm90b19fID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gICAgICBpZiAoISh0b1N0cmluZ1RhZ1N5bWJvbCBpbiBnZW5GdW4pKSB7XG4gICAgICAgIGdlbkZ1blt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG4gICAgICB9XG4gICAgfVxuICAgIGdlbkZ1bi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEdwKTtcbiAgICByZXR1cm4gZ2VuRnVuO1xuICB9O1xuXG4gIC8vIFdpdGhpbiB0aGUgYm9keSBvZiBhbnkgYXN5bmMgZnVuY3Rpb24sIGBhd2FpdCB4YCBpcyB0cmFuc2Zvcm1lZCB0b1xuICAvLyBgeWllbGQgcmVnZW5lcmF0b3JSdW50aW1lLmF3cmFwKHgpYCwgc28gdGhhdCB0aGUgcnVudGltZSBjYW4gdGVzdFxuICAvLyBgaGFzT3duLmNhbGwodmFsdWUsIFwiX19hd2FpdFwiKWAgdG8gZGV0ZXJtaW5lIGlmIHRoZSB5aWVsZGVkIHZhbHVlIGlzXG4gIC8vIG1lYW50IHRvIGJlIGF3YWl0ZWQuXG4gIHJ1bnRpbWUuYXdyYXAgPSBmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4geyBfX2F3YWl0OiBhcmcgfTtcbiAgfTtcblxuICBmdW5jdGlvbiBBc3luY0l0ZXJhdG9yKGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGludm9rZShtZXRob2QsIGFyZywgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2goZ2VuZXJhdG9yW21ldGhvZF0sIGdlbmVyYXRvciwgYXJnKTtcbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHJlamVjdChyZWNvcmQuYXJnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciByZXN1bHQgPSByZWNvcmQuYXJnO1xuICAgICAgICB2YXIgdmFsdWUgPSByZXN1bHQudmFsdWU7XG4gICAgICAgIGlmICh2YWx1ZSAmJlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZS5fX2F3YWl0KS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJuZXh0XCIsIHZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0sIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgICAgaW52b2tlKFwidGhyb3dcIiwgZXJyLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkudGhlbihmdW5jdGlvbih1bndyYXBwZWQpIHtcbiAgICAgICAgICAvLyBXaGVuIGEgeWllbGRlZCBQcm9taXNlIGlzIHJlc29sdmVkLCBpdHMgZmluYWwgdmFsdWUgYmVjb21lc1xuICAgICAgICAgIC8vIHRoZSAudmFsdWUgb2YgdGhlIFByb21pc2U8e3ZhbHVlLGRvbmV9PiByZXN1bHQgZm9yIHRoZVxuICAgICAgICAgIC8vIGN1cnJlbnQgaXRlcmF0aW9uLiBJZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCwgaG93ZXZlciwgdGhlXG4gICAgICAgICAgLy8gcmVzdWx0IGZvciB0aGlzIGl0ZXJhdGlvbiB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHNhbWVcbiAgICAgICAgICAvLyByZWFzb24uIE5vdGUgdGhhdCByZWplY3Rpb25zIG9mIHlpZWxkZWQgUHJvbWlzZXMgYXJlIG5vdFxuICAgICAgICAgIC8vIHRocm93biBiYWNrIGludG8gdGhlIGdlbmVyYXRvciBmdW5jdGlvbiwgYXMgaXMgdGhlIGNhc2VcbiAgICAgICAgICAvLyB3aGVuIGFuIGF3YWl0ZWQgUHJvbWlzZSBpcyByZWplY3RlZC4gVGhpcyBkaWZmZXJlbmNlIGluXG4gICAgICAgICAgLy8gYmVoYXZpb3IgYmV0d2VlbiB5aWVsZCBhbmQgYXdhaXQgaXMgaW1wb3J0YW50LCBiZWNhdXNlIGl0XG4gICAgICAgICAgLy8gYWxsb3dzIHRoZSBjb25zdW1lciB0byBkZWNpZGUgd2hhdCB0byBkbyB3aXRoIHRoZSB5aWVsZGVkXG4gICAgICAgICAgLy8gcmVqZWN0aW9uIChzd2FsbG93IGl0IGFuZCBjb250aW51ZSwgbWFudWFsbHkgLnRocm93IGl0IGJhY2tcbiAgICAgICAgICAvLyBpbnRvIHRoZSBnZW5lcmF0b3IsIGFiYW5kb24gaXRlcmF0aW9uLCB3aGF0ZXZlcikuIFdpdGhcbiAgICAgICAgICAvLyBhd2FpdCwgYnkgY29udHJhc3QsIHRoZXJlIGlzIG5vIG9wcG9ydHVuaXR5IHRvIGV4YW1pbmUgdGhlXG4gICAgICAgICAgLy8gcmVqZWN0aW9uIHJlYXNvbiBvdXRzaWRlIHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24sIHNvIHRoZVxuICAgICAgICAgIC8vIG9ubHkgb3B0aW9uIGlzIHRvIHRocm93IGl0IGZyb20gdGhlIGF3YWl0IGV4cHJlc3Npb24sIGFuZFxuICAgICAgICAgIC8vIGxldCB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGhhbmRsZSB0aGUgZXhjZXB0aW9uLlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IHVud3JhcHBlZDtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBnbG9iYWwucHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBnbG9iYWwucHJvY2Vzcy5kb21haW4pIHtcbiAgICAgIGludm9rZSA9IGdsb2JhbC5wcm9jZXNzLmRvbWFpbi5iaW5kKGludm9rZSk7XG4gICAgfVxuXG4gICAgdmFyIHByZXZpb3VzUHJvbWlzZTtcblxuICAgIGZ1bmN0aW9uIGVucXVldWUobWV0aG9kLCBhcmcpIHtcbiAgICAgIGZ1bmN0aW9uIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByZXZpb3VzUHJvbWlzZSA9XG4gICAgICAgIC8vIElmIGVucXVldWUgaGFzIGJlZW4gY2FsbGVkIGJlZm9yZSwgdGhlbiB3ZSB3YW50IHRvIHdhaXQgdW50aWxcbiAgICAgICAgLy8gYWxsIHByZXZpb3VzIFByb21pc2VzIGhhdmUgYmVlbiByZXNvbHZlZCBiZWZvcmUgY2FsbGluZyBpbnZva2UsXG4gICAgICAgIC8vIHNvIHRoYXQgcmVzdWx0cyBhcmUgYWx3YXlzIGRlbGl2ZXJlZCBpbiB0aGUgY29ycmVjdCBvcmRlci4gSWZcbiAgICAgICAgLy8gZW5xdWV1ZSBoYXMgbm90IGJlZW4gY2FsbGVkIGJlZm9yZSwgdGhlbiBpdCBpcyBpbXBvcnRhbnQgdG9cbiAgICAgICAgLy8gY2FsbCBpbnZva2UgaW1tZWRpYXRlbHksIHdpdGhvdXQgd2FpdGluZyBvbiBhIGNhbGxiYWNrIHRvIGZpcmUsXG4gICAgICAgIC8vIHNvIHRoYXQgdGhlIGFzeW5jIGdlbmVyYXRvciBmdW5jdGlvbiBoYXMgdGhlIG9wcG9ydHVuaXR5IHRvIGRvXG4gICAgICAgIC8vIGFueSBuZWNlc3Nhcnkgc2V0dXAgaW4gYSBwcmVkaWN0YWJsZSB3YXkuIFRoaXMgcHJlZGljdGFiaWxpdHlcbiAgICAgICAgLy8gaXMgd2h5IHRoZSBQcm9taXNlIGNvbnN0cnVjdG9yIHN5bmNocm9ub3VzbHkgaW52b2tlcyBpdHNcbiAgICAgICAgLy8gZXhlY3V0b3IgY2FsbGJhY2ssIGFuZCB3aHkgYXN5bmMgZnVuY3Rpb25zIHN5bmNocm9ub3VzbHlcbiAgICAgICAgLy8gZXhlY3V0ZSBjb2RlIGJlZm9yZSB0aGUgZmlyc3QgYXdhaXQuIFNpbmNlIHdlIGltcGxlbWVudCBzaW1wbGVcbiAgICAgICAgLy8gYXN5bmMgZnVuY3Rpb25zIGluIHRlcm1zIG9mIGFzeW5jIGdlbmVyYXRvcnMsIGl0IGlzIGVzcGVjaWFsbHlcbiAgICAgICAgLy8gaW1wb3J0YW50IHRvIGdldCB0aGlzIHJpZ2h0LCBldmVuIHRob3VnaCBpdCByZXF1aXJlcyBjYXJlLlxuICAgICAgICBwcmV2aW91c1Byb21pc2UgPyBwcmV2aW91c1Byb21pc2UudGhlbihcbiAgICAgICAgICBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZyxcbiAgICAgICAgICAvLyBBdm9pZCBwcm9wYWdhdGluZyBmYWlsdXJlcyB0byBQcm9taXNlcyByZXR1cm5lZCBieSBsYXRlclxuICAgICAgICAgIC8vIGludm9jYXRpb25zIG9mIHRoZSBpdGVyYXRvci5cbiAgICAgICAgICBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZ1xuICAgICAgICApIDogY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcoKTtcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgdGhlIHVuaWZpZWQgaGVscGVyIG1ldGhvZCB0aGF0IGlzIHVzZWQgdG8gaW1wbGVtZW50IC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gKHNlZSBkZWZpbmVJdGVyYXRvck1ldGhvZHMpLlxuICAgIHRoaXMuX2ludm9rZSA9IGVucXVldWU7XG4gIH1cblxuICBkZWZpbmVJdGVyYXRvck1ldGhvZHMoQXN5bmNJdGVyYXRvci5wcm90b3R5cGUpO1xuICBBc3luY0l0ZXJhdG9yLnByb3RvdHlwZVthc3luY0l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgcnVudGltZS5Bc3luY0l0ZXJhdG9yID0gQXN5bmNJdGVyYXRvcjtcblxuICAvLyBOb3RlIHRoYXQgc2ltcGxlIGFzeW5jIGZ1bmN0aW9ucyBhcmUgaW1wbGVtZW50ZWQgb24gdG9wIG9mXG4gIC8vIEFzeW5jSXRlcmF0b3Igb2JqZWN0czsgdGhleSBqdXN0IHJldHVybiBhIFByb21pc2UgZm9yIHRoZSB2YWx1ZSBvZlxuICAvLyB0aGUgZmluYWwgcmVzdWx0IHByb2R1Y2VkIGJ5IHRoZSBpdGVyYXRvci5cbiAgcnVudGltZS5hc3luYyA9IGZ1bmN0aW9uKGlubmVyRm4sIG91dGVyRm4sIHNlbGYsIHRyeUxvY3NMaXN0KSB7XG4gICAgdmFyIGl0ZXIgPSBuZXcgQXN5bmNJdGVyYXRvcihcbiAgICAgIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpXG4gICAgKTtcblxuICAgIHJldHVybiBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24ob3V0ZXJGbilcbiAgICAgID8gaXRlciAvLyBJZiBvdXRlckZuIGlzIGEgZ2VuZXJhdG9yLCByZXR1cm4gdGhlIGZ1bGwgaXRlcmF0b3IuXG4gICAgICA6IGl0ZXIubmV4dCgpLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdC5kb25lID8gcmVzdWx0LnZhbHVlIDogaXRlci5uZXh0KCk7XG4gICAgICAgIH0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCkge1xuICAgIHZhciBzdGF0ZSA9IEdlblN0YXRlU3VzcGVuZGVkU3RhcnQ7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnKSB7XG4gICAgICBpZiAoc3RhdGUgPT09IEdlblN0YXRlRXhlY3V0aW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IHJ1bm5pbmdcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVDb21wbGV0ZWQpIHtcbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgdGhyb3cgYXJnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQmUgZm9yZ2l2aW5nLCBwZXIgMjUuMy4zLjMuMyBvZiB0aGUgc3BlYzpcbiAgICAgICAgLy8gaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLWdlbmVyYXRvcnJlc3VtZVxuICAgICAgICByZXR1cm4gZG9uZVJlc3VsdCgpO1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IG1ldGhvZDtcbiAgICAgIGNvbnRleHQuYXJnID0gYXJnO1xuXG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICB2YXIgZGVsZWdhdGUgPSBjb250ZXh0LmRlbGVnYXRlO1xuICAgICAgICBpZiAoZGVsZWdhdGUpIHtcbiAgICAgICAgICB2YXIgZGVsZWdhdGVSZXN1bHQgPSBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KTtcbiAgICAgICAgICBpZiAoZGVsZWdhdGVSZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCA9PT0gQ29udGludWVTZW50aW5lbCkgY29udGludWU7XG4gICAgICAgICAgICByZXR1cm4gZGVsZWdhdGVSZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcIm5leHRcIikge1xuICAgICAgICAgIC8vIFNldHRpbmcgY29udGV4dC5fc2VudCBmb3IgbGVnYWN5IHN1cHBvcnQgb2YgQmFiZWwnc1xuICAgICAgICAgIC8vIGZ1bmN0aW9uLnNlbnQgaW1wbGVtZW50YXRpb24uXG4gICAgICAgICAgY29udGV4dC5zZW50ID0gY29udGV4dC5fc2VudCA9IGNvbnRleHQuYXJnO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydCkge1xuICAgICAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUNvbXBsZXRlZDtcbiAgICAgICAgICAgIHRocm93IGNvbnRleHQuYXJnO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2hFeGNlcHRpb24oY29udGV4dC5hcmcpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5tZXRob2QgPT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgICBjb250ZXh0LmFicnVwdChcInJldHVyblwiLCBjb250ZXh0LmFyZyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZSA9IEdlblN0YXRlRXhlY3V0aW5nO1xuXG4gICAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcIm5vcm1hbFwiKSB7XG4gICAgICAgICAgLy8gSWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biBmcm9tIGlubmVyRm4sIHdlIGxlYXZlIHN0YXRlID09PVxuICAgICAgICAgIC8vIEdlblN0YXRlRXhlY3V0aW5nIGFuZCBsb29wIGJhY2sgZm9yIGFub3RoZXIgaW52b2NhdGlvbi5cbiAgICAgICAgICBzdGF0ZSA9IGNvbnRleHQuZG9uZVxuICAgICAgICAgICAgPyBHZW5TdGF0ZUNvbXBsZXRlZFxuICAgICAgICAgICAgOiBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkO1xuXG4gICAgICAgICAgaWYgKHJlY29yZC5hcmcgPT09IENvbnRpbnVlU2VudGluZWwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogcmVjb3JkLmFyZyxcbiAgICAgICAgICAgIGRvbmU6IGNvbnRleHQuZG9uZVxuICAgICAgICAgIH07XG5cbiAgICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUNvbXBsZXRlZDtcbiAgICAgICAgICAvLyBEaXNwYXRjaCB0aGUgZXhjZXB0aW9uIGJ5IGxvb3BpbmcgYmFjayBhcm91bmQgdG8gdGhlXG4gICAgICAgICAgLy8gY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZykgY2FsbCBhYm92ZS5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gQ2FsbCBkZWxlZ2F0ZS5pdGVyYXRvcltjb250ZXh0Lm1ldGhvZF0oY29udGV4dC5hcmcpIGFuZCBoYW5kbGUgdGhlXG4gIC8vIHJlc3VsdCwgZWl0aGVyIGJ5IHJldHVybmluZyBhIHsgdmFsdWUsIGRvbmUgfSByZXN1bHQgZnJvbSB0aGVcbiAgLy8gZGVsZWdhdGUgaXRlcmF0b3IsIG9yIGJ5IG1vZGlmeWluZyBjb250ZXh0Lm1ldGhvZCBhbmQgY29udGV4dC5hcmcsXG4gIC8vIHNldHRpbmcgY29udGV4dC5kZWxlZ2F0ZSB0byBudWxsLCBhbmQgcmV0dXJuaW5nIHRoZSBDb250aW51ZVNlbnRpbmVsLlxuICBmdW5jdGlvbiBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIG1ldGhvZCA9IGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXTtcbiAgICBpZiAobWV0aG9kID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEEgLnRocm93IG9yIC5yZXR1cm4gd2hlbiB0aGUgZGVsZWdhdGUgaXRlcmF0b3IgaGFzIG5vIC50aHJvd1xuICAgICAgLy8gbWV0aG9kIGFsd2F5cyB0ZXJtaW5hdGVzIHRoZSB5aWVsZCogbG9vcC5cbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuXG4gICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICBpZiAoZGVsZWdhdGUuaXRlcmF0b3IucmV0dXJuKSB7XG4gICAgICAgICAgLy8gSWYgdGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGhhcyBhIHJldHVybiBtZXRob2QsIGdpdmUgaXQgYVxuICAgICAgICAgIC8vIGNoYW5jZSB0byBjbGVhbiB1cC5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwicmV0dXJuXCI7XG4gICAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgbWF5YmVJbnZva2VEZWxlZ2F0ZShkZWxlZ2F0ZSwgY29udGV4dCk7XG5cbiAgICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgLy8gSWYgbWF5YmVJbnZva2VEZWxlZ2F0ZShjb250ZXh0KSBjaGFuZ2VkIGNvbnRleHQubWV0aG9kIGZyb21cbiAgICAgICAgICAgIC8vIFwicmV0dXJuXCIgdG8gXCJ0aHJvd1wiLCBsZXQgdGhhdCBvdmVycmlkZSB0aGUgVHlwZUVycm9yIGJlbG93LlxuICAgICAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICAgIGNvbnRleHQuYXJnID0gbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICBcIlRoZSBpdGVyYXRvciBkb2VzIG5vdCBwcm92aWRlIGEgJ3Rocm93JyBtZXRob2RcIik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChtZXRob2QsIGRlbGVnYXRlLml0ZXJhdG9yLCBjb250ZXh0LmFyZyk7XG5cbiAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICBjb250ZXh0LmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIHZhciBpbmZvID0gcmVjb3JkLmFyZztcblxuICAgIGlmICghIGluZm8pIHtcbiAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgY29udGV4dC5hcmcgPSBuZXcgVHlwZUVycm9yKFwiaXRlcmF0b3IgcmVzdWx0IGlzIG5vdCBhbiBvYmplY3RcIik7XG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIGlmIChpbmZvLmRvbmUpIHtcbiAgICAgIC8vIEFzc2lnbiB0aGUgcmVzdWx0IG9mIHRoZSBmaW5pc2hlZCBkZWxlZ2F0ZSB0byB0aGUgdGVtcG9yYXJ5XG4gICAgICAvLyB2YXJpYWJsZSBzcGVjaWZpZWQgYnkgZGVsZWdhdGUucmVzdWx0TmFtZSAoc2VlIGRlbGVnYXRlWWllbGQpLlxuICAgICAgY29udGV4dFtkZWxlZ2F0ZS5yZXN1bHROYW1lXSA9IGluZm8udmFsdWU7XG5cbiAgICAgIC8vIFJlc3VtZSBleGVjdXRpb24gYXQgdGhlIGRlc2lyZWQgbG9jYXRpb24gKHNlZSBkZWxlZ2F0ZVlpZWxkKS5cbiAgICAgIGNvbnRleHQubmV4dCA9IGRlbGVnYXRlLm5leHRMb2M7XG5cbiAgICAgIC8vIElmIGNvbnRleHQubWV0aG9kIHdhcyBcInRocm93XCIgYnV0IHRoZSBkZWxlZ2F0ZSBoYW5kbGVkIHRoZVxuICAgICAgLy8gZXhjZXB0aW9uLCBsZXQgdGhlIG91dGVyIGdlbmVyYXRvciBwcm9jZWVkIG5vcm1hbGx5LiBJZlxuICAgICAgLy8gY29udGV4dC5tZXRob2Qgd2FzIFwibmV4dFwiLCBmb3JnZXQgY29udGV4dC5hcmcgc2luY2UgaXQgaGFzIGJlZW5cbiAgICAgIC8vIFwiY29uc3VtZWRcIiBieSB0aGUgZGVsZWdhdGUgaXRlcmF0b3IuIElmIGNvbnRleHQubWV0aG9kIHdhc1xuICAgICAgLy8gXCJyZXR1cm5cIiwgYWxsb3cgdGhlIG9yaWdpbmFsIC5yZXR1cm4gY2FsbCB0byBjb250aW51ZSBpbiB0aGVcbiAgICAgIC8vIG91dGVyIGdlbmVyYXRvci5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCAhPT0gXCJyZXR1cm5cIikge1xuICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZS15aWVsZCB0aGUgcmVzdWx0IHJldHVybmVkIGJ5IHRoZSBkZWxlZ2F0ZSBtZXRob2QuXG4gICAgICByZXR1cm4gaW5mbztcbiAgICB9XG5cbiAgICAvLyBUaGUgZGVsZWdhdGUgaXRlcmF0b3IgaXMgZmluaXNoZWQsIHNvIGZvcmdldCBpdCBhbmQgY29udGludWUgd2l0aFxuICAgIC8vIHRoZSBvdXRlciBnZW5lcmF0b3IuXG4gICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gIH1cblxuICAvLyBEZWZpbmUgR2VuZXJhdG9yLnByb3RvdHlwZS57bmV4dCx0aHJvdyxyZXR1cm59IGluIHRlcm1zIG9mIHRoZVxuICAvLyB1bmlmaWVkIC5faW52b2tlIGhlbHBlciBtZXRob2QuXG4gIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhHcCk7XG5cbiAgR3BbdG9TdHJpbmdUYWdTeW1ib2xdID0gXCJHZW5lcmF0b3JcIjtcblxuICAvLyBBIEdlbmVyYXRvciBzaG91bGQgYWx3YXlzIHJldHVybiBpdHNlbGYgYXMgdGhlIGl0ZXJhdG9yIG9iamVjdCB3aGVuIHRoZVxuICAvLyBAQGl0ZXJhdG9yIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBpdC4gU29tZSBicm93c2VycycgaW1wbGVtZW50YXRpb25zIG9mIHRoZVxuICAvLyBpdGVyYXRvciBwcm90b3R5cGUgY2hhaW4gaW5jb3JyZWN0bHkgaW1wbGVtZW50IHRoaXMsIGNhdXNpbmcgdGhlIEdlbmVyYXRvclxuICAvLyBvYmplY3QgdG8gbm90IGJlIHJldHVybmVkIGZyb20gdGhpcyBjYWxsLiBUaGlzIGVuc3VyZXMgdGhhdCBkb2Vzbid0IGhhcHBlbi5cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWdlbmVyYXRvci9pc3N1ZXMvMjc0IGZvciBtb3JlIGRldGFpbHMuXG4gIEdwW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEdwLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIFwiW29iamVjdCBHZW5lcmF0b3JdXCI7XG4gIH07XG5cbiAgZnVuY3Rpb24gcHVzaFRyeUVudHJ5KGxvY3MpIHtcbiAgICB2YXIgZW50cnkgPSB7IHRyeUxvYzogbG9jc1swXSB9O1xuXG4gICAgaWYgKDEgaW4gbG9jcykge1xuICAgICAgZW50cnkuY2F0Y2hMb2MgPSBsb2NzWzFdO1xuICAgIH1cblxuICAgIGlmICgyIGluIGxvY3MpIHtcbiAgICAgIGVudHJ5LmZpbmFsbHlMb2MgPSBsb2NzWzJdO1xuICAgICAgZW50cnkuYWZ0ZXJMb2MgPSBsb2NzWzNdO1xuICAgIH1cblxuICAgIHRoaXMudHJ5RW50cmllcy5wdXNoKGVudHJ5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0VHJ5RW50cnkoZW50cnkpIHtcbiAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbiB8fCB7fTtcbiAgICByZWNvcmQudHlwZSA9IFwibm9ybWFsXCI7XG4gICAgZGVsZXRlIHJlY29yZC5hcmc7XG4gICAgZW50cnkuY29tcGxldGlvbiA9IHJlY29yZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIENvbnRleHQodHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBUaGUgcm9vdCBlbnRyeSBvYmplY3QgKGVmZmVjdGl2ZWx5IGEgdHJ5IHN0YXRlbWVudCB3aXRob3V0IGEgY2F0Y2hcbiAgICAvLyBvciBhIGZpbmFsbHkgYmxvY2spIGdpdmVzIHVzIGEgcGxhY2UgdG8gc3RvcmUgdmFsdWVzIHRocm93biBmcm9tXG4gICAgLy8gbG9jYXRpb25zIHdoZXJlIHRoZXJlIGlzIG5vIGVuY2xvc2luZyB0cnkgc3RhdGVtZW50LlxuICAgIHRoaXMudHJ5RW50cmllcyA9IFt7IHRyeUxvYzogXCJyb290XCIgfV07XG4gICAgdHJ5TG9jc0xpc3QuZm9yRWFjaChwdXNoVHJ5RW50cnksIHRoaXMpO1xuICAgIHRoaXMucmVzZXQodHJ1ZSk7XG4gIH1cblxuICBydW50aW1lLmtleXMgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGtleXMucHVzaChrZXkpO1xuICAgIH1cbiAgICBrZXlzLnJldmVyc2UoKTtcblxuICAgIC8vIFJhdGhlciB0aGFuIHJldHVybmluZyBhbiBvYmplY3Qgd2l0aCBhIG5leHQgbWV0aG9kLCB3ZSBrZWVwXG4gICAgLy8gdGhpbmdzIHNpbXBsZSBhbmQgcmV0dXJuIHRoZSBuZXh0IGZ1bmN0aW9uIGl0c2VsZi5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgIHdoaWxlIChrZXlzLmxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0ga2V5cy5wb3AoKTtcbiAgICAgICAgaWYgKGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgICBuZXh0LnZhbHVlID0ga2V5O1xuICAgICAgICAgIG5leHQuZG9uZSA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRvIGF2b2lkIGNyZWF0aW5nIGFuIGFkZGl0aW9uYWwgb2JqZWN0LCB3ZSBqdXN0IGhhbmcgdGhlIC52YWx1ZVxuICAgICAgLy8gYW5kIC5kb25lIHByb3BlcnRpZXMgb2ZmIHRoZSBuZXh0IGZ1bmN0aW9uIG9iamVjdCBpdHNlbGYuIFRoaXNcbiAgICAgIC8vIGFsc28gZW5zdXJlcyB0aGF0IHRoZSBtaW5pZmllciB3aWxsIG5vdCBhbm9ueW1pemUgdGhlIGZ1bmN0aW9uLlxuICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcbiAgICAgIHJldHVybiBuZXh0O1xuICAgIH07XG4gIH07XG5cbiAgZnVuY3Rpb24gdmFsdWVzKGl0ZXJhYmxlKSB7XG4gICAgaWYgKGl0ZXJhYmxlKSB7XG4gICAgICB2YXIgaXRlcmF0b3JNZXRob2QgPSBpdGVyYWJsZVtpdGVyYXRvclN5bWJvbF07XG4gICAgICBpZiAoaXRlcmF0b3JNZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yTWV0aG9kLmNhbGwoaXRlcmFibGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGl0ZXJhYmxlLm5leHQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gaXRlcmFibGU7XG4gICAgICB9XG5cbiAgICAgIGlmICghaXNOYU4oaXRlcmFibGUubGVuZ3RoKSkge1xuICAgICAgICB2YXIgaSA9IC0xLCBuZXh0ID0gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgaXRlcmFibGUubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duLmNhbGwoaXRlcmFibGUsIGkpKSB7XG4gICAgICAgICAgICAgIG5leHQudmFsdWUgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG5leHQudmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcblxuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBuZXh0Lm5leHQgPSBuZXh0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiBhbiBpdGVyYXRvciB3aXRoIG5vIHZhbHVlcy5cbiAgICByZXR1cm4geyBuZXh0OiBkb25lUmVzdWx0IH07XG4gIH1cbiAgcnVudGltZS52YWx1ZXMgPSB2YWx1ZXM7XG5cbiAgZnVuY3Rpb24gZG9uZVJlc3VsdCgpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH07XG4gIH1cblxuICBDb250ZXh0LnByb3RvdHlwZSA9IHtcbiAgICBjb25zdHJ1Y3RvcjogQ29udGV4dCxcblxuICAgIHJlc2V0OiBmdW5jdGlvbihza2lwVGVtcFJlc2V0KSB7XG4gICAgICB0aGlzLnByZXYgPSAwO1xuICAgICAgdGhpcy5uZXh0ID0gMDtcbiAgICAgIC8vIFJlc2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAvLyBmdW5jdGlvbi5zZW50IGltcGxlbWVudGF0aW9uLlxuICAgICAgdGhpcy5zZW50ID0gdGhpcy5fc2VudCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuZG9uZSA9IGZhbHNlO1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIHRoaXMubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcblxuICAgICAgdGhpcy50cnlFbnRyaWVzLmZvckVhY2gocmVzZXRUcnlFbnRyeSk7XG5cbiAgICAgIGlmICghc2tpcFRlbXBSZXNldCkge1xuICAgICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMpIHtcbiAgICAgICAgICAvLyBOb3Qgc3VyZSBhYm91dCB0aGUgb3B0aW1hbCBvcmRlciBvZiB0aGVzZSBjb25kaXRpb25zOlxuICAgICAgICAgIGlmIChuYW1lLmNoYXJBdCgwKSA9PT0gXCJ0XCIgJiZcbiAgICAgICAgICAgICAgaGFzT3duLmNhbGwodGhpcywgbmFtZSkgJiZcbiAgICAgICAgICAgICAgIWlzTmFOKCtuYW1lLnNsaWNlKDEpKSkge1xuICAgICAgICAgICAgdGhpc1tuYW1lXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmRvbmUgPSB0cnVlO1xuXG4gICAgICB2YXIgcm9vdEVudHJ5ID0gdGhpcy50cnlFbnRyaWVzWzBdO1xuICAgICAgdmFyIHJvb3RSZWNvcmQgPSByb290RW50cnkuY29tcGxldGlvbjtcbiAgICAgIGlmIChyb290UmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByb290UmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucnZhbDtcbiAgICB9LFxuXG4gICAgZGlzcGF0Y2hFeGNlcHRpb246IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuICAgICAgaWYgKHRoaXMuZG9uZSkge1xuICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcztcbiAgICAgIGZ1bmN0aW9uIGhhbmRsZShsb2MsIGNhdWdodCkge1xuICAgICAgICByZWNvcmQudHlwZSA9IFwidGhyb3dcIjtcbiAgICAgICAgcmVjb3JkLmFyZyA9IGV4Y2VwdGlvbjtcbiAgICAgICAgY29udGV4dC5uZXh0ID0gbG9jO1xuXG4gICAgICAgIGlmIChjYXVnaHQpIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGlzcGF0Y2hlZCBleGNlcHRpb24gd2FzIGNhdWdodCBieSBhIGNhdGNoIGJsb2NrLFxuICAgICAgICAgIC8vIHRoZW4gbGV0IHRoYXQgY2F0Y2ggYmxvY2sgaGFuZGxlIHRoZSBleGNlcHRpb24gbm9ybWFsbHkuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAhISBjYXVnaHQ7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSBcInJvb3RcIikge1xuICAgICAgICAgIC8vIEV4Y2VwdGlvbiB0aHJvd24gb3V0c2lkZSBvZiBhbnkgdHJ5IGJsb2NrIHRoYXQgY291bGQgaGFuZGxlXG4gICAgICAgICAgLy8gaXQsIHNvIHNldCB0aGUgY29tcGxldGlvbiB2YWx1ZSBvZiB0aGUgZW50aXJlIGZ1bmN0aW9uIHRvXG4gICAgICAgICAgLy8gdGhyb3cgdGhlIGV4Y2VwdGlvbi5cbiAgICAgICAgICByZXR1cm4gaGFuZGxlKFwiZW5kXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYpIHtcbiAgICAgICAgICB2YXIgaGFzQ2F0Y2ggPSBoYXNPd24uY2FsbChlbnRyeSwgXCJjYXRjaExvY1wiKTtcbiAgICAgICAgICB2YXIgaGFzRmluYWxseSA9IGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIik7XG5cbiAgICAgICAgICBpZiAoaGFzQ2F0Y2ggJiYgaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmNhdGNoTG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuY2F0Y2hMb2MsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0NhdGNoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0ZpbmFsbHkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJ5IHN0YXRlbWVudCB3aXRob3V0IGNhdGNoIG9yIGZpbmFsbHlcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFicnVwdDogZnVuY3Rpb24odHlwZSwgYXJnKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIikgJiZcbiAgICAgICAgICAgIHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB2YXIgZmluYWxseUVudHJ5ID0gZW50cnk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSAmJlxuICAgICAgICAgICh0eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICAgdHlwZSA9PT0gXCJjb250aW51ZVwiKSAmJlxuICAgICAgICAgIGZpbmFsbHlFbnRyeS50cnlMb2MgPD0gYXJnICYmXG4gICAgICAgICAgYXJnIDw9IGZpbmFsbHlFbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgIC8vIElnbm9yZSB0aGUgZmluYWxseSBlbnRyeSBpZiBjb250cm9sIGlzIG5vdCBqdW1waW5nIHRvIGFcbiAgICAgICAgLy8gbG9jYXRpb24gb3V0c2lkZSB0aGUgdHJ5L2NhdGNoIGJsb2NrLlxuICAgICAgICBmaW5hbGx5RW50cnkgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVjb3JkID0gZmluYWxseUVudHJ5ID8gZmluYWxseUVudHJ5LmNvbXBsZXRpb24gOiB7fTtcbiAgICAgIHJlY29yZC50eXBlID0gdHlwZTtcbiAgICAgIHJlY29yZC5hcmcgPSBhcmc7XG5cbiAgICAgIGlmIChmaW5hbGx5RW50cnkpIHtcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgdGhpcy5uZXh0ID0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2M7XG4gICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZShyZWNvcmQpO1xuICAgIH0sXG5cbiAgICBjb21wbGV0ZTogZnVuY3Rpb24ocmVjb3JkLCBhZnRlckxvYykge1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgdGhyb3cgcmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICByZWNvcmQudHlwZSA9PT0gXCJjb250aW51ZVwiKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IHJlY29yZC5hcmc7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInJldHVyblwiKSB7XG4gICAgICAgIHRoaXMucnZhbCA9IHRoaXMuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcInJldHVyblwiO1xuICAgICAgICB0aGlzLm5leHQgPSBcImVuZFwiO1xuICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJub3JtYWxcIiAmJiBhZnRlckxvYykge1xuICAgICAgICB0aGlzLm5leHQgPSBhZnRlckxvYztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfSxcblxuICAgIGZpbmlzaDogZnVuY3Rpb24oZmluYWxseUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS5maW5hbGx5TG9jID09PSBmaW5hbGx5TG9jKSB7XG4gICAgICAgICAgdGhpcy5jb21wbGV0ZShlbnRyeS5jb21wbGV0aW9uLCBlbnRyeS5hZnRlckxvYyk7XG4gICAgICAgICAgcmVzZXRUcnlFbnRyeShlbnRyeSk7XG4gICAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgXCJjYXRjaFwiOiBmdW5jdGlvbih0cnlMb2MpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSB0cnlMb2MpIHtcbiAgICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcbiAgICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgdmFyIHRocm93biA9IHJlY29yZC5hcmc7XG4gICAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRocm93bjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUgY29udGV4dC5jYXRjaCBtZXRob2QgbXVzdCBvbmx5IGJlIGNhbGxlZCB3aXRoIGEgbG9jYXRpb25cbiAgICAgIC8vIGFyZ3VtZW50IHRoYXQgY29ycmVzcG9uZHMgdG8gYSBrbm93biBjYXRjaCBibG9jay5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlsbGVnYWwgY2F0Y2ggYXR0ZW1wdFwiKTtcbiAgICB9LFxuXG4gICAgZGVsZWdhdGVZaWVsZDogZnVuY3Rpb24oaXRlcmFibGUsIHJlc3VsdE5hbWUsIG5leHRMb2MpIHtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSB7XG4gICAgICAgIGl0ZXJhdG9yOiB2YWx1ZXMoaXRlcmFibGUpLFxuICAgICAgICByZXN1bHROYW1lOiByZXN1bHROYW1lLFxuICAgICAgICBuZXh0TG9jOiBuZXh0TG9jXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgIC8vIERlbGliZXJhdGVseSBmb3JnZXQgdGhlIGxhc3Qgc2VudCB2YWx1ZSBzbyB0aGF0IHdlIGRvbid0XG4gICAgICAgIC8vIGFjY2lkZW50YWxseSBwYXNzIGl0IG9uIHRvIHRoZSBkZWxlZ2F0ZS5cbiAgICAgICAgdGhpcy5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cbiAgfTtcbn0pKFxuICAvLyBBbW9uZyB0aGUgdmFyaW91cyB0cmlja3MgZm9yIG9idGFpbmluZyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsXG4gIC8vIG9iamVjdCwgdGhpcyBzZWVtcyB0byBiZSB0aGUgbW9zdCByZWxpYWJsZSB0ZWNobmlxdWUgdGhhdCBkb2VzIG5vdFxuICAvLyB1c2UgaW5kaXJlY3QgZXZhbCAod2hpY2ggdmlvbGF0ZXMgQ29udGVudCBTZWN1cml0eSBQb2xpY3kpLlxuICB0eXBlb2YgZ2xvYmFsID09PSBcIm9iamVjdFwiID8gZ2xvYmFsIDpcbiAgdHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIiA/IHdpbmRvdyA6XG4gIHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IHRoaXNcbik7XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQgIT09IHVuZGVmaW5lZFxuICA/IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gIDogdHlwZWRBcnJheVN1cHBvcnQoKVxuXG4vKlxuICogRXhwb3J0IGtNYXhMZW5ndGggYWZ0ZXIgdHlwZWQgYXJyYXkgc3VwcG9ydCBpcyBkZXRlcm1pbmVkLlxuICovXG5leHBvcnRzLmtNYXhMZW5ndGggPSBrTWF4TGVuZ3RoKClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5fX3Byb3RvX18gPSB7X19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9fVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChrTWF4TGVuZ3RoKCkgPCBsZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlZCBhcnJheSBsZW5ndGgnKVxuICB9XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIGlmICh0aGF0ID09PSBudWxsKSB7XG4gICAgICB0aGF0ID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gICAgfVxuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiAhKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZSh0aGlzLCBhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20odGhpcywgYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG4vLyBUT0RPOiBMZWdhY3ksIG5vdCBuZWVkZWQgYW55bW9yZS4gUmVtb3ZlIGluIG5leHQgbWFqb3IgdmVyc2lvbi5cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiBmcm9tICh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhhdCwgdmFsdWUpXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20obnVsbCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICYmXG4gICAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgICAvLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IHRoYXQud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIHRoYXQgPSB0aGF0LnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKHRoYXQsIGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgYXJyYXkuYnl0ZUxlbmd0aCAvLyB0aGlzIHRocm93cyBpZiBgYXJyYXlgIGlzIG5vdCBhIHZhbGlkIEFycmF5QnVmZmVyXG5cbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ29mZnNldFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnbGVuZ3RoXFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW4pXG5cbiAgICBpZiAodGhhdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGF0XG4gICAgfVxuXG4gICAgb2JqLmNvcHkodGhhdCwgMCwgMCwgbGVuKVxuICAgIHJldHVybiB0aGF0XG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGgoKWAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgc3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhlIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgYW5kIGBpcy1idWZmZXJgIChpbiBTYWZhcmkgNS03KSB0byBkZXRlY3Rcbi8vIEJ1ZmZlciBpbnN0YW5jZXMuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgIC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChpc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmXG4gICAgICAgIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgKytpKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDQpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuICB2YXIgaVxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIGlmIChsZW4gPCAxMDAwIHx8ICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIGFzY2VuZGluZyBjb3B5IGZyb20gc3RhcnRcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKGNvZGUgPCAyNTYpIHtcbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IHV0ZjhUb0J5dGVzKG5ldyBCdWZmZXIodmFsLCBlbmNvZGluZykudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gaXNuYW4gKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSB2YWwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9jb3JlLnJlZ2V4cC5lc2NhcGUnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLlJlZ0V4cC5lc2NhcGU7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCJ2YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgbXNnKSB7XG4gIGlmICh0eXBlb2YgaXQgIT0gJ251bWJlcicgJiYgY29mKGl0KSAhPSAnTnVtYmVyJykgdGhyb3cgVHlwZUVycm9yKG1zZyk7XG4gIHJldHVybiAraXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMxIEFycmF5LnByb3RvdHlwZVtAQHVuc2NvcGFibGVzXVxudmFyIFVOU0NPUEFCTEVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3Vuc2NvcGFibGVzJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcbmlmIChBcnJheVByb3RvW1VOU0NPUEFCTEVTXSA9PSB1bmRlZmluZWQpIHJlcXVpcmUoJy4vX2hpZGUnKShBcnJheVByb3RvLCBVTlNDT1BBQkxFUywge30pO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdW2tleV0gPSB0cnVlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKHRydWUpO1xuXG4gLy8gYEFkdmFuY2VTdHJpbmdJbmRleGAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1hZHZhbmNlc3RyaW5naW5kZXhcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFMsIGluZGV4LCB1bmljb2RlKSB7XG4gIHJldHVybiBpbmRleCArICh1bmljb2RlID8gYXQoUywgaW5kZXgpLmxlbmd0aCA6IDEpO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpIHtcbiAgaWYgKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkgdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMgQXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCwgZW5kID0gdGhpcy5sZW5ndGgpXG4ndXNlIHN0cmljdCc7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gW10uY29weVdpdGhpbiB8fCBmdW5jdGlvbiBjb3B5V2l0aGluKHRhcmdldCAvKiA9IDAgKi8sIHN0YXJ0IC8qID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgdG8gPSB0b0Fic29sdXRlSW5kZXgodGFyZ2V0LCBsZW4pO1xuICB2YXIgZnJvbSA9IHRvQWJzb2x1dGVJbmRleChzdGFydCwgbGVuKTtcbiAgdmFyIGVuZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgY291bnQgPSBNYXRoLm1pbigoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pKSAtIGZyb20sIGxlbiAtIHRvKTtcbiAgdmFyIGluYyA9IDE7XG4gIGlmIChmcm9tIDwgdG8gJiYgdG8gPCBmcm9tICsgY291bnQpIHtcbiAgICBpbmMgPSAtMTtcbiAgICBmcm9tICs9IGNvdW50IC0gMTtcbiAgICB0byArPSBjb3VudCAtIDE7XG4gIH1cbiAgd2hpbGUgKGNvdW50LS0gPiAwKSB7XG4gICAgaWYgKGZyb20gaW4gTykgT1t0b10gPSBPW2Zyb21dO1xuICAgIGVsc2UgZGVsZXRlIE9bdG9dO1xuICAgIHRvICs9IGluYztcbiAgICBmcm9tICs9IGluYztcbiAgfSByZXR1cm4gTztcbn07XG4iLCIvLyAyMi4xLjMuNiBBcnJheS5wcm90b3R5cGUuZmlsbCh2YWx1ZSwgc3RhcnQgPSAwLCBlbmQgPSB0aGlzLmxlbmd0aClcbid1c2Ugc3RyaWN0JztcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmlsbCh2YWx1ZSAvKiAsIHN0YXJ0ID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IHRvQWJzb2x1dGVJbmRleChhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgbGVuZ3RoKTtcbiAgdmFyIGVuZCA9IGFMZW4gPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgZW5kUG9zID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW5ndGgpO1xuICB3aGlsZSAoZW5kUG9zID4gaW5kZXgpIE9baW5kZXgrK10gPSB2YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXIsIElURVJBVE9SKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yT2YoaXRlciwgZmFsc2UsIHJlc3VsdC5wdXNoLCByZXN1bHQsIElURVJBVE9SKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvLyBmYWxzZSAtPiBBcnJheSNpbmRleE9mXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChJU19JTkNMVURFUykge1xuICByZXR1cm4gZnVuY3Rpb24gKCR0aGlzLCBlbCwgZnJvbUluZGV4KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoJHRoaXMpO1xuICAgIHZhciBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgdmFyIGluZGV4ID0gdG9BYnNvbHV0ZUluZGV4KGZyb21JbmRleCwgbGVuZ3RoKTtcbiAgICB2YXIgdmFsdWU7XG4gICAgLy8gQXJyYXkjaW5jbHVkZXMgdXNlcyBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICBpZiAoSVNfSU5DTFVERVMgJiYgZWwgIT0gZWwpIHdoaWxlIChsZW5ndGggPiBpbmRleCkge1xuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgICAgaWYgKHZhbHVlICE9IHZhbHVlKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBBcnJheSNpbmRleE9mIGlnbm9yZXMgaG9sZXMsIEFycmF5I2luY2x1ZGVzIC0gbm90XG4gICAgfSBlbHNlIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoSVNfSU5DTFVERVMgfHwgaW5kZXggaW4gTykge1xuICAgICAgaWYgKE9baW5kZXhdID09PSBlbCkgcmV0dXJuIElTX0lOQ0xVREVTIHx8IGluZGV4IHx8IDA7XG4gICAgfSByZXR1cm4gIUlTX0lOQ0xVREVTICYmIC0xO1xuICB9O1xufTtcbiIsIi8vIDAgLT4gQXJyYXkjZm9yRWFjaFxuLy8gMSAtPiBBcnJheSNtYXBcbi8vIDIgLT4gQXJyYXkjZmlsdGVyXG4vLyAzIC0+IEFycmF5I3NvbWVcbi8vIDQgLT4gQXJyYXkjZXZlcnlcbi8vIDUgLT4gQXJyYXkjZmluZFxuLy8gNiAtPiBBcnJheSNmaW5kSW5kZXhcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBhc2MgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoVFlQRSwgJGNyZWF0ZSkge1xuICB2YXIgSVNfTUFQID0gVFlQRSA9PSAxO1xuICB2YXIgSVNfRklMVEVSID0gVFlQRSA9PSAyO1xuICB2YXIgSVNfU09NRSA9IFRZUEUgPT0gMztcbiAgdmFyIElTX0VWRVJZID0gVFlQRSA9PSA0O1xuICB2YXIgSVNfRklORF9JTkRFWCA9IFRZUEUgPT0gNjtcbiAgdmFyIE5PX0hPTEVTID0gVFlQRSA9PSA1IHx8IElTX0ZJTkRfSU5ERVg7XG4gIHZhciBjcmVhdGUgPSAkY3JlYXRlIHx8IGFzYztcbiAgcmV0dXJuIGZ1bmN0aW9uICgkdGhpcywgY2FsbGJhY2tmbiwgdGhhdCkge1xuICAgIHZhciBPID0gdG9PYmplY3QoJHRoaXMpO1xuICAgIHZhciBzZWxmID0gSU9iamVjdChPKTtcbiAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCB0aGF0LCAzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoc2VsZi5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHJlc3VsdCA9IElTX01BUCA/IGNyZWF0ZSgkdGhpcywgbGVuZ3RoKSA6IElTX0ZJTFRFUiA/IGNyZWF0ZSgkdGhpcywgMCkgOiB1bmRlZmluZWQ7XG4gICAgdmFyIHZhbCwgcmVzO1xuICAgIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoTk9fSE9MRVMgfHwgaW5kZXggaW4gc2VsZikge1xuICAgICAgdmFsID0gc2VsZltpbmRleF07XG4gICAgICByZXMgPSBmKHZhbCwgaW5kZXgsIE8pO1xuICAgICAgaWYgKFRZUEUpIHtcbiAgICAgICAgaWYgKElTX01BUCkgcmVzdWx0W2luZGV4XSA9IHJlczsgICAvLyBtYXBcbiAgICAgICAgZWxzZSBpZiAocmVzKSBzd2l0Y2ggKFRZUEUpIHtcbiAgICAgICAgICBjYXNlIDM6IHJldHVybiB0cnVlOyAgICAgICAgICAgICAvLyBzb21lXG4gICAgICAgICAgY2FzZSA1OiByZXR1cm4gdmFsOyAgICAgICAgICAgICAgLy8gZmluZFxuICAgICAgICAgIGNhc2UgNjogcmV0dXJuIGluZGV4OyAgICAgICAgICAgIC8vIGZpbmRJbmRleFxuICAgICAgICAgIGNhc2UgMjogcmVzdWx0LnB1c2godmFsKTsgICAgICAgIC8vIGZpbHRlclxuICAgICAgICB9IGVsc2UgaWYgKElTX0VWRVJZKSByZXR1cm4gZmFsc2U7IC8vIGV2ZXJ5XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBJU19GSU5EX0lOREVYID8gLTEgOiBJU19TT01FIHx8IElTX0VWRVJZID8gSVNfRVZFUlkgOiByZXN1bHQ7XG4gIH07XG59O1xuIiwidmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgY2FsbGJhY2tmbiwgYUxlbiwgbWVtbywgaXNSaWdodCkge1xuICBhRnVuY3Rpb24oY2FsbGJhY2tmbik7XG4gIHZhciBPID0gdG9PYmplY3QodGhhdCk7XG4gIHZhciBzZWxmID0gSU9iamVjdChPKTtcbiAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgdmFyIGluZGV4ID0gaXNSaWdodCA/IGxlbmd0aCAtIDEgOiAwO1xuICB2YXIgaSA9IGlzUmlnaHQgPyAtMSA6IDE7XG4gIGlmIChhTGVuIDwgMikgZm9yICg7Oykge1xuICAgIGlmIChpbmRleCBpbiBzZWxmKSB7XG4gICAgICBtZW1vID0gc2VsZltpbmRleF07XG4gICAgICBpbmRleCArPSBpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGluZGV4ICs9IGk7XG4gICAgaWYgKGlzUmlnaHQgPyBpbmRleCA8IDAgOiBsZW5ndGggPD0gaW5kZXgpIHtcbiAgICAgIHRocm93IFR5cGVFcnJvcignUmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgIH1cbiAgfVxuICBmb3IgKDtpc1JpZ2h0ID8gaW5kZXggPj0gMCA6IGxlbmd0aCA+IGluZGV4OyBpbmRleCArPSBpKSBpZiAoaW5kZXggaW4gc2VsZikge1xuICAgIG1lbW8gPSBjYWxsYmFja2ZuKG1lbW8sIHNlbGZbaW5kZXhdLCBpbmRleCwgTyk7XG4gIH1cbiAgcmV0dXJuIG1lbW87XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9yaWdpbmFsKSB7XG4gIHZhciBDO1xuICBpZiAoaXNBcnJheShvcmlnaW5hbCkpIHtcbiAgICBDID0gb3JpZ2luYWwuY29uc3RydWN0b3I7XG4gICAgLy8gY3Jvc3MtcmVhbG0gZmFsbGJhY2tcbiAgICBpZiAodHlwZW9mIEMgPT0gJ2Z1bmN0aW9uJyAmJiAoQyA9PT0gQXJyYXkgfHwgaXNBcnJheShDLnByb3RvdHlwZSkpKSBDID0gdW5kZWZpbmVkO1xuICAgIGlmIChpc09iamVjdChDKSkge1xuICAgICAgQyA9IENbU1BFQ0lFU107XG4gICAgICBpZiAoQyA9PT0gbnVsbCkgQyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gcmV0dXJuIEMgPT09IHVuZGVmaW5lZCA/IEFycmF5IDogQztcbn07XG4iLCIvLyA5LjQuMi4zIEFycmF5U3BlY2llc0NyZWF0ZShvcmlnaW5hbEFycmF5LCBsZW5ndGgpXG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcmlnaW5hbCwgbGVuZ3RoKSB7XG4gIHJldHVybiBuZXcgKHNwZWNpZXNDb25zdHJ1Y3RvcihvcmlnaW5hbCkpKGxlbmd0aCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGFycmF5U2xpY2UgPSBbXS5zbGljZTtcbnZhciBmYWN0b3JpZXMgPSB7fTtcblxudmFyIGNvbnN0cnVjdCA9IGZ1bmN0aW9uIChGLCBsZW4sIGFyZ3MpIHtcbiAgaWYgKCEobGVuIGluIGZhY3RvcmllcykpIHtcbiAgICBmb3IgKHZhciBuID0gW10sIGkgPSAwOyBpIDwgbGVuOyBpKyspIG5baV0gPSAnYVsnICsgaSArICddJztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICBmYWN0b3JpZXNbbGVuXSA9IEZ1bmN0aW9uKCdGLGEnLCAncmV0dXJuIG5ldyBGKCcgKyBuLmpvaW4oJywnKSArICcpJyk7XG4gIH0gcmV0dXJuIGZhY3Rvcmllc1tsZW5dKEYsIGFyZ3MpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5iaW5kIHx8IGZ1bmN0aW9uIGJpbmQodGhhdCAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgdmFyIGZuID0gYUZ1bmN0aW9uKHRoaXMpO1xuICB2YXIgcGFydEFyZ3MgPSBhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgdmFyIGJvdW5kID0gZnVuY3Rpb24gKC8qIGFyZ3MuLi4gKi8pIHtcbiAgICB2YXIgYXJncyA9IHBhcnRBcmdzLmNvbmNhdChhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBib3VuZCA/IGNvbnN0cnVjdChmbiwgYXJncy5sZW5ndGgsIGFyZ3MpIDogaW52b2tlKGZuLCBhcmdzLCB0aGF0KTtcbiAgfTtcbiAgaWYgKGlzT2JqZWN0KGZuLnByb3RvdHlwZSkpIGJvdW5kLnByb3RvdHlwZSA9IGZuLnByb3RvdHlwZTtcbiAgcmV0dXJuIGJvdW5kO1xufTtcbiIsIi8vIGdldHRpbmcgdGFnIGZyb20gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgVEFHID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyk7XG4vLyBFUzMgd3JvbmcgaGVyZVxudmFyIEFSRyA9IGNvZihmdW5jdGlvbiAoKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPT0gJ0FyZ3VtZW50cyc7XG5cbi8vIGZhbGxiYWNrIGZvciBJRTExIFNjcmlwdCBBY2Nlc3MgRGVuaWVkIGVycm9yXG52YXIgdHJ5R2V0ID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gaXRba2V5XTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgTywgVCwgQjtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyAnVW5kZWZpbmVkJyA6IGl0ID09PSBudWxsID8gJ051bGwnXG4gICAgLy8gQEB0b1N0cmluZ1RhZyBjYXNlXG4gICAgOiB0eXBlb2YgKFQgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRBRykpID09ICdzdHJpbmcnID8gVFxuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQVJHID8gY29mKE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKEIgPSBjb2YoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiBCO1xufTtcbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciAkaXRlckRlZmluZSA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJyk7XG52YXIgc3RlcCA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpO1xudmFyIHNldFNwZWNpZXMgPSByZXF1aXJlKCcuL19zZXQtc3BlY2llcycpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBmYXN0S2V5ID0gcmVxdWlyZSgnLi9fbWV0YScpLmZhc3RLZXk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgU0laRSA9IERFU0NSSVBUT1JTID8gJ19zJyA6ICdzaXplJztcblxudmFyIGdldEVudHJ5ID0gZnVuY3Rpb24gKHRoYXQsIGtleSkge1xuICAvLyBmYXN0IGNhc2VcbiAgdmFyIGluZGV4ID0gZmFzdEtleShrZXkpO1xuICB2YXIgZW50cnk7XG4gIGlmIChpbmRleCAhPT0gJ0YnKSByZXR1cm4gdGhhdC5faVtpbmRleF07XG4gIC8vIGZyb3plbiBvYmplY3QgY2FzZVxuICBmb3IgKGVudHJ5ID0gdGhhdC5fZjsgZW50cnk7IGVudHJ5ID0gZW50cnkubikge1xuICAgIGlmIChlbnRyeS5rID09IGtleSkgcmV0dXJuIGVudHJ5O1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q29uc3RydWN0b3I6IGZ1bmN0aW9uICh3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKSB7XG4gICAgdmFyIEMgPSB3cmFwcGVyKGZ1bmN0aW9uICh0aGF0LCBpdGVyYWJsZSkge1xuICAgICAgYW5JbnN0YW5jZSh0aGF0LCBDLCBOQU1FLCAnX2knKTtcbiAgICAgIHRoYXQuX3QgPSBOQU1FOyAgICAgICAgIC8vIGNvbGxlY3Rpb24gdHlwZVxuICAgICAgdGhhdC5faSA9IGNyZWF0ZShudWxsKTsgLy8gaW5kZXhcbiAgICAgIHRoYXQuX2YgPSB1bmRlZmluZWQ7ICAgIC8vIGZpcnN0IGVudHJ5XG4gICAgICB0aGF0Ll9sID0gdW5kZWZpbmVkOyAgICAvLyBsYXN0IGVudHJ5XG4gICAgICB0aGF0W1NJWkVdID0gMDsgICAgICAgICAvLyBzaXplXG4gICAgICBpZiAoaXRlcmFibGUgIT0gdW5kZWZpbmVkKSBmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XG4gICAgfSk7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIHtcbiAgICAgIC8vIDIzLjEuMy4xIE1hcC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgLy8gMjMuMi4zLjIgU2V0LnByb3RvdHlwZS5jbGVhcigpXG4gICAgICBjbGVhcjogZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgICAgIGZvciAodmFyIHRoYXQgPSB2YWxpZGF0ZSh0aGlzLCBOQU1FKSwgZGF0YSA9IHRoYXQuX2ksIGVudHJ5ID0gdGhhdC5fZjsgZW50cnk7IGVudHJ5ID0gZW50cnkubikge1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmIChlbnRyeS5wKSBlbnRyeS5wID0gZW50cnkucC5uID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGRlbGV0ZSBkYXRhW2VudHJ5LmldO1xuICAgICAgICB9XG4gICAgICAgIHRoYXQuX2YgPSB0aGF0Ll9sID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGF0W1NJWkVdID0gMDtcbiAgICAgIH0sXG4gICAgICAvLyAyMy4xLjMuMyBNYXAucHJvdG90eXBlLmRlbGV0ZShrZXkpXG4gICAgICAvLyAyMy4yLjMuNCBTZXQucHJvdG90eXBlLmRlbGV0ZSh2YWx1ZSlcbiAgICAgICdkZWxldGUnOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciB0aGF0ID0gdmFsaWRhdGUodGhpcywgTkFNRSk7XG4gICAgICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSk7XG4gICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgIHZhciBuZXh0ID0gZW50cnkubjtcbiAgICAgICAgICB2YXIgcHJldiA9IGVudHJ5LnA7XG4gICAgICAgICAgZGVsZXRlIHRoYXQuX2lbZW50cnkuaV07XG4gICAgICAgICAgZW50cnkuciA9IHRydWU7XG4gICAgICAgICAgaWYgKHByZXYpIHByZXYubiA9IG5leHQ7XG4gICAgICAgICAgaWYgKG5leHQpIG5leHQucCA9IHByZXY7XG4gICAgICAgICAgaWYgKHRoYXQuX2YgPT0gZW50cnkpIHRoYXQuX2YgPSBuZXh0O1xuICAgICAgICAgIGlmICh0aGF0Ll9sID09IGVudHJ5KSB0aGF0Ll9sID0gcHJldjtcbiAgICAgICAgICB0aGF0W1NJWkVdLS07XG4gICAgICAgIH0gcmV0dXJuICEhZW50cnk7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMi4zLjYgU2V0LnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4sIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gICAgICAvLyAyMy4xLjMuNSBNYXAucHJvdG90eXBlLmZvckVhY2goY2FsbGJhY2tmbiwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbiAvKiAsIHRoYXQgPSB1bmRlZmluZWQgKi8pIHtcbiAgICAgICAgdmFsaWRhdGUodGhpcywgTkFNRSk7XG4gICAgICAgIHZhciBmID0gY3R4KGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCAzKTtcbiAgICAgICAgdmFyIGVudHJ5O1xuICAgICAgICB3aGlsZSAoZW50cnkgPSBlbnRyeSA/IGVudHJ5Lm4gOiB0aGlzLl9mKSB7XG4gICAgICAgICAgZihlbnRyeS52LCBlbnRyeS5rLCB0aGlzKTtcbiAgICAgICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcbiAgICAgICAgICB3aGlsZSAoZW50cnkgJiYgZW50cnkucikgZW50cnkgPSBlbnRyeS5wO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjcgTWFwLnByb3RvdHlwZS5oYXMoa2V5KVxuICAgICAgLy8gMjMuMi4zLjcgU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXG4gICAgICBoYXM6IGZ1bmN0aW9uIGhhcyhrZXkpIHtcbiAgICAgICAgcmV0dXJuICEhZ2V0RW50cnkodmFsaWRhdGUodGhpcywgTkFNRSksIGtleSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKERFU0NSSVBUT1JTKSBkUChDLnByb3RvdHlwZSwgJ3NpemUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRlKHRoaXMsIE5BTUUpW1NJWkVdO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBDO1xuICB9LFxuICBkZWY6IGZ1bmN0aW9uICh0aGF0LCBrZXksIHZhbHVlKSB7XG4gICAgdmFyIGVudHJ5ID0gZ2V0RW50cnkodGhhdCwga2V5KTtcbiAgICB2YXIgcHJldiwgaW5kZXg7XG4gICAgLy8gY2hhbmdlIGV4aXN0aW5nIGVudHJ5XG4gICAgaWYgKGVudHJ5KSB7XG4gICAgICBlbnRyeS52ID0gdmFsdWU7XG4gICAgLy8gY3JlYXRlIG5ldyBlbnRyeVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGF0Ll9sID0gZW50cnkgPSB7XG4gICAgICAgIGk6IGluZGV4ID0gZmFzdEtleShrZXksIHRydWUpLCAvLyA8LSBpbmRleFxuICAgICAgICBrOiBrZXksICAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0ga2V5XG4gICAgICAgIHY6IHZhbHVlLCAgICAgICAgICAgICAgICAgICAgICAvLyA8LSB2YWx1ZVxuICAgICAgICBwOiBwcmV2ID0gdGhhdC5fbCwgICAgICAgICAgICAgLy8gPC0gcHJldmlvdXMgZW50cnlcbiAgICAgICAgbjogdW5kZWZpbmVkLCAgICAgICAgICAgICAgICAgIC8vIDwtIG5leHQgZW50cnlcbiAgICAgICAgcjogZmFsc2UgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIHJlbW92ZWRcbiAgICAgIH07XG4gICAgICBpZiAoIXRoYXQuX2YpIHRoYXQuX2YgPSBlbnRyeTtcbiAgICAgIGlmIChwcmV2KSBwcmV2Lm4gPSBlbnRyeTtcbiAgICAgIHRoYXRbU0laRV0rKztcbiAgICAgIC8vIGFkZCB0byBpbmRleFxuICAgICAgaWYgKGluZGV4ICE9PSAnRicpIHRoYXQuX2lbaW5kZXhdID0gZW50cnk7XG4gICAgfSByZXR1cm4gdGhhdDtcbiAgfSxcbiAgZ2V0RW50cnk6IGdldEVudHJ5LFxuICBzZXRTdHJvbmc6IGZ1bmN0aW9uIChDLCBOQU1FLCBJU19NQVApIHtcbiAgICAvLyBhZGQgLmtleXMsIC52YWx1ZXMsIC5lbnRyaWVzLCBbQEBpdGVyYXRvcl1cbiAgICAvLyAyMy4xLjMuNCwgMjMuMS4zLjgsIDIzLjEuMy4xMSwgMjMuMS4zLjEyLCAyMy4yLjMuNSwgMjMuMi4zLjgsIDIzLjIuMy4xMCwgMjMuMi4zLjExXG4gICAgJGl0ZXJEZWZpbmUoQywgTkFNRSwgZnVuY3Rpb24gKGl0ZXJhdGVkLCBraW5kKSB7XG4gICAgICB0aGlzLl90ID0gdmFsaWRhdGUoaXRlcmF0ZWQsIE5BTUUpOyAvLyB0YXJnZXRcbiAgICAgIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAgICAgIC8vIGtpbmRcbiAgICAgIHRoaXMuX2wgPSB1bmRlZmluZWQ7ICAgICAgICAgICAgICAgIC8vIHByZXZpb3VzXG4gICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgdmFyIGtpbmQgPSB0aGF0Ll9rO1xuICAgICAgdmFyIGVudHJ5ID0gdGhhdC5fbDtcbiAgICAgIC8vIHJldmVydCB0byB0aGUgbGFzdCBleGlzdGluZyBlbnRyeVxuICAgICAgd2hpbGUgKGVudHJ5ICYmIGVudHJ5LnIpIGVudHJ5ID0gZW50cnkucDtcbiAgICAgIC8vIGdldCBuZXh0IGVudHJ5XG4gICAgICBpZiAoIXRoYXQuX3QgfHwgISh0aGF0Ll9sID0gZW50cnkgPSBlbnRyeSA/IGVudHJ5Lm4gOiB0aGF0Ll90Ll9mKSkge1xuICAgICAgICAvLyBvciBmaW5pc2ggdGhlIGl0ZXJhdGlvblxuICAgICAgICB0aGF0Ll90ID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gc3RlcCgxKTtcbiAgICAgIH1cbiAgICAgIC8vIHJldHVybiBzdGVwIGJ5IGtpbmRcbiAgICAgIGlmIChraW5kID09ICdrZXlzJykgcmV0dXJuIHN0ZXAoMCwgZW50cnkuayk7XG4gICAgICBpZiAoa2luZCA9PSAndmFsdWVzJykgcmV0dXJuIHN0ZXAoMCwgZW50cnkudik7XG4gICAgICByZXR1cm4gc3RlcCgwLCBbZW50cnkuaywgZW50cnkudl0pO1xuICAgIH0sIElTX01BUCA/ICdlbnRyaWVzJyA6ICd2YWx1ZXMnLCAhSVNfTUFQLCB0cnVlKTtcblxuICAgIC8vIGFkZCBbQEBzcGVjaWVzXSwgMjMuMS4yLjIsIDIzLjIuMi4yXG4gICAgc2V0U3BlY2llcyhOQU1FKTtcbiAgfVxufTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9EYXZpZEJydWFudC9NYXAtU2V0LnByb3RvdHlwZS50b0pTT05cbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIGZyb20gPSByZXF1aXJlKCcuL19hcnJheS1mcm9tLWl0ZXJhYmxlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChOQU1FKSB7XG4gIHJldHVybiBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgaWYgKGNsYXNzb2YodGhpcykgIT0gTkFNRSkgdGhyb3cgVHlwZUVycm9yKE5BTUUgKyBcIiN0b0pTT04gaXNuJ3QgZ2VuZXJpY1wiKTtcbiAgICByZXR1cm4gZnJvbSh0aGlzKTtcbiAgfTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbnZhciBnZXRXZWFrID0gcmVxdWlyZSgnLi9fbWV0YScpLmdldFdlYWs7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgY3JlYXRlQXJyYXlNZXRob2QgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJyk7XG52YXIgJGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIGFycmF5RmluZCA9IGNyZWF0ZUFycmF5TWV0aG9kKDUpO1xudmFyIGFycmF5RmluZEluZGV4ID0gY3JlYXRlQXJyYXlNZXRob2QoNik7XG52YXIgaWQgPSAwO1xuXG4vLyBmYWxsYmFjayBmb3IgdW5jYXVnaHQgZnJvemVuIGtleXNcbnZhciB1bmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24gKHRoYXQpIHtcbiAgcmV0dXJuIHRoYXQuX2wgfHwgKHRoYXQuX2wgPSBuZXcgVW5jYXVnaHRGcm96ZW5TdG9yZSgpKTtcbn07XG52YXIgVW5jYXVnaHRGcm96ZW5TdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5hID0gW107XG59O1xudmFyIGZpbmRVbmNhdWdodEZyb3plbiA9IGZ1bmN0aW9uIChzdG9yZSwga2V5KSB7XG4gIHJldHVybiBhcnJheUZpbmQoc3RvcmUuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgcmV0dXJuIGl0WzBdID09PSBrZXk7XG4gIH0pO1xufTtcblVuY2F1Z2h0RnJvemVuU3RvcmUucHJvdG90eXBlID0ge1xuICBnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIHJldHVybiBlbnRyeVsxXTtcbiAgfSxcbiAgaGFzOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuICEhZmluZFVuY2F1Z2h0RnJvemVuKHRoaXMsIGtleSk7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIGVudHJ5WzFdID0gdmFsdWU7XG4gICAgZWxzZSB0aGlzLmEucHVzaChba2V5LCB2YWx1ZV0pO1xuICB9LFxuICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBpbmRleCA9IGFycmF5RmluZEluZGV4KHRoaXMuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgICB9KTtcbiAgICBpZiAofmluZGV4KSB0aGlzLmEuc3BsaWNlKGluZGV4LCAxKTtcbiAgICByZXR1cm4gISF+aW5kZXg7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDb25zdHJ1Y3RvcjogZnVuY3Rpb24gKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpIHtcbiAgICB2YXIgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGl0ZXJhYmxlKSB7XG4gICAgICBhbkluc3RhbmNlKHRoYXQsIEMsIE5BTUUsICdfaScpO1xuICAgICAgdGhhdC5fdCA9IE5BTUU7ICAgICAgLy8gY29sbGVjdGlvbiB0eXBlXG4gICAgICB0aGF0Ll9pID0gaWQrKzsgICAgICAvLyBjb2xsZWN0aW9uIGlkXG4gICAgICB0aGF0Ll9sID0gdW5kZWZpbmVkOyAvLyBsZWFrIHN0b3JlIGZvciB1bmNhdWdodCBmcm96ZW4gb2JqZWN0c1xuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4zLjMuMiBXZWFrTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuNC4zLjMgV2Vha1NldC5wcm90b3R5cGUuZGVsZXRlKHZhbHVlKVxuICAgICAgJ2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpWydkZWxldGUnXShrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpICYmIGRlbGV0ZSBkYXRhW3RoaXMuX2ldO1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjMuMy40IFdlYWtNYXAucHJvdG90eXBlLmhhcyhrZXkpXG4gICAgICAvLyAyMy40LjMuNCBXZWFrU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXG4gICAgICBoYXM6IGZ1bmN0aW9uIGhhcyhrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpLmhhcyhrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBDO1xuICB9LFxuICBkZWY6IGZ1bmN0aW9uICh0aGF0LCBrZXksIHZhbHVlKSB7XG4gICAgdmFyIGRhdGEgPSBnZXRXZWFrKGFuT2JqZWN0KGtleSksIHRydWUpO1xuICAgIGlmIChkYXRhID09PSB0cnVlKSB1bmNhdWdodEZyb3plblN0b3JlKHRoYXQpLnNldChrZXksIHZhbHVlKTtcbiAgICBlbHNlIGRhdGFbdGhhdC5faV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhhdDtcbiAgfSxcbiAgdWZzdG9yZTogdW5jYXVnaHRGcm96ZW5TdG9yZVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgbWV0YSA9IHJlcXVpcmUoJy4vX21ldGEnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyICRpdGVyRGV0ZWN0ID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE5BTUUsIHdyYXBwZXIsIG1ldGhvZHMsIGNvbW1vbiwgSVNfTUFQLCBJU19XRUFLKSB7XG4gIHZhciBCYXNlID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgQyA9IEJhc2U7XG4gIHZhciBBRERFUiA9IElTX01BUCA/ICdzZXQnIDogJ2FkZCc7XG4gIHZhciBwcm90byA9IEMgJiYgQy5wcm90b3R5cGU7XG4gIHZhciBPID0ge307XG4gIHZhciBmaXhNZXRob2QgPSBmdW5jdGlvbiAoS0VZKSB7XG4gICAgdmFyIGZuID0gcHJvdG9bS0VZXTtcbiAgICByZWRlZmluZShwcm90bywgS0VZLFxuICAgICAgS0VZID09ICdkZWxldGUnID8gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdoYXMnID8gZnVuY3Rpb24gaGFzKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdnZXQnID8gZnVuY3Rpb24gZ2V0KGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gdW5kZWZpbmVkIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnYWRkJyA/IGZ1bmN0aW9uIGFkZChhKSB7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTsgcmV0dXJuIHRoaXM7IH1cbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYikgeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSwgYik7IHJldHVybiB0aGlzOyB9XG4gICAgKTtcbiAgfTtcbiAgaWYgKHR5cGVvZiBDICE9ICdmdW5jdGlvbicgfHwgIShJU19XRUFLIHx8IHByb3RvLmZvckVhY2ggJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgQygpLmVudHJpZXMoKS5uZXh0KCk7XG4gIH0pKSkge1xuICAgIC8vIGNyZWF0ZSBjb2xsZWN0aW9uIGNvbnN0cnVjdG9yXG4gICAgQyA9IGNvbW1vbi5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gICAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcbiAgICB2YXIgSEFTTlRfQ0hBSU5JTkcgPSBpbnN0YW5jZVtBRERFUl0oSVNfV0VBSyA/IHt9IDogLTAsIDEpICE9IGluc3RhbmNlO1xuICAgIC8vIFY4IH4gIENocm9taXVtIDQwLSB3ZWFrLWNvbGxlY3Rpb25zIHRocm93cyBvbiBwcmltaXRpdmVzLCBidXQgc2hvdWxkIHJldHVybiBmYWxzZVxuICAgIHZhciBUSFJPV1NfT05fUFJJTUlUSVZFUyA9IGZhaWxzKGZ1bmN0aW9uICgpIHsgaW5zdGFuY2UuaGFzKDEpOyB9KTtcbiAgICAvLyBtb3N0IGVhcmx5IGltcGxlbWVudGF0aW9ucyBkb2Vzbid0IHN1cHBvcnRzIGl0ZXJhYmxlcywgbW9zdCBtb2Rlcm4gLSBub3QgY2xvc2UgaXQgY29ycmVjdGx5XG4gICAgdmFyIEFDQ0VQVF9JVEVSQUJMRVMgPSAkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikgeyBuZXcgQyhpdGVyKTsgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXG4gICAgdmFyIEJVR0dZX1pFUk8gPSAhSVNfV0VBSyAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBWOCB+IENocm9taXVtIDQyLSBmYWlscyBvbmx5IHdpdGggNSsgZWxlbWVudHNcbiAgICAgIHZhciAkaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgICAgdmFyIGluZGV4ID0gNTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSAkaW5zdGFuY2VbQURERVJdKGluZGV4LCBpbmRleCk7XG4gICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xuICAgIH0pO1xuICAgIGlmICghQUNDRVBUX0lURVJBQkxFUykge1xuICAgICAgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRhcmdldCwgaXRlcmFibGUpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0YXJnZXQsIEMsIE5BTUUpO1xuICAgICAgICB2YXIgdGhhdCA9IGluaGVyaXRJZlJlcXVpcmVkKG5ldyBCYXNlKCksIHRhcmdldCwgQyk7XG4gICAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICAgICAgcmV0dXJuIHRoYXQ7XG4gICAgICB9KTtcbiAgICAgIEMucHJvdG90eXBlID0gcHJvdG87XG4gICAgICBwcm90by5jb25zdHJ1Y3RvciA9IEM7XG4gICAgfVxuICAgIGlmIChUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKSB7XG4gICAgICBmaXhNZXRob2QoJ2RlbGV0ZScpO1xuICAgICAgZml4TWV0aG9kKCdoYXMnKTtcbiAgICAgIElTX01BUCAmJiBmaXhNZXRob2QoJ2dldCcpO1xuICAgIH1cbiAgICBpZiAoQlVHR1lfWkVSTyB8fCBIQVNOVF9DSEFJTklORykgZml4TWV0aG9kKEFEREVSKTtcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxuICAgIGlmIChJU19XRUFLICYmIHByb3RvLmNsZWFyKSBkZWxldGUgcHJvdG8uY2xlYXI7XG4gIH1cblxuICBzZXRUb1N0cmluZ1RhZyhDLCBOQU1FKTtcblxuICBPW05BTUVdID0gQztcbiAgJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAoQyAhPSBCYXNlKSwgTyk7XG5cbiAgaWYgKCFJU19XRUFLKSBjb21tb24uc2V0U3Ryb25nKEMsIE5BTUUsIElTX01BUCk7XG5cbiAgcmV0dXJuIEM7XG59O1xuIiwidmFyIGNvcmUgPSBtb2R1bGUuZXhwb3J0cyA9IHsgdmVyc2lvbjogJzIuNi40JyB9O1xuaWYgKHR5cGVvZiBfX2UgPT0gJ251bWJlcicpIF9fZSA9IGNvcmU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIGluZGV4LCB2YWx1ZSkge1xuICBpZiAoaW5kZXggaW4gb2JqZWN0KSAkZGVmaW5lUHJvcGVydHkuZihvYmplY3QsIGluZGV4LCBjcmVhdGVEZXNjKDAsIHZhbHVlKSk7XG4gIGVsc2Ugb2JqZWN0W2luZGV4XSA9IHZhbHVlO1xufTtcbiIsIi8vIG9wdGlvbmFsIC8gc2ltcGxlIGNvbnRleHQgYmluZGluZ1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCB0aGF0LCBsZW5ndGgpIHtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYgKHRoYXQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZuO1xuICBzd2l0Y2ggKGxlbmd0aCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uIChhKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhKTtcbiAgICB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uIChhLCBiLCBjKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiLCBjKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbiAoLyogLi4uYXJncyAqLykge1xuICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIwLjMuNC4zNiAvIDE1LjkuNS40MyBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZygpXG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGdldFRpbWUgPSBEYXRlLnByb3RvdHlwZS5nZXRUaW1lO1xudmFyICR0b0lTT1N0cmluZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nO1xuXG52YXIgbHogPSBmdW5jdGlvbiAobnVtKSB7XG4gIHJldHVybiBudW0gPiA5ID8gbnVtIDogJzAnICsgbnVtO1xufTtcblxuLy8gUGhhbnRvbUpTIC8gb2xkIFdlYktpdCBoYXMgYSBicm9rZW4gaW1wbGVtZW50YXRpb25zXG5tb2R1bGUuZXhwb3J0cyA9IChmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAkdG9JU09TdHJpbmcuY2FsbChuZXcgRGF0ZSgtNWUxMyAtIDEpKSAhPSAnMDM4NS0wNy0yNVQwNzowNjozOS45OTlaJztcbn0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICR0b0lTT1N0cmluZy5jYWxsKG5ldyBEYXRlKE5hTikpO1xufSkpID8gZnVuY3Rpb24gdG9JU09TdHJpbmcoKSB7XG4gIGlmICghaXNGaW5pdGUoZ2V0VGltZS5jYWxsKHRoaXMpKSkgdGhyb3cgUmFuZ2VFcnJvcignSW52YWxpZCB0aW1lIHZhbHVlJyk7XG4gIHZhciBkID0gdGhpcztcbiAgdmFyIHkgPSBkLmdldFVUQ0Z1bGxZZWFyKCk7XG4gIHZhciBtID0gZC5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgdmFyIHMgPSB5IDwgMCA/ICctJyA6IHkgPiA5OTk5ID8gJysnIDogJyc7XG4gIHJldHVybiBzICsgKCcwMDAwMCcgKyBNYXRoLmFicyh5KSkuc2xpY2UocyA/IC02IDogLTQpICtcbiAgICAnLScgKyBseihkLmdldFVUQ01vbnRoKCkgKyAxKSArICctJyArIGx6KGQuZ2V0VVRDRGF0ZSgpKSArXG4gICAgJ1QnICsgbHooZC5nZXRVVENIb3VycygpKSArICc6JyArIGx6KGQuZ2V0VVRDTWludXRlcygpKSArXG4gICAgJzonICsgbHooZC5nZXRVVENTZWNvbmRzKCkpICsgJy4nICsgKG0gPiA5OSA/IG0gOiAnMCcgKyBseihtKSkgKyAnWic7XG59IDogJHRvSVNPU3RyaW5nO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBOVU1CRVIgPSAnbnVtYmVyJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaGludCkge1xuICBpZiAoaGludCAhPT0gJ3N0cmluZycgJiYgaGludCAhPT0gTlVNQkVSICYmIGhpbnQgIT09ICdkZWZhdWx0JykgdGhyb3cgVHlwZUVycm9yKCdJbmNvcnJlY3QgaGludCcpO1xuICByZXR1cm4gdG9QcmltaXRpdmUoYW5PYmplY3QodGhpcyksIGhpbnQgIT0gTlVNQkVSKTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xuLy8gdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgaXMgJ29iamVjdCcgaW4gb2xkIElFXG52YXIgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXMgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwiLy8gYWxsIGVudW1lcmFibGUgb2JqZWN0IGtleXMsIGluY2x1ZGVzIHN5bWJvbHNcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgcmVzdWx0ID0gZ2V0S2V5cyhpdCk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICBpZiAoZ2V0U3ltYm9scykge1xuICAgIHZhciBzeW1ib2xzID0gZ2V0U3ltYm9scyhpdCk7XG4gICAgdmFyIGlzRW51bSA9IHBJRS5mO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChzeW1ib2xzLmxlbmd0aCA+IGkpIGlmIChpc0VudW0uY2FsbChpdCwga2V5ID0gc3ltYm9sc1tpKytdKSkgcmVzdWx0LnB1c2goa2V5KTtcbiAgfSByZXR1cm4gcmVzdWx0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCBzb3VyY2UpIHtcbiAgdmFyIElTX0ZPUkNFRCA9IHR5cGUgJiAkZXhwb3J0LkY7XG4gIHZhciBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HO1xuICB2YXIgSVNfU1RBVElDID0gdHlwZSAmICRleHBvcnQuUztcbiAgdmFyIElTX1BST1RPID0gdHlwZSAmICRleHBvcnQuUDtcbiAgdmFyIElTX0JJTkQgPSB0eXBlICYgJGV4cG9ydC5CO1xuICB2YXIgdGFyZ2V0ID0gSVNfR0xPQkFMID8gZ2xvYmFsIDogSVNfU1RBVElDID8gZ2xvYmFsW25hbWVdIHx8IChnbG9iYWxbbmFtZV0gPSB7fSkgOiAoZ2xvYmFsW25hbWVdIHx8IHt9KVtQUk9UT1RZUEVdO1xuICB2YXIgZXhwb3J0cyA9IElTX0dMT0JBTCA/IGNvcmUgOiBjb3JlW25hbWVdIHx8IChjb3JlW25hbWVdID0ge30pO1xuICB2YXIgZXhwUHJvdG8gPSBleHBvcnRzW1BST1RPVFlQRV0gfHwgKGV4cG9ydHNbUFJPVE9UWVBFXSA9IHt9KTtcbiAgdmFyIGtleSwgb3duLCBvdXQsIGV4cDtcbiAgaWYgKElTX0dMT0JBTCkgc291cmNlID0gbmFtZTtcbiAgZm9yIChrZXkgaW4gc291cmNlKSB7XG4gICAgLy8gY29udGFpbnMgaW4gbmF0aXZlXG4gICAgb3duID0gIUlTX0ZPUkNFRCAmJiB0YXJnZXQgJiYgdGFyZ2V0W2tleV0gIT09IHVuZGVmaW5lZDtcbiAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuICAgIG91dCA9IChvd24gPyB0YXJnZXQgOiBzb3VyY2UpW2tleV07XG4gICAgLy8gYmluZCB0aW1lcnMgdG8gZ2xvYmFsIGZvciBjYWxsIGZyb20gZXhwb3J0IGNvbnRleHRcbiAgICBleHAgPSBJU19CSU5EICYmIG93biA/IGN0eChvdXQsIGdsb2JhbCkgOiBJU19QUk9UTyAmJiB0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicgPyBjdHgoRnVuY3Rpb24uY2FsbCwgb3V0KSA6IG91dDtcbiAgICAvLyBleHRlbmQgZ2xvYmFsXG4gICAgaWYgKHRhcmdldCkgcmVkZWZpbmUodGFyZ2V0LCBrZXksIG91dCwgdHlwZSAmICRleHBvcnQuVSk7XG4gICAgLy8gZXhwb3J0XG4gICAgaWYgKGV4cG9ydHNba2V5XSAhPSBvdXQpIGhpZGUoZXhwb3J0cywga2V5LCBleHApO1xuICAgIGlmIChJU19QUk9UTyAmJiBleHBQcm90b1trZXldICE9IG91dCkgZXhwUHJvdG9ba2V5XSA9IG91dDtcbiAgfVxufTtcbmdsb2JhbC5jb3JlID0gY29yZTtcbi8vIHR5cGUgYml0bWFwXG4kZXhwb3J0LkYgPSAxOyAgIC8vIGZvcmNlZFxuJGV4cG9ydC5HID0gMjsgICAvLyBnbG9iYWxcbiRleHBvcnQuUyA9IDQ7ICAgLy8gc3RhdGljXG4kZXhwb3J0LlAgPSA4OyAgIC8vIHByb3RvXG4kZXhwb3J0LkIgPSAxNjsgIC8vIGJpbmRcbiRleHBvcnQuVyA9IDMyOyAgLy8gd3JhcFxuJGV4cG9ydC5VID0gNjQ7ICAvLyBzYWZlXG4kZXhwb3J0LlIgPSAxMjg7IC8vIHJlYWwgcHJvdG8gbWV0aG9kIGZvciBgbGlicmFyeWBcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDtcbiIsInZhciBNQVRDSCA9IHJlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciByZSA9IC8uLztcbiAgdHJ5IHtcbiAgICAnLy4vJ1tLRVldKHJlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRyeSB7XG4gICAgICByZVtNQVRDSF0gPSBmYWxzZTtcbiAgICAgIHJldHVybiAhJy8uLydbS0VZXShyZSk7XG4gICAgfSBjYXRjaCAoZikgeyAvKiBlbXB0eSAqLyB9XG4gIH0gcmV0dXJuIHRydWU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYykge1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xucmVxdWlyZSgnLi9lczYucmVnZXhwLmV4ZWMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciByZWdleHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMnKTtcblxudmFyIFNQRUNJRVMgPSB3a3MoJ3NwZWNpZXMnKTtcblxudmFyIFJFUExBQ0VfU1VQUE9SVFNfTkFNRURfR1JPVVBTID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gI3JlcGxhY2UgbmVlZHMgYnVpbHQtaW4gc3VwcG9ydCBmb3IgbmFtZWQgZ3JvdXBzLlxuICAvLyAjbWF0Y2ggd29ya3MgZmluZSBiZWNhdXNlIGl0IGp1c3QgcmV0dXJuIHRoZSBleGVjIHJlc3VsdHMsIGV2ZW4gaWYgaXQgaGFzXG4gIC8vIGEgXCJncm9wc1wiIHByb3BlcnR5LlxuICB2YXIgcmUgPSAvLi87XG4gIHJlLmV4ZWMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHJlc3VsdC5ncm91cHMgPSB7IGE6ICc3JyB9O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIHJldHVybiAnJy5yZXBsYWNlKHJlLCAnJDxhPicpICE9PSAnNyc7XG59KTtcblxudmFyIFNQTElUX1dPUktTX1dJVEhfT1ZFUldSSVRURU5fRVhFQyA9IChmdW5jdGlvbiAoKSB7XG4gIC8vIENocm9tZSA1MSBoYXMgYSBidWdneSBcInNwbGl0XCIgaW1wbGVtZW50YXRpb24gd2hlbiBSZWdFeHAjZXhlYyAhPT0gbmF0aXZlRXhlY1xuICB2YXIgcmUgPSAvKD86KS87XG4gIHZhciBvcmlnaW5hbEV4ZWMgPSByZS5leGVjO1xuICByZS5leGVjID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gb3JpZ2luYWxFeGVjLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gIHZhciByZXN1bHQgPSAnYWInLnNwbGl0KHJlKTtcbiAgcmV0dXJuIHJlc3VsdC5sZW5ndGggPT09IDIgJiYgcmVzdWx0WzBdID09PSAnYScgJiYgcmVzdWx0WzFdID09PSAnYic7XG59KSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChLRVksIGxlbmd0aCwgZXhlYykge1xuICB2YXIgU1lNQk9MID0gd2tzKEtFWSk7XG5cbiAgdmFyIERFTEVHQVRFU19UT19TWU1CT0wgPSAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIFN0cmluZyBtZXRob2RzIGNhbGwgc3ltYm9sLW5hbWVkIFJlZ0VwIG1ldGhvZHNcbiAgICB2YXIgTyA9IHt9O1xuICAgIE9bU1lNQk9MXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH07XG4gICAgcmV0dXJuICcnW0tFWV0oTykgIT0gNztcbiAgfSk7XG5cbiAgdmFyIERFTEVHQVRFU19UT19FWEVDID0gREVMRUdBVEVTX1RPX1NZTUJPTCA/ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgLy8gU3ltYm9sLW5hbWVkIFJlZ0V4cCBtZXRob2RzIGNhbGwgLmV4ZWNcbiAgICB2YXIgZXhlY0NhbGxlZCA9IGZhbHNlO1xuICAgIHZhciByZSA9IC9hLztcbiAgICByZS5leGVjID0gZnVuY3Rpb24gKCkgeyBleGVjQ2FsbGVkID0gdHJ1ZTsgcmV0dXJuIG51bGw7IH07XG4gICAgaWYgKEtFWSA9PT0gJ3NwbGl0Jykge1xuICAgICAgLy8gUmVnRXhwW0BAc3BsaXRdIGRvZXNuJ3QgY2FsbCB0aGUgcmVnZXgncyBleGVjIG1ldGhvZCwgYnV0IGZpcnN0IGNyZWF0ZXNcbiAgICAgIC8vIGEgbmV3IG9uZS4gV2UgbmVlZCB0byByZXR1cm4gdGhlIHBhdGNoZWQgcmVnZXggd2hlbiBjcmVhdGluZyB0aGUgbmV3IG9uZS5cbiAgICAgIHJlLmNvbnN0cnVjdG9yID0ge307XG4gICAgICByZS5jb25zdHJ1Y3RvcltTUEVDSUVTXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJlOyB9O1xuICAgIH1cbiAgICByZVtTWU1CT0xdKCcnKTtcbiAgICByZXR1cm4gIWV4ZWNDYWxsZWQ7XG4gIH0pIDogdW5kZWZpbmVkO1xuXG4gIGlmIChcbiAgICAhREVMRUdBVEVTX1RPX1NZTUJPTCB8fFxuICAgICFERUxFR0FURVNfVE9fRVhFQyB8fFxuICAgIChLRVkgPT09ICdyZXBsYWNlJyAmJiAhUkVQTEFDRV9TVVBQT1JUU19OQU1FRF9HUk9VUFMpIHx8XG4gICAgKEtFWSA9PT0gJ3NwbGl0JyAmJiAhU1BMSVRfV09SS1NfV0lUSF9PVkVSV1JJVFRFTl9FWEVDKVxuICApIHtcbiAgICB2YXIgbmF0aXZlUmVnRXhwTWV0aG9kID0gLy4vW1NZTUJPTF07XG4gICAgdmFyIGZucyA9IGV4ZWMoXG4gICAgICBkZWZpbmVkLFxuICAgICAgU1lNQk9MLFxuICAgICAgJydbS0VZXSxcbiAgICAgIGZ1bmN0aW9uIG1heWJlQ2FsbE5hdGl2ZShuYXRpdmVNZXRob2QsIHJlZ2V4cCwgc3RyLCBhcmcyLCBmb3JjZVN0cmluZ01ldGhvZCkge1xuICAgICAgICBpZiAocmVnZXhwLmV4ZWMgPT09IHJlZ2V4cEV4ZWMpIHtcbiAgICAgICAgICBpZiAoREVMRUdBVEVTX1RPX1NZTUJPTCAmJiAhZm9yY2VTdHJpbmdNZXRob2QpIHtcbiAgICAgICAgICAgIC8vIFRoZSBuYXRpdmUgU3RyaW5nIG1ldGhvZCBhbHJlYWR5IGRlbGVnYXRlcyB0byBAQG1ldGhvZCAodGhpc1xuICAgICAgICAgICAgLy8gcG9seWZpbGxlZCBmdW5jdGlvbiksIGxlYXNpbmcgdG8gaW5maW5pdGUgcmVjdXJzaW9uLlxuICAgICAgICAgICAgLy8gV2UgYXZvaWQgaXQgYnkgZGlyZWN0bHkgY2FsbGluZyB0aGUgbmF0aXZlIEBAbWV0aG9kIG1ldGhvZC5cbiAgICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiBuYXRpdmVSZWdFeHBNZXRob2QuY2FsbChyZWdleHAsIHN0ciwgYXJnMikgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IG5hdGl2ZU1ldGhvZC5jYWxsKHN0ciwgcmVnZXhwLCBhcmcyKSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IGRvbmU6IGZhbHNlIH07XG4gICAgICB9XG4gICAgKTtcbiAgICB2YXIgc3RyZm4gPSBmbnNbMF07XG4gICAgdmFyIHJ4Zm4gPSBmbnNbMV07XG5cbiAgICByZWRlZmluZShTdHJpbmcucHJvdG90eXBlLCBLRVksIHN0cmZuKTtcbiAgICBoaWRlKFJlZ0V4cC5wcm90b3R5cGUsIFNZTUJPTCwgbGVuZ3RoID09IDJcbiAgICAgIC8vIDIxLjIuNS44IFJlZ0V4cC5wcm90b3R5cGVbQEByZXBsYWNlXShzdHJpbmcsIHJlcGxhY2VWYWx1ZSlcbiAgICAgIC8vIDIxLjIuNS4xMSBSZWdFeHAucHJvdG90eXBlW0BAc3BsaXRdKHN0cmluZywgbGltaXQpXG4gICAgICA/IGZ1bmN0aW9uIChzdHJpbmcsIGFyZykgeyByZXR1cm4gcnhmbi5jYWxsKHN0cmluZywgdGhpcywgYXJnKTsgfVxuICAgICAgLy8gMjEuMi41LjYgUmVnRXhwLnByb3RvdHlwZVtAQG1hdGNoXShzdHJpbmcpXG4gICAgICAvLyAyMS4yLjUuOSBSZWdFeHAucHJvdG90eXBlW0BAc2VhcmNoXShzdHJpbmcpXG4gICAgICA6IGZ1bmN0aW9uIChzdHJpbmcpIHsgcmV0dXJuIHJ4Zm4uY2FsbChzdHJpbmcsIHRoaXMpOyB9XG4gICAgKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIxLjIuNS4zIGdldCBSZWdFeHAucHJvdG90eXBlLmZsYWdzXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdGhhdCA9IGFuT2JqZWN0KHRoaXMpO1xuICB2YXIgcmVzdWx0ID0gJyc7XG4gIGlmICh0aGF0Lmdsb2JhbCkgcmVzdWx0ICs9ICdnJztcbiAgaWYgKHRoYXQuaWdub3JlQ2FzZSkgcmVzdWx0ICs9ICdpJztcbiAgaWYgKHRoYXQubXVsdGlsaW5lKSByZXN1bHQgKz0gJ20nO1xuICBpZiAodGhhdC51bmljb2RlKSByZXN1bHQgKz0gJ3UnO1xuICBpZiAodGhhdC5zdGlja3kpIHJlc3VsdCArPSAneSc7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1mbGF0TWFwLyNzZWMtRmxhdHRlbkludG9BcnJheVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuL19pcy1hcnJheScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBJU19DT05DQVRfU1BSRUFEQUJMRSA9IHJlcXVpcmUoJy4vX3drcycpKCdpc0NvbmNhdFNwcmVhZGFibGUnKTtcblxuZnVuY3Rpb24gZmxhdHRlbkludG9BcnJheSh0YXJnZXQsIG9yaWdpbmFsLCBzb3VyY2UsIHNvdXJjZUxlbiwgc3RhcnQsIGRlcHRoLCBtYXBwZXIsIHRoaXNBcmcpIHtcbiAgdmFyIHRhcmdldEluZGV4ID0gc3RhcnQ7XG4gIHZhciBzb3VyY2VJbmRleCA9IDA7XG4gIHZhciBtYXBGbiA9IG1hcHBlciA/IGN0eChtYXBwZXIsIHRoaXNBcmcsIDMpIDogZmFsc2U7XG4gIHZhciBlbGVtZW50LCBzcHJlYWRhYmxlO1xuXG4gIHdoaWxlIChzb3VyY2VJbmRleCA8IHNvdXJjZUxlbikge1xuICAgIGlmIChzb3VyY2VJbmRleCBpbiBzb3VyY2UpIHtcbiAgICAgIGVsZW1lbnQgPSBtYXBGbiA/IG1hcEZuKHNvdXJjZVtzb3VyY2VJbmRleF0sIHNvdXJjZUluZGV4LCBvcmlnaW5hbCkgOiBzb3VyY2Vbc291cmNlSW5kZXhdO1xuXG4gICAgICBzcHJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBpZiAoaXNPYmplY3QoZWxlbWVudCkpIHtcbiAgICAgICAgc3ByZWFkYWJsZSA9IGVsZW1lbnRbSVNfQ09OQ0FUX1NQUkVBREFCTEVdO1xuICAgICAgICBzcHJlYWRhYmxlID0gc3ByZWFkYWJsZSAhPT0gdW5kZWZpbmVkID8gISFzcHJlYWRhYmxlIDogaXNBcnJheShlbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNwcmVhZGFibGUgJiYgZGVwdGggPiAwKSB7XG4gICAgICAgIHRhcmdldEluZGV4ID0gZmxhdHRlbkludG9BcnJheSh0YXJnZXQsIG9yaWdpbmFsLCBlbGVtZW50LCB0b0xlbmd0aChlbGVtZW50Lmxlbmd0aCksIHRhcmdldEluZGV4LCBkZXB0aCAtIDEpIC0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0YXJnZXRJbmRleCA+PSAweDFmZmZmZmZmZmZmZmZmKSB0aHJvdyBUeXBlRXJyb3IoKTtcbiAgICAgICAgdGFyZ2V0W3RhcmdldEluZGV4XSA9IGVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIHRhcmdldEluZGV4Kys7XG4gICAgfVxuICAgIHNvdXJjZUluZGV4Kys7XG4gIH1cbiAgcmV0dXJuIHRhcmdldEluZGV4O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZsYXR0ZW5JbnRvQXJyYXk7XG4iLCJ2YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2FsbCA9IHJlcXVpcmUoJy4vX2l0ZXItY2FsbCcpO1xudmFyIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBnZXRJdGVyRm4gPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xudmFyIEJSRUFLID0ge307XG52YXIgUkVUVVJOID0ge307XG52YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXJhYmxlLCBlbnRyaWVzLCBmbiwgdGhhdCwgSVRFUkFUT1IpIHtcbiAgdmFyIGl0ZXJGbiA9IElURVJBVE9SID8gZnVuY3Rpb24gKCkgeyByZXR1cm4gaXRlcmFibGU7IH0gOiBnZXRJdGVyRm4oaXRlcmFibGUpO1xuICB2YXIgZiA9IGN0eChmbiwgdGhhdCwgZW50cmllcyA/IDIgOiAxKTtcbiAgdmFyIGluZGV4ID0gMDtcbiAgdmFyIGxlbmd0aCwgc3RlcCwgaXRlcmF0b3IsIHJlc3VsdDtcbiAgaWYgKHR5cGVvZiBpdGVyRm4gIT0gJ2Z1bmN0aW9uJykgdGhyb3cgVHlwZUVycm9yKGl0ZXJhYmxlICsgJyBpcyBub3QgaXRlcmFibGUhJyk7XG4gIC8vIGZhc3QgY2FzZSBmb3IgYXJyYXlzIHdpdGggZGVmYXVsdCBpdGVyYXRvclxuICBpZiAoaXNBcnJheUl0ZXIoaXRlckZuKSkgZm9yIChsZW5ndGggPSB0b0xlbmd0aChpdGVyYWJsZS5sZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKykge1xuICAgIHJlc3VsdCA9IGVudHJpZXMgPyBmKGFuT2JqZWN0KHN0ZXAgPSBpdGVyYWJsZVtpbmRleF0pWzBdLCBzdGVwWzFdKSA6IGYoaXRlcmFibGVbaW5kZXhdKTtcbiAgICBpZiAocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTikgcmV0dXJuIHJlc3VsdDtcbiAgfSBlbHNlIGZvciAoaXRlcmF0b3IgPSBpdGVyRm4uY2FsbChpdGVyYWJsZSk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTspIHtcbiAgICByZXN1bHQgPSBjYWxsKGl0ZXJhdG9yLCBmLCBzdGVwLnZhbHVlLCBlbnRyaWVzKTtcbiAgICBpZiAocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTikgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcbmV4cG9ydHMuQlJFQUsgPSBCUkVBSztcbmV4cG9ydHMuUkVUVVJOID0gUkVUVVJOO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgnbmF0aXZlLWZ1bmN0aW9uLXRvLXN0cmluZycsIEZ1bmN0aW9uLnRvU3RyaW5nKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGZcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXG4gIDogRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbmlmICh0eXBlb2YgX19nID09ICdudW1iZXInKSBfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsInZhciBoYXNPd25Qcm9wZXJ0eSA9IHt9Lmhhc093blByb3BlcnR5O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIGtleSkge1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChpdCwga2V5KTtcbn07XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICByZXR1cm4gZFAuZihvYmplY3QsIGtleSwgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xufSA6IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG4iLCJ2YXIgZG9jdW1lbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudDtcbm1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuIiwibW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpKCdkaXYnKSwgJ2EnLCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gNzsgfSB9KS5hICE9IDc7XG59KTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fc2V0LXByb3RvJykuc2V0O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgdGFyZ2V0LCBDKSB7XG4gIHZhciBTID0gdGFyZ2V0LmNvbnN0cnVjdG9yO1xuICB2YXIgUDtcbiAgaWYgKFMgIT09IEMgJiYgdHlwZW9mIFMgPT0gJ2Z1bmN0aW9uJyAmJiAoUCA9IFMucHJvdG90eXBlKSAhPT0gQy5wcm90b3R5cGUgJiYgaXNPYmplY3QoUCkgJiYgc2V0UHJvdG90eXBlT2YpIHtcbiAgICBzZXRQcm90b3R5cGVPZih0aGF0LCBQKTtcbiAgfSByZXR1cm4gdGhhdDtcbn07XG4iLCIvLyBmYXN0IGFwcGx5LCBodHRwOi8vanNwZXJmLmxua2l0LmNvbS9mYXN0LWFwcGx5LzVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCBhcmdzLCB0aGF0KSB7XG4gIHZhciB1biA9IHRoYXQgPT09IHVuZGVmaW5lZDtcbiAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgIGNhc2UgMDogcmV0dXJuIHVuID8gZm4oKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0KTtcbiAgICBjYXNlIDE6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0pO1xuICAgIGNhc2UgMjogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgY2FzZSAzOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICBjYXNlIDQ6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICB9IHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmdzKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QoJ3onKS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgwKSA/IE9iamVjdCA6IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gY29mKGl0KSA9PSAnU3RyaW5nJyA/IGl0LnNwbGl0KCcnKSA6IE9iamVjdChpdCk7XG59O1xuIiwiLy8gY2hlY2sgb24gZGVmYXVsdCBBcnJheSBpdGVyYXRvclxudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ICE9PSB1bmRlZmluZWQgJiYgKEl0ZXJhdG9ycy5BcnJheSA9PT0gaXQgfHwgQXJyYXlQcm90b1tJVEVSQVRPUl0gPT09IGl0KTtcbn07XG4iLCIvLyA3LjIuMiBJc0FycmF5KGFyZ3VtZW50KVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIHJldHVybiBjb2YoYXJnKSA9PSAnQXJyYXknO1xufTtcbiIsIi8vIDIwLjEuMi4zIE51bWJlci5pc0ludGVnZXIobnVtYmVyKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0ludGVnZXIoaXQpIHtcbiAgcmV0dXJuICFpc09iamVjdChpdCkgJiYgaXNGaW5pdGUoaXQpICYmIGZsb29yKGl0KSA9PT0gaXQ7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IHR5cGVvZiBpdCA9PT0gJ2Z1bmN0aW9uJztcbn07XG4iLCIvLyA3LjIuOCBJc1JlZ0V4cChhcmd1bWVudClcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xudmFyIE1BVENIID0gcmVxdWlyZSgnLi9fd2tzJykoJ21hdGNoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgaXNSZWdFeHA7XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgKChpc1JlZ0V4cCA9IGl0W01BVENIXSkgIT09IHVuZGVmaW5lZCA/ICEhaXNSZWdFeHAgOiBjb2YoaXQpID09ICdSZWdFeHAnKTtcbn07XG4iLCIvLyBjYWxsIHNvbWV0aGluZyBvbiBpdGVyYXRvciBzdGVwIHdpdGggc2FmZSBjbG9zaW5nIG9uIGVycm9yXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXJhdG9yLCBmbiwgdmFsdWUsIGVudHJpZXMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZW50cmllcyA/IGZuKGFuT2JqZWN0KHZhbHVlKVswXSwgdmFsdWVbMV0pIDogZm4odmFsdWUpO1xuICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxuICB9IGNhdGNoIChlKSB7XG4gICAgdmFyIHJldCA9IGl0ZXJhdG9yWydyZXR1cm4nXTtcbiAgICBpZiAocmV0ICE9PSB1bmRlZmluZWQpIGFuT2JqZWN0KHJldC5jYWxsKGl0ZXJhdG9yKSk7XG4gICAgdGhyb3cgZTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBjcmVhdGUgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJyk7XG52YXIgZGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcblxuLy8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2hpZGUnKShJdGVyYXRvclByb3RvdHlwZSwgcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyksIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCkge1xuICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBjcmVhdGUoSXRlcmF0b3JQcm90b3R5cGUsIHsgbmV4dDogZGVzY3JpcHRvcigxLCBuZXh0KSB9KTtcbiAgc2V0VG9TdHJpbmdUYWcoQ29uc3RydWN0b3IsIE5BTUUgKyAnIEl0ZXJhdG9yJyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyICRpdGVyQ3JlYXRlID0gcmVxdWlyZSgnLi9faXRlci1jcmVhdGUnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBCVUdHWSA9ICEoW10ua2V5cyAmJiAnbmV4dCcgaW4gW10ua2V5cygpKTsgLy8gU2FmYXJpIGhhcyBidWdneSBpdGVyYXRvcnMgdy9vIGBuZXh0YFxudmFyIEZGX0lURVJBVE9SID0gJ0BAaXRlcmF0b3InO1xudmFyIEtFWVMgPSAna2V5cyc7XG52YXIgVkFMVUVTID0gJ3ZhbHVlcyc7XG5cbnZhciByZXR1cm5UaGlzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQmFzZSwgTkFNRSwgQ29uc3RydWN0b3IsIG5leHQsIERFRkFVTFQsIElTX1NFVCwgRk9SQ0VEKSB7XG4gICRpdGVyQ3JlYXRlKENvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KTtcbiAgdmFyIGdldE1ldGhvZCA9IGZ1bmN0aW9uIChraW5kKSB7XG4gICAgaWYgKCFCVUdHWSAmJiBraW5kIGluIHByb3RvKSByZXR1cm4gcHJvdG9ba2luZF07XG4gICAgc3dpdGNoIChraW5kKSB7XG4gICAgICBjYXNlIEtFWVM6IHJldHVybiBmdW5jdGlvbiBrZXlzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgICAgY2FzZSBWQUxVRVM6IHJldHVybiBmdW5jdGlvbiB2YWx1ZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gICAgfSByZXR1cm4gZnVuY3Rpb24gZW50cmllcygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgfTtcbiAgdmFyIFRBRyA9IE5BTUUgKyAnIEl0ZXJhdG9yJztcbiAgdmFyIERFRl9WQUxVRVMgPSBERUZBVUxUID09IFZBTFVFUztcbiAgdmFyIFZBTFVFU19CVUcgPSBmYWxzZTtcbiAgdmFyIHByb3RvID0gQmFzZS5wcm90b3R5cGU7XG4gIHZhciAkbmF0aXZlID0gcHJvdG9bSVRFUkFUT1JdIHx8IHByb3RvW0ZGX0lURVJBVE9SXSB8fCBERUZBVUxUICYmIHByb3RvW0RFRkFVTFRdO1xuICB2YXIgJGRlZmF1bHQgPSAkbmF0aXZlIHx8IGdldE1ldGhvZChERUZBVUxUKTtcbiAgdmFyICRlbnRyaWVzID0gREVGQVVMVCA/ICFERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoJ2VudHJpZXMnKSA6IHVuZGVmaW5lZDtcbiAgdmFyICRhbnlOYXRpdmUgPSBOQU1FID09ICdBcnJheScgPyBwcm90by5lbnRyaWVzIHx8ICRuYXRpdmUgOiAkbmF0aXZlO1xuICB2YXIgbWV0aG9kcywga2V5LCBJdGVyYXRvclByb3RvdHlwZTtcbiAgLy8gRml4IG5hdGl2ZVxuICBpZiAoJGFueU5hdGl2ZSkge1xuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG90eXBlT2YoJGFueU5hdGl2ZS5jYWxsKG5ldyBCYXNlKCkpKTtcbiAgICBpZiAoSXRlcmF0b3JQcm90b3R5cGUgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgSXRlcmF0b3JQcm90b3R5cGUubmV4dCkge1xuICAgICAgLy8gU2V0IEBAdG9TdHJpbmdUYWcgdG8gbmF0aXZlIGl0ZXJhdG9yc1xuICAgICAgc2V0VG9TdHJpbmdUYWcoSXRlcmF0b3JQcm90b3R5cGUsIFRBRywgdHJ1ZSk7XG4gICAgICAvLyBmaXggZm9yIHNvbWUgb2xkIGVuZ2luZXNcbiAgICAgIGlmICghTElCUkFSWSAmJiB0eXBlb2YgSXRlcmF0b3JQcm90b3R5cGVbSVRFUkFUT1JdICE9ICdmdW5jdGlvbicpIGhpZGUoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SLCByZXR1cm5UaGlzKTtcbiAgICB9XG4gIH1cbiAgLy8gZml4IEFycmF5I3t2YWx1ZXMsIEBAaXRlcmF0b3J9Lm5hbWUgaW4gVjggLyBGRlxuICBpZiAoREVGX1ZBTFVFUyAmJiAkbmF0aXZlICYmICRuYXRpdmUubmFtZSAhPT0gVkFMVUVTKSB7XG4gICAgVkFMVUVTX0JVRyA9IHRydWU7XG4gICAgJGRlZmF1bHQgPSBmdW5jdGlvbiB2YWx1ZXMoKSB7IHJldHVybiAkbmF0aXZlLmNhbGwodGhpcyk7IH07XG4gIH1cbiAgLy8gRGVmaW5lIGl0ZXJhdG9yXG4gIGlmICgoIUxJQlJBUlkgfHwgRk9SQ0VEKSAmJiAoQlVHR1kgfHwgVkFMVUVTX0JVRyB8fCAhcHJvdG9bSVRFUkFUT1JdKSkge1xuICAgIGhpZGUocHJvdG8sIElURVJBVE9SLCAkZGVmYXVsdCk7XG4gIH1cbiAgLy8gUGx1ZyBmb3IgbGlicmFyeVxuICBJdGVyYXRvcnNbTkFNRV0gPSAkZGVmYXVsdDtcbiAgSXRlcmF0b3JzW1RBR10gPSByZXR1cm5UaGlzO1xuICBpZiAoREVGQVVMVCkge1xuICAgIG1ldGhvZHMgPSB7XG4gICAgICB2YWx1ZXM6IERFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChWQUxVRVMpLFxuICAgICAga2V5czogSVNfU0VUID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoS0VZUyksXG4gICAgICBlbnRyaWVzOiAkZW50cmllc1xuICAgIH07XG4gICAgaWYgKEZPUkNFRCkgZm9yIChrZXkgaW4gbWV0aG9kcykge1xuICAgICAgaWYgKCEoa2V5IGluIHByb3RvKSkgcmVkZWZpbmUocHJvdG8sIGtleSwgbWV0aG9kc1trZXldKTtcbiAgICB9IGVsc2UgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoQlVHR1kgfHwgVkFMVUVTX0JVRyksIE5BTUUsIG1ldGhvZHMpO1xuICB9XG4gIHJldHVybiBtZXRob2RzO1xufTtcbiIsInZhciBJVEVSQVRPUiA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpO1xudmFyIFNBRkVfQ0xPU0lORyA9IGZhbHNlO1xuXG50cnkge1xuICB2YXIgcml0ZXIgPSBbN11bSVRFUkFUT1JdKCk7XG4gIHJpdGVyWydyZXR1cm4nXSA9IGZ1bmN0aW9uICgpIHsgU0FGRV9DTE9TSU5HID0gdHJ1ZTsgfTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcbiAgQXJyYXkuZnJvbShyaXRlciwgZnVuY3Rpb24gKCkgeyB0aHJvdyAyOyB9KTtcbn0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChleGVjLCBza2lwQ2xvc2luZykge1xuICBpZiAoIXNraXBDbG9zaW5nICYmICFTQUZFX0NMT1NJTkcpIHJldHVybiBmYWxzZTtcbiAgdmFyIHNhZmUgPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gWzddO1xuICAgIHZhciBpdGVyID0gYXJyW0lURVJBVE9SXSgpO1xuICAgIGl0ZXIubmV4dCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHsgZG9uZTogc2FmZSA9IHRydWUgfTsgfTtcbiAgICBhcnJbSVRFUkFUT1JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gaXRlcjsgfTtcbiAgICBleGVjKGFycik7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gc2FmZTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChkb25lLCB2YWx1ZSkge1xuICByZXR1cm4geyB2YWx1ZTogdmFsdWUsIGRvbmU6ICEhZG9uZSB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge307XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZhbHNlO1xuIiwiLy8gMjAuMi4yLjE0IE1hdGguZXhwbTEoeClcbnZhciAkZXhwbTEgPSBNYXRoLmV4cG0xO1xubW9kdWxlLmV4cG9ydHMgPSAoISRleHBtMVxuICAvLyBPbGQgRkYgYnVnXG4gIHx8ICRleHBtMSgxMCkgPiAyMjAyNS40NjU3OTQ4MDY3MTkgfHwgJGV4cG0xKDEwKSA8IDIyMDI1LjQ2NTc5NDgwNjcxNjUxNjhcbiAgLy8gVG9yIEJyb3dzZXIgYnVnXG4gIHx8ICRleHBtMSgtMmUtMTcpICE9IC0yZS0xN1xuKSA/IGZ1bmN0aW9uIGV4cG0xKHgpIHtcbiAgcmV0dXJuICh4ID0gK3gpID09IDAgPyB4IDogeCA+IC0xZS02ICYmIHggPCAxZS02ID8geCArIHggKiB4IC8gMiA6IE1hdGguZXhwKHgpIC0gMTtcbn0gOiAkZXhwbTE7XG4iLCIvLyAyMC4yLjIuMTYgTWF0aC5mcm91bmQoeClcbnZhciBzaWduID0gcmVxdWlyZSgnLi9fbWF0aC1zaWduJyk7XG52YXIgcG93ID0gTWF0aC5wb3c7XG52YXIgRVBTSUxPTiA9IHBvdygyLCAtNTIpO1xudmFyIEVQU0lMT04zMiA9IHBvdygyLCAtMjMpO1xudmFyIE1BWDMyID0gcG93KDIsIDEyNykgKiAoMiAtIEVQU0lMT04zMik7XG52YXIgTUlOMzIgPSBwb3coMiwgLTEyNik7XG5cbnZhciByb3VuZFRpZXNUb0V2ZW4gPSBmdW5jdGlvbiAobikge1xuICByZXR1cm4gbiArIDEgLyBFUFNJTE9OIC0gMSAvIEVQU0lMT047XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguZnJvdW5kIHx8IGZ1bmN0aW9uIGZyb3VuZCh4KSB7XG4gIHZhciAkYWJzID0gTWF0aC5hYnMoeCk7XG4gIHZhciAkc2lnbiA9IHNpZ24oeCk7XG4gIHZhciBhLCByZXN1bHQ7XG4gIGlmICgkYWJzIDwgTUlOMzIpIHJldHVybiAkc2lnbiAqIHJvdW5kVGllc1RvRXZlbigkYWJzIC8gTUlOMzIgLyBFUFNJTE9OMzIpICogTUlOMzIgKiBFUFNJTE9OMzI7XG4gIGEgPSAoMSArIEVQU0lMT04zMiAvIEVQU0lMT04pICogJGFicztcbiAgcmVzdWx0ID0gYSAtIChhIC0gJGFicyk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgaWYgKHJlc3VsdCA+IE1BWDMyIHx8IHJlc3VsdCAhPSByZXN1bHQpIHJldHVybiAkc2lnbiAqIEluZmluaXR5O1xuICByZXR1cm4gJHNpZ24gKiByZXN1bHQ7XG59O1xuIiwiLy8gMjAuMi4yLjIwIE1hdGgubG9nMXAoeClcbm1vZHVsZS5leHBvcnRzID0gTWF0aC5sb2cxcCB8fCBmdW5jdGlvbiBsb2cxcCh4KSB7XG4gIHJldHVybiAoeCA9ICt4KSA+IC0xZS04ICYmIHggPCAxZS04ID8geCAtIHggKiB4IC8gMiA6IE1hdGgubG9nKDEgKyB4KTtcbn07XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguc2NhbGUgfHwgZnVuY3Rpb24gc2NhbGUoeCwgaW5Mb3csIGluSGlnaCwgb3V0TG93LCBvdXRIaWdoKSB7XG4gIGlmIChcbiAgICBhcmd1bWVudHMubGVuZ3RoID09PSAwXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCB4ICE9IHhcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICAgIHx8IGluTG93ICE9IGluTG93XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCBpbkhpZ2ggIT0gaW5IaWdoXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCBvdXRMb3cgIT0gb3V0TG93XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCBvdXRIaWdoICE9IG91dEhpZ2hcbiAgKSByZXR1cm4gTmFOO1xuICBpZiAoeCA9PT0gSW5maW5pdHkgfHwgeCA9PT0gLUluZmluaXR5KSByZXR1cm4geDtcbiAgcmV0dXJuICh4IC0gaW5Mb3cpICogKG91dEhpZ2ggLSBvdXRMb3cpIC8gKGluSGlnaCAtIGluTG93KSArIG91dExvdztcbn07XG4iLCIvLyAyMC4yLjIuMjggTWF0aC5zaWduKHgpXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguc2lnbiB8fCBmdW5jdGlvbiBzaWduKHgpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICByZXR1cm4gKHggPSAreCkgPT0gMCB8fCB4ICE9IHggPyB4IDogeCA8IDAgPyAtMSA6IDE7XG59O1xuIiwidmFyIE1FVEEgPSByZXF1aXJlKCcuL191aWQnKSgnbWV0YScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgc2V0RGVzYyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgaWQgPSAwO1xudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGUgfHwgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG52YXIgRlJFRVpFID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gaXNFeHRlbnNpYmxlKE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh7fSkpO1xufSk7XG52YXIgc2V0TWV0YSA9IGZ1bmN0aW9uIChpdCkge1xuICBzZXREZXNjKGl0LCBNRVRBLCB7IHZhbHVlOiB7XG4gICAgaTogJ08nICsgKytpZCwgLy8gb2JqZWN0IElEXG4gICAgdzoge30gICAgICAgICAgLy8gd2VhayBjb2xsZWN0aW9ucyBJRHNcbiAgfSB9KTtcbn07XG52YXIgZmFzdEtleSA9IGZ1bmN0aW9uIChpdCwgY3JlYXRlKSB7XG4gIC8vIHJldHVybiBwcmltaXRpdmUgd2l0aCBwcmVmaXhcbiAgaWYgKCFpc09iamVjdChpdCkpIHJldHVybiB0eXBlb2YgaXQgPT0gJ3N5bWJvbCcgPyBpdCA6ICh0eXBlb2YgaXQgPT0gJ3N0cmluZycgPyAnUycgOiAnUCcpICsgaXQ7XG4gIGlmICghaGFzKGl0LCBNRVRBKSkge1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYgKCFpc0V4dGVuc2libGUoaXQpKSByZXR1cm4gJ0YnO1xuICAgIC8vIG5vdCBuZWNlc3NhcnkgdG8gYWRkIG1ldGFkYXRhXG4gICAgaWYgKCFjcmVhdGUpIHJldHVybiAnRSc7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIG9iamVjdCBJRFxuICB9IHJldHVybiBpdFtNRVRBXS5pO1xufTtcbnZhciBnZXRXZWFrID0gZnVuY3Rpb24gKGl0LCBjcmVhdGUpIHtcbiAgaWYgKCFoYXMoaXQsIE1FVEEpKSB7XG4gICAgLy8gY2FuJ3Qgc2V0IG1ldGFkYXRhIHRvIHVuY2F1Z2h0IGZyb3plbiBvYmplY3RcbiAgICBpZiAoIWlzRXh0ZW5zaWJsZShpdCkpIHJldHVybiB0cnVlO1xuICAgIC8vIG5vdCBuZWNlc3NhcnkgdG8gYWRkIG1ldGFkYXRhXG4gICAgaWYgKCFjcmVhdGUpIHJldHVybiBmYWxzZTtcbiAgICAvLyBhZGQgbWlzc2luZyBtZXRhZGF0YVxuICAgIHNldE1ldGEoaXQpO1xuICAvLyByZXR1cm4gaGFzaCB3ZWFrIGNvbGxlY3Rpb25zIElEc1xuICB9IHJldHVybiBpdFtNRVRBXS53O1xufTtcbi8vIGFkZCBtZXRhZGF0YSBvbiBmcmVlemUtZmFtaWx5IG1ldGhvZHMgY2FsbGluZ1xudmFyIG9uRnJlZXplID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmIChGUkVFWkUgJiYgbWV0YS5ORUVEICYmIGlzRXh0ZW5zaWJsZShpdCkgJiYgIWhhcyhpdCwgTUVUQSkpIHNldE1ldGEoaXQpO1xuICByZXR1cm4gaXQ7XG59O1xudmFyIG1ldGEgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgS0VZOiBNRVRBLFxuICBORUVEOiBmYWxzZSxcbiAgZmFzdEtleTogZmFzdEtleSxcbiAgZ2V0V2VhazogZ2V0V2VhayxcbiAgb25GcmVlemU6IG9uRnJlZXplXG59O1xuIiwidmFyIE1hcCA9IHJlcXVpcmUoJy4vZXM2Lm1hcCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBzaGFyZWQgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgnbWV0YWRhdGEnKTtcbnZhciBzdG9yZSA9IHNoYXJlZC5zdG9yZSB8fCAoc2hhcmVkLnN0b3JlID0gbmV3IChyZXF1aXJlKCcuL2VzNi53ZWFrLW1hcCcpKSgpKTtcblxudmFyIGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAgPSBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGNyZWF0ZSkge1xuICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBzdG9yZS5nZXQodGFyZ2V0KTtcbiAgaWYgKCF0YXJnZXRNZXRhZGF0YSkge1xuICAgIGlmICghY3JlYXRlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHN0b3JlLnNldCh0YXJnZXQsIHRhcmdldE1ldGFkYXRhID0gbmV3IE1hcCgpKTtcbiAgfVxuICB2YXIga2V5TWV0YWRhdGEgPSB0YXJnZXRNZXRhZGF0YS5nZXQodGFyZ2V0S2V5KTtcbiAgaWYgKCFrZXlNZXRhZGF0YSkge1xuICAgIGlmICghY3JlYXRlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHRhcmdldE1ldGFkYXRhLnNldCh0YXJnZXRLZXksIGtleU1ldGFkYXRhID0gbmV3IE1hcCgpKTtcbiAgfSByZXR1cm4ga2V5TWV0YWRhdGE7XG59O1xudmFyIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBmdW5jdGlvbiAoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgdmFyIG1ldGFkYXRhTWFwID0gZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCBmYWxzZSk7XG4gIHJldHVybiBtZXRhZGF0YU1hcCA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBtZXRhZGF0YU1hcC5oYXMoTWV0YWRhdGFLZXkpO1xufTtcbnZhciBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gZnVuY3Rpb24gKE1ldGFkYXRhS2V5LCBPLCBQKSB7XG4gIHZhciBtZXRhZGF0YU1hcCA9IGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgZmFsc2UpO1xuICByZXR1cm4gbWV0YWRhdGFNYXAgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IG1ldGFkYXRhTWFwLmdldChNZXRhZGF0YUtleSk7XG59O1xudmFyIG9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEgPSBmdW5jdGlvbiAoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUsIE8sIFApIHtcbiAgZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCB0cnVlKS5zZXQoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUpO1xufTtcbnZhciBvcmRpbmFyeU93bk1ldGFkYXRhS2V5cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSkge1xuICB2YXIgbWV0YWRhdGFNYXAgPSBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwKHRhcmdldCwgdGFyZ2V0S2V5LCBmYWxzZSk7XG4gIHZhciBrZXlzID0gW107XG4gIGlmIChtZXRhZGF0YU1hcCkgbWV0YWRhdGFNYXAuZm9yRWFjaChmdW5jdGlvbiAoXywga2V5KSB7IGtleXMucHVzaChrZXkpOyB9KTtcbiAgcmV0dXJuIGtleXM7XG59O1xudmFyIHRvTWV0YUtleSA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgaXQgPT0gJ3N5bWJvbCcgPyBpdCA6IFN0cmluZyhpdCk7XG59O1xudmFyIGV4cCA9IGZ1bmN0aW9uIChPKSB7XG4gICRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIE8pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHN0b3JlOiBzdG9yZSxcbiAgbWFwOiBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwLFxuICBoYXM6IG9yZGluYXJ5SGFzT3duTWV0YWRhdGEsXG4gIGdldDogb3JkaW5hcnlHZXRPd25NZXRhZGF0YSxcbiAgc2V0OiBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhLFxuICBrZXlzOiBvcmRpbmFyeU93bk1ldGFkYXRhS2V5cyxcbiAga2V5OiB0b01ldGFLZXksXG4gIGV4cDogZXhwXG59O1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIG1hY3JvdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgT2JzZXJ2ZXIgPSBnbG9iYWwuTXV0YXRpb25PYnNlcnZlciB8fCBnbG9iYWwuV2ViS2l0TXV0YXRpb25PYnNlcnZlcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgUHJvbWlzZSA9IGdsb2JhbC5Qcm9taXNlO1xudmFyIGlzTm9kZSA9IHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBoZWFkLCBsYXN0LCBub3RpZnk7XG5cbiAgdmFyIGZsdXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwYXJlbnQsIGZuO1xuICAgIGlmIChpc05vZGUgJiYgKHBhcmVudCA9IHByb2Nlc3MuZG9tYWluKSkgcGFyZW50LmV4aXQoKTtcbiAgICB3aGlsZSAoaGVhZCkge1xuICAgICAgZm4gPSBoZWFkLmZuO1xuICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZuKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChoZWFkKSBub3RpZnkoKTtcbiAgICAgICAgZWxzZSBsYXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH0gbGFzdCA9IHVuZGVmaW5lZDtcbiAgICBpZiAocGFyZW50KSBwYXJlbnQuZW50ZXIoKTtcbiAgfTtcblxuICAvLyBOb2RlLmpzXG4gIGlmIChpc05vZGUpIHtcbiAgICBub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGZsdXNoKTtcbiAgICB9O1xuICAvLyBicm93c2VycyB3aXRoIE11dGF0aW9uT2JzZXJ2ZXIsIGV4Y2VwdCBpT1MgU2FmYXJpIC0gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzMzOVxuICB9IGVsc2UgaWYgKE9ic2VydmVyICYmICEoZ2xvYmFsLm5hdmlnYXRvciAmJiBnbG9iYWwubmF2aWdhdG9yLnN0YW5kYWxvbmUpKSB7XG4gICAgdmFyIHRvZ2dsZSA9IHRydWU7XG4gICAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gICAgbmV3IE9ic2VydmVyKGZsdXNoKS5vYnNlcnZlKG5vZGUsIHsgY2hhcmFjdGVyRGF0YTogdHJ1ZSB9KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICBub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBub2RlLmRhdGEgPSB0b2dnbGUgPSAhdG9nZ2xlO1xuICAgIH07XG4gIC8vIGVudmlyb25tZW50cyB3aXRoIG1heWJlIG5vbi1jb21wbGV0ZWx5IGNvcnJlY3QsIGJ1dCBleGlzdGVudCBQcm9taXNlXG4gIH0gZWxzZSBpZiAoUHJvbWlzZSAmJiBQcm9taXNlLnJlc29sdmUpIHtcbiAgICAvLyBQcm9taXNlLnJlc29sdmUgd2l0aG91dCBhbiBhcmd1bWVudCB0aHJvd3MgYW4gZXJyb3IgaW4gTEcgV2ViT1MgMlxuICAgIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcHJvbWlzZS50aGVuKGZsdXNoKTtcbiAgICB9O1xuICAvLyBmb3Igb3RoZXIgZW52aXJvbm1lbnRzIC0gbWFjcm90YXNrIGJhc2VkIG9uOlxuICAvLyAtIHNldEltbWVkaWF0ZVxuICAvLyAtIE1lc3NhZ2VDaGFubmVsXG4gIC8vIC0gd2luZG93LnBvc3RNZXNzYWdcbiAgLy8gLSBvbnJlYWR5c3RhdGVjaGFuZ2VcbiAgLy8gLSBzZXRUaW1lb3V0XG4gIH0gZWxzZSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgLy8gc3RyYW5nZSBJRSArIHdlYnBhY2sgZGV2IHNlcnZlciBidWcgLSB1c2UgLmNhbGwoZ2xvYmFsKVxuICAgICAgbWFjcm90YXNrLmNhbGwoZ2xvYmFsLCBmbHVzaCk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoZm4pIHtcbiAgICB2YXIgdGFzayA9IHsgZm46IGZuLCBuZXh0OiB1bmRlZmluZWQgfTtcbiAgICBpZiAobGFzdCkgbGFzdC5uZXh0ID0gdGFzaztcbiAgICBpZiAoIWhlYWQpIHtcbiAgICAgIGhlYWQgPSB0YXNrO1xuICAgICAgbm90aWZ5KCk7XG4gICAgfSBsYXN0ID0gdGFzaztcbiAgfTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyNS40LjEuNSBOZXdQcm9taXNlQ2FwYWJpbGl0eShDKVxudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcblxuZnVuY3Rpb24gUHJvbWlzZUNhcGFiaWxpdHkoQykge1xuICB2YXIgcmVzb2x2ZSwgcmVqZWN0O1xuICB0aGlzLnByb21pc2UgPSBuZXcgQyhmdW5jdGlvbiAoJCRyZXNvbHZlLCAkJHJlamVjdCkge1xuICAgIGlmIChyZXNvbHZlICE9PSB1bmRlZmluZWQgfHwgcmVqZWN0ICE9PSB1bmRlZmluZWQpIHRocm93IFR5cGVFcnJvcignQmFkIFByb21pc2UgY29uc3RydWN0b3InKTtcbiAgICByZXNvbHZlID0gJCRyZXNvbHZlO1xuICAgIHJlamVjdCA9ICQkcmVqZWN0O1xuICB9KTtcbiAgdGhpcy5yZXNvbHZlID0gYUZ1bmN0aW9uKHJlc29sdmUpO1xuICB0aGlzLnJlamVjdCA9IGFGdW5jdGlvbihyZWplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gKEMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlQ2FwYWJpbGl0eShDKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgZ09QUyA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJyk7XG52YXIgcElFID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciAkYXNzaWduID0gT2JqZWN0LmFzc2lnbjtcblxuLy8gc2hvdWxkIHdvcmsgd2l0aCBzeW1ib2xzIGFuZCBzaG91bGQgaGF2ZSBkZXRlcm1pbmlzdGljIHByb3BlcnR5IG9yZGVyIChWOCBidWcpXG5tb2R1bGUuZXhwb3J0cyA9ICEkYXNzaWduIHx8IHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICB2YXIgQSA9IHt9O1xuICB2YXIgQiA9IHt9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgdmFyIFMgPSBTeW1ib2woKTtcbiAgdmFyIEsgPSAnYWJjZGVmZ2hpamtsbW5vcHFyc3QnO1xuICBBW1NdID0gNztcbiAgSy5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAoaykgeyBCW2tdID0gazsgfSk7XG4gIHJldHVybiAkYXNzaWduKHt9LCBBKVtTXSAhPSA3IHx8IE9iamVjdC5rZXlzKCRhc3NpZ24oe30sIEIpKS5qb2luKCcnKSAhPSBLO1xufSkgPyBmdW5jdGlvbiBhc3NpZ24odGFyZ2V0LCBzb3VyY2UpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICB2YXIgVCA9IHRvT2JqZWN0KHRhcmdldCk7XG4gIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgdmFyIGluZGV4ID0gMTtcbiAgdmFyIGdldFN5bWJvbHMgPSBnT1BTLmY7XG4gIHZhciBpc0VudW0gPSBwSUUuZjtcbiAgd2hpbGUgKGFMZW4gPiBpbmRleCkge1xuICAgIHZhciBTID0gSU9iamVjdChhcmd1bWVudHNbaW5kZXgrK10pO1xuICAgIHZhciBrZXlzID0gZ2V0U3ltYm9scyA/IGdldEtleXMoUykuY29uY2F0KGdldFN5bWJvbHMoUykpIDogZ2V0S2V5cyhTKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGogPSAwO1xuICAgIHZhciBrZXk7XG4gICAgd2hpbGUgKGxlbmd0aCA+IGopIGlmIChpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKSBUW2tleV0gPSBTW2tleV07XG4gIH0gcmV0dXJuIFQ7XG59IDogJGFzc2lnbjtcbiIsIi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgZFBzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwcycpO1xudmFyIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xudmFyIEVtcHR5ID0gZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9O1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG4vLyBDcmVhdGUgb2JqZWN0IHdpdGggZmFrZSBgbnVsbGAgcHJvdG90eXBlOiB1c2UgaWZyYW1lIE9iamVjdCB3aXRoIGNsZWFyZWQgcHJvdG90eXBlXG52YXIgY3JlYXRlRGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gVGhyYXNoLCB3YXN0ZSBhbmQgc29kb215OiBJRSBHQyBidWdcbiAgdmFyIGlmcmFtZSA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnaWZyYW1lJyk7XG4gIHZhciBpID0gZW51bUJ1Z0tleXMubGVuZ3RoO1xuICB2YXIgbHQgPSAnPCc7XG4gIHZhciBndCA9ICc+JztcbiAgdmFyIGlmcmFtZURvY3VtZW50O1xuICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgcmVxdWlyZSgnLi9faHRtbCcpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gIGlmcmFtZS5zcmMgPSAnamF2YXNjcmlwdDonOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNjcmlwdC11cmxcbiAgLy8gY3JlYXRlRGljdCA9IGlmcmFtZS5jb250ZW50V2luZG93Lk9iamVjdDtcbiAgLy8gaHRtbC5yZW1vdmVDaGlsZChpZnJhbWUpO1xuICBpZnJhbWVEb2N1bWVudCA9IGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50O1xuICBpZnJhbWVEb2N1bWVudC5vcGVuKCk7XG4gIGlmcmFtZURvY3VtZW50LndyaXRlKGx0ICsgJ3NjcmlwdCcgKyBndCArICdkb2N1bWVudC5GPU9iamVjdCcgKyBsdCArICcvc2NyaXB0JyArIGd0KTtcbiAgaWZyYW1lRG9jdW1lbnQuY2xvc2UoKTtcbiAgY3JlYXRlRGljdCA9IGlmcmFtZURvY3VtZW50LkY7XG4gIHdoaWxlIChpLS0pIGRlbGV0ZSBjcmVhdGVEaWN0W1BST1RPVFlQRV1bZW51bUJ1Z0tleXNbaV1dO1xuICByZXR1cm4gY3JlYXRlRGljdCgpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuY3JlYXRlIHx8IGZ1bmN0aW9uIGNyZWF0ZShPLCBQcm9wZXJ0aWVzKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChPICE9PSBudWxsKSB7XG4gICAgRW1wdHlbUFJPVE9UWVBFXSA9IGFuT2JqZWN0KE8pO1xuICAgIHJlc3VsdCA9IG5ldyBFbXB0eSgpO1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBudWxsO1xuICAgIC8vIGFkZCBcIl9fcHJvdG9fX1wiIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YgcG9seWZpbGxcbiAgICByZXN1bHRbSUVfUFJPVE9dID0gTztcbiAgfSBlbHNlIHJlc3VsdCA9IGNyZWF0ZURpY3QoKTtcbiAgcmV0dXJuIFByb3BlcnRpZXMgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IGRQcyhyZXN1bHQsIFByb3BlcnRpZXMpO1xufTtcbiIsInZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGRQID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xuXG5leHBvcnRzLmYgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnR5IDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcykge1xuICBhbk9iamVjdChPKTtcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xuICBhbk9iamVjdChBdHRyaWJ1dGVzKTtcbiAgaWYgKElFOF9ET01fREVGSU5FKSB0cnkge1xuICAgIHJldHVybiBkUChPLCBQLCBBdHRyaWJ1dGVzKTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG4gIGlmICgnZ2V0JyBpbiBBdHRyaWJ1dGVzIHx8ICdzZXQnIGluIEF0dHJpYnV0ZXMpIHRocm93IFR5cGVFcnJvcignQWNjZXNzb3JzIG5vdCBzdXBwb3J0ZWQhJyk7XG4gIGlmICgndmFsdWUnIGluIEF0dHJpYnV0ZXMpIE9bUF0gPSBBdHRyaWJ1dGVzLnZhbHVlO1xuICByZXR1cm4gTztcbn07XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcykge1xuICBhbk9iamVjdChPKTtcbiAgdmFyIGtleXMgPSBnZXRLZXlzKFByb3BlcnRpZXMpO1xuICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gIHZhciBpID0gMDtcbiAgdmFyIFA7XG4gIHdoaWxlIChsZW5ndGggPiBpKSBkUC5mKE8sIFAgPSBrZXlzW2krK10sIFByb3BlcnRpZXNbUF0pO1xuICByZXR1cm4gTztcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyBGb3JjZWQgcmVwbGFjZW1lbnQgcHJvdG90eXBlIGFjY2Vzc29ycyBtZXRob2RzXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKSB8fCAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHZhciBLID0gTWF0aC5yYW5kb20oKTtcbiAgLy8gSW4gRkYgdGhyb3dzIG9ubHkgZGVmaW5lIG1ldGhvZHNcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmLCBuby11c2VsZXNzLWNhbGxcbiAgX19kZWZpbmVTZXR0ZXJfXy5jYWxsKG51bGwsIEssIGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSk7XG4gIGRlbGV0ZSByZXF1aXJlKCcuL19nbG9iYWwnKVtLXTtcbn0pO1xuIiwidmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKTtcbnZhciBnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGdPUEQgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCkge1xuICBPID0gdG9JT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZ09QRChPLCBQKTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG4gIGlmIChoYXMoTywgUCkpIHJldHVybiBjcmVhdGVEZXNjKCFwSUUuZi5jYWxsKE8sIFApLCBPW1BdKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxudmFyIHdpbmRvd05hbWVzID0gdHlwZW9mIHdpbmRvdyA9PSAnb2JqZWN0JyAmJiB3aW5kb3cgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXNcbiAgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh3aW5kb3cpIDogW107XG5cbnZhciBnZXRXaW5kb3dOYW1lcyA9IGZ1bmN0aW9uIChpdCkge1xuICB0cnkge1xuICAgIHJldHVybiBnT1BOKGl0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCkge1xuICByZXR1cm4gd2luZG93TmFtZXMgJiYgdG9TdHJpbmcuY2FsbChpdCkgPT0gJ1tvYmplY3QgV2luZG93XScgPyBnZXRXaW5kb3dOYW1lcyhpdCkgOiBnT1BOKHRvSU9iamVjdChpdCkpO1xufTtcbiIsIi8vIDE5LjEuMi43IC8gMTUuMi4zLjQgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbnZhciAka2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJyk7XG52YXIgaGlkZGVuS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKS5jb25jYXQoJ2xlbmd0aCcsICdwcm90b3R5cGUnKTtcblxuZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgfHwgZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhPKSB7XG4gIHJldHVybiAka2V5cyhPLCBoaWRkZW5LZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xuIiwiLy8gMTkuMS4yLjkgLyAxNS4yLjMuMiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTylcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xudmFyIE9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24gKE8pIHtcbiAgTyA9IHRvT2JqZWN0KE8pO1xuICBpZiAoaGFzKE8sIElFX1BST1RPKSkgcmV0dXJuIE9bSUVfUFJPVE9dO1xuICBpZiAodHlwZW9mIE8uY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBPIGluc3RhbmNlb2YgTy5jb25zdHJ1Y3Rvcikge1xuICAgIHJldHVybiBPLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgfSByZXR1cm4gTyBpbnN0YW5jZW9mIE9iamVjdCA/IE9iamVjdFByb3RvIDogbnVsbDtcbn07XG4iLCJ2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGFycmF5SW5kZXhPZiA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykoZmFsc2UpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWVzKSB7XG4gIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gIHZhciBpID0gMDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBPKSBpZiAoa2V5ICE9IElFX1BST1RPKSBoYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSBpZiAoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKSB7XG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8vIDE5LjEuMi4xNCAvIDE1LjIuMy4xNCBPYmplY3Qua2V5cyhPKVxudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMtaW50ZXJuYWwnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzKE8pIHtcbiAgcmV0dXJuICRrZXlzKE8sIGVudW1CdWdLZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiIsIi8vIG1vc3QgT2JqZWN0IG1ldGhvZHMgYnkgRVM2IHNob3VsZCBhY2NlcHQgcHJpbWl0aXZlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSwgZXhlYykge1xuICB2YXIgZm4gPSAoY29yZS5PYmplY3QgfHwge30pW0tFWV0gfHwgT2JqZWN0W0tFWV07XG4gIHZhciBleHAgPSB7fTtcbiAgZXhwW0tFWV0gPSBleGVjKGZuKTtcbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7IGZuKDEpOyB9KSwgJ09iamVjdCcsIGV4cCk7XG59O1xuIiwidmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBpc0VudW0gPSByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGlzRW50cmllcykge1xuICByZXR1cm4gZnVuY3Rpb24gKGl0KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoaXQpO1xuICAgIHZhciBrZXlzID0gZ2V0S2V5cyhPKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBpKSBpZiAoaXNFbnVtLmNhbGwoTywga2V5ID0ga2V5c1tpKytdKSkge1xuICAgICAgcmVzdWx0LnB1c2goaXNFbnRyaWVzID8gW2tleSwgT1trZXldXSA6IE9ba2V5XSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9O1xufTtcbiIsIi8vIGFsbCBvYmplY3Qga2V5cywgaW5jbHVkZXMgbm9uLWVudW1lcmFibGUgYW5kIHN5bWJvbHNcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIFJlZmxlY3QgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0O1xubW9kdWxlLmV4cG9ydHMgPSBSZWZsZWN0ICYmIFJlZmxlY3Qub3duS2V5cyB8fCBmdW5jdGlvbiBvd25LZXlzKGl0KSB7XG4gIHZhciBrZXlzID0gZ09QTi5mKGFuT2JqZWN0KGl0KSk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICByZXR1cm4gZ2V0U3ltYm9scyA/IGtleXMuY29uY2F0KGdldFN5bWJvbHMoaXQpKSA6IGtleXM7XG59O1xuIiwidmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykucGFyc2VGbG9hdDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcblxubW9kdWxlLmV4cG9ydHMgPSAxIC8gJHBhcnNlRmxvYXQocmVxdWlyZSgnLi9fc3RyaW5nLXdzJykgKyAnLTAnKSAhPT0gLUluZmluaXR5ID8gZnVuY3Rpb24gcGFyc2VGbG9hdChzdHIpIHtcbiAgdmFyIHN0cmluZyA9ICR0cmltKFN0cmluZyhzdHIpLCAzKTtcbiAgdmFyIHJlc3VsdCA9ICRwYXJzZUZsb2F0KHN0cmluZyk7XG4gIHJldHVybiByZXN1bHQgPT09IDAgJiYgc3RyaW5nLmNoYXJBdCgwKSA9PSAnLScgPyAtMCA6IHJlc3VsdDtcbn0gOiAkcGFyc2VGbG9hdDtcbiIsInZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wYXJzZUludDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciB3cyA9IHJlcXVpcmUoJy4vX3N0cmluZy13cycpO1xudmFyIGhleCA9IC9eWy0rXT8wW3hYXS87XG5cbm1vZHVsZS5leHBvcnRzID0gJHBhcnNlSW50KHdzICsgJzA4JykgIT09IDggfHwgJHBhcnNlSW50KHdzICsgJzB4MTYnKSAhPT0gMjIgPyBmdW5jdGlvbiBwYXJzZUludChzdHIsIHJhZGl4KSB7XG4gIHZhciBzdHJpbmcgPSAkdHJpbShTdHJpbmcoc3RyKSwgMyk7XG4gIHJldHVybiAkcGFyc2VJbnQoc3RyaW5nLCAocmFkaXggPj4+IDApIHx8IChoZXgudGVzdChzdHJpbmcpID8gMTYgOiAxMCkpO1xufSA6ICRwYXJzZUludDtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4geyBlOiBmYWxzZSwgdjogZXhlYygpIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4geyBlOiB0cnVlLCB2OiBlIH07XG4gIH1cbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5ID0gcmVxdWlyZSgnLi9fbmV3LXByb21pc2UtY2FwYWJpbGl0eScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDLCB4KSB7XG4gIGFuT2JqZWN0KEMpO1xuICBpZiAoaXNPYmplY3QoeCkgJiYgeC5jb25zdHJ1Y3RvciA9PT0gQykgcmV0dXJuIHg7XG4gIHZhciBwcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5LmYoQyk7XG4gIHZhciByZXNvbHZlID0gcHJvbWlzZUNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgcmVzb2x2ZSh4KTtcbiAgcmV0dXJuIHByb21pc2VDYXBhYmlsaXR5LnByb21pc2U7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYml0bWFwLCB2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIGVudW1lcmFibGU6ICEoYml0bWFwICYgMSksXG4gICAgY29uZmlndXJhYmxlOiAhKGJpdG1hcCAmIDIpLFxuICAgIHdyaXRhYmxlOiAhKGJpdG1hcCAmIDQpLFxuICAgIHZhbHVlOiB2YWx1ZVxuICB9O1xufTtcbiIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHNyYywgc2FmZSkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSByZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0sIHNhZmUpO1xuICByZXR1cm4gdGFyZ2V0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIFNSQyA9IHJlcXVpcmUoJy4vX3VpZCcpKCdzcmMnKTtcbnZhciAkdG9TdHJpbmcgPSByZXF1aXJlKCcuL19mdW5jdGlvbi10by1zdHJpbmcnKTtcbnZhciBUT19TVFJJTkcgPSAndG9TdHJpbmcnO1xudmFyIFRQTCA9ICgnJyArICR0b1N0cmluZykuc3BsaXQoVE9fU1RSSU5HKTtcblxucmVxdWlyZSgnLi9fY29yZScpLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuICR0b1N0cmluZy5jYWxsKGl0KTtcbn07XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChPLCBrZXksIHZhbCwgc2FmZSkge1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcbiAgaWYgKGlzRnVuY3Rpb24pIGhhcyh2YWwsICduYW1lJykgfHwgaGlkZSh2YWwsICduYW1lJywga2V5KTtcbiAgaWYgKE9ba2V5XSA9PT0gdmFsKSByZXR1cm47XG4gIGlmIChpc0Z1bmN0aW9uKSBoYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcbiAgaWYgKE8gPT09IGdsb2JhbCkge1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIGlmICghc2FmZSkge1xuICAgIGRlbGV0ZSBPW2tleV07XG4gICAgaGlkZShPLCBrZXksIHZhbCk7XG4gIH0gZWxzZSBpZiAoT1trZXldKSB7XG4gICAgT1trZXldID0gdmFsO1xuICB9IGVsc2Uge1xuICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICB9XG4vLyBhZGQgZmFrZSBGdW5jdGlvbiN0b1N0cmluZyBmb3IgY29ycmVjdCB3b3JrIHdyYXBwZWQgbWV0aG9kcyAvIGNvbnN0cnVjdG9ycyB3aXRoIG1ldGhvZHMgbGlrZSBMb0Rhc2ggaXNOYXRpdmVcbn0pKEZ1bmN0aW9uLnByb3RvdHlwZSwgVE9fU1RSSU5HLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgcmV0dXJuIHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgJiYgdGhpc1tTUkNdIHx8ICR0b1N0cmluZy5jYWxsKHRoaXMpO1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIGJ1aWx0aW5FeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjO1xuXG4gLy8gYFJlZ0V4cEV4ZWNgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcmVnZXhwZXhlY1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoUiwgUykge1xuICB2YXIgZXhlYyA9IFIuZXhlYztcbiAgaWYgKHR5cGVvZiBleGVjID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIHJlc3VsdCA9IGV4ZWMuY2FsbChSLCBTKTtcbiAgICBpZiAodHlwZW9mIHJlc3VsdCAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlZ0V4cCBleGVjIG1ldGhvZCByZXR1cm5lZCBzb21ldGhpbmcgb3RoZXIgdGhhbiBhbiBPYmplY3Qgb3IgbnVsbCcpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGlmIChjbGFzc29mKFIpICE9PSAnUmVnRXhwJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlZ0V4cCNleGVjIGNhbGxlZCBvbiBpbmNvbXBhdGlibGUgcmVjZWl2ZXInKTtcbiAgfVxuICByZXR1cm4gYnVpbHRpbkV4ZWMuY2FsbChSLCBTKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZWdleHBGbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG5cbnZhciBuYXRpdmVFeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjO1xuLy8gVGhpcyBhbHdheXMgcmVmZXJzIHRvIHRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24sIGJlY2F1c2UgdGhlXG4vLyBTdHJpbmcjcmVwbGFjZSBwb2x5ZmlsbCB1c2VzIC4vZml4LXJlZ2V4cC13ZWxsLWtub3duLXN5bWJvbC1sb2dpYy5qcyxcbi8vIHdoaWNoIGxvYWRzIHRoaXMgZmlsZSBiZWZvcmUgcGF0Y2hpbmcgdGhlIG1ldGhvZC5cbnZhciBuYXRpdmVSZXBsYWNlID0gU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlO1xuXG52YXIgcGF0Y2hlZEV4ZWMgPSBuYXRpdmVFeGVjO1xuXG52YXIgTEFTVF9JTkRFWCA9ICdsYXN0SW5kZXgnO1xuXG52YXIgVVBEQVRFU19MQVNUX0lOREVYX1dST05HID0gKGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJlMSA9IC9hLyxcbiAgICAgIHJlMiA9IC9iKi9nO1xuICBuYXRpdmVFeGVjLmNhbGwocmUxLCAnYScpO1xuICBuYXRpdmVFeGVjLmNhbGwocmUyLCAnYScpO1xuICByZXR1cm4gcmUxW0xBU1RfSU5ERVhdICE9PSAwIHx8IHJlMltMQVNUX0lOREVYXSAhPT0gMDtcbn0pKCk7XG5cbi8vIG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwLCBjb3BpZWQgZnJvbSBlczUtc2hpbSdzIFN0cmluZyNzcGxpdCBwYXRjaC5cbnZhciBOUENHX0lOQ0xVREVEID0gLygpPz8vLmV4ZWMoJycpWzFdICE9PSB1bmRlZmluZWQ7XG5cbnZhciBQQVRDSCA9IFVQREFURVNfTEFTVF9JTkRFWF9XUk9ORyB8fCBOUENHX0lOQ0xVREVEO1xuXG5pZiAoUEFUQ0gpIHtcbiAgcGF0Y2hlZEV4ZWMgPSBmdW5jdGlvbiBleGVjKHN0cikge1xuICAgIHZhciByZSA9IHRoaXM7XG4gICAgdmFyIGxhc3RJbmRleCwgcmVDb3B5LCBtYXRjaCwgaTtcblxuICAgIGlmIChOUENHX0lOQ0xVREVEKSB7XG4gICAgICByZUNvcHkgPSBuZXcgUmVnRXhwKCdeJyArIHJlLnNvdXJjZSArICckKD8hXFxcXHMpJywgcmVnZXhwRmxhZ3MuY2FsbChyZSkpO1xuICAgIH1cbiAgICBpZiAoVVBEQVRFU19MQVNUX0lOREVYX1dST05HKSBsYXN0SW5kZXggPSByZVtMQVNUX0lOREVYXTtcblxuICAgIG1hdGNoID0gbmF0aXZlRXhlYy5jYWxsKHJlLCBzdHIpO1xuXG4gICAgaWYgKFVQREFURVNfTEFTVF9JTkRFWF9XUk9ORyAmJiBtYXRjaCkge1xuICAgICAgcmVbTEFTVF9JTkRFWF0gPSByZS5nbG9iYWwgPyBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCA6IGxhc3RJbmRleDtcbiAgICB9XG4gICAgaWYgKE5QQ0dfSU5DTFVERUQgJiYgbWF0Y2ggJiYgbWF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgLy8gRml4IGJyb3dzZXJzIHdob3NlIGBleGVjYCBtZXRob2RzIGRvbid0IGNvbnNpc3RlbnRseSByZXR1cm4gYHVuZGVmaW5lZGBcbiAgICAgIC8vIGZvciBOUENHLCBsaWtlIElFOC4gTk9URTogVGhpcyBkb2Vzbicgd29yayBmb3IgLyguPyk/L1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3AtZnVuY1xuICAgICAgbmF0aXZlUmVwbGFjZS5jYWxsKG1hdGNoWzBdLCByZUNvcHksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGggLSAyOyBpKyspIHtcbiAgICAgICAgICBpZiAoYXJndW1lbnRzW2ldID09PSB1bmRlZmluZWQpIG1hdGNoW2ldID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWF0Y2g7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGF0Y2hlZEV4ZWM7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChyZWdFeHAsIHJlcGxhY2UpIHtcbiAgdmFyIHJlcGxhY2VyID0gcmVwbGFjZSA9PT0gT2JqZWN0KHJlcGxhY2UpID8gZnVuY3Rpb24gKHBhcnQpIHtcbiAgICByZXR1cm4gcmVwbGFjZVtwYXJ0XTtcbiAgfSA6IHJlcGxhY2U7XG4gIHJldHVybiBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gU3RyaW5nKGl0KS5yZXBsYWNlKHJlZ0V4cCwgcmVwbGFjZXIpO1xuICB9O1xufTtcbiIsIi8vIDcuMi45IFNhbWVWYWx1ZSh4LCB5KVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuaXMgfHwgZnVuY3Rpb24gaXMoeCwgeSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIHJldHVybiB4ID09PSB5ID8geCAhPT0gMCB8fCAxIC8geCA9PT0gMSAvIHkgOiB4ICE9IHggJiYgeSAhPSB5O1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS9cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKENPTExFQ1RJT04pIHtcbiAgJGV4cG9ydCgkZXhwb3J0LlMsIENPTExFQ1RJT04sIHsgZnJvbTogZnVuY3Rpb24gZnJvbShzb3VyY2UgLyogLCBtYXBGbiwgdGhpc0FyZyAqLykge1xuICAgIHZhciBtYXBGbiA9IGFyZ3VtZW50c1sxXTtcbiAgICB2YXIgbWFwcGluZywgQSwgbiwgY2I7XG4gICAgYUZ1bmN0aW9uKHRoaXMpO1xuICAgIG1hcHBpbmcgPSBtYXBGbiAhPT0gdW5kZWZpbmVkO1xuICAgIGlmIChtYXBwaW5nKSBhRnVuY3Rpb24obWFwRm4pO1xuICAgIGlmIChzb3VyY2UgPT0gdW5kZWZpbmVkKSByZXR1cm4gbmV3IHRoaXMoKTtcbiAgICBBID0gW107XG4gICAgaWYgKG1hcHBpbmcpIHtcbiAgICAgIG4gPSAwO1xuICAgICAgY2IgPSBjdHgobWFwRm4sIGFyZ3VtZW50c1syXSwgMik7XG4gICAgICBmb3JPZihzb3VyY2UsIGZhbHNlLCBmdW5jdGlvbiAobmV4dEl0ZW0pIHtcbiAgICAgICAgQS5wdXNoKGNiKG5leHRJdGVtLCBuKyspKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPZihzb3VyY2UsIGZhbHNlLCBBLnB1c2gsIEEpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IHRoaXMoQSk7XG4gIH0gfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ09MTEVDVElPTikge1xuICAkZXhwb3J0KCRleHBvcnQuUywgQ09MTEVDVElPTiwgeyBvZjogZnVuY3Rpb24gb2YoKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIEEgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIEFbbGVuZ3RoXSA9IGFyZ3VtZW50c1tsZW5ndGhdO1xuICAgIHJldHVybiBuZXcgdGhpcyhBKTtcbiAgfSB9KTtcbn07XG4iLCIvLyBXb3JrcyB3aXRoIF9fcHJvdG9fXyBvbmx5LiBPbGQgdjggY2FuJ3Qgd29yayB3aXRoIG51bGwgcHJvdG8gb2JqZWN0cy5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGNoZWNrID0gZnVuY3Rpb24gKE8sIHByb3RvKSB7XG4gIGFuT2JqZWN0KE8pO1xuICBpZiAoIWlzT2JqZWN0KHByb3RvKSAmJiBwcm90byAhPT0gbnVsbCkgdGhyb3cgVHlwZUVycm9yKHByb3RvICsgXCI6IGNhbid0IHNldCBhcyBwcm90b3R5cGUhXCIpO1xufTtcbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXQ6IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCAoJ19fcHJvdG9fXycgaW4ge30gPyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgZnVuY3Rpb24gKHRlc3QsIGJ1Z2d5LCBzZXQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNldCA9IHJlcXVpcmUoJy4vX2N0eCcpKEZ1bmN0aW9uLmNhbGwsIHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJykuZihPYmplY3QucHJvdG90eXBlLCAnX19wcm90b19fJykuc2V0LCAyKTtcbiAgICAgICAgc2V0KHRlc3QsIFtdKTtcbiAgICAgICAgYnVnZ3kgPSAhKHRlc3QgaW5zdGFuY2VvZiBBcnJheSk7XG4gICAgICB9IGNhdGNoIChlKSB7IGJ1Z2d5ID0gdHJ1ZTsgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKSB7XG4gICAgICAgIGNoZWNrKE8sIHByb3RvKTtcbiAgICAgICAgaWYgKGJ1Z2d5KSBPLl9fcHJvdG9fXyA9IHByb3RvO1xuICAgICAgICBlbHNlIHNldChPLCBwcm90byk7XG4gICAgICAgIHJldHVybiBPO1xuICAgICAgfTtcbiAgICB9KHt9LCBmYWxzZSkgOiB1bmRlZmluZWQpLFxuICBjaGVjazogY2hlY2tcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSkge1xuICB2YXIgQyA9IGdsb2JhbFtLRVldO1xuICBpZiAoREVTQ1JJUFRPUlMgJiYgQyAmJiAhQ1tTUEVDSUVTXSkgZFAuZihDLCBTUEVDSUVTLCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfVxuICB9KTtcbn07XG4iLCJ2YXIgZGVmID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIHRhZywgc3RhdCkge1xuICBpZiAoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSkgZGVmKGl0LCBUQUcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnIH0pO1xufTtcbiIsInZhciBzaGFyZWQgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgna2V5cycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIHJldHVybiBzaGFyZWRba2V5XSB8fCAoc2hhcmVkW2tleV0gPSB1aWQoa2V5KSk7XG59O1xuIiwidmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXyc7XG52YXIgc3RvcmUgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIHJldHVybiBzdG9yZVtrZXldIHx8IChzdG9yZVtrZXldID0gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoge30pO1xufSkoJ3ZlcnNpb25zJywgW10pLnB1c2goe1xuICB2ZXJzaW9uOiBjb3JlLnZlcnNpb24sXG4gIG1vZGU6IHJlcXVpcmUoJy4vX2xpYnJhcnknKSA/ICdwdXJlJyA6ICdnbG9iYWwnLFxuICBjb3B5cmlnaHQ6ICfCqSAyMDE5IERlbmlzIFB1c2hrYXJldiAoemxvaXJvY2sucnUpJ1xufSk7XG4iLCIvLyA3LjMuMjAgU3BlY2llc0NvbnN0cnVjdG9yKE8sIGRlZmF1bHRDb25zdHJ1Y3RvcilcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE8sIEQpIHtcbiAgdmFyIEMgPSBhbk9iamVjdChPKS5jb25zdHJ1Y3RvcjtcbiAgdmFyIFM7XG4gIHJldHVybiBDID09PSB1bmRlZmluZWQgfHwgKFMgPSBhbk9iamVjdChDKVtTUEVDSUVTXSkgPT0gdW5kZWZpbmVkID8gRCA6IGFGdW5jdGlvbihTKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChtZXRob2QsIGFyZykge1xuICByZXR1cm4gISFtZXRob2QgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNhbGxcbiAgICBhcmcgPyBtZXRob2QuY2FsbChudWxsLCBmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0sIDEpIDogbWV0aG9kLmNhbGwobnVsbCk7XG4gIH0pO1xufTtcbiIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbi8vIHRydWUgIC0+IFN0cmluZyNhdFxuLy8gZmFsc2UgLT4gU3RyaW5nI2NvZGVQb2ludEF0XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChUT19TVFJJTkcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0aGF0LCBwb3MpIHtcbiAgICB2YXIgcyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbiAgICB2YXIgaSA9IHRvSW50ZWdlcihwb3MpO1xuICAgIHZhciBsID0gcy5sZW5ndGg7XG4gICAgdmFyIGEsIGI7XG4gICAgaWYgKGkgPCAwIHx8IGkgPj0gbCkgcmV0dXJuIFRPX1NUUklORyA/ICcnIDogdW5kZWZpbmVkO1xuICAgIGEgPSBzLmNoYXJDb2RlQXQoaSk7XG4gICAgcmV0dXJuIGEgPCAweGQ4MDAgfHwgYSA+IDB4ZGJmZiB8fCBpICsgMSA9PT0gbCB8fCAoYiA9IHMuY2hhckNvZGVBdChpICsgMSkpIDwgMHhkYzAwIHx8IGIgPiAweGRmZmZcbiAgICAgID8gVE9fU1RSSU5HID8gcy5jaGFyQXQoaSkgOiBhXG4gICAgICA6IFRPX1NUUklORyA/IHMuc2xpY2UoaSwgaSArIDIpIDogKGEgLSAweGQ4MDAgPDwgMTApICsgKGIgLSAweGRjMDApICsgMHgxMDAwMDtcbiAgfTtcbn07XG4iLCIvLyBoZWxwZXIgZm9yIFN0cmluZyN7c3RhcnRzV2l0aCwgZW5kc1dpdGgsIGluY2x1ZGVzfVxudmFyIGlzUmVnRXhwID0gcmVxdWlyZSgnLi9faXMtcmVnZXhwJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgc2VhcmNoU3RyaW5nLCBOQU1FKSB7XG4gIGlmIChpc1JlZ0V4cChzZWFyY2hTdHJpbmcpKSB0aHJvdyBUeXBlRXJyb3IoJ1N0cmluZyMnICsgTkFNRSArIFwiIGRvZXNuJ3QgYWNjZXB0IHJlZ2V4IVwiKTtcbiAgcmV0dXJuIFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbn07XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIHF1b3QgPSAvXCIvZztcbi8vIEIuMi4zLjIuMSBDcmVhdGVIVE1MKHN0cmluZywgdGFnLCBhdHRyaWJ1dGUsIHZhbHVlKVxudmFyIGNyZWF0ZUhUTUwgPSBmdW5jdGlvbiAoc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgdmFyIFMgPSBTdHJpbmcoZGVmaW5lZChzdHJpbmcpKTtcbiAgdmFyIHAxID0gJzwnICsgdGFnO1xuICBpZiAoYXR0cmlidXRlICE9PSAnJykgcDEgKz0gJyAnICsgYXR0cmlidXRlICsgJz1cIicgKyBTdHJpbmcodmFsdWUpLnJlcGxhY2UocXVvdCwgJyZxdW90OycpICsgJ1wiJztcbiAgcmV0dXJuIHAxICsgJz4nICsgUyArICc8LycgKyB0YWcgKyAnPic7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTkFNRSwgZXhlYykge1xuICB2YXIgTyA9IHt9O1xuICBPW05BTUVdID0gZXhlYyhjcmVhdGVIVE1MKTtcbiAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRlc3QgPSAnJ1tOQU1FXSgnXCInKTtcbiAgICByZXR1cm4gdGVzdCAhPT0gdGVzdC50b0xvd2VyQ2FzZSgpIHx8IHRlc3Quc3BsaXQoJ1wiJykubGVuZ3RoID4gMztcbiAgfSksICdTdHJpbmcnLCBPKTtcbn07XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgcmVwZWF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoYXQsIG1heExlbmd0aCwgZmlsbFN0cmluZywgbGVmdCkge1xuICB2YXIgUyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbiAgdmFyIHN0cmluZ0xlbmd0aCA9IFMubGVuZ3RoO1xuICB2YXIgZmlsbFN0ciA9IGZpbGxTdHJpbmcgPT09IHVuZGVmaW5lZCA/ICcgJyA6IFN0cmluZyhmaWxsU3RyaW5nKTtcbiAgdmFyIGludE1heExlbmd0aCA9IHRvTGVuZ3RoKG1heExlbmd0aCk7XG4gIGlmIChpbnRNYXhMZW5ndGggPD0gc3RyaW5nTGVuZ3RoIHx8IGZpbGxTdHIgPT0gJycpIHJldHVybiBTO1xuICB2YXIgZmlsbExlbiA9IGludE1heExlbmd0aCAtIHN0cmluZ0xlbmd0aDtcbiAgdmFyIHN0cmluZ0ZpbGxlciA9IHJlcGVhdC5jYWxsKGZpbGxTdHIsIE1hdGguY2VpbChmaWxsTGVuIC8gZmlsbFN0ci5sZW5ndGgpKTtcbiAgaWYgKHN0cmluZ0ZpbGxlci5sZW5ndGggPiBmaWxsTGVuKSBzdHJpbmdGaWxsZXIgPSBzdHJpbmdGaWxsZXIuc2xpY2UoMCwgZmlsbExlbik7XG4gIHJldHVybiBsZWZ0ID8gc3RyaW5nRmlsbGVyICsgUyA6IFMgKyBzdHJpbmdGaWxsZXI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlcGVhdChjb3VudCkge1xuICB2YXIgc3RyID0gU3RyaW5nKGRlZmluZWQodGhpcykpO1xuICB2YXIgcmVzID0gJyc7XG4gIHZhciBuID0gdG9JbnRlZ2VyKGNvdW50KTtcbiAgaWYgKG4gPCAwIHx8IG4gPT0gSW5maW5pdHkpIHRocm93IFJhbmdlRXJyb3IoXCJDb3VudCBjYW4ndCBiZSBuZWdhdGl2ZVwiKTtcbiAgZm9yICg7biA+IDA7IChuID4+Pj0gMSkgJiYgKHN0ciArPSBzdHIpKSBpZiAobiAmIDEpIHJlcyArPSBzdHI7XG4gIHJldHVybiByZXM7XG59O1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBzcGFjZXMgPSByZXF1aXJlKCcuL19zdHJpbmctd3MnKTtcbnZhciBzcGFjZSA9ICdbJyArIHNwYWNlcyArICddJztcbnZhciBub24gPSAnXFx1MjAwYlxcdTAwODUnO1xudmFyIGx0cmltID0gUmVnRXhwKCdeJyArIHNwYWNlICsgc3BhY2UgKyAnKicpO1xudmFyIHJ0cmltID0gUmVnRXhwKHNwYWNlICsgc3BhY2UgKyAnKiQnKTtcblxudmFyIGV4cG9ydGVyID0gZnVuY3Rpb24gKEtFWSwgZXhlYywgQUxJQVMpIHtcbiAgdmFyIGV4cCA9IHt9O1xuICB2YXIgRk9SQ0UgPSBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhc3BhY2VzW0tFWV0oKSB8fCBub25bS0VZXSgpICE9IG5vbjtcbiAgfSk7XG4gIHZhciBmbiA9IGV4cFtLRVldID0gRk9SQ0UgPyBleGVjKHRyaW0pIDogc3BhY2VzW0tFWV07XG4gIGlmIChBTElBUykgZXhwW0FMSUFTXSA9IGZuO1xuICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIEZPUkNFLCAnU3RyaW5nJywgZXhwKTtcbn07XG5cbi8vIDEgLT4gU3RyaW5nI3RyaW1MZWZ0XG4vLyAyIC0+IFN0cmluZyN0cmltUmlnaHRcbi8vIDMgLT4gU3RyaW5nI3RyaW1cbnZhciB0cmltID0gZXhwb3J0ZXIudHJpbSA9IGZ1bmN0aW9uIChzdHJpbmcsIFRZUEUpIHtcbiAgc3RyaW5nID0gU3RyaW5nKGRlZmluZWQoc3RyaW5nKSk7XG4gIGlmIChUWVBFICYgMSkgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UobHRyaW0sICcnKTtcbiAgaWYgKFRZUEUgJiAyKSBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShydHJpbSwgJycpO1xuICByZXR1cm4gc3RyaW5nO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRlcjtcbiIsIm1vZHVsZS5leHBvcnRzID0gJ1xceDA5XFx4MEFcXHgwQlxceDBDXFx4MERcXHgyMFxceEEwXFx1MTY4MFxcdTE4MEVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzJyArXG4gICdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOFxcdTIwMjlcXHVGRUZGJztcbiIsInZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBpbnZva2UgPSByZXF1aXJlKCcuL19pbnZva2UnKTtcbnZhciBodG1sID0gcmVxdWlyZSgnLi9faHRtbCcpO1xudmFyIGNlbCA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKTtcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgc2V0VGFzayA9IGdsb2JhbC5zZXRJbW1lZGlhdGU7XG52YXIgY2xlYXJUYXNrID0gZ2xvYmFsLmNsZWFySW1tZWRpYXRlO1xudmFyIE1lc3NhZ2VDaGFubmVsID0gZ2xvYmFsLk1lc3NhZ2VDaGFubmVsO1xudmFyIERpc3BhdGNoID0gZ2xvYmFsLkRpc3BhdGNoO1xudmFyIGNvdW50ZXIgPSAwO1xudmFyIHF1ZXVlID0ge307XG52YXIgT05SRUFEWVNUQVRFQ0hBTkdFID0gJ29ucmVhZHlzdGF0ZWNoYW5nZSc7XG52YXIgZGVmZXIsIGNoYW5uZWwsIHBvcnQ7XG52YXIgcnVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaWQgPSArdGhpcztcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xuICBpZiAocXVldWUuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgdmFyIGZuID0gcXVldWVbaWRdO1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gICAgZm4oKTtcbiAgfVxufTtcbnZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudCkge1xuICBydW4uY2FsbChldmVudC5kYXRhKTtcbn07XG4vLyBOb2RlLmpzIDAuOSsgJiBJRTEwKyBoYXMgc2V0SW1tZWRpYXRlLCBvdGhlcndpc2U6XG5pZiAoIXNldFRhc2sgfHwgIWNsZWFyVGFzaykge1xuICBzZXRUYXNrID0gZnVuY3Rpb24gc2V0SW1tZWRpYXRlKGZuKSB7XG4gICAgdmFyIGFyZ3MgPSBbXTtcbiAgICB2YXIgaSA9IDE7XG4gICAgd2hpbGUgKGFyZ3VtZW50cy5sZW5ndGggPiBpKSBhcmdzLnB1c2goYXJndW1lbnRzW2krK10pO1xuICAgIHF1ZXVlWysrY291bnRlcl0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICAgIGludm9rZSh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pLCBhcmdzKTtcbiAgICB9O1xuICAgIGRlZmVyKGNvdW50ZXIpO1xuICAgIHJldHVybiBjb3VudGVyO1xuICB9O1xuICBjbGVhclRhc2sgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCkge1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gIH07XG4gIC8vIE5vZGUuanMgMC44LVxuICBpZiAocmVxdWlyZSgnLi9fY29mJykocHJvY2VzcykgPT0gJ3Byb2Nlc3MnKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBTcGhlcmUgKEpTIGdhbWUgZW5naW5lKSBEaXNwYXRjaCBBUElcbiAgfSBlbHNlIGlmIChEaXNwYXRjaCAmJiBEaXNwYXRjaC5ub3cpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgRGlzcGF0Y2gubm93KGN0eChydW4sIGlkLCAxKSk7XG4gICAgfTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBNZXNzYWdlQ2hhbm5lbCwgaW5jbHVkZXMgV2ViV29ya2Vyc1xuICB9IGVsc2UgaWYgKE1lc3NhZ2VDaGFubmVsKSB7XG4gICAgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHBvcnQgPSBjaGFubmVsLnBvcnQyO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGlzdGVuZXI7XG4gICAgZGVmZXIgPSBjdHgocG9ydC5wb3N0TWVzc2FnZSwgcG9ydCwgMSk7XG4gIC8vIEJyb3dzZXJzIHdpdGggcG9zdE1lc3NhZ2UsIHNraXAgV2ViV29ya2Vyc1xuICAvLyBJRTggaGFzIHBvc3RNZXNzYWdlLCBidXQgaXQncyBzeW5jICYgdHlwZW9mIGl0cyBwb3N0TWVzc2FnZSBpcyAnb2JqZWN0J1xuICB9IGVsc2UgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyICYmIHR5cGVvZiBwb3N0TWVzc2FnZSA9PSAnZnVuY3Rpb24nICYmICFnbG9iYWwuaW1wb3J0U2NyaXB0cykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBnbG9iYWwucG9zdE1lc3NhZ2UoaWQgKyAnJywgJyonKTtcbiAgICB9O1xuICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIsIGZhbHNlKTtcbiAgLy8gSUU4LVxuICB9IGVsc2UgaWYgKE9OUkVBRFlTVEFURUNIQU5HRSBpbiBjZWwoJ3NjcmlwdCcpKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoY2VsKCdzY3JpcHQnKSlbT05SRUFEWVNUQVRFQ0hBTkdFXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaHRtbC5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgICAgICAgcnVuLmNhbGwoaWQpO1xuICAgICAgfTtcbiAgICB9O1xuICAvLyBSZXN0IG9sZCBicm93c2Vyc1xuICB9IGVsc2Uge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBzZXRUaW1lb3V0KGN0eChydW4sIGlkLCAxKSwgMCk7XG4gICAgfTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogc2V0VGFzayxcbiAgY2xlYXI6IGNsZWFyVGFza1xufTtcbiIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgbWluID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpbmRleCwgbGVuZ3RoKSB7XG4gIGluZGV4ID0gdG9JbnRlZ2VyKGluZGV4KTtcbiAgcmV0dXJuIGluZGV4IDwgMCA/IG1heChpbmRleCArIGxlbmd0aCwgMCkgOiBtaW4oaW5kZXgsIGxlbmd0aCk7XG59O1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdG9pbmRleFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09PSB1bmRlZmluZWQpIHJldHVybiAwO1xuICB2YXIgbnVtYmVyID0gdG9JbnRlZ2VyKGl0KTtcbiAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKG51bWJlcik7XG4gIGlmIChudW1iZXIgIT09IGxlbmd0aCkgdGhyb3cgUmFuZ2VFcnJvcignV3JvbmcgbGVuZ3RoIScpO1xuICByZXR1cm4gbGVuZ3RoO1xufTtcbiIsIi8vIDcuMS40IFRvSW50ZWdlclxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XG59O1xuIiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcbiIsIi8vIDcuMS4xNSBUb0xlbmd0aFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCA+IDAgPyBtaW4odG9JbnRlZ2VyKGl0KSwgMHgxZmZmZmZmZmZmZmZmZikgOiAwOyAvLyBwb3coMiwgNTMpIC0gMSA9PSA5MDA3MTk5MjU0NzQwOTkxXG59O1xuIiwiLy8gNy4xLjEzIFRvT2JqZWN0KGFyZ3VtZW50KVxudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG4iLCIvLyA3LjEuMSBUb1ByaW1pdGl2ZShpbnB1dCBbLCBQcmVmZXJyZWRUeXBlXSlcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuLy8gaW5zdGVhZCBvZiB0aGUgRVM2IHNwZWMgdmVyc2lvbiwgd2UgZGlkbid0IGltcGxlbWVudCBAQHRvUHJpbWl0aXZlIGNhc2Vcbi8vIGFuZCB0aGUgc2Vjb25kIGFyZ3VtZW50IC0gZmxhZyAtIHByZWZlcnJlZCB0eXBlIGlzIGEgc3RyaW5nXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgUykge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkgcmV0dXJuIGl0O1xuICB2YXIgZm4sIHZhbDtcbiAgaWYgKFMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIGlmICh0eXBlb2YgKGZuID0gaXQudmFsdWVPZikgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAoIVMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIHRocm93IFR5cGVFcnJvcihcIkNhbid0IGNvbnZlcnQgb2JqZWN0IHRvIHByaW1pdGl2ZSB2YWx1ZVwiKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5pZiAocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSkge1xuICB2YXIgTElCUkFSWSA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKTtcbiAgdmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xuICB2YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xuICB2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuICB2YXIgJHR5cGVkID0gcmVxdWlyZSgnLi9fdHlwZWQnKTtcbiAgdmFyICRidWZmZXIgPSByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKTtcbiAgdmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xuICB2YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG4gIHZhciBwcm9wZXJ0eURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG4gIHZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xuICB2YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbiAgdmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbiAgdmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG4gIHZhciB0b0luZGV4ID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbiAgdmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG4gIHZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuICB2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG4gIHZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xuICB2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbiAgdmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG4gIHZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbiAgdmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbiAgdmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xuICB2YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbiAgdmFyIGdldEl0ZXJGbiA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJyk7XG4gIHZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbiAgdmFyIHdrcyA9IHJlcXVpcmUoJy4vX3drcycpO1xuICB2YXIgY3JlYXRlQXJyYXlNZXRob2QgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJyk7XG4gIHZhciBjcmVhdGVBcnJheUluY2x1ZGVzID0gcmVxdWlyZSgnLi9fYXJyYXktaW5jbHVkZXMnKTtcbiAgdmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKTtcbiAgdmFyIEFycmF5SXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbiAgdmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xuICB2YXIgJGl0ZXJEZXRlY3QgPSByZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpO1xuICB2YXIgc2V0U3BlY2llcyA9IHJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJyk7XG4gIHZhciBhcnJheUZpbGwgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJyk7XG4gIHZhciBhcnJheUNvcHlXaXRoaW4gPSByZXF1aXJlKCcuL19hcnJheS1jb3B5LXdpdGhpbicpO1xuICB2YXIgJERQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG4gIHZhciAkR09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG4gIHZhciBkUCA9ICREUC5mO1xuICB2YXIgZ09QRCA9ICRHT1BELmY7XG4gIHZhciBSYW5nZUVycm9yID0gZ2xvYmFsLlJhbmdlRXJyb3I7XG4gIHZhciBUeXBlRXJyb3IgPSBnbG9iYWwuVHlwZUVycm9yO1xuICB2YXIgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuICB2YXIgQVJSQVlfQlVGRkVSID0gJ0FycmF5QnVmZmVyJztcbiAgdmFyIFNIQVJFRF9CVUZGRVIgPSAnU2hhcmVkJyArIEFSUkFZX0JVRkZFUjtcbiAgdmFyIEJZVEVTX1BFUl9FTEVNRU5UID0gJ0JZVEVTX1BFUl9FTEVNRU5UJztcbiAgdmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuICB2YXIgQXJyYXlQcm90byA9IEFycmF5W1BST1RPVFlQRV07XG4gIHZhciAkQXJyYXlCdWZmZXIgPSAkYnVmZmVyLkFycmF5QnVmZmVyO1xuICB2YXIgJERhdGFWaWV3ID0gJGJ1ZmZlci5EYXRhVmlldztcbiAgdmFyIGFycmF5Rm9yRWFjaCA9IGNyZWF0ZUFycmF5TWV0aG9kKDApO1xuICB2YXIgYXJyYXlGaWx0ZXIgPSBjcmVhdGVBcnJheU1ldGhvZCgyKTtcbiAgdmFyIGFycmF5U29tZSA9IGNyZWF0ZUFycmF5TWV0aG9kKDMpO1xuICB2YXIgYXJyYXlFdmVyeSA9IGNyZWF0ZUFycmF5TWV0aG9kKDQpO1xuICB2YXIgYXJyYXlGaW5kID0gY3JlYXRlQXJyYXlNZXRob2QoNSk7XG4gIHZhciBhcnJheUZpbmRJbmRleCA9IGNyZWF0ZUFycmF5TWV0aG9kKDYpO1xuICB2YXIgYXJyYXlJbmNsdWRlcyA9IGNyZWF0ZUFycmF5SW5jbHVkZXModHJ1ZSk7XG4gIHZhciBhcnJheUluZGV4T2YgPSBjcmVhdGVBcnJheUluY2x1ZGVzKGZhbHNlKTtcbiAgdmFyIGFycmF5VmFsdWVzID0gQXJyYXlJdGVyYXRvcnMudmFsdWVzO1xuICB2YXIgYXJyYXlLZXlzID0gQXJyYXlJdGVyYXRvcnMua2V5cztcbiAgdmFyIGFycmF5RW50cmllcyA9IEFycmF5SXRlcmF0b3JzLmVudHJpZXM7XG4gIHZhciBhcnJheUxhc3RJbmRleE9mID0gQXJyYXlQcm90by5sYXN0SW5kZXhPZjtcbiAgdmFyIGFycmF5UmVkdWNlID0gQXJyYXlQcm90by5yZWR1Y2U7XG4gIHZhciBhcnJheVJlZHVjZVJpZ2h0ID0gQXJyYXlQcm90by5yZWR1Y2VSaWdodDtcbiAgdmFyIGFycmF5Sm9pbiA9IEFycmF5UHJvdG8uam9pbjtcbiAgdmFyIGFycmF5U29ydCA9IEFycmF5UHJvdG8uc29ydDtcbiAgdmFyIGFycmF5U2xpY2UgPSBBcnJheVByb3RvLnNsaWNlO1xuICB2YXIgYXJyYXlUb1N0cmluZyA9IEFycmF5UHJvdG8udG9TdHJpbmc7XG4gIHZhciBhcnJheVRvTG9jYWxlU3RyaW5nID0gQXJyYXlQcm90by50b0xvY2FsZVN0cmluZztcbiAgdmFyIElURVJBVE9SID0gd2tzKCdpdGVyYXRvcicpO1xuICB2YXIgVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xuICB2YXIgVFlQRURfQ09OU1RSVUNUT1IgPSB1aWQoJ3R5cGVkX2NvbnN0cnVjdG9yJyk7XG4gIHZhciBERUZfQ09OU1RSVUNUT1IgPSB1aWQoJ2RlZl9jb25zdHJ1Y3RvcicpO1xuICB2YXIgQUxMX0NPTlNUUlVDVE9SUyA9ICR0eXBlZC5DT05TVFI7XG4gIHZhciBUWVBFRF9BUlJBWSA9ICR0eXBlZC5UWVBFRDtcbiAgdmFyIFZJRVcgPSAkdHlwZWQuVklFVztcbiAgdmFyIFdST05HX0xFTkdUSCA9ICdXcm9uZyBsZW5ndGghJztcblxuICB2YXIgJG1hcCA9IGNyZWF0ZUFycmF5TWV0aG9kKDEsIGZ1bmN0aW9uIChPLCBsZW5ndGgpIHtcbiAgICByZXR1cm4gYWxsb2NhdGUoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxlbmd0aCk7XG4gIH0pO1xuXG4gIHZhciBMSVRUTEVfRU5ESUFOID0gZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgIHJldHVybiBuZXcgVWludDhBcnJheShuZXcgVWludDE2QXJyYXkoWzFdKS5idWZmZXIpWzBdID09PSAxO1xuICB9KTtcblxuICB2YXIgRk9SQ0VEX1NFVCA9ICEhVWludDhBcnJheSAmJiAhIVVpbnQ4QXJyYXlbUFJPVE9UWVBFXS5zZXQgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIG5ldyBVaW50OEFycmF5KDEpLnNldCh7fSk7XG4gIH0pO1xuXG4gIHZhciB0b09mZnNldCA9IGZ1bmN0aW9uIChpdCwgQllURVMpIHtcbiAgICB2YXIgb2Zmc2V0ID0gdG9JbnRlZ2VyKGl0KTtcbiAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgJSBCWVRFUykgdGhyb3cgUmFuZ2VFcnJvcignV3Jvbmcgb2Zmc2V0IScpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH07XG5cbiAgdmFyIHZhbGlkYXRlID0gZnVuY3Rpb24gKGl0KSB7XG4gICAgaWYgKGlzT2JqZWN0KGl0KSAmJiBUWVBFRF9BUlJBWSBpbiBpdCkgcmV0dXJuIGl0O1xuICAgIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgdHlwZWQgYXJyYXkhJyk7XG4gIH07XG5cbiAgdmFyIGFsbG9jYXRlID0gZnVuY3Rpb24gKEMsIGxlbmd0aCkge1xuICAgIGlmICghKGlzT2JqZWN0KEMpICYmIFRZUEVEX0NPTlNUUlVDVE9SIGluIEMpKSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ0l0IGlzIG5vdCBhIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9yIScpO1xuICAgIH0gcmV0dXJuIG5ldyBDKGxlbmd0aCk7XG4gIH07XG5cbiAgdmFyIHNwZWNpZXNGcm9tTGlzdCA9IGZ1bmN0aW9uIChPLCBsaXN0KSB7XG4gICAgcmV0dXJuIGZyb21MaXN0KHNwZWNpZXNDb25zdHJ1Y3RvcihPLCBPW0RFRl9DT05TVFJVQ1RPUl0pLCBsaXN0KTtcbiAgfTtcblxuICB2YXIgZnJvbUxpc3QgPSBmdW5jdGlvbiAoQywgbGlzdCkge1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICAgIHZhciByZXN1bHQgPSBhbGxvY2F0ZShDLCBsZW5ndGgpO1xuICAgIHdoaWxlIChsZW5ndGggPiBpbmRleCkgcmVzdWx0W2luZGV4XSA9IGxpc3RbaW5kZXgrK107XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgYWRkR2V0dGVyID0gZnVuY3Rpb24gKGl0LCBrZXksIGludGVybmFsKSB7XG4gICAgZFAoaXQsIGtleSwgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2RbaW50ZXJuYWxdOyB9IH0pO1xuICB9O1xuXG4gIHZhciAkZnJvbSA9IGZ1bmN0aW9uIGZyb20oc291cmNlIC8qICwgbWFwZm4sIHRoaXNBcmcgKi8pIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KHNvdXJjZSk7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBtYXBmbiA9IGFMZW4gPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBtYXBwaW5nID0gbWFwZm4gIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgaXRlckZuID0gZ2V0SXRlckZuKE8pO1xuICAgIHZhciBpLCBsZW5ndGgsIHZhbHVlcywgcmVzdWx0LCBzdGVwLCBpdGVyYXRvcjtcbiAgICBpZiAoaXRlckZuICE9IHVuZGVmaW5lZCAmJiAhaXNBcnJheUl0ZXIoaXRlckZuKSkge1xuICAgICAgZm9yIChpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCB2YWx1ZXMgPSBbXSwgaSA9IDA7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaSsrKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHN0ZXAudmFsdWUpO1xuICAgICAgfSBPID0gdmFsdWVzO1xuICAgIH1cbiAgICBpZiAobWFwcGluZyAmJiBhTGVuID4gMikgbWFwZm4gPSBjdHgobWFwZm4sIGFyZ3VtZW50c1syXSwgMik7XG4gICAgZm9yIChpID0gMCwgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpLCByZXN1bHQgPSBhbGxvY2F0ZSh0aGlzLCBsZW5ndGgpOyBsZW5ndGggPiBpOyBpKyspIHtcbiAgICAgIHJlc3VsdFtpXSA9IG1hcHBpbmcgPyBtYXBmbihPW2ldLCBpKSA6IE9baV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyICRvZiA9IGZ1bmN0aW9uIG9mKC8qIC4uLml0ZW1zICovKSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgcmVzdWx0ID0gYWxsb2NhdGUodGhpcywgbGVuZ3RoKTtcbiAgICB3aGlsZSAobGVuZ3RoID4gaW5kZXgpIHJlc3VsdFtpbmRleF0gPSBhcmd1bWVudHNbaW5kZXgrK107XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBpT1MgU2FmYXJpIDYueCBmYWlscyBoZXJlXG4gIHZhciBUT19MT0NBTEVfQlVHID0gISFVaW50OEFycmF5ICYmIGZhaWxzKGZ1bmN0aW9uICgpIHsgYXJyYXlUb0xvY2FsZVN0cmluZy5jYWxsKG5ldyBVaW50OEFycmF5KDEpKTsgfSk7XG5cbiAgdmFyICR0b0xvY2FsZVN0cmluZyA9IGZ1bmN0aW9uIHRvTG9jYWxlU3RyaW5nKCkge1xuICAgIHJldHVybiBhcnJheVRvTG9jYWxlU3RyaW5nLmFwcGx5KFRPX0xPQ0FMRV9CVUcgPyBhcnJheVNsaWNlLmNhbGwodmFsaWRhdGUodGhpcykpIDogdmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgdmFyIHByb3RvID0ge1xuICAgIGNvcHlXaXRoaW46IGZ1bmN0aW9uIGNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCAvKiAsIGVuZCAqLykge1xuICAgICAgcmV0dXJuIGFycmF5Q29weVdpdGhpbi5jYWxsKHZhbGlkYXRlKHRoaXMpLCB0YXJnZXQsIHN0YXJ0LCBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUV2ZXJ5KHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBmaWxsOiBmdW5jdGlvbiBmaWxsKHZhbHVlIC8qICwgc3RhcnQsIGVuZCAqLykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4gYXJyYXlGaWxsLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBzcGVjaWVzRnJvbUxpc3QodGhpcywgYXJyYXlGaWx0ZXIodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sXG4gICAgICAgIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKSk7XG4gICAgfSxcbiAgICBmaW5kOiBmdW5jdGlvbiBmaW5kKHByZWRpY2F0ZSAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUZpbmQodmFsaWRhdGUodGhpcyksIHByZWRpY2F0ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgZmluZEluZGV4OiBmdW5jdGlvbiBmaW5kSW5kZXgocHJlZGljYXRlIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIGFycmF5RmluZEluZGV4KHZhbGlkYXRlKHRoaXMpLCBwcmVkaWNhdGUsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIGFycmF5Rm9yRWFjaCh2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgaW5kZXhPZjogZnVuY3Rpb24gaW5kZXhPZihzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlJbmRleE9mKHZhbGlkYXRlKHRoaXMpLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCAqLykge1xuICAgICAgcmV0dXJuIGFycmF5SW5jbHVkZXModmFsaWRhdGUodGhpcyksIHNlYXJjaEVsZW1lbnQsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUpvaW4uYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCAqLykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4gYXJyYXlMYXN0SW5kZXhPZi5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIG1hcDogZnVuY3Rpb24gbWFwKG1hcGZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuICRtYXAodmFsaWRhdGUodGhpcyksIG1hcGZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICByZWR1Y2U6IGZ1bmN0aW9uIHJlZHVjZShjYWxsYmFja2ZuIC8qICwgaW5pdGlhbFZhbHVlICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZS5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbiByZWR1Y2VSaWdodChjYWxsYmFja2ZuIC8qICwgaW5pdGlhbFZhbHVlICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZVJpZ2h0LmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgcmV2ZXJzZTogZnVuY3Rpb24gcmV2ZXJzZSgpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICAgIHZhciBsZW5ndGggPSB2YWxpZGF0ZSh0aGF0KS5sZW5ndGg7XG4gICAgICB2YXIgbWlkZGxlID0gTWF0aC5mbG9vcihsZW5ndGggLyAyKTtcbiAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICB3aGlsZSAoaW5kZXggPCBtaWRkbGUpIHtcbiAgICAgICAgdmFsdWUgPSB0aGF0W2luZGV4XTtcbiAgICAgICAgdGhhdFtpbmRleCsrXSA9IHRoYXRbLS1sZW5ndGhdO1xuICAgICAgICB0aGF0W2xlbmd0aF0gPSB2YWx1ZTtcbiAgICAgIH0gcmV0dXJuIHRoYXQ7XG4gICAgfSxcbiAgICBzb21lOiBmdW5jdGlvbiBzb21lKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlTb21lKHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBzb3J0OiBmdW5jdGlvbiBzb3J0KGNvbXBhcmVmbikge1xuICAgICAgcmV0dXJuIGFycmF5U29ydC5jYWxsKHZhbGlkYXRlKHRoaXMpLCBjb21wYXJlZm4pO1xuICAgIH0sXG4gICAgc3ViYXJyYXk6IGZ1bmN0aW9uIHN1YmFycmF5KGJlZ2luLCBlbmQpIHtcbiAgICAgIHZhciBPID0gdmFsaWRhdGUodGhpcyk7XG4gICAgICB2YXIgbGVuZ3RoID0gTy5sZW5ndGg7XG4gICAgICB2YXIgJGJlZ2luID0gdG9BYnNvbHV0ZUluZGV4KGJlZ2luLCBsZW5ndGgpO1xuICAgICAgcmV0dXJuIG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSkpKFxuICAgICAgICBPLmJ1ZmZlcixcbiAgICAgICAgTy5ieXRlT2Zmc2V0ICsgJGJlZ2luICogTy5CWVRFU19QRVJfRUxFTUVOVCxcbiAgICAgICAgdG9MZW5ndGgoKGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9BYnNvbHV0ZUluZGV4KGVuZCwgbGVuZ3RoKSkgLSAkYmVnaW4pXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICB2YXIgJHNsaWNlID0gZnVuY3Rpb24gc2xpY2Uoc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiBzcGVjaWVzRnJvbUxpc3QodGhpcywgYXJyYXlTbGljZS5jYWxsKHZhbGlkYXRlKHRoaXMpLCBzdGFydCwgZW5kKSk7XG4gIH07XG5cbiAgdmFyICRzZXQgPSBmdW5jdGlvbiBzZXQoYXJyYXlMaWtlIC8qICwgb2Zmc2V0ICovKSB7XG4gICAgdmFsaWRhdGUodGhpcyk7XG4gICAgdmFyIG9mZnNldCA9IHRvT2Zmc2V0KGFyZ3VtZW50c1sxXSwgMSk7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgIHZhciBzcmMgPSB0b09iamVjdChhcnJheUxpa2UpO1xuICAgIHZhciBsZW4gPSB0b0xlbmd0aChzcmMubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIGlmIChsZW4gKyBvZmZzZXQgPiBsZW5ndGgpIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICB3aGlsZSAoaW5kZXggPCBsZW4pIHRoaXNbb2Zmc2V0ICsgaW5kZXhdID0gc3JjW2luZGV4KytdO1xuICB9O1xuXG4gIHZhciAkaXRlcmF0b3JzID0ge1xuICAgIGVudHJpZXM6IGZ1bmN0aW9uIGVudHJpZXMoKSB7XG4gICAgICByZXR1cm4gYXJyYXlFbnRyaWVzLmNhbGwodmFsaWRhdGUodGhpcykpO1xuICAgIH0sXG4gICAga2V5czogZnVuY3Rpb24ga2V5cygpIHtcbiAgICAgIHJldHVybiBhcnJheUtleXMuY2FsbCh2YWxpZGF0ZSh0aGlzKSk7XG4gICAgfSxcbiAgICB2YWx1ZXM6IGZ1bmN0aW9uIHZhbHVlcygpIHtcbiAgICAgIHJldHVybiBhcnJheVZhbHVlcy5jYWxsKHZhbGlkYXRlKHRoaXMpKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIGlzVEFJbmRleCA9IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgIHJldHVybiBpc09iamVjdCh0YXJnZXQpXG4gICAgICAmJiB0YXJnZXRbVFlQRURfQVJSQVldXG4gICAgICAmJiB0eXBlb2Yga2V5ICE9ICdzeW1ib2wnXG4gICAgICAmJiBrZXkgaW4gdGFyZ2V0XG4gICAgICAmJiBTdHJpbmcoK2tleSkgPT0gU3RyaW5nKGtleSk7XG4gIH07XG4gIHZhciAkZ2V0RGVzYyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkge1xuICAgIHJldHVybiBpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxuICAgICAgPyBwcm9wZXJ0eURlc2MoMiwgdGFyZ2V0W2tleV0pXG4gICAgICA6IGdPUEQodGFyZ2V0LCBrZXkpO1xuICB9O1xuICB2YXIgJHNldERlc2MgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzYykge1xuICAgIGlmIChpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxuICAgICAgJiYgaXNPYmplY3QoZGVzYylcbiAgICAgICYmIGhhcyhkZXNjLCAndmFsdWUnKVxuICAgICAgJiYgIWhhcyhkZXNjLCAnZ2V0JylcbiAgICAgICYmICFoYXMoZGVzYywgJ3NldCcpXG4gICAgICAvLyBUT0RPOiBhZGQgdmFsaWRhdGlvbiBkZXNjcmlwdG9yIHcvbyBjYWxsaW5nIGFjY2Vzc29yc1xuICAgICAgJiYgIWRlc2MuY29uZmlndXJhYmxlXG4gICAgICAmJiAoIWhhcyhkZXNjLCAnd3JpdGFibGUnKSB8fCBkZXNjLndyaXRhYmxlKVxuICAgICAgJiYgKCFoYXMoZGVzYywgJ2VudW1lcmFibGUnKSB8fCBkZXNjLmVudW1lcmFibGUpXG4gICAgKSB7XG4gICAgICB0YXJnZXRba2V5XSA9IGRlc2MudmFsdWU7XG4gICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH0gcmV0dXJuIGRQKHRhcmdldCwga2V5LCBkZXNjKTtcbiAgfTtcblxuICBpZiAoIUFMTF9DT05TVFJVQ1RPUlMpIHtcbiAgICAkR09QRC5mID0gJGdldERlc2M7XG4gICAgJERQLmYgPSAkc2V0RGVzYztcbiAgfVxuXG4gICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIUFMTF9DT05TVFJVQ1RPUlMsICdPYmplY3QnLCB7XG4gICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0RGVzYyxcbiAgICBkZWZpbmVQcm9wZXJ0eTogJHNldERlc2NcbiAgfSk7XG5cbiAgaWYgKGZhaWxzKGZ1bmN0aW9uICgpIHsgYXJyYXlUb1N0cmluZy5jYWxsKHt9KTsgfSkpIHtcbiAgICBhcnJheVRvU3RyaW5nID0gYXJyYXlUb0xvY2FsZVN0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgcmV0dXJuIGFycmF5Sm9pbi5jYWxsKHRoaXMpO1xuICAgIH07XG4gIH1cblxuICB2YXIgJFR5cGVkQXJyYXlQcm90b3R5cGUkID0gcmVkZWZpbmVBbGwoe30sIHByb3RvKTtcbiAgcmVkZWZpbmVBbGwoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAkaXRlcmF0b3JzKTtcbiAgaGlkZSgkVHlwZWRBcnJheVByb3RvdHlwZSQsIElURVJBVE9SLCAkaXRlcmF0b3JzLnZhbHVlcyk7XG4gIHJlZGVmaW5lQWxsKCRUeXBlZEFycmF5UHJvdG90eXBlJCwge1xuICAgIHNsaWNlOiAkc2xpY2UsXG4gICAgc2V0OiAkc2V0LFxuICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiAoKSB7IC8qIG5vb3AgKi8gfSxcbiAgICB0b1N0cmluZzogYXJyYXlUb1N0cmluZyxcbiAgICB0b0xvY2FsZVN0cmluZzogJHRvTG9jYWxlU3RyaW5nXG4gIH0pO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnVmZmVyJywgJ2InKTtcbiAgYWRkR2V0dGVyKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgJ2J5dGVPZmZzZXQnLCAnbycpO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnl0ZUxlbmd0aCcsICdsJyk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdsZW5ndGgnLCAnZScpO1xuICBkUCgkVHlwZWRBcnJheVByb3RvdHlwZSQsIFRBRywge1xuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpc1tUWVBFRF9BUlJBWV07IH1cbiAgfSk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1zdGF0ZW1lbnRzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSwgQllURVMsIHdyYXBwZXIsIENMQU1QRUQpIHtcbiAgICBDTEFNUEVEID0gISFDTEFNUEVEO1xuICAgIHZhciBOQU1FID0gS0VZICsgKENMQU1QRUQgPyAnQ2xhbXBlZCcgOiAnJykgKyAnQXJyYXknO1xuICAgIHZhciBHRVRURVIgPSAnZ2V0JyArIEtFWTtcbiAgICB2YXIgU0VUVEVSID0gJ3NldCcgKyBLRVk7XG4gICAgdmFyIFR5cGVkQXJyYXkgPSBnbG9iYWxbTkFNRV07XG4gICAgdmFyIEJhc2UgPSBUeXBlZEFycmF5IHx8IHt9O1xuICAgIHZhciBUQUMgPSBUeXBlZEFycmF5ICYmIGdldFByb3RvdHlwZU9mKFR5cGVkQXJyYXkpO1xuICAgIHZhciBGT1JDRUQgPSAhVHlwZWRBcnJheSB8fCAhJHR5cGVkLkFCVjtcbiAgICB2YXIgTyA9IHt9O1xuICAgIHZhciBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheSAmJiBUeXBlZEFycmF5W1BST1RPVFlQRV07XG4gICAgdmFyIGdldHRlciA9IGZ1bmN0aW9uICh0aGF0LCBpbmRleCkge1xuICAgICAgdmFyIGRhdGEgPSB0aGF0Ll9kO1xuICAgICAgcmV0dXJuIGRhdGEudltHRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIExJVFRMRV9FTkRJQU4pO1xuICAgIH07XG4gICAgdmFyIHNldHRlciA9IGZ1bmN0aW9uICh0aGF0LCBpbmRleCwgdmFsdWUpIHtcbiAgICAgIHZhciBkYXRhID0gdGhhdC5fZDtcbiAgICAgIGlmIChDTEFNUEVEKSB2YWx1ZSA9ICh2YWx1ZSA9IE1hdGgucm91bmQodmFsdWUpKSA8IDAgPyAwIDogdmFsdWUgPiAweGZmID8gMHhmZiA6IHZhbHVlICYgMHhmZjtcbiAgICAgIGRhdGEudltTRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIHZhbHVlLCBMSVRUTEVfRU5ESUFOKTtcbiAgICB9O1xuICAgIHZhciBhZGRFbGVtZW50ID0gZnVuY3Rpb24gKHRoYXQsIGluZGV4KSB7XG4gICAgICBkUCh0aGF0LCBpbmRleCwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gZ2V0dGVyKHRoaXMsIGluZGV4KTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICByZXR1cm4gc2V0dGVyKHRoaXMsIGluZGV4LCB2YWx1ZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgIH07XG4gICAgaWYgKEZPUkNFRCkge1xuICAgICAgVHlwZWRBcnJheSA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGRhdGEsICRvZmZzZXQsICRsZW5ndGgpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGF0LCBUeXBlZEFycmF5LCBOQU1FLCAnX2QnKTtcbiAgICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgIHZhciBidWZmZXIsIGJ5dGVMZW5ndGgsIGxlbmd0aCwga2xhc3M7XG4gICAgICAgIGlmICghaXNPYmplY3QoZGF0YSkpIHtcbiAgICAgICAgICBsZW5ndGggPSB0b0luZGV4KGRhdGEpO1xuICAgICAgICAgIGJ5dGVMZW5ndGggPSBsZW5ndGggKiBCWVRFUztcbiAgICAgICAgICBidWZmZXIgPSBuZXcgJEFycmF5QnVmZmVyKGJ5dGVMZW5ndGgpO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGEgaW5zdGFuY2VvZiAkQXJyYXlCdWZmZXIgfHwgKGtsYXNzID0gY2xhc3NvZihkYXRhKSkgPT0gQVJSQVlfQlVGRkVSIHx8IGtsYXNzID09IFNIQVJFRF9CVUZGRVIpIHtcbiAgICAgICAgICBidWZmZXIgPSBkYXRhO1xuICAgICAgICAgIG9mZnNldCA9IHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKTtcbiAgICAgICAgICB2YXIgJGxlbiA9IGRhdGEuYnl0ZUxlbmd0aDtcbiAgICAgICAgICBpZiAoJGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoJGxlbiAlIEJZVEVTKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gJGxlbiAtIG9mZnNldDtcbiAgICAgICAgICAgIGlmIChieXRlTGVuZ3RoIDwgMCkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gdG9MZW5ndGgoJGxlbmd0aCkgKiBCWVRFUztcbiAgICAgICAgICAgIGlmIChieXRlTGVuZ3RoICsgb2Zmc2V0ID4gJGxlbikgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsZW5ndGggPSBieXRlTGVuZ3RoIC8gQllURVM7XG4gICAgICAgIH0gZWxzZSBpZiAoVFlQRURfQVJSQVkgaW4gZGF0YSkge1xuICAgICAgICAgIHJldHVybiBmcm9tTGlzdChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gJGZyb20uY2FsbChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBoaWRlKHRoYXQsICdfZCcsIHtcbiAgICAgICAgICBiOiBidWZmZXIsXG4gICAgICAgICAgbzogb2Zmc2V0LFxuICAgICAgICAgIGw6IGJ5dGVMZW5ndGgsXG4gICAgICAgICAgZTogbGVuZ3RoLFxuICAgICAgICAgIHY6IG5ldyAkRGF0YVZpZXcoYnVmZmVyKVxuICAgICAgICB9KTtcbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSBhZGRFbGVtZW50KHRoYXQsIGluZGV4KyspO1xuICAgICAgfSk7XG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gY3JlYXRlKCRUeXBlZEFycmF5UHJvdG90eXBlJCk7XG4gICAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsICdjb25zdHJ1Y3RvcicsIFR5cGVkQXJyYXkpO1xuICAgIH0gZWxzZSBpZiAoIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAgIFR5cGVkQXJyYXkoMSk7XG4gICAgfSkgfHwgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5ldyBUeXBlZEFycmF5KC0xKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICB9KSB8fCAhJGl0ZXJEZXRlY3QoZnVuY3Rpb24gKGl0ZXIpIHtcbiAgICAgIG5ldyBUeXBlZEFycmF5KCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgICBuZXcgVHlwZWRBcnJheShudWxsKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KDEuNSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgICBuZXcgVHlwZWRBcnJheShpdGVyKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICB9LCB0cnVlKSkge1xuICAgICAgVHlwZWRBcnJheSA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGRhdGEsICRvZmZzZXQsICRsZW5ndGgpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGF0LCBUeXBlZEFycmF5LCBOQU1FKTtcbiAgICAgICAgdmFyIGtsYXNzO1xuICAgICAgICAvLyBgd3NgIG1vZHVsZSBidWcsIHRlbXBvcmFyaWx5IHJlbW92ZSB2YWxpZGF0aW9uIGxlbmd0aCBmb3IgVWludDhBcnJheVxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vd2Vic29ja2V0cy93cy9wdWxsLzY0NVxuICAgICAgICBpZiAoIWlzT2JqZWN0KGRhdGEpKSByZXR1cm4gbmV3IEJhc2UodG9JbmRleChkYXRhKSk7XG4gICAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgJEFycmF5QnVmZmVyIHx8IChrbGFzcyA9IGNsYXNzb2YoZGF0YSkpID09IEFSUkFZX0JVRkZFUiB8fCBrbGFzcyA9PSBTSEFSRURfQlVGRkVSKSB7XG4gICAgICAgICAgcmV0dXJuICRsZW5ndGggIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBuZXcgQmFzZShkYXRhLCB0b09mZnNldCgkb2Zmc2V0LCBCWVRFUyksICRsZW5ndGgpXG4gICAgICAgICAgICA6ICRvZmZzZXQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IG5ldyBCYXNlKGRhdGEsIHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKSlcbiAgICAgICAgICAgICAgOiBuZXcgQmFzZShkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoVFlQRURfQVJSQVkgaW4gZGF0YSkgcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICByZXR1cm4gJGZyb20uY2FsbChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgYXJyYXlGb3JFYWNoKFRBQyAhPT0gRnVuY3Rpb24ucHJvdG90eXBlID8gZ09QTihCYXNlKS5jb25jYXQoZ09QTihUQUMpKSA6IGdPUE4oQmFzZSksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCEoa2V5IGluIFR5cGVkQXJyYXkpKSBoaWRlKFR5cGVkQXJyYXksIGtleSwgQmFzZVtrZXldKTtcbiAgICAgIH0pO1xuICAgICAgVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gVHlwZWRBcnJheVByb3RvdHlwZTtcbiAgICAgIGlmICghTElCUkFSWSkgVHlwZWRBcnJheVByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFR5cGVkQXJyYXk7XG4gICAgfVxuICAgIHZhciAkbmF0aXZlSXRlcmF0b3IgPSBUeXBlZEFycmF5UHJvdG90eXBlW0lURVJBVE9SXTtcbiAgICB2YXIgQ09SUkVDVF9JVEVSX05BTUUgPSAhISRuYXRpdmVJdGVyYXRvclxuICAgICAgJiYgKCRuYXRpdmVJdGVyYXRvci5uYW1lID09ICd2YWx1ZXMnIHx8ICRuYXRpdmVJdGVyYXRvci5uYW1lID09IHVuZGVmaW5lZCk7XG4gICAgdmFyICRpdGVyYXRvciA9ICRpdGVyYXRvcnMudmFsdWVzO1xuICAgIGhpZGUoVHlwZWRBcnJheSwgVFlQRURfQ09OU1RSVUNUT1IsIHRydWUpO1xuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgVFlQRURfQVJSQVksIE5BTUUpO1xuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgVklFVywgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBERUZfQ09OU1RSVUNUT1IsIFR5cGVkQXJyYXkpO1xuXG4gICAgaWYgKENMQU1QRUQgPyBuZXcgVHlwZWRBcnJheSgxKVtUQUddICE9IE5BTUUgOiAhKFRBRyBpbiBUeXBlZEFycmF5UHJvdG90eXBlKSkge1xuICAgICAgZFAoVHlwZWRBcnJheVByb3RvdHlwZSwgVEFHLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gTkFNRTsgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT1tOQU1FXSA9IFR5cGVkQXJyYXk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChUeXBlZEFycmF5ICE9IEJhc2UpLCBPKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5TLCBOQU1FLCB7XG4gICAgICBCWVRFU19QRVJfRUxFTUVOVDogQllURVNcbiAgICB9KTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24gKCkgeyBCYXNlLm9mLmNhbGwoVHlwZWRBcnJheSwgMSk7IH0pLCBOQU1FLCB7XG4gICAgICBmcm9tOiAkZnJvbSxcbiAgICAgIG9mOiAkb2ZcbiAgICB9KTtcblxuICAgIGlmICghKEJZVEVTX1BFUl9FTEVNRU5UIGluIFR5cGVkQXJyYXlQcm90b3R5cGUpKSBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIEJZVEVTX1BFUl9FTEVNRU5ULCBCWVRFUyk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCwgTkFNRSwgcHJvdG8pO1xuXG4gICAgc2V0U3BlY2llcyhOQU1FKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogRk9SQ0VEX1NFVCwgTkFNRSwgeyBzZXQ6ICRzZXQgfSk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFDT1JSRUNUX0lURVJfTkFNRSwgTkFNRSwgJGl0ZXJhdG9ycyk7XG5cbiAgICBpZiAoIUxJQlJBUlkgJiYgVHlwZWRBcnJheVByb3RvdHlwZS50b1N0cmluZyAhPSBhcnJheVRvU3RyaW5nKSBUeXBlZEFycmF5UHJvdG90eXBlLnRvU3RyaW5nID0gYXJyYXlUb1N0cmluZztcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFR5cGVkQXJyYXkoMSkuc2xpY2UoKTtcbiAgICB9KSwgTkFNRSwgeyBzbGljZTogJHNsaWNlIH0pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIFsxLCAyXS50b0xvY2FsZVN0cmluZygpICE9IG5ldyBUeXBlZEFycmF5KFsxLCAyXSkudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgVHlwZWRBcnJheVByb3RvdHlwZS50b0xvY2FsZVN0cmluZy5jYWxsKFsxLCAyXSk7XG4gICAgfSkpLCBOQU1FLCB7IHRvTG9jYWxlU3RyaW5nOiAkdG9Mb2NhbGVTdHJpbmcgfSk7XG5cbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBDT1JSRUNUX0lURVJfTkFNRSA/ICRuYXRpdmVJdGVyYXRvciA6ICRpdGVyYXRvcjtcbiAgICBpZiAoIUxJQlJBUlkgJiYgIUNPUlJFQ1RfSVRFUl9OQU1FKSBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIElURVJBVE9SLCAkaXRlcmF0b3IpO1xuICB9O1xufSBlbHNlIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICR0eXBlZCA9IHJlcXVpcmUoJy4vX3R5cGVkJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciB0b0luZGV4ID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBhcnJheUZpbGwgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEFSUkFZX0JVRkZFUiA9ICdBcnJheUJ1ZmZlcic7XG52YXIgREFUQV9WSUVXID0gJ0RhdGFWaWV3JztcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcbnZhciBXUk9OR19MRU5HVEggPSAnV3JvbmcgbGVuZ3RoISc7XG52YXIgV1JPTkdfSU5ERVggPSAnV3JvbmcgaW5kZXghJztcbnZhciAkQXJyYXlCdWZmZXIgPSBnbG9iYWxbQVJSQVlfQlVGRkVSXTtcbnZhciAkRGF0YVZpZXcgPSBnbG9iYWxbREFUQV9WSUVXXTtcbnZhciBNYXRoID0gZ2xvYmFsLk1hdGg7XG52YXIgUmFuZ2VFcnJvciA9IGdsb2JhbC5SYW5nZUVycm9yO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNoYWRvdy1yZXN0cmljdGVkLW5hbWVzXG52YXIgSW5maW5pdHkgPSBnbG9iYWwuSW5maW5pdHk7XG52YXIgQmFzZUJ1ZmZlciA9ICRBcnJheUJ1ZmZlcjtcbnZhciBhYnMgPSBNYXRoLmFicztcbnZhciBwb3cgPSBNYXRoLnBvdztcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG52YXIgbG9nID0gTWF0aC5sb2c7XG52YXIgTE4yID0gTWF0aC5MTjI7XG52YXIgQlVGRkVSID0gJ2J1ZmZlcic7XG52YXIgQllURV9MRU5HVEggPSAnYnl0ZUxlbmd0aCc7XG52YXIgQllURV9PRkZTRVQgPSAnYnl0ZU9mZnNldCc7XG52YXIgJEJVRkZFUiA9IERFU0NSSVBUT1JTID8gJ19iJyA6IEJVRkZFUjtcbnZhciAkTEVOR1RIID0gREVTQ1JJUFRPUlMgPyAnX2wnIDogQllURV9MRU5HVEg7XG52YXIgJE9GRlNFVCA9IERFU0NSSVBUT1JTID8gJ19vJyA6IEJZVEVfT0ZGU0VUO1xuXG4vLyBJRUVFNzU0IGNvbnZlcnNpb25zIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvaWVlZTc1NFxuZnVuY3Rpb24gcGFja0lFRUU3NTQodmFsdWUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgYnVmZmVyID0gbmV3IEFycmF5KG5CeXRlcyk7XG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxO1xuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMTtcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxO1xuICB2YXIgcnQgPSBtTGVuID09PSAyMyA/IHBvdygyLCAtMjQpIC0gcG93KDIsIC03NykgOiAwO1xuICB2YXIgaSA9IDA7XG4gIHZhciBzID0gdmFsdWUgPCAwIHx8IHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDAgPyAxIDogMDtcbiAgdmFyIGUsIG0sIGM7XG4gIHZhbHVlID0gYWJzKHZhbHVlKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICBpZiAodmFsdWUgIT0gdmFsdWUgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIG0gPSB2YWx1ZSAhPSB2YWx1ZSA/IDEgOiAwO1xuICAgIGUgPSBlTWF4O1xuICB9IGVsc2Uge1xuICAgIGUgPSBmbG9vcihsb2codmFsdWUpIC8gTE4yKTtcbiAgICBpZiAodmFsdWUgKiAoYyA9IHBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tO1xuICAgICAgYyAqPSAyO1xuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBwb3coMiwgMSAtIGVCaWFzKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKys7XG4gICAgICBjIC89IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDA7XG4gICAgICBlID0gZU1heDtcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogcG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogcG93KDIsIGVCaWFzIC0gMSkgKiBwb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW2krK10gPSBtICYgMjU1LCBtIC89IDI1NiwgbUxlbiAtPSA4KTtcbiAgZSA9IGUgPDwgbUxlbiB8IG07XG4gIGVMZW4gKz0gbUxlbjtcbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbaSsrXSA9IGUgJiAyNTUsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xuICBidWZmZXJbLS1pXSB8PSBzICogMTI4O1xuICByZXR1cm4gYnVmZmVyO1xufVxuZnVuY3Rpb24gdW5wYWNrSUVFRTc1NChidWZmZXIsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMTtcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDE7XG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMTtcbiAgdmFyIG5CaXRzID0gZUxlbiAtIDc7XG4gIHZhciBpID0gbkJ5dGVzIC0gMTtcbiAgdmFyIHMgPSBidWZmZXJbaS0tXTtcbiAgdmFyIGUgPSBzICYgMTI3O1xuICB2YXIgbTtcbiAgcyA+Pj0gNztcbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbaV0sIGktLSwgbkJpdHMgLT0gOCk7XG4gIG0gPSBlICYgKDEgPDwgLW5CaXRzKSAtIDE7XG4gIGUgPj49IC1uQml0cztcbiAgbkJpdHMgKz0gbUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbaV0sIGktLSwgbkJpdHMgLT0gOCk7XG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhcztcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiBzID8gLUluZmluaXR5IDogSW5maW5pdHk7XG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBwb3coMiwgbUxlbik7XG4gICAgZSA9IGUgLSBlQmlhcztcbiAgfSByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIHBvdygyLCBlIC0gbUxlbik7XG59XG5cbmZ1bmN0aW9uIHVucGFja0kzMihieXRlcykge1xuICByZXR1cm4gYnl0ZXNbM10gPDwgMjQgfCBieXRlc1syXSA8PCAxNiB8IGJ5dGVzWzFdIDw8IDggfCBieXRlc1swXTtcbn1cbmZ1bmN0aW9uIHBhY2tJOChpdCkge1xuICByZXR1cm4gW2l0ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrSTE2KGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmLCBpdCA+PiA4ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrSTMyKGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmLCBpdCA+PiA4ICYgMHhmZiwgaXQgPj4gMTYgJiAweGZmLCBpdCA+PiAyNCAmIDB4ZmZdO1xufVxuZnVuY3Rpb24gcGFja0Y2NChpdCkge1xuICByZXR1cm4gcGFja0lFRUU3NTQoaXQsIDUyLCA4KTtcbn1cbmZ1bmN0aW9uIHBhY2tGMzIoaXQpIHtcbiAgcmV0dXJuIHBhY2tJRUVFNzU0KGl0LCAyMywgNCk7XG59XG5cbmZ1bmN0aW9uIGFkZEdldHRlcihDLCBrZXksIGludGVybmFsKSB7XG4gIGRQKENbUFJPVE9UWVBFXSwga2V5LCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpc1tpbnRlcm5hbF07IH0gfSk7XG59XG5cbmZ1bmN0aW9uIGdldCh2aWV3LCBieXRlcywgaW5kZXgsIGlzTGl0dGxlRW5kaWFuKSB7XG4gIHZhciBudW1JbmRleCA9ICtpbmRleDtcbiAgdmFyIGludEluZGV4ID0gdG9JbmRleChudW1JbmRleCk7XG4gIGlmIChpbnRJbmRleCArIGJ5dGVzID4gdmlld1skTEVOR1RIXSkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19JTkRFWCk7XG4gIHZhciBzdG9yZSA9IHZpZXdbJEJVRkZFUl0uX2I7XG4gIHZhciBzdGFydCA9IGludEluZGV4ICsgdmlld1skT0ZGU0VUXTtcbiAgdmFyIHBhY2sgPSBzdG9yZS5zbGljZShzdGFydCwgc3RhcnQgKyBieXRlcyk7XG4gIHJldHVybiBpc0xpdHRsZUVuZGlhbiA/IHBhY2sgOiBwYWNrLnJldmVyc2UoKTtcbn1cbmZ1bmN0aW9uIHNldCh2aWV3LCBieXRlcywgaW5kZXgsIGNvbnZlcnNpb24sIHZhbHVlLCBpc0xpdHRsZUVuZGlhbikge1xuICB2YXIgbnVtSW5kZXggPSAraW5kZXg7XG4gIHZhciBpbnRJbmRleCA9IHRvSW5kZXgobnVtSW5kZXgpO1xuICBpZiAoaW50SW5kZXggKyBieXRlcyA+IHZpZXdbJExFTkdUSF0pIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfSU5ERVgpO1xuICB2YXIgc3RvcmUgPSB2aWV3WyRCVUZGRVJdLl9iO1xuICB2YXIgc3RhcnQgPSBpbnRJbmRleCArIHZpZXdbJE9GRlNFVF07XG4gIHZhciBwYWNrID0gY29udmVyc2lvbigrdmFsdWUpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHN0b3JlW3N0YXJ0ICsgaV0gPSBwYWNrW2lzTGl0dGxlRW5kaWFuID8gaSA6IGJ5dGVzIC0gaSAtIDFdO1xufVxuXG5pZiAoISR0eXBlZC5BQlYpIHtcbiAgJEFycmF5QnVmZmVyID0gZnVuY3Rpb24gQXJyYXlCdWZmZXIobGVuZ3RoKSB7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkQXJyYXlCdWZmZXIsIEFSUkFZX0JVRkZFUik7XG4gICAgdmFyIGJ5dGVMZW5ndGggPSB0b0luZGV4KGxlbmd0aCk7XG4gICAgdGhpcy5fYiA9IGFycmF5RmlsbC5jYWxsKG5ldyBBcnJheShieXRlTGVuZ3RoKSwgMCk7XG4gICAgdGhpc1skTEVOR1RIXSA9IGJ5dGVMZW5ndGg7XG4gIH07XG5cbiAgJERhdGFWaWV3ID0gZnVuY3Rpb24gRGF0YVZpZXcoYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSB7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkRGF0YVZpZXcsIERBVEFfVklFVyk7XG4gICAgYW5JbnN0YW5jZShidWZmZXIsICRBcnJheUJ1ZmZlciwgREFUQV9WSUVXKTtcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYnVmZmVyWyRMRU5HVEhdO1xuICAgIHZhciBvZmZzZXQgPSB0b0ludGVnZXIoYnl0ZU9mZnNldCk7XG4gICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gYnVmZmVyTGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKCdXcm9uZyBvZmZzZXQhJyk7XG4gICAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPT09IHVuZGVmaW5lZCA/IGJ1ZmZlckxlbmd0aCAtIG9mZnNldCA6IHRvTGVuZ3RoKGJ5dGVMZW5ndGgpO1xuICAgIGlmIChvZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyTGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgdGhpc1skQlVGRkVSXSA9IGJ1ZmZlcjtcbiAgICB0aGlzWyRPRkZTRVRdID0gb2Zmc2V0O1xuICAgIHRoaXNbJExFTkdUSF0gPSBieXRlTGVuZ3RoO1xuICB9O1xuXG4gIGlmIChERVNDUklQVE9SUykge1xuICAgIGFkZEdldHRlcigkQXJyYXlCdWZmZXIsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCVUZGRVIsICdfYicpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCWVRFX09GRlNFVCwgJ19vJyk7XG4gIH1cblxuICByZWRlZmluZUFsbCgkRGF0YVZpZXdbUFJPVE9UWVBFXSwge1xuICAgIGdldEludDg6IGZ1bmN0aW9uIGdldEludDgoYnl0ZU9mZnNldCkge1xuICAgICAgcmV0dXJuIGdldCh0aGlzLCAxLCBieXRlT2Zmc2V0KVswXSA8PCAyNCA+PiAyNDtcbiAgICB9LFxuICAgIGdldFVpbnQ4OiBmdW5jdGlvbiBnZXRVaW50OChieXRlT2Zmc2V0KSB7XG4gICAgICByZXR1cm4gZ2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQpWzBdO1xuICAgIH0sXG4gICAgZ2V0SW50MTY6IGZ1bmN0aW9uIGdldEludDE2KGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHZhciBieXRlcyA9IGdldCh0aGlzLCAyLCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pO1xuICAgICAgcmV0dXJuIChieXRlc1sxXSA8PCA4IHwgYnl0ZXNbMF0pIDw8IDE2ID4+IDE2O1xuICAgIH0sXG4gICAgZ2V0VWludDE2OiBmdW5jdGlvbiBnZXRVaW50MTYoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgdmFyIGJ5dGVzID0gZ2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSk7XG4gICAgICByZXR1cm4gYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xuICAgIH0sXG4gICAgZ2V0SW50MzI6IGZ1bmN0aW9uIGdldEludDMyKGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJMzIoZ2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSkpO1xuICAgIH0sXG4gICAgZ2V0VWludDMyOiBmdW5jdGlvbiBnZXRVaW50MzIoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0kzMihnZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKSkgPj4+IDA7XG4gICAgfSxcbiAgICBnZXRGbG9hdDMyOiBmdW5jdGlvbiBnZXRGbG9hdDMyKGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCAyMywgNCk7XG4gICAgfSxcbiAgICBnZXRGbG9hdDY0OiBmdW5jdGlvbiBnZXRGbG9hdDY0KGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA4LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCA1MiwgOCk7XG4gICAgfSxcbiAgICBzZXRJbnQ4OiBmdW5jdGlvbiBzZXRJbnQ4KGJ5dGVPZmZzZXQsIHZhbHVlKSB7XG4gICAgICBzZXQodGhpcywgMSwgYnl0ZU9mZnNldCwgcGFja0k4LCB2YWx1ZSk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgIHNldCh0aGlzLCAxLCBieXRlT2Zmc2V0LCBwYWNrSTgsIHZhbHVlKTtcbiAgICB9LFxuICAgIHNldEludDE2OiBmdW5jdGlvbiBzZXRJbnQxNihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIHBhY2tJMTYsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0VWludDE2OiBmdW5jdGlvbiBzZXRVaW50MTYoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCAyLCBieXRlT2Zmc2V0LCBwYWNrSTE2LCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEludDMyOiBmdW5jdGlvbiBzZXRJbnQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIHBhY2tJMzIsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0VWludDMyOiBmdW5jdGlvbiBzZXRVaW50MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrSTMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEZsb2F0MzI6IGZ1bmN0aW9uIHNldEZsb2F0MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrRjMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEZsb2F0NjQ6IGZ1bmN0aW9uIHNldEZsb2F0NjQoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA4LCBieXRlT2Zmc2V0LCBwYWNrRjY0LCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgaWYgKCFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgJEFycmF5QnVmZmVyKDEpO1xuICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoLTEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICB9KSB8fCBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3ICRBcnJheUJ1ZmZlcigpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoMS41KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICBuZXcgJEFycmF5QnVmZmVyKE5hTik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgcmV0dXJuICRBcnJheUJ1ZmZlci5uYW1lICE9IEFSUkFZX0JVRkZFUjtcbiAgfSkpIHtcbiAgICAkQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhpcywgJEFycmF5QnVmZmVyKTtcbiAgICAgIHJldHVybiBuZXcgQmFzZUJ1ZmZlcih0b0luZGV4KGxlbmd0aCkpO1xuICAgIH07XG4gICAgdmFyIEFycmF5QnVmZmVyUHJvdG8gPSAkQXJyYXlCdWZmZXJbUFJPVE9UWVBFXSA9IEJhc2VCdWZmZXJbUFJPVE9UWVBFXTtcbiAgICBmb3IgKHZhciBrZXlzID0gZ09QTihCYXNlQnVmZmVyKSwgaiA9IDAsIGtleTsga2V5cy5sZW5ndGggPiBqOykge1xuICAgICAgaWYgKCEoKGtleSA9IGtleXNbaisrXSkgaW4gJEFycmF5QnVmZmVyKSkgaGlkZSgkQXJyYXlCdWZmZXIsIGtleSwgQmFzZUJ1ZmZlcltrZXldKTtcbiAgICB9XG4gICAgaWYgKCFMSUJSQVJZKSBBcnJheUJ1ZmZlclByb3RvLmNvbnN0cnVjdG9yID0gJEFycmF5QnVmZmVyO1xuICB9XG4gIC8vIGlPUyBTYWZhcmkgNy54IGJ1Z1xuICB2YXIgdmlldyA9IG5ldyAkRGF0YVZpZXcobmV3ICRBcnJheUJ1ZmZlcigyKSk7XG4gIHZhciAkc2V0SW50OCA9ICREYXRhVmlld1tQUk9UT1RZUEVdLnNldEludDg7XG4gIHZpZXcuc2V0SW50OCgwLCAyMTQ3NDgzNjQ4KTtcbiAgdmlldy5zZXRJbnQ4KDEsIDIxNDc0ODM2NDkpO1xuICBpZiAodmlldy5nZXRJbnQ4KDApIHx8ICF2aWV3LmdldEludDgoMSkpIHJlZGVmaW5lQWxsKCREYXRhVmlld1tQUk9UT1RZUEVdLCB7XG4gICAgc2V0SW50ODogZnVuY3Rpb24gc2V0SW50OChieXRlT2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgJHNldEludDguY2FsbCh0aGlzLCBieXRlT2Zmc2V0LCB2YWx1ZSA8PCAyNCA+PiAyNCk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgICRzZXRJbnQ4LmNhbGwodGhpcywgYnl0ZU9mZnNldCwgdmFsdWUgPDwgMjQgPj4gMjQpO1xuICAgIH1cbiAgfSwgdHJ1ZSk7XG59XG5zZXRUb1N0cmluZ1RhZygkQXJyYXlCdWZmZXIsIEFSUkFZX0JVRkZFUik7XG5zZXRUb1N0cmluZ1RhZygkRGF0YVZpZXcsIERBVEFfVklFVyk7XG5oaWRlKCREYXRhVmlld1tQUk9UT1RZUEVdLCAkdHlwZWQuVklFVywgdHJ1ZSk7XG5leHBvcnRzW0FSUkFZX0JVRkZFUl0gPSAkQXJyYXlCdWZmZXI7XG5leHBvcnRzW0RBVEFfVklFV10gPSAkRGF0YVZpZXc7XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciBUWVBFRCA9IHVpZCgndHlwZWRfYXJyYXknKTtcbnZhciBWSUVXID0gdWlkKCd2aWV3Jyk7XG52YXIgQUJWID0gISEoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGdsb2JhbC5EYXRhVmlldyk7XG52YXIgQ09OU1RSID0gQUJWO1xudmFyIGkgPSAwO1xudmFyIGwgPSA5O1xudmFyIFR5cGVkO1xuXG52YXIgVHlwZWRBcnJheUNvbnN0cnVjdG9ycyA9IChcbiAgJ0ludDhBcnJheSxVaW50OEFycmF5LFVpbnQ4Q2xhbXBlZEFycmF5LEludDE2QXJyYXksVWludDE2QXJyYXksSW50MzJBcnJheSxVaW50MzJBcnJheSxGbG9hdDMyQXJyYXksRmxvYXQ2NEFycmF5J1xuKS5zcGxpdCgnLCcpO1xuXG53aGlsZSAoaSA8IGwpIHtcbiAgaWYgKFR5cGVkID0gZ2xvYmFsW1R5cGVkQXJyYXlDb25zdHJ1Y3RvcnNbaSsrXV0pIHtcbiAgICBoaWRlKFR5cGVkLnByb3RvdHlwZSwgVFlQRUQsIHRydWUpO1xuICAgIGhpZGUoVHlwZWQucHJvdG90eXBlLCBWSUVXLCB0cnVlKTtcbiAgfSBlbHNlIENPTlNUUiA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQUJWOiBBQlYsXG4gIENPTlNUUjogQ09OU1RSLFxuICBUWVBFRDogVFlQRUQsXG4gIFZJRVc6IFZJRVdcbn07XG4iLCJ2YXIgaWQgPSAwO1xudmFyIHB4ID0gTWF0aC5yYW5kb20oKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBuYXZpZ2F0b3IgPSBnbG9iYWwubmF2aWdhdG9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5hdmlnYXRvciAmJiBuYXZpZ2F0b3IudXNlckFnZW50IHx8ICcnO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgVFlQRSkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSB8fCBpdC5fdCAhPT0gVFlQRSkgdGhyb3cgVHlwZUVycm9yKCdJbmNvbXBhdGlibGUgcmVjZWl2ZXIsICcgKyBUWVBFICsgJyByZXF1aXJlZCEnKTtcbiAgcmV0dXJuIGl0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgd2tzRXh0ID0gcmVxdWlyZSgnLi9fd2tzLWV4dCcpO1xudmFyIGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgdmFyICRTeW1ib2wgPSBjb3JlLlN5bWJvbCB8fCAoY29yZS5TeW1ib2wgPSBMSUJSQVJZID8ge30gOiBnbG9iYWwuU3ltYm9sIHx8IHt9KTtcbiAgaWYgKG5hbWUuY2hhckF0KDApICE9ICdfJyAmJiAhKG5hbWUgaW4gJFN5bWJvbCkpIGRlZmluZVByb3BlcnR5KCRTeW1ib2wsIG5hbWUsIHsgdmFsdWU6IHdrc0V4dC5mKG5hbWUpIH0pO1xufTtcbiIsImV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX3drcycpO1xuIiwidmFyIHN0b3JlID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ3drcycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLlN5bWJvbDtcbnZhciBVU0VfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PSAnZnVuY3Rpb24nO1xuXG52YXIgJGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFVTRV9TWU1CT0wgJiYgU3ltYm9sW25hbWVdIHx8IChVU0VfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuXG4kZXhwb3J0cy5zdG9yZSA9IHN0b3JlO1xuIiwidmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29yZScpLmdldEl0ZXJhdG9yTWV0aG9kID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmIChpdCAhPSB1bmRlZmluZWQpIHJldHVybiBpdFtJVEVSQVRPUl1cbiAgICB8fCBpdFsnQEBpdGVyYXRvciddXG4gICAgfHwgSXRlcmF0b3JzW2NsYXNzb2YoaXQpXTtcbn07XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vYmVuamFtaW5nci9SZXhFeHAuZXNjYXBlXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRyZSA9IHJlcXVpcmUoJy4vX3JlcGxhY2VyJykoL1tcXFxcXiQqKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVnRXhwJywgeyBlc2NhcGU6IGZ1bmN0aW9uIGVzY2FwZShpdCkgeyByZXR1cm4gJHJlKGl0KTsgfSB9KTtcbiIsIi8vIDIyLjEuMy4zIEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluKHRhcmdldCwgc3RhcnQsIGVuZCA9IHRoaXMubGVuZ3RoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdBcnJheScsIHsgY29weVdpdGhpbjogcmVxdWlyZSgnLi9fYXJyYXktY29weS13aXRoaW4nKSB9KTtcblxucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoJ2NvcHlXaXRoaW4nKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGV2ZXJ5ID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDQpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uZXZlcnksIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy41IC8gMTUuNC40LjE2IEFycmF5LnByb3RvdHlwZS5ldmVyeShjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGV2ZXJ5KHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiLy8gMjIuMS4zLjYgQXJyYXkucHJvdG90eXBlLmZpbGwodmFsdWUsIHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5JywgeyBmaWxsOiByZXF1aXJlKCcuL19hcnJheS1maWxsJykgfSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdmaWxsJyk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmaWx0ZXIgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMik7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5maWx0ZXIsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy43IC8gMTUuNC40LjIwIEFycmF5LnByb3RvdHlwZS5maWx0ZXIoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGZpbHRlcih0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy45IEFycmF5LnByb3RvdHlwZS5maW5kSW5kZXgocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZmluZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg2KTtcbnZhciBLRVkgPSAnZmluZEluZGV4JztcbnZhciBmb3JjZWQgPSB0cnVlO1xuLy8gU2hvdWxkbid0IHNraXAgaG9sZXNcbmlmIChLRVkgaW4gW10pIEFycmF5KDEpW0tFWV0oZnVuY3Rpb24gKCkgeyBmb3JjZWQgPSBmYWxzZTsgfSk7XG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZvcmNlZCwgJ0FycmF5Jywge1xuICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChjYWxsYmFja2ZuIC8qICwgdGhhdCA9IHVuZGVmaW5lZCAqLykge1xuICAgIHJldHVybiAkZmluZCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoS0VZKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy44IEFycmF5LnByb3RvdHlwZS5maW5kKHByZWRpY2F0ZSwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZpbmQgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoNSk7XG52YXIgS0VZID0gJ2ZpbmQnO1xudmFyIGZvcmNlZCA9IHRydWU7XG4vLyBTaG91bGRuJ3Qgc2tpcCBob2xlc1xuaWYgKEtFWSBpbiBbXSkgQXJyYXkoMSlbS0VZXShmdW5jdGlvbiAoKSB7IGZvcmNlZCA9IGZhbHNlOyB9KTtcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogZm9yY2VkLCAnQXJyYXknLCB7XG4gIGZpbmQ6IGZ1bmN0aW9uIGZpbmQoY2FsbGJhY2tmbiAvKiAsIHRoYXQgPSB1bmRlZmluZWQgKi8pIHtcbiAgICByZXR1cm4gJGZpbmQodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICB9XG59KTtcbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKEtFWSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmb3JFYWNoID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDApO1xudmFyIFNUUklDVCA9IHJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5mb3JFYWNoLCB0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhU1RSSUNULCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMCAvIDE1LjQuNC4xOCBBcnJheS5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgcmV0dXJuICRmb3JFYWNoKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGNyZWF0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fY3JlYXRlLXByb3BlcnR5Jyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikgeyBBcnJheS5mcm9tKGl0ZXIpOyB9KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMSBBcnJheS5mcm9tKGFycmF5TGlrZSwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gIGZyb206IGZ1bmN0aW9uIGZyb20oYXJyYXlMaWtlIC8qICwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQgKi8pIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KGFycmF5TGlrZSk7XG4gICAgdmFyIEMgPSB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nID8gdGhpcyA6IEFycmF5O1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgbWFwZm4gPSBhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDtcbiAgICB2YXIgbWFwcGluZyA9IG1hcGZuICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgaXRlckZuID0gZ2V0SXRlckZuKE8pO1xuICAgIHZhciBsZW5ndGgsIHJlc3VsdCwgc3RlcCwgaXRlcmF0b3I7XG4gICAgaWYgKG1hcHBpbmcpIG1hcGZuID0gY3R4KG1hcGZuLCBhTGVuID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCwgMik7XG4gICAgLy8gaWYgb2JqZWN0IGlzbid0IGl0ZXJhYmxlIG9yIGl0J3MgYXJyYXkgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yIC0gdXNlIHNpbXBsZSBjYXNlXG4gICAgaWYgKGl0ZXJGbiAhPSB1bmRlZmluZWQgJiYgIShDID09IEFycmF5ICYmIGlzQXJyYXlJdGVyKGl0ZXJGbikpKSB7XG4gICAgICBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoTyksIHJlc3VsdCA9IG5ldyBDKCk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaW5kZXgrKykge1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gY2FsbChpdGVyYXRvciwgbWFwZm4sIFtzdGVwLnZhbHVlLCBpbmRleF0sIHRydWUpIDogc3RlcC52YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICAgIGZvciAocmVzdWx0ID0gbmV3IEMobGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICAgICAgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgbWFwcGluZyA/IG1hcGZuKE9baW5kZXhdLCBpbmRleCkgOiBPW2luZGV4XSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5sZW5ndGggPSBpbmRleDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKTtcbnZhciAkbmF0aXZlID0gW10uaW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0uaW5kZXhPZigxLCAtMCkgPCAwO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChORUdBVElWRV9aRVJPIHx8ICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoJG5hdGl2ZSkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMSAvIDE1LjQuNC4xNCBBcnJheS5wcm90b3R5cGUuaW5kZXhPZihzZWFyY2hFbGVtZW50IFssIGZyb21JbmRleF0pXG4gIGluZGV4T2Y6IGZ1bmN0aW9uIGluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gTkVHQVRJVkVfWkVST1xuICAgICAgLy8gY29udmVydCAtMCB0byArMFxuICAgICAgPyAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMFxuICAgICAgOiAkaW5kZXhPZih0aGlzLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIi8vIDIyLjEuMi4yIC8gMTUuNC4zLjIgQXJyYXkuaXNBcnJheShhcmcpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0FycmF5JywgeyBpc0FycmF5OiByZXF1aXJlKCcuL19pcy1hcnJheScpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKTtcbnZhciBzdGVwID0gcmVxdWlyZSgnLi9faXRlci1zdGVwJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xuXG4vLyAyMi4xLjMuNCBBcnJheS5wcm90b3R5cGUuZW50cmllcygpXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmtleXMoKVxuLy8gMjIuMS4zLjI5IEFycmF5LnByb3RvdHlwZS52YWx1ZXMoKVxuLy8gMjIuMS4zLjMwIEFycmF5LnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIga2luZCA9IHRoaXMuX2s7XG4gIHZhciBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYgKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKSB7XG4gICAgdGhpcy5fdCA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gc3RlcCgxKTtcbiAgfVxuICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGluZGV4KTtcbiAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy4xMyBBcnJheS5wcm90b3R5cGUuam9pbihzZXBhcmF0b3IpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBhcnJheUpvaW4gPSBbXS5qb2luO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2Ugc3RyaW5nc1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAocmVxdWlyZSgnLi9faW9iamVjdCcpICE9IE9iamVjdCB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKGFycmF5Sm9pbikpLCAnQXJyYXknLCB7XG4gIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgcmV0dXJuIGFycmF5Sm9pbi5jYWxsKHRvSU9iamVjdCh0aGlzKSwgc2VwYXJhdG9yID09PSB1bmRlZmluZWQgPyAnLCcgOiBzZXBhcmF0b3IpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyICRuYXRpdmUgPSBbXS5sYXN0SW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0ubGFzdEluZGV4T2YoMSwgLTApIDwgMDtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoTkVHQVRJVkVfWkVSTyB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTQgLyAxNS40LjQuMTUgQXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgWywgZnJvbUluZGV4XSlcbiAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgLyogLCBmcm9tSW5kZXggPSBAWyotMV0gKi8pIHtcbiAgICAvLyBjb252ZXJ0IC0wIHRvICswXG4gICAgaWYgKE5FR0FUSVZFX1pFUk8pIHJldHVybiAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMDtcbiAgICB2YXIgTyA9IHRvSU9iamVjdCh0aGlzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IGxlbmd0aCAtIDE7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSBpbmRleCA9IE1hdGgubWluKGluZGV4LCB0b0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgaWYgKGluZGV4IDwgMCkgaW5kZXggPSBsZW5ndGggKyBpbmRleDtcbiAgICBmb3IgKDtpbmRleCA+PSAwOyBpbmRleC0tKSBpZiAoaW5kZXggaW4gTykgaWYgKE9baW5kZXhdID09PSBzZWFyY2hFbGVtZW50KSByZXR1cm4gaW5kZXggfHwgMDtcbiAgICByZXR1cm4gLTE7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkbWFwID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDEpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ubWFwLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTUgLyAxNS40LjQuMTkgQXJyYXkucHJvdG90eXBlLm1hcChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBtYXA6IGZ1bmN0aW9uIG1hcChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgIHJldHVybiAkbWFwKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpO1xuXG4vLyBXZWJLaXQgQXJyYXkub2YgaXNuJ3QgZ2VuZXJpY1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRigpIHsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gIShBcnJheS5vZi5jYWxsKEYpIGluc3RhbmNlb2YgRik7XG59KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMyBBcnJheS5vZiggLi4uaXRlbXMpXG4gIG9mOiBmdW5jdGlvbiBvZigvKiAuLi5hcmdzICovKSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyAodHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheSkoYUxlbik7XG4gICAgd2hpbGUgKGFMZW4gPiBpbmRleCkgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICByZXN1bHQubGVuZ3RoID0gYUxlbjtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHJlZHVjZSA9IHJlcXVpcmUoJy4vX2FycmF5LXJlZHVjZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ucmVkdWNlUmlnaHQsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOSAvIDE1LjQuNC4yMiBBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQoY2FsbGJhY2tmbiBbLCBpbml0aWFsVmFsdWVdKVxuICByZWR1Y2VSaWdodDogZnVuY3Rpb24gcmVkdWNlUmlnaHQoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgdHJ1ZSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcmVkdWNlID0gcmVxdWlyZSgnLi9fYXJyYXktcmVkdWNlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5yZWR1Y2UsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOCAvIDE1LjQuNC4yMSBBcnJheS5wcm90b3R5cGUucmVkdWNlKGNhbGxiYWNrZm4gWywgaW5pdGlhbFZhbHVlXSlcbiAgcmVkdWNlOiBmdW5jdGlvbiByZWR1Y2UoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgZmFsc2UpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaHRtbCA9IHJlcXVpcmUoJy4vX2h0bWwnKTtcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXJyYXlTbGljZSA9IFtdLnNsaWNlO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2UgRVMzIHN0cmluZ3MgYW5kIERPTSBvYmplY3RzXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICBpZiAoaHRtbCkgYXJyYXlTbGljZS5jYWxsKGh0bWwpO1xufSksICdBcnJheScsIHtcbiAgc2xpY2U6IGZ1bmN0aW9uIHNsaWNlKGJlZ2luLCBlbmQpIHtcbiAgICB2YXIgbGVuID0gdG9MZW5ndGgodGhpcy5sZW5ndGgpO1xuICAgIHZhciBrbGFzcyA9IGNvZih0aGlzKTtcbiAgICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IGVuZDtcbiAgICBpZiAoa2xhc3MgPT0gJ0FycmF5JykgcmV0dXJuIGFycmF5U2xpY2UuY2FsbCh0aGlzLCBiZWdpbiwgZW5kKTtcbiAgICB2YXIgc3RhcnQgPSB0b0Fic29sdXRlSW5kZXgoYmVnaW4sIGxlbik7XG4gICAgdmFyIHVwVG8gPSB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pO1xuICAgIHZhciBzaXplID0gdG9MZW5ndGgodXBUbyAtIHN0YXJ0KTtcbiAgICB2YXIgY2xvbmVkID0gbmV3IEFycmF5KHNpemUpO1xuICAgIHZhciBpID0gMDtcbiAgICBmb3IgKDsgaSA8IHNpemU7IGkrKykgY2xvbmVkW2ldID0ga2xhc3MgPT0gJ1N0cmluZydcbiAgICAgID8gdGhpcy5jaGFyQXQoc3RhcnQgKyBpKVxuICAgICAgOiB0aGlzW3N0YXJ0ICsgaV07XG4gICAgcmV0dXJuIGNsb25lZDtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRzb21lID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDMpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uc29tZSwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjIzIC8gMTUuNC40LjE3IEFycmF5LnByb3RvdHlwZS5zb21lKGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXG4gIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJHNvbWUodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciAkc29ydCA9IFtdLnNvcnQ7XG52YXIgdGVzdCA9IFsxLCAyLCAzXTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAvLyBJRTgtXG4gIHRlc3Quc29ydCh1bmRlZmluZWQpO1xufSkgfHwgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gVjggYnVnXG4gIHRlc3Quc29ydChudWxsKTtcbiAgLy8gT2xkIFdlYktpdFxufSkgfHwgIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKSgkc29ydCkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4yNSBBcnJheS5wcm90b3R5cGUuc29ydChjb21wYXJlZm4pXG4gIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZWZuKSB7XG4gICAgcmV0dXJuIGNvbXBhcmVmbiA9PT0gdW5kZWZpbmVkXG4gICAgICA/ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcykpXG4gICAgICA6ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcyksIGFGdW5jdGlvbihjb21wYXJlZm4pKTtcbiAgfVxufSk7XG4iLCJyZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdBcnJheScpO1xuIiwiLy8gMjAuMy4zLjEgLyAxNS45LjQuNCBEYXRlLm5vdygpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0RhdGUnLCB7IG5vdzogZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7IH0gfSk7XG4iLCIvLyAyMC4zLjQuMzYgLyAxNS45LjUuNDMgRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0lTT1N0cmluZyA9IHJlcXVpcmUoJy4vX2RhdGUtdG8taXNvLXN0cmluZycpO1xuXG4vLyBQaGFudG9tSlMgLyBvbGQgV2ViS2l0IGhhcyBhIGJyb2tlbiBpbXBsZW1lbnRhdGlvbnNcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICE9PSB0b0lTT1N0cmluZyksICdEYXRlJywge1xuICB0b0lTT1N0cmluZzogdG9JU09TdHJpbmdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgRGF0ZShOYU4pLnRvSlNPTigpICE9PSBudWxsXG4gICAgfHwgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoeyB0b0lTT1N0cmluZzogZnVuY3Rpb24gKCkgeyByZXR1cm4gMTsgfSB9KSAhPT0gMTtcbn0pLCAnRGF0ZScsIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gIHRvSlNPTjogZnVuY3Rpb24gdG9KU09OKGtleSkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIHB2ID0gdG9QcmltaXRpdmUoTyk7XG4gICAgcmV0dXJuIHR5cGVvZiBwdiA9PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUocHYpID8gbnVsbCA6IE8udG9JU09TdHJpbmcoKTtcbiAgfVxufSk7XG4iLCJ2YXIgVE9fUFJJTUlUSVZFID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvUHJpbWl0aXZlJyk7XG52YXIgcHJvdG8gPSBEYXRlLnByb3RvdHlwZTtcblxuaWYgKCEoVE9fUFJJTUlUSVZFIGluIHByb3RvKSkgcmVxdWlyZSgnLi9faGlkZScpKHByb3RvLCBUT19QUklNSVRJVkUsIHJlcXVpcmUoJy4vX2RhdGUtdG8tcHJpbWl0aXZlJykpO1xuIiwidmFyIERhdGVQcm90byA9IERhdGUucHJvdG90eXBlO1xudmFyIElOVkFMSURfREFURSA9ICdJbnZhbGlkIERhdGUnO1xudmFyIFRPX1NUUklORyA9ICd0b1N0cmluZyc7XG52YXIgJHRvU3RyaW5nID0gRGF0ZVByb3RvW1RPX1NUUklOR107XG52YXIgZ2V0VGltZSA9IERhdGVQcm90by5nZXRUaW1lO1xuaWYgKG5ldyBEYXRlKE5hTikgKyAnJyAhPSBJTlZBTElEX0RBVEUpIHtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShEYXRlUHJvdG8sIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgdmFyIHZhbHVlID0gZ2V0VGltZS5jYWxsKHRoaXMpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gJHRvU3RyaW5nLmNhbGwodGhpcykgOiBJTlZBTElEX0RBVEU7XG4gIH0pO1xufVxuIiwiLy8gMTkuMi4zLjIgLyAxNS4zLjQuNSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCh0aGlzQXJnLCBhcmdzLi4uKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdGdW5jdGlvbicsIHsgYmluZDogcmVxdWlyZSgnLi9fYmluZCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgSEFTX0lOU1RBTkNFID0gcmVxdWlyZSgnLi9fd2tzJykoJ2hhc0luc3RhbmNlJyk7XG52YXIgRnVuY3Rpb25Qcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbi8vIDE5LjIuMy42IEZ1bmN0aW9uLnByb3RvdHlwZVtAQGhhc0luc3RhbmNlXShWKVxuaWYgKCEoSEFTX0lOU1RBTkNFIGluIEZ1bmN0aW9uUHJvdG8pKSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mKEZ1bmN0aW9uUHJvdG8sIEhBU19JTlNUQU5DRSwgeyB2YWx1ZTogZnVuY3Rpb24gKE8pIHtcbiAgaWYgKHR5cGVvZiB0aGlzICE9ICdmdW5jdGlvbicgfHwgIWlzT2JqZWN0KE8pKSByZXR1cm4gZmFsc2U7XG4gIGlmICghaXNPYmplY3QodGhpcy5wcm90b3R5cGUpKSByZXR1cm4gTyBpbnN0YW5jZW9mIHRoaXM7XG4gIC8vIGZvciBlbnZpcm9ubWVudCB3L28gbmF0aXZlIGBAQGhhc0luc3RhbmNlYCBsb2dpYyBlbm91Z2ggYGluc3RhbmNlb2ZgLCBidXQgYWRkIHRoaXM6XG4gIHdoaWxlIChPID0gZ2V0UHJvdG90eXBlT2YoTykpIGlmICh0aGlzLnByb3RvdHlwZSA9PT0gTykgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn0gfSk7XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIEZQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbnZhciBuYW1lUkUgPSAvXlxccypmdW5jdGlvbiAoW14gKF0qKS87XG52YXIgTkFNRSA9ICduYW1lJztcblxuLy8gMTkuMi40LjIgbmFtZVxuTkFNRSBpbiBGUHJvdG8gfHwgcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiBkUChGUHJvdG8sIE5BTUUsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICgnJyArIHRoaXMpLm1hdGNoKG5hbWVSRSlbMV07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgc3Ryb25nID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi1zdHJvbmcnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBNQVAgPSAnTWFwJztcblxuLy8gMjMuMSBNYXAgT2JqZWN0c1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoTUFQLCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBNYXAoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4xLjMuNiBNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIHZhciBlbnRyeSA9IHN0cm9uZy5nZXRFbnRyeSh2YWxpZGF0ZSh0aGlzLCBNQVApLCBrZXkpO1xuICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeS52O1xuICB9LFxuICAvLyAyMy4xLjMuOSBNYXAucHJvdG90eXBlLnNldChrZXksIHZhbHVlKVxuICBzZXQ6IGZ1bmN0aW9uIHNldChrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgTUFQKSwga2V5ID09PSAwID8gMCA6IGtleSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcsIHRydWUpO1xuIiwiLy8gMjAuMi4yLjMgTWF0aC5hY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBsb2cxcCA9IHJlcXVpcmUoJy4vX21hdGgtbG9nMXAnKTtcbnZhciBzcXJ0ID0gTWF0aC5zcXJ0O1xudmFyICRhY29zaCA9IE1hdGguYWNvc2g7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISgkYWNvc2hcbiAgLy8gVjggYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzUwOVxuICAmJiBNYXRoLmZsb29yKCRhY29zaChOdW1iZXIuTUFYX1ZBTFVFKSkgPT0gNzEwXG4gIC8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hY29zaChJbmZpbml0eSkgLT4gTmFOXG4gICYmICRhY29zaChJbmZpbml0eSkgPT0gSW5maW5pdHlcbiksICdNYXRoJywge1xuICBhY29zaDogZnVuY3Rpb24gYWNvc2goeCkge1xuICAgIHJldHVybiAoeCA9ICt4KSA8IDEgPyBOYU4gOiB4ID4gOTQ5MDYyNjUuNjI0MjUxNTZcbiAgICAgID8gTWF0aC5sb2coeCkgKyBNYXRoLkxOMlxuICAgICAgOiBsb2cxcCh4IC0gMSArIHNxcnQoeCAtIDEpICogc3FydCh4ICsgMSkpO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi41IE1hdGguYXNpbmgoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGFzaW5oID0gTWF0aC5hc2luaDtcblxuZnVuY3Rpb24gYXNpbmgoeCkge1xuICByZXR1cm4gIWlzRmluaXRlKHggPSAreCkgfHwgeCA9PSAwID8geCA6IHggPCAwID8gLWFzaW5oKC14KSA6IE1hdGgubG9nKHggKyBNYXRoLnNxcnQoeCAqIHggKyAxKSk7XG59XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hc2luaCgwKSAtPiAtMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhc2luaCAmJiAxIC8gJGFzaW5oKDApID4gMCksICdNYXRoJywgeyBhc2luaDogYXNpbmggfSk7XG4iLCIvLyAyMC4yLjIuNyBNYXRoLmF0YW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhdGFuaCA9IE1hdGguYXRhbmg7XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hdGFuaCgtMCkgLT4gMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhdGFuaCAmJiAxIC8gJGF0YW5oKC0wKSA8IDApLCAnTWF0aCcsIHtcbiAgYXRhbmg6IGZ1bmN0aW9uIGF0YW5oKHgpIHtcbiAgICByZXR1cm4gKHggPSAreCkgPT0gMCA/IHggOiBNYXRoLmxvZygoMSArIHgpIC8gKDEgLSB4KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi45IE1hdGguY2JydCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBzaWduID0gcmVxdWlyZSgnLi9fbWF0aC1zaWduJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2JydDogZnVuY3Rpb24gY2JydCh4KSB7XG4gICAgcmV0dXJuIHNpZ24oeCA9ICt4KSAqIE1hdGgucG93KE1hdGguYWJzKHgpLCAxIC8gMyk7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjExIE1hdGguY2x6MzIoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2x6MzI6IGZ1bmN0aW9uIGNsejMyKHgpIHtcbiAgICByZXR1cm4gKHggPj4+PSAwKSA/IDMxIC0gTWF0aC5mbG9vcihNYXRoLmxvZyh4ICsgMC41KSAqIE1hdGguTE9HMkUpIDogMzI7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjEyIE1hdGguY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjb3NoOiBmdW5jdGlvbiBjb3NoKHgpIHtcbiAgICByZXR1cm4gKGV4cCh4ID0gK3gpICsgZXhwKC14KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xNCBNYXRoLmV4cG0xKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoJGV4cG0xICE9IE1hdGguZXhwbTEpLCAnTWF0aCcsIHsgZXhwbTE6ICRleHBtMSB9KTtcbiIsIi8vIDIwLjIuMi4xNiBNYXRoLmZyb3VuZCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywgeyBmcm91bmQ6IHJlcXVpcmUoJy4vX21hdGgtZnJvdW5kJykgfSk7XG4iLCIvLyAyMC4yLjIuMTcgTWF0aC5oeXBvdChbdmFsdWUxWywgdmFsdWUyWywg4oCmIF1dXSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYWJzID0gTWF0aC5hYnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgaHlwb3Q6IGZ1bmN0aW9uIGh5cG90KHZhbHVlMSwgdmFsdWUyKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICB2YXIgc3VtID0gMDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBsYXJnID0gMDtcbiAgICB2YXIgYXJnLCBkaXY7XG4gICAgd2hpbGUgKGkgPCBhTGVuKSB7XG4gICAgICBhcmcgPSBhYnMoYXJndW1lbnRzW2krK10pO1xuICAgICAgaWYgKGxhcmcgPCBhcmcpIHtcbiAgICAgICAgZGl2ID0gbGFyZyAvIGFyZztcbiAgICAgICAgc3VtID0gc3VtICogZGl2ICogZGl2ICsgMTtcbiAgICAgICAgbGFyZyA9IGFyZztcbiAgICAgIH0gZWxzZSBpZiAoYXJnID4gMCkge1xuICAgICAgICBkaXYgPSBhcmcgLyBsYXJnO1xuICAgICAgICBzdW0gKz0gZGl2ICogZGl2O1xuICAgICAgfSBlbHNlIHN1bSArPSBhcmc7XG4gICAgfVxuICAgIHJldHVybiBsYXJnID09PSBJbmZpbml0eSA/IEluZmluaXR5IDogbGFyZyAqIE1hdGguc3FydChzdW0pO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xOCBNYXRoLmltdWwoeCwgeSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGltdWwgPSBNYXRoLmltdWw7XG5cbi8vIHNvbWUgV2ViS2l0IHZlcnNpb25zIGZhaWxzIHdpdGggYmlnIG51bWJlcnMsIHNvbWUgaGFzIHdyb25nIGFyaXR5XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJGltdWwoMHhmZmZmZmZmZiwgNSkgIT0gLTUgfHwgJGltdWwubGVuZ3RoICE9IDI7XG59KSwgJ01hdGgnLCB7XG4gIGltdWw6IGZ1bmN0aW9uIGltdWwoeCwgeSkge1xuICAgIHZhciBVSU5UMTYgPSAweGZmZmY7XG4gICAgdmFyIHhuID0gK3g7XG4gICAgdmFyIHluID0gK3k7XG4gICAgdmFyIHhsID0gVUlOVDE2ICYgeG47XG4gICAgdmFyIHlsID0gVUlOVDE2ICYgeW47XG4gICAgcmV0dXJuIDAgfCB4bCAqIHlsICsgKChVSU5UMTYgJiB4biA+Pj4gMTYpICogeWwgKyB4bCAqIChVSU5UMTYgJiB5biA+Pj4gMTYpIDw8IDE2ID4+PiAwKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMjEgTWF0aC5sb2cxMCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBsb2cxMDogZnVuY3Rpb24gbG9nMTAoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAqIE1hdGguTE9HMTBFO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IGxvZzFwOiByZXF1aXJlKCcuL19tYXRoLWxvZzFwJykgfSk7XG4iLCIvLyAyMC4yLjIuMjIgTWF0aC5sb2cyKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGxvZzI6IGZ1bmN0aW9uIGxvZzIoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAvIE1hdGguTE4yO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yOCBNYXRoLnNpZ24oeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgc2lnbjogcmVxdWlyZSgnLi9fbWF0aC1zaWduJykgfSk7XG4iLCIvLyAyMC4yLjIuMzAgTWF0aC5zaW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGV4cG0xID0gcmVxdWlyZSgnLi9fbWF0aC1leHBtMScpO1xudmFyIGV4cCA9IE1hdGguZXhwO1xuXG4vLyBWOCBuZWFyIENocm9taXVtIDM4IGhhcyBhIHByb2JsZW0gd2l0aCB2ZXJ5IHNtYWxsIG51bWJlcnNcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhTWF0aC5zaW5oKC0yZS0xNykgIT0gLTJlLTE3O1xufSksICdNYXRoJywge1xuICBzaW5oOiBmdW5jdGlvbiBzaW5oKHgpIHtcbiAgICByZXR1cm4gTWF0aC5hYnMoeCA9ICt4KSA8IDFcbiAgICAgID8gKGV4cG0xKHgpIC0gZXhwbTEoLXgpKSAvIDJcbiAgICAgIDogKGV4cCh4IC0gMSkgLSBleHAoLXggLSAxKSkgKiAoTWF0aC5FIC8gMik7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjMzIE1hdGgudGFuaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0YW5oOiBmdW5jdGlvbiB0YW5oKHgpIHtcbiAgICB2YXIgYSA9IGV4cG0xKHggPSAreCk7XG4gICAgdmFyIGIgPSBleHBtMSgteCk7XG4gICAgcmV0dXJuIGEgPT0gSW5maW5pdHkgPyAxIDogYiA9PSBJbmZpbml0eSA/IC0xIDogKGEgLSBiKSAvIChleHAoeCkgKyBleHAoLXgpKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMzQgTWF0aC50cnVuYyh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0cnVuYzogZnVuY3Rpb24gdHJ1bmMoaXQpIHtcbiAgICByZXR1cm4gKGl0ID4gMCA/IE1hdGguZmxvb3IgOiBNYXRoLmNlaWwpKGl0KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciBOVU1CRVIgPSAnTnVtYmVyJztcbnZhciAkTnVtYmVyID0gZ2xvYmFsW05VTUJFUl07XG52YXIgQmFzZSA9ICROdW1iZXI7XG52YXIgcHJvdG8gPSAkTnVtYmVyLnByb3RvdHlwZTtcbi8vIE9wZXJhIH4xMiBoYXMgYnJva2VuIE9iamVjdCN0b1N0cmluZ1xudmFyIEJST0tFTl9DT0YgPSBjb2YocmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpKHByb3RvKSkgPT0gTlVNQkVSO1xudmFyIFRSSU0gPSAndHJpbScgaW4gU3RyaW5nLnByb3RvdHlwZTtcblxuLy8gNy4xLjMgVG9OdW1iZXIoYXJndW1lbnQpXG52YXIgdG9OdW1iZXIgPSBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgdmFyIGl0ID0gdG9QcmltaXRpdmUoYXJndW1lbnQsIGZhbHNlKTtcbiAgaWYgKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyAmJiBpdC5sZW5ndGggPiAyKSB7XG4gICAgaXQgPSBUUklNID8gaXQudHJpbSgpIDogJHRyaW0oaXQsIDMpO1xuICAgIHZhciBmaXJzdCA9IGl0LmNoYXJDb2RlQXQoMCk7XG4gICAgdmFyIHRoaXJkLCByYWRpeCwgbWF4Q29kZTtcbiAgICBpZiAoZmlyc3QgPT09IDQzIHx8IGZpcnN0ID09PSA0NSkge1xuICAgICAgdGhpcmQgPSBpdC5jaGFyQ29kZUF0KDIpO1xuICAgICAgaWYgKHRoaXJkID09PSA4OCB8fCB0aGlyZCA9PT0gMTIwKSByZXR1cm4gTmFOOyAvLyBOdW1iZXIoJysweDEnKSBzaG91bGQgYmUgTmFOLCBvbGQgVjggZml4XG4gICAgfSBlbHNlIGlmIChmaXJzdCA9PT0gNDgpIHtcbiAgICAgIHN3aXRjaCAoaXQuY2hhckNvZGVBdCgxKSkge1xuICAgICAgICBjYXNlIDY2OiBjYXNlIDk4OiByYWRpeCA9IDI7IG1heENvZGUgPSA0OTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wYlswMV0rJC9pXG4gICAgICAgIGNhc2UgNzk6IGNhc2UgMTExOiByYWRpeCA9IDg7IG1heENvZGUgPSA1NTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wb1swLTddKyQvaVxuICAgICAgICBkZWZhdWx0OiByZXR1cm4gK2l0O1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgZGlnaXRzID0gaXQuc2xpY2UoMiksIGkgPSAwLCBsID0gZGlnaXRzLmxlbmd0aCwgY29kZTsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb2RlID0gZGlnaXRzLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIC8vIHBhcnNlSW50IHBhcnNlcyBhIHN0cmluZyB0byBhIGZpcnN0IHVuYXZhaWxhYmxlIHN5bWJvbFxuICAgICAgICAvLyBidXQgVG9OdW1iZXIgc2hvdWxkIHJldHVybiBOYU4gaWYgYSBzdHJpbmcgY29udGFpbnMgdW5hdmFpbGFibGUgc3ltYm9sc1xuICAgICAgICBpZiAoY29kZSA8IDQ4IHx8IGNvZGUgPiBtYXhDb2RlKSByZXR1cm4gTmFOO1xuICAgICAgfSByZXR1cm4gcGFyc2VJbnQoZGlnaXRzLCByYWRpeCk7XG4gICAgfVxuICB9IHJldHVybiAraXQ7XG59O1xuXG5pZiAoISROdW1iZXIoJyAwbzEnKSB8fCAhJE51bWJlcignMGIxJykgfHwgJE51bWJlcignKzB4MScpKSB7XG4gICROdW1iZXIgPSBmdW5jdGlvbiBOdW1iZXIodmFsdWUpIHtcbiAgICB2YXIgaXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMSA/IDAgOiB2YWx1ZTtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgcmV0dXJuIHRoYXQgaW5zdGFuY2VvZiAkTnVtYmVyXG4gICAgICAvLyBjaGVjayBvbiAxLi5jb25zdHJ1Y3Rvcihmb28pIGNhc2VcbiAgICAgICYmIChCUk9LRU5fQ09GID8gZmFpbHMoZnVuY3Rpb24gKCkgeyBwcm90by52YWx1ZU9mLmNhbGwodGhhdCk7IH0pIDogY29mKHRoYXQpICE9IE5VTUJFUilcbiAgICAgICAgPyBpbmhlcml0SWZSZXF1aXJlZChuZXcgQmFzZSh0b051bWJlcihpdCkpLCB0aGF0LCAkTnVtYmVyKSA6IHRvTnVtYmVyKGl0KTtcbiAgfTtcbiAgZm9yICh2YXIga2V5cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BOKEJhc2UpIDogKFxuICAgIC8vIEVTMzpcbiAgICAnTUFYX1ZBTFVFLE1JTl9WQUxVRSxOYU4sTkVHQVRJVkVfSU5GSU5JVFksUE9TSVRJVkVfSU5GSU5JVFksJyArXG4gICAgLy8gRVM2IChpbiBjYXNlLCBpZiBtb2R1bGVzIHdpdGggRVM2IE51bWJlciBzdGF0aWNzIHJlcXVpcmVkIGJlZm9yZSk6XG4gICAgJ0VQU0lMT04saXNGaW5pdGUsaXNJbnRlZ2VyLGlzTmFOLGlzU2FmZUludGVnZXIsTUFYX1NBRkVfSU5URUdFUiwnICtcbiAgICAnTUlOX1NBRkVfSU5URUdFUixwYXJzZUZsb2F0LHBhcnNlSW50LGlzSW50ZWdlcidcbiAgKS5zcGxpdCgnLCcpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7IGorKykge1xuICAgIGlmIChoYXMoQmFzZSwga2V5ID0ga2V5c1tqXSkgJiYgIWhhcygkTnVtYmVyLCBrZXkpKSB7XG4gICAgICBkUCgkTnVtYmVyLCBrZXksIGdPUEQoQmFzZSwga2V5KSk7XG4gICAgfVxuICB9XG4gICROdW1iZXIucHJvdG90eXBlID0gcHJvdG87XG4gIHByb3RvLmNvbnN0cnVjdG9yID0gJE51bWJlcjtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShnbG9iYWwsIE5VTUJFUiwgJE51bWJlcik7XG59XG4iLCIvLyAyMC4xLjIuMSBOdW1iZXIuRVBTSUxPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7IEVQU0lMT046IE1hdGgucG93KDIsIC01MikgfSk7XG4iLCIvLyAyMC4xLjIuMiBOdW1iZXIuaXNGaW5pdGUobnVtYmVyKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBfaXNGaW5pdGUgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5pc0Zpbml0ZTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzRmluaXRlOiBmdW5jdGlvbiBpc0Zpbml0ZShpdCkge1xuICAgIHJldHVybiB0eXBlb2YgaXQgPT0gJ251bWJlcicgJiYgX2lzRmluaXRlKGl0KTtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuMyBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlcilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBpc0ludGVnZXI6IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKSB9KTtcbiIsIi8vIDIwLjEuMi40IE51bWJlci5pc05hTihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtcbiAgaXNOYU46IGZ1bmN0aW9uIGlzTmFOKG51bWJlcikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gbnVtYmVyICE9IG51bWJlcjtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuNSBOdW1iZXIuaXNTYWZlSW50ZWdlcihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGlzSW50ZWdlciA9IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKTtcbnZhciBhYnMgPSBNYXRoLmFicztcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzU2FmZUludGVnZXI6IGZ1bmN0aW9uIGlzU2FmZUludGVnZXIobnVtYmVyKSB7XG4gICAgcmV0dXJuIGlzSW50ZWdlcihudW1iZXIpICYmIGFicyhudW1iZXIpIDw9IDB4MWZmZmZmZmZmZmZmZmY7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMS4yLjYgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBNQVhfU0FGRV9JTlRFR0VSOiAweDFmZmZmZmZmZmZmZmZmIH0pO1xuIiwiLy8gMjAuMS4yLjEwIE51bWJlci5NSU5fU0FGRV9JTlRFR0VSXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHsgTUlOX1NBRkVfSU5URUdFUjogLTB4MWZmZmZmZmZmZmZmZmYgfSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDIwLjEuMi4xMiBOdW1iZXIucGFyc2VGbG9hdChzdHJpbmcpXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChOdW1iZXIucGFyc2VGbG9hdCAhPSAkcGFyc2VGbG9hdCksICdOdW1iZXInLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDIwLjEuMi4xMyBOdW1iZXIucGFyc2VJbnQoc3RyaW5nLCByYWRpeClcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE51bWJlci5wYXJzZUludCAhPSAkcGFyc2VJbnQpLCAnTnVtYmVyJywgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgYU51bWJlclZhbHVlID0gcmVxdWlyZSgnLi9fYS1udW1iZXItdmFsdWUnKTtcbnZhciByZXBlYXQgPSByZXF1aXJlKCcuL19zdHJpbmctcmVwZWF0Jyk7XG52YXIgJHRvRml4ZWQgPSAxLjAudG9GaXhlZDtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG52YXIgZGF0YSA9IFswLCAwLCAwLCAwLCAwLCAwXTtcbnZhciBFUlJPUiA9ICdOdW1iZXIudG9GaXhlZDogaW5jb3JyZWN0IGludm9jYXRpb24hJztcbnZhciBaRVJPID0gJzAnO1xuXG52YXIgbXVsdGlwbHkgPSBmdW5jdGlvbiAobiwgYykge1xuICB2YXIgaSA9IC0xO1xuICB2YXIgYzIgPSBjO1xuICB3aGlsZSAoKytpIDwgNikge1xuICAgIGMyICs9IG4gKiBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBjMiAlIDFlNztcbiAgICBjMiA9IGZsb29yKGMyIC8gMWU3KTtcbiAgfVxufTtcbnZhciBkaXZpZGUgPSBmdW5jdGlvbiAobikge1xuICB2YXIgaSA9IDY7XG4gIHZhciBjID0gMDtcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgYyArPSBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBmbG9vcihjIC8gbik7XG4gICAgYyA9IChjICUgbikgKiAxZTc7XG4gIH1cbn07XG52YXIgbnVtVG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpID0gNjtcbiAgdmFyIHMgPSAnJztcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgaWYgKHMgIT09ICcnIHx8IGkgPT09IDAgfHwgZGF0YVtpXSAhPT0gMCkge1xuICAgICAgdmFyIHQgPSBTdHJpbmcoZGF0YVtpXSk7XG4gICAgICBzID0gcyA9PT0gJycgPyB0IDogcyArIHJlcGVhdC5jYWxsKFpFUk8sIDcgLSB0Lmxlbmd0aCkgKyB0O1xuICAgIH1cbiAgfSByZXR1cm4gcztcbn07XG52YXIgcG93ID0gZnVuY3Rpb24gKHgsIG4sIGFjYykge1xuICByZXR1cm4gbiA9PT0gMCA/IGFjYyA6IG4gJSAyID09PSAxID8gcG93KHgsIG4gLSAxLCBhY2MgKiB4KSA6IHBvdyh4ICogeCwgbiAvIDIsIGFjYyk7XG59O1xudmFyIGxvZyA9IGZ1bmN0aW9uICh4KSB7XG4gIHZhciBuID0gMDtcbiAgdmFyIHgyID0geDtcbiAgd2hpbGUgKHgyID49IDQwOTYpIHtcbiAgICBuICs9IDEyO1xuICAgIHgyIC89IDQwOTY7XG4gIH1cbiAgd2hpbGUgKHgyID49IDIpIHtcbiAgICBuICs9IDE7XG4gICAgeDIgLz0gMjtcbiAgfSByZXR1cm4gbjtcbn07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKCEhJHRvRml4ZWQgJiYgKFxuICAwLjAwMDA4LnRvRml4ZWQoMykgIT09ICcwLjAwMCcgfHxcbiAgMC45LnRvRml4ZWQoMCkgIT09ICcxJyB8fFxuICAxLjI1NS50b0ZpeGVkKDIpICE9PSAnMS4yNScgfHxcbiAgMTAwMDAwMDAwMDAwMDAwMDEyOC4wLnRvRml4ZWQoMCkgIT09ICcxMDAwMDAwMDAwMDAwMDAwMTI4J1xuKSB8fCAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b0ZpeGVkLmNhbGwoe30pO1xufSkpLCAnTnVtYmVyJywge1xuICB0b0ZpeGVkOiBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKSB7XG4gICAgdmFyIHggPSBhTnVtYmVyVmFsdWUodGhpcywgRVJST1IpO1xuICAgIHZhciBmID0gdG9JbnRlZ2VyKGZyYWN0aW9uRGlnaXRzKTtcbiAgICB2YXIgcyA9ICcnO1xuICAgIHZhciBtID0gWkVSTztcbiAgICB2YXIgZSwgeiwgaiwgaztcbiAgICBpZiAoZiA8IDAgfHwgZiA+IDIwKSB0aHJvdyBSYW5nZUVycm9yKEVSUk9SKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgaWYgKHggIT0geCkgcmV0dXJuICdOYU4nO1xuICAgIGlmICh4IDw9IC0xZTIxIHx8IHggPj0gMWUyMSkgcmV0dXJuIFN0cmluZyh4KTtcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIHMgPSAnLSc7XG4gICAgICB4ID0gLXg7XG4gICAgfVxuICAgIGlmICh4ID4gMWUtMjEpIHtcbiAgICAgIGUgPSBsb2coeCAqIHBvdygyLCA2OSwgMSkpIC0gNjk7XG4gICAgICB6ID0gZSA8IDAgPyB4ICogcG93KDIsIC1lLCAxKSA6IHggLyBwb3coMiwgZSwgMSk7XG4gICAgICB6ICo9IDB4MTAwMDAwMDAwMDAwMDA7XG4gICAgICBlID0gNTIgLSBlO1xuICAgICAgaWYgKGUgPiAwKSB7XG4gICAgICAgIG11bHRpcGx5KDAsIHopO1xuICAgICAgICBqID0gZjtcbiAgICAgICAgd2hpbGUgKGogPj0gNykge1xuICAgICAgICAgIG11bHRpcGx5KDFlNywgMCk7XG4gICAgICAgICAgaiAtPSA3O1xuICAgICAgICB9XG4gICAgICAgIG11bHRpcGx5KHBvdygxMCwgaiwgMSksIDApO1xuICAgICAgICBqID0gZSAtIDE7XG4gICAgICAgIHdoaWxlIChqID49IDIzKSB7XG4gICAgICAgICAgZGl2aWRlKDEgPDwgMjMpO1xuICAgICAgICAgIGogLT0gMjM7XG4gICAgICAgIH1cbiAgICAgICAgZGl2aWRlKDEgPDwgaik7XG4gICAgICAgIG11bHRpcGx5KDEsIDEpO1xuICAgICAgICBkaXZpZGUoMik7XG4gICAgICAgIG0gPSBudW1Ub1N0cmluZygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXVsdGlwbHkoMCwgeik7XG4gICAgICAgIG11bHRpcGx5KDEgPDwgLWUsIDApO1xuICAgICAgICBtID0gbnVtVG9TdHJpbmcoKSArIHJlcGVhdC5jYWxsKFpFUk8sIGYpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZiA+IDApIHtcbiAgICAgIGsgPSBtLmxlbmd0aDtcbiAgICAgIG0gPSBzICsgKGsgPD0gZiA/ICcwLicgKyByZXBlYXQuY2FsbChaRVJPLCBmIC0gaykgKyBtIDogbS5zbGljZSgwLCBrIC0gZikgKyAnLicgKyBtLnNsaWNlKGsgLSBmKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBzICsgbTtcbiAgICB9IHJldHVybiBtO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBhTnVtYmVyVmFsdWUgPSByZXF1aXJlKCcuL19hLW51bWJlci12YWx1ZScpO1xudmFyICR0b1ByZWNpc2lvbiA9IDEuMC50b1ByZWNpc2lvbjtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoJGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gSUU3LVxuICByZXR1cm4gJHRvUHJlY2lzaW9uLmNhbGwoMSwgdW5kZWZpbmVkKSAhPT0gJzEnO1xufSkgfHwgISRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b1ByZWNpc2lvbi5jYWxsKHt9KTtcbn0pKSwgJ051bWJlcicsIHtcbiAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbikge1xuICAgIHZhciB0aGF0ID0gYU51bWJlclZhbHVlKHRoaXMsICdOdW1iZXIjdG9QcmVjaXNpb246IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICAgIHJldHVybiBwcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/ICR0b1ByZWNpc2lvbi5jYWxsKHRoYXQpIDogJHRvUHJlY2lzaW9uLmNhbGwodGhhdCwgcHJlY2lzaW9uKTtcbiAgfVxufSk7XG4iLCIvLyAxOS4xLjMuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYsICdPYmplY3QnLCB7IGFzc2lnbjogcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7IGNyZWF0ZTogcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4zIC8gMTUuMi4zLjcgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyksICdPYmplY3QnLCB7IGRlZmluZVByb3BlcnRpZXM6IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKSB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4vLyAxOS4xLjIuNCAvIDE1LjIuMy42IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSwgJ09iamVjdCcsIHsgZGVmaW5lUHJvcGVydHk6IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmYgfSk7XG4iLCIvLyAxOS4xLjIuNSBPYmplY3QuZnJlZXplKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2ZyZWV6ZScsIGZ1bmN0aW9uICgkZnJlZXplKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmcmVlemUoaXQpIHtcbiAgICByZXR1cm4gJGZyZWV6ZSAmJiBpc09iamVjdChpdCkgPyAkZnJlZXplKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpIHtcbiAgICByZXR1cm4gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0b0lPYmplY3QoaXQpLCBrZXkpO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdnZXRPd25Qcm9wZXJ0eU5hbWVzJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0JykuZjtcbn0pO1xuIiwiLy8gMTkuMS4yLjkgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciAkZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0UHJvdG90eXBlT2YnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBnZXRQcm90b3R5cGVPZihpdCkge1xuICAgIHJldHVybiAkZ2V0UHJvdG90eXBlT2YodG9PYmplY3QoaXQpKTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjExIE9iamVjdC5pc0V4dGVuc2libGUoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzRXh0ZW5zaWJsZScsIGZ1bmN0aW9uICgkaXNFeHRlbnNpYmxlKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpc0V4dGVuc2libGUoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUoaXQpIDogdHJ1ZSA6IGZhbHNlO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTIgT2JqZWN0LmlzRnJvemVuKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc0Zyb3plbicsIGZ1bmN0aW9uICgkaXNGcm96ZW4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGlzRnJvemVuKGl0KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc0Zyb3plbiA/ICRpc0Zyb3plbihpdCkgOiBmYWxzZSA6IHRydWU7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xMyBPYmplY3QuaXNTZWFsZWQoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzU2VhbGVkJywgZnVuY3Rpb24gKCRpc1NlYWxlZCkge1xuICByZXR1cm4gZnVuY3Rpb24gaXNTZWFsZWQoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzU2VhbGVkID8gJGlzU2VhbGVkKGl0KSA6IGZhbHNlIDogdHJ1ZTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjEwIE9iamVjdC5pcyh2YWx1ZTEsIHZhbHVlMilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgaXM6IHJlcXVpcmUoJy4vX3NhbWUtdmFsdWUnKSB9KTtcbiIsIi8vIDE5LjEuMi4xNCBPYmplY3Qua2V5cyhPKVxudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2tleXMnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBrZXlzKGl0KSB7XG4gICAgcmV0dXJuICRrZXlzKHRvT2JqZWN0KGl0KSk7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xNSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgncHJldmVudEV4dGVuc2lvbnMnLCBmdW5jdGlvbiAoJHByZXZlbnRFeHRlbnNpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwcmV2ZW50RXh0ZW5zaW9ucyhpdCkge1xuICAgIHJldHVybiAkcHJldmVudEV4dGVuc2lvbnMgJiYgaXNPYmplY3QoaXQpID8gJHByZXZlbnRFeHRlbnNpb25zKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTcgT2JqZWN0LnNlYWwoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnc2VhbCcsIGZ1bmN0aW9uICgkc2VhbCkge1xuICByZXR1cm4gZnVuY3Rpb24gc2VhbChpdCkge1xuICAgIHJldHVybiAkc2VhbCAmJiBpc09iamVjdChpdCkgPyAkc2VhbChtZXRhKGl0KSkgOiBpdDtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgc2V0UHJvdG90eXBlT2Y6IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldCB9KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgdGVzdCA9IHt9O1xudGVzdFtyZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKV0gPSAneic7XG5pZiAodGVzdCArICcnICE9ICdbb2JqZWN0IHpdJykge1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKE9iamVjdC5wcm90b3R5cGUsICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAnW29iamVjdCAnICsgY2xhc3NvZih0aGlzKSArICddJztcbiAgfSwgdHJ1ZSk7XG59XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDE4LjIuNCBwYXJzZUZsb2F0KHN0cmluZylcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5GICogKHBhcnNlRmxvYXQgIT0gJHBhcnNlRmxvYXQpLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDE4LjIuNSBwYXJzZUludChzdHJpbmcsIHJhZGl4KVxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkYgKiAocGFyc2VJbnQgIT0gJHBhcnNlSW50KSwgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcbnZhciBwZXJmb3JtID0gcmVxdWlyZSgnLi9fcGVyZm9ybScpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4vX3Byb21pc2UtcmVzb2x2ZScpO1xudmFyIFBST01JU0UgPSAnUHJvbWlzZSc7XG52YXIgVHlwZUVycm9yID0gZ2xvYmFsLlR5cGVFcnJvcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgdmVyc2lvbnMgPSBwcm9jZXNzICYmIHByb2Nlc3MudmVyc2lvbnM7XG52YXIgdjggPSB2ZXJzaW9ucyAmJiB2ZXJzaW9ucy52OCB8fCAnJztcbnZhciAkUHJvbWlzZSA9IGdsb2JhbFtQUk9NSVNFXTtcbnZhciBpc05vZGUgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJztcbnZhciBlbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBJbnRlcm5hbCwgbmV3R2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBPd25Qcm9taXNlQ2FwYWJpbGl0eSwgV3JhcHBlcjtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmY7XG5cbnZhciBVU0VfTkFUSVZFID0gISFmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgLy8gY29ycmVjdCBzdWJjbGFzc2luZyB3aXRoIEBAc3BlY2llcyBzdXBwb3J0XG4gICAgdmFyIHByb21pc2UgPSAkUHJvbWlzZS5yZXNvbHZlKDEpO1xuICAgIHZhciBGYWtlUHJvbWlzZSA9IChwcm9taXNlLmNvbnN0cnVjdG9yID0ge30pW3JlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyldID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgICAgIGV4ZWMoZW1wdHksIGVtcHR5KTtcbiAgICB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpXG4gICAgICAmJiBwcm9taXNlLnRoZW4oZW1wdHkpIGluc3RhbmNlb2YgRmFrZVByb21pc2VcbiAgICAgIC8vIHY4IDYuNiAoTm9kZSAxMCBhbmQgQ2hyb21lIDY2KSBoYXZlIGEgYnVnIHdpdGggcmVzb2x2aW5nIGN1c3RvbSB0aGVuYWJsZXNcbiAgICAgIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTgzMDU2NVxuICAgICAgLy8gd2UgY2FuJ3QgZGV0ZWN0IGl0IHN5bmNocm9ub3VzbHksIHNvIGp1c3QgY2hlY2sgdmVyc2lvbnNcbiAgICAgICYmIHY4LmluZGV4T2YoJzYuNicpICE9PSAwXG4gICAgICAmJiB1c2VyQWdlbnQuaW5kZXhPZignQ2hyb21lLzY2JykgPT09IC0xO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn0oKTtcblxuLy8gaGVscGVyc1xudmFyIGlzVGhlbmFibGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIHRoZW47XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcbn07XG52YXIgbm90aWZ5ID0gZnVuY3Rpb24gKHByb21pc2UsIGlzUmVqZWN0KSB7XG4gIGlmIChwcm9taXNlLl9uKSByZXR1cm47XG4gIHByb21pc2UuX24gPSB0cnVlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9jO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIG9rID0gcHJvbWlzZS5fcyA9PSAxO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24gKHJlYWN0aW9uKSB7XG4gICAgICB2YXIgaGFuZGxlciA9IG9rID8gcmVhY3Rpb24ub2sgOiByZWFjdGlvbi5mYWlsO1xuICAgICAgdmFyIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlO1xuICAgICAgdmFyIHJlamVjdCA9IHJlYWN0aW9uLnJlamVjdDtcbiAgICAgIHZhciBkb21haW4gPSByZWFjdGlvbi5kb21haW47XG4gICAgICB2YXIgcmVzdWx0LCB0aGVuLCBleGl0ZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgIGlmIChwcm9taXNlLl9oID09IDIpIG9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xuICAgICAgICAgICAgcHJvbWlzZS5faCA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChoYW5kbGVyID09PSB0cnVlKSByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkb21haW4pIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7IC8vIG1heSB0aHJvd1xuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICBleGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKSB7XG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGRvbWFpbiAmJiAhZXhpdGVkKSBkb21haW4uZXhpdCgpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aGlsZSAoY2hhaW4ubGVuZ3RoID4gaSkgcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYgKGlzUmVqZWN0ICYmICFwcm9taXNlLl9oKSBvblVuaGFuZGxlZChwcm9taXNlKTtcbiAgfSk7XG59O1xudmFyIG9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgdGFzay5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIHVuaGFuZGxlZCA9IGlzVW5oYW5kbGVkKHByb21pc2UpO1xuICAgIHZhciByZXN1bHQsIGhhbmRsZXIsIGNvbnNvbGU7XG4gICAgaWYgKHVuaGFuZGxlZCkge1xuICAgICAgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChpc05vZGUpIHtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYW5kbGVyID0gZ2xvYmFsLm9udW5oYW5kbGVkcmVqZWN0aW9uKSB7XG4gICAgICAgICAgaGFuZGxlcih7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKGNvbnNvbGUgPSBnbG9iYWwuY29uc29sZSkgJiYgY29uc29sZS5lcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZiAodW5oYW5kbGVkICYmIHJlc3VsdC5lKSB0aHJvdyByZXN1bHQudjtcbiAgfSk7XG59O1xudmFyIGlzVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgcmV0dXJuIHByb21pc2UuX2ggIT09IDEgJiYgKHByb21pc2UuX2EgfHwgcHJvbWlzZS5fYykubGVuZ3RoID09PSAwO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFuZGxlcjtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYgKGhhbmRsZXIgPSBnbG9iYWwub25yZWplY3Rpb25oYW5kbGVkKSB7XG4gICAgICBoYW5kbGVyKHsgcHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92IH0pO1xuICAgIH1cbiAgfSk7XG59O1xudmFyICRyZWplY3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fcyA9IDI7XG4gIGlmICghcHJvbWlzZS5fYSkgcHJvbWlzZS5fYSA9IHByb21pc2UuX2Muc2xpY2UoKTtcbiAgbm90aWZ5KHByb21pc2UsIHRydWUpO1xufTtcbnZhciAkcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIHZhciB0aGVuO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB0aHJvdyBUeXBlRXJyb3IoXCJQcm9taXNlIGNhbid0IGJlIHJlc29sdmVkIGl0c2VsZlwiKTtcbiAgICBpZiAodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKSB7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgd3JhcHBlciA9IHsgX3c6IHByb21pc2UsIF9kOiBmYWxzZSB9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgJHJlamVjdC5jYWxsKHdyYXBwZXIsIGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZS5fdiA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fcyA9IDE7XG4gICAgICBub3RpZnkocHJvbWlzZSwgZmFsc2UpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgICRyZWplY3QuY2FsbCh7IF93OiBwcm9taXNlLCBfZDogZmFsc2UgfSwgZSk7IC8vIHdyYXBcbiAgfVxufTtcblxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcbmlmICghVVNFX05BVElWRSkge1xuICAvLyAyNS40LjMuMSBQcm9taXNlKGV4ZWN1dG9yKVxuICAkUHJvbWlzZSA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRQcm9taXNlLCBQUk9NSVNFLCAnX2gnKTtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGN0eCgkcmVzb2x2ZSwgdGhpcywgMSksIGN0eCgkcmVqZWN0LCB0aGlzLCAxKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAkcmVqZWN0LmNhbGwodGhpcywgZXJyKTtcbiAgICB9XG4gIH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBJbnRlcm5hbCA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgIHZhciByZWFjdGlvbiA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkUHJvbWlzZSkpO1xuICAgICAgcmVhY3Rpb24ub2sgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgPSB0eXBlb2Ygb25SZWplY3RlZCA9PSAnZnVuY3Rpb24nICYmIG9uUmVqZWN0ZWQ7XG4gICAgICByZWFjdGlvbi5kb21haW4gPSBpc05vZGUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX2MucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAodGhpcy5fYSkgdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmICh0aGlzLl9zKSBub3RpZnkodGhpcywgZmFsc2UpO1xuICAgICAgcmV0dXJuIHJlYWN0aW9uLnByb21pc2U7XG4gICAgfSxcbiAgICAvLyAyNS40LjUuMSBQcm9taXNlLnByb3RvdHlwZS5jYXRjaChvblJlamVjdGVkKVxuICAgICdjYXRjaCc6IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy50aGVuKHVuZGVmaW5lZCwgb25SZWplY3RlZCk7XG4gICAgfVxuICB9KTtcbiAgT3duUHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgSW50ZXJuYWwoKTtcbiAgICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xuICAgIHRoaXMucmVzb2x2ZSA9IGN0eCgkcmVzb2x2ZSwgcHJvbWlzZSwgMSk7XG4gICAgdGhpcy5yZWplY3QgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG4gIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmYgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uIChDKSB7XG4gICAgcmV0dXJuIEMgPT09ICRQcm9taXNlIHx8IEMgPT09IFdyYXBwZXJcbiAgICAgID8gbmV3IE93blByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICA6IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgfTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgeyBQcm9taXNlOiAkUHJvbWlzZSB9KTtcbnJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJykoJFByb21pc2UsIFBST01JU0UpO1xucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShQUk9NSVNFKTtcbldyYXBwZXIgPSByZXF1aXJlKCcuL19jb3JlJylbUFJPTUlTRV07XG5cbi8vIHN0YXRpY3NcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjUgUHJvbWlzZS5yZWplY3QocilcbiAgcmVqZWN0OiBmdW5jdGlvbiByZWplY3Qocikge1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcyk7XG4gICAgdmFyICQkcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgJCRyZWplY3Qocik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChMSUJSQVJZIHx8ICFVU0VfTkFUSVZFKSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNiBQcm9taXNlLnJlc29sdmUoeClcbiAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKExJQlJBUlkgJiYgdGhpcyA9PT0gV3JhcHBlciA/ICRQcm9taXNlIDogdGhpcywgeCk7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKFVTRV9OQVRJVkUgJiYgcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikge1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICAgIHZhciBDID0gdGhpcztcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpO1xuICAgIHZhciByZXNvbHZlID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgIHZhciByZWplY3QgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgdmFyIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgIHZhciAkaW5kZXggPSBpbmRleCsrO1xuICAgICAgICB2YXIgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKGFscmVhZHlDYWxsZWQpIHJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuZSkgcmVqZWN0KHJlc3VsdC52KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICBDLnJlc29sdmUocHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmUpIHJlamVjdChyZXN1bHQudik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjEgUmVmbGVjdC5hcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgckFwcGx5ID0gKHJlcXVpcmUoJy4vX2dsb2JhbCcpLlJlZmxlY3QgfHwge30pLmFwcGx5O1xudmFyIGZBcHBseSA9IEZ1bmN0aW9uLmFwcGx5O1xuLy8gTVMgRWRnZSBhcmd1bWVudHNMaXN0IGFyZ3VtZW50IGlzIG9wdGlvbmFsXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgckFwcGx5KGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSk7XG59KSwgJ1JlZmxlY3QnLCB7XG4gIGFwcGx5OiBmdW5jdGlvbiBhcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdCkge1xuICAgIHZhciBUID0gYUZ1bmN0aW9uKHRhcmdldCk7XG4gICAgdmFyIEwgPSBhbk9iamVjdChhcmd1bWVudHNMaXN0KTtcbiAgICByZXR1cm4gckFwcGx5ID8gckFwcGx5KFQsIHRoaXNBcmd1bWVudCwgTCkgOiBmQXBwbHkuY2FsbChULCB0aGlzQXJndW1lbnQsIEwpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMiBSZWZsZWN0LmNvbnN0cnVjdCh0YXJnZXQsIGFyZ3VtZW50c0xpc3QgWywgbmV3VGFyZ2V0XSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGJpbmQgPSByZXF1aXJlKCcuL19iaW5kJyk7XG52YXIgckNvbnN0cnVjdCA9IChyZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0IHx8IHt9KS5jb25zdHJ1Y3Q7XG5cbi8vIE1TIEVkZ2Ugc3VwcG9ydHMgb25seSAyIGFyZ3VtZW50cyBhbmQgYXJndW1lbnRzTGlzdCBhcmd1bWVudCBpcyBvcHRpb25hbFxuLy8gRkYgTmlnaHRseSBzZXRzIHRoaXJkIGFyZ3VtZW50IGFzIGBuZXcudGFyZ2V0YCwgYnV0IGRvZXMgbm90IGNyZWF0ZSBgdGhpc2AgZnJvbSBpdFxudmFyIE5FV19UQVJHRVRfQlVHID0gZmFpbHMoZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGKCkgeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiAhKHJDb25zdHJ1Y3QoZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9LCBbXSwgRikgaW5zdGFuY2VvZiBGKTtcbn0pO1xudmFyIEFSR1NfQlVHID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgckNvbnN0cnVjdChmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0pO1xufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE5FV19UQVJHRVRfQlVHIHx8IEFSR1NfQlVHKSwgJ1JlZmxlY3QnLCB7XG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gY29uc3RydWN0KFRhcmdldCwgYXJncyAvKiAsIG5ld1RhcmdldCAqLykge1xuICAgIGFGdW5jdGlvbihUYXJnZXQpO1xuICAgIGFuT2JqZWN0KGFyZ3MpO1xuICAgIHZhciBuZXdUYXJnZXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IFRhcmdldCA6IGFGdW5jdGlvbihhcmd1bWVudHNbMl0pO1xuICAgIGlmIChBUkdTX0JVRyAmJiAhTkVXX1RBUkdFVF9CVUcpIHJldHVybiByQ29uc3RydWN0KFRhcmdldCwgYXJncywgbmV3VGFyZ2V0KTtcbiAgICBpZiAoVGFyZ2V0ID09IG5ld1RhcmdldCkge1xuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBvcHRpbWl6YXRpb24gZm9yIDAtNCBhcmd1bWVudHNcbiAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IFRhcmdldCgpO1xuICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0pO1xuICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICBjYXNlIDM6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICBjYXNlIDQ6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgfVxuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBsb3Qgb2YgYXJndW1lbnRzIGNhc2VcbiAgICAgIHZhciAkYXJncyA9IFtudWxsXTtcbiAgICAgICRhcmdzLnB1c2guYXBwbHkoJGFyZ3MsIGFyZ3MpO1xuICAgICAgcmV0dXJuIG5ldyAoYmluZC5hcHBseShUYXJnZXQsICRhcmdzKSkoKTtcbiAgICB9XG4gICAgLy8gd2l0aCBhbHRlcmVkIG5ld1RhcmdldCwgbm90IHN1cHBvcnQgYnVpbHQtaW4gY29uc3RydWN0b3JzXG4gICAgdmFyIHByb3RvID0gbmV3VGFyZ2V0LnByb3RvdHlwZTtcbiAgICB2YXIgaW5zdGFuY2UgPSBjcmVhdGUoaXNPYmplY3QocHJvdG8pID8gcHJvdG8gOiBPYmplY3QucHJvdG90eXBlKTtcbiAgICB2YXIgcmVzdWx0ID0gRnVuY3Rpb24uYXBwbHkuY2FsbChUYXJnZXQsIGluc3RhbmNlLCBhcmdzKTtcbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IGluc3RhbmNlO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMyBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpXG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuXG4vLyBNUyBFZGdlIGhhcyBicm9rZW4gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSAtIHRocm93aW5nIGluc3RlYWQgb2YgcmV0dXJuaW5nIGZhbHNlXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eShkUC5mKHt9LCAxLCB7IHZhbHVlOiAxIH0pLCAxLCB7IHZhbHVlOiAyIH0pO1xufSksICdSZWZsZWN0Jywge1xuICBkZWZpbmVQcm9wZXJ0eTogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcykge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgcHJvcGVydHlLZXkgPSB0b1ByaW1pdGl2ZShwcm9wZXJ0eUtleSwgdHJ1ZSk7XG4gICAgYW5PYmplY3QoYXR0cmlidXRlcyk7XG4gICAgdHJ5IHtcbiAgICAgIGRQLmYodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59KTtcbiIsIi8vIDI2LjEuNCBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBkZWxldGVQcm9wZXJ0eTogZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHZhciBkZXNjID0gZ09QRChhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSk7XG4gICAgcmV0dXJuIGRlc2MgJiYgIWRlc2MuY29uZmlndXJhYmxlID8gZmFsc2UgOiBkZWxldGUgdGFyZ2V0W3Byb3BlcnR5S2V5XTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyNi4xLjUgUmVmbGVjdC5lbnVtZXJhdGUodGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIEVudW1lcmF0ZSA9IGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICB0aGlzLl90ID0gYW5PYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICB2YXIga2V5cyA9IHRoaXMuX2sgPSBbXTsgICAgICAvLyBrZXlzXG4gIHZhciBrZXk7XG4gIGZvciAoa2V5IGluIGl0ZXJhdGVkKSBrZXlzLnB1c2goa2V5KTtcbn07XG5yZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpKEVudW1lcmF0ZSwgJ09iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIga2V5cyA9IHRoYXQuX2s7XG4gIHZhciBrZXk7XG4gIGRvIHtcbiAgICBpZiAodGhhdC5faSA+PSBrZXlzLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICB9IHdoaWxlICghKChrZXkgPSBrZXlzW3RoYXQuX2krK10pIGluIHRoYXQuX3QpKTtcbiAgcmV0dXJuIHsgdmFsdWU6IGtleSwgZG9uZTogZmFsc2UgfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGVudW1lcmF0ZTogZnVuY3Rpb24gZW51bWVyYXRlKHRhcmdldCkge1xuICAgIHJldHVybiBuZXcgRW51bWVyYXRlKHRhcmdldCk7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS43IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuOCBSZWZsZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZ2V0UHJvdG8gPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBnZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSB7XG4gICAgcmV0dXJuIGdldFByb3RvKGFuT2JqZWN0KHRhcmdldCkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuNiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3BlcnR5S2V5IFssIHJlY2VpdmVyXSlcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xuXG5mdW5jdGlvbiBnZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSAvKiAsIHJlY2VpdmVyICovKSB7XG4gIHZhciByZWNlaXZlciA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdGFyZ2V0IDogYXJndW1lbnRzWzJdO1xuICB2YXIgZGVzYywgcHJvdG87XG4gIGlmIChhbk9iamVjdCh0YXJnZXQpID09PSByZWNlaXZlcikgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eUtleV07XG4gIGlmIChkZXNjID0gZ09QRC5mKHRhcmdldCwgcHJvcGVydHlLZXkpKSByZXR1cm4gaGFzKGRlc2MsICd2YWx1ZScpXG4gICAgPyBkZXNjLnZhbHVlXG4gICAgOiBkZXNjLmdldCAhPT0gdW5kZWZpbmVkXG4gICAgICA/IGRlc2MuZ2V0LmNhbGwocmVjZWl2ZXIpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHJldHVybiBnZXQocHJvdG8sIHByb3BlcnR5S2V5LCByZWNlaXZlcik7XG59XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHsgZ2V0OiBnZXQgfSk7XG4iLCIvLyAyNi4xLjkgUmVmbGVjdC5oYXModGFyZ2V0LCBwcm9wZXJ0eUtleSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaGFzOiBmdW5jdGlvbiBoYXModGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBwcm9wZXJ0eUtleSBpbiB0YXJnZXQ7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMCBSZWZsZWN0LmlzRXh0ZW5zaWJsZSh0YXJnZXQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaXNFeHRlbnNpYmxlOiBmdW5jdGlvbiBpc0V4dGVuc2libGUodGFyZ2V0KSB7XG4gICAgYW5PYmplY3QodGFyZ2V0KTtcbiAgICByZXR1cm4gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUodGFyZ2V0KSA6IHRydWU7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMSBSZWZsZWN0Lm93bktleXModGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBvd25LZXlzOiByZXF1aXJlKCcuL19vd24ta2V5cycpIH0pO1xuIiwiLy8gMjYuMS4xMiBSZWZsZWN0LnByZXZlbnRFeHRlbnNpb25zKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciAkcHJldmVudEV4dGVuc2lvbnMgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgcHJldmVudEV4dGVuc2lvbnM6IGZ1bmN0aW9uIHByZXZlbnRFeHRlbnNpb25zKHRhcmdldCkge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICgkcHJldmVudEV4dGVuc2lvbnMpICRwcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufSk7XG4iLCIvLyAyNi4xLjE0IFJlZmxlY3Quc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgc2V0UHJvdG8gPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKTtcblxuaWYgKHNldFByb3RvKSAkZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIHNldFByb3RvdHlwZU9mOiBmdW5jdGlvbiBzZXRQcm90b3R5cGVPZih0YXJnZXQsIHByb3RvKSB7XG4gICAgc2V0UHJvdG8uY2hlY2sodGFyZ2V0LCBwcm90byk7XG4gICAgdHJ5IHtcbiAgICAgIHNldFByb3RvLnNldCh0YXJnZXQsIHByb3RvKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMyBSZWZsZWN0LnNldCh0YXJnZXQsIHByb3BlcnR5S2V5LCBWIFssIHJlY2VpdmVyXSlcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxuZnVuY3Rpb24gc2V0KHRhcmdldCwgcHJvcGVydHlLZXksIFYgLyogLCByZWNlaXZlciAqLykge1xuICB2YXIgcmVjZWl2ZXIgPSBhcmd1bWVudHMubGVuZ3RoIDwgNCA/IHRhcmdldCA6IGFyZ3VtZW50c1szXTtcbiAgdmFyIG93bkRlc2MgPSBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB2YXIgZXhpc3RpbmdEZXNjcmlwdG9yLCBwcm90bztcbiAgaWYgKCFvd25EZXNjKSB7XG4gICAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHtcbiAgICAgIHJldHVybiBzZXQocHJvdG8sIHByb3BlcnR5S2V5LCBWLCByZWNlaXZlcik7XG4gICAgfVxuICAgIG93bkRlc2MgPSBjcmVhdGVEZXNjKDApO1xuICB9XG4gIGlmIChoYXMob3duRGVzYywgJ3ZhbHVlJykpIHtcbiAgICBpZiAob3duRGVzYy53cml0YWJsZSA9PT0gZmFsc2UgfHwgIWlzT2JqZWN0KHJlY2VpdmVyKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChleGlzdGluZ0Rlc2NyaXB0b3IgPSBnT1BELmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5KSkge1xuICAgICAgaWYgKGV4aXN0aW5nRGVzY3JpcHRvci5nZXQgfHwgZXhpc3RpbmdEZXNjcmlwdG9yLnNldCB8fCBleGlzdGluZ0Rlc2NyaXB0b3Iud3JpdGFibGUgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgICBleGlzdGluZ0Rlc2NyaXB0b3IudmFsdWUgPSBWO1xuICAgICAgZFAuZihyZWNlaXZlciwgcHJvcGVydHlLZXksIGV4aXN0aW5nRGVzY3JpcHRvcik7XG4gICAgfSBlbHNlIGRQLmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5LCBjcmVhdGVEZXNjKDAsIFYpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gb3duRGVzYy5zZXQgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogKG93bkRlc2Muc2V0LmNhbGwocmVjZWl2ZXIsIFYpLCB0cnVlKTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBzZXQ6IHNldCB9KTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBpbmhlcml0SWZSZXF1aXJlZCA9IHJlcXVpcmUoJy4vX2luaGVyaXQtaWYtcmVxdWlyZWQnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBpc1JlZ0V4cCA9IHJlcXVpcmUoJy4vX2lzLXJlZ2V4cCcpO1xudmFyICRmbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG52YXIgJFJlZ0V4cCA9IGdsb2JhbC5SZWdFeHA7XG52YXIgQmFzZSA9ICRSZWdFeHA7XG52YXIgcHJvdG8gPSAkUmVnRXhwLnByb3RvdHlwZTtcbnZhciByZTEgPSAvYS9nO1xudmFyIHJlMiA9IC9hL2c7XG4vLyBcIm5ld1wiIGNyZWF0ZXMgYSBuZXcgb2JqZWN0LCBvbGQgd2Via2l0IGJ1Z2d5IGhlcmVcbnZhciBDT1JSRUNUX05FVyA9IG5ldyAkUmVnRXhwKHJlMSkgIT09IHJlMTtcblxuaWYgKHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgKCFDT1JSRUNUX05FVyB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmUyW3JlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpXSA9IGZhbHNlO1xuICAvLyBSZWdFeHAgY29uc3RydWN0b3IgY2FuIGFsdGVyIGZsYWdzIGFuZCBJc1JlZ0V4cCB3b3JrcyBjb3JyZWN0IHdpdGggQEBtYXRjaFxuICByZXR1cm4gJFJlZ0V4cChyZTEpICE9IHJlMSB8fCAkUmVnRXhwKHJlMikgPT0gcmUyIHx8ICRSZWdFeHAocmUxLCAnaScpICE9ICcvYS9pJztcbn0pKSkge1xuICAkUmVnRXhwID0gZnVuY3Rpb24gUmVnRXhwKHAsIGYpIHtcbiAgICB2YXIgdGlSRSA9IHRoaXMgaW5zdGFuY2VvZiAkUmVnRXhwO1xuICAgIHZhciBwaVJFID0gaXNSZWdFeHAocCk7XG4gICAgdmFyIGZpVSA9IGYgPT09IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gIXRpUkUgJiYgcGlSRSAmJiBwLmNvbnN0cnVjdG9yID09PSAkUmVnRXhwICYmIGZpVSA/IHBcbiAgICAgIDogaW5oZXJpdElmUmVxdWlyZWQoQ09SUkVDVF9ORVdcbiAgICAgICAgPyBuZXcgQmFzZShwaVJFICYmICFmaVUgPyBwLnNvdXJjZSA6IHAsIGYpXG4gICAgICAgIDogQmFzZSgocGlSRSA9IHAgaW5zdGFuY2VvZiAkUmVnRXhwKSA/IHAuc291cmNlIDogcCwgcGlSRSAmJiBmaVUgPyAkZmxhZ3MuY2FsbChwKSA6IGYpXG4gICAgICAsIHRpUkUgPyB0aGlzIDogcHJvdG8sICRSZWdFeHApO1xuICB9O1xuICB2YXIgcHJveHkgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAga2V5IGluICRSZWdFeHAgfHwgZFAoJFJlZ0V4cCwga2V5LCB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIEJhc2Vba2V5XTsgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gKGl0KSB7IEJhc2Vba2V5XSA9IGl0OyB9XG4gICAgfSk7XG4gIH07XG4gIGZvciAodmFyIGtleXMgPSBnT1BOKEJhc2UpLCBpID0gMDsga2V5cy5sZW5ndGggPiBpOykgcHJveHkoa2V5c1tpKytdKTtcbiAgcHJvdG8uY29uc3RydWN0b3IgPSAkUmVnRXhwO1xuICAkUmVnRXhwLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKGdsb2JhbCwgJ1JlZ0V4cCcsICRSZWdFeHApO1xufVxuXG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdSZWdFeHAnKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciByZWdleHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMnKTtcbnJlcXVpcmUoJy4vX2V4cG9ydCcpKHtcbiAgdGFyZ2V0OiAnUmVnRXhwJyxcbiAgcHJvdG86IHRydWUsXG4gIGZvcmNlZDogcmVnZXhwRXhlYyAhPT0gLy4vLmV4ZWNcbn0sIHtcbiAgZXhlYzogcmVnZXhwRXhlY1xufSk7XG4iLCIvLyAyMS4yLjUuMyBnZXQgUmVnRXhwLnByb3RvdHlwZS5mbGFncygpXG5pZiAocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAvLi9nLmZsYWdzICE9ICdnJykgcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZihSZWdFeHAucHJvdG90eXBlLCAnZmxhZ3MnLCB7XG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgZ2V0OiByZXF1aXJlKCcuL19mbGFncycpXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBhZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL19hZHZhbmNlLXN0cmluZy1pbmRleCcpO1xudmFyIHJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL19yZWdleHAtZXhlYy1hYnN0cmFjdCcpO1xuXG4vLyBAQG1hdGNoIGxvZ2ljXG5yZXF1aXJlKCcuL19maXgtcmUtd2tzJykoJ21hdGNoJywgMSwgZnVuY3Rpb24gKGRlZmluZWQsIE1BVENILCAkbWF0Y2gsIG1heWJlQ2FsbE5hdGl2ZSkge1xuICByZXR1cm4gW1xuICAgIC8vIGBTdHJpbmcucHJvdG90eXBlLm1hdGNoYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLm1hdGNoXG4gICAgZnVuY3Rpb24gbWF0Y2gocmVnZXhwKSB7XG4gICAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgICB2YXIgZm4gPSByZWdleHAgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcmVnZXhwW01BVENIXTtcbiAgICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW01BVENIXShTdHJpbmcoTykpO1xuICAgIH0sXG4gICAgLy8gYFJlZ0V4cC5wcm90b3R5cGVbQEBtYXRjaF1gIG1ldGhvZFxuICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXJlZ2V4cC5wcm90b3R5cGUtQEBtYXRjaFxuICAgIGZ1bmN0aW9uIChyZWdleHApIHtcbiAgICAgIHZhciByZXMgPSBtYXliZUNhbGxOYXRpdmUoJG1hdGNoLCByZWdleHAsIHRoaXMpO1xuICAgICAgaWYgKHJlcy5kb25lKSByZXR1cm4gcmVzLnZhbHVlO1xuICAgICAgdmFyIHJ4ID0gYW5PYmplY3QocmVnZXhwKTtcbiAgICAgIHZhciBTID0gU3RyaW5nKHRoaXMpO1xuICAgICAgaWYgKCFyeC5nbG9iYWwpIHJldHVybiByZWdFeHBFeGVjKHJ4LCBTKTtcbiAgICAgIHZhciBmdWxsVW5pY29kZSA9IHJ4LnVuaWNvZGU7XG4gICAgICByeC5sYXN0SW5kZXggPSAwO1xuICAgICAgdmFyIEEgPSBbXTtcbiAgICAgIHZhciBuID0gMDtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICB3aGlsZSAoKHJlc3VsdCA9IHJlZ0V4cEV4ZWMocngsIFMpKSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgbWF0Y2hTdHIgPSBTdHJpbmcocmVzdWx0WzBdKTtcbiAgICAgICAgQVtuXSA9IG1hdGNoU3RyO1xuICAgICAgICBpZiAobWF0Y2hTdHIgPT09ICcnKSByeC5sYXN0SW5kZXggPSBhZHZhbmNlU3RyaW5nSW5kZXgoUywgdG9MZW5ndGgocngubGFzdEluZGV4KSwgZnVsbFVuaWNvZGUpO1xuICAgICAgICBuKys7XG4gICAgICB9XG4gICAgICByZXR1cm4gbiA9PT0gMCA/IG51bGwgOiBBO1xuICAgIH1cbiAgXTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIGFkdmFuY2VTdHJpbmdJbmRleCA9IHJlcXVpcmUoJy4vX2FkdmFuY2Utc3RyaW5nLWluZGV4Jyk7XG52YXIgcmVnRXhwRXhlYyA9IHJlcXVpcmUoJy4vX3JlZ2V4cC1leGVjLWFic3RyYWN0Jyk7XG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgbWluID0gTWF0aC5taW47XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xudmFyIFNVQlNUSVRVVElPTl9TWU1CT0xTID0gL1xcJChbJCZgJ118XFxkXFxkP3w8W14+XSo+KS9nO1xudmFyIFNVQlNUSVRVVElPTl9TWU1CT0xTX05PX05BTUVEID0gL1xcJChbJCZgJ118XFxkXFxkPykvZztcblxudmFyIG1heWJlVG9TdHJpbmcgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyBpdCA6IFN0cmluZyhpdCk7XG59O1xuXG4vLyBAQHJlcGxhY2UgbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgncmVwbGFjZScsIDIsIGZ1bmN0aW9uIChkZWZpbmVkLCBSRVBMQUNFLCAkcmVwbGFjZSwgbWF5YmVDYWxsTmF0aXZlKSB7XG4gIHJldHVybiBbXG4gICAgLy8gYFN0cmluZy5wcm90b3R5cGUucmVwbGFjZWAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlXG4gICAgZnVuY3Rpb24gcmVwbGFjZShzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKSB7XG4gICAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgICB2YXIgZm4gPSBzZWFyY2hWYWx1ZSA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzZWFyY2hWYWx1ZVtSRVBMQUNFXTtcbiAgICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gZm4uY2FsbChzZWFyY2hWYWx1ZSwgTywgcmVwbGFjZVZhbHVlKVxuICAgICAgICA6ICRyZXBsYWNlLmNhbGwoU3RyaW5nKE8pLCBzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAcmVwbGFjZV1gIG1ldGhvZFxuICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXJlZ2V4cC5wcm90b3R5cGUtQEByZXBsYWNlXG4gICAgZnVuY3Rpb24gKHJlZ2V4cCwgcmVwbGFjZVZhbHVlKSB7XG4gICAgICB2YXIgcmVzID0gbWF5YmVDYWxsTmF0aXZlKCRyZXBsYWNlLCByZWdleHAsIHRoaXMsIHJlcGxhY2VWYWx1ZSk7XG4gICAgICBpZiAocmVzLmRvbmUpIHJldHVybiByZXMudmFsdWU7XG5cbiAgICAgIHZhciByeCA9IGFuT2JqZWN0KHJlZ2V4cCk7XG4gICAgICB2YXIgUyA9IFN0cmluZyh0aGlzKTtcbiAgICAgIHZhciBmdW5jdGlvbmFsUmVwbGFjZSA9IHR5cGVvZiByZXBsYWNlVmFsdWUgPT09ICdmdW5jdGlvbic7XG4gICAgICBpZiAoIWZ1bmN0aW9uYWxSZXBsYWNlKSByZXBsYWNlVmFsdWUgPSBTdHJpbmcocmVwbGFjZVZhbHVlKTtcbiAgICAgIHZhciBnbG9iYWwgPSByeC5nbG9iYWw7XG4gICAgICBpZiAoZ2xvYmFsKSB7XG4gICAgICAgIHZhciBmdWxsVW5pY29kZSA9IHJ4LnVuaWNvZGU7XG4gICAgICAgIHJ4Lmxhc3RJbmRleCA9IDA7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlZ0V4cEV4ZWMocngsIFMpO1xuICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSBicmVhaztcbiAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgIGlmICghZ2xvYmFsKSBicmVhaztcbiAgICAgICAgdmFyIG1hdGNoU3RyID0gU3RyaW5nKHJlc3VsdFswXSk7XG4gICAgICAgIGlmIChtYXRjaFN0ciA9PT0gJycpIHJ4Lmxhc3RJbmRleCA9IGFkdmFuY2VTdHJpbmdJbmRleChTLCB0b0xlbmd0aChyeC5sYXN0SW5kZXgpLCBmdWxsVW5pY29kZSk7XG4gICAgICB9XG4gICAgICB2YXIgYWNjdW11bGF0ZWRSZXN1bHQgPSAnJztcbiAgICAgIHZhciBuZXh0U291cmNlUG9zaXRpb24gPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdHNbaV07XG4gICAgICAgIHZhciBtYXRjaGVkID0gU3RyaW5nKHJlc3VsdFswXSk7XG4gICAgICAgIHZhciBwb3NpdGlvbiA9IG1heChtaW4odG9JbnRlZ2VyKHJlc3VsdC5pbmRleCksIFMubGVuZ3RoKSwgMCk7XG4gICAgICAgIHZhciBjYXB0dXJlcyA9IFtdO1xuICAgICAgICAvLyBOT1RFOiBUaGlzIGlzIGVxdWl2YWxlbnQgdG9cbiAgICAgICAgLy8gICBjYXB0dXJlcyA9IHJlc3VsdC5zbGljZSgxKS5tYXAobWF5YmVUb1N0cmluZylcbiAgICAgICAgLy8gYnV0IGZvciBzb21lIHJlYXNvbiBgbmF0aXZlU2xpY2UuY2FsbChyZXN1bHQsIDEsIHJlc3VsdC5sZW5ndGgpYCAoY2FsbGVkIGluXG4gICAgICAgIC8vIHRoZSBzbGljZSBwb2x5ZmlsbCB3aGVuIHNsaWNpbmcgbmF0aXZlIGFycmF5cykgXCJkb2Vzbid0IHdvcmtcIiBpbiBzYWZhcmkgOSBhbmRcbiAgICAgICAgLy8gY2F1c2VzIGEgY3Jhc2ggKGh0dHBzOi8vcGFzdGViaW4uY29tL04yMVF6ZVFBKSB3aGVuIHRyeWluZyB0byBkZWJ1ZyBpdC5cbiAgICAgICAgZm9yICh2YXIgaiA9IDE7IGogPCByZXN1bHQubGVuZ3RoOyBqKyspIGNhcHR1cmVzLnB1c2gobWF5YmVUb1N0cmluZyhyZXN1bHRbal0pKTtcbiAgICAgICAgdmFyIG5hbWVkQ2FwdHVyZXMgPSByZXN1bHQuZ3JvdXBzO1xuICAgICAgICBpZiAoZnVuY3Rpb25hbFJlcGxhY2UpIHtcbiAgICAgICAgICB2YXIgcmVwbGFjZXJBcmdzID0gW21hdGNoZWRdLmNvbmNhdChjYXB0dXJlcywgcG9zaXRpb24sIFMpO1xuICAgICAgICAgIGlmIChuYW1lZENhcHR1cmVzICE9PSB1bmRlZmluZWQpIHJlcGxhY2VyQXJncy5wdXNoKG5hbWVkQ2FwdHVyZXMpO1xuICAgICAgICAgIHZhciByZXBsYWNlbWVudCA9IFN0cmluZyhyZXBsYWNlVmFsdWUuYXBwbHkodW5kZWZpbmVkLCByZXBsYWNlckFyZ3MpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXBsYWNlbWVudCA9IGdldFN1YnN0aXR1dGlvbihtYXRjaGVkLCBTLCBwb3NpdGlvbiwgY2FwdHVyZXMsIG5hbWVkQ2FwdHVyZXMsIHJlcGxhY2VWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uID49IG5leHRTb3VyY2VQb3NpdGlvbikge1xuICAgICAgICAgIGFjY3VtdWxhdGVkUmVzdWx0ICs9IFMuc2xpY2UobmV4dFNvdXJjZVBvc2l0aW9uLCBwb3NpdGlvbikgKyByZXBsYWNlbWVudDtcbiAgICAgICAgICBuZXh0U291cmNlUG9zaXRpb24gPSBwb3NpdGlvbiArIG1hdGNoZWQubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW11bGF0ZWRSZXN1bHQgKyBTLnNsaWNlKG5leHRTb3VyY2VQb3NpdGlvbik7XG4gICAgfVxuICBdO1xuXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZ2V0c3Vic3RpdHV0aW9uXG4gIGZ1bmN0aW9uIGdldFN1YnN0aXR1dGlvbihtYXRjaGVkLCBzdHIsIHBvc2l0aW9uLCBjYXB0dXJlcywgbmFtZWRDYXB0dXJlcywgcmVwbGFjZW1lbnQpIHtcbiAgICB2YXIgdGFpbFBvcyA9IHBvc2l0aW9uICsgbWF0Y2hlZC5sZW5ndGg7XG4gICAgdmFyIG0gPSBjYXB0dXJlcy5sZW5ndGg7XG4gICAgdmFyIHN5bWJvbHMgPSBTVUJTVElUVVRJT05fU1lNQk9MU19OT19OQU1FRDtcbiAgICBpZiAobmFtZWRDYXB0dXJlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBuYW1lZENhcHR1cmVzID0gdG9PYmplY3QobmFtZWRDYXB0dXJlcyk7XG4gICAgICBzeW1ib2xzID0gU1VCU1RJVFVUSU9OX1NZTUJPTFM7XG4gICAgfVxuICAgIHJldHVybiAkcmVwbGFjZS5jYWxsKHJlcGxhY2VtZW50LCBzeW1ib2xzLCBmdW5jdGlvbiAobWF0Y2gsIGNoKSB7XG4gICAgICB2YXIgY2FwdHVyZTtcbiAgICAgIHN3aXRjaCAoY2guY2hhckF0KDApKSB7XG4gICAgICAgIGNhc2UgJyQnOiByZXR1cm4gJyQnO1xuICAgICAgICBjYXNlICcmJzogcmV0dXJuIG1hdGNoZWQ7XG4gICAgICAgIGNhc2UgJ2AnOiByZXR1cm4gc3RyLnNsaWNlKDAsIHBvc2l0aW9uKTtcbiAgICAgICAgY2FzZSBcIidcIjogcmV0dXJuIHN0ci5zbGljZSh0YWlsUG9zKTtcbiAgICAgICAgY2FzZSAnPCc6XG4gICAgICAgICAgY2FwdHVyZSA9IG5hbWVkQ2FwdHVyZXNbY2guc2xpY2UoMSwgLTEpXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDogLy8gXFxkXFxkP1xuICAgICAgICAgIHZhciBuID0gK2NoO1xuICAgICAgICAgIGlmIChuID09PSAwKSByZXR1cm4gbWF0Y2g7XG4gICAgICAgICAgaWYgKG4gPiBtKSB7XG4gICAgICAgICAgICB2YXIgZiA9IGZsb29yKG4gLyAxMCk7XG4gICAgICAgICAgICBpZiAoZiA9PT0gMCkgcmV0dXJuIG1hdGNoO1xuICAgICAgICAgICAgaWYgKGYgPD0gbSkgcmV0dXJuIGNhcHR1cmVzW2YgLSAxXSA9PT0gdW5kZWZpbmVkID8gY2guY2hhckF0KDEpIDogY2FwdHVyZXNbZiAtIDFdICsgY2guY2hhckF0KDEpO1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXB0dXJlID0gY2FwdHVyZXNbbiAtIDFdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNhcHR1cmUgPT09IHVuZGVmaW5lZCA/ICcnIDogY2FwdHVyZTtcbiAgICB9KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vX3NhbWUtdmFsdWUnKTtcbnZhciByZWdFeHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMtYWJzdHJhY3QnKTtcblxuLy8gQEBzZWFyY2ggbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgnc2VhcmNoJywgMSwgZnVuY3Rpb24gKGRlZmluZWQsIFNFQVJDSCwgJHNlYXJjaCwgbWF5YmVDYWxsTmF0aXZlKSB7XG4gIHJldHVybiBbXG4gICAgLy8gYFN0cmluZy5wcm90b3R5cGUuc2VhcmNoYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLnNlYXJjaFxuICAgIGZ1bmN0aW9uIHNlYXJjaChyZWdleHApIHtcbiAgICAgIHZhciBPID0gZGVmaW5lZCh0aGlzKTtcbiAgICAgIHZhciBmbiA9IHJlZ2V4cCA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZWdleHBbU0VBUkNIXTtcbiAgICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW1NFQVJDSF0oU3RyaW5nKE8pKTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAc2VhcmNoXWAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcmVnZXhwLnByb3RvdHlwZS1AQHNlYXJjaFxuICAgIGZ1bmN0aW9uIChyZWdleHApIHtcbiAgICAgIHZhciByZXMgPSBtYXliZUNhbGxOYXRpdmUoJHNlYXJjaCwgcmVnZXhwLCB0aGlzKTtcbiAgICAgIGlmIChyZXMuZG9uZSkgcmV0dXJuIHJlcy52YWx1ZTtcbiAgICAgIHZhciByeCA9IGFuT2JqZWN0KHJlZ2V4cCk7XG4gICAgICB2YXIgUyA9IFN0cmluZyh0aGlzKTtcbiAgICAgIHZhciBwcmV2aW91c0xhc3RJbmRleCA9IHJ4Lmxhc3RJbmRleDtcbiAgICAgIGlmICghc2FtZVZhbHVlKHByZXZpb3VzTGFzdEluZGV4LCAwKSkgcngubGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciByZXN1bHQgPSByZWdFeHBFeGVjKHJ4LCBTKTtcbiAgICAgIGlmICghc2FtZVZhbHVlKHJ4Lmxhc3RJbmRleCwgcHJldmlvdXNMYXN0SW5kZXgpKSByeC5sYXN0SW5kZXggPSBwcmV2aW91c0xhc3RJbmRleDtcbiAgICAgIHJldHVybiByZXN1bHQgPT09IG51bGwgPyAtMSA6IHJlc3VsdC5pbmRleDtcbiAgICB9XG4gIF07XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGlzUmVnRXhwID0gcmVxdWlyZSgnLi9faXMtcmVnZXhwJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgYWR2YW5jZVN0cmluZ0luZGV4ID0gcmVxdWlyZSgnLi9fYWR2YW5jZS1zdHJpbmctaW5kZXgnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGNhbGxSZWdFeHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMtYWJzdHJhY3QnKTtcbnZhciByZWdleHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgJG1pbiA9IE1hdGgubWluO1xudmFyICRwdXNoID0gW10ucHVzaDtcbnZhciAkU1BMSVQgPSAnc3BsaXQnO1xudmFyIExFTkdUSCA9ICdsZW5ndGgnO1xudmFyIExBU1RfSU5ERVggPSAnbGFzdEluZGV4JztcbnZhciBNQVhfVUlOVDMyID0gMHhmZmZmZmZmZjtcblxuLy8gYmFiZWwtbWluaWZ5IHRyYW5zcGlsZXMgUmVnRXhwKCd4JywgJ3knKSAtPiAveC95IGFuZCBpdCBjYXVzZXMgU3ludGF4RXJyb3JcbnZhciBTVVBQT1JUU19ZID0gIWZhaWxzKGZ1bmN0aW9uICgpIHsgUmVnRXhwKE1BWF9VSU5UMzIsICd5Jyk7IH0pO1xuXG4vLyBAQHNwbGl0IGxvZ2ljXG5yZXF1aXJlKCcuL19maXgtcmUtd2tzJykoJ3NwbGl0JywgMiwgZnVuY3Rpb24gKGRlZmluZWQsIFNQTElULCAkc3BsaXQsIG1heWJlQ2FsbE5hdGl2ZSkge1xuICB2YXIgaW50ZXJuYWxTcGxpdDtcbiAgaWYgKFxuICAgICdhYmJjJ1skU1BMSVRdKC8oYikqLylbMV0gPT0gJ2MnIHx8XG4gICAgJ3Rlc3QnWyRTUExJVF0oLyg/OikvLCAtMSlbTEVOR1RIXSAhPSA0IHx8XG4gICAgJ2FiJ1skU1BMSVRdKC8oPzphYikqLylbTEVOR1RIXSAhPSAyIHx8XG4gICAgJy4nWyRTUExJVF0oLyguPykoLj8pLylbTEVOR1RIXSAhPSA0IHx8XG4gICAgJy4nWyRTUExJVF0oLygpKCkvKVtMRU5HVEhdID4gMSB8fFxuICAgICcnWyRTUExJVF0oLy4/LylbTEVOR1RIXVxuICApIHtcbiAgICAvLyBiYXNlZCBvbiBlczUtc2hpbSBpbXBsZW1lbnRhdGlvbiwgbmVlZCB0byByZXdvcmsgaXRcbiAgICBpbnRlcm5hbFNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIHZhciBzdHJpbmcgPSBTdHJpbmcodGhpcyk7XG4gICAgICBpZiAoc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDApIHJldHVybiBbXTtcbiAgICAgIC8vIElmIGBzZXBhcmF0b3JgIGlzIG5vdCBhIHJlZ2V4LCB1c2UgbmF0aXZlIHNwbGl0XG4gICAgICBpZiAoIWlzUmVnRXhwKHNlcGFyYXRvcikpIHJldHVybiAkc3BsaXQuY2FsbChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgdmFyIGZsYWdzID0gKHNlcGFyYXRvci5pZ25vcmVDYXNlID8gJ2knIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IubXVsdGlsaW5lID8gJ20nIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnN0aWNreSA/ICd5JyA6ICcnKTtcbiAgICAgIHZhciBsYXN0TGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciBzcGxpdExpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IE1BWF9VSU5UMzIgOiBsaW1pdCA+Pj4gMDtcbiAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICB2YXIgc2VwYXJhdG9yQ29weSA9IG5ldyBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgZmxhZ3MgKyAnZycpO1xuICAgICAgdmFyIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGg7XG4gICAgICB3aGlsZSAobWF0Y2ggPSByZWdleHBFeGVjLmNhbGwoc2VwYXJhdG9yQ29weSwgc3RyaW5nKSkge1xuICAgICAgICBsYXN0SW5kZXggPSBzZXBhcmF0b3JDb3B5W0xBU1RfSU5ERVhdO1xuICAgICAgICBpZiAobGFzdEluZGV4ID4gbGFzdExhc3RJbmRleCkge1xuICAgICAgICAgIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgIGlmIChtYXRjaFtMRU5HVEhdID4gMSAmJiBtYXRjaC5pbmRleCA8IHN0cmluZ1tMRU5HVEhdKSAkcHVzaC5hcHBseShvdXRwdXQsIG1hdGNoLnNsaWNlKDEpKTtcbiAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF1bTEVOR1RIXTtcbiAgICAgICAgICBsYXN0TGFzdEluZGV4ID0gbGFzdEluZGV4O1xuICAgICAgICAgIGlmIChvdXRwdXRbTEVOR1RIXSA+PSBzcGxpdExpbWl0KSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VwYXJhdG9yQ29weVtMQVNUX0lOREVYXSA9PT0gbWF0Y2guaW5kZXgpIHNlcGFyYXRvckNvcHlbTEFTVF9JTkRFWF0rKzsgLy8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcFxuICAgICAgfVxuICAgICAgaWYgKGxhc3RMYXN0SW5kZXggPT09IHN0cmluZ1tMRU5HVEhdKSB7XG4gICAgICAgIGlmIChsYXN0TGVuZ3RoIHx8ICFzZXBhcmF0b3JDb3B5LnRlc3QoJycpKSBvdXRwdXQucHVzaCgnJyk7XG4gICAgICB9IGVsc2Ugb3V0cHV0LnB1c2goc3RyaW5nLnNsaWNlKGxhc3RMYXN0SW5kZXgpKTtcbiAgICAgIHJldHVybiBvdXRwdXRbTEVOR1RIXSA+IHNwbGl0TGltaXQgPyBvdXRwdXQuc2xpY2UoMCwgc3BsaXRMaW1pdCkgOiBvdXRwdXQ7XG4gICAgfTtcbiAgLy8gQ2hha3JhLCBWOFxuICB9IGVsc2UgaWYgKCcwJ1skU1BMSVRdKHVuZGVmaW5lZCwgMClbTEVOR1RIXSkge1xuICAgIGludGVybmFsU3BsaXQgPSBmdW5jdGlvbiAoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgcmV0dXJuIHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkICYmIGxpbWl0ID09PSAwID8gW10gOiAkc3BsaXQuY2FsbCh0aGlzLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGludGVybmFsU3BsaXQgPSAkc3BsaXQ7XG4gIH1cblxuICByZXR1cm4gW1xuICAgIC8vIGBTdHJpbmcucHJvdG90eXBlLnNwbGl0YCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLnNwbGl0XG4gICAgZnVuY3Rpb24gc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgdmFyIE8gPSBkZWZpbmVkKHRoaXMpO1xuICAgICAgdmFyIHNwbGl0dGVyID0gc2VwYXJhdG9yID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNlcGFyYXRvcltTUExJVF07XG4gICAgICByZXR1cm4gc3BsaXR0ZXIgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHNwbGl0dGVyLmNhbGwoc2VwYXJhdG9yLCBPLCBsaW1pdClcbiAgICAgICAgOiBpbnRlcm5hbFNwbGl0LmNhbGwoU3RyaW5nKE8pLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAc3BsaXRdYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1yZWdleHAucHJvdG90eXBlLUBAc3BsaXRcbiAgICAvL1xuICAgIC8vIE5PVEU6IFRoaXMgY2Fubm90IGJlIHByb3Blcmx5IHBvbHlmaWxsZWQgaW4gZW5naW5lcyB0aGF0IGRvbid0IHN1cHBvcnRcbiAgICAvLyB0aGUgJ3knIGZsYWcuXG4gICAgZnVuY3Rpb24gKHJlZ2V4cCwgbGltaXQpIHtcbiAgICAgIHZhciByZXMgPSBtYXliZUNhbGxOYXRpdmUoaW50ZXJuYWxTcGxpdCwgcmVnZXhwLCB0aGlzLCBsaW1pdCwgaW50ZXJuYWxTcGxpdCAhPT0gJHNwbGl0KTtcbiAgICAgIGlmIChyZXMuZG9uZSkgcmV0dXJuIHJlcy52YWx1ZTtcblxuICAgICAgdmFyIHJ4ID0gYW5PYmplY3QocmVnZXhwKTtcbiAgICAgIHZhciBTID0gU3RyaW5nKHRoaXMpO1xuICAgICAgdmFyIEMgPSBzcGVjaWVzQ29uc3RydWN0b3IocngsIFJlZ0V4cCk7XG5cbiAgICAgIHZhciB1bmljb2RlTWF0Y2hpbmcgPSByeC51bmljb2RlO1xuICAgICAgdmFyIGZsYWdzID0gKHJ4Lmlnbm9yZUNhc2UgPyAnaScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgKHJ4Lm11bHRpbGluZSA/ICdtJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAocngudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoU1VQUE9SVFNfWSA/ICd5JyA6ICdnJyk7XG5cbiAgICAgIC8vIF4oPyArIHJ4ICsgKSBpcyBuZWVkZWQsIGluIGNvbWJpbmF0aW9uIHdpdGggc29tZSBTIHNsaWNpbmcsIHRvXG4gICAgICAvLyBzaW11bGF0ZSB0aGUgJ3knIGZsYWcuXG4gICAgICB2YXIgc3BsaXR0ZXIgPSBuZXcgQyhTVVBQT1JUU19ZID8gcnggOiAnXig/OicgKyByeC5zb3VyY2UgKyAnKScsIGZsYWdzKTtcbiAgICAgIHZhciBsaW0gPSBsaW1pdCA9PT0gdW5kZWZpbmVkID8gTUFYX1VJTlQzMiA6IGxpbWl0ID4+PiAwO1xuICAgICAgaWYgKGxpbSA9PT0gMCkgcmV0dXJuIFtdO1xuICAgICAgaWYgKFMubGVuZ3RoID09PSAwKSByZXR1cm4gY2FsbFJlZ0V4cEV4ZWMoc3BsaXR0ZXIsIFMpID09PSBudWxsID8gW1NdIDogW107XG4gICAgICB2YXIgcCA9IDA7XG4gICAgICB2YXIgcSA9IDA7XG4gICAgICB2YXIgQSA9IFtdO1xuICAgICAgd2hpbGUgKHEgPCBTLmxlbmd0aCkge1xuICAgICAgICBzcGxpdHRlci5sYXN0SW5kZXggPSBTVVBQT1JUU19ZID8gcSA6IDA7XG4gICAgICAgIHZhciB6ID0gY2FsbFJlZ0V4cEV4ZWMoc3BsaXR0ZXIsIFNVUFBPUlRTX1kgPyBTIDogUy5zbGljZShxKSk7XG4gICAgICAgIHZhciBlO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgeiA9PT0gbnVsbCB8fFxuICAgICAgICAgIChlID0gJG1pbih0b0xlbmd0aChzcGxpdHRlci5sYXN0SW5kZXggKyAoU1VQUE9SVFNfWSA/IDAgOiBxKSksIFMubGVuZ3RoKSkgPT09IHBcbiAgICAgICAgKSB7XG4gICAgICAgICAgcSA9IGFkdmFuY2VTdHJpbmdJbmRleChTLCBxLCB1bmljb2RlTWF0Y2hpbmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEEucHVzaChTLnNsaWNlKHAsIHEpKTtcbiAgICAgICAgICBpZiAoQS5sZW5ndGggPT09IGxpbSkgcmV0dXJuIEE7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gei5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgIEEucHVzaCh6W2ldKTtcbiAgICAgICAgICAgIGlmIChBLmxlbmd0aCA9PT0gbGltKSByZXR1cm4gQTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcSA9IHAgPSBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBBLnB1c2goUy5zbGljZShwKSk7XG4gICAgICByZXR1cm4gQTtcbiAgICB9XG4gIF07XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnJlcXVpcmUoJy4vZXM2LnJlZ2V4cC5mbGFncycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJGZsYWdzID0gcmVxdWlyZSgnLi9fZmxhZ3MnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciAkdG9TdHJpbmcgPSAvLi9bVE9fU1RSSU5HXTtcblxudmFyIGRlZmluZSA9IGZ1bmN0aW9uIChmbikge1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKFJlZ0V4cC5wcm90b3R5cGUsIFRPX1NUUklORywgZm4sIHRydWUpO1xufTtcblxuLy8gMjEuMi41LjE0IFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcoKVxuaWYgKHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkgeyByZXR1cm4gJHRvU3RyaW5nLmNhbGwoeyBzb3VyY2U6ICdhJywgZmxhZ3M6ICdiJyB9KSAhPSAnL2EvYic7IH0pKSB7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICB2YXIgUiA9IGFuT2JqZWN0KHRoaXMpO1xuICAgIHJldHVybiAnLycuY29uY2F0KFIuc291cmNlLCAnLycsXG4gICAgICAnZmxhZ3MnIGluIFIgPyBSLmZsYWdzIDogIURFU0NSSVBUT1JTICYmIFIgaW5zdGFuY2VvZiBSZWdFeHAgPyAkZmxhZ3MuY2FsbChSKSA6IHVuZGVmaW5lZCk7XG4gIH0pO1xuLy8gRkY0NC0gUmVnRXhwI3RvU3RyaW5nIGhhcyBhIHdyb25nIG5hbWVcbn0gZWxzZSBpZiAoJHRvU3RyaW5nLm5hbWUgIT0gVE9fU1RSSU5HKSB7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gJHRvU3RyaW5nLmNhbGwodGhpcyk7XG4gIH0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgU0VUID0gJ1NldCc7XG5cbi8vIDIzLjIgU2V0IE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFNFVCwgZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gU2V0KCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuMi4zLjEgU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgU0VUKSwgdmFsdWUgPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMiBTdHJpbmcucHJvdG90eXBlLmFuY2hvcihuYW1lKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnYW5jaG9yJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGFuY2hvcihuYW1lKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2EnLCAnbmFtZScsIG5hbWUpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4zIFN0cmluZy5wcm90b3R5cGUuYmlnKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JpZycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBiaWcoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2JpZycsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjQgU3RyaW5nLnByb3RvdHlwZS5ibGluaygpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdibGluaycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBibGluaygpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYmxpbmsnLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy41IFN0cmluZy5wcm90b3R5cGUuYm9sZCgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdib2xkJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJvbGQoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2InLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKGZhbHNlKTtcbiRleHBvcnQoJGV4cG9ydC5QLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjMuMyBTdHJpbmcucHJvdG90eXBlLmNvZGVQb2ludEF0KHBvcylcbiAgY29kZVBvaW50QXQ6IGZ1bmN0aW9uIGNvZGVQb2ludEF0KHBvcykge1xuICAgIHJldHVybiAkYXQodGhpcywgcG9zKTtcbiAgfVxufSk7XG4iLCIvLyAyMS4xLjMuNiBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKHNlYXJjaFN0cmluZyBbLCBlbmRQb3NpdGlvbl0pXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgRU5EU19XSVRIID0gJ2VuZHNXaXRoJztcbnZhciAkZW5kc1dpdGggPSAnJ1tFTkRTX1dJVEhdO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzLWlzLXJlZ2V4cCcpKEVORFNfV0lUSCksICdTdHJpbmcnLCB7XG4gIGVuZHNXaXRoOiBmdW5jdGlvbiBlbmRzV2l0aChzZWFyY2hTdHJpbmcgLyogLCBlbmRQb3NpdGlvbiA9IEBsZW5ndGggKi8pIHtcbiAgICB2YXIgdGhhdCA9IGNvbnRleHQodGhpcywgc2VhcmNoU3RyaW5nLCBFTkRTX1dJVEgpO1xuICAgIHZhciBlbmRQb3NpdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBsZW4gPSB0b0xlbmd0aCh0aGF0Lmxlbmd0aCk7XG4gICAgdmFyIGVuZCA9IGVuZFBvc2l0aW9uID09PSB1bmRlZmluZWQgPyBsZW4gOiBNYXRoLm1pbih0b0xlbmd0aChlbmRQb3NpdGlvbiksIGxlbik7XG4gICAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgIHJldHVybiAkZW5kc1dpdGhcbiAgICAgID8gJGVuZHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBlbmQpXG4gICAgICA6IHRoYXQuc2xpY2UoZW5kIC0gc2VhcmNoLmxlbmd0aCwgZW5kKSA9PT0gc2VhcmNoO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjYgU3RyaW5nLnByb3RvdHlwZS5maXhlZCgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdmaXhlZCcsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmaXhlZCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAndHQnLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy43IFN0cmluZy5wcm90b3R5cGUuZm9udGNvbG9yKGNvbG9yKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnZm9udGNvbG9yJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbnRjb2xvcihjb2xvcikge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdmb250JywgJ2NvbG9yJywgY29sb3IpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy44IFN0cmluZy5wcm90b3R5cGUuZm9udHNpemUoc2l6ZSlcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2ZvbnRzaXplJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbnRzaXplKHNpemUpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnZm9udCcsICdzaXplJywgc2l6ZSk7XG4gIH07XG59KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbnZhciBmcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xudmFyICRmcm9tQ29kZVBvaW50ID0gU3RyaW5nLmZyb21Db2RlUG9pbnQ7XG5cbi8vIGxlbmd0aCBzaG91bGQgYmUgMSwgb2xkIEZGIHByb2JsZW1cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCEhJGZyb21Db2RlUG9pbnQgJiYgJGZyb21Db2RlUG9pbnQubGVuZ3RoICE9IDEpLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjIuMiBTdHJpbmcuZnJvbUNvZGVQb2ludCguLi5jb2RlUG9pbnRzKVxuICBmcm9tQ29kZVBvaW50OiBmdW5jdGlvbiBmcm9tQ29kZVBvaW50KHgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIHZhciByZXMgPSBbXTtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBjb2RlO1xuICAgIHdoaWxlIChhTGVuID4gaSkge1xuICAgICAgY29kZSA9ICthcmd1bWVudHNbaSsrXTtcbiAgICAgIGlmICh0b0Fic29sdXRlSW5kZXgoY29kZSwgMHgxMGZmZmYpICE9PSBjb2RlKSB0aHJvdyBSYW5nZUVycm9yKGNvZGUgKyAnIGlzIG5vdCBhIHZhbGlkIGNvZGUgcG9pbnQnKTtcbiAgICAgIHJlcy5wdXNoKGNvZGUgPCAweDEwMDAwXG4gICAgICAgID8gZnJvbUNoYXJDb2RlKGNvZGUpXG4gICAgICAgIDogZnJvbUNoYXJDb2RlKCgoY29kZSAtPSAweDEwMDAwKSA+PiAxMCkgKyAweGQ4MDAsIGNvZGUgJSAweDQwMCArIDB4ZGMwMClcbiAgICAgICk7XG4gICAgfSByZXR1cm4gcmVzLmpvaW4oJycpO1xuICB9XG59KTtcbiIsIi8vIDIxLjEuMy43IFN0cmluZy5wcm90b3R5cGUuaW5jbHVkZXMoc2VhcmNoU3RyaW5nLCBwb3NpdGlvbiA9IDApXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvbnRleHQgPSByZXF1aXJlKCcuL19zdHJpbmctY29udGV4dCcpO1xudmFyIElOQ0xVREVTID0gJ2luY2x1ZGVzJztcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscy1pcy1yZWdleHAnKShJTkNMVURFUyksICdTdHJpbmcnLCB7XG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhzZWFyY2hTdHJpbmcgLyogLCBwb3NpdGlvbiA9IDAgKi8pIHtcbiAgICByZXR1cm4gISF+Y29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIElOQ0xVREVTKVxuICAgICAgLmluZGV4T2Yoc2VhcmNoU3RyaW5nLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuOSBTdHJpbmcucHJvdG90eXBlLml0YWxpY3MoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnaXRhbGljcycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpdGFsaWNzKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdpJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKHRydWUpO1xuXG4vLyAyMS4xLjMuMjcgU3RyaW5nLnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKFN0cmluZywgJ1N0cmluZycsIGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICB0aGlzLl90ID0gU3RyaW5nKGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4vLyAyMS4xLjUuMi4xICVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbiAoKSB7XG4gIHZhciBPID0gdGhpcy5fdDtcbiAgdmFyIGluZGV4ID0gdGhpcy5faTtcbiAgdmFyIHBvaW50O1xuICBpZiAoaW5kZXggPj0gTy5sZW5ndGgpIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgcG9pbnQgPSAkYXQoTywgaW5kZXgpO1xuICB0aGlzLl9pICs9IHBvaW50Lmxlbmd0aDtcbiAgcmV0dXJuIHsgdmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZSB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMCBTdHJpbmcucHJvdG90eXBlLmxpbmsodXJsKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnbGluaycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBsaW5rKHVybCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdhJywgJ2hyZWYnLCB1cmwpO1xuICB9O1xufSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1N0cmluZycsIHtcbiAgLy8gMjEuMS4yLjQgU3RyaW5nLnJhdyhjYWxsU2l0ZSwgLi4uc3Vic3RpdHV0aW9ucylcbiAgcmF3OiBmdW5jdGlvbiByYXcoY2FsbFNpdGUpIHtcbiAgICB2YXIgdHBsID0gdG9JT2JqZWN0KGNhbGxTaXRlLnJhdyk7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHRwbC5sZW5ndGgpO1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgcmVzID0gW107XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChsZW4gPiBpKSB7XG4gICAgICByZXMucHVzaChTdHJpbmcodHBsW2krK10pKTtcbiAgICAgIGlmIChpIDwgYUxlbikgcmVzLnB1c2goU3RyaW5nKGFyZ3VtZW50c1tpXSkpO1xuICAgIH0gcmV0dXJuIHJlcy5qb2luKCcnKTtcbiAgfVxufSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgLy8gMjEuMS4zLjEzIFN0cmluZy5wcm90b3R5cGUucmVwZWF0KGNvdW50KVxuICByZXBlYXQ6IHJlcXVpcmUoJy4vX3N0cmluZy1yZXBlYXQnKVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMSBTdHJpbmcucHJvdG90eXBlLnNtYWxsKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3NtYWxsJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHNtYWxsKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzbWFsbCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIi8vIDIxLjEuMy4xOCBTdHJpbmcucHJvdG90eXBlLnN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nIFssIHBvc2l0aW9uIF0pXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgU1RBUlRTX1dJVEggPSAnc3RhcnRzV2l0aCc7XG52YXIgJHN0YXJ0c1dpdGggPSAnJ1tTVEFSVFNfV0lUSF07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMtaXMtcmVnZXhwJykoU1RBUlRTX1dJVEgpLCAnU3RyaW5nJywge1xuICBzdGFydHNXaXRoOiBmdW5jdGlvbiBzdGFydHNXaXRoKHNlYXJjaFN0cmluZyAvKiAsIHBvc2l0aW9uID0gMCAqLykge1xuICAgIHZhciB0aGF0ID0gY29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIFNUQVJUU19XSVRIKTtcbiAgICB2YXIgaW5kZXggPSB0b0xlbmd0aChNYXRoLm1pbihhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgdGhhdC5sZW5ndGgpKTtcbiAgICB2YXIgc2VhcmNoID0gU3RyaW5nKHNlYXJjaFN0cmluZyk7XG4gICAgcmV0dXJuICRzdGFydHNXaXRoXG4gICAgICA/ICRzdGFydHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBpbmRleClcbiAgICAgIDogdGhhdC5zbGljZShpbmRleCwgaW5kZXggKyBzZWFyY2gubGVuZ3RoKSA9PT0gc2VhcmNoO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEyIFN0cmluZy5wcm90b3R5cGUuc3RyaWtlKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N0cmlrZScsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdHJpa2UoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N0cmlrZScsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEzIFN0cmluZy5wcm90b3R5cGUuc3ViKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N1YicsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdWIoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N1YicsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjE0IFN0cmluZy5wcm90b3R5cGUuc3VwKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N1cCcsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdXAoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N1cCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIxLjEuMy4yNSBTdHJpbmcucHJvdG90eXBlLnRyaW0oKVxucmVxdWlyZSgnLi9fc3RyaW5nLXRyaW0nKSgndHJpbScsIGZ1bmN0aW9uICgkdHJpbSkge1xuICByZXR1cm4gZnVuY3Rpb24gdHJpbSgpIHtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEVDTUFTY3JpcHQgNiBzeW1ib2xzIHNoaW1cbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBNRVRBID0gcmVxdWlyZSgnLi9fbWV0YScpLktFWTtcbnZhciAkZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpO1xudmFyIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciB3a3NFeHQgPSByZXF1aXJlKCcuL193a3MtZXh0Jyk7XG52YXIgd2tzRGVmaW5lID0gcmVxdWlyZSgnLi9fd2tzLWRlZmluZScpO1xudmFyIGVudW1LZXlzID0gcmVxdWlyZSgnLi9fZW51bS1rZXlzJyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG52YXIgX2NyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciBnT1BORXh0ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0Jyk7XG52YXIgJEdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyICREUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BEID0gJEdPUEQuZjtcbnZhciBkUCA9ICREUC5mO1xudmFyIGdPUE4gPSBnT1BORXh0LmY7XG52YXIgJFN5bWJvbCA9IGdsb2JhbC5TeW1ib2w7XG52YXIgJEpTT04gPSBnbG9iYWwuSlNPTjtcbnZhciBfc3RyaW5naWZ5ID0gJEpTT04gJiYgJEpTT04uc3RyaW5naWZ5O1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xudmFyIEhJRERFTiA9IHdrcygnX2hpZGRlbicpO1xudmFyIFRPX1BSSU1JVElWRSA9IHdrcygndG9QcmltaXRpdmUnKTtcbnZhciBpc0VudW0gPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbnZhciBTeW1ib2xSZWdpc3RyeSA9IHNoYXJlZCgnc3ltYm9sLXJlZ2lzdHJ5Jyk7XG52YXIgQWxsU3ltYm9scyA9IHNoYXJlZCgnc3ltYm9scycpO1xudmFyIE9QU3ltYm9scyA9IHNoYXJlZCgnb3Atc3ltYm9scycpO1xudmFyIE9iamVjdFByb3RvID0gT2JqZWN0W1BST1RPVFlQRV07XG52YXIgVVNFX05BVElWRSA9IHR5cGVvZiAkU3ltYm9sID09ICdmdW5jdGlvbic7XG52YXIgUU9iamVjdCA9IGdsb2JhbC5RT2JqZWN0O1xuLy8gRG9uJ3QgdXNlIHNldHRlcnMgaW4gUXQgU2NyaXB0LCBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMTczXG52YXIgc2V0dGVyID0gIVFPYmplY3QgfHwgIVFPYmplY3RbUFJPVE9UWVBFXSB8fCAhUU9iamVjdFtQUk9UT1RZUEVdLmZpbmRDaGlsZDtcblxuLy8gZmFsbGJhY2sgZm9yIG9sZCBBbmRyb2lkLCBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9Njg3XG52YXIgc2V0U3ltYm9sRGVzYyA9IERFU0NSSVBUT1JTICYmICRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBfY3JlYXRlKGRQKHt9LCAnYScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRQKHRoaXMsICdhJywgeyB2YWx1ZTogNyB9KS5hOyB9XG4gIH0pKS5hICE9IDc7XG59KSA/IGZ1bmN0aW9uIChpdCwga2V5LCBEKSB7XG4gIHZhciBwcm90b0Rlc2MgPSBnT1BEKE9iamVjdFByb3RvLCBrZXkpO1xuICBpZiAocHJvdG9EZXNjKSBkZWxldGUgT2JqZWN0UHJvdG9ba2V5XTtcbiAgZFAoaXQsIGtleSwgRCk7XG4gIGlmIChwcm90b0Rlc2MgJiYgaXQgIT09IE9iamVjdFByb3RvKSBkUChPYmplY3RQcm90bywga2V5LCBwcm90b0Rlc2MpO1xufSA6IGRQO1xuXG52YXIgd3JhcCA9IGZ1bmN0aW9uICh0YWcpIHtcbiAgdmFyIHN5bSA9IEFsbFN5bWJvbHNbdGFnXSA9IF9jcmVhdGUoJFN5bWJvbFtQUk9UT1RZUEVdKTtcbiAgc3ltLl9rID0gdGFnO1xuICByZXR1cm4gc3ltO1xufTtcblxudmFyIGlzU3ltYm9sID0gVVNFX05BVElWRSAmJiB0eXBlb2YgJFN5bWJvbC5pdGVyYXRvciA9PSAnc3ltYm9sJyA/IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnO1xufSA6IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgaW5zdGFuY2VvZiAkU3ltYm9sO1xufTtcblxudmFyICRkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KGl0LCBrZXksIEQpIHtcbiAgaWYgKGl0ID09PSBPYmplY3RQcm90bykgJGRlZmluZVByb3BlcnR5KE9QU3ltYm9scywga2V5LCBEKTtcbiAgYW5PYmplY3QoaXQpO1xuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xuICBhbk9iamVjdChEKTtcbiAgaWYgKGhhcyhBbGxTeW1ib2xzLCBrZXkpKSB7XG4gICAgaWYgKCFELmVudW1lcmFibGUpIHtcbiAgICAgIGlmICghaGFzKGl0LCBISURERU4pKSBkUChpdCwgSElEREVOLCBjcmVhdGVEZXNjKDEsIHt9KSk7XG4gICAgICBpdFtISURERU5dW2tleV0gPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaGFzKGl0LCBISURERU4pICYmIGl0W0hJRERFTl1ba2V5XSkgaXRbSElEREVOXVtrZXldID0gZmFsc2U7XG4gICAgICBEID0gX2NyZWF0ZShELCB7IGVudW1lcmFibGU6IGNyZWF0ZURlc2MoMCwgZmFsc2UpIH0pO1xuICAgIH0gcmV0dXJuIHNldFN5bWJvbERlc2MoaXQsIGtleSwgRCk7XG4gIH0gcmV0dXJuIGRQKGl0LCBrZXksIEQpO1xufTtcbnZhciAkZGVmaW5lUHJvcGVydGllcyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoaXQsIFApIHtcbiAgYW5PYmplY3QoaXQpO1xuICB2YXIga2V5cyA9IGVudW1LZXlzKFAgPSB0b0lPYmplY3QoUCkpO1xuICB2YXIgaSA9IDA7XG4gIHZhciBsID0ga2V5cy5sZW5ndGg7XG4gIHZhciBrZXk7XG4gIHdoaWxlIChsID4gaSkgJGRlZmluZVByb3BlcnR5KGl0LCBrZXkgPSBrZXlzW2krK10sIFBba2V5XSk7XG4gIHJldHVybiBpdDtcbn07XG52YXIgJGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpdCwgUCkge1xuICByZXR1cm4gUCA9PT0gdW5kZWZpbmVkID8gX2NyZWF0ZShpdCkgOiAkZGVmaW5lUHJvcGVydGllcyhfY3JlYXRlKGl0KSwgUCk7XG59O1xudmFyICRwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uIHByb3BlcnR5SXNFbnVtZXJhYmxlKGtleSkge1xuICB2YXIgRSA9IGlzRW51bS5jYWxsKHRoaXMsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpO1xuICBpZiAodGhpcyA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIEUgfHwgIWhhcyh0aGlzLCBrZXkpIHx8ICFoYXMoQWxsU3ltYm9scywga2V5KSB8fCBoYXModGhpcywgSElEREVOKSAmJiB0aGlzW0hJRERFTl1ba2V5XSA/IEUgOiB0cnVlO1xufTtcbnZhciAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpIHtcbiAgaXQgPSB0b0lPYmplY3QoaXQpO1xuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xuICBpZiAoaXQgPT09IE9iamVjdFByb3RvICYmIGhhcyhBbGxTeW1ib2xzLCBrZXkpICYmICFoYXMoT1BTeW1ib2xzLCBrZXkpKSByZXR1cm47XG4gIHZhciBEID0gZ09QRChpdCwga2V5KTtcbiAgaWYgKEQgJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIShoYXMoaXQsIEhJRERFTikgJiYgaXRbSElEREVOXVtrZXldKSkgRC5lbnVtZXJhYmxlID0gdHJ1ZTtcbiAgcmV0dXJuIEQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eU5hbWVzID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCkge1xuICB2YXIgbmFtZXMgPSBnT1BOKHRvSU9iamVjdChpdCkpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBpID0gMDtcbiAgdmFyIGtleTtcbiAgd2hpbGUgKG5hbWVzLmxlbmd0aCA+IGkpIHtcbiAgICBpZiAoIWhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiBrZXkgIT0gSElEREVOICYmIGtleSAhPSBNRVRBKSByZXN1bHQucHVzaChrZXkpO1xuICB9IHJldHVybiByZXN1bHQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoaXQpIHtcbiAgdmFyIElTX09QID0gaXQgPT09IE9iamVjdFByb3RvO1xuICB2YXIgbmFtZXMgPSBnT1BOKElTX09QID8gT1BTeW1ib2xzIDogdG9JT2JqZWN0KGl0KSk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIga2V5O1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkge1xuICAgIGlmIChoYXMoQWxsU3ltYm9scywga2V5ID0gbmFtZXNbaSsrXSkgJiYgKElTX09QID8gaGFzKE9iamVjdFByb3RvLCBrZXkpIDogdHJ1ZSkpIHJlc3VsdC5wdXNoKEFsbFN5bWJvbHNba2V5XSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8vIDE5LjQuMS4xIFN5bWJvbChbZGVzY3JpcHRpb25dKVxuaWYgKCFVU0VfTkFUSVZFKSB7XG4gICRTeW1ib2wgPSBmdW5jdGlvbiBTeW1ib2woKSB7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiAkU3ltYm9sKSB0aHJvdyBUeXBlRXJyb3IoJ1N5bWJvbCBpcyBub3QgYSBjb25zdHJ1Y3RvciEnKTtcbiAgICB2YXIgdGFnID0gdWlkKGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTtcbiAgICB2YXIgJHNldCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgaWYgKHRoaXMgPT09IE9iamVjdFByb3RvKSAkc2V0LmNhbGwoT1BTeW1ib2xzLCB2YWx1ZSk7XG4gICAgICBpZiAoaGFzKHRoaXMsIEhJRERFTikgJiYgaGFzKHRoaXNbSElEREVOXSwgdGFnKSkgdGhpc1tISURERU5dW3RhZ10gPSBmYWxzZTtcbiAgICAgIHNldFN5bWJvbERlc2ModGhpcywgdGFnLCBjcmVhdGVEZXNjKDEsIHZhbHVlKSk7XG4gICAgfTtcbiAgICBpZiAoREVTQ1JJUFRPUlMgJiYgc2V0dGVyKSBzZXRTeW1ib2xEZXNjKE9iamVjdFByb3RvLCB0YWcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCBzZXQ6ICRzZXQgfSk7XG4gICAgcmV0dXJuIHdyYXAodGFnKTtcbiAgfTtcbiAgcmVkZWZpbmUoJFN5bWJvbFtQUk9UT1RZUEVdLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5faztcbiAgfSk7XG5cbiAgJEdPUEQuZiA9ICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG4gICREUC5mID0gJGRlZmluZVByb3BlcnR5O1xuICByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmYgPSBnT1BORXh0LmYgPSAkZ2V0T3duUHJvcGVydHlOYW1lcztcbiAgcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpLmYgPSAkcHJvcGVydHlJc0VudW1lcmFibGU7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJykuZiA9ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbiAgaWYgKERFU0NSSVBUT1JTICYmICFyZXF1aXJlKCcuL19saWJyYXJ5JykpIHtcbiAgICByZWRlZmluZShPYmplY3RQcm90bywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJywgJHByb3BlcnR5SXNFbnVtZXJhYmxlLCB0cnVlKTtcbiAgfVxuXG4gIHdrc0V4dC5mID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICByZXR1cm4gd3JhcCh3a3MobmFtZSkpO1xuICB9O1xufVxuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCB7IFN5bWJvbDogJFN5bWJvbCB9KTtcblxuZm9yICh2YXIgZXM2U3ltYm9scyA9IChcbiAgLy8gMTkuNC4yLjIsIDE5LjQuMi4zLCAxOS40LjIuNCwgMTkuNC4yLjYsIDE5LjQuMi44LCAxOS40LjIuOSwgMTkuNC4yLjEwLCAxOS40LjIuMTEsIDE5LjQuMi4xMiwgMTkuNC4yLjEzLCAxOS40LjIuMTRcbiAgJ2hhc0luc3RhbmNlLGlzQ29uY2F0U3ByZWFkYWJsZSxpdGVyYXRvcixtYXRjaCxyZXBsYWNlLHNlYXJjaCxzcGVjaWVzLHNwbGl0LHRvUHJpbWl0aXZlLHRvU3RyaW5nVGFnLHVuc2NvcGFibGVzJ1xuKS5zcGxpdCgnLCcpLCBqID0gMDsgZXM2U3ltYm9scy5sZW5ndGggPiBqOyl3a3MoZXM2U3ltYm9sc1tqKytdKTtcblxuZm9yICh2YXIgd2VsbEtub3duU3ltYm9scyA9ICRrZXlzKHdrcy5zdG9yZSksIGsgPSAwOyB3ZWxsS25vd25TeW1ib2xzLmxlbmd0aCA+IGs7KSB3a3NEZWZpbmUod2VsbEtub3duU3ltYm9sc1trKytdKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgJ1N5bWJvbCcsIHtcbiAgLy8gMTkuNC4yLjEgU3ltYm9sLmZvcihrZXkpXG4gICdmb3InOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGhhcyhTeW1ib2xSZWdpc3RyeSwga2V5ICs9ICcnKVxuICAgICAgPyBTeW1ib2xSZWdpc3RyeVtrZXldXG4gICAgICA6IFN5bWJvbFJlZ2lzdHJ5W2tleV0gPSAkU3ltYm9sKGtleSk7XG4gIH0sXG4gIC8vIDE5LjQuMi41IFN5bWJvbC5rZXlGb3Ioc3ltKVxuICBrZXlGb3I6IGZ1bmN0aW9uIGtleUZvcihzeW0pIHtcbiAgICBpZiAoIWlzU3ltYm9sKHN5bSkpIHRocm93IFR5cGVFcnJvcihzeW0gKyAnIGlzIG5vdCBhIHN5bWJvbCEnKTtcbiAgICBmb3IgKHZhciBrZXkgaW4gU3ltYm9sUmVnaXN0cnkpIGlmIChTeW1ib2xSZWdpc3RyeVtrZXldID09PSBzeW0pIHJldHVybiBrZXk7XG4gIH0sXG4gIHVzZVNldHRlcjogZnVuY3Rpb24gKCkgeyBzZXR0ZXIgPSB0cnVlOyB9LFxuICB1c2VTaW1wbGU6IGZ1bmN0aW9uICgpIHsgc2V0dGVyID0gZmFsc2U7IH1cbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCAnT2JqZWN0Jywge1xuICAvLyAxOS4xLjIuMiBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXG4gIGNyZWF0ZTogJGNyZWF0ZSxcbiAgLy8gMTkuMS4yLjQgT2JqZWN0LmRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpXG4gIGRlZmluZVByb3BlcnR5OiAkZGVmaW5lUHJvcGVydHksXG4gIC8vIDE5LjEuMi4zIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpXG4gIGRlZmluZVByb3BlcnRpZXM6ICRkZWZpbmVQcm9wZXJ0aWVzLFxuICAvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogJGdldE93blByb3BlcnR5RGVzY3JpcHRvcixcbiAgLy8gMTkuMS4yLjcgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbiAgZ2V0T3duUHJvcGVydHlOYW1lczogJGdldE93blByb3BlcnR5TmFtZXMsXG4gIC8vIDE5LjEuMi44IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoTylcbiAgZ2V0T3duUHJvcGVydHlTeW1ib2xzOiAkZ2V0T3duUHJvcGVydHlTeW1ib2xzXG59KTtcblxuLy8gMjQuMy4yIEpTT04uc3RyaW5naWZ5KHZhbHVlIFssIHJlcGxhY2VyIFssIHNwYWNlXV0pXG4kSlNPTiAmJiAkZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICghVVNFX05BVElWRSB8fCAkZmFpbHMoZnVuY3Rpb24gKCkge1xuICB2YXIgUyA9ICRTeW1ib2woKTtcbiAgLy8gTVMgRWRnZSBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMge31cbiAgLy8gV2ViS2l0IGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyBudWxsXG4gIC8vIFY4IHRocm93cyBvbiBib3hlZCBzeW1ib2xzXG4gIHJldHVybiBfc3RyaW5naWZ5KFtTXSkgIT0gJ1tudWxsXScgfHwgX3N0cmluZ2lmeSh7IGE6IFMgfSkgIT0gJ3t9JyB8fCBfc3RyaW5naWZ5KE9iamVjdChTKSkgIT0gJ3t9Jztcbn0pKSwgJ0pTT04nLCB7XG4gIHN0cmluZ2lmeTogZnVuY3Rpb24gc3RyaW5naWZ5KGl0KSB7XG4gICAgdmFyIGFyZ3MgPSBbaXRdO1xuICAgIHZhciBpID0gMTtcbiAgICB2YXIgcmVwbGFjZXIsICRyZXBsYWNlcjtcbiAgICB3aGlsZSAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgJHJlcGxhY2VyID0gcmVwbGFjZXIgPSBhcmdzWzFdO1xuICAgIGlmICghaXNPYmplY3QocmVwbGFjZXIpICYmIGl0ID09PSB1bmRlZmluZWQgfHwgaXNTeW1ib2woaXQpKSByZXR1cm47IC8vIElFOCByZXR1cm5zIHN0cmluZyBvbiB1bmRlZmluZWRcbiAgICBpZiAoIWlzQXJyYXkocmVwbGFjZXIpKSByZXBsYWNlciA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mICRyZXBsYWNlciA9PSAnZnVuY3Rpb24nKSB2YWx1ZSA9ICRyZXBsYWNlci5jYWxsKHRoaXMsIGtleSwgdmFsdWUpO1xuICAgICAgaWYgKCFpc1N5bWJvbCh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgICB9O1xuICAgIGFyZ3NbMV0gPSByZXBsYWNlcjtcbiAgICByZXR1cm4gX3N0cmluZ2lmeS5hcHBseSgkSlNPTiwgYXJncyk7XG4gIH1cbn0pO1xuXG4vLyAxOS40LjMuNCBTeW1ib2wucHJvdG90eXBlW0BAdG9QcmltaXRpdmVdKGhpbnQpXG4kU3ltYm9sW1BST1RPVFlQRV1bVE9fUFJJTUlUSVZFXSB8fCByZXF1aXJlKCcuL19oaWRlJykoJFN5bWJvbFtQUk9UT1RZUEVdLCBUT19QUklNSVRJVkUsICRTeW1ib2xbUFJPVE9UWVBFXS52YWx1ZU9mKTtcbi8vIDE5LjQuMy41IFN5bWJvbC5wcm90b3R5cGVbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKCRTeW1ib2wsICdTeW1ib2wnKTtcbi8vIDIwLjIuMS45IE1hdGhbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKE1hdGgsICdNYXRoJywgdHJ1ZSk7XG4vLyAyNC4zLjMgSlNPTltAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoZ2xvYmFsLkpTT04sICdKU09OJywgdHJ1ZSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICR0eXBlZCA9IHJlcXVpcmUoJy4vX3R5cGVkJyk7XG52YXIgYnVmZmVyID0gcmVxdWlyZSgnLi9fdHlwZWQtYnVmZmVyJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBBcnJheUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLkFycmF5QnVmZmVyO1xudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKTtcbnZhciAkQXJyYXlCdWZmZXIgPSBidWZmZXIuQXJyYXlCdWZmZXI7XG52YXIgJERhdGFWaWV3ID0gYnVmZmVyLkRhdGFWaWV3O1xudmFyICRpc1ZpZXcgPSAkdHlwZWQuQUJWICYmIEFycmF5QnVmZmVyLmlzVmlldztcbnZhciAkc2xpY2UgPSAkQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlO1xudmFyIFZJRVcgPSAkdHlwZWQuVklFVztcbnZhciBBUlJBWV9CVUZGRVIgPSAnQXJyYXlCdWZmZXInO1xuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChBcnJheUJ1ZmZlciAhPT0gJEFycmF5QnVmZmVyKSwgeyBBcnJheUJ1ZmZlcjogJEFycmF5QnVmZmVyIH0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEkdHlwZWQuQ09OU1RSLCBBUlJBWV9CVUZGRVIsIHtcbiAgLy8gMjQuMS4zLjEgQXJyYXlCdWZmZXIuaXNWaWV3KGFyZylcbiAgaXNWaWV3OiBmdW5jdGlvbiBpc1ZpZXcoaXQpIHtcbiAgICByZXR1cm4gJGlzVmlldyAmJiAkaXNWaWV3KGl0KSB8fCBpc09iamVjdChpdCkgJiYgVklFVyBpbiBpdDtcbiAgfVxufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5VICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhbmV3ICRBcnJheUJ1ZmZlcigyKS5zbGljZSgxLCB1bmRlZmluZWQpLmJ5dGVMZW5ndGg7XG59KSwgQVJSQVlfQlVGRkVSLCB7XG4gIC8vIDI0LjEuNC4zIEFycmF5QnVmZmVyLnByb3RvdHlwZS5zbGljZShzdGFydCwgZW5kKVxuICBzbGljZTogZnVuY3Rpb24gc2xpY2Uoc3RhcnQsIGVuZCkge1xuICAgIGlmICgkc2xpY2UgIT09IHVuZGVmaW5lZCAmJiBlbmQgPT09IHVuZGVmaW5lZCkgcmV0dXJuICRzbGljZS5jYWxsKGFuT2JqZWN0KHRoaXMpLCBzdGFydCk7IC8vIEZGIGZpeFxuICAgIHZhciBsZW4gPSBhbk9iamVjdCh0aGlzKS5ieXRlTGVuZ3RoO1xuICAgIHZhciBmaXJzdCA9IHRvQWJzb2x1dGVJbmRleChzdGFydCwgbGVuKTtcbiAgICB2YXIgZmluID0gdG9BYnNvbHV0ZUluZGV4KGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogZW5kLCBsZW4pO1xuICAgIHZhciByZXN1bHQgPSBuZXcgKHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkQXJyYXlCdWZmZXIpKSh0b0xlbmd0aChmaW4gLSBmaXJzdCkpO1xuICAgIHZhciB2aWV3UyA9IG5ldyAkRGF0YVZpZXcodGhpcyk7XG4gICAgdmFyIHZpZXdUID0gbmV3ICREYXRhVmlldyhyZXN1bHQpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgd2hpbGUgKGZpcnN0IDwgZmluKSB7XG4gICAgICB2aWV3VC5zZXRVaW50OChpbmRleCsrLCB2aWV3Uy5nZXRVaW50OChmaXJzdCsrKSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcblxucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShBUlJBWV9CVUZGRVIpO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3R5cGVkJykuQUJWLCB7XG4gIERhdGFWaWV3OiByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKS5EYXRhVmlld1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdGbG9hdDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEZsb2F0MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdGbG9hdDY0JywgOCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEZsb2F0NjRBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdJbnQxNicsIDIsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBJbnQxNkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0ludDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDMyQXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50OCcsIDEsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBJbnQ4QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDE2JywgMiwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQxNkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQzMicsIDQsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBVaW50MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdVaW50OCcsIDEsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBVaW50OEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQ4JywgMSwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQ4Q2xhbXBlZEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59LCB0cnVlKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBlYWNoID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDApO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpO1xudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vX29iamVjdC1hc3NpZ24nKTtcbnZhciB3ZWFrID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi13ZWFrJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBOQVRJVkVfV0VBS19NQVAgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgSVNfSUUxMSA9ICFnbG9iYWwuQWN0aXZlWE9iamVjdCAmJiAnQWN0aXZlWE9iamVjdCcgaW4gZ2xvYmFsO1xudmFyIFdFQUtfTUFQID0gJ1dlYWtNYXAnO1xudmFyIGdldFdlYWsgPSBtZXRhLmdldFdlYWs7XG52YXIgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZTtcbnZhciB1bmNhdWdodEZyb3plblN0b3JlID0gd2Vhay51ZnN0b3JlO1xudmFyIEludGVybmFsTWFwO1xuXG52YXIgd3JhcHBlciA9IGZ1bmN0aW9uIChnZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFdlYWtNYXAoKSB7XG4gICAgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7XG4gIH07XG59O1xuXG52YXIgbWV0aG9kcyA9IHtcbiAgLy8gMjMuMy4zLjMgV2Vha01hcC5wcm90b3R5cGUuZ2V0KGtleSlcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoa2V5KSB7XG4gICAgaWYgKGlzT2JqZWN0KGtleSkpIHtcbiAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgaWYgKGRhdGEgPT09IHRydWUpIHJldHVybiB1bmNhdWdodEZyb3plblN0b3JlKHZhbGlkYXRlKHRoaXMsIFdFQUtfTUFQKSkuZ2V0KGtleSk7XG4gICAgICByZXR1cm4gZGF0YSA/IGRhdGFbdGhpcy5faV0gOiB1bmRlZmluZWQ7XG4gICAgfVxuICB9LFxuICAvLyAyMy4zLjMuNSBXZWFrTWFwLnByb3RvdHlwZS5zZXQoa2V5LCB2YWx1ZSlcbiAgc2V0OiBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiB3ZWFrLmRlZih2YWxpZGF0ZSh0aGlzLCBXRUFLX01BUCksIGtleSwgdmFsdWUpO1xuICB9XG59O1xuXG4vLyAyMy4zIFdlYWtNYXAgT2JqZWN0c1xudmFyICRXZWFrTWFwID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoV0VBS19NQVAsIHdyYXBwZXIsIG1ldGhvZHMsIHdlYWssIHRydWUsIHRydWUpO1xuXG4vLyBJRTExIFdlYWtNYXAgZnJvemVuIGtleXMgZml4XG5pZiAoTkFUSVZFX1dFQUtfTUFQICYmIElTX0lFMTEpIHtcbiAgSW50ZXJuYWxNYXAgPSB3ZWFrLmdldENvbnN0cnVjdG9yKHdyYXBwZXIsIFdFQUtfTUFQKTtcbiAgYXNzaWduKEludGVybmFsTWFwLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gIG1ldGEuTkVFRCA9IHRydWU7XG4gIGVhY2goWydkZWxldGUnLCAnaGFzJywgJ2dldCcsICdzZXQnXSwgZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBwcm90byA9ICRXZWFrTWFwLnByb3RvdHlwZTtcbiAgICB2YXIgbWV0aG9kID0gcHJvdG9ba2V5XTtcbiAgICByZWRlZmluZShwcm90bywga2V5LCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgLy8gc3RvcmUgZnJvemVuIG9iamVjdHMgb24gaW50ZXJuYWwgd2Vha21hcCBzaGltXG4gICAgICBpZiAoaXNPYmplY3QoYSkgJiYgIWlzRXh0ZW5zaWJsZShhKSkge1xuICAgICAgICBpZiAoIXRoaXMuX2YpIHRoaXMuX2YgPSBuZXcgSW50ZXJuYWxNYXAoKTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuX2Zba2V5XShhLCBiKTtcbiAgICAgICAgcmV0dXJuIGtleSA9PSAnc2V0JyA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICAvLyBzdG9yZSBhbGwgdGhlIHJlc3Qgb24gbmF0aXZlIHdlYWttYXBcbiAgICAgIH0gcmV0dXJuIG1ldGhvZC5jYWxsKHRoaXMsIGEsIGIpO1xuICAgIH0pO1xuICB9KTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcbnZhciB3ZWFrID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi13ZWFrJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgV0VBS19TRVQgPSAnV2Vha1NldCc7XG5cbi8vIDIzLjQgV2Vha1NldCBPYmplY3RzXG5yZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoV0VBS19TRVQsIGZ1bmN0aW9uIChnZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFdlYWtTZXQoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy40LjMuMSBXZWFrU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHdlYWsuZGVmKHZhbGlkYXRlKHRoaXMsIFdFQUtfU0VUKSwgdmFsdWUsIHRydWUpO1xuICB9XG59LCB3ZWFrLCBmYWxzZSwgdHJ1ZSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLWZsYXRNYXAvI3NlYy1BcnJheS5wcm90b3R5cGUuZmxhdE1hcFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBmbGF0dGVuSW50b0FycmF5ID0gcmVxdWlyZSgnLi9fZmxhdHRlbi1pbnRvLWFycmF5Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBhcnJheVNwZWNpZXNDcmVhdGUgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge1xuICBmbGF0TWFwOiBmdW5jdGlvbiBmbGF0TWFwKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgdmFyIE8gPSB0b09iamVjdCh0aGlzKTtcbiAgICB2YXIgc291cmNlTGVuLCBBO1xuICAgIGFGdW5jdGlvbihjYWxsYmFja2ZuKTtcbiAgICBzb3VyY2VMZW4gPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgQSA9IGFycmF5U3BlY2llc0NyZWF0ZShPLCAwKTtcbiAgICBmbGF0dGVuSW50b0FycmF5KEEsIE8sIE8sIHNvdXJjZUxlbiwgMCwgMSwgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgICByZXR1cm4gQTtcbiAgfVxufSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdmbGF0TWFwJyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLWZsYXRNYXAvI3NlYy1BcnJheS5wcm90b3R5cGUuZmxhdHRlblxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBmbGF0dGVuSW50b0FycmF5ID0gcmVxdWlyZSgnLi9fZmxhdHRlbi1pbnRvLWFycmF5Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBhcnJheVNwZWNpZXNDcmVhdGUgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge1xuICBmbGF0dGVuOiBmdW5jdGlvbiBmbGF0dGVuKC8qIGRlcHRoQXJnID0gMSAqLykge1xuICAgIHZhciBkZXB0aEFyZyA9IGFyZ3VtZW50c1swXTtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICAgIHZhciBzb3VyY2VMZW4gPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgdmFyIEEgPSBhcnJheVNwZWNpZXNDcmVhdGUoTywgMCk7XG4gICAgZmxhdHRlbkludG9BcnJheShBLCBPLCBPLCBzb3VyY2VMZW4sIDAsIGRlcHRoQXJnID09PSB1bmRlZmluZWQgPyAxIDogdG9JbnRlZ2VyKGRlcHRoQXJnKSk7XG4gICAgcmV0dXJuIEE7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKSgnZmxhdHRlbicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvQXJyYXkucHJvdG90eXBlLmluY2x1ZGVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRpbmNsdWRlcyA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykodHJ1ZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnQXJyYXknLCB7XG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhlbCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gJGluY2x1ZGVzKHRoaXMsIGVsLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKSgnaW5jbHVkZXMnKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9yd2FsZHJvbi90YzM5LW5vdGVzL2Jsb2IvbWFzdGVyL2VzNi8yMDE0LTA5L3NlcHQtMjUubWQjNTEwLWdsb2JhbGFzYXAtZm9yLWVucXVldWluZy1hLW1pY3JvdGFza1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBtaWNyb3Rhc2sgPSByZXF1aXJlKCcuL19taWNyb3Rhc2snKSgpO1xudmFyIHByb2Nlc3MgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wcm9jZXNzO1xudmFyIGlzTm9kZSA9IHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJztcblxuJGV4cG9ydCgkZXhwb3J0LkcsIHtcbiAgYXNhcDogZnVuY3Rpb24gYXNhcChmbikge1xuICAgIHZhciBkb21haW4gPSBpc05vZGUgJiYgcHJvY2Vzcy5kb21haW47XG4gICAgbWljcm90YXNrKGRvbWFpbiA/IGRvbWFpbi5iaW5kKGZuKSA6IGZuKTtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL3Byb3Bvc2FsLWlzLWVycm9yXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0Vycm9yJywge1xuICBpc0Vycm9yOiBmdW5jdGlvbiBpc0Vycm9yKGl0KSB7XG4gICAgcmV0dXJuIGNvZihpdCkgPT09ICdFcnJvcic7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtZ2xvYmFsXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuRywgeyBnbG9iYWw6IHJlcXVpcmUoJy4vX2dsb2JhbCcpIH0pO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnTWFwJyk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy1tYXAub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ01hcCcpO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL0RhdmlkQnJ1YW50L01hcC1TZXQucHJvdG90eXBlLnRvSlNPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdNYXAnLCB7IHRvSlNPTjogcmVxdWlyZSgnLi9fY29sbGVjdGlvbi10by1qc29uJykoJ01hcCcpIH0pO1xuIiwiLy8gaHR0cHM6Ly9yd2FsZHJvbi5naXRodWIuaW8vcHJvcG9zYWwtbWF0aC1leHRlbnNpb25zL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjbGFtcDogZnVuY3Rpb24gY2xhbXAoeCwgbG93ZXIsIHVwcGVyKSB7XG4gICAgcmV0dXJuIE1hdGgubWluKHVwcGVyLCBNYXRoLm1heChsb3dlciwgeCkpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vcndhbGRyb24uZ2l0aHViLmlvL3Byb3Bvc2FsLW1hdGgtZXh0ZW5zaW9ucy9cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgREVHX1BFUl9SQUQ6IE1hdGguUEkgLyAxODAgfSk7XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIFJBRF9QRVJfREVHID0gMTgwIC8gTWF0aC5QSTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBkZWdyZWVzOiBmdW5jdGlvbiBkZWdyZWVzKHJhZGlhbnMpIHtcbiAgICByZXR1cm4gcmFkaWFucyAqIFJBRF9QRVJfREVHO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vcndhbGRyb24uZ2l0aHViLmlvL3Byb3Bvc2FsLW1hdGgtZXh0ZW5zaW9ucy9cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgc2NhbGUgPSByZXF1aXJlKCcuL19tYXRoLXNjYWxlJyk7XG52YXIgZnJvdW5kID0gcmVxdWlyZSgnLi9fbWF0aC1mcm91bmQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBmc2NhbGU6IGZ1bmN0aW9uIGZzY2FsZSh4LCBpbkxvdywgaW5IaWdoLCBvdXRMb3csIG91dEhpZ2gpIHtcbiAgICByZXR1cm4gZnJvdW5kKHNjYWxlKHgsIGluTG93LCBpbkhpZ2gsIG91dExvdywgb3V0SGlnaCkpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGlhZGRoOiBmdW5jdGlvbiBpYWRkaCh4MCwgeDEsIHkwLCB5MSkge1xuICAgIHZhciAkeDAgPSB4MCA+Pj4gMDtcbiAgICB2YXIgJHgxID0geDEgPj4+IDA7XG4gICAgdmFyICR5MCA9IHkwID4+PiAwO1xuICAgIHJldHVybiAkeDEgKyAoeTEgPj4+IDApICsgKCgkeDAgJiAkeTAgfCAoJHgwIHwgJHkwKSAmIH4oJHgwICsgJHkwID4+PiAwKSkgPj4+IDMxKSB8IDA7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vQnJlbmRhbkVpY2gvNDI5NGQ1YzIxMmE2ZDIyNTQ3MDNcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgaW11bGg6IGZ1bmN0aW9uIGltdWxoKHUsIHYpIHtcbiAgICB2YXIgVUlOVDE2ID0gMHhmZmZmO1xuICAgIHZhciAkdSA9ICt1O1xuICAgIHZhciAkdiA9ICt2O1xuICAgIHZhciB1MCA9ICR1ICYgVUlOVDE2O1xuICAgIHZhciB2MCA9ICR2ICYgVUlOVDE2O1xuICAgIHZhciB1MSA9ICR1ID4+IDE2O1xuICAgIHZhciB2MSA9ICR2ID4+IDE2O1xuICAgIHZhciB0ID0gKHUxICogdjAgPj4+IDApICsgKHUwICogdjAgPj4+IDE2KTtcbiAgICByZXR1cm4gdTEgKiB2MSArICh0ID4+IDE2KSArICgodTAgKiB2MSA+Pj4gMCkgKyAodCAmIFVJTlQxNikgPj4gMTYpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGlzdWJoOiBmdW5jdGlvbiBpc3ViaCh4MCwgeDEsIHkwLCB5MSkge1xuICAgIHZhciAkeDAgPSB4MCA+Pj4gMDtcbiAgICB2YXIgJHgxID0geDEgPj4+IDA7XG4gICAgdmFyICR5MCA9IHkwID4+PiAwO1xuICAgIHJldHVybiAkeDEgLSAoeTEgPj4+IDApIC0gKCh+JHgwICYgJHkwIHwgfigkeDAgXiAkeTApICYgJHgwIC0gJHkwID4+PiAwKSA+Pj4gMzEpIHwgMDtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IFJBRF9QRVJfREVHOiAxODAgLyBNYXRoLlBJIH0pO1xuIiwiLy8gaHR0cHM6Ly9yd2FsZHJvbi5naXRodWIuaW8vcHJvcG9zYWwtbWF0aC1leHRlbnNpb25zL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBERUdfUEVSX1JBRCA9IE1hdGguUEkgLyAxODA7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgcmFkaWFuczogZnVuY3Rpb24gcmFkaWFucyhkZWdyZWVzKSB7XG4gICAgcmV0dXJuIGRlZ3JlZXMgKiBERUdfUEVSX1JBRDtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IHNjYWxlOiByZXF1aXJlKCcuL19tYXRoLXNjYWxlJykgfSk7XG4iLCIvLyBodHRwOi8vamZiYXN0aWVuLmdpdGh1Yi5pby9wYXBlcnMvTWF0aC5zaWduYml0Lmh0bWxcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgc2lnbmJpdDogZnVuY3Rpb24gc2lnbmJpdCh4KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgcmV0dXJuICh4ID0gK3gpICE9IHggPyB4IDogeCA9PSAwID8gMSAvIHggPT0gSW5maW5pdHkgOiB4ID4gMDtcbn0gfSk7XG4iLCIvLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9CcmVuZGFuRWljaC80Mjk0ZDVjMjEyYTZkMjI1NDcwM1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB1bXVsaDogZnVuY3Rpb24gdW11bGgodSwgdikge1xuICAgIHZhciBVSU5UMTYgPSAweGZmZmY7XG4gICAgdmFyICR1ID0gK3U7XG4gICAgdmFyICR2ID0gK3Y7XG4gICAgdmFyIHUwID0gJHUgJiBVSU5UMTY7XG4gICAgdmFyIHYwID0gJHYgJiBVSU5UMTY7XG4gICAgdmFyIHUxID0gJHUgPj4+IDE2O1xuICAgIHZhciB2MSA9ICR2ID4+PiAxNjtcbiAgICB2YXIgdCA9ICh1MSAqIHYwID4+PiAwKSArICh1MCAqIHYwID4+PiAxNik7XG4gICAgcmV0dXJuIHUxICogdjEgKyAodCA+Pj4gMTYpICsgKCh1MCAqIHYxID4+PiAwKSArICh0ICYgVUlOVDE2KSA+Pj4gMTYpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG5cbi8vIEIuMi4yLjIgT2JqZWN0LnByb3RvdHlwZS5fX2RlZmluZUdldHRlcl9fKFAsIGdldHRlcilcbnJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgJGV4cG9ydCgkZXhwb3J0LlAgKyByZXF1aXJlKCcuL19vYmplY3QtZm9yY2VkLXBhbScpLCAnT2JqZWN0Jywge1xuICBfX2RlZmluZUdldHRlcl9fOiBmdW5jdGlvbiBfX2RlZmluZUdldHRlcl9fKFAsIGdldHRlcikge1xuICAgICRkZWZpbmVQcm9wZXJ0eS5mKHRvT2JqZWN0KHRoaXMpLCBQLCB7IGdldDogYUZ1bmN0aW9uKGdldHRlciksIGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyICRkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xuXG4vLyBCLjIuMi4zIE9iamVjdC5wcm90b3R5cGUuX19kZWZpbmVTZXR0ZXJfXyhQLCBzZXR0ZXIpXG5yZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICRleHBvcnQoJGV4cG9ydC5QICsgcmVxdWlyZSgnLi9fb2JqZWN0LWZvcmNlZC1wYW0nKSwgJ09iamVjdCcsIHtcbiAgX19kZWZpbmVTZXR0ZXJfXzogZnVuY3Rpb24gX19kZWZpbmVTZXR0ZXJfXyhQLCBzZXR0ZXIpIHtcbiAgICAkZGVmaW5lUHJvcGVydHkuZih0b09iamVjdCh0aGlzKSwgUCwgeyBzZXQ6IGFGdW5jdGlvbihzZXR0ZXIpLCBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LXZhbHVlcy1lbnRyaWVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRlbnRyaWVzID0gcmVxdWlyZSgnLi9fb2JqZWN0LXRvLWFycmF5JykodHJ1ZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge1xuICBlbnRyaWVzOiBmdW5jdGlvbiBlbnRyaWVzKGl0KSB7XG4gICAgcmV0dXJuICRlbnRyaWVzKGl0KTtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1vYmplY3QtZ2V0b3ducHJvcGVydHlkZXNjcmlwdG9yc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBvd25LZXlzID0gcmVxdWlyZSgnLi9fb3duLWtleXMnKTtcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgY3JlYXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL19jcmVhdGUtcHJvcGVydHknKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7XG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcnM6IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcnMob2JqZWN0KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3Qob2JqZWN0KTtcbiAgICB2YXIgZ2V0RGVzYyA9IGdPUEQuZjtcbiAgICB2YXIga2V5cyA9IG93bktleXMoTyk7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIga2V5LCBkZXNjO1xuICAgIHdoaWxlIChrZXlzLmxlbmd0aCA+IGkpIHtcbiAgICAgIGRlc2MgPSBnZXREZXNjKE8sIGtleSA9IGtleXNbaSsrXSk7XG4gICAgICBpZiAoZGVzYyAhPT0gdW5kZWZpbmVkKSBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGtleSwgZGVzYyk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xuXG4vLyBCLjIuMi40IE9iamVjdC5wcm90b3R5cGUuX19sb29rdXBHZXR0ZXJfXyhQKVxucmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAkZXhwb3J0KCRleHBvcnQuUCArIHJlcXVpcmUoJy4vX29iamVjdC1mb3JjZWQtcGFtJyksICdPYmplY3QnLCB7XG4gIF9fbG9va3VwR2V0dGVyX186IGZ1bmN0aW9uIF9fbG9va3VwR2V0dGVyX18oUCkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIEsgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgICB2YXIgRDtcbiAgICBkbyB7XG4gICAgICBpZiAoRCA9IGdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBLKSkgcmV0dXJuIEQuZ2V0O1xuICAgIH0gd2hpbGUgKE8gPSBnZXRQcm90b3R5cGVPZihPKSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xuXG4vLyBCLjIuMi41IE9iamVjdC5wcm90b3R5cGUuX19sb29rdXBTZXR0ZXJfXyhQKVxucmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAkZXhwb3J0KCRleHBvcnQuUCArIHJlcXVpcmUoJy4vX29iamVjdC1mb3JjZWQtcGFtJyksICdPYmplY3QnLCB7XG4gIF9fbG9va3VwU2V0dGVyX186IGZ1bmN0aW9uIF9fbG9va3VwU2V0dGVyX18oUCkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIEsgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgICB2YXIgRDtcbiAgICBkbyB7XG4gICAgICBpZiAoRCA9IGdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBLKSkgcmV0dXJuIEQuc2V0O1xuICAgIH0gd2hpbGUgKE8gPSBnZXRQcm90b3R5cGVPZihPKSk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LXZhbHVlcy1lbnRyaWVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICR2YWx1ZXMgPSByZXF1aXJlKCcuL19vYmplY3QtdG8tYXJyYXknKShmYWxzZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge1xuICB2YWx1ZXM6IGZ1bmN0aW9uIHZhbHVlcyhpdCkge1xuICAgIHJldHVybiAkdmFsdWVzKGl0KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vemVucGFyc2luZy9lcy1vYnNlcnZhYmxlXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBPQlNFUlZBQkxFID0gcmVxdWlyZSgnLi9fd2tzJykoJ29ic2VydmFibGUnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBSRVRVUk4gPSBmb3JPZi5SRVRVUk47XG5cbnZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoZm4pIHtcbiAgcmV0dXJuIGZuID09IG51bGwgPyB1bmRlZmluZWQgOiBhRnVuY3Rpb24oZm4pO1xufTtcblxudmFyIGNsZWFudXBTdWJzY3JpcHRpb24gPSBmdW5jdGlvbiAoc3Vic2NyaXB0aW9uKSB7XG4gIHZhciBjbGVhbnVwID0gc3Vic2NyaXB0aW9uLl9jO1xuICBpZiAoY2xlYW51cCkge1xuICAgIHN1YnNjcmlwdGlvbi5fYyA9IHVuZGVmaW5lZDtcbiAgICBjbGVhbnVwKCk7XG4gIH1cbn07XG5cbnZhciBzdWJzY3JpcHRpb25DbG9zZWQgPSBmdW5jdGlvbiAoc3Vic2NyaXB0aW9uKSB7XG4gIHJldHVybiBzdWJzY3JpcHRpb24uX28gPT09IHVuZGVmaW5lZDtcbn07XG5cbnZhciBjbG9zZVN1YnNjcmlwdGlvbiA9IGZ1bmN0aW9uIChzdWJzY3JpcHRpb24pIHtcbiAgaWYgKCFzdWJzY3JpcHRpb25DbG9zZWQoc3Vic2NyaXB0aW9uKSkge1xuICAgIHN1YnNjcmlwdGlvbi5fbyA9IHVuZGVmaW5lZDtcbiAgICBjbGVhbnVwU3Vic2NyaXB0aW9uKHN1YnNjcmlwdGlvbik7XG4gIH1cbn07XG5cbnZhciBTdWJzY3JpcHRpb24gPSBmdW5jdGlvbiAob2JzZXJ2ZXIsIHN1YnNjcmliZXIpIHtcbiAgYW5PYmplY3Qob2JzZXJ2ZXIpO1xuICB0aGlzLl9jID0gdW5kZWZpbmVkO1xuICB0aGlzLl9vID0gb2JzZXJ2ZXI7XG4gIG9ic2VydmVyID0gbmV3IFN1YnNjcmlwdGlvbk9ic2VydmVyKHRoaXMpO1xuICB0cnkge1xuICAgIHZhciBjbGVhbnVwID0gc3Vic2NyaWJlcihvYnNlcnZlcik7XG4gICAgdmFyIHN1YnNjcmlwdGlvbiA9IGNsZWFudXA7XG4gICAgaWYgKGNsZWFudXAgIT0gbnVsbCkge1xuICAgICAgaWYgKHR5cGVvZiBjbGVhbnVwLnVuc3Vic2NyaWJlID09PSAnZnVuY3Rpb24nKSBjbGVhbnVwID0gZnVuY3Rpb24gKCkgeyBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTsgfTtcbiAgICAgIGVsc2UgYUZ1bmN0aW9uKGNsZWFudXApO1xuICAgICAgdGhpcy5fYyA9IGNsZWFudXA7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgb2JzZXJ2ZXIuZXJyb3IoZSk7XG4gICAgcmV0dXJuO1xuICB9IGlmIChzdWJzY3JpcHRpb25DbG9zZWQodGhpcykpIGNsZWFudXBTdWJzY3JpcHRpb24odGhpcyk7XG59O1xuXG5TdWJzY3JpcHRpb24ucHJvdG90eXBlID0gcmVkZWZpbmVBbGwoe30sIHtcbiAgdW5zdWJzY3JpYmU6IGZ1bmN0aW9uIHVuc3Vic2NyaWJlKCkgeyBjbG9zZVN1YnNjcmlwdGlvbih0aGlzKTsgfVxufSk7XG5cbnZhciBTdWJzY3JpcHRpb25PYnNlcnZlciA9IGZ1bmN0aW9uIChzdWJzY3JpcHRpb24pIHtcbiAgdGhpcy5fcyA9IHN1YnNjcmlwdGlvbjtcbn07XG5cblN1YnNjcmlwdGlvbk9ic2VydmVyLnByb3RvdHlwZSA9IHJlZGVmaW5lQWxsKHt9LCB7XG4gIG5leHQ6IGZ1bmN0aW9uIG5leHQodmFsdWUpIHtcbiAgICB2YXIgc3Vic2NyaXB0aW9uID0gdGhpcy5fcztcbiAgICBpZiAoIXN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKSB7XG4gICAgICB2YXIgb2JzZXJ2ZXIgPSBzdWJzY3JpcHRpb24uX287XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgbSA9IGdldE1ldGhvZChvYnNlcnZlci5uZXh0KTtcbiAgICAgICAgaWYgKG0pIHJldHVybiBtLmNhbGwob2JzZXJ2ZXIsIHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjbG9zZVN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIGVycm9yOiBmdW5jdGlvbiBlcnJvcih2YWx1ZSkge1xuICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGlzLl9zO1xuICAgIGlmIChzdWJzY3JpcHRpb25DbG9zZWQoc3Vic2NyaXB0aW9uKSkgdGhyb3cgdmFsdWU7XG4gICAgdmFyIG9ic2VydmVyID0gc3Vic2NyaXB0aW9uLl9vO1xuICAgIHN1YnNjcmlwdGlvbi5fbyA9IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgdmFyIG0gPSBnZXRNZXRob2Qob2JzZXJ2ZXIuZXJyb3IpO1xuICAgICAgaWYgKCFtKSB0aHJvdyB2YWx1ZTtcbiAgICAgIHZhbHVlID0gbS5jYWxsKG9ic2VydmVyLCB2YWx1ZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGNsZWFudXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIGNvbXBsZXRlOiBmdW5jdGlvbiBjb21wbGV0ZSh2YWx1ZSkge1xuICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGlzLl9zO1xuICAgIGlmICghc3Vic2NyaXB0aW9uQ2xvc2VkKHN1YnNjcmlwdGlvbikpIHtcbiAgICAgIHZhciBvYnNlcnZlciA9IHN1YnNjcmlwdGlvbi5fbztcbiAgICAgIHN1YnNjcmlwdGlvbi5fbyA9IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBtID0gZ2V0TWV0aG9kKG9ic2VydmVyLmNvbXBsZXRlKTtcbiAgICAgICAgdmFsdWUgPSBtID8gbS5jYWxsKG9ic2VydmVyLCB2YWx1ZSkgOiB1bmRlZmluZWQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0gY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfVxufSk7XG5cbnZhciAkT2JzZXJ2YWJsZSA9IGZ1bmN0aW9uIE9ic2VydmFibGUoc3Vic2NyaWJlcikge1xuICBhbkluc3RhbmNlKHRoaXMsICRPYnNlcnZhYmxlLCAnT2JzZXJ2YWJsZScsICdfZicpLl9mID0gYUZ1bmN0aW9uKHN1YnNjcmliZXIpO1xufTtcblxucmVkZWZpbmVBbGwoJE9ic2VydmFibGUucHJvdG90eXBlLCB7XG4gIHN1YnNjcmliZTogZnVuY3Rpb24gc3Vic2NyaWJlKG9ic2VydmVyKSB7XG4gICAgcmV0dXJuIG5ldyBTdWJzY3JpcHRpb24ob2JzZXJ2ZXIsIHRoaXMuX2YpO1xuICB9LFxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGZuKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHJldHVybiBuZXcgKGNvcmUuUHJvbWlzZSB8fCBnbG9iYWwuUHJvbWlzZSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgYUZ1bmN0aW9uKGZuKTtcbiAgICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGF0LnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZm4odmFsdWUpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IHJlamVjdCxcbiAgICAgICAgY29tcGxldGU6IHJlc29sdmVcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59KTtcblxucmVkZWZpbmVBbGwoJE9ic2VydmFibGUsIHtcbiAgZnJvbTogZnVuY3Rpb24gZnJvbSh4KSB7XG4gICAgdmFyIEMgPSB0eXBlb2YgdGhpcyA9PT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiAkT2JzZXJ2YWJsZTtcbiAgICB2YXIgbWV0aG9kID0gZ2V0TWV0aG9kKGFuT2JqZWN0KHgpW09CU0VSVkFCTEVdKTtcbiAgICBpZiAobWV0aG9kKSB7XG4gICAgICB2YXIgb2JzZXJ2YWJsZSA9IGFuT2JqZWN0KG1ldGhvZC5jYWxsKHgpKTtcbiAgICAgIHJldHVybiBvYnNlcnZhYmxlLmNvbnN0cnVjdG9yID09PSBDID8gb2JzZXJ2YWJsZSA6IG5ldyBDKGZ1bmN0aW9uIChvYnNlcnZlcikge1xuICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZS5zdWJzY3JpYmUob2JzZXJ2ZXIpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQyhmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcbiAgICAgIHZhciBkb25lID0gZmFsc2U7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWRvbmUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKGZvck9mKHgsIGZhbHNlLCBmdW5jdGlvbiAoaXQpIHtcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChpdCk7XG4gICAgICAgICAgICAgIGlmIChkb25lKSByZXR1cm4gUkVUVVJOO1xuICAgICAgICAgICAgfSkgPT09IFJFVFVSTikgcmV0dXJuO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChkb25lKSB0aHJvdyBlO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfSBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IGRvbmUgPSB0cnVlOyB9O1xuICAgIH0pO1xuICB9LFxuICBvZjogZnVuY3Rpb24gb2YoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcmd1bWVudHMubGVuZ3RoLCBpdGVtcyA9IG5ldyBBcnJheShsKTsgaSA8IGw7KSBpdGVtc1tpXSA9IGFyZ3VtZW50c1tpKytdO1xuICAgIHJldHVybiBuZXcgKHR5cGVvZiB0aGlzID09PSAnZnVuY3Rpb24nID8gdGhpcyA6ICRPYnNlcnZhYmxlKShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcbiAgICAgIHZhciBkb25lID0gZmFsc2U7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWRvbmUpIHtcbiAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGl0ZW1zLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICBvYnNlcnZlci5uZXh0KGl0ZW1zW2pdKTtcbiAgICAgICAgICAgIGlmIChkb25lKSByZXR1cm47XG4gICAgICAgICAgfSBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IGRvbmUgPSB0cnVlOyB9O1xuICAgIH0pO1xuICB9XG59KTtcblxuaGlkZSgkT2JzZXJ2YWJsZS5wcm90b3R5cGUsIE9CU0VSVkFCTEUsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0pO1xuXG4kZXhwb3J0KCRleHBvcnQuRywgeyBPYnNlcnZhYmxlOiAkT2JzZXJ2YWJsZSB9KTtcblxucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKSgnT2JzZXJ2YWJsZScpO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcHJvbWlzZS1maW5hbGx5XG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xudmFyIHByb21pc2VSZXNvbHZlID0gcmVxdWlyZSgnLi9fcHJvbWlzZS1yZXNvbHZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5SLCAnUHJvbWlzZScsIHsgJ2ZpbmFsbHknOiBmdW5jdGlvbiAob25GaW5hbGx5KSB7XG4gIHZhciBDID0gc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsIGNvcmUuUHJvbWlzZSB8fCBnbG9iYWwuUHJvbWlzZSk7XG4gIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIG9uRmluYWxseSA9PSAnZnVuY3Rpb24nO1xuICByZXR1cm4gdGhpcy50aGVuKFxuICAgIGlzRnVuY3Rpb24gPyBmdW5jdGlvbiAoeCkge1xuICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKEMsIG9uRmluYWxseSgpKS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHg7IH0pO1xuICAgIH0gOiBvbkZpbmFsbHksXG4gICAgaXNGdW5jdGlvbiA/IGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmUoQywgb25GaW5hbGx5KCkpLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyBlOyB9KTtcbiAgICB9IDogb25GaW5hbGx5XG4gICk7XG59IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcHJvbWlzZS10cnlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgbmV3UHJvbWlzZUNhcGFiaWxpdHkgPSByZXF1aXJlKCcuL19uZXctcHJvbWlzZS1jYXBhYmlsaXR5Jyk7XG52YXIgcGVyZm9ybSA9IHJlcXVpcmUoJy4vX3BlcmZvcm0nKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdQcm9taXNlJywgeyAndHJ5JzogZnVuY3Rpb24gKGNhbGxiYWNrZm4pIHtcbiAgdmFyIHByb21pc2VDYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkuZih0aGlzKTtcbiAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oY2FsbGJhY2tmbik7XG4gIChyZXN1bHQuZSA/IHByb21pc2VDYXBhYmlsaXR5LnJlamVjdCA6IHByb21pc2VDYXBhYmlsaXR5LnJlc29sdmUpKHJlc3VsdC52KTtcbiAgcmV0dXJuIHByb21pc2VDYXBhYmlsaXR5LnByb21pc2U7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvTWV0YUtleSA9IG1ldGFkYXRhLmtleTtcbnZhciBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhID0gbWV0YWRhdGEuc2V0O1xuXG5tZXRhZGF0YS5leHAoeyBkZWZpbmVNZXRhZGF0YTogZnVuY3Rpb24gZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgdGFyZ2V0S2V5KSB7XG4gIG9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIGFuT2JqZWN0KHRhcmdldCksIHRvTWV0YUtleSh0YXJnZXRLZXkpKTtcbn0gfSk7XG4iLCJ2YXIgbWV0YWRhdGEgPSByZXF1aXJlKCcuL19tZXRhZGF0YScpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xudmFyIGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAgPSBtZXRhZGF0YS5tYXA7XG52YXIgc3RvcmUgPSBtZXRhZGF0YS5zdG9yZTtcblxubWV0YWRhdGEuZXhwKHsgZGVsZXRlTWV0YWRhdGE6IGZ1bmN0aW9uIGRlbGV0ZU1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQgLyogLCB0YXJnZXRLZXkgKi8pIHtcbiAgdmFyIHRhcmdldEtleSA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdW5kZWZpbmVkIDogdG9NZXRhS2V5KGFyZ3VtZW50c1syXSk7XG4gIHZhciBtZXRhZGF0YU1hcCA9IGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoYW5PYmplY3QodGFyZ2V0KSwgdGFyZ2V0S2V5LCBmYWxzZSk7XG4gIGlmIChtZXRhZGF0YU1hcCA9PT0gdW5kZWZpbmVkIHx8ICFtZXRhZGF0YU1hcFsnZGVsZXRlJ10obWV0YWRhdGFLZXkpKSByZXR1cm4gZmFsc2U7XG4gIGlmIChtZXRhZGF0YU1hcC5zaXplKSByZXR1cm4gdHJ1ZTtcbiAgdmFyIHRhcmdldE1ldGFkYXRhID0gc3RvcmUuZ2V0KHRhcmdldCk7XG4gIHRhcmdldE1ldGFkYXRhWydkZWxldGUnXSh0YXJnZXRLZXkpO1xuICByZXR1cm4gISF0YXJnZXRNZXRhZGF0YS5zaXplIHx8IHN0b3JlWydkZWxldGUnXSh0YXJnZXQpO1xufSB9KTtcbiIsInZhciBTZXQgPSByZXF1aXJlKCcuL2VzNi5zZXQnKTtcbnZhciBmcm9tID0gcmVxdWlyZSgnLi9fYXJyYXktZnJvbS1pdGVyYWJsZScpO1xudmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzID0gbWV0YWRhdGEua2V5cztcbnZhciB0b01ldGFLZXkgPSBtZXRhZGF0YS5rZXk7XG5cbnZhciBvcmRpbmFyeU1ldGFkYXRhS2V5cyA9IGZ1bmN0aW9uIChPLCBQKSB7XG4gIHZhciBvS2V5cyA9IG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApO1xuICB2YXIgcGFyZW50ID0gZ2V0UHJvdG90eXBlT2YoTyk7XG4gIGlmIChwYXJlbnQgPT09IG51bGwpIHJldHVybiBvS2V5cztcbiAgdmFyIHBLZXlzID0gb3JkaW5hcnlNZXRhZGF0YUtleXMocGFyZW50LCBQKTtcbiAgcmV0dXJuIHBLZXlzLmxlbmd0aCA/IG9LZXlzLmxlbmd0aCA/IGZyb20obmV3IFNldChvS2V5cy5jb25jYXQocEtleXMpKSkgOiBwS2V5cyA6IG9LZXlzO1xufTtcblxubWV0YWRhdGEuZXhwKHsgZ2V0TWV0YWRhdGFLZXlzOiBmdW5jdGlvbiBnZXRNZXRhZGF0YUtleXModGFyZ2V0IC8qICwgdGFyZ2V0S2V5ICovKSB7XG4gIHJldHVybiBvcmRpbmFyeU1ldGFkYXRhS2V5cyhhbk9iamVjdCh0YXJnZXQpLCBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMV0pKTtcbn0gfSk7XG4iLCJ2YXIgbWV0YWRhdGEgPSByZXF1aXJlKCcuL19tZXRhZGF0YScpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgb3JkaW5hcnlIYXNPd25NZXRhZGF0YSA9IG1ldGFkYXRhLmhhcztcbnZhciBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gbWV0YWRhdGEuZ2V0O1xudmFyIHRvTWV0YUtleSA9IG1ldGFkYXRhLmtleTtcblxudmFyIG9yZGluYXJ5R2V0TWV0YWRhdGEgPSBmdW5jdGlvbiAoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgdmFyIGhhc093biA9IG9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xuICBpZiAoaGFzT3duKSByZXR1cm4gb3JkaW5hcnlHZXRPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XG4gIHZhciBwYXJlbnQgPSBnZXRQcm90b3R5cGVPZihPKTtcbiAgcmV0dXJuIHBhcmVudCAhPT0gbnVsbCA/IG9yZGluYXJ5R2V0TWV0YWRhdGEoTWV0YWRhdGFLZXksIHBhcmVudCwgUCkgOiB1bmRlZmluZWQ7XG59O1xuXG5tZXRhZGF0YS5leHAoeyBnZXRNZXRhZGF0YTogZnVuY3Rpb24gZ2V0TWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlHZXRNZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzID0gbWV0YWRhdGEua2V5cztcbnZhciB0b01ldGFLZXkgPSBtZXRhZGF0YS5rZXk7XG5cbm1ldGFkYXRhLmV4cCh7IGdldE93bk1ldGFkYXRhS2V5czogZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGFLZXlzKHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlPd25NZXRhZGF0YUtleXMoYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDIgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzFdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIG9yZGluYXJ5R2V0T3duTWV0YWRhdGEgPSBtZXRhZGF0YS5nZXQ7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xuXG5tZXRhZGF0YS5leHAoeyBnZXRPd25NZXRhZGF0YTogZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlHZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KVxuICAgICwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBtZXRhZGF0YS5oYXM7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xuXG52YXIgb3JkaW5hcnlIYXNNZXRhZGF0YSA9IGZ1bmN0aW9uIChNZXRhZGF0YUtleSwgTywgUCkge1xuICB2YXIgaGFzT3duID0gb3JkaW5hcnlIYXNPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XG4gIGlmIChoYXNPd24pIHJldHVybiB0cnVlO1xuICB2YXIgcGFyZW50ID0gZ2V0UHJvdG90eXBlT2YoTyk7XG4gIHJldHVybiBwYXJlbnQgIT09IG51bGwgPyBvcmRpbmFyeUhhc01ldGFkYXRhKE1ldGFkYXRhS2V5LCBwYXJlbnQsIFApIDogZmFsc2U7XG59O1xuXG5tZXRhZGF0YS5leHAoeyBoYXNNZXRhZGF0YTogZnVuY3Rpb24gaGFzTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlIYXNNZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBtZXRhZGF0YS5oYXM7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xuXG5tZXRhZGF0YS5leHAoeyBoYXNPd25NZXRhZGF0YTogZnVuY3Rpb24gaGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlIYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KVxuICAgICwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyICRtZXRhZGF0YSA9IHJlcXVpcmUoJy4vX21ldGFkYXRhJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgdG9NZXRhS2V5ID0gJG1ldGFkYXRhLmtleTtcbnZhciBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhID0gJG1ldGFkYXRhLnNldDtcblxuJG1ldGFkYXRhLmV4cCh7IG1ldGFkYXRhOiBmdW5jdGlvbiBtZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24gZGVjb3JhdG9yKHRhcmdldCwgdGFyZ2V0S2V5KSB7XG4gICAgb3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShcbiAgICAgIG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlLFxuICAgICAgKHRhcmdldEtleSAhPT0gdW5kZWZpbmVkID8gYW5PYmplY3QgOiBhRnVuY3Rpb24pKHRhcmdldCksXG4gICAgICB0b01ldGFLZXkodGFyZ2V0S2V5KVxuICAgICk7XG4gIH07XG59IH0pO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtc2V0LmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnU2V0Jyk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy1zZXQub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ1NldCcpO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL0RhdmlkQnJ1YW50L01hcC1TZXQucHJvdG90eXBlLnRvSlNPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdTZXQnLCB7IHRvSlNPTjogcmVxdWlyZSgnLi9fY29sbGVjdGlvbi10by1qc29uJykoJ1NldCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL21hdGhpYXNieW5lbnMvU3RyaW5nLnByb3RvdHlwZS5hdFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkYXQgPSByZXF1aXJlKCcuL19zdHJpbmctYXQnKSh0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdTdHJpbmcnLCB7XG4gIGF0OiBmdW5jdGlvbiBhdChwb3MpIHtcbiAgICByZXR1cm4gJGF0KHRoaXMsIHBvcyk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9TdHJpbmcucHJvdG90eXBlLm1hdGNoQWxsL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuL19pcy1yZWdleHAnKTtcbnZhciBnZXRGbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG52YXIgUmVnRXhwUHJvdG8gPSBSZWdFeHAucHJvdG90eXBlO1xuXG52YXIgJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yID0gZnVuY3Rpb24gKHJlZ2V4cCwgc3RyaW5nKSB7XG4gIHRoaXMuX3IgPSByZWdleHA7XG4gIHRoaXMuX3MgPSBzdHJpbmc7XG59O1xuXG5yZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpKCRSZWdFeHBTdHJpbmdJdGVyYXRvciwgJ1JlZ0V4cCBTdHJpbmcnLCBmdW5jdGlvbiBuZXh0KCkge1xuICB2YXIgbWF0Y2ggPSB0aGlzLl9yLmV4ZWModGhpcy5fcyk7XG4gIHJldHVybiB7IHZhbHVlOiBtYXRjaCwgZG9uZTogbWF0Y2ggPT09IG51bGwgfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgbWF0Y2hBbGw6IGZ1bmN0aW9uIG1hdGNoQWxsKHJlZ2V4cCkge1xuICAgIGRlZmluZWQodGhpcyk7XG4gICAgaWYgKCFpc1JlZ0V4cChyZWdleHApKSB0aHJvdyBUeXBlRXJyb3IocmVnZXhwICsgJyBpcyBub3QgYSByZWdleHAhJyk7XG4gICAgdmFyIFMgPSBTdHJpbmcodGhpcyk7XG4gICAgdmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSZWdFeHBQcm90byA/IFN0cmluZyhyZWdleHAuZmxhZ3MpIDogZ2V0RmxhZ3MuY2FsbChyZWdleHApO1xuICAgIHZhciByeCA9IG5ldyBSZWdFeHAocmVnZXhwLnNvdXJjZSwgfmZsYWdzLmluZGV4T2YoJ2cnKSA/IGZsYWdzIDogJ2cnICsgZmxhZ3MpO1xuICAgIHJ4Lmxhc3RJbmRleCA9IHRvTGVuZ3RoKHJlZ2V4cC5sYXN0SW5kZXgpO1xuICAgIHJldHVybiBuZXcgJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKHJ4LCBTKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFkID0gcmVxdWlyZSgnLi9fc3RyaW5nLXBhZCcpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzI4MFxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAvVmVyc2lvblxcLzEwXFwuXFxkKyhcXC5cXGQrKT8gU2FmYXJpXFwvLy50ZXN0KHVzZXJBZ2VudCksICdTdHJpbmcnLCB7XG4gIHBhZEVuZDogZnVuY3Rpb24gcGFkRW5kKG1heExlbmd0aCAvKiAsIGZpbGxTdHJpbmcgPSAnICcgKi8pIHtcbiAgICByZXR1cm4gJHBhZCh0aGlzLCBtYXhMZW5ndGgsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCBmYWxzZSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLXBhZC1zdGFydC1lbmRcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHBhZCA9IHJlcXVpcmUoJy4vX3N0cmluZy1wYWQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8yODBcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogL1ZlcnNpb25cXC8xMFxcLlxcZCsoXFwuXFxkKyk/IFNhZmFyaVxcLy8udGVzdCh1c2VyQWdlbnQpLCAnU3RyaW5nJywge1xuICBwYWRTdGFydDogZnVuY3Rpb24gcGFkU3RhcnQobWF4TGVuZ3RoIC8qICwgZmlsbFN0cmluZyA9ICcgJyAqLykge1xuICAgIHJldHVybiAkcGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIHRydWUpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zZWJtYXJrYmFnZS9lY21hc2NyaXB0LXN0cmluZy1sZWZ0LXJpZ2h0LXRyaW1cbnJlcXVpcmUoJy4vX3N0cmluZy10cmltJykoJ3RyaW1MZWZ0JywgZnVuY3Rpb24gKCR0cmltKSB7XG4gIHJldHVybiBmdW5jdGlvbiB0cmltTGVmdCgpIHtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMSk7XG4gIH07XG59LCAndHJpbVN0YXJ0Jyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vc2VibWFya2JhZ2UvZWNtYXNjcmlwdC1zdHJpbmctbGVmdC1yaWdodC10cmltXG5yZXF1aXJlKCcuL19zdHJpbmctdHJpbScpKCd0cmltUmlnaHQnLCBmdW5jdGlvbiAoJHRyaW0pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHRyaW1SaWdodCgpIHtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMik7XG4gIH07XG59LCAndHJpbUVuZCcpO1xuIiwicmVxdWlyZSgnLi9fd2tzLWRlZmluZScpKCdhc3luY0l0ZXJhdG9yJyk7XG4iLCJyZXF1aXJlKCcuL193a3MtZGVmaW5lJykoJ29ic2VydmFibGUnKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLWdsb2JhbFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdTeXN0ZW0nLCB7IGdsb2JhbDogcmVxdWlyZSgnLi9fZ2xvYmFsJykgfSk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy13ZWFrbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnV2Vha01hcCcpO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtd2Vha21hcC5vZlxucmVxdWlyZSgnLi9fc2V0LWNvbGxlY3Rpb24tb2YnKSgnV2Vha01hcCcpO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtd2Vha3NldC5mcm9tXG5yZXF1aXJlKCcuL19zZXQtY29sbGVjdGlvbi1mcm9tJykoJ1dlYWtTZXQnKTtcbiIsIi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS8jc2VjLXdlYWtzZXQub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ1dlYWtTZXQnKTtcbiIsInZhciAkaXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciBJVEVSQVRPUiA9IHdrcygnaXRlcmF0b3InKTtcbnZhciBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xudmFyIEFycmF5VmFsdWVzID0gSXRlcmF0b3JzLkFycmF5O1xuXG52YXIgRE9NSXRlcmFibGVzID0ge1xuICBDU1NSdWxlTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIENTU1N0eWxlRGVjbGFyYXRpb246IGZhbHNlLFxuICBDU1NWYWx1ZUxpc3Q6IGZhbHNlLFxuICBDbGllbnRSZWN0TGlzdDogZmFsc2UsXG4gIERPTVJlY3RMaXN0OiBmYWxzZSxcbiAgRE9NU3RyaW5nTGlzdDogZmFsc2UsXG4gIERPTVRva2VuTGlzdDogdHJ1ZSxcbiAgRGF0YVRyYW5zZmVySXRlbUxpc3Q6IGZhbHNlLFxuICBGaWxlTGlzdDogZmFsc2UsXG4gIEhUTUxBbGxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTENvbGxlY3Rpb246IGZhbHNlLFxuICBIVE1MRm9ybUVsZW1lbnQ6IGZhbHNlLFxuICBIVE1MU2VsZWN0RWxlbWVudDogZmFsc2UsXG4gIE1lZGlhTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIE1pbWVUeXBlQXJyYXk6IGZhbHNlLFxuICBOYW1lZE5vZGVNYXA6IGZhbHNlLFxuICBOb2RlTGlzdDogdHJ1ZSxcbiAgUGFpbnRSZXF1ZXN0TGlzdDogZmFsc2UsXG4gIFBsdWdpbjogZmFsc2UsXG4gIFBsdWdpbkFycmF5OiBmYWxzZSxcbiAgU1ZHTGVuZ3RoTGlzdDogZmFsc2UsXG4gIFNWR051bWJlckxpc3Q6IGZhbHNlLFxuICBTVkdQYXRoU2VnTGlzdDogZmFsc2UsXG4gIFNWR1BvaW50TGlzdDogZmFsc2UsXG4gIFNWR1N0cmluZ0xpc3Q6IGZhbHNlLFxuICBTVkdUcmFuc2Zvcm1MaXN0OiBmYWxzZSxcbiAgU291cmNlQnVmZmVyTGlzdDogZmFsc2UsXG4gIFN0eWxlU2hlZXRMaXN0OiB0cnVlLCAvLyBUT0RPOiBOb3Qgc3BlYyBjb21wbGlhbnQsIHNob3VsZCBiZSBmYWxzZS5cbiAgVGV4dFRyYWNrQ3VlTGlzdDogZmFsc2UsXG4gIFRleHRUcmFja0xpc3Q6IGZhbHNlLFxuICBUb3VjaExpc3Q6IGZhbHNlXG59O1xuXG5mb3IgKHZhciBjb2xsZWN0aW9ucyA9IGdldEtleXMoRE9NSXRlcmFibGVzKSwgaSA9IDA7IGkgPCBjb2xsZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICB2YXIgTkFNRSA9IGNvbGxlY3Rpb25zW2ldO1xuICB2YXIgZXhwbGljaXQgPSBET01JdGVyYWJsZXNbTkFNRV07XG4gIHZhciBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgcHJvdG8gPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICB2YXIga2V5O1xuICBpZiAocHJvdG8pIHtcbiAgICBpZiAoIXByb3RvW0lURVJBVE9SXSkgaGlkZShwcm90bywgSVRFUkFUT1IsIEFycmF5VmFsdWVzKTtcbiAgICBpZiAoIXByb3RvW1RPX1NUUklOR19UQUddKSBoaWRlKHByb3RvLCBUT19TVFJJTkdfVEFHLCBOQU1FKTtcbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBBcnJheVZhbHVlcztcbiAgICBpZiAoZXhwbGljaXQpIGZvciAoa2V5IGluICRpdGVyYXRvcnMpIGlmICghcHJvdG9ba2V5XSkgcmVkZWZpbmUocHJvdG8sIGtleSwgJGl0ZXJhdG9yc1trZXldLCB0cnVlKTtcbiAgfVxufVxuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5CLCB7XG4gIHNldEltbWVkaWF0ZTogJHRhc2suc2V0LFxuICBjbGVhckltbWVkaWF0ZTogJHRhc2suY2xlYXJcbn0pO1xuIiwiLy8gaWU5LSBzZXRUaW1lb3V0ICYgc2V0SW50ZXJ2YWwgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGZpeFxudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG52YXIgc2xpY2UgPSBbXS5zbGljZTtcbnZhciBNU0lFID0gL01TSUUgLlxcLi8udGVzdCh1c2VyQWdlbnQpOyAvLyA8LSBkaXJ0eSBpZTktIGNoZWNrXG52YXIgd3JhcCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChmbiwgdGltZSAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgICB2YXIgYm91bmRBcmdzID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gICAgdmFyIGFyZ3MgPSBib3VuZEFyZ3MgPyBzbGljZS5jYWxsKGFyZ3VtZW50cywgMikgOiBmYWxzZTtcbiAgICByZXR1cm4gc2V0KGJvdW5kQXJncyA/IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbikpLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0gOiBmbiwgdGltZSk7XG4gIH07XG59O1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkIgKyAkZXhwb3J0LkYgKiBNU0lFLCB7XG4gIHNldFRpbWVvdXQ6IHdyYXAoZ2xvYmFsLnNldFRpbWVvdXQpLFxuICBzZXRJbnRlcnZhbDogd3JhcChnbG9iYWwuc2V0SW50ZXJ2YWwpXG59KTtcbiIsInJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3ltYm9sJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5jcmVhdGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0eScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1uYW1lcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZnJlZXplJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5wcmV2ZW50LWV4dGVuc2lvbnMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmlzLWZyb3plbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtc2VhbGVkJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1leHRlbnNpYmxlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmlzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmhhcy1pbnN0YW5jZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5wYXJzZS1pbnQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucGFyc2UtZmxvYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmNvbnN0cnVjdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci50by1maXhlZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIudG8tcHJlY2lzaW9uJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5lcHNpbG9uJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5pcy1maW5pdGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmlzLWludGVnZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmlzLW5hbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5tYXgtc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5taW4tc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguYWNvc2gnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5hc2luaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmF0YW5oJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguY2JydCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmNsejMyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguY29zaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmV4cG0xJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguZnJvdW5kJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguaHlwb3QnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5pbXVsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGgubG9nMTAnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5sb2cxcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5zaWduJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguc2luaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLnRhbmgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC50cnVuYycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuZnJvbS1jb2RlLXBvaW50Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5yYXcnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5jb2RlLXBvaW50LWF0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5lbmRzLXdpdGgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmluY2x1ZGVzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5yZXBlYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnN0YXJ0cy13aXRoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5hbmNob3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmJpZycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmxpbmsnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmJvbGQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmZpeGVkJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRzaXplJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5pdGFsaWNzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5saW5rJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5zbWFsbCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3RyaWtlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5zdWInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnN1cCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5kYXRlLm5vdycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5kYXRlLnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuZGF0ZS50by1pc28tc3RyaW5nJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmRhdGUudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmRhdGUudG8tcHJpbWl0aXZlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmlzLWFycmF5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZyb20nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkub2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuam9pbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5zbGljZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5zb3J0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZvci1lYWNoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5Lm1hcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5maWx0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuc29tZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5ldmVyeScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlLXJpZ2h0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmluZGV4LW9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5Lmxhc3QtaW5kZXgtb2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuY29weS13aXRoaW4nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuZmlsbCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZpbmQtaW5kZXgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuc3BlY2llcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWdleHAuY29uc3RydWN0b3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLmV4ZWMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWdleHAuZmxhZ3MnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLm1hdGNoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZ2V4cC5yZXBsYWNlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZ2V4cC5zZWFyY2gnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLnNwbGl0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnByb21pc2UnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWFwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnNldCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi53ZWFrLW1hcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi53ZWFrLXNldCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC5hcnJheS1idWZmZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuZGF0YS12aWV3Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnR5cGVkLmludDgtYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQudWludDgtYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQudWludDgtY2xhbXBlZC1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC51aW50MTYtYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuaW50MzItYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQudWludDMyLWFycmF5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0MzItYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuZmxvYXQ2NC1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmFwcGx5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuY29uc3RydWN0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVmaW5lLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVsZXRlLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZW51bWVyYXRlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmhhcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmlzLWV4dGVuc2libGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5vd24ta2V5cycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnByZXZlbnQtZXh0ZW5zaW9ucycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC1wcm90b3R5cGUtb2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuYXJyYXkuaW5jbHVkZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuYXJyYXkuZmxhdC1tYXAnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuYXJyYXkuZmxhdHRlbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcuYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1sZWZ0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN0cmluZy50cmltLXJpZ2h0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN0cmluZy5tYXRjaC1hbGwnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN5bWJvbC5vYnNlcnZhYmxlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9iamVjdC52YWx1ZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1nZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1zZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWFwLnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc2V0LnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWFwLm9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnNldC5vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy53ZWFrLW1hcC5vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy53ZWFrLXNldC5vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXAuZnJvbScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zZXQuZnJvbScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy53ZWFrLW1hcC5mcm9tJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LndlYWstc2V0LmZyb20nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuZ2xvYmFsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuZXJyb3IuaXMtZXJyb3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWF0aC5jbGFtcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLmRlZy1wZXItcmFkJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGguZGVncmVlcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLmZzY2FsZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLmlhZGRoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGguaXN1YmgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWF0aC5pbXVsaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLnJhZC1wZXItZGVnJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGgucmFkaWFucycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLnNjYWxlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGgudW11bGgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWF0aC5zaWduYml0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnByb21pc2UuZmluYWxseScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5wcm9taXNlLnRyeScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlZmluZS1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlbGV0ZS1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1tZXRhZGF0YS1rZXlzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW93bi1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1vd24tbWV0YWRhdGEta2V5cycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0Lmhhcy1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0Lmhhcy1vd24tbWV0YWRhdGEnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcucmVmbGVjdC5tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5hc2FwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9ic2VydmFibGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy93ZWIudGltZXJzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvd2ViLmltbWVkaWF0ZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9tb2R1bGVzL19jb3JlJyk7XG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IChlICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IChtICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKCh2YWx1ZSAqIGMpIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG4iLCIvKipcbiAqIENvbnZlcnQgYXJyYXkgb2YgMTYgYnl0ZSB2YWx1ZXMgdG8gVVVJRCBzdHJpbmcgZm9ybWF0IG9mIHRoZSBmb3JtOlxuICogWFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYXG4gKi9cbnZhciBieXRlVG9IZXggPSBbXTtcbmZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgYnl0ZVRvSGV4W2ldID0gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigxKTtcbn1cblxuZnVuY3Rpb24gYnl0ZXNUb1V1aWQoYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBvZmZzZXQgfHwgMDtcbiAgdmFyIGJ0aCA9IGJ5dGVUb0hleDtcbiAgLy8gam9pbiB1c2VkIHRvIGZpeCBtZW1vcnkgaXNzdWUgY2F1c2VkIGJ5IGNvbmNhdGVuYXRpb246IGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMxNzUjYzRcbiAgcmV0dXJuIChbYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXV0pLmpvaW4oJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJ5dGVzVG9VdWlkO1xuIiwiLy8gVW5pcXVlIElEIGNyZWF0aW9uIHJlcXVpcmVzIGEgaGlnaCBxdWFsaXR5IHJhbmRvbSAjIGdlbmVyYXRvci4gIEluIHRoZVxuLy8gYnJvd3NlciB0aGlzIGlzIGEgbGl0dGxlIGNvbXBsaWNhdGVkIGR1ZSB0byB1bmtub3duIHF1YWxpdHkgb2YgTWF0aC5yYW5kb20oKVxuLy8gYW5kIGluY29uc2lzdGVudCBzdXBwb3J0IGZvciB0aGUgYGNyeXB0b2AgQVBJLiAgV2UgZG8gdGhlIGJlc3Qgd2UgY2FuIHZpYVxuLy8gZmVhdHVyZS1kZXRlY3Rpb25cblxuLy8gZ2V0UmFuZG9tVmFsdWVzIG5lZWRzIHRvIGJlIGludm9rZWQgaW4gYSBjb250ZXh0IHdoZXJlIFwidGhpc1wiIGlzIGEgQ3J5cHRvXG4vLyBpbXBsZW1lbnRhdGlvbi4gQWxzbywgZmluZCB0aGUgY29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgY3J5cHRvIG9uIElFMTEuXG52YXIgZ2V0UmFuZG9tVmFsdWVzID0gKHR5cGVvZihjcnlwdG8pICE9ICd1bmRlZmluZWQnICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKGNyeXB0bykpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgKHR5cGVvZihtc0NyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHdpbmRvdy5tc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMgPT0gJ2Z1bmN0aW9uJyAmJiBtc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChtc0NyeXB0bykpO1xuXG5pZiAoZ2V0UmFuZG9tVmFsdWVzKSB7XG4gIC8vIFdIQVRXRyBjcnlwdG8gUk5HIC0gaHR0cDovL3dpa2kud2hhdHdnLm9yZy93aWtpL0NyeXB0b1xuICB2YXIgcm5kczggPSBuZXcgVWludDhBcnJheSgxNik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHdoYXR3Z1JORygpIHtcbiAgICBnZXRSYW5kb21WYWx1ZXMocm5kczgpO1xuICAgIHJldHVybiBybmRzODtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIE1hdGgucmFuZG9tKCktYmFzZWQgKFJORylcbiAgLy9cbiAgLy8gSWYgYWxsIGVsc2UgZmFpbHMsIHVzZSBNYXRoLnJhbmRvbSgpLiAgSXQncyBmYXN0LCBidXQgaXMgb2YgdW5zcGVjaWZpZWRcbiAgLy8gcXVhbGl0eS5cbiAgdmFyIHJuZHMgPSBuZXcgQXJyYXkoMTYpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbWF0aFJORygpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgcjsgaSA8IDE2OyBpKyspIHtcbiAgICAgIGlmICgoaSAmIDB4MDMpID09PSAwKSByID0gTWF0aC5yYW5kb20oKSAqIDB4MTAwMDAwMDAwO1xuICAgICAgcm5kc1tpXSA9IHIgPj4+ICgoaSAmIDB4MDMpIDw8IDMpICYgMHhmZjtcbiAgICB9XG5cbiAgICByZXR1cm4gcm5kcztcbiAgfTtcbn1cbiIsInZhciBybmcgPSByZXF1aXJlKCcuL2xpYi9ybmcnKTtcbnZhciBieXRlc1RvVXVpZCA9IHJlcXVpcmUoJy4vbGliL2J5dGVzVG9VdWlkJyk7XG5cbmZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gIGlmICh0eXBlb2Yob3B0aW9ucykgPT0gJ3N0cmluZycpIHtcbiAgICBidWYgPSBvcHRpb25zID09PSAnYmluYXJ5JyA/IG5ldyBBcnJheSgxNikgOiBudWxsO1xuICAgIG9wdGlvbnMgPSBudWxsO1xuICB9XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IHJuZykoKTtcblxuICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgcm5kc1s4XSA9IChybmRzWzhdICYgMHgzZikgfCAweDgwO1xuXG4gIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICBpZiAoYnVmKSB7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IDE2OyArK2lpKSB7XG4gICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgfHwgYnl0ZXNUb1V1aWQocm5kcyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjQ7XG4iLCJ2YXIgZztcblxuLy8gVGhpcyB3b3JrcyBpbiBub24tc3RyaWN0IG1vZGVcbmcgPSAoZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzO1xufSkoKTtcblxudHJ5IHtcblx0Ly8gVGhpcyB3b3JrcyBpZiBldmFsIGlzIGFsbG93ZWQgKHNlZSBDU1ApXG5cdGcgPSBnIHx8IG5ldyBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKCk7XG59IGNhdGNoIChlKSB7XG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXG5cdGlmICh0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiKSBnID0gd2luZG93O1xufVxuXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXG4vLyBXZSByZXR1cm4gdW5kZWZpbmVkLCBpbnN0ZWFkIG9mIG5vdGhpbmcgaGVyZSwgc28gaXQnc1xuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGc7XG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFRpbWVyIH0gZnJvbSAnLi9UaW1lci5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIEFjY2Vzc1Rva2VuRXZlbnRzIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ1RpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyaW5nXCIpLFxyXG4gICAgICAgIGFjY2Vzc1Rva2VuRXhwaXJlZFRpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyZWRcIilcclxuICAgIH0gPSB7fSkge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcgPSBhY2Nlc3NUb2tlbkV4cGlyaW5nVGltZXI7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkID0gYWNjZXNzVG9rZW5FeHBpcmVkVGltZXI7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZChjb250YWluZXIpIHtcclxuICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV2ZW50cyBpZiB0aGVyZSdzIGFuIGFjY2VzcyB0b2tlbiBhbmQgaXQgaGFzIGFuIGV4cGlyYXRpb25cclxuICAgICAgICBpZiAoY29udGFpbmVyLmFjY2Vzc190b2tlbiAmJiBjb250YWluZXIuZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbiA9IGNvbnRhaW5lci5leHBpcmVzX2luO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiBhY2Nlc3MgdG9rZW4gcHJlc2VudCwgcmVtYWluaW5nIGR1cmF0aW9uOlwiLCBkdXJhdGlvbik7XHJcblxyXG4gICAgICAgICAgICBpZiAoZHVyYXRpb24gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV4cGlyaW5nIGlmIHdlIHN0aWxsIGhhdmUgdGltZVxyXG4gICAgICAgICAgICAgICAgbGV0IGV4cGlyaW5nID0gZHVyYXRpb24gLSB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgICAgICAgICAgICAgIGlmIChleHBpcmluZyA8PSAwKXtcclxuICAgICAgICAgICAgICAgICAgICBleHBpcmluZyA9IDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkFjY2Vzc1Rva2VuRXZlbnRzLmxvYWQ6IHJlZ2lzdGVyaW5nIGV4cGlyaW5nIHRpbWVyIGluOlwiLCBleHBpcmluZyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmluaXQoZXhwaXJpbmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQWNjZXNzVG9rZW5FdmVudHMubG9hZDogY2FuY2VsaW5nIGV4aXN0aW5nIGV4cGlyaW5nIHRpbWVyIGJlY2FzZSB3ZSdyZSBwYXN0IGV4cGlyYXRpb24uXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmluZy5jYW5jZWwoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaWYgaXQncyBuZWdhdGl2ZSwgaXQgd2lsbCBzdGlsbCBmaXJlXHJcbiAgICAgICAgICAgIGxldCBleHBpcmVkID0gZHVyYXRpb24gKyAxO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiByZWdpc3RlcmluZyBleHBpcmVkIHRpbWVyIGluOlwiLCBleHBpcmVkKTtcclxuICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmluaXQoZXhwaXJlZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmNhbmNlbCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyZWQuY2FuY2VsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHVubG9hZCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy51bmxvYWQ6IGNhbmNlbGluZyBleGlzdGluZyBhY2Nlc3MgdG9rZW4gdGltZXJzXCIpO1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcuY2FuY2VsKCk7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmNhbmNlbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZEFjY2Vzc1Rva2VuRXhwaXJpbmcoY2IpIHtcclxuICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmluZyhjYikge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRJbnRlcnZhbCA9IDIwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgQ2hlY2tTZXNzaW9uSUZyYW1lIHtcclxuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCBjbGllbnRfaWQsIHVybCwgaW50ZXJ2YWwsIHN0b3BPbkVycm9yID0gdHJ1ZSkge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX3VybCA9IHVybDtcclxuICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IGludGVydmFsIHx8IERlZmF1bHRJbnRlcnZhbDtcclxuICAgICAgICB0aGlzLl9zdG9wT25FcnJvciA9IHN0b3BPbkVycm9yO1xyXG5cclxuICAgICAgICB2YXIgaWR4ID0gdXJsLmluZGV4T2YoXCIvXCIsIHVybC5pbmRleE9mKFwiLy9cIikgKyAyKTtcclxuICAgICAgICB0aGlzLl9mcmFtZV9vcmlnaW4gPSB1cmwuc3Vic3RyKDAsIGlkeCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpZnJhbWVcIik7XHJcblxyXG4gICAgICAgIC8vIHNob3RndW4gYXBwcm9hY2hcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUud2lkdGggPSAwO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmhlaWdodCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnNyYyA9IHVybDtcclxuICAgIH1cclxuICAgIGxvYWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfbWVzc2FnZShlKSB7XHJcbiAgICAgICAgaWYgKGUub3JpZ2luID09PSB0aGlzLl9mcmFtZV9vcmlnaW4gJiZcclxuICAgICAgICAgICAgZS5zb3VyY2UgPT09IHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3dcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgaWYgKGUuZGF0YSA9PT0gXCJlcnJvclwiKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJDaGVja1Nlc3Npb25JRnJhbWU6IGVycm9yIG1lc3NhZ2UgZnJvbSBjaGVjayBzZXNzaW9uIG9wIGlmcmFtZVwiKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdG9wT25FcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGUuZGF0YSA9PT0gXCJjaGFuZ2VkXCIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZTogY2hhbmdlZCBtZXNzYWdlIGZyb20gY2hlY2sgc2Vzc2lvbiBvcCBpZnJhbWVcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJDaGVja1Nlc3Npb25JRnJhbWU6IFwiICsgZS5kYXRhICsgXCIgbWVzc2FnZSBmcm9tIGNoZWNrIHNlc3Npb24gb3AgaWZyYW1lXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhcnQoc2Vzc2lvbl9zdGF0ZSkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXNzaW9uX3N0YXRlICE9PSBzZXNzaW9uX3N0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdGFydFwiKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcblxyXG4gICAgICAgICAgICBsZXQgc2VuZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UodGhpcy5fY2xpZW50X2lkICsgXCIgXCIgKyB0aGlzLl9zZXNzaW9uX3N0YXRlLCB0aGlzLl9mcmFtZV9vcmlnaW4pO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBub3dcclxuICAgICAgICAgICAgc2VuZCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gYW5kIHNldHVwIHRpbWVyXHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldEludGVydmFsKHNlbmQsIHRoaXMuX2ludGVydmFsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc3RvcCgpIHtcclxuICAgICAgICB0aGlzLl9zZXNzaW9uX3N0YXRlID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdG9wXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IENvcmRvdmFQb3B1cFdpbmRvdyB9IGZyb20gJy4vQ29yZG92YVBvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzID0gJ2hpZGRlbj15ZXMnO1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBDb3Jkb3ZhUG9wdXBXaW5kb3cgfSBmcm9tICcuL0NvcmRvdmFQb3B1cFdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgQ29yZG92YVBvcHVwTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHpvb209bm8nO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIENvcmRvdmFQb3B1cFdpbmRvdyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IocGFyYW1zKSB7XHJcbiAgICAgICAgdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZSA9IHJlc29sdmU7XHJcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdCA9IHJlamVjdDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5mZWF0dXJlcyA9IHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzIHx8IERlZmF1bHRQb3B1cEZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnJlZGlyZWN0X3VyaSA9IHBhcmFtcy5zdGFydFVybDtcclxuICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3cuY3RvcjogcmVkaXJlY3RfdXJpOiBcIiArIHRoaXMucmVkaXJlY3RfdXJpKTtcclxuICAgIH1cclxuXHJcbiAgICBfaXNJbkFwcEJyb3dzZXJJbnN0YWxsZWQoY29yZG92YU1ldGFkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIFtcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3NlclwiLCBcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3Nlci5pbmFwcGJyb3dzZXJcIiwgXCJvcmcuYXBhY2hlLmNvcmRvdmEuaW5hcHBicm93c2VyXCJdLnNvbWUoZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNvcmRvdmFNZXRhZGF0YS5oYXNPd25Qcm9wZXJ0eShuYW1lKVxyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbiAgICBcclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICghd2luZG93LmNvcmRvdmEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9lcnJvcihcImNvcmRvdmEgaXMgdW5kZWZpbmVkXCIpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHZhciBjb3Jkb3ZhTWV0YWRhdGEgPSB3aW5kb3cuY29yZG92YS5yZXF1aXJlKFwiY29yZG92YS9wbHVnaW5fbGlzdFwiKS5tZXRhZGF0YTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzSW5BcHBCcm93c2VySW5zdGFsbGVkKGNvcmRvdmFNZXRhZGF0YSkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3IoXCJJbkFwcEJyb3dzZXIgcGx1Z2luIG5vdCBmb3VuZFwiKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwID0gY29yZG92YS5JbkFwcEJyb3dzZXIub3BlbihwYXJhbXMudXJsLCB0aGlzLnRhcmdldCwgdGhpcy5mZWF0dXJlcyk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9wb3B1cCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQ29yZG92YVBvcHVwV2luZG93Lm5hdmlnYXRlOiBwb3B1cCBzdWNjZXNzZnVsbHkgY3JlYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQgPSB0aGlzLl9leGl0Q2FsbGJhY2suYmluZCh0aGlzKTsgXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkU3RhcnRDYWxsYmFja0V2ZW50ID0gdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2suYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcG9wdXAuYWRkRXZlbnRMaXN0ZW5lcihcImV4aXRcIiwgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BvcHVwLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2Fkc3RhcnRcIiwgdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJFcnJvciBvcGVuaW5nIHBvcHVwIHdpbmRvd1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwcm9taXNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkU3RhcnRDYWxsYmFjayhldmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC51cmwuaW5kZXhPZih0aGlzLnJlZGlyZWN0X3VyaSkgPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5fc3VjY2Vzcyh7IHVybDogZXZlbnQudXJsIH0pO1xyXG4gICAgICAgIH0gICAgXHJcbiAgICB9XHJcbiAgICBfZXhpdENhbGxiYWNrKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLl9lcnJvcihtZXNzYWdlKTsgICAgXHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICB0aGlzLl9jbGVhbnVwKCk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIkNvcmRvdmFQb3B1cFdpbmRvdzogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIGNvcmRvdmEgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fcG9wdXApe1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3c6IGNsZWFuaW5nIHVwIHBvcHVwXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXhpdFwiLCB0aGlzLl9leGl0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwibG9hZHN0YXJ0XCIsIHRoaXMuX2xvYWRTdGFydENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgdGhpcy5fcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSBudWxsO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFcnJvclJlc3BvbnNlIGV4dGVuZHMgRXJyb3Ige1xyXG4gICAgY29uc3RydWN0b3Ioe2Vycm9yLCBlcnJvcl9kZXNjcmlwdGlvbiwgZXJyb3JfdXJpLCBzdGF0ZSwgc2Vzc2lvbl9zdGF0ZX09e31cclxuICAgICkge1xyXG4gICAgICAgICBpZiAoIWVycm9yKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiTm8gZXJyb3IgcGFzc2VkIHRvIEVycm9yUmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImVycm9yXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3VwZXIoZXJyb3JfZGVzY3JpcHRpb24gfHwgZXJyb3IpO1xyXG5cclxuICAgICAgICB0aGlzLm5hbWUgPSBcIkVycm9yUmVzcG9uc2VcIjtcclxuXHJcbiAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSBlcnJvcl9kZXNjcmlwdGlvbjtcclxuICAgICAgICB0aGlzLmVycm9yX3VyaSA9IGVycm9yX3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEV2ZW50IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lKSB7XHJcbiAgICAgICAgdGhpcy5fbmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgYWRkSGFuZGxlcihjYikge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrcy5wdXNoKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVIYW5kbGVyKGNiKSB7XHJcbiAgICAgICAgdmFyIGlkeCA9IHRoaXMuX2NhbGxiYWNrcy5maW5kSW5kZXgoaXRlbSA9PiBpdGVtID09PSBjYik7XHJcbiAgICAgICAgaWYgKGlkeCA+PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmFpc2UoLi4ucGFyYW1zKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiRXZlbnQ6IFJhaXNpbmcgZXZlbnQ6IFwiICsgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9jYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzW2ldKC4uLnBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmNvbnN0IHRpbWVyID0ge1xyXG4gICAgc2V0SW50ZXJ2YWw6IGZ1bmN0aW9uIChjYiwgZHVyYXRpb24pIHtcclxuICAgICAgICByZXR1cm4gc2V0SW50ZXJ2YWwoY2IsIGR1cmF0aW9uKTtcclxuICAgIH0sXHJcbiAgICBjbGVhckludGVydmFsOiBmdW5jdGlvbiAoaGFuZGxlKSB7XHJcbiAgICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwoaGFuZGxlKTtcclxuICAgIH1cclxufTtcclxuXHJcbmxldCB0ZXN0aW5nID0gZmFsc2U7XHJcbmxldCByZXF1ZXN0ID0gbnVsbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBHbG9iYWwge1xyXG5cclxuICAgIHN0YXRpYyBfdGVzdGluZygpIHtcclxuICAgICAgICB0ZXN0aW5nID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IGxvY2F0aW9uKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgbG9jYWxTdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYWxTdG9yYWdlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IHNlc3Npb25TdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gc2Vzc2lvblN0b3JhZ2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBzZXRYTUxIdHRwUmVxdWVzdChuZXdSZXF1ZXN0KSB7XHJcbiAgICAgICAgcmVxdWVzdCA9IG5ld1JlcXVlc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGdldCBYTUxIdHRwUmVxdWVzdCgpIHtcclxuICAgICAgICBpZiAoIXRlc3RpbmcgJiYgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QgfHwgWE1MSHR0cFJlcXVlc3Q7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgdGltZXIoKSB7XHJcbiAgICAgICAgaWYgKCF0ZXN0aW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aW1lcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVXaW5kb3cgfSBmcm9tICcuL0lGcmFtZVdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBmcmFtZSA9IG5ldyBJRnJhbWVXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZyYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVOYXZpZ2F0b3IuY2FsbGJhY2tcIik7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIElGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQodXJsKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRUaW1lb3V0ID0gMTAwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZnJhbWUgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlmcmFtZVwiKTtcclxuXHJcbiAgICAgICAgLy8gc2hvdGd1biBhcHByb2FjaFxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnZpc2liaWxpdHkgPSBcImhpZGRlblwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS53aWR0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUuaGVpZ2h0ID0gMDtcclxuXHJcbiAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IHRpbWVvdXQgPSBwYXJhbXMuc2lsZW50UmVxdWVzdFRpbWVvdXQgfHwgRGVmYXVsdFRpbWVvdXQ7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5uYXZpZ2F0ZTogVXNpbmcgdGltZW91dCBvZjpcIiwgdGltZW91dCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldFRpbWVvdXQodGhpcy5fdGltZW91dC5iaW5kKHRoaXMpLCB0aW1lb3V0KTtcclxuICAgICAgICAgICAgdGhpcy5fZnJhbWUuc3JjID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHByb21pc2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgX3N1Y2Nlc3MoZGF0YSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBTdWNjZXNzZnVsIHJlc3BvbnNlIGZyb20gZnJhbWUgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fZnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBjbGVhbnVwXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLl9mcmFtZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lID0gbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdGltZW91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVXaW5kb3cudGltZW91dFwiKTtcclxuICAgICAgICB0aGlzLl9lcnJvcihcIkZyYW1lIHdpbmRvdyB0aW1lZCBvdXRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgX21lc3NhZ2UoZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5tZXNzYWdlXCIpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fdGltZXIgJiZcclxuICAgICAgICAgICAgZS5vcmlnaW4gPT09IHRoaXMuX29yaWdpbiAmJlxyXG4gICAgICAgICAgICBlLnNvdXJjZSA9PT0gdGhpcy5fZnJhbWUuY29udGVudFdpbmRvd1xyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICBsZXQgdXJsID0gZS5kYXRhO1xyXG4gICAgICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWNjZXNzKHsgdXJsOiB1cmwgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9lcnJvcihcIkludmFsaWQgcmVzcG9uc2UgZnJvbSBmcmFtZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX29yaWdpbigpIHtcclxuICAgICAgICByZXR1cm4gbG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyBsb2NhdGlvbi5ob3N0O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBub3RpZnlQYXJlbnQodXJsKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93Lm5vdGlmeVBhcmVudFwiKTtcclxuICAgICAgICBpZiAod2luZG93LmZyYW1lRWxlbWVudCkge1xyXG4gICAgICAgICAgICB1cmwgPSB1cmwgfHwgd2luZG93LmxvY2F0aW9uLmhyZWY7XHJcbiAgICAgICAgICAgIGlmICh1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQ6IHBvc3RpbmcgdXJsIG1lc3NhZ2UgdG8gcGFyZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZSh1cmwsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICsgbG9jYXRpb24uaG9zdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEluTWVtb3J5V2ViU3RvcmFnZXtcclxuICAgIGNvbnN0cnVjdG9yKCl7XHJcbiAgICAgICAgdGhpcy5fZGF0YSA9IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIGdldEl0ZW0oa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLmdldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIHNldEl0ZW0oa2V5LCB2YWx1ZSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnNldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICB0aGlzLl9kYXRhW2tleV0gPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVJdGVtKGtleSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnJlbW92ZUl0ZW1cIiwga2V5KTtcclxuICAgICAgICBkZWxldGUgdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBsZW5ndGgoKSB7XHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMuX2RhdGEpLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBrZXkoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcy5fZGF0YSlbaW5kZXhdO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IGp3cywgS2V5VXRpbCwgWDUwOSwgY3J5cHRvLCBoZXh0b2I2NHUsIGI2NHRvaGV4LCBBbGxvd2VkU2lnbmluZ0FsZ3MgfSBmcm9tICcuL2NyeXB0by9qc3JzYXNpZ24nO1xyXG5pbXBvcnQgZ2V0Sm9zZVV0aWwgZnJvbSAnLi9Kb3NlVXRpbEltcGwnO1xyXG5cclxuZXhwb3J0IGNvbnN0IEpvc2VVdGlsID0gZ2V0Sm9zZVV0aWwoeyBqd3MsIEtleVV0aWwsIFg1MDksIGNyeXB0bywgaGV4dG9iNjR1LCBiNjR0b2hleCwgQWxsb3dlZFNpZ25pbmdBbGdzIH0pO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRKb3NlVXRpbCh7IGp3cywgS2V5VXRpbCwgWDUwOSwgY3J5cHRvLCBoZXh0b2I2NHUsIGI2NHRvaGV4LCBBbGxvd2VkU2lnbmluZ0FsZ3MgfSkge1xyXG4gICAgcmV0dXJuIGNsYXNzIEpvc2VVdGlsIHtcclxuXHJcbiAgICAgICAgc3RhdGljIHBhcnNlSnd0KGp3dCkge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJKb3NlVXRpbC5wYXJzZUp3dFwiKTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHZhciB0b2tlbiA9IGp3cy5KV1MucGFyc2Uoand0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyOiB0b2tlbi5oZWFkZXJPYmosXHJcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDogdG9rZW4ucGF5bG9hZE9ialxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyB2YWxpZGF0ZUp3dChqd3QsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3LCBub3csIHRpbWVJbnNlbnNpdGl2ZSkge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dFwiKTtcclxuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoa2V5Lmt0eSA9PT0gXCJSU0FcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuZSAmJiBrZXkubikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBLZXlVdGlsLmdldEtleShrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5Lng1YyAmJiBrZXkueDVjLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGV4ID0gYjY0dG9oZXgoa2V5Lng1Y1swXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFg1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRIZXgoaGV4KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dDogUlNBIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiUlNBIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkua3R5ID09PSBcIkVDXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LmNydiAmJiBrZXkueCAmJiBrZXkueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBLZXlVdGlsLmdldEtleShrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLnZhbGlkYXRlSnd0OiBFQyBrZXkgbWlzc2luZyBrZXkgbWF0ZXJpYWxcIiwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkVDIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dDogVW5zdXBwb3J0ZWQga2V5IHR5cGVcIiwga2V5ICYmIGtleS5rdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBrZXkgdHlwZTogXCIgKyBrZXkgJiYga2V5Lmt0eSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBKb3NlVXRpbC5fdmFsaWRhdGVKd3Qoand0LCBrZXksIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSAmJiBlLm1lc3NhZ2UgfHwgZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJKV1QgdmFsaWRhdGlvbiBmYWlsZWRcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyB2YWxpZGF0ZUp3dEF0dHJpYnV0ZXMoand0LCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXcsIG5vdywgdGltZUluc2Vuc2l0aXZlKSB7XHJcbiAgICAgICAgICAgIGlmICghY2xvY2tTa2V3KSB7XHJcbiAgICAgICAgICAgICAgICBjbG9ja1NrZXcgPSAwO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIW5vdykge1xyXG4gICAgICAgICAgICAgICAgbm93ID0gcGFyc2VJbnQoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIgcGF5bG9hZCA9IEpvc2VVdGlsLnBhcnNlSnd0KGp3dCkucGF5bG9hZDtcclxuXHJcbiAgICAgICAgICAgIGlmICghcGF5bG9hZC5pc3MpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogaXNzdWVyIHdhcyBub3QgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaXNzdWVyIHdhcyBub3QgcHJvdmlkZWRcIikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmlzcyAhPT0gaXNzdWVyKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IEludmFsaWQgaXNzdWVyIGluIHRva2VuXCIsIHBheWxvYWQuaXNzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIGlzc3VlciBpbiB0b2tlbjogXCIgKyBwYXlsb2FkLmlzcykpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXBheWxvYWQuYXVkKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGF1ZCB3YXMgbm90IHByb3ZpZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImF1ZCB3YXMgbm90IHByb3ZpZGVkXCIpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgdmFsaWRBdWRpZW5jZSA9IHBheWxvYWQuYXVkID09PSBhdWRpZW5jZSB8fCAoQXJyYXkuaXNBcnJheShwYXlsb2FkLmF1ZCkgJiYgcGF5bG9hZC5hdWQuaW5kZXhPZihhdWRpZW5jZSkgPj0gMCk7XHJcbiAgICAgICAgICAgIGlmICghdmFsaWRBdWRpZW5jZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBJbnZhbGlkIGF1ZGllbmNlIGluIHRva2VuXCIsIHBheWxvYWQuYXVkKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIGF1ZGllbmNlIGluIHRva2VuOiBcIiArIHBheWxvYWQuYXVkKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuYXpwICYmIHBheWxvYWQuYXpwICE9PSBhdWRpZW5jZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBJbnZhbGlkIGF6cCBpbiB0b2tlblwiLCBwYXlsb2FkLmF6cCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBhenAgaW4gdG9rZW46IFwiICsgcGF5bG9hZC5henApKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aW1lSW5zZW5zaXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHZhciBsb3dlck5vdyA9IG5vdyArIGNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgIHZhciB1cHBlck5vdyA9IG5vdyAtIGNsb2NrU2tldztcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXBheWxvYWQuaWF0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBpYXQgd2FzIG5vdCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaWF0IHdhcyBub3QgcHJvdmlkZWRcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGxvd2VyTm93IDwgcGF5bG9hZC5pYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGlhdCBpcyBpbiB0aGUgZnV0dXJlXCIsIHBheWxvYWQuaWF0KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaWF0IGlzIGluIHRoZSBmdXR1cmU6IFwiICsgcGF5bG9hZC5pYXQpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5uYmYgJiYgbG93ZXJOb3cgPCBwYXlsb2FkLm5iZikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogbmJmIGlzIGluIHRoZSBmdXR1cmVcIiwgcGF5bG9hZC5uYmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJuYmYgaXMgaW4gdGhlIGZ1dHVyZTogXCIgKyBwYXlsb2FkLm5iZikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5leHApIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGV4cCB3YXMgbm90IHByb3ZpZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJleHAgd2FzIG5vdCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5leHAgPCB1cHBlck5vdykge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogZXhwIGlzIGluIHRoZSBwYXN0XCIsIHBheWxvYWQuZXhwKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiZXhwIGlzIGluIHRoZSBwYXN0OlwiICsgcGF5bG9hZC5leHApKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwYXlsb2FkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyBfdmFsaWRhdGVKd3Qoand0LCBrZXksIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBKb3NlVXRpbC52YWxpZGF0ZUp3dEF0dHJpYnV0ZXMoand0LCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXcsIG5vdywgdGltZUluc2Vuc2l0aXZlKS50aGVuKHBheWxvYWQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWp3cy5KV1MudmVyaWZ5KGp3dCwga2V5LCBBbGxvd2VkU2lnbmluZ0FsZ3MpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogc2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihlICYmIGUubWVzc2FnZSB8fCBlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGF0aWMgaGFzaFN0cmluZyh2YWx1ZSwgYWxnKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY3J5cHRvLlV0aWwuaGFzaFN0cmluZyh2YWx1ZSwgYWxnKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGF0aWMgaGV4VG9CYXNlNjRVcmwodmFsdWUpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBoZXh0b2I2NHUodmFsdWUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSnNvblNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgYWRkaXRpb25hbENvbnRlbnRUeXBlcyA9IG51bGwsIFxyXG4gICAgICAgIFhNTEh0dHBSZXF1ZXN0Q3RvciA9IEdsb2JhbC5YTUxIdHRwUmVxdWVzdCwgXHJcbiAgICAgICAgand0SGFuZGxlciA9IG51bGxcclxuICAgICkge1xyXG4gICAgICAgIGlmIChhZGRpdGlvbmFsQ29udGVudFR5cGVzICYmIEFycmF5LmlzQXJyYXkoYWRkaXRpb25hbENvbnRlbnRUeXBlcykpXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMgPSBhZGRpdGlvbmFsQ29udGVudFR5cGVzLnNsaWNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcyA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMucHVzaCgnYXBwbGljYXRpb24vanNvbicpO1xyXG4gICAgICAgIGlmIChqd3RIYW5kbGVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcy5wdXNoKCdhcHBsaWNhdGlvbi9qd3QnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX1hNTEh0dHBSZXF1ZXN0ID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX2p3dEhhbmRsZXIgPSBqd3RIYW5kbGVyO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEpzb24odXJsLCB0b2tlbikge1xyXG4gICAgICAgIGlmICghdXJsKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbiwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ0dFVCcsIHVybCk7XHJcblxyXG4gICAgICAgICAgICB2YXIgYWxsb3dlZENvbnRlbnRUeXBlcyA9IHRoaXMuX2NvbnRlbnRUeXBlcztcclxuICAgICAgICAgICAgdmFyIGp3dEhhbmRsZXIgPSB0aGlzLl9qd3RIYW5kbGVyO1xyXG5cclxuICAgICAgICAgICAgcmVxLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kID09IFwiYXBwbGljYXRpb24vand0XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp3dEhhbmRsZXIocmVxKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKEpTT04ucGFyc2UocmVxLnJlc3BvbnNlVGV4dCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IocmVxLnN0YXR1c1RleHQgKyBcIiAoXCIgKyByZXEuc3RhdHVzICsgXCIpXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5nZXRKc29uOiBuZXR3b3JrIGVycm9yXCIpO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiTmV0d29yayBFcnJvclwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkpzb25TZXJ2aWNlLmdldEpzb246IHRva2VuIHBhc3NlZCwgc2V0dGluZyBBdXRob3JpemF0aW9uIGhlYWRlclwiKTtcclxuICAgICAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyKFwiQXV0aG9yaXphdGlvblwiLCBcIkJlYXJlciBcIiArIHRva2VuKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNlbmQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwb3N0Rm9ybSh1cmwsIHBheWxvYWQpIHtcclxuICAgICAgICBpZiAoIXVybCl7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybSwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ1BPU1QnLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGFsbG93ZWRDb250ZW50VHlwZXMgPSB0aGlzLl9jb250ZW50VHlwZXM7XHJcblxyXG4gICAgICAgICAgICByZXEub25sb2FkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSA0MDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXlsb2FkID0gSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF5bG9hZCAmJiBwYXlsb2FkLmVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBFcnJvciBmcm9tIHNlcnZlcjogXCIsIHBheWxvYWQuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKHBheWxvYWQuZXJyb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IEVycm9yIHBhcnNpbmcgSlNPTiByZXNwb25zZVwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlcS5zdGF0dXNUZXh0ICsgXCIgKFwiICsgcmVxLnN0YXR1cyArIFwiKVwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IG5ldHdvcmsgZXJyb3JcIik7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IoXCJOZXR3b3JrIEVycm9yXCIpKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGxldCBib2R5ID0gXCJcIjtcclxuICAgICAgICAgICAgZm9yKGxldCBrZXkgaW4gcGF5bG9hZCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHBheWxvYWRba2V5XTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJvZHkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiJlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYm9keSArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KTtcclxuICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiPVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIik7XHJcbiAgICAgICAgICAgIHJlcS5zZW5kKGJvZHkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmxldCBub3BMb2dnZXIgPSB7XHJcbiAgICBkZWJ1Zygpe30sXHJcbiAgICBpbmZvKCl7fSxcclxuICAgIHdhcm4oKXt9LFxyXG4gICAgZXJyb3IoKXt9XHJcbn07XHJcblxyXG5jb25zdCBOT05FID0gMDtcclxuY29uc3QgRVJST1IgPSAxO1xyXG5jb25zdCBXQVJOID0gMjtcclxuY29uc3QgSU5GTyA9IDM7XHJcbmNvbnN0IERFQlVHID0gNDtcclxuXHJcbmxldCBsb2dnZXI7XHJcbmxldCBsZXZlbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBMb2cge1xyXG4gICAgc3RhdGljIGdldCBOT05FKCkge3JldHVybiBOT05FfTtcclxuICAgIHN0YXRpYyBnZXQgRVJST1IoKSB7cmV0dXJuIEVSUk9SfTtcclxuICAgIHN0YXRpYyBnZXQgV0FSTigpIHtyZXR1cm4gV0FSTn07XHJcbiAgICBzdGF0aWMgZ2V0IElORk8oKSB7cmV0dXJuIElORk99O1xyXG4gICAgc3RhdGljIGdldCBERUJVRygpIHtyZXR1cm4gREVCVUd9O1xyXG4gICAgXHJcbiAgICBzdGF0aWMgcmVzZXQoKXtcclxuICAgICAgICBsZXZlbCA9IElORk87XHJcbiAgICAgICAgbG9nZ2VyID0gbm9wTG9nZ2VyO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxldmVsKCl7XHJcbiAgICAgICAgcmV0dXJuIGxldmVsO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIHNldCBsZXZlbCh2YWx1ZSl7XHJcbiAgICAgICAgaWYgKE5PTkUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gREVCVUcpe1xyXG4gICAgICAgICAgICBsZXZlbCA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBsb2cgbGV2ZWxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxvZ2dlcigpe1xyXG4gICAgICAgIHJldHVybiBsb2dnZXI7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgc2V0IGxvZ2dlcih2YWx1ZSl7XHJcbiAgICAgICAgaWYgKCF2YWx1ZS5kZWJ1ZyAmJiB2YWx1ZS5pbmZvKSB7XHJcbiAgICAgICAgICAgIC8vIGp1c3QgdG8gc3RheSBiYWNrd2FyZHMgY29tcGF0LiBjYW4gcmVtb3ZlIGluIDIuMFxyXG4gICAgICAgICAgICB2YWx1ZS5kZWJ1ZyA9IHZhbHVlLmluZm87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmFsdWUuZGVidWcgJiYgdmFsdWUuaW5mbyAmJiB2YWx1ZS53YXJuICYmIHZhbHVlLmVycm9yKXtcclxuICAgICAgICAgICAgbG9nZ2VyID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGxvZ2dlclwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHN0YXRpYyBkZWJ1ZyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gREVCVUcpe1xyXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgaW5mbyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gSU5GTyl7XHJcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvLmFwcGx5KGxvZ2dlciwgQXJyYXkuZnJvbShhcmdzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIHdhcm4oLi4uYXJncyl7XHJcbiAgICAgICAgaWYgKGxldmVsID49IFdBUk4pe1xyXG4gICAgICAgICAgICBsb2dnZXIud2Fybi5hcHBseShsb2dnZXIsIEFycmF5LmZyb20oYXJncykpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHN0YXRpYyBlcnJvciguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gRVJST1Ipe1xyXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbkxvZy5yZXNldCgpO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmV4cG9ydCBjbGFzcyBNZXRhZGF0YVNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MsIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2U6IE5vIHNldHRpbmdzIHBhc3NlZCB0byBNZXRhZGF0YVNlcnZpY2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IoWydhcHBsaWNhdGlvbi9qd2stc2V0K2pzb24nXSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1ldGFkYXRhVXJsKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5fbWV0YWRhdGFVcmwpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgPSB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsICYmIHRoaXMuX21ldGFkYXRhVXJsLmluZGV4T2YoT2lkY01ldGFkYXRhVXJsUGF0aCkgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsW3RoaXMuX21ldGFkYXRhVXJsLmxlbmd0aCAtIDFdICE9PSAnLycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCArPSBPaWRjTWV0YWRhdGFVcmxQYXRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TWV0YWRhdGEoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogUmV0dXJuaW5nIG1ldGFkYXRhIGZyb20gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fc2V0dGluZ3MubWV0YWRhdGEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogTm8gYXV0aG9yaXR5IG9yIG1ldGFkYXRhVXJsIGNvbmZpZ3VyZWQgb24gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb3IgbWV0YWRhdGFVcmwgY29uZmlndXJlZCBvbiBzZXR0aW5nc1wiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGE6IGdldHRpbmcgbWV0YWRhdGEgZnJvbVwiLCB0aGlzLm1ldGFkYXRhVXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24odGhpcy5tZXRhZGF0YVVybClcclxuICAgICAgICAgICAgLnRoZW4obWV0YWRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiTWV0YWRhdGFTZXJ2aWNlLmdldE1ldGFkYXRhOiBqc29uIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MubWV0YWRhdGEgPSBtZXRhZGF0YTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0SXNzdWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiaXNzdWVyXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEF1dGhvcml6YXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImF1dGhvcml6YXRpb25fZW5kcG9pbnRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlckluZm9FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInVzZXJpbmZvX2VuZHBvaW50XCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFRva2VuRW5kcG9pbnQob3B0aW9uYWw9dHJ1ZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwidG9rZW5fZW5kcG9pbnRcIiwgb3B0aW9uYWwpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENoZWNrU2Vzc2lvbklmcmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImNoZWNrX3Nlc3Npb25faWZyYW1lXCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEVuZFNlc3Npb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImVuZF9zZXNzaW9uX2VuZHBvaW50XCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFJldm9jYXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInJldm9jYXRpb25fZW5kcG9pbnRcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0S2V5c0VuZHBvaW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldE1ldGFkYXRhUHJvcGVydHkobmFtZSwgb3B0aW9uYWw9ZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eSBmb3I6IFwiICsgbmFtZSk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1ldGFkYXRhKCkudGhlbihtZXRhZGF0YSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YVByb3BlcnR5OiBtZXRhZGF0YSByZWNpZXZlZFwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChtZXRhZGF0YVtuYW1lXSA9PT0gdW5kZWZpbmVkKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBvcHRpb25hbCBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGFkYXRhIGRvZXMgbm90IGNvbnRhaW4gcHJvcGVydHkgXCIgKyBuYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhW25hbWVdO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IFJldHVybmluZyBzaWduaW5nS2V5cyBmcm9tIHNldHRpbmdzXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIikudGhlbihqd2tzX3VyaSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czogandrc191cmkgcmVjZWl2ZWRcIiwgandrc191cmkpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24oandrc191cmkpLnRoZW4oa2V5U2V0ID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czoga2V5IHNldCByZWNlaXZlZFwiLCBrZXlTZXQpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICgha2V5U2V0LmtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IE1pc3Npbmcga2V5cyBvbiBrZXlzZXRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBrZXlzIG9uIGtleXNldFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cyA9IGtleVNldC5rZXlzO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE9pZGNDbGllbnRTZXR0aW5ncyB9IGZyb20gJy4vT2lkY0NsaWVudFNldHRpbmdzLmpzJztcclxuaW1wb3J0IHsgRXJyb3JSZXNwb25zZSB9IGZyb20gJy4vRXJyb3JSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblJlcXVlc3QgfSBmcm9tICcuL1NpZ25pblJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWduaW5SZXNwb25zZSB9IGZyb20gJy4vU2lnbmluUmVzcG9uc2UuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVxdWVzdCB9IGZyb20gJy4vU2lnbm91dFJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVzcG9uc2UgfSBmcm9tICcuL1NpZ25vdXRSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9KSB7XHJcbiAgICAgICAgaWYgKHNldHRpbmdzIGluc3RhbmNlb2YgT2lkY0NsaWVudFNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5ncyA9IG5ldyBPaWRjQ2xpZW50U2V0dGluZ3Moc2V0dGluZ3MpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3N0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3Muc3RhdGVTdG9yZTtcclxuICAgIH1cclxuICAgIGdldCBfdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnZhbGlkYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLm1ldGFkYXRhU2VydmljZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2V0dGluZ3MoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG5cclxuICAgIGNyZWF0ZVNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgIHJlc3BvbnNlX3R5cGUsIHNjb3BlLCByZWRpcmVjdF91cmksXHJcbiAgICAgICAgLy8gZGF0YSB3YXMgbWVhbnQgdG8gYmUgdGhlIHBsYWNlIGEgY2FsbGVyIGNvdWxkIGluZGljYXRlIHRoZSBkYXRhIHRvXHJcbiAgICAgICAgLy8gaGF2ZSByb3VuZCB0cmlwcGVkLCBidXQgcGVvcGxlIHdlcmUgZ2V0dGluZyBjb25mdXNlZCwgc28gaSBhZGRlZCBzdGF0ZSAoc2luY2UgdGhhdCBtYXRjaGVzIHRoZSBzcGVjKVxyXG4gICAgICAgIC8vIGFuZCBzbyBub3cgaWYgZGF0YSBpcyBub3QgcGFzc2VkLCBidXQgc3RhdGUgaXMgdGhlbiBzdGF0ZSB3aWxsIGJlIHVzZWRcclxuICAgICAgICBkYXRhLCBzdGF0ZSwgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBpZF90b2tlbl9oaW50LCBsb2dpbl9oaW50LCBhY3JfdmFsdWVzLFxyXG4gICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgcmVzcG9uc2VfbW9kZSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCBza2lwVXNlckluZm8gfSA9IHt9LFxyXG4gICAgICAgIHN0YXRlU3RvcmVcclxuICAgICkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbmluUmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICByZXNwb25zZV90eXBlID0gcmVzcG9uc2VfdHlwZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHNjb3BlID0gc2NvcGUgfHwgdGhpcy5fc2V0dGluZ3Muc2NvcGU7XHJcbiAgICAgICAgcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgLy8gaWRfdG9rZW5faGludCwgbG9naW5faGludCBhcmVuJ3QgYWxsb3dlZCBvbiBfc2V0dGluZ3NcclxuICAgICAgICBwcm9tcHQgPSBwcm9tcHQgfHwgdGhpcy5fc2V0dGluZ3MucHJvbXB0O1xyXG4gICAgICAgIGRpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuX3NldHRpbmdzLmRpc3BsYXk7XHJcbiAgICAgICAgbWF4X2FnZSA9IG1heF9hZ2UgfHwgdGhpcy5fc2V0dGluZ3MubWF4X2FnZTtcclxuICAgICAgICB1aV9sb2NhbGVzID0gdWlfbG9jYWxlcyB8fCB0aGlzLl9zZXR0aW5ncy51aV9sb2NhbGVzO1xyXG4gICAgICAgIGFjcl92YWx1ZXMgPSBhY3JfdmFsdWVzIHx8IHRoaXMuX3NldHRpbmdzLmFjcl92YWx1ZXM7XHJcbiAgICAgICAgcmVzb3VyY2UgPSByZXNvdXJjZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNvdXJjZTtcclxuICAgICAgICByZXNwb25zZV9tb2RlID0gcmVzcG9uc2VfbW9kZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlO1xyXG4gICAgICAgIGV4dHJhUXVlcnlQYXJhbXMgPSBleHRyYVF1ZXJ5UGFyYW1zIHx8IHRoaXMuX3NldHRpbmdzLmV4dHJhUXVlcnlQYXJhbXM7XHJcbiAgICAgICAgZXh0cmFUb2tlblBhcmFtcyA9IGV4dHJhVG9rZW5QYXJhbXMgfHwgdGhpcy5fc2V0dGluZ3MuZXh0cmFUb2tlblBhcmFtcztcclxuXHJcbiAgICAgICAgbGV0IGF1dGhvcml0eSA9IHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eTtcclxuXHJcbiAgICAgICAgaWYgKFNpZ25pblJlcXVlc3QuaXNDb2RlKHJlc3BvbnNlX3R5cGUpICYmIHJlc3BvbnNlX3R5cGUgIT09IFwiY29kZVwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJPcGVuSUQgQ29ubmVjdCBoeWJyaWQgZmxvdyBpcyBub3Qgc3VwcG9ydGVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0QXV0aG9yaXphdGlvbkVuZHBvaW50KCkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25pblJlcXVlc3Q6IFJlY2VpdmVkIGF1dGhvcml6YXRpb24gZW5kcG9pbnRcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBzaWduaW5SZXF1ZXN0ID0gbmV3IFNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X2lkLFxyXG4gICAgICAgICAgICAgICAgcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VfdHlwZSxcclxuICAgICAgICAgICAgICAgIHNjb3BlLFxyXG4gICAgICAgICAgICAgICAgZGF0YTogZGF0YSB8fCBzdGF0ZSxcclxuICAgICAgICAgICAgICAgIGF1dGhvcml0eSxcclxuICAgICAgICAgICAgICAgIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcyxcclxuICAgICAgICAgICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCByZXNwb25zZV9tb2RlLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X3NlY3JldDogdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgICAgIHNraXBVc2VySW5mb1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHZhciBzaWduaW5TdGF0ZSA9IHNpZ25pblJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gc3RhdGVTdG9yZS5zZXQoc2lnbmluU3RhdGUuaWQsIHNpZ25pblN0YXRlLnRvU3RvcmFnZVN0cmluZygpKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzaWduaW5SZXF1ZXN0O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbmluUmVzcG9uc2VTdGF0ZSh1cmwsIHN0YXRlU3RvcmUsIHJlbW92ZVN0YXRlID0gZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBsZXQgdXNlUXVlcnkgPSB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlID09PSBcInF1ZXJ5XCIgfHwgXHJcbiAgICAgICAgICAgICghdGhpcy5fc2V0dGluZ3MucmVzcG9uc2VfbW9kZSAmJiBTaWduaW5SZXF1ZXN0LmlzQ29kZSh0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlKSk7XHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9IHVzZVF1ZXJ5ID8gXCI/XCIgOiBcIiNcIjtcclxuXHJcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNpZ25pblJlc3BvbnNlKHVybCwgZGVsaW1pdGVyKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN0YXRlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUFwaSA9IHJlbW92ZVN0YXRlID8gc3RhdGVTdG9yZS5yZW1vdmUuYmluZChzdGF0ZVN0b3JlKSA6IHN0YXRlU3RvcmUuZ2V0LmJpbmQoc3RhdGVTdG9yZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShyZXNwb25zZS5zdGF0ZSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25pblJlc3BvbnNlU3RhdGU6IE5vIG1hdGNoaW5nIHN0YXRlIGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgc3RhdGUgPSBTaWduaW5TdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhzdG9yZWRTdGF0ZVN0cmluZyk7XHJcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGUsIHJlc3BvbnNlfTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcm9jZXNzU2lnbmluUmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCwgc3RhdGVTdG9yZSwgdHJ1ZSkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2U6IFJlY2VpdmVkIHN0YXRlIGZyb20gc3RvcmFnZTsgdmFsaWRhdGluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY3JlYXRlU2lnbm91dFJlcXVlc3Qoe2lkX3Rva2VuX2hpbnQsIGRhdGEsIHN0YXRlLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSB9ID0ge30sXHJcbiAgICAgICAgc3RhdGVTdG9yZVxyXG4gICAgKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5jcmVhdGVTaWdub3V0UmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zID0gZXh0cmFRdWVyeVBhcmFtcyB8fCB0aGlzLl9zZXR0aW5ncy5leHRyYVF1ZXJ5UGFyYW1zO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldEVuZFNlc3Npb25FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IE5vIGVuZCBzZXNzaW9uIGVuZHBvaW50IHVybCByZXR1cm5lZFwiKTtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vIGVuZCBzZXNzaW9uIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25vdXRSZXF1ZXN0OiBSZWNlaXZlZCBlbmQgc2Vzc2lvbiBlbmRwb2ludFwiLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgU2lnbm91dFJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgaWRfdG9rZW5faGludCxcclxuICAgICAgICAgICAgICAgIHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEgfHwgc3RhdGUsXHJcbiAgICAgICAgICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zLFxyXG4gICAgICAgICAgICAgICAgcmVxdWVzdF90eXBlXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdmFyIHNpZ25vdXRTdGF0ZSA9IHJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIGlmIChzaWdub3V0U3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IFNpZ25vdXQgcmVxdWVzdCBoYXMgc3RhdGUgdG8gcGVyc2lzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG4gICAgICAgICAgICAgICAgc3RhdGVTdG9yZS5zZXQoc2lnbm91dFN0YXRlLmlkLCBzaWdub3V0U3RhdGUudG9TdG9yYWdlU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCByZW1vdmVTdGF0ZSA9IGZhbHNlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGVcIik7XHJcblxyXG4gICAgICAgIHZhciByZXNwb25zZSA9IG5ldyBTaWdub3V0UmVzcG9uc2UodXJsKTtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLndhcm4oXCJPaWRjQ2xpZW50LnJlYWRTaWdub3V0UmVzcG9uc2VTdGF0ZTogUmVzcG9uc2Ugd2FzIGVycm9yOiBcIiwgcmVzcG9uc2UuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe3VuZGVmaW5lZCwgcmVzcG9uc2V9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUtleSA9IHJlc3BvbnNlLnN0YXRlO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICB2YXIgc3RhdGVBcGkgPSByZW1vdmVTdGF0ZSA/IHN0YXRlU3RvcmUucmVtb3ZlLmJpbmQoc3RhdGVTdG9yZSkgOiBzdGF0ZVN0b3JlLmdldC5iaW5kKHN0YXRlU3RvcmUpO1xyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShzdGF0ZUtleSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWF0Y2hpbmcgc3RhdGUgZm91bmQgaW4gc3RvcmFnZVwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IHN0YXRlID0gU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmVkU3RhdGVTdHJpbmcpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtzdGF0ZSwgcmVzcG9uc2V9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCB0cnVlKS50aGVuKCh7c3RhdGUsIHJlc3BvbnNlfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoc3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucHJvY2Vzc1NpZ25vdXRSZXNwb25zZTogUmVjZWl2ZWQgc3RhdGUgZnJvbSBzdG9yYWdlOyB2YWxpZGF0aW5nIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlOiBObyBzdGF0ZSBmcm9tIHN0b3JhZ2U7IHNraXBwaW5nIHZhbGlkYXRpbmcgcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhclN0YWxlU3RhdGUoc3RhdGVTdG9yZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY2xlYXJTdGFsZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICByZXR1cm4gU3RhdGUuY2xlYXJTdGFsZVN0YXRlKHN0YXRlU3RvcmUsIHRoaXMuc2V0dGluZ3Muc3RhbGVTdGF0ZUFnZSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB9IGZyb20gJy4vV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMnO1xyXG5pbXBvcnQgeyBSZXNwb25zZVZhbGlkYXRvciB9IGZyb20gJy4vUmVzcG9uc2VWYWxpZGF0b3IuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmNvbnN0IERlZmF1bHRSZXNwb25zZVR5cGUgPSBcImlkX3Rva2VuXCI7XHJcbmNvbnN0IERlZmF1bHRTY29wZSA9IFwib3BlbmlkXCI7XHJcbmNvbnN0IERlZmF1bHRTdGFsZVN0YXRlQWdlID0gNjAgKiAxNTsgLy8gc2Vjb25kc1xyXG5jb25zdCBEZWZhdWx0Q2xvY2tTa2V3SW5TZWNvbmRzID0gNjAgKiA1O1xyXG5cclxuZXhwb3J0IGNsYXNzIE9pZGNDbGllbnRTZXR0aW5ncyB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWV0YWRhdGEgcmVsYXRlZFxyXG4gICAgICAgIGF1dGhvcml0eSwgbWV0YWRhdGFVcmwsIG1ldGFkYXRhLCBzaWduaW5nS2V5cyxcclxuICAgICAgICAvLyBjbGllbnQgcmVsYXRlZFxyXG4gICAgICAgIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgcmVzcG9uc2VfdHlwZSA9IERlZmF1bHRSZXNwb25zZVR5cGUsIHNjb3BlID0gRGVmYXVsdFNjb3BlLFxyXG4gICAgICAgIHJlZGlyZWN0X3VyaSwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIC8vIG9wdGlvbmFsIHByb3RvY29sXHJcbiAgICAgICAgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBhY3JfdmFsdWVzLCByZXNvdXJjZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAvLyBiZWhhdmlvciBmbGFnc1xyXG4gICAgICAgIGZpbHRlclByb3RvY29sQ2xhaW1zID0gdHJ1ZSwgbG9hZFVzZXJJbmZvID0gdHJ1ZSxcclxuICAgICAgICBzdGFsZVN0YXRlQWdlID0gRGVmYXVsdFN0YWxlU3RhdGVBZ2UsIGNsb2NrU2tldyA9IERlZmF1bHRDbG9ja1NrZXdJblNlY29uZHMsXHJcbiAgICAgICAgdXNlckluZm9Kd3RJc3N1ZXIgPSAnT1AnLFxyXG4gICAgICAgIC8vIG90aGVyIGJlaGF2aW9yXHJcbiAgICAgICAgc3RhdGVTdG9yZSA9IG5ldyBXZWJTdG9yYWdlU3RhdGVTdG9yZSgpLFxyXG4gICAgICAgIFJlc3BvbnNlVmFsaWRhdG9yQ3RvciA9IFJlc3BvbnNlVmFsaWRhdG9yLFxyXG4gICAgICAgIE1ldGFkYXRhU2VydmljZUN0b3IgPSBNZXRhZGF0YVNlcnZpY2UsXHJcbiAgICAgICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICAgICAgZXh0cmFRdWVyeVBhcmFtcyA9IHt9LFxyXG4gICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgPSB7fVxyXG4gICAgfSA9IHt9KSB7XHJcblxyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IG1ldGFkYXRhVXJsO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gbWV0YWRhdGE7XHJcbiAgICAgICAgdGhpcy5fc2lnbmluZ0tleXMgPSBzaWduaW5nS2V5cztcclxuXHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX2NsaWVudF9zZWNyZXQgPSBjbGllbnRfc2VjcmV0O1xyXG4gICAgICAgIHRoaXMuX3Jlc3BvbnNlX3R5cGUgPSByZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHRoaXMuX3Njb3BlID0gc2NvcGU7XHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSA9IHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5fcHJvbXB0ID0gcHJvbXB0O1xyXG4gICAgICAgIHRoaXMuX2Rpc3BsYXkgPSBkaXNwbGF5O1xyXG4gICAgICAgIHRoaXMuX21heF9hZ2UgPSBtYXhfYWdlO1xyXG4gICAgICAgIHRoaXMuX3VpX2xvY2FsZXMgPSB1aV9sb2NhbGVzO1xyXG4gICAgICAgIHRoaXMuX2Fjcl92YWx1ZXMgPSBhY3JfdmFsdWVzO1xyXG4gICAgICAgIHRoaXMuX3Jlc291cmNlID0gcmVzb3VyY2U7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZpbHRlclByb3RvY29sQ2xhaW1zID0gISFmaWx0ZXJQcm90b2NvbENsYWltcztcclxuICAgICAgICB0aGlzLl9sb2FkVXNlckluZm8gPSAhIWxvYWRVc2VySW5mbztcclxuICAgICAgICB0aGlzLl9zdGFsZVN0YXRlQWdlID0gc3RhbGVTdGF0ZUFnZTtcclxuICAgICAgICB0aGlzLl9jbG9ja1NrZXcgPSBjbG9ja1NrZXc7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXIgPSB1c2VySW5mb0p3dElzc3VlcjtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RhdGVTdG9yZSA9IHN0YXRlU3RvcmU7XHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yID0gbmV3IFJlc3BvbnNlVmFsaWRhdG9yQ3Rvcih0aGlzKTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHR5cGVvZiBleHRyYVF1ZXJ5UGFyYW1zID09PSAnb2JqZWN0JyA/IGV4dHJhUXVlcnlQYXJhbXMgOiB7fTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gdHlwZW9mIGV4dHJhVG9rZW5QYXJhbXMgPT09ICdvYmplY3QnID8gZXh0cmFUb2tlblBhcmFtcyA6IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGNsaWVudCBjb25maWdcclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIHNldCBjbGllbnRfaWQodmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NsaWVudF9pZCkge1xyXG4gICAgICAgICAgICAvLyBvbmUtdGltZSBzZXQgb25seVxyXG4gICAgICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnRTZXR0aW5ncy5zZXRfY2xpZW50X2lkOiBjbGllbnRfaWQgaGFzIGFscmVhZHkgYmVlbiBhc3NpZ25lZC5cIilcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkIGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzcG9uc2VfdHlwZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVzcG9uc2VfdHlwZTtcclxuICAgIH1cclxuICAgIGdldCBzY29wZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2NvcGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG9wdGlvbmFsIHByb3RvY29sIHBhcmFtc1xyXG4gICAgZ2V0IHByb21wdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbXB0O1xyXG4gICAgfVxyXG4gICAgZ2V0IGRpc3BsYXkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3BsYXk7XHJcbiAgICB9XHJcbiAgICBnZXQgbWF4X2FnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWF4X2FnZTtcclxuICAgIH1cclxuICAgIGdldCB1aV9sb2NhbGVzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl91aV9sb2NhbGVzO1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjcl92YWx1ZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Fjcl92YWx1ZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzb3VyY2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc291cmNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IHJlc3BvbnNlX21vZGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc3BvbnNlX21vZGU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG1ldGFkYXRhXHJcbiAgICBnZXQgYXV0aG9yaXR5KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hdXRob3JpdHk7XHJcbiAgICB9XHJcbiAgICBzZXQgYXV0aG9yaXR5KHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgLy8gb25lLXRpbWUgc2V0IG9ubHlcclxuICAgICAgICAgICAgdGhpcy5fYXV0aG9yaXR5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50U2V0dGluZ3Muc2V0X2F1dGhvcml0eTogYXV0aG9yaXR5IGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eSBoYXMgYWxyZWFkeSBiZWVuIGFzc2lnbmVkLlwiKVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBtZXRhZGF0YVVybCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX21ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhVXJsID0gdGhpcy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5fbWV0YWRhdGFVcmwgJiYgdGhpcy5fbWV0YWRhdGFVcmwuaW5kZXhPZihPaWRjTWV0YWRhdGFVcmxQYXRoKSA8IDApIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9tZXRhZGF0YVVybFt0aGlzLl9tZXRhZGF0YVVybC5sZW5ndGggLSAxXSAhPT0gJy8nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gT2lkY01ldGFkYXRhVXJsUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhVXJsO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHNldHRhYmxlL2NhY2hhYmxlIG1ldGFkYXRhIHZhbHVlc1xyXG4gICAgZ2V0IG1ldGFkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YTtcclxuICAgIH1cclxuICAgIHNldCBtZXRhZGF0YSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5nS2V5cztcclxuICAgIH1cclxuICAgIHNldCBzaWduaW5nS2V5cyh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX3NpZ25pbmdLZXlzID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYmVoYXZpb3IgZmxhZ3NcclxuICAgIGdldCBmaWx0ZXJQcm90b2NvbENsYWltcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyUHJvdG9jb2xDbGFpbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgbG9hZFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBnZXQgc3RhbGVTdGF0ZUFnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhbGVTdGF0ZUFnZTtcclxuICAgIH1cclxuICAgIGdldCBjbG9ja1NrZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrU2tldztcclxuICAgIH1cclxuICAgIGdldCB1c2VySW5mb0p3dElzc3VlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHN0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlU3RvcmU7XHJcbiAgICB9XHJcbiAgICBnZXQgdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICBnZXQgZXh0cmFRdWVyeVBhcmFtcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZXh0cmFRdWVyeVBhcmFtcztcclxuICAgIH1cclxuICAgIHNldCBleHRyYVF1ZXJ5UGFyYW1zKHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpe1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVF1ZXJ5UGFyYW1zID0gdmFsdWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHt9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBleHRyYSB0b2tlbiBwYXJhbXNcclxuICAgIGdldCBleHRyYVRva2VuUGFyYW1zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHRyYVRva2VuUGFyYW1zO1xyXG4gICAgfVxyXG4gICAgc2V0IGV4dHJhVG9rZW5QYXJhbXModmFsdWUpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jyl7XHJcbiAgICAgICAgICAgIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXMgPSB2YWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0ge307XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgUG9wdXBXaW5kb3cgfSBmcm9tICcuL1BvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBQb3B1cE5hdmlnYXRvciB7XHJcblxyXG4gICAgcHJlcGFyZShwYXJhbXMpIHtcclxuICAgICAgICBsZXQgcG9wdXAgPSBuZXcgUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwsIGtlZXBPcGVuLCBkZWxpbWl0ZXIpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cE5hdmlnYXRvci5jYWxsYmFja1wiKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgUG9wdXBXaW5kb3cubm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgQ2hlY2tGb3JQb3B1cENsb3NlZEludGVydmFsID0gNTAwO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7JztcclxuLy9jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7cmVzaXphYmxlPXllcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFBvcHVwV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsZXQgdGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBsZXQgZmVhdHVyZXMgPSBwYXJhbXMucG9wdXBXaW5kb3dGZWF0dXJlcyB8fCBEZWZhdWx0UG9wdXBGZWF0dXJlcztcclxuXHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSB3aW5kb3cub3BlbignJywgdGFyZ2V0LCBmZWF0dXJlcyk7XHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmN0b3I6IHBvcHVwIHN1Y2Nlc3NmdWxseSBjcmVhdGVkXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSB3aW5kb3cuc2V0SW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZC5iaW5kKHRoaXMpLCBDaGVja0ZvclBvcHVwQ2xvc2VkSW50ZXJ2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgcHJvbWlzZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICBuYXZpZ2F0ZShwYXJhbXMpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IEVycm9yIG9wZW5pbmcgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IG5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJObyB1cmwgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5uYXZpZ2F0ZTogU2V0dGluZyBVUkwgaW4gcG9wdXBcIik7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9pZCA9IHBhcmFtcy5pZDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lkKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3dbXCJwb3B1cENhbGxiYWNrX1wiICsgcGFyYW1zLmlkXSA9IHRoaXMuX2NhbGxiYWNrLmJpbmQodGhpcyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLndpbmRvdy5sb2NhdGlvbiA9IHBhcmFtcy51cmw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5jYWxsYmFjazogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIHBvcHVwIHdpbmRvd1wiKTtcclxuXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIExvZy5lcnJvcihcIlBvcHVwV2luZG93LmVycm9yOiBcIiwgbWVzc2FnZSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIF9jbGVhbnVwKGtlZXBPcGVuKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUG9wdXBXaW5kb3cuY2xlYW51cFwiKTtcclxuXHJcbiAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZFRpbWVyKTtcclxuICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSBudWxsO1xyXG5cclxuICAgICAgICBkZWxldGUgd2luZG93W1wicG9wdXBDYWxsYmFja19cIiArIHRoaXMuX2lkXTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwICYmICFrZWVwT3Blbikge1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5jbG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9wb3B1cCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgX2NoZWNrRm9yUG9wdXBDbG9zZWQoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9wb3B1cCB8fCB0aGlzLl9wb3B1cC5jbG9zZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJQb3B1cCB3aW5kb3cgY2xvc2VkXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfY2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoa2VlcE9wZW4pO1xyXG5cclxuICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrIHN1Y2Nlc3NcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX3N1Y2Nlc3MoeyB1cmw6IHVybCB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrOiBJbnZhbGlkIHJlc3BvbnNlIGZyb20gcG9wdXBcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiSW52YWxpZCByZXNwb25zZSBmcm9tIHBvcHVwXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgbm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcikge1xyXG4gICAgICAgIGlmICh3aW5kb3cub3BlbmVyKSB7XHJcbiAgICAgICAgICAgIHVybCA9IHVybCB8fCB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWUgPSBcInBvcHVwQ2FsbGJhY2tfXCIgKyBkYXRhLnN0YXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IHdpbmRvdy5vcGVuZXJbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogcGFzc2luZyB1cmwgbWVzc2FnZSB0byBvcGVuZXJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJQb3B1cFdpbmRvdy5ub3RpZnlPcGVuZXI6IG5vIG1hdGNoaW5nIGNhbGxiYWNrIGZvdW5kIG9uIG9wZW5lclwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gc3RhdGUgZm91bmQgaW4gcmVzcG9uc2UgdXJsXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gd2luZG93Lm9wZW5lci4gQ2FuJ3QgY29tcGxldGUgbm90aWZpY2F0aW9uLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlZGlyZWN0TmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKCkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgbmF2aWdhdGUocGFyYW1zKSB7XHJcbiAgICAgICAgaWYgKCFwYXJhbXMgfHwgIXBhcmFtcy51cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVkaXJlY3ROYXZpZ2F0b3IubmF2aWdhdGU6IE5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHVybCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyYW1zLnVzZVJlcGxhY2VUb05hdmlnYXRlKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHBhcmFtcy51cmwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdXJsKCkge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgVXNlckluZm9TZXJ2aWNlIH0gZnJvbSAnLi9Vc2VySW5mb1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBUb2tlbkNsaWVudCB9IGZyb20gJy4vVG9rZW5DbGllbnQuanMnO1xyXG5pbXBvcnQgeyBFcnJvclJlc3BvbnNlIH0gZnJvbSAnLi9FcnJvclJlc3BvbnNlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmNvbnN0IFByb3RvY29sQ2xhaW1zID0gW1wibm9uY2VcIiwgXCJhdF9oYXNoXCIsIFwiaWF0XCIsIFwibmJmXCIsIFwiZXhwXCIsIFwiYXVkXCIsIFwiaXNzXCIsIFwiY19oYXNoXCJdO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlc3BvbnNlVmFsaWRhdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgXHJcbiAgICAgICAgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSxcclxuICAgICAgICBVc2VySW5mb1NlcnZpY2VDdG9yID0gVXNlckluZm9TZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsLFxyXG4gICAgICAgIFRva2VuQ2xpZW50Q3RvciA9IFRva2VuQ2xpZW50KSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWQgdG8gUmVzcG9uc2VWYWxpZGF0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9TZXJ2aWNlID0gbmV3IFVzZXJJbmZvU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICAgICAgdGhpcy5fdG9rZW5DbGllbnQgPSBuZXcgVG9rZW5DbGllbnRDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzU2lnbmluUGFyYW1zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2U6IHN0YXRlIHByb2Nlc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlVG9rZW5zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiB0b2tlbnMgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3NDbGFpbXMoc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiBjbGFpbXMgcHJvY2Vzc2VkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoc3RhdGUuaWQgIT09IHJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbm91dFJlc3BvbnNlOiBTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlN0YXRlIGRvZXMgbm90IG1hdGNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG5vdyB0aGF0IHdlIGtub3cgdGhlIHN0YXRlIG1hdGNoZXMsIHRha2UgdGhlIHN0b3JlZCBkYXRhXHJcbiAgICAgICAgLy8gYW5kIHNldCBpdCBpbnRvIHRoZSByZXNwb25zZSBzbyBjYWxsZXJzIGNhbiBnZXQgdGhlaXIgc3RhdGVcclxuICAgICAgICAvLyB0aGlzIGlzIGltcG9ydGFudCBmb3IgYm90aCBzdWNjZXNzICYgZXJyb3Igb3V0Y29tZXNcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZTogc3RhdGUgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgIHJlc3BvbnNlLnN0YXRlID0gc3RhdGUuZGF0YTtcclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmVycm9yKSB7XHJcbiAgICAgICAgICAgIExvZy53YXJuKFwiUmVzcG9uc2VWYWxpZGF0b3IudmFsaWRhdGVTaWdub3V0UmVzcG9uc2U6IFJlc3BvbnNlIHdhcyBlcnJvclwiLCByZXNwb25zZS5lcnJvcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3JSZXNwb25zZShyZXNwb25zZSkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NTaWduaW5QYXJhbXMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHN0YXRlLmlkICE9PSByZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogU3RhdGUgZG9lcyBub3QgbWF0Y2hcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuYXV0aG9yaXR5KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBObyBhdXRob3JpdHkgb24gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb24gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gdGhpcyBhbGxvd3MgdGhlIGF1dGhvcml0eSB0byBiZSBsb2FkZWQgZnJvbSB0aGUgc2lnbmluIHN0YXRlXHJcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MuYXV0aG9yaXR5ID0gc3RhdGUuYXV0aG9yaXR5O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBlbnN1cmUgd2UncmUgdXNpbmcgdGhlIGNvcnJlY3QgYXV0aG9yaXR5IGlmIHRoZSBhdXRob3JpdHkgaXMgbm90IGxvYWRlZCBmcm9tIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eSAmJiB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkgIT09IHN0YXRlLmF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogYXV0aG9yaXR5IG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJhdXRob3JpdHkgbWlzbWF0Y2ggb24gc2V0dGluZ3MgdnMuIHNpZ25pbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRoaXMgYWxsb3dzIHRoZSBjbGllbnRfaWQgdG8gYmUgbG9hZGVkIGZyb20gdGhlIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZCA9IHN0YXRlLmNsaWVudF9pZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZW5zdXJlIHdlJ3JlIHVzaW5nIHRoZSBjb3JyZWN0IGNsaWVudF9pZCBpZiB0aGUgY2xpZW50X2lkIGlzIG5vdCBsb2FkZWQgZnJvbSBzaWduaW4gc3RhdGVcclxuICAgICAgICBlbHNlIGlmICh0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQgJiYgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkICE9PSBzdGF0ZS5jbGllbnRfaWQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NTaWduaW5QYXJhbXM6IGNsaWVudF9pZCBtaXNtYXRjaCBvbiBzZXR0aW5ncyB2cy4gc2lnbmluIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiY2xpZW50X2lkIG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gbm93IHRoYXQgd2Uga25vdyB0aGUgc3RhdGUgbWF0Y2hlcywgdGFrZSB0aGUgc3RvcmVkIGRhdGFcclxuICAgICAgICAvLyBhbmQgc2V0IGl0IGludG8gdGhlIHJlc3BvbnNlIHNvIGNhbGxlcnMgY2FuIGdldCB0aGVpciBzdGF0ZVxyXG4gICAgICAgIC8vIHRoaXMgaXMgaW1wb3J0YW50IGZvciBib3RoIHN1Y2Nlc3MgJiBlcnJvciBvdXRjb21lc1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBzdGF0ZSB2YWxpZGF0ZWRcIik7XHJcbiAgICAgICAgcmVzcG9uc2Uuc3RhdGUgPSBzdGF0ZS5kYXRhO1xyXG5cclxuICAgICAgICBpZiAocmVzcG9uc2UuZXJyb3IpIHtcclxuICAgICAgICAgICAgTG9nLndhcm4oXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogUmVzcG9uc2Ugd2FzIGVycm9yXCIsIHJlc3BvbnNlLmVycm9yKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUubm9uY2UgJiYgIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBFeHBlY3RpbmcgaWRfdG9rZW4gaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLm5vbmNlICYmIHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGlkX3Rva2VuIGluIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5leHBlY3RlZCBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUuY29kZV92ZXJpZmllciAmJiAhcmVzcG9uc2UuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogRXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBjb2RlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuY29kZV92ZXJpZmllciAmJiByZXNwb25zZS5jb2RlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGNvZGUgaW4gcmVzcG9uc2VcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zY29wZSkge1xyXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSdzIG5vIHNjb3BlIG9uIHRoZSByZXNwb25zZSwgdGhlbiBhc3N1bWUgYWxsIHNjb3BlcyBncmFudGVkIChwZXItc3BlYykgYW5kIGNvcHkgb3ZlciBzY29wZXMgZnJvbSBvcmlnaW5hbCByZXF1ZXN0XHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnNjb3BlID0gc3RhdGUuc2NvcGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcHJvY2Vzc0NsYWltcyhzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAocmVzcG9uc2UuaXNPcGVuSWRDb25uZWN0KSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiByZXNwb25zZSBpcyBPSURDLCBwcm9jZXNzaW5nIGNsYWltc1wiKTtcclxuXHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnByb2ZpbGUgPSB0aGlzLl9maWx0ZXJQcm90b2NvbENsYWltcyhyZXNwb25zZS5wcm9maWxlKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5za2lwVXNlckluZm8gIT09IHRydWUgJiYgdGhpcy5fc2V0dGluZ3MubG9hZFVzZXJJbmZvICYmIHJlc3BvbnNlLmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IGxvYWRpbmcgdXNlciBpbmZvXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zKHJlc3BvbnNlLmFjY2Vzc190b2tlbikudGhlbihjbGFpbXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiB1c2VyIGluZm8gY2xhaW1zIHJlY2VpdmVkIGZyb20gdXNlciBpbmZvIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xhaW1zLnN1YiAhPT0gcmVzcG9uc2UucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHN1YiBmcm9tIHVzZXIgaW5mbyBlbmRwb2ludCBkb2VzIG5vdCBtYXRjaCBzdWIgaW4gYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic3ViIGZyb20gdXNlciBpbmZvIGVuZHBvaW50IGRvZXMgbm90IG1hdGNoIHN1YiBpbiBhY2Nlc3NfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UucHJvZmlsZSA9IHRoaXMuX21lcmdlQ2xhaW1zKHJlc3BvbnNlLnByb2ZpbGUsIGNsYWltcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHVzZXIgaW5mbyBjbGFpbXMgcmVjZWl2ZWQsIHVwZGF0ZWQgcHJvZmlsZTpcIiwgcmVzcG9uc2UucHJvZmlsZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IG5vdCBsb2FkaW5nIHVzZXIgaW5mb1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHJlc3BvbnNlIGlzIG5vdCBPSURDLCBub3QgcHJvY2Vzc2luZyBjbGFpbXNcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfbWVyZ2VDbGFpbXMoY2xhaW1zMSwgY2xhaW1zMikge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSBPYmplY3QuYXNzaWduKHt9LCBjbGFpbXMxKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBjbGFpbXMyKSB7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBjbGFpbXMyW25hbWVdO1xyXG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzID0gW3ZhbHVlc107XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSB2YWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdFtuYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRbbmFtZV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtuYW1lXS5pbmRleE9mKHZhbHVlKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W25hbWVdLnB1c2godmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdFtuYW1lXSAhPT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSB0aGlzLl9tZXJnZUNsYWltcyhyZXN1bHRbbmFtZV0sIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSBbcmVzdWx0W25hbWVdLCB2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIF9maWx0ZXJQcm90b2NvbENsYWltcyhjbGFpbXMpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyUHJvdG9jb2xDbGFpbXMsIGluY29taW5nIGNsYWltczpcIiwgY2xhaW1zKTtcclxuXHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oe30sIGNsYWltcyk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5fZmlsdGVyUHJvdG9jb2xDbGFpbXMpIHtcclxuICAgICAgICAgICAgUHJvdG9jb2xDbGFpbXMuZm9yRWFjaCh0eXBlID0+IHtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRbdHlwZV07XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlclByb3RvY29sQ2xhaW1zOiBwcm90b2NvbCBjbGFpbXMgZmlsdGVyZWRcIiwgcmVzdWx0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJQcm90b2NvbENsYWltczogcHJvdG9jb2wgY2xhaW1zIG5vdCBmaWx0ZXJlZFwiKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBfdmFsaWRhdGVUb2tlbnMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmNvZGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBWYWxpZGF0aW5nIGNvZGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzQ29kZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5hY2Nlc3NfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlbiBhbmQgYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbihzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBObyBjb2RlIHRvIHByb2Nlc3Mgb3IgaWRfdG9rZW4gdG8gdmFsaWRhdGVcIik7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NDb2RlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHZhciByZXF1ZXN0ID0ge1xyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHN0YXRlLmNsaWVudF9pZCxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldDogc3RhdGUuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgY29kZSA6IHJlc3BvbnNlLmNvZGUsXHJcbiAgICAgICAgICAgIHJlZGlyZWN0X3VyaTogc3RhdGUucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBjb2RlX3ZlcmlmaWVyOiBzdGF0ZS5jb2RlX3ZlcmlmaWVyXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMgJiYgdHlwZW9mKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHJlcXVlc3QsIHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5DbGllbnQuZXhjaGFuZ2VDb2RlKHJlcXVlc3QpLnRoZW4odG9rZW5SZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBmb3IodmFyIGtleSBpbiB0b2tlblJlc3BvbnNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gdG9rZW5SZXNwb25zZVtrZXldO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuaWRfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ29kZTogdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc2Z1bCwgcHJvY2Vzc2luZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc0NvZGU6IHRva2VuIHJlc3BvbnNlIHN1Y2Nlc3NmdWwsIHJldHVybmluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCkudGhlbihpc3N1ZXIgPT4ge1xyXG5cclxuICAgICAgICAgICAgbGV0IGF1ZGllbmNlID0gc3RhdGUuY2xpZW50X2lkO1xyXG4gICAgICAgICAgICBsZXQgY2xvY2tTa2V3SW5TZWNvbmRzID0gdGhpcy5fc2V0dGluZ3MuY2xvY2tTa2V3O1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogVmFsaWRhaW5nIEpXVCBhdHRyaWJ1dGVzOyB1c2luZyBjbG9jayBza2V3IChpbiBzZWNvbmRzKSBvZjogXCIsIGNsb2NrU2tld0luU2Vjb25kcyk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3RBdHRyaWJ1dGVzKHJlc3BvbnNlLmlkX3Rva2VuLCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXdJblNlY29uZHMpLnRoZW4ocGF5bG9hZCA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLm5vbmNlICYmIHN0YXRlLm5vbmNlICE9PSBwYXlsb2FkLm5vbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbkF0dHJpYnV0ZXM6IEludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN1YiBwcmVzZW50IGluIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gcGF5bG9hZDtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKCFzdGF0ZS5ub25jZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBub25jZSBvbiBzdGF0ZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIG5vbmNlIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzdGF0ZS5ub25jZSAhPT0gand0LnBheWxvYWQubm9uY2UpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSW52YWxpZCBub25jZSBpbiBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGtpZCA9IGp3dC5oZWFkZXIua2lkO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogUmVjZWl2ZWQgaXNzdWVyXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5cygpLnRoZW4oa2V5cyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gc2lnbmluZyBrZXlzIGZyb20gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFJlY2VpdmVkIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleXMgPSB0aGlzLl9maWx0ZXJCeUFsZyhrZXlzLCBqd3QuaGVhZGVyLmFsZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGtpZCBmb3VuZCBpbiBpZF90b2tlbiBhbmQgbW9yZSB0aGFuIG9uZSBrZXkgZm91bmQgaW4gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8ga2lkIGlzIG1hbmRhdG9yeSBvbmx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIGtleXMgaW4gdGhlIHJlZmVyZW5jZWQgSldLIFNldCBkb2N1bWVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cDovL29wZW5pZC5uZXQvc3BlY3Mvb3BlbmlkLWNvbm5lY3QtY29yZS0xXzAuaHRtbCNTaWduaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5cy5maWx0ZXIoa2V5ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5raWQgPT09IGtpZDtcclxuICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IE5vIGtleSBtYXRjaGluZyBraWQgb3IgYWxnIGZvdW5kIGluIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgYXVkaWVuY2UgPSBzdGF0ZS5jbGllbnRfaWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3QocmVzcG9uc2UuaWRfdG9rZW4sIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzKS50aGVuKCgpPT57XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSldUIHZhbGlkYXRpb24gc3VjY2Vzc2Z1bFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqd3QucGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzdWIgcHJlc2VudCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gand0LnBheWxvYWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKXtcclxuICAgICAgICB2YXIga3R5ID0gbnVsbDtcclxuICAgICAgICBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJSU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlJTQVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChhbGcuc3RhcnRzV2l0aChcIlBTXCIpKSB7XHJcbiAgICAgICAgICAgIGt0eSA9IFwiUFNcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJFU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIkVDXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyQnlBbGc6IGFsZyBub3Qgc3VwcG9ydGVkOiBcIiwgYWxnKTtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJCeUFsZzogTnVtYmVyIG9mIGtleXMgdGhhdCBtYXRjaCBrdHk6IFwiLCBrdHksIGtleXMubGVuZ3RoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGtleXM7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnByb2ZpbGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IE5vIHByb2ZpbGUgbG9hZGVkIGZyb20gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBwcm9maWxlIGxvYWRlZCBmcm9tIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBhdF9oYXNoIGluIGlkX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gYXRfaGFzaCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQWxnID0gand0LmhlYWRlci5hbGc7XHJcbiAgICAgICAgaWYgKCFoYXNoQWxnIHx8IGhhc2hBbGcubGVuZ3RoICE9PSA1KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBVbnN1cHBvcnRlZCBhbGc6XCIsIGhhc2hBbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQml0cyA9IGhhc2hBbGcuc3Vic3RyKDIsIDMpO1xyXG4gICAgICAgIGlmICghaGFzaEJpdHMpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IFVuc3VwcG9ydGVkIGFsZzpcIiwgaGFzaEFsZywgaGFzaEJpdHMpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGhhc2hCaXRzID0gcGFyc2VJbnQoaGFzaEJpdHMpO1xyXG4gICAgICAgIGlmIChoYXNoQml0cyAhPT0gMjU2ICYmIGhhc2hCaXRzICE9PSAzODQgJiYgaGFzaEJpdHMgIT09IDUxMikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogVW5zdXBwb3J0ZWQgYWxnOlwiLCBoYXNoQWxnLCBoYXNoQml0cyk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBhbGc6IFwiICsgaGFzaEFsZykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHNoYSA9IFwic2hhXCIgKyBoYXNoQml0cztcclxuICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2pvc2VVdGlsLmhhc2hTdHJpbmcocmVzcG9uc2UuYWNjZXNzX3Rva2VuLCBzaGEpO1xyXG4gICAgICAgIGlmICghaGFzaCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogYWNjZXNzX3Rva2VuIGhhc2ggZmFpbGVkOlwiLCBzaGEpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGF0X2hhc2hcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGxlZnQgPSBoYXNoLnN1YnN0cigwLCBoYXNoLmxlbmd0aCAvIDIpO1xyXG4gICAgICAgIHZhciBsZWZ0X2I2NHUgPSB0aGlzLl9qb3NlVXRpbC5oZXhUb0Jhc2U2NFVybChsZWZ0KTtcclxuICAgICAgICBpZiAobGVmdF9iNjR1ICE9PSByZXNwb25zZS5wcm9maWxlLmF0X2hhc2gpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIsIGxlZnRfYjY0dSwgcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBzdWNjZXNzXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IENoZWNrU2Vzc2lvbklGcmFtZSB9IGZyb20gJy4vQ2hlY2tTZXNzaW9uSUZyYW1lLmpzJztcclxuaW1wb3J0IHsgR2xvYmFsIH0gZnJvbSAnLi9HbG9iYWwuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNlc3Npb25Nb25pdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih1c2VyTWFuYWdlciwgQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvciA9IENoZWNrU2Vzc2lvbklGcmFtZSwgdGltZXIgPSBHbG9iYWwudGltZXIpIHtcclxuICAgICAgICBpZiAoIXVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLmN0b3I6IE5vIHVzZXIgbWFuYWdlciBwYXNzZWQgdG8gU2Vzc2lvbk1vbml0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVzZXJNYW5hZ2VyXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgICAgICB0aGlzLl9DaGVja1Nlc3Npb25JRnJhbWVDdG9yID0gQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvcjtcclxuICAgICAgICB0aGlzLl90aW1lciA9IHRpbWVyO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlckxvYWRlZCh0aGlzLl9zdGFydC5iaW5kKHRoaXMpKTtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlclVubG9hZGVkKHRoaXMuX3N0b3AuYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICAvLyBkb2luZyB0aGlzIG1hbnVhbGx5IGhlcmUgc2luY2UgY2FsbGluZyBnZXRVc2VyIFxyXG4gICAgICAgICAgICAvLyBkb2Vzbid0IHRyaWdnZXIgbG9hZCBldmVudC5cclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHVzZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLm1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXMoKS50aGVuKHNlc3Npb24gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0bXBVc2VyID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uX3N0YXRlIDogc2Vzc2lvbi5zZXNzaW9uX3N0YXRlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgJiYgc2Vzc2lvbi5zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG1wVXNlci5wcm9maWxlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViOiBzZXNzaW9uLnN1YixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2Vzc2lvbi5zaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodG1wVXNlcik7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yIGN0b3I6IGVycm9yIGZyb20gcXVlcnlTZXNzaW9uU3RhdHVzOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBhIGN0b3JcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2Vzc2lvbk1vbml0b3IgY3RvcjogZXJyb3IgZnJvbSBnZXRVc2VyOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IF9zZXR0aW5ncygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIuc2V0dGluZ3M7XHJcbiAgICB9XHJcbiAgICBnZXQgX21ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIubWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9jbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCBfY2hlY2tTZXNzaW9uSW50ZXJ2YWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9zdG9wQ2hlY2tTZXNzaW9uT25FcnJvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3Muc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgX3N0YXJ0KHVzZXIpIHtcclxuICAgICAgICBsZXQgc2Vzc2lvbl9zdGF0ZSA9IHVzZXIuc2Vzc2lvbl9zdGF0ZTtcclxuXHJcbiAgICAgICAgaWYgKHNlc3Npb25fc3RhdGUpIHtcclxuICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3ViID0gdXNlci5wcm9maWxlLnN1YjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NpZCA9IHVzZXIucHJvZmlsZS5zaWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBzdWI6XCIsIHRoaXMuX3N1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWIgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBhbm9ueW1vdXMgdXNlclwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRDaGVja1Nlc3Npb25JZnJhbWUoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IEluaXRpYWxpemluZyBjaGVjayBzZXNzaW9uIGlmcmFtZVwiKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX2NsaWVudF9pZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGludGVydmFsID0gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdG9wT25FcnJvciA9IHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lID0gbmV3IHRoaXMuX0NoZWNrU2Vzc2lvbklGcmFtZUN0b3IodGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKSwgY2xpZW50X2lkLCB1cmwsIGludGVydmFsLCBzdG9wT25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5sb2FkKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IE5vIGNoZWNrIHNlc3Npb24gaWZyYW1lIGZvdW5kIGluIHRoZSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBub24tcHJvbWlzZSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLl9zdGFydDogRXJyb3IgZnJvbSBnZXRDaGVja1Nlc3Npb25JZnJhbWU6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lLnN0YXJ0KHNlc3Npb25fc3RhdGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9zdG9wKCkge1xyXG4gICAgICAgIHRoaXMuX3N1YiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX3N0b3BcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5zdG9wKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fc2V0dGluZ3MubW9uaXRvckFub255bW91c1Nlc3Npb24pIHtcclxuICAgICAgICAgICAgLy8gdXNpbmcgYSB0aW1lciB0byBkZWxheSByZS1pbml0aWFsaXphdGlvbiB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnMgZHVyaW5nIHNpZ25vdXRcclxuICAgICAgICAgICAgbGV0IHRpbWVySGFuZGxlID0gdGhpcy5fdGltZXIuc2V0SW50ZXJ2YWwoKCk9PntcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGltZXJIYW5kbGUpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRtcFVzZXIgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGUgOiBzZXNzaW9uLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uLnN1YiAmJiBzZXNzaW9uLnNpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0bXBVc2VyLnByb2ZpbGUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWI6IHNlc3Npb24uc3ViLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lkOiBzZXNzaW9uLnNpZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0bXBVc2VyKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjYXRjaCB0byBzdXBwcmVzcyBlcnJvcnMgc2luY2Ugd2UncmUgaW4gYSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yOiBlcnJvciBmcm9tIHF1ZXJ5U2Vzc2lvblN0YXR1czpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB9LCAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgX2NhbGxiYWNrKCkge1xyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgIHZhciByYWlzZUV2ZW50ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgPT09IHRoaXMuX3N1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJhaXNlRXZlbnQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24uc2lkID09PSB0aGlzLl9zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTYW1lIHN1YiBzdGlsbCBsb2dnZWQgaW4gYXQgT1AsIHJlc3RhcnRpbmcgY2hlY2sgc2Vzc2lvbiBpZnJhbWU7IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb24uc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s6IFNhbWUgc3ViIHN0aWxsIGxvZ2dlZCBpbiBhdCBPUCwgc2Vzc2lvbiBzdGF0ZSBoYXMgY2hhbmdlZCwgcmVzdGFydGluZyBjaGVjayBzZXNzaW9uIGlmcmFtZTsgc2Vzc2lvbl9zdGF0ZTpcIiwgc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTZXNzaW9uQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRGlmZmVyZW50IHN1YmplY3Qgc2lnbmVkIGludG8gT1A6XCIsIHNlc3Npb24uc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogU3ViamVjdCBubyBsb25nZXIgc2lnbmVkIGludG8gT1BcIik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIG91dCBldmVudFwiKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlVXNlclNpZ25lZE91dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIGluIGV2ZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkSW4oKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdWIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRXJyb3IgY2FsbGluZyBxdWVyeUN1cnJlbnRTaWduaW5TZXNzaW9uOyByYWlzaW5nIHNpZ25lZCBvdXQgZXZlbnRcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTaWduZWRPdXQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluUmVxdWVzdCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWFuZGF0b3J5XHJcbiAgICAgICAgdXJsLCBjbGllbnRfaWQsIHJlZGlyZWN0X3VyaSwgcmVzcG9uc2VfdHlwZSwgc2NvcGUsIGF1dGhvcml0eSxcclxuICAgICAgICAvLyBvcHRpb25hbFxyXG4gICAgICAgIGRhdGEsIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgcmVxdWVzdCwgcmVxdWVzdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSwgY2xpZW50X3NlY3JldCwgZXh0cmFUb2tlblBhcmFtcywgc2tpcFVzZXJJbmZvXHJcbiAgICB9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlZGlyZWN0X3VyaVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gcmVzcG9uc2VfdHlwZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlc3BvbnNlX3R5cGVcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghc2NvcGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyBzY29wZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNjb3BlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIGF1dGhvcml0eSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eVwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBvaWRjID0gU2lnbmluUmVxdWVzdC5pc09pZGMocmVzcG9uc2VfdHlwZSk7XHJcbiAgICAgICAgbGV0IGNvZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV9tb2RlKSB7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlX21vZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKSA/IFwicXVlcnlcIiA6IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFNpZ25pblN0YXRlKHsgbm9uY2U6IG9pZGMsIFxyXG4gICAgICAgICAgICBkYXRhLCBjbGllbnRfaWQsIGF1dGhvcml0eSwgcmVkaXJlY3RfdXJpLCBcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogY29kZSwgXHJcbiAgICAgICAgICAgIHJlcXVlc3RfdHlwZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldCwgc2NvcGUsIGV4dHJhVG9rZW5QYXJhbXMsIHNraXBVc2VySW5mbyB9KTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJjbGllbnRfaWRcIiwgY2xpZW50X2lkKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInJlZGlyZWN0X3VyaVwiLCByZWRpcmVjdF91cmkpO1xyXG4gICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIFwicmVzcG9uc2VfdHlwZVwiLCByZXNwb25zZV90eXBlKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInNjb3BlXCIsIHNjb3BlKTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICBpZiAob2lkYykge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcIm5vbmNlXCIsIHRoaXMuc3RhdGUubm9uY2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29kZSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlXCIsIHRoaXMuc3RhdGUuY29kZV9jaGFsbGVuZ2UpO1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlX21ldGhvZFwiLCBcIlMyNTZcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgb3B0aW9uYWwgPSB7IHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlcXVlc3QsIHJlcXVlc3RfdXJpLCByZXNwb25zZV9tb2RlIH07XHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gb3B0aW9uYWwpe1xyXG4gICAgICAgICAgICBpZiAob3B0aW9uYWxba2V5XSkge1xyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwga2V5LCBvcHRpb25hbFtrZXldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGlzT2lkYyhyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiaWRfdG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgaXNPQXV0aChyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwidG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgc3RhdGljIGlzQ29kZShyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiY29kZVwiO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiAhIShyZXN1bHRbMF0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgT2lkY1Njb3BlID0gXCJvcGVuaWRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWduaW5SZXNwb25zZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih1cmwsIGRlbGltaXRlciA9IFwiI1wiKSB7XHJcblxyXG4gICAgICAgIHZhciB2YWx1ZXMgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLmNvZGUgPSB2YWx1ZXMuY29kZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgICAgIHRoaXMuaWRfdG9rZW4gPSB2YWx1ZXMuaWRfdG9rZW47XHJcbiAgICAgICAgdGhpcy5zZXNzaW9uX3N0YXRlID0gdmFsdWVzLnNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSB2YWx1ZXMuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgIHRoaXMudG9rZW5fdHlwZSA9IHZhbHVlcy50b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSB2YWx1ZXMuc2NvcGU7XHJcbiAgICAgICAgdGhpcy5wcm9maWxlID0gdW5kZWZpbmVkOyAvLyB3aWxsIGJlIHNldCBmcm9tIFJlc3BvbnNlVmFsaWRhdG9yXHJcblxyXG4gICAgICAgIHRoaXMuZXhwaXJlc19pbiA9IHZhbHVlcy5leHBpcmVzX2luO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKXtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHBhcnNlSW50KHZhbHVlKTtcclxuICAgICAgICBpZiAodHlwZW9mIGV4cGlyZXNfaW4gPT09ICdudW1iZXInICYmIGV4cGlyZXNfaW4gPiAwKSB7XHJcbiAgICAgICAgICAgIGxldCBub3cgPSBwYXJzZUludChEYXRlLm5vdygpIC8gMTAwMCk7XHJcbiAgICAgICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IG5vdyArIGV4cGlyZXNfaW47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVkKCkge1xyXG4gICAgICAgIGxldCBleHBpcmVzX2luID0gdGhpcy5leHBpcmVzX2luO1xyXG4gICAgICAgIGlmIChleHBpcmVzX2luICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4cGlyZXNfaW4gPD0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2NvcGVzKCkge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5zY29wZSB8fCBcIlwiKS5zcGxpdChcIiBcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGlzT3BlbklkQ29ubmVjdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zY29wZXMuaW5kZXhPZihPaWRjU2NvcGUpID49IDAgfHwgISF0aGlzLmlkX3Rva2VuO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuL1N0YXRlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluU3RhdGUgZXh0ZW5kcyBTdGF0ZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7bm9uY2UsIGF1dGhvcml0eSwgY2xpZW50X2lkLCByZWRpcmVjdF91cmksIGNvZGVfdmVyaWZpZXIsIHJlc3BvbnNlX21vZGUsIGNsaWVudF9zZWNyZXQsIHNjb3BlLCBleHRyYVRva2VuUGFyYW1zLCBza2lwVXNlckluZm99ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICBpZiAobm9uY2UgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSByYW5kb20oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAobm9uY2UpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSBub25jZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjb2RlX3ZlcmlmaWVyID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIC8vIHJhbmRvbSgpIHByb2R1Y2VzIDMyIGxlbmd0aFxyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX3ZlcmlmaWVyID0gcmFuZG9tKCkgKyByYW5kb20oKSArIHJhbmRvbSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChjb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvZGVfdmVyaWZpZXIgPSBjb2RlX3ZlcmlmaWVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAodGhpcy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIGxldCBoYXNoID0gSm9zZVV0aWwuaGFzaFN0cmluZyh0aGlzLmNvZGVfdmVyaWZpZXIsIFwiU0hBMjU2XCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX2NoYWxsZW5nZSA9IEpvc2VVdGlsLmhleFRvQmFzZTY0VXJsKGhhc2gpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSBjbGllbnRfaWQ7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X3NlY3JldCA9IGNsaWVudF9zZWNyZXQ7XHJcbiAgICAgICAgdGhpcy5fc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gZXh0cmFUb2tlblBhcmFtcztcclxuICAgICAgICB0aGlzLl9za2lwVXNlckluZm8gPSBza2lwVXNlckluZm87XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG5vbmNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub25jZTtcclxuICAgIH1cclxuICAgIGdldCBhdXRob3JpdHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dGhvcml0eTtcclxuICAgIH1cclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCByZWRpcmVjdF91cmkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZGlyZWN0X3VyaTtcclxuICAgIH1cclxuICAgIGdldCBjb2RlX3ZlcmlmaWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX3ZlcmlmaWVyO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNvZGVfY2hhbGxlbmdlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX2NoYWxsZW5nZTtcclxuICAgIH1cclxuICAgIGdldCByZXNwb25zZV9tb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNwb25zZV9tb2RlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgc2NvcGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Njb3BlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGV4dHJhVG9rZW5QYXJhbXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgc2tpcFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9za2lwVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJTaWduaW5TdGF0ZS50b1N0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgICAgICAgaWQ6IHRoaXMuaWQsXHJcbiAgICAgICAgICAgIGRhdGE6IHRoaXMuZGF0YSxcclxuICAgICAgICAgICAgY3JlYXRlZDogdGhpcy5jcmVhdGVkLFxyXG4gICAgICAgICAgICByZXF1ZXN0X3R5cGU6IHRoaXMucmVxdWVzdF90eXBlLFxyXG4gICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogdGhpcy5jb2RlX3ZlcmlmaWVyLFxyXG4gICAgICAgICAgICByZWRpcmVjdF91cmk6IHRoaXMucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBhdXRob3JpdHk6IHRoaXMuYXV0aG9yaXR5LFxyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY2xpZW50X2lkLFxyXG4gICAgICAgICAgICByZXNwb25zZV9tb2RlOiB0aGlzLnJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgICAgIGNsaWVudF9zZWNyZXQ6IHRoaXMuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgOiB0aGlzLmV4dHJhVG9rZW5QYXJhbXMsXHJcbiAgICAgICAgICAgIHNraXBVc2VySW5mbzogdGhpcy5za2lwVXNlckluZm9cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmFnZVN0cmluZykge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlNpZ25pblN0YXRlLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHZhciBkYXRhID0gSlNPTi5wYXJzZShzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICByZXR1cm4gbmV3IFNpZ25pblN0YXRlKGRhdGEpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlcXVlc3Qge1xyXG4gICAgY29uc3RydWN0b3Ioe3VybCwgaWRfdG9rZW5faGludCwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLCBkYXRhLCBleHRyYVF1ZXJ5UGFyYW1zLCByZXF1ZXN0X3R5cGV9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbm91dFJlcXVlc3QuY3RvcjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGlkX3Rva2VuX2hpbnQpIHtcclxuICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJpZF90b2tlbl9oaW50XCIsIGlkX3Rva2VuX2hpbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaVwiLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBuZXcgU3RhdGUoeyBkYXRhLCByZXF1ZXN0X3R5cGUgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlc3BvbnNlIHtcclxuICAgIGNvbnN0cnVjdG9yKHVybCkge1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVzID0gVXJsVXRpbGl0eS5wYXJzZVVybEZyYWdtZW50KHVybCwgXCI/XCIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWxlbnRSZW5ld1NlcnZpY2Uge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgIH1cclxuXHJcbiAgICBzdGFydCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrID0gdGhpcy5fdG9rZW5FeHBpcmluZy5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkQWNjZXNzVG9rZW5FeHBpcmluZyh0aGlzLl9jYWxsYmFjayk7XHJcblxyXG4gICAgICAgICAgICAvLyB0aGlzIHdpbGwgdHJpZ2dlciBsb2FkaW5nIG9mIHRoZSB1c2VyIHNvIHRoZSBleHBpcmluZyBldmVudHMgY2FuIGJlIGluaXRpYWxpemVkXHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXI9PntcclxuICAgICAgICAgICAgICAgIC8vIGRlbGliZXJhdGUgbm9wXHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVycj0+e1xyXG4gICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLnN0YXJ0OiBFcnJvciBmcm9tIGdldFVzZXI6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0b3AoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5yZW1vdmVBY2Nlc3NUb2tlbkV4cGlyaW5nKHRoaXMuX2NhbGxiYWNrKTtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdG9rZW5FeHBpcmluZygpIHtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5zaWduaW5TaWxlbnQoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTaWxlbnRSZW5ld1NlcnZpY2UuX3Rva2VuRXhwaXJpbmc6IFNpbGVudCB0b2tlbiByZW5ld2FsIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgfSwgZXJyID0+IHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLl90b2tlbkV4cGlyaW5nOiBFcnJvciBmcm9tIHNpZ25pblNpbGVudDpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlcnIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU3RhdGUge1xyXG4gICAgY29uc3RydWN0b3Ioe2lkLCBkYXRhLCBjcmVhdGVkLCByZXF1ZXN0X3R5cGV9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9pZCA9IGlkIHx8IHJhbmRvbSgpO1xyXG4gICAgICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xyXG5cclxuICAgICAgICBpZiAodHlwZW9mIGNyZWF0ZWQgPT09ICdudW1iZXInICYmIGNyZWF0ZWQgPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZWQgPSBjcmVhdGVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fY3JlYXRlZCA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdF90eXBlID0gIHJlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lkO1xyXG4gICAgfVxyXG4gICAgZ2V0IGRhdGEoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XHJcbiAgICB9XHJcbiAgICBnZXQgY3JlYXRlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlZDtcclxuICAgIH1cclxuICAgIGdldCByZXF1ZXN0X3R5cGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICB0b1N0b3JhZ2VTdHJpbmcoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUudG9TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxyXG4gICAgICAgICAgICBkYXRhOiB0aGlzLmRhdGEsXHJcbiAgICAgICAgICAgIGNyZWF0ZWQ6IHRoaXMuY3JlYXRlZCxcclxuICAgICAgICAgICAgcmVxdWVzdF90eXBlOiB0aGlzLnJlcXVlc3RfdHlwZVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBmcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBTdGF0ZShKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgY2xlYXJTdGFsZVN0YXRlKHN0b3JhZ2UsIGFnZSkge1xyXG5cclxuICAgICAgICB2YXIgY3V0b2ZmID0gRGF0ZS5ub3coKSAvIDEwMDAgLSBhZ2U7XHJcblxyXG4gICAgICAgIHJldHVybiBzdG9yYWdlLmdldEFsbEtleXMoKS50aGVuKGtleXMgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IGdvdCBrZXlzXCIsIGtleXMpO1xyXG5cclxuICAgICAgICAgICAgdmFyIHByb21pc2VzID0gW107XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGtleSA9IGtleXNbaV07XHJcbiAgICAgICAgICAgICAgICB2YXIgcCA9IHN0b3JhZ2UuZ2V0KGtleSkudGhlbihpdGVtID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVtb3ZlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBTdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhpdGVtKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogZ290IGl0ZW0gZnJvbSBrZXk6IFwiLCBrZXksIHN0YXRlLmNyZWF0ZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5jcmVhdGVkIDw9IGN1dG9mZikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogRXJyb3IgcGFyc2luZyBzdGF0ZSBmb3Iga2V5XCIsIGtleSwgZS5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogbm8gaXRlbSBpbiBzdG9yYWdlIGZvciBrZXk6IFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IHJlbW92ZWQgaXRlbSBmb3Iga2V5OiBcIiwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0b3JhZ2UucmVtb3ZlKGtleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChwKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuY2xlYXJTdGFsZVN0YXRlOiB3YWl0aW5nIG9uIHByb21pc2UgY291bnQ6XCIsIHByb21pc2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5jb25zdCBUaW1lckR1cmF0aW9uID0gNTsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIFRpbWVyIGV4dGVuZHMgRXZlbnQge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKG5hbWUsIHRpbWVyID0gR2xvYmFsLnRpbWVyLCBub3dGdW5jID0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc3VwZXIobmFtZSk7XHJcbiAgICAgICAgdGhpcy5fdGltZXIgPSB0aW1lcjtcclxuXHJcbiAgICAgICAgaWYgKG5vd0Z1bmMpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm93RnVuYyA9IG5vd0Z1bmM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9ub3dGdW5jID0gKCkgPT4gRGF0ZS5ub3coKSAvIDEwMDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBub3coKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuX25vd0Z1bmMoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdChkdXJhdGlvbikge1xyXG4gICAgICAgIGlmIChkdXJhdGlvbiA8PSAwKSB7XHJcbiAgICAgICAgICAgIGR1cmF0aW9uID0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZHVyYXRpb24gPSBwYXJzZUludChkdXJhdGlvbik7XHJcblxyXG4gICAgICAgIHZhciBleHBpcmF0aW9uID0gdGhpcy5ub3cgKyBkdXJhdGlvbjtcclxuICAgICAgICBpZiAodGhpcy5leHBpcmF0aW9uID09PSBleHBpcmF0aW9uICYmIHRoaXMuX3RpbWVySGFuZGxlKSB7XHJcbiAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gcmVpbml0aWFsaXplIHRvIHNhbWUgZXhwaXJhdGlvbiwgc28gYmFpbCBvdXRcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuaW5pdCB0aW1lciBcIiArIHRoaXMuX25hbWUgKyBcIiBza2lwcGluZyBpbml0aWFsaXphdGlvbiBzaW5jZSBhbHJlYWR5IGluaXRpYWxpemVkIGZvciBleHBpcmF0aW9uOlwiLCB0aGlzLmV4cGlyYXRpb24pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmNhbmNlbCgpO1xyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5pbml0IHRpbWVyIFwiICsgdGhpcy5fbmFtZSArIFwiIGZvciBkdXJhdGlvbjpcIiwgZHVyYXRpb24pO1xyXG4gICAgICAgIHRoaXMuX2V4cGlyYXRpb24gPSBleHBpcmF0aW9uO1xyXG5cclxuICAgICAgICAvLyB3ZSdyZSB1c2luZyBhIGZhaXJseSBzaG9ydCB0aW1lciBhbmQgdGhlbiBjaGVja2luZyB0aGUgZXhwaXJhdGlvbiBpbiB0aGVcclxuICAgICAgICAvLyBjYWxsYmFjayB0byBoYW5kbGUgc2NlbmFyaW9zIHdoZXJlIHRoZSBicm93c2VyIGRldmljZSBzbGVlcHMsIGFuZCB0aGVuXHJcbiAgICAgICAgLy8gdGhlIHRpbWVycyBlbmQgdXAgZ2V0dGluZyBkZWxheWVkLlxyXG4gICAgICAgIHZhciB0aW1lckR1cmF0aW9uID0gVGltZXJEdXJhdGlvbjtcclxuICAgICAgICBpZiAoZHVyYXRpb24gPCB0aW1lckR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHRpbWVyRHVyYXRpb24gPSBkdXJhdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fdGltZXJIYW5kbGUgPSB0aGlzLl90aW1lci5zZXRJbnRlcnZhbCh0aGlzLl9jYWxsYmFjay5iaW5kKHRoaXMpLCB0aW1lckR1cmF0aW9uICogMTAwMCk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCBleHBpcmF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHBpcmF0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGNhbmNlbCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fdGltZXJIYW5kbGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuY2FuY2VsOiBcIiwgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXJIYW5kbGUpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lckhhbmRsZSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9jYWxsYmFjaygpIHtcclxuICAgICAgICB2YXIgZGlmZiA9IHRoaXMuX2V4cGlyYXRpb24gLSB0aGlzLm5vdztcclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5jYWxsYmFjazsgXCIgKyB0aGlzLl9uYW1lICsgXCIgdGltZXIgZXhwaXJlcyBpbjpcIiwgZGlmZik7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9leHBpcmF0aW9uIDw9IHRoaXMubm93KSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsKCk7XHJcbiAgICAgICAgICAgIHN1cGVyLnJhaXNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuQ2xpZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHNldHRpbmdzLCBKc29uU2VydmljZUN0b3IgPSBKc29uU2VydmljZSwgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSkge1xyXG4gICAgICAgIGlmICghc2V0dGluZ3MpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZXR0aW5nc1wiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fanNvblNlcnZpY2UgPSBuZXcgSnNvblNlcnZpY2VDdG9yKCk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGV4Y2hhbmdlQ29kZShhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcImF1dGhvcml6YXRpb25fY29kZVwiO1xyXG4gICAgICAgIGFyZ3MuY2xpZW50X2lkID0gYXJncy5jbGllbnRfaWQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkO1xyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gYXJncy5yZWRpcmVjdF91cmkgfHwgdGhpcy5fc2V0dGluZ3MucmVkaXJlY3RfdXJpO1xyXG5cclxuICAgICAgICBpZiAoIWFyZ3MuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIGNvZGUgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSBjb2RlIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHJlZGlyZWN0X3VyaSBpcyByZXF1aXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghYXJncy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY29kZV92ZXJpZmllciBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIGNvZGVfdmVyaWZpZXIgaXMgcmVxdWlyZWRcIikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWFyZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IFJlY2VpdmVkIHRva2VuIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLnBvc3RGb3JtKHVybCwgYXJncykudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IHJlc3BvbnNlIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBleGNoYW5nZVJlZnJlc2hUb2tlbihhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcInJlZnJlc2hfdG9rZW5cIjtcclxuICAgICAgICBhcmdzLmNsaWVudF9pZCA9IGFyZ3MuY2xpZW50X2lkIHx8IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICBhcmdzLmNsaWVudF9zZWNyZXQgPSBhcmdzLmNsaWVudF9zZWNyZXQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuXHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuZXhjaGFuZ2VSZWZyZXNoVG9rZW46IE5vIHJlZnJlc2hfdG9rZW4gcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSByZWZyZXNoX3Rva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogUmVjZWl2ZWQgdG9rZW4gZW5kcG9pbnRcIik7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UucG9zdEZvcm0odXJsLCBhcmdzKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuOiByZXNwb25zZSByZWNlaXZlZFwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmNvbnN0IEFjY2Vzc1Rva2VuVHlwZUhpbnQgPSBcImFjY2Vzc190b2tlblwiO1xyXG5jb25zdCBSZWZyZXNoVG9rZW5UeXBlSGludCA9IFwicmVmcmVzaF90b2tlblwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuUmV2b2NhdGlvbkNsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgWE1MSHR0cFJlcXVlc3RDdG9yID0gR2xvYmFsLlhNTEh0dHBSZXF1ZXN0LCBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHNldHRpbmdzIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fWE1MSHR0cFJlcXVlc3RDdG9yID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZSA9IG5ldyBNZXRhZGF0YVNlcnZpY2VDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICByZXZva2UodG9rZW4sIHJlcXVpcmVkLCB0eXBlID0gXCJhY2Nlc3NfdG9rZW5cIikge1xyXG4gICAgICAgIGlmICghdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogTm8gdG9rZW4gcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHRva2VuIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0eXBlICE9PSBBY2Nlc3NUb2tlblR5cGVIaW50ICYmIHR5cGUgIT0gUmVmcmVzaFRva2VuVHlwZUhpbnQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogSW52YWxpZCB0b2tlbiB0eXBlXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRva2VuIHR5cGUuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRSZXZvY2F0aW9uRW5kcG9pbnQoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdXJsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBSZXZvY2F0aW9uIG5vdCBzdXBwb3J0ZWRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmV2b2NhdGlvbiBub3Qgc3VwcG9ydGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIG5vdCByZXF1aXJlZCwgc28gZG9uJ3QgZXJyb3IgYW5kIGp1c3QgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2U6IFJldm9raW5nIFwiICsgdHlwZSk7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfaWQgPSB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQ7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfc2VjcmV0ID0gdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZSh1cmwsIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgdG9rZW4sIHR5cGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2UodXJsLCBjbGllbnRfaWQsIGNsaWVudF9zZWNyZXQsIHRva2VuLCB0eXBlKSB7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblxyXG4gICAgICAgICAgICB2YXIgeGhyID0gbmV3IHRoaXMuX1hNTEh0dHBSZXF1ZXN0Q3RvcigpO1xyXG4gICAgICAgICAgICB4aHIub3BlbihcIlBPU1RcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIHhoci5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBIVFRQIHJlc3BvbnNlIHJlY2VpdmVkLCBzdGF0dXNcIiwgeGhyLnN0YXR1cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcih4aHIuc3RhdHVzVGV4dCArIFwiIChcIiArIHhoci5zdGF0dXMgKyBcIilcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB4aHIub25lcnJvciA9ICgpID0+IHsgXHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBOZXR3b3JrIEVycm9yLlwiKVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KFwiTmV0d29yayBFcnJvclwiKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHZhciBib2R5ID0gXCJjbGllbnRfaWQ9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoY2xpZW50X2lkKTtcclxuICAgICAgICAgICAgaWYgKGNsaWVudF9zZWNyZXQpIHtcclxuICAgICAgICAgICAgICAgIGJvZHkgKz0gXCImY2xpZW50X3NlY3JldD1cIiArIGVuY29kZVVSSUNvbXBvbmVudChjbGllbnRfc2VjcmV0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBib2R5ICs9IFwiJnRva2VuX3R5cGVfaGludD1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0eXBlKTtcclxuICAgICAgICAgICAgYm9keSArPSBcIiZ0b2tlbj1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0b2tlbik7XHJcblxyXG4gICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKTtcclxuICAgICAgICAgICAgeGhyLnNlbmQoYm9keSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXJsVXRpbGl0eSB7XHJcbiAgICBzdGF0aWMgYWRkUXVlcnlQYXJhbSh1cmwsIG5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKCc/JykgPCAwKSB7XHJcbiAgICAgICAgICAgIHVybCArPSBcIj9cIjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh1cmxbdXJsLmxlbmd0aCAtIDFdICE9PSBcIj9cIikge1xyXG4gICAgICAgICAgICB1cmwgKz0gXCImXCI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KG5hbWUpO1xyXG4gICAgICAgIHVybCArPSBcIj1cIjtcclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHVybDtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgcGFyc2VVcmxGcmFnbWVudCh2YWx1ZSwgZGVsaW1pdGVyID0gXCIjXCIsIGdsb2JhbCA9IEdsb2JhbCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKXtcclxuICAgICAgICAgICAgdmFsdWUgPSBnbG9iYWwubG9jYXRpb24uaHJlZjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBpZHggPSB2YWx1ZS5sYXN0SW5kZXhPZihkZWxpbWl0ZXIpO1xyXG4gICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cihpZHggKyAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChkZWxpbWl0ZXIgPT09IFwiP1wiKSB7XHJcbiAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGRvaW5nIHF1ZXJ5LCB0aGVuIHN0cmlwIG9mZiBoYXNoIGZyYWdtZW50IGJlZm9yZSB3ZSBwYXJzZVxyXG4gICAgICAgICAgICBpZHggPSB2YWx1ZS5pbmRleE9mKCcjJyk7XHJcbiAgICAgICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHIoMCwgaWR4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHBhcmFtcyA9IHt9LFxyXG4gICAgICAgICAgICByZWdleCA9IC8oW14mPV0rKT0oW14mXSopL2csXHJcbiAgICAgICAgICAgIG07XHJcblxyXG4gICAgICAgIHZhciBjb3VudGVyID0gMDtcclxuICAgICAgICB3aGlsZSAobSA9IHJlZ2V4LmV4ZWModmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHBhcmFtc1tkZWNvZGVVUklDb21wb25lbnQobVsxXSldID0gZGVjb2RlVVJJQ29tcG9uZW50KG1bMl0pO1xyXG4gICAgICAgICAgICBpZiAoY291bnRlcisrID4gNTApIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVybFV0aWxpdHkucGFyc2VVcmxGcmFnbWVudDogcmVzcG9uc2UgZXhjZWVkZWQgZXhwZWN0ZWQgbnVtYmVyIG9mIHBhcmFtZXRlcnNcIiwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogXCJSZXNwb25zZSBleGNlZWRlZCBleHBlY3RlZCBudW1iZXIgb2YgcGFyYW1ldGVyc1wiXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHBhcmFtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gcGFyYW1zO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHt9O1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyIHtcclxuICAgIGNvbnN0cnVjdG9yKHtpZF90b2tlbiwgc2Vzc2lvbl9zdGF0ZSwgYWNjZXNzX3Rva2VuLCByZWZyZXNoX3Rva2VuLCB0b2tlbl90eXBlLCBzY29wZSwgcHJvZmlsZSwgZXhwaXJlc19hdCwgc3RhdGV9KSB7XHJcbiAgICAgICAgdGhpcy5pZF90b2tlbiA9IGlkX3Rva2VuO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSBhY2Nlc3NfdG9rZW47XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoX3Rva2VuID0gcmVmcmVzaF90b2tlbjtcclxuICAgICAgICB0aGlzLnRva2VuX3R5cGUgPSB0b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLnByb2ZpbGUgPSBwcm9maWxlO1xyXG4gICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IGV4cGlyZXNfYXQ7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKSB7XHJcbiAgICAgICAgbGV0IGV4cGlyZXNfaW4gPSBwYXJzZUludCh2YWx1ZSk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBleHBpcmVzX2luID09PSAnbnVtYmVyJyAmJiBleHBpcmVzX2luID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgbm93ID0gcGFyc2VJbnQoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG4gICAgICAgICAgICB0aGlzLmV4cGlyZXNfYXQgPSBub3cgKyBleHBpcmVzX2luO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXhwaXJlZCgpIHtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHRoaXMuZXhwaXJlc19pbjtcclxuICAgICAgICBpZiAoZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHBpcmVzX2luIDw9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNjb3BlcygpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuc2NvcGUgfHwgXCJcIikuc3BsaXQoXCIgXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLnRvU3RvcmFnZVN0cmluZ1wiKTtcclxuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xyXG4gICAgICAgICAgICBpZF90b2tlbjogdGhpcy5pZF90b2tlbixcclxuICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogdGhpcy5zZXNzaW9uX3N0YXRlLFxyXG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46IHRoaXMuYWNjZXNzX3Rva2VuLFxyXG4gICAgICAgICAgICByZWZyZXNoX3Rva2VuOiB0aGlzLnJlZnJlc2hfdG9rZW4sXHJcbiAgICAgICAgICAgIHRva2VuX3R5cGU6IHRoaXMudG9rZW5fdHlwZSxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIHByb2ZpbGU6IHRoaXMucHJvZmlsZSxcclxuICAgICAgICAgICAgZXhwaXJlc19hdDogdGhpcy5leHBpcmVzX2F0XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGZyb21TdG9yYWdlU3RyaW5nKHN0b3JhZ2VTdHJpbmcpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgVXNlcihKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBKc29uU2VydmljZSB9IGZyb20gJy4vSnNvblNlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VySW5mb1NlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgc2V0dGluZ3MsIFxyXG4gICAgICAgIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlLCBcclxuICAgICAgICBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuICAgICAgICBpZiAoIXNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IodW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMuX2dldENsYWltc0Zyb21Kd3QuYmluZCh0aGlzKSk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Q2xhaW1zKHRva2VuKSB7XHJcbiAgICAgICAgaWYgKCF0b2tlbikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBObyB0b2tlbiBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHRva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VXNlckluZm9FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLmdldENsYWltczogcmVjZWl2ZWQgdXNlcmluZm8gdXJsXCIsIHVybCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UuZ2V0SnNvbih1cmwsIHRva2VuKS50aGVuKGNsYWltcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBjbGFpbXMgcmVjZWl2ZWRcIiwgY2xhaW1zKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjbGFpbXM7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRDbGFpbXNGcm9tSnd0KHJlcSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEZhaWxlZCB0byBwYXJzZSBKV1RcIiwgand0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcGFyc2UgaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIga2lkID0gand0LmhlYWRlci5raWQ7XHJcblxyXG4gICAgICAgICAgICBsZXQgaXNzdWVyUHJvbWlzZTtcclxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnT1AnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdBTlknOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoand0LnBheWxvYWQuaXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVyUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBpc3N1ZXJQcm9taXNlLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgaXNzdWVyOlwiICsgaXNzdWVyKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldFNpZ25pbmdLZXlzKCkudGhlbihrZXlzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlckluZm9TZXJ2aWNlLl9nZXRDbGFpbXNGcm9tSnd0OiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpZ25pbmcga2V5cyBmcm9tIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFraWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5cyA9IHRoaXMuX2ZpbHRlckJ5QWxnKGtleXMsIGp3dC5oZWFkZXIuYWxnKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBraWQgZm91bmQgaW4gaWRfdG9rZW4gYW5kIG1vcmUgdGhhbiBvbmUga2V5IGZvdW5kIGluIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGtpZCBpcyBtYW5kYXRvcnkgb25seSB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBrZXlzIGluIHRoZSByZWZlcmVuY2VkIEpXSyBTZXQgZG9jdW1lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwOi8vb3BlbmlkLm5ldC9zcGVjcy9vcGVuaWQtY29ubmVjdC1jb3JlLTFfMC5odG1sI1NpZ25pbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5LmtpZCA9PT0ga2lkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgha2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhdWRpZW5jZSA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0KHJlcS5yZXNwb25zZVRleHQsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzLCB1bmRlZmluZWQsIHRydWUpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEpXVCB2YWxpZGF0aW9uIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBqd3QucGF5bG9hZDtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEVycm9yIHBhcnNpbmcgSldUIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKSB7XHJcbiAgICAgICAgdmFyIGt0eSA9IG51bGw7XHJcbiAgICAgICAgaWYgKGFsZy5zdGFydHNXaXRoKFwiUlNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJSU0FcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJQU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlBTXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGFsZy5zdGFydHNXaXRoKFwiRVNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJFQ1wiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLl9maWx0ZXJCeUFsZzogYWxnIG5vdCBzdXBwb3J0ZWQ6IFwiLCBhbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZmlsdGVyQnlBbGc6IE51bWJlciBvZiBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5LCBrZXlzLmxlbmd0aCk7XHJcblxyXG4gICAgICAgIHJldHVybiBrZXlzO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudCB9IGZyb20gJy4vT2lkY0NsaWVudC5qcyc7XHJcbmltcG9ydCB7IFVzZXJNYW5hZ2VyU2V0dGluZ3MgfSBmcm9tICcuL1VzZXJNYW5hZ2VyU2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi9Vc2VyLmpzJztcclxuaW1wb3J0IHsgVXNlck1hbmFnZXJFdmVudHMgfSBmcm9tICcuL1VzZXJNYW5hZ2VyRXZlbnRzLmpzJztcclxuaW1wb3J0IHsgU2lsZW50UmVuZXdTZXJ2aWNlIH0gZnJvbSAnLi9TaWxlbnRSZW5ld1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBTZXNzaW9uTW9uaXRvciB9IGZyb20gJy4vU2Vzc2lvbk1vbml0b3IuanMnO1xyXG5pbXBvcnQgeyBUb2tlblJldm9jYXRpb25DbGllbnQgfSBmcm9tICcuL1Rva2VuUmV2b2NhdGlvbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IFRva2VuQ2xpZW50IH0gZnJvbSAnLi9Ub2tlbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IEpvc2VVdGlsIH0gZnJvbSAnLi9Kb3NlVXRpbC5qcyc7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFVzZXJNYW5hZ2VyIGV4dGVuZHMgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9LFxyXG4gICAgICAgIFNpbGVudFJlbmV3U2VydmljZUN0b3IgPSBTaWxlbnRSZW5ld1NlcnZpY2UsXHJcbiAgICAgICAgU2Vzc2lvbk1vbml0b3JDdG9yID0gU2Vzc2lvbk1vbml0b3IsXHJcbiAgICAgICAgVG9rZW5SZXZvY2F0aW9uQ2xpZW50Q3RvciA9IFRva2VuUmV2b2NhdGlvbkNsaWVudCxcclxuICAgICAgICBUb2tlbkNsaWVudEN0b3IgPSBUb2tlbkNsaWVudCxcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuXHJcbiAgICAgICAgaWYgKCEoc2V0dGluZ3MgaW5zdGFuY2VvZiBVc2VyTWFuYWdlclNldHRpbmdzKSkge1xyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IG5ldyBVc2VyTWFuYWdlclNldHRpbmdzKHNldHRpbmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xyXG5cclxuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVXNlck1hbmFnZXJFdmVudHMoc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3U2VydmljZSA9IG5ldyBTaWxlbnRSZW5ld1NlcnZpY2VDdG9yKHRoaXMpO1xyXG5cclxuICAgICAgICAvLyBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczsgdGhlc2Ugc2VydmljZXMgZGVwZW5kIHVwb24gdGhlIGV2ZW50cy5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5hdXRvbWF0aWNTaWxlbnRSZW5ldykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBhdXRvbWF0aWNTaWxlbnRSZW5ldyBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNpbGVudCByZW5ld1wiKTtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNpbGVudFJlbmV3KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5tb25pdG9yU2Vzc2lvbikge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBtb25pdG9yU2Vzc2lvbiBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNlc3Npb24gbW9uaXRvclwiKTtcclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbk1vbml0b3IgPSBuZXcgU2Vzc2lvbk1vbml0b3JDdG9yKHRoaXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50ID0gbmV3IFRva2VuUmV2b2NhdGlvbkNsaWVudEN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3Rva2VuQ2xpZW50ID0gbmV3IFRva2VuQ2xpZW50Q3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fam9zZVV0aWwgPSBqb3NlVXRpbDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3JlZGlyZWN0TmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9wb3B1cE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5ncy5wb3B1cE5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfaWZyYW1lTmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLmlmcmFtZU5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfdXNlclN0b3JlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnVzZXJTdG9yZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXZlbnRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5nZXRVc2VyOiB1c2VyIGxvYWRlZFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMubG9hZCh1c2VyLCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLmdldFVzZXI6IHVzZXIgbm90IGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVVzZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKG51bGwpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnJlbW92ZVVzZXI6IHVzZXIgcmVtb3ZlZCBmcm9tIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy51bmxvYWQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5SZWRpcmVjdChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpyXCI7XHJcbiAgICAgICAgbGV0IG5hdlBhcmFtcyA9IHtcclxuICAgICAgICAgICAgdXNlUmVwbGFjZVRvTmF2aWdhdGUgOiBhcmdzLnVzZVJlcGxhY2VUb05hdmlnYXRlXHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0OiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbmluUmVkaXJlY3RDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5SZWRpcmVjdENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmluUG9wdXAoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6cFwiO1xyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnBvcHVwX3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cDogTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pbihhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IHNpZ25pblBvcHVwIHN1Y2Nlc3NmdWwsIHNpZ25lZCBpbiBzdWI6IFwiLCB1c2VyLnByb2ZpbGUuc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBzaWduaW5Qb3B1cENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5DYWxsYmFjayh1cmwsIHRoaXMuX3BvcHVwTmF2aWdhdG9yKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSAmJiB1c2VyLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSkuY2F0Y2goZXJyPT57XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2sgZXJyb3I6IFwiICsgZXJyICYmIGVyci5tZXNzYWdlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnQoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6c1wiO1xyXG4gICAgICAgIC8vIGZpcnN0IGRldGVybWluZSBpZiB3ZSBoYXZlIGEgcmVmcmVzaCB0b2tlbiwgb3IgbmVlZCB0byB1c2UgaWZyYW1lXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIgJiYgdXNlci5yZWZyZXNoX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICBhcmdzLnJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlUmVmcmVzaFRva2VuKGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYXJncy5pZF90b2tlbl9oaW50ID0gYXJncy5pZF90b2tlbl9oaW50IHx8ICh0aGlzLnNldHRpbmdzLmluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyAmJiB1c2VyICYmIHVzZXIuaWRfdG9rZW4pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIgJiYgdGhpcy5fc2V0dGluZ3MudmFsaWRhdGVTdWJPblNpbGVudFJlbmV3KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50LCBzdWJqZWN0IHByaW9yIHRvIHNpbGVudCByZW5ldzogXCIsIHVzZXIucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MuY3VycmVudF9zdWIgPSB1c2VyLnByb2ZpbGUuc3ViO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblNpbGVudElmcmFtZShhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF91c2VSZWZyZXNoVG9rZW4oYXJncyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuKGFyZ3MpLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IE5vIHJlc3BvbnNlIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyByZXNwb25zZSByZXR1cm5lZCBmcm9tIHRva2VuIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghcmVzdWx0LmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3VzZVJlZnJlc2hUb2tlbjogTm8gYWNjZXNzIHRva2VuIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyBhY2Nlc3MgdG9rZW4gcmV0dXJuZWQgZnJvbSB0b2tlbiBlbmRwb2ludFwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGlkVG9rZW5WYWxpZGF0aW9uID0gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pZF90b2tlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZFRva2VuVmFsaWRhdGlvbiA9IHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbih1c2VyLnByb2ZpbGUsIHJlc3VsdC5pZF90b2tlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWRUb2tlblZhbGlkYXRpb24udGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IHJlZnJlc2ggdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc1wiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5pZF90b2tlbiA9IHJlc3VsdC5pZF90b2tlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSByZXN1bHQuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VyLnJlZnJlc2hfdG9rZW4gPSByZXN1bHQucmVmcmVzaF90b2tlbiB8fCB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXIuZXhwaXJlc19pbiA9IHJlc3VsdC5leHBpcmVzX2luO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKHVzZXIpLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW4ocHJvZmlsZSwgaWRfdG9rZW4pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0QXR0cmlidXRlcyhpZF90b2tlbiwgaXNzdWVyLCB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQsIHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldykudGhlbihwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLnN1YiAhPT0gcHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5fdmFsaWRhdGVJZFRva2VuRnJvbVRva2VuUmVmcmVzaFRva2VuOiBzdWIgaW4gaWRfdG9rZW4gZG9lcyBub3QgbWF0Y2ggY3VycmVudCBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcInN1YiBpbiBpZF90b2tlbiBkb2VzIG5vdCBtYXRjaCBjdXJyZW50IHN1YlwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5hdXRoX3RpbWUgJiYgcGF5bG9hZC5hdXRoX3RpbWUgIT09IHByb2ZpbGUuYXV0aF90aW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5henAgJiYgcGF5bG9hZC5henAgIT09IHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIXBheWxvYWQuYXpwICYmIHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIG5vdCBpbiBpZF90b2tlbiwgYnV0IHByZXNlbnQgaW4gb3JpZ2luYWwgaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImF6cCBub3QgaW4gaWRfdG9rZW4sIGJ1dCBwcmVzZW50IGluIG9yaWdpbmFsIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zaWduaW5TaWxlbnRJZnJhbWUoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3Muc2lsZW50X3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5TaWxlbnQ6IE5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhcmdzLnJlZGlyZWN0X3VyaSA9IHVybDtcclxuICAgICAgICBhcmdzLnByb21wdCA9IGFyZ3MucHJvbXB0IHx8IFwibm9uZVwiO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluKGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50OiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudDogbm8gc3ViXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdXNlcjtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluQ2FsbGJhY2sodXJsLCB0aGlzLl9pZnJhbWVOYXZpZ2F0b3IpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodXNlci5wcm9maWxlICYmIHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBubyBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25pbkNhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlLnJlcXVlc3RfdHlwZSA9PT0gXCJzaTpyXCIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2sodXJsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNpOnBcIikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2lnbmluUG9wdXBDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5yZXF1ZXN0X3R5cGUgPT09IFwic2k6c1wiKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJpbnZhbGlkIHJlc3BvbnNlX3R5cGUgaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRDYWxsYmFjayh1cmwsIGtlZXBPcGVuKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnBcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRQb3B1cENhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImludmFsaWQgcmVzcG9uc2VfdHlwZSBpbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHF1ZXJ5U2Vzc2lvblN0YXR1cyhhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpzXCI7IC8vIHRoaXMgYWN0cyBsaWtlIGEgc2lnbmluIHNpbGVudFxyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnNpbGVudF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXJncy5yZWRpcmVjdF91cmkgPSB1cmw7XHJcbiAgICAgICAgYXJncy5wcm9tcHQgPSBcIm5vbmVcIjtcclxuICAgICAgICBhcmdzLnJlc3BvbnNlX3R5cGUgPSBhcmdzLnJlc3BvbnNlX3R5cGUgfHwgdGhpcy5zZXR0aW5ncy5xdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZTtcclxuICAgICAgICBhcmdzLnNjb3BlID0gYXJncy5zY29wZSB8fCBcIm9wZW5pZFwiO1xyXG4gICAgICAgIGFyZ3Muc2tpcFVzZXJJbmZvID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblN0YXJ0KGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZShuYXZSZXNwb25zZS51cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzaWduaW5SZXNwb25zZS5zZXNzaW9uX3N0YXRlICYmIHNpZ25pblJlc3BvbnNlLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXM6IHF1ZXJ5U2Vzc2lvblN0YXR1cyBzdWNjZXNzIGZvciBzdWI6IFwiLCAgc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGU6IHNpZ25pblJlc3BvbnNlLnNlc3Npb25fc3RhdGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Yjogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zaWRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJxdWVyeVNlc3Npb25TdGF0dXMgc3VjY2Vzc2Z1bCwgdXNlciBub3QgYXV0aGVudGljYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyLnNlc3Npb25fc3RhdGUgJiYgdGhpcy5zZXR0aW5ncy5tb25pdG9yQW5vbnltb3VzU2Vzc2lvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIubWVzc2FnZSA9PSBcImxvZ2luX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiY29uc2VudF9yZXF1aXJlZFwiIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnIubWVzc2FnZSA9PSBcImludGVyYWN0aW9uX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiYWNjb3VudF9zZWxlY3Rpb25fcmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1czogcXVlcnlTZXNzaW9uU3RhdHVzIHN1Y2Nlc3MgZm9yIGFub255bW91cyB1c2VyXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogZXJyLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbmluKGFyZ3MsIG5hdmlnYXRvciwgbmF2aWdhdG9yUGFyYW1zID0ge30pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMpLnRoZW4obmF2UmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKG5hdlJlc3BvbnNlLnVybCwgYXJncyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG5cclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnByZXBhcmUobmF2aWdhdG9yUGFyYW1zKS50aGVuKGhhbmRsZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5TdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2lnbmluUmVxdWVzdChhcmdzKS50aGVuKHNpZ25pblJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBnb3Qgc2lnbmluIHJlcXVlc3RcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLnVybCA9IHNpZ25pblJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbmluUmVxdWVzdC5zdGF0ZS5pZDtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBFcnJvciBhZnRlciBwcmVwYXJpbmcgbmF2aWdhdG9yLCBjbG9zaW5nIG5hdmlnYXRvciB3aW5kb3dcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgX3NpZ25pbkVuZCh1cmwsIGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZSh1cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHVzZXIgPSBuZXcgVXNlcihzaWduaW5SZXNwb25zZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoYXJncy5jdXJyZW50X3N1Yikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MuY3VycmVudF9zdWIgIT09IHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBjdXJyZW50IHVzZXIgZG9lcyBub3QgbWF0Y2ggdXNlciByZXR1cm5lZCBmcm9tIHNpZ25pbi4gc3ViIGZyb20gc2lnbmluOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImxvZ2luX3JlcXVpcmVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IGN1cnJlbnQgdXNlciBtYXRjaGVzIHVzZXIgcmV0dXJuZWQgZnJvbSBzaWduaW5cIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0b3JlVXNlcih1c2VyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IHVzZXIgc3RvcmVkXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWduaW5DYWxsYmFjayh1cmwsIG5hdmlnYXRvcikge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5DYWxsYmFja1wiKTtcclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLmNhbGxiYWNrKHVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbm91dFJlZGlyZWN0KGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIGFyZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBhcmdzKTtcclxuXHJcbiAgICAgICAgYXJncy5yZXF1ZXN0X3R5cGUgPSBcInNvOnJcIjtcclxuICAgICAgICBsZXQgcG9zdExvZ291dFJlZGlyZWN0VXJpID0gYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKHBvc3RMb2dvdXRSZWRpcmVjdFVyaSl7XHJcbiAgICAgICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdExvZ291dFJlZGlyZWN0VXJpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgbmF2UGFyYW1zID0ge1xyXG4gICAgICAgICAgICB1c2VSZXBsYWNlVG9OYXZpZ2F0ZSA6IGFyZ3MudXNlUmVwbGFjZVRvTmF2aWdhdGVcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0U3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25vdXRSZWRpcmVjdDogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4ocmVzcG9uc2U9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UmVkaXJlY3RDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRQb3B1cChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzbzpwXCI7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuICAgICAgICBpZiAoYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpe1xyXG4gICAgICAgICAgICAvLyB3ZSdyZSBwdXR0aW5nIGEgZHVtbXkgZW50cnkgaW4gaGVyZSBiZWNhdXNlIHdlXHJcbiAgICAgICAgICAgIC8vIG5lZWQgYSB1bmlxdWUgaWQgZnJvbSB0aGUgc3RhdGUgZm9yIG5vdGlmaWNhdGlvblxyXG4gICAgICAgICAgICAvLyB0byB0aGUgcGFyZW50IHdpbmRvdywgd2hpY2ggaXMgbmVjZXNzYXJ5IGlmIHdlXHJcbiAgICAgICAgICAgIC8vIHBsYW4gdG8gcmV0dXJuIGJhY2sgdG8gdGhlIGNsaWVudCBhZnRlciBzaWdub3V0XHJcbiAgICAgICAgICAgIC8vIGFuZCBzbyB3ZSBjYW4gY2xvc2UgdGhlIHBvcHVwIGFmdGVyIHNpZ25vdXRcclxuICAgICAgICAgICAgYXJncy5zdGF0ZSA9IGFyZ3Muc3RhdGUgfHwge307XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbm91dChhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbm91dFBvcHVwOiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbm91dFBvcHVwQ2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Yoa2VlcE9wZW4pID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YodXJsKSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgICAgICAgIGtlZXBPcGVuID0gdXJsO1xyXG4gICAgICAgICAgICB1cmwgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9ICc/JztcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBOYXZpZ2F0b3IuY2FsbGJhY2sodXJsLCBrZWVwT3BlbiwgZGVsaW1pdGVyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UG9wdXBDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbm91dChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25vdXRTdGFydChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcykudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKG5hdlJlc3BvbnNlLnVybCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbm91dFN0YXJ0KGFyZ3MgPSB7fSwgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiBuYXZpZ2F0b3IucHJlcGFyZShuYXZpZ2F0b3JQYXJhbXMpLnRoZW4oaGFuZGxlID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IGxvYWRlZCBjdXJyZW50IHVzZXIgZnJvbSBzdG9yYWdlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciByZXZva2VQcm9taXNlID0gdGhpcy5fc2V0dGluZ3MucmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQgPyB0aGlzLl9yZXZva2VJbnRlcm5hbCh1c2VyKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldm9rZVByb21pc2UudGhlbigoKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZF90b2tlbiA9IGFyZ3MuaWRfdG9rZW5faGludCB8fCB1c2VyICYmIHVzZXIuaWRfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IFNldHRpbmcgaWRfdG9rZW4gaW50byBzaWdub3V0IHJlcXVlc3RcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MuaWRfdG9rZW5faGludCA9IGlkX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlVXNlcigpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbm91dFN0YXJ0OiB1c2VyIHJlbW92ZWQsIGNyZWF0aW5nIHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVNpZ25vdXRSZXF1ZXN0KGFyZ3MpLnRoZW4oc2lnbm91dFJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3JQYXJhbXMudXJsID0gc2lnbm91dFJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpZ25vdXRSZXF1ZXN0LnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbm91dFJlcXVlc3Quc3RhdGUuaWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogRXJyb3IgYWZ0ZXIgcHJlcGFyaW5nIG5hdmlnYXRvciwgY2xvc2luZyBuYXZpZ2F0b3Igd2luZG93XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZS5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWdub3V0RW5kKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsKS50aGVuKHNpZ25vdXRSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0RW5kOiBnb3Qgc2lnbm91dCByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBzaWdub3V0UmVzcG9uc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV2b2tlQWNjZXNzVG9rZW4oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUludGVybmFsKHVzZXIsIHRydWUpLnRoZW4oc3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3VjY2Vzcykge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiByZW1vdmluZyB0b2tlbiBwcm9wZXJ0aWVzIGZyb20gdXNlciBhbmQgcmUtc3RvcmluZ1wiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHVzZXIucmVmcmVzaF90b2tlbiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5leHBpcmVzX2F0ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB1c2VyLnRva2VuX3R5cGUgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdG9yZVVzZXIodXNlcikudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiB1c2VyIHN0b3JlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmxvYWQodXNlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5yZXZva2VBY2Nlc3NUb2tlbjogYWNjZXNzIHRva2VuIHJldm9rZWQgc3VjY2Vzc2Z1bGx5XCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2VJbnRlcm5hbCh1c2VyLCByZXF1aXJlZCkge1xyXG4gICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgIHZhciBhY2Nlc3NfdG9rZW4gPSB1c2VyLmFjY2Vzc190b2tlbjtcclxuICAgICAgICAgICAgdmFyIHJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oYXRTdWNjZXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJ0U3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0U3VjY2VzcyAmJiAhcnRTdWNjZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucmV2b2tlQWNjZXNzVG9rZW46IG5vIG5lZWQgdG8gcmV2b2tlIGR1ZSB0byBubyB0b2tlbihzKSwgb3IgSldUIGZvcm1hdFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0U3VjY2VzcyB8fCBydFN1Y2Nlc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKSB7XHJcbiAgICAgICAgLy8gY2hlY2sgZm9yIEpXVCB2cy4gcmVmZXJlbmNlIHRva2VuXHJcbiAgICAgICAgaWYgKCFhY2Nlc3NfdG9rZW4gfHwgYWNjZXNzX3Rva2VuLmluZGV4T2YoJy4nKSA+PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2UoYWNjZXNzX3Rva2VuLCByZXF1aXJlZCkudGhlbigoKSA9PiB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpIHtcclxuICAgICAgICBpZiAoIXJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZShyZWZyZXNoX3Rva2VuLCByZXF1aXJlZCwgXCJyZWZyZXNoX3Rva2VuXCIpLnRoZW4oKCkgPT4gdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhcnRTaWxlbnRSZW5ldygpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld1NlcnZpY2Uuc3RhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBzdG9wU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdTZXJ2aWNlLnN0b3AoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3VzZXJTdG9yZUtleSgpIHtcclxuICAgICAgICByZXR1cm4gYHVzZXI6JHt0aGlzLnNldHRpbmdzLmF1dGhvcml0eX06JHt0aGlzLnNldHRpbmdzLmNsaWVudF9pZH1gO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkVXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLmdldCh0aGlzLl91c2VyU3RvcmVLZXkpLnRoZW4oc3RvcmFnZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmIChzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fbG9hZFVzZXI6IHVzZXIgc3RvcmFnZVN0cmluZyBsb2FkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXNlci5mcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX2xvYWRVc2VyOiBubyB1c2VyIHN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0b3JlVXNlcih1c2VyKSB7XHJcbiAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc3RvcmVVc2VyOiBzdG9yaW5nIHVzZXJcIik7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RvcmFnZVN0cmluZyA9IHVzZXIudG9TdG9yYWdlU3RyaW5nKCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VyU3RvcmUuc2V0KHRoaXMuX3VzZXJTdG9yZUtleSwgc3RvcmFnZVN0cmluZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJzdG9yZVVzZXIuc3RvcmVVc2VyOiByZW1vdmluZyB1c2VyXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLnJlbW92ZSh0aGlzLl91c2VyU3RvcmVLZXkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEFjY2Vzc1Rva2VuRXZlbnRzIH0gZnJvbSAnLi9BY2Nlc3NUb2tlbkV2ZW50cy5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXNlck1hbmFnZXJFdmVudHMgZXh0ZW5kcyBBY2Nlc3NUb2tlbkV2ZW50cyB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcclxuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgbG9hZGVkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgdW5sb2FkZWRcIik7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvciA9IG5ldyBFdmVudChcIlNpbGVudCByZW5ldyBlcnJvclwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4gPSBuZXcgRXZlbnQoXCJVc2VyIHNpZ25lZCBpblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0ID0gbmV3IEV2ZW50KFwiVXNlciBzaWduZWQgb3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZCA9IG5ldyBFdmVudChcIlVzZXIgc2Vzc2lvbiBjaGFuZ2VkXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGxvYWQodXNlciwgcmFpc2VFdmVudD10cnVlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMubG9hZFwiKTtcclxuICAgICAgICBzdXBlci5sb2FkKHVzZXIpO1xyXG4gICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJMb2FkZWQucmFpc2UodXNlcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdW5sb2FkKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLnVubG9hZFwiKTtcclxuICAgICAgICBzdXBlci51bmxvYWQoKTtcclxuICAgICAgICB0aGlzLl91c2VyVW5sb2FkZWQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyTG9hZGVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJMb2FkZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyTG9hZGVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZFVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5yZW1vdmVIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRTaWxlbnRSZW5ld0Vycm9yKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvci5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVNpbGVudFJlbmV3RXJyb3IoY2IpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld0Vycm9yLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvclwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3RXJyb3IucmFpc2UoZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZEluKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLl9yYWlzZVVzZXJTaWduZWRJblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4ucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2lnbmVkT3V0KGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZE91dC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJTaWduZWRPdXQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0LnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZE91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlckV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkT3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTaWduZWRPdXQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQuYWRkSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICByZW1vdmVVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICBfcmFpc2VVc2VyU2Vzc2lvbkNoYW5nZWQoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlVXNlclNlc3Npb25DaGFuZ2VkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZC5yYWlzZSgpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudFNldHRpbmdzIH0gZnJvbSAnLi9PaWRjQ2xpZW50U2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBSZWRpcmVjdE5hdmlnYXRvciB9IGZyb20gJy4vUmVkaXJlY3ROYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBQb3B1cE5hdmlnYXRvciB9IGZyb20gJy4vUG9wdXBOYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVOYXZpZ2F0b3IgfSBmcm9tICcuL0lGcmFtZU5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IFdlYlN0b3JhZ2VTdGF0ZVN0b3JlIH0gZnJvbSAnLi9XZWJTdG9yYWdlU3RhdGVTdG9yZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuaW1wb3J0IHsgU2lnbmluUmVxdWVzdCB9IGZyb20gJy4vU2lnbmluUmVxdWVzdC5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDtcclxuY29uc3QgRGVmYXVsdENoZWNrU2Vzc2lvbkludGVydmFsID0gMjAwMDtcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyTWFuYWdlclNldHRpbmdzIGV4dGVuZHMgT2lkY0NsaWVudFNldHRpbmdzIHtcclxuICAgIGNvbnN0cnVjdG9yKHtcclxuICAgICAgICBwb3B1cF9yZWRpcmVjdF91cmksXHJcbiAgICAgICAgcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIHBvcHVwV2luZG93RmVhdHVyZXMsXHJcbiAgICAgICAgcG9wdXBXaW5kb3dUYXJnZXQsXHJcbiAgICAgICAgc2lsZW50X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dCxcclxuICAgICAgICBhdXRvbWF0aWNTaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyA9IHRydWUsXHJcbiAgICAgICAgbW9uaXRvclNlc3Npb24gPSB0cnVlLFxyXG4gICAgICAgIG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uID0gZmFsc2UsXHJcbiAgICAgICAgY2hlY2tTZXNzaW9uSW50ZXJ2YWwgPSBEZWZhdWx0Q2hlY2tTZXNzaW9uSW50ZXJ2YWwsXHJcbiAgICAgICAgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IgPSB0cnVlLFxyXG4gICAgICAgIHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlLFxyXG4gICAgICAgIHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0ID0gZmFsc2UsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgcmVkaXJlY3ROYXZpZ2F0b3IgPSBuZXcgUmVkaXJlY3ROYXZpZ2F0b3IoKSxcclxuICAgICAgICBwb3B1cE5hdmlnYXRvciA9IG5ldyBQb3B1cE5hdmlnYXRvcigpLFxyXG4gICAgICAgIGlmcmFtZU5hdmlnYXRvciA9IG5ldyBJRnJhbWVOYXZpZ2F0b3IoKSxcclxuICAgICAgICB1c2VyU3RvcmUgPSBuZXcgV2ViU3RvcmFnZVN0YXRlU3RvcmUoeyBzdG9yZTogR2xvYmFsLnNlc3Npb25TdG9yYWdlIH0pXHJcbiAgICB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICB0aGlzLl9wb3B1cF9yZWRpcmVjdF91cmkgPSBwb3B1cF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXMgPSBwb3B1cFdpbmRvd0ZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0ID0gcG9wdXBXaW5kb3dUYXJnZXQ7XHJcblxyXG4gICAgICAgIHRoaXMuX3NpbGVudF9yZWRpcmVjdF91cmkgPSBzaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlcXVlc3RUaW1lb3V0ID0gc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICAgICAgdGhpcy5fYXV0b21hdGljU2lsZW50UmVuZXcgPSBhdXRvbWF0aWNTaWxlbnRSZW5ldztcclxuICAgICAgICB0aGlzLl92YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXcgPSB2YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXc7XHJcbiAgICAgICAgdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3ID0gaW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX21vbml0b3JTZXNzaW9uID0gbW9uaXRvclNlc3Npb247XHJcbiAgICAgICAgdGhpcy5fbW9uaXRvckFub255bW91c1Nlc3Npb24gPSBtb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JbnRlcnZhbCA9IGNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgICAgIHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yID0gc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICAgICAgaWYgKHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICAgICAgfSBcclxuICAgICAgICBlbHNlIGlmIChhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnJlc3BvbnNlX3R5cGUpIHtcclxuICAgICAgICAgICAgdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUgPSBTaWduaW5SZXF1ZXN0LmlzT2lkYyhhcmd1bWVudHNbMF0ucmVzcG9uc2VfdHlwZSkgPyBcImlkX3Rva2VuXCIgOiBcImNvZGVcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gXCJpZF90b2tlblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9yZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCA9IHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG5cclxuICAgICAgICB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvciA9IHJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwTmF2aWdhdG9yID0gcG9wdXBOYXZpZ2F0b3I7XHJcbiAgICAgICAgdGhpcy5faWZyYW1lTmF2aWdhdG9yID0gaWZyYW1lTmF2aWdhdG9yO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyU3RvcmUgPSB1c2VyU3RvcmU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHBvcHVwX3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwV2luZG93RmVhdHVyZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBXaW5kb3dUYXJnZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzaWxlbnRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgIGdldCBzaWxlbnRSZXF1ZXN0VGltZW91dCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgYXV0b21hdGljU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9tYXRpY1NpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVTdWJPblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9uaXRvclNlc3Npb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vbml0b3JTZXNzaW9uO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgIH1cclxuICAgIGdldCBjaGVja1Nlc3Npb25JbnRlcnZhbCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICB9XHJcbiAgICBnZXQgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCByZWRpcmVjdE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBOYXZpZ2F0b3IoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwTmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IGlmcmFtZU5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faWZyYW1lTmF2aWdhdG9yO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB1c2VyU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VzZXJTdG9yZTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7cHJlZml4ID0gXCJvaWRjLlwiLCBzdG9yZSA9IEdsb2JhbC5sb2NhbFN0b3JhZ2V9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9zdG9yZSA9IHN0b3JlO1xyXG4gICAgICAgIHRoaXMuX3ByZWZpeCA9IHByZWZpeDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnNldFwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIHRoaXMuX3N0b3JlLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQoa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiV2ViU3RvcmFnZVN0YXRlU3RvcmUuZ2V0XCIsIGtleSk7XHJcblxyXG4gICAgICAgIGtleSA9IHRoaXMuX3ByZWZpeCArIGtleTtcclxuXHJcbiAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLl9zdG9yZS5nZXRJdGVtKGtleSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoaXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlKGtleSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnJlbW92ZVwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIGxldCBpdGVtID0gdGhpcy5fc3RvcmUuZ2V0SXRlbShrZXkpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlLnJlbW92ZUl0ZW0oa2V5KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpdGVtKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRBbGxLZXlzKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLmdldEFsbEtleXNcIik7XHJcblxyXG4gICAgICAgIHZhciBrZXlzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLl9zdG9yZS5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgbGV0IGtleSA9IHRoaXMuX3N0b3JlLmtleShpbmRleCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YodGhpcy5fcHJlZml4KSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleS5zdWJzdHIodGhpcy5fcHJlZml4Lmxlbmd0aCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGtleXMpO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IGp3cywgS0VZVVRJTCBhcyBLZXlVdGlsLCBYNTA5LCBjcnlwdG8sIGhleHRvYjY0dSwgYjY0dG9oZXggfSBmcm9tICcuLi8uLi9qc3JzYXNpZ24vZGlzdC9qc3JzYXNpZ24uanMnO1xyXG5cclxuY29uc3QgQWxsb3dlZFNpZ25pbmdBbGdzID0gWydSUzI1NicsICdSUzM4NCcsICdSUzUxMicsICdQUzI1NicsICdQUzM4NCcsICdQUzUxMicsICdFUzI1NicsICdFUzM4NCcsICdFUzUxMiddO1xyXG5cclxuZXhwb3J0IHtcclxuICAgIGp3cyxcclxuICAgIEtleVV0aWwsXHJcbiAgICBYNTA5LFxyXG4gICAgY3J5cHRvLFxyXG4gICAgaGV4dG9iNjR1LFxyXG4gICAgYjY0dG9oZXgsXHJcbiAgICBBbGxvd2VkU2lnbmluZ0FsZ3NcclxufTtcclxuIiwiaW1wb3J0IHV1aWQ0IGZyb20gJ3V1aWQvdjQnO1xyXG5cclxuLyoqXHJcbiAqIEdlbmVyYXRlcyBSRkM0MTIyIHZlcnNpb24gNCBndWlkICgpXHJcbiAqL1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmFuZG9tKCkge1xyXG4gIHJldHVybiB1dWlkNCgpLnJlcGxhY2UoLy0vZywgJycpO1xyXG59XHJcbiIsImNvbnN0IFZlcnNpb24gPSBcIjEuMTAuMVwiOyBleHBvcnQge1ZlcnNpb259OyJdLCJzb3VyY2VSb290IjoiIn0="
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/libs/oidc-client.rsa256.slim.js",
    "content": "var Oidc =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ \"./index.js\":\n/*!******************!*\\\n  !*** ./index.js ***!\n  \\******************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _Log = __webpack_require__(/*! ./src/Log.js */ \"./src/Log.js\");\n\nvar _OidcClient = __webpack_require__(/*! ./src/OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./src/OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./src/WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _InMemoryWebStorage = __webpack_require__(/*! ./src/InMemoryWebStorage.js */ \"./src/InMemoryWebStorage.js\");\n\nvar _UserManager = __webpack_require__(/*! ./src/UserManager.js */ \"./src/UserManager.js\");\n\nvar _AccessTokenEvents = __webpack_require__(/*! ./src/AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./src/MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _CordovaPopupNavigator = __webpack_require__(/*! ./src/CordovaPopupNavigator.js */ \"./src/CordovaPopupNavigator.js\");\n\nvar _CordovaIFrameNavigator = __webpack_require__(/*! ./src/CordovaIFrameNavigator.js */ \"./src/CordovaIFrameNavigator.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./src/CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./src/TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./src/SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _Global = __webpack_require__(/*! ./src/Global.js */ \"./src/Global.js\");\n\nvar _User = __webpack_require__(/*! ./src/User.js */ \"./src/User.js\");\n\nvar _version = __webpack_require__(/*! ./version.js */ \"./version.js\");\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nexports.default = {\n    Version: _version.Version,\n    Log: _Log.Log,\n    OidcClient: _OidcClient.OidcClient,\n    OidcClientSettings: _OidcClientSettings.OidcClientSettings,\n    WebStorageStateStore: _WebStorageStateStore.WebStorageStateStore,\n    InMemoryWebStorage: _InMemoryWebStorage.InMemoryWebStorage,\n    UserManager: _UserManager.UserManager,\n    AccessTokenEvents: _AccessTokenEvents.AccessTokenEvents,\n    MetadataService: _MetadataService.MetadataService,\n    CordovaPopupNavigator: _CordovaPopupNavigator.CordovaPopupNavigator,\n    CordovaIFrameNavigator: _CordovaIFrameNavigator.CordovaIFrameNavigator,\n    CheckSessionIFrame: _CheckSessionIFrame.CheckSessionIFrame,\n    TokenRevocationClient: _TokenRevocationClient.TokenRevocationClient,\n    SessionMonitor: _SessionMonitor.SessionMonitor,\n    Global: _Global.Global,\n    User: _User.User\n};\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./node_modules/base64-js/index.js\":\n/*!*****************************************!*\\\n  !*** ./node_modules/base64-js/index.js ***!\n  \\*****************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  var validLen = b64.indexOf('=')\n  if (validLen === -1) validLen = len\n\n  var placeHoldersLen = validLen === len\n    ? 0\n    : 4 - (validLen % 4)\n\n  return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n  var tmp\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n\n  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n  var curByte = 0\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  var len = placeHoldersLen > 0\n    ? validLen - 4\n    : validLen\n\n  for (var i = 0; i < len; i += 4) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 18) |\n      (revLookup[b64.charCodeAt(i + 1)] << 12) |\n      (revLookup[b64.charCodeAt(i + 2)] << 6) |\n      revLookup[b64.charCodeAt(i + 3)]\n    arr[curByte++] = (tmp >> 16) & 0xFF\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 2) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 2) |\n      (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 1) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 10) |\n      (revLookup[b64.charCodeAt(i + 1)] << 4) |\n      (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] +\n    lookup[num >> 12 & 0x3F] +\n    lookup[num >> 6 & 0x3F] +\n    lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp =\n      ((uint8[i] << 16) & 0xFF0000) +\n      ((uint8[i + 1] << 8) & 0xFF00) +\n      (uint8[i + 2] & 0xFF)\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(\n      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n    ))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 2] +\n      lookup[(tmp << 4) & 0x3F] +\n      '=='\n    )\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 10] +\n      lookup[(tmp >> 4) & 0x3F] +\n      lookup[(tmp << 2) & 0x3F] +\n      '='\n    )\n  }\n\n  return parts.join('')\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/es6/promise.js\":\n/*!*********************************************!*\\\n  !*** ./node_modules/core-js/es6/promise.js ***!\n  \\*********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../modules/es6.object.to-string */ \"./node_modules/core-js/modules/es6.object.to-string.js\");\n__webpack_require__(/*! ../modules/es6.string.iterator */ \"./node_modules/core-js/modules/es6.string.iterator.js\");\n__webpack_require__(/*! ../modules/web.dom.iterable */ \"./node_modules/core-js/modules/web.dom.iterable.js\");\n__webpack_require__(/*! ../modules/es6.promise */ \"./node_modules/core-js/modules/es6.promise.js\");\nmodule.exports = __webpack_require__(/*! ../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Promise;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/find.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/fn/array/find.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.array.find */ \"./node_modules/core-js/modules/es6.array.find.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Array.find;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/is-array.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/fn/array/is-array.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.array.is-array */ \"./node_modules/core-js/modules/es6.array.is-array.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Array.isArray;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/some.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/fn/array/some.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.array.some */ \"./node_modules/core-js/modules/es6.array.some.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Array.some;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/splice.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/fn/array/splice.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// for a legacy code and future fixes\nmodule.exports = function () {\n  return Function.call.apply(Array.prototype.splice, arguments);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/function/bind.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/fn/function/bind.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.function.bind */ \"./node_modules/core-js/modules/es6.function.bind.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Function.bind;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/object/assign.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/fn/object/assign.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.object.assign */ \"./node_modules/core-js/modules/es6.object.assign.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Object.assign;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_a-function.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_a-function.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_add-to-unscopables.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_add-to-unscopables.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.31 Array.prototype[@@unscopables]\nvar UNSCOPABLES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('unscopables');\nvar ArrayProto = Array.prototype;\nif (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(ArrayProto, UNSCOPABLES, {});\nmodule.exports = function (key) {\n  ArrayProto[UNSCOPABLES][key] = true;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-instance.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-instance.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it, Constructor, name, forbiddenField) {\n  if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {\n    throw TypeError(name + ': incorrect invocation!');\n  } return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nmodule.exports = function (it) {\n  if (!isObject(it)) throw TypeError(it + ' is not an object!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-includes.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-includes.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// false -> Array#indexOf\n// true  -> Array#includes\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nmodule.exports = function (IS_INCLUDES) {\n  return function ($this, el, fromIndex) {\n    var O = toIObject($this);\n    var length = toLength(O.length);\n    var index = toAbsoluteIndex(fromIndex, length);\n    var value;\n    // Array#includes uses SameValueZero equality algorithm\n    // eslint-disable-next-line no-self-compare\n    if (IS_INCLUDES && el != el) while (length > index) {\n      value = O[index++];\n      // eslint-disable-next-line no-self-compare\n      if (value != value) return true;\n    // Array#indexOf ignores holes, Array#includes - not\n    } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n      if (O[index] === el) return IS_INCLUDES || index || 0;\n    } return !IS_INCLUDES && -1;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-methods.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-methods.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 0 -> Array#forEach\n// 1 -> Array#map\n// 2 -> Array#filter\n// 3 -> Array#some\n// 4 -> Array#every\n// 5 -> Array#find\n// 6 -> Array#findIndex\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar asc = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\nmodule.exports = function (TYPE, $create) {\n  var IS_MAP = TYPE == 1;\n  var IS_FILTER = TYPE == 2;\n  var IS_SOME = TYPE == 3;\n  var IS_EVERY = TYPE == 4;\n  var IS_FIND_INDEX = TYPE == 6;\n  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;\n  var create = $create || asc;\n  return function ($this, callbackfn, that) {\n    var O = toObject($this);\n    var self = IObject(O);\n    var f = ctx(callbackfn, that, 3);\n    var length = toLength(self.length);\n    var index = 0;\n    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;\n    var val, res;\n    for (;length > index; index++) if (NO_HOLES || index in self) {\n      val = self[index];\n      res = f(val, index, O);\n      if (TYPE) {\n        if (IS_MAP) result[index] = res;   // map\n        else if (res) switch (TYPE) {\n          case 3: return true;             // some\n          case 5: return val;              // find\n          case 6: return index;            // findIndex\n          case 2: result.push(val);        // filter\n        } else if (IS_EVERY) return false; // every\n      }\n    }\n    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-constructor.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-constructor.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (original) {\n  var C;\n  if (isArray(original)) {\n    C = original.constructor;\n    // cross-realm fallback\n    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;\n    if (isObject(C)) {\n      C = C[SPECIES];\n      if (C === null) C = undefined;\n    }\n  } return C === undefined ? Array : C;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-create.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-create.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 9.4.2.3 ArraySpeciesCreate(originalArray, length)\nvar speciesConstructor = __webpack_require__(/*! ./_array-species-constructor */ \"./node_modules/core-js/modules/_array-species-constructor.js\");\n\nmodule.exports = function (original, length) {\n  return new (speciesConstructor(original))(length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_bind.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_bind.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar arraySlice = [].slice;\nvar factories = {};\n\nvar construct = function (F, len, args) {\n  if (!(len in factories)) {\n    for (var n = [], i = 0; i < len; i++) n[i] = 'a[' + i + ']';\n    // eslint-disable-next-line no-new-func\n    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');\n  } return factories[len](F, args);\n};\n\nmodule.exports = Function.bind || function bind(that /* , ...args */) {\n  var fn = aFunction(this);\n  var partArgs = arraySlice.call(arguments, 1);\n  var bound = function (/* args... */) {\n    var args = partArgs.concat(arraySlice.call(arguments));\n    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);\n  };\n  if (isObject(fn.prototype)) bound.prototype = fn.prototype;\n  return bound;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_classof.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_classof.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n  try {\n    return it[key];\n  } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n  var O, T, B;\n  return it === undefined ? 'Undefined' : it === null ? 'Null'\n    // @@toStringTag case\n    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n    // builtinTag case\n    : ARG ? cof(O)\n    // ES3 arguments fallback\n    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_cof.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_cof.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = function (it) {\n  return toString.call(it).slice(8, -1);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_core.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_core.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar core = module.exports = { version: '2.6.4' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ctx.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_ctx.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// optional / simple context binding\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nmodule.exports = function (fn, that, length) {\n  aFunction(fn);\n  if (that === undefined) return fn;\n  switch (length) {\n    case 1: return function (a) {\n      return fn.call(that, a);\n    };\n    case 2: return function (a, b) {\n      return fn.call(that, a, b);\n    };\n    case 3: return function (a, b, c) {\n      return fn.call(that, a, b, c);\n    };\n  }\n  return function (/* ...args */) {\n    return fn.apply(that, arguments);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_defined.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_defined.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n  if (it == undefined) throw TypeError(\"Can't call method on  \" + it);\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_descriptors.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_descriptors.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_dom-create.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_dom-create.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n  return is ? document.createElement(it) : {};\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_enum-bug-keys.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_enum-bug-keys.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// IE 8- don't enum bug keys\nmodule.exports = (\n  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_export.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_export.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n  var IS_FORCED = type & $export.F;\n  var IS_GLOBAL = type & $export.G;\n  var IS_STATIC = type & $export.S;\n  var IS_PROTO = type & $export.P;\n  var IS_BIND = type & $export.B;\n  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n  var key, own, out, exp;\n  if (IS_GLOBAL) source = name;\n  for (key in source) {\n    // contains in native\n    own = !IS_FORCED && target && target[key] !== undefined;\n    // export native or passed\n    out = (own ? target : source)[key];\n    // bind timers to global for call from export context\n    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n    // extend global\n    if (target) redefine(target, key, out, type & $export.U);\n    // export\n    if (exports[key] != out) hide(exports, key, exp);\n    if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n  }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1;   // forced\n$export.G = 2;   // global\n$export.S = 4;   // static\n$export.P = 8;   // proto\n$export.B = 16;  // bind\n$export.W = 32;  // wrap\n$export.U = 64;  // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fails.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fails.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return !!exec();\n  } catch (e) {\n    return true;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_for-of.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_for-of.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar call = __webpack_require__(/*! ./_iter-call */ \"./node_modules/core-js/modules/_iter-call.js\");\nvar isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\nvar BREAK = {};\nvar RETURN = {};\nvar exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {\n  var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);\n  var f = ctx(fn, that, entries ? 2 : 1);\n  var index = 0;\n  var length, step, iterator, result;\n  if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');\n  // fast case for arrays with default iterator\n  if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {\n    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n    if (result === BREAK || result === RETURN) return result;\n  } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {\n    result = call(iterator, f, step.value, entries);\n    if (result === BREAK || result === RETURN) return result;\n  }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_function-to-string.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_function-to-string.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('native-function-to-string', Function.toString);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_global.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_global.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n  ? window : typeof self != 'undefined' && self.Math == Math ? self\n  // eslint-disable-next-line no-new-func\n  : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_has.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_has.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n  return hasOwnProperty.call(it, key);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_hide.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_hide.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? function (object, key, value) {\n  return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n  object[key] = value;\n  return object;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_html.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_html.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\nmodule.exports = document && document.documentElement;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ie8-dom-define.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_ie8-dom-define.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_invoke.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_invoke.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function (fn, args, that) {\n  var un = that === undefined;\n  switch (args.length) {\n    case 0: return un ? fn()\n                      : fn.call(that);\n    case 1: return un ? fn(args[0])\n                      : fn.call(that, args[0]);\n    case 2: return un ? fn(args[0], args[1])\n                      : fn.call(that, args[0], args[1]);\n    case 3: return un ? fn(args[0], args[1], args[2])\n                      : fn.call(that, args[0], args[1], args[2]);\n    case 4: return un ? fn(args[0], args[1], args[2], args[3])\n                      : fn.call(that, args[0], args[1], args[2], args[3]);\n  } return fn.apply(that, args);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iobject.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iobject.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n  return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array-iter.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array-iter.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// check on default Array iterator\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar ArrayProto = Array.prototype;\n\nmodule.exports = function (it) {\n  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.2.2 IsArray(argument)\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nmodule.exports = Array.isArray || function isArray(arg) {\n  return cof(arg) == 'Array';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-call.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-call.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// call something on iterator step with safe closing on error\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nmodule.exports = function (iterator, fn, value, entries) {\n  try {\n    return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n  // 7.4.6 IteratorClose(iterator, completion)\n  } catch (e) {\n    var ret = iterator['return'];\n    if (ret !== undefined) anObject(ret.call(iterator));\n    throw e;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-create.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-create.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar descriptor = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\n__webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(IteratorPrototype, __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n  Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n  setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-define.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-define.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar $iterCreate = __webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n  $iterCreate(Constructor, NAME, next);\n  var getMethod = function (kind) {\n    if (!BUGGY && kind in proto) return proto[kind];\n    switch (kind) {\n      case KEYS: return function keys() { return new Constructor(this, kind); };\n      case VALUES: return function values() { return new Constructor(this, kind); };\n    } return function entries() { return new Constructor(this, kind); };\n  };\n  var TAG = NAME + ' Iterator';\n  var DEF_VALUES = DEFAULT == VALUES;\n  var VALUES_BUG = false;\n  var proto = Base.prototype;\n  var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n  var $default = $native || getMethod(DEFAULT);\n  var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n  var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n  var methods, key, IteratorPrototype;\n  // Fix native\n  if ($anyNative) {\n    IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n    if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n      // Set @@toStringTag to native iterators\n      setToStringTag(IteratorPrototype, TAG, true);\n      // fix for some old engines\n      if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n    }\n  }\n  // fix Array#{values, @@iterator}.name in V8 / FF\n  if (DEF_VALUES && $native && $native.name !== VALUES) {\n    VALUES_BUG = true;\n    $default = function values() { return $native.call(this); };\n  }\n  // Define iterator\n  if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n    hide(proto, ITERATOR, $default);\n  }\n  // Plug for library\n  Iterators[NAME] = $default;\n  Iterators[TAG] = returnThis;\n  if (DEFAULT) {\n    methods = {\n      values: DEF_VALUES ? $default : getMethod(VALUES),\n      keys: IS_SET ? $default : getMethod(KEYS),\n      entries: $entries\n    };\n    if (FORCED) for (key in methods) {\n      if (!(key in proto)) redefine(proto, key, methods[key]);\n    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n  }\n  return methods;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-detect.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-detect.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n  var riter = [7][ITERATOR]();\n  riter['return'] = function () { SAFE_CLOSING = true; };\n  // eslint-disable-next-line no-throw-literal\n  Array.from(riter, function () { throw 2; });\n} catch (e) { /* empty */ }\n\nmodule.exports = function (exec, skipClosing) {\n  if (!skipClosing && !SAFE_CLOSING) return false;\n  var safe = false;\n  try {\n    var arr = [7];\n    var iter = arr[ITERATOR]();\n    iter.next = function () { return { done: safe = true }; };\n    arr[ITERATOR] = function () { return iter; };\n    exec(arr);\n  } catch (e) { /* empty */ }\n  return safe;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-step.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-step.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (done, value) {\n  return { value: value, done: !!done };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iterators.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iterators.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = {};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_library.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_library.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = false;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_microtask.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_microtask.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar macrotask = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar Observer = global.MutationObserver || global.WebKitMutationObserver;\nvar process = global.process;\nvar Promise = global.Promise;\nvar isNode = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process';\n\nmodule.exports = function () {\n  var head, last, notify;\n\n  var flush = function () {\n    var parent, fn;\n    if (isNode && (parent = process.domain)) parent.exit();\n    while (head) {\n      fn = head.fn;\n      head = head.next;\n      try {\n        fn();\n      } catch (e) {\n        if (head) notify();\n        else last = undefined;\n        throw e;\n      }\n    } last = undefined;\n    if (parent) parent.enter();\n  };\n\n  // Node.js\n  if (isNode) {\n    notify = function () {\n      process.nextTick(flush);\n    };\n  // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339\n  } else if (Observer && !(global.navigator && global.navigator.standalone)) {\n    var toggle = true;\n    var node = document.createTextNode('');\n    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new\n    notify = function () {\n      node.data = toggle = !toggle;\n    };\n  // environments with maybe non-completely correct, but existent Promise\n  } else if (Promise && Promise.resolve) {\n    // Promise.resolve without an argument throws an error in LG WebOS 2\n    var promise = Promise.resolve(undefined);\n    notify = function () {\n      promise.then(flush);\n    };\n  // for other environments - macrotask based on:\n  // - setImmediate\n  // - MessageChannel\n  // - window.postMessag\n  // - onreadystatechange\n  // - setTimeout\n  } else {\n    notify = function () {\n      // strange IE + webpack dev server bug - use .call(global)\n      macrotask.call(global, flush);\n    };\n  }\n\n  return function (fn) {\n    var task = { fn: fn, next: undefined };\n    if (last) last.next = task;\n    if (!head) {\n      head = task;\n      notify();\n    } last = task;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_new-promise-capability.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_new-promise-capability.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 25.4.1.5 NewPromiseCapability(C)\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\n\nfunction PromiseCapability(C) {\n  var resolve, reject;\n  this.promise = new C(function ($$resolve, $$reject) {\n    if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n    resolve = $$resolve;\n    reject = $$reject;\n  });\n  this.resolve = aFunction(resolve);\n  this.reject = aFunction(reject);\n}\n\nmodule.exports.f = function (C) {\n  return new PromiseCapability(C);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-assign.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-assign.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  var A = {};\n  var B = {};\n  // eslint-disable-next-line no-undef\n  var S = Symbol();\n  var K = 'abcdefghijklmnopqrst';\n  A[S] = 7;\n  K.split('').forEach(function (k) { B[k] = k; });\n  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source) { // eslint-disable-line no-unused-vars\n  var T = toObject(target);\n  var aLen = arguments.length;\n  var index = 1;\n  var getSymbols = gOPS.f;\n  var isEnum = pIE.f;\n  while (aLen > index) {\n    var S = IObject(arguments[index++]);\n    var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);\n    var length = keys.length;\n    var j = 0;\n    var key;\n    while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];\n  } return T;\n} : $assign;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-create.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-create.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar dPs = __webpack_require__(/*! ./_object-dps */ \"./node_modules/core-js/modules/_object-dps.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n  // Thrash, waste and sodomy: IE GC bug\n  var iframe = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('iframe');\n  var i = enumBugKeys.length;\n  var lt = '<';\n  var gt = '>';\n  var iframeDocument;\n  iframe.style.display = 'none';\n  __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\").appendChild(iframe);\n  iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n  // createDict = iframe.contentWindow.Object;\n  // html.removeChild(iframe);\n  iframeDocument = iframe.contentWindow.document;\n  iframeDocument.open();\n  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n  iframeDocument.close();\n  createDict = iframeDocument.F;\n  while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n  return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n  var result;\n  if (O !== null) {\n    Empty[PROTOTYPE] = anObject(O);\n    result = new Empty();\n    Empty[PROTOTYPE] = null;\n    // add \"__proto__\" for Object.getPrototypeOf polyfill\n    result[IE_PROTO] = O;\n  } else result = createDict();\n  return Properties === undefined ? result : dPs(result, Properties);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dp.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dp.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ \"./node_modules/core-js/modules/_ie8-dom-define.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar dP = Object.defineProperty;\n\nexports.f = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n  anObject(O);\n  P = toPrimitive(P, true);\n  anObject(Attributes);\n  if (IE8_DOM_DEFINE) try {\n    return dP(O, P, Attributes);\n  } catch (e) { /* empty */ }\n  if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n  if ('value' in Attributes) O[P] = Attributes.value;\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dps.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dps.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\n\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperties : function defineProperties(O, Properties) {\n  anObject(O);\n  var keys = getKeys(Properties);\n  var length = keys.length;\n  var i = 0;\n  var P;\n  while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gops.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gops.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = Object.getOwnPropertySymbols;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gpo.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gpo.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n  O = toObject(O);\n  if (has(O, IE_PROTO)) return O[IE_PROTO];\n  if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n    return O.constructor.prototype;\n  } return O instanceof Object ? ObjectProto : null;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys-internal.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys-internal.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar arrayIndexOf = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(false);\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\n\nmodule.exports = function (object, names) {\n  var O = toIObject(object);\n  var i = 0;\n  var result = [];\n  var key;\n  for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n  // Don't enum bug & hidden keys\n  while (names.length > i) if (has(O, key = names[i++])) {\n    ~arrayIndexOf(result, key) || result.push(key);\n  }\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = __webpack_require__(/*! ./_object-keys-internal */ \"./node_modules/core-js/modules/_object-keys-internal.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\n\nmodule.exports = Object.keys || function keys(O) {\n  return $keys(O, enumBugKeys);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-pie.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-pie.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = {}.propertyIsEnumerable;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_perform.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_perform.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return { e: false, v: exec() };\n  } catch (e) {\n    return { e: true, v: e };\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_promise-resolve.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_promise-resolve.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar newPromiseCapability = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\n\nmodule.exports = function (C, x) {\n  anObject(C);\n  if (isObject(x) && x.constructor === C) return x;\n  var promiseCapability = newPromiseCapability.f(C);\n  var resolve = promiseCapability.resolve;\n  resolve(x);\n  return promiseCapability.promise;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_property-desc.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_property-desc.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (bitmap, value) {\n  return {\n    enumerable: !(bitmap & 1),\n    configurable: !(bitmap & 2),\n    writable: !(bitmap & 4),\n    value: value\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine-all.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine-all.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nmodule.exports = function (target, src, safe) {\n  for (var key in src) redefine(target, key, src[key], safe);\n  return target;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar SRC = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\")('src');\nvar $toString = __webpack_require__(/*! ./_function-to-string */ \"./node_modules/core-js/modules/_function-to-string.js\");\nvar TO_STRING = 'toString';\nvar TPL = ('' + $toString).split(TO_STRING);\n\n__webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").inspectSource = function (it) {\n  return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n  var isFunction = typeof val == 'function';\n  if (isFunction) has(val, 'name') || hide(val, 'name', key);\n  if (O[key] === val) return;\n  if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n  if (O === global) {\n    O[key] = val;\n  } else if (!safe) {\n    delete O[key];\n    hide(O, key, val);\n  } else if (O[key]) {\n    O[key] = val;\n  } else {\n    hide(O, key, val);\n  }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n  return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-species.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-species.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (KEY) {\n  var C = global[KEY];\n  if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {\n    configurable: true,\n    get: function () { return this; }\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-to-string-tag.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-to-string-tag.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar def = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n  if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared-key.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared-key.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('keys');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nmodule.exports = function (key) {\n  return shared[key] || (shared[key] = uid(key));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n  return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n  version: core.version,\n  mode: __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\") ? 'pure' : 'global',\n  copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_species-constructor.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_species-constructor.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\nmodule.exports = function (O, D) {\n  var C = anObject(O).constructor;\n  var S;\n  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_strict-method.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_strict-method.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\n\nmodule.exports = function (method, arg) {\n  return !!method && fails(function () {\n    // eslint-disable-next-line no-useless-call\n    arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-at.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-at.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n// true  -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n  return function (that, pos) {\n    var s = String(defined(that));\n    var i = toInteger(pos);\n    var l = s.length;\n    var a, b;\n    if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n    a = s.charCodeAt(i);\n    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n      ? TO_STRING ? s.charAt(i) : a\n      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_task.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_task.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar html = __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\");\nvar cel = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar process = global.process;\nvar setTask = global.setImmediate;\nvar clearTask = global.clearImmediate;\nvar MessageChannel = global.MessageChannel;\nvar Dispatch = global.Dispatch;\nvar counter = 0;\nvar queue = {};\nvar ONREADYSTATECHANGE = 'onreadystatechange';\nvar defer, channel, port;\nvar run = function () {\n  var id = +this;\n  // eslint-disable-next-line no-prototype-builtins\n  if (queue.hasOwnProperty(id)) {\n    var fn = queue[id];\n    delete queue[id];\n    fn();\n  }\n};\nvar listener = function (event) {\n  run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif (!setTask || !clearTask) {\n  setTask = function setImmediate(fn) {\n    var args = [];\n    var i = 1;\n    while (arguments.length > i) args.push(arguments[i++]);\n    queue[++counter] = function () {\n      // eslint-disable-next-line no-new-func\n      invoke(typeof fn == 'function' ? fn : Function(fn), args);\n    };\n    defer(counter);\n    return counter;\n  };\n  clearTask = function clearImmediate(id) {\n    delete queue[id];\n  };\n  // Node.js 0.8-\n  if (__webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process') {\n    defer = function (id) {\n      process.nextTick(ctx(run, id, 1));\n    };\n  // Sphere (JS game engine) Dispatch API\n  } else if (Dispatch && Dispatch.now) {\n    defer = function (id) {\n      Dispatch.now(ctx(run, id, 1));\n    };\n  // Browsers with MessageChannel, includes WebWorkers\n  } else if (MessageChannel) {\n    channel = new MessageChannel();\n    port = channel.port2;\n    channel.port1.onmessage = listener;\n    defer = ctx(port.postMessage, port, 1);\n  // Browsers with postMessage, skip WebWorkers\n  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n  } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {\n    defer = function (id) {\n      global.postMessage(id + '', '*');\n    };\n    global.addEventListener('message', listener, false);\n  // IE8-\n  } else if (ONREADYSTATECHANGE in cel('script')) {\n    defer = function (id) {\n      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {\n        html.removeChild(this);\n        run.call(id);\n      };\n    };\n  // Rest old browsers\n  } else {\n    defer = function (id) {\n      setTimeout(ctx(run, id, 1), 0);\n    };\n  }\n}\nmodule.exports = {\n  set: setTask,\n  clear: clearTask\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-absolute-index.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-absolute-index.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n  index = toInteger(index);\n  return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-integer.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-integer.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-iobject.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-iobject.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return IObject(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-length.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-length.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.15 ToLength\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar min = Math.min;\nmodule.exports = function (it) {\n  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.13 ToObject(argument)\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return Object(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-primitive.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-primitive.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n  if (!isObject(it)) return it;\n  var fn, val;\n  if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_uid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_uid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_user-agent.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_user-agent.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar store = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('wks');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar Symbol = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n  return store[name] || (store[name] =\n    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/core.get-iterator-method.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/core.get-iterator-method.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nmodule.exports = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").getIteratorMethod = function (it) {\n  if (it != undefined) return it[ITERATOR]\n    || it['@@iterator']\n    || Iterators[classof(it)];\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.find.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.find.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $find = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(5);\nvar KEY = 'find';\nvar forced = true;\n// Shouldn't skip holes\nif (KEY in []) Array(1)[KEY](function () { forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  find: function find(callbackfn /* , that = undefined */) {\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")(KEY);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.is-array.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.is-array.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Array', { isArray: __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.iterator.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.iterator.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar addToUnscopables = __webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\");\nvar step = __webpack_require__(/*! ./_iter-step */ \"./node_modules/core-js/modules/_iter-step.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = __webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(Array, 'Array', function (iterated, kind) {\n  this._t = toIObject(iterated); // target\n  this._i = 0;                   // next index\n  this._k = kind;                // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var kind = this._k;\n  var index = this._i++;\n  if (!O || index >= O.length) {\n    this._t = undefined;\n    return step(1);\n  }\n  if (kind == 'keys') return step(0, index);\n  if (kind == 'values') return step(0, O[index]);\n  return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.some.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.some.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $some = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(3);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].some, true), 'Array', {\n  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])\n  some: function some(callbackfn /* , thisArg */) {\n    return $some(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.bind.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.bind.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Function', { bind: __webpack_require__(/*! ./_bind */ \"./node_modules/core-js/modules/_bind.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.assign.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.assign.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.1 Object.assign(target, source)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S + $export.F, 'Object', { assign: __webpack_require__(/*! ./_object-assign */ \"./node_modules/core-js/modules/_object-assign.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.to-string.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.to-string.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.3.6 Object.prototype.toString()\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar test = {};\ntest[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag')] = 'z';\nif (test + '' != '[object z]') {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(Object.prototype, 'toString', function toString() {\n    return '[object ' + classof(this) + ']';\n  }, true);\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.promise.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.promise.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar task = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar newPromiseCapabilityModule = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\nvar perform = __webpack_require__(/*! ./_perform */ \"./node_modules/core-js/modules/_perform.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\nvar promiseResolve = __webpack_require__(/*! ./_promise-resolve */ \"./node_modules/core-js/modules/_promise-resolve.js\");\nvar PROMISE = 'Promise';\nvar TypeError = global.TypeError;\nvar process = global.process;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8 || '';\nvar $Promise = global[PROMISE];\nvar isNode = classof(process) == 'process';\nvar empty = function () { /* empty */ };\nvar Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;\nvar newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;\n\nvar USE_NATIVE = !!function () {\n  try {\n    // correct subclassing with @@species support\n    var promise = $Promise.resolve(1);\n    var FakePromise = (promise.constructor = {})[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species')] = function (exec) {\n      exec(empty, empty);\n    };\n    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n    return (isNode || typeof PromiseRejectionEvent == 'function')\n      && promise.then(empty) instanceof FakePromise\n      // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables\n      // https://bugs.chromium.org/p/chromium/issues/detail?id=830565\n      // we can't detect it synchronously, so just check versions\n      && v8.indexOf('6.6') !== 0\n      && userAgent.indexOf('Chrome/66') === -1;\n  } catch (e) { /* empty */ }\n}();\n\n// helpers\nvar isThenable = function (it) {\n  var then;\n  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar notify = function (promise, isReject) {\n  if (promise._n) return;\n  promise._n = true;\n  var chain = promise._c;\n  microtask(function () {\n    var value = promise._v;\n    var ok = promise._s == 1;\n    var i = 0;\n    var run = function (reaction) {\n      var handler = ok ? reaction.ok : reaction.fail;\n      var resolve = reaction.resolve;\n      var reject = reaction.reject;\n      var domain = reaction.domain;\n      var result, then, exited;\n      try {\n        if (handler) {\n          if (!ok) {\n            if (promise._h == 2) onHandleUnhandled(promise);\n            promise._h = 1;\n          }\n          if (handler === true) result = value;\n          else {\n            if (domain) domain.enter();\n            result = handler(value); // may throw\n            if (domain) {\n              domain.exit();\n              exited = true;\n            }\n          }\n          if (result === reaction.promise) {\n            reject(TypeError('Promise-chain cycle'));\n          } else if (then = isThenable(result)) {\n            then.call(result, resolve, reject);\n          } else resolve(result);\n        } else reject(value);\n      } catch (e) {\n        if (domain && !exited) domain.exit();\n        reject(e);\n      }\n    };\n    while (chain.length > i) run(chain[i++]); // variable length - can't use forEach\n    promise._c = [];\n    promise._n = false;\n    if (isReject && !promise._h) onUnhandled(promise);\n  });\n};\nvar onUnhandled = function (promise) {\n  task.call(global, function () {\n    var value = promise._v;\n    var unhandled = isUnhandled(promise);\n    var result, handler, console;\n    if (unhandled) {\n      result = perform(function () {\n        if (isNode) {\n          process.emit('unhandledRejection', value, promise);\n        } else if (handler = global.onunhandledrejection) {\n          handler({ promise: promise, reason: value });\n        } else if ((console = global.console) && console.error) {\n          console.error('Unhandled promise rejection', value);\n        }\n      });\n      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n      promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n    } promise._a = undefined;\n    if (unhandled && result.e) throw result.v;\n  });\n};\nvar isUnhandled = function (promise) {\n  return promise._h !== 1 && (promise._a || promise._c).length === 0;\n};\nvar onHandleUnhandled = function (promise) {\n  task.call(global, function () {\n    var handler;\n    if (isNode) {\n      process.emit('rejectionHandled', promise);\n    } else if (handler = global.onrejectionhandled) {\n      handler({ promise: promise, reason: promise._v });\n    }\n  });\n};\nvar $reject = function (value) {\n  var promise = this;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  promise._v = value;\n  promise._s = 2;\n  if (!promise._a) promise._a = promise._c.slice();\n  notify(promise, true);\n};\nvar $resolve = function (value) {\n  var promise = this;\n  var then;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  try {\n    if (promise === value) throw TypeError(\"Promise can't be resolved itself\");\n    if (then = isThenable(value)) {\n      microtask(function () {\n        var wrapper = { _w: promise, _d: false }; // wrap\n        try {\n          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n        } catch (e) {\n          $reject.call(wrapper, e);\n        }\n      });\n    } else {\n      promise._v = value;\n      promise._s = 1;\n      notify(promise, false);\n    }\n  } catch (e) {\n    $reject.call({ _w: promise, _d: false }, e); // wrap\n  }\n};\n\n// constructor polyfill\nif (!USE_NATIVE) {\n  // 25.4.3.1 Promise(executor)\n  $Promise = function Promise(executor) {\n    anInstance(this, $Promise, PROMISE, '_h');\n    aFunction(executor);\n    Internal.call(this);\n    try {\n      executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n    } catch (err) {\n      $reject.call(this, err);\n    }\n  };\n  // eslint-disable-next-line no-unused-vars\n  Internal = function Promise(executor) {\n    this._c = [];             // <- awaiting reactions\n    this._a = undefined;      // <- checked in isUnhandled reactions\n    this._s = 0;              // <- state\n    this._d = false;          // <- done\n    this._v = undefined;      // <- value\n    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n    this._n = false;          // <- notify\n  };\n  Internal.prototype = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\")($Promise.prototype, {\n    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n    then: function then(onFulfilled, onRejected) {\n      var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n      reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n      reaction.fail = typeof onRejected == 'function' && onRejected;\n      reaction.domain = isNode ? process.domain : undefined;\n      this._c.push(reaction);\n      if (this._a) this._a.push(reaction);\n      if (this._s) notify(this, false);\n      return reaction.promise;\n    },\n    // 25.4.5.1 Promise.prototype.catch(onRejected)\n    'catch': function (onRejected) {\n      return this.then(undefined, onRejected);\n    }\n  });\n  OwnPromiseCapability = function () {\n    var promise = new Internal();\n    this.promise = promise;\n    this.resolve = ctx($resolve, promise, 1);\n    this.reject = ctx($reject, promise, 1);\n  };\n  newPromiseCapabilityModule.f = newPromiseCapability = function (C) {\n    return C === $Promise || C === Wrapper\n      ? new OwnPromiseCapability(C)\n      : newGenericPromiseCapability(C);\n  };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });\n__webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\")($Promise, PROMISE);\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")(PROMISE);\nWrapper = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\")[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n  // 25.4.4.5 Promise.reject(r)\n  reject: function reject(r) {\n    var capability = newPromiseCapability(this);\n    var $$reject = capability.reject;\n    $$reject(r);\n    return capability.promise;\n  }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n  // 25.4.4.6 Promise.resolve(x)\n  resolve: function resolve(x) {\n    return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);\n  }\n});\n$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\")(function (iter) {\n  $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n  // 25.4.4.1 Promise.all(iterable)\n  all: function all(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var resolve = capability.resolve;\n    var reject = capability.reject;\n    var result = perform(function () {\n      var values = [];\n      var index = 0;\n      var remaining = 1;\n      forOf(iterable, false, function (promise) {\n        var $index = index++;\n        var alreadyCalled = false;\n        values.push(undefined);\n        remaining++;\n        C.resolve(promise).then(function (value) {\n          if (alreadyCalled) return;\n          alreadyCalled = true;\n          values[$index] = value;\n          --remaining || resolve(values);\n        }, reject);\n      });\n      --remaining || resolve(values);\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  },\n  // 25.4.4.4 Promise.race(iterable)\n  race: function race(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var reject = capability.reject;\n    var result = perform(function () {\n      forOf(iterable, false, function (promise) {\n        C.resolve(promise).then(capability.resolve, reject);\n      });\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.iterator.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.iterator.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\n__webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(String, 'String', function (iterated) {\n  this._t = String(iterated); // target\n  this._i = 0;                // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var index = this._i;\n  var point;\n  if (index >= O.length) return { value: undefined, done: true };\n  point = $at(O, index);\n  this._i += point.length;\n  return { value: point, done: false };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.dom.iterable.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.dom.iterable.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $iterators = __webpack_require__(/*! ./es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar ITERATOR = wks('iterator');\nvar TO_STRING_TAG = wks('toStringTag');\nvar ArrayValues = Iterators.Array;\n\nvar DOMIterables = {\n  CSSRuleList: true, // TODO: Not spec compliant, should be false.\n  CSSStyleDeclaration: false,\n  CSSValueList: false,\n  ClientRectList: false,\n  DOMRectList: false,\n  DOMStringList: false,\n  DOMTokenList: true,\n  DataTransferItemList: false,\n  FileList: false,\n  HTMLAllCollection: false,\n  HTMLCollection: false,\n  HTMLFormElement: false,\n  HTMLSelectElement: false,\n  MediaList: true, // TODO: Not spec compliant, should be false.\n  MimeTypeArray: false,\n  NamedNodeMap: false,\n  NodeList: true,\n  PaintRequestList: false,\n  Plugin: false,\n  PluginArray: false,\n  SVGLengthList: false,\n  SVGNumberList: false,\n  SVGPathSegList: false,\n  SVGPointList: false,\n  SVGStringList: false,\n  SVGTransformList: false,\n  SourceBufferList: false,\n  StyleSheetList: true, // TODO: Not spec compliant, should be false.\n  TextTrackCueList: false,\n  TextTrackList: false,\n  TouchList: false\n};\n\nfor (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {\n  var NAME = collections[i];\n  var explicit = DOMIterables[NAME];\n  var Collection = global[NAME];\n  var proto = Collection && Collection.prototype;\n  var key;\n  if (proto) {\n    if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);\n    if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n    Iterators[NAME] = ArrayValues;\n    if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);\n  }\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/crypto-js/core.js\":\n/*!****************************************!*\\\n  !*** ./node_modules/crypto-js/core.js ***!\n  \\****************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n;(function (root, factory) {\n\tif (true) {\n\t\t// CommonJS\n\t\tmodule.exports = exports = factory();\n\t}\n\telse {}\n}(this, function () {\n\n\t/**\n\t * CryptoJS core components.\n\t */\n\tvar CryptoJS = CryptoJS || (function (Math, undefined) {\n\t    /*\n\t     * Local polyfil of Object.create\n\t     */\n\t    var create = Object.create || (function () {\n\t        function F() {};\n\n\t        return function (obj) {\n\t            var subtype;\n\n\t            F.prototype = obj;\n\n\t            subtype = new F();\n\n\t            F.prototype = null;\n\n\t            return subtype;\n\t        };\n\t    }())\n\n\t    /**\n\t     * CryptoJS namespace.\n\t     */\n\t    var C = {};\n\n\t    /**\n\t     * Library namespace.\n\t     */\n\t    var C_lib = C.lib = {};\n\n\t    /**\n\t     * Base object for prototypal inheritance.\n\t     */\n\t    var Base = C_lib.Base = (function () {\n\n\n\t        return {\n\t            /**\n\t             * Creates a new object that inherits from this object.\n\t             *\n\t             * @param {Object} overrides Properties to copy into the new object.\n\t             *\n\t             * @return {Object} The new object.\n\t             *\n\t             * @static\n\t             *\n\t             * @example\n\t             *\n\t             *     var MyType = CryptoJS.lib.Base.extend({\n\t             *         field: 'value',\n\t             *\n\t             *         method: function () {\n\t             *         }\n\t             *     });\n\t             */\n\t            extend: function (overrides) {\n\t                // Spawn\n\t                var subtype = create(this);\n\n\t                // Augment\n\t                if (overrides) {\n\t                    subtype.mixIn(overrides);\n\t                }\n\n\t                // Create default initializer\n\t                if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {\n\t                    subtype.init = function () {\n\t                        subtype.$super.init.apply(this, arguments);\n\t                    };\n\t                }\n\n\t                // Initializer's prototype is the subtype object\n\t                subtype.init.prototype = subtype;\n\n\t                // Reference supertype\n\t                subtype.$super = this;\n\n\t                return subtype;\n\t            },\n\n\t            /**\n\t             * Extends this object and runs the init method.\n\t             * Arguments to create() will be passed to init().\n\t             *\n\t             * @return {Object} The new object.\n\t             *\n\t             * @static\n\t             *\n\t             * @example\n\t             *\n\t             *     var instance = MyType.create();\n\t             */\n\t            create: function () {\n\t                var instance = this.extend();\n\t                instance.init.apply(instance, arguments);\n\n\t                return instance;\n\t            },\n\n\t            /**\n\t             * Initializes a newly created object.\n\t             * Override this method to add some logic when your objects are created.\n\t             *\n\t             * @example\n\t             *\n\t             *     var MyType = CryptoJS.lib.Base.extend({\n\t             *         init: function () {\n\t             *             // ...\n\t             *         }\n\t             *     });\n\t             */\n\t            init: function () {\n\t            },\n\n\t            /**\n\t             * Copies properties into this object.\n\t             *\n\t             * @param {Object} properties The properties to mix in.\n\t             *\n\t             * @example\n\t             *\n\t             *     MyType.mixIn({\n\t             *         field: 'value'\n\t             *     });\n\t             */\n\t            mixIn: function (properties) {\n\t                for (var propertyName in properties) {\n\t                    if (properties.hasOwnProperty(propertyName)) {\n\t                        this[propertyName] = properties[propertyName];\n\t                    }\n\t                }\n\n\t                // IE won't copy toString using the loop above\n\t                if (properties.hasOwnProperty('toString')) {\n\t                    this.toString = properties.toString;\n\t                }\n\t            },\n\n\t            /**\n\t             * Creates a copy of this object.\n\t             *\n\t             * @return {Object} The clone.\n\t             *\n\t             * @example\n\t             *\n\t             *     var clone = instance.clone();\n\t             */\n\t            clone: function () {\n\t                return this.init.prototype.extend(this);\n\t            }\n\t        };\n\t    }());\n\n\t    /**\n\t     * An array of 32-bit words.\n\t     *\n\t     * @property {Array} words The array of 32-bit words.\n\t     * @property {number} sigBytes The number of significant bytes in this word array.\n\t     */\n\t    var WordArray = C_lib.WordArray = Base.extend({\n\t        /**\n\t         * Initializes a newly created word array.\n\t         *\n\t         * @param {Array} words (Optional) An array of 32-bit words.\n\t         * @param {number} sigBytes (Optional) The number of significant bytes in the words.\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.lib.WordArray.create();\n\t         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);\n\t         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);\n\t         */\n\t        init: function (words, sigBytes) {\n\t            words = this.words = words || [];\n\n\t            if (sigBytes != undefined) {\n\t                this.sigBytes = sigBytes;\n\t            } else {\n\t                this.sigBytes = words.length * 4;\n\t            }\n\t        },\n\n\t        /**\n\t         * Converts this word array to a string.\n\t         *\n\t         * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex\n\t         *\n\t         * @return {string} The stringified word array.\n\t         *\n\t         * @example\n\t         *\n\t         *     var string = wordArray + '';\n\t         *     var string = wordArray.toString();\n\t         *     var string = wordArray.toString(CryptoJS.enc.Utf8);\n\t         */\n\t        toString: function (encoder) {\n\t            return (encoder || Hex).stringify(this);\n\t        },\n\n\t        /**\n\t         * Concatenates a word array to this word array.\n\t         *\n\t         * @param {WordArray} wordArray The word array to append.\n\t         *\n\t         * @return {WordArray} This word array.\n\t         *\n\t         * @example\n\t         *\n\t         *     wordArray1.concat(wordArray2);\n\t         */\n\t        concat: function (wordArray) {\n\t            // Shortcuts\n\t            var thisWords = this.words;\n\t            var thatWords = wordArray.words;\n\t            var thisSigBytes = this.sigBytes;\n\t            var thatSigBytes = wordArray.sigBytes;\n\n\t            // Clamp excess bits\n\t            this.clamp();\n\n\t            // Concat\n\t            if (thisSigBytes % 4) {\n\t                // Copy one byte at a time\n\t                for (var i = 0; i < thatSigBytes; i++) {\n\t                    var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n\t                    thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);\n\t                }\n\t            } else {\n\t                // Copy one word at a time\n\t                for (var i = 0; i < thatSigBytes; i += 4) {\n\t                    thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];\n\t                }\n\t            }\n\t            this.sigBytes += thatSigBytes;\n\n\t            // Chainable\n\t            return this;\n\t        },\n\n\t        /**\n\t         * Removes insignificant bits.\n\t         *\n\t         * @example\n\t         *\n\t         *     wordArray.clamp();\n\t         */\n\t        clamp: function () {\n\t            // Shortcuts\n\t            var words = this.words;\n\t            var sigBytes = this.sigBytes;\n\n\t            // Clamp\n\t            words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);\n\t            words.length = Math.ceil(sigBytes / 4);\n\t        },\n\n\t        /**\n\t         * Creates a copy of this word array.\n\t         *\n\t         * @return {WordArray} The clone.\n\t         *\n\t         * @example\n\t         *\n\t         *     var clone = wordArray.clone();\n\t         */\n\t        clone: function () {\n\t            var clone = Base.clone.call(this);\n\t            clone.words = this.words.slice(0);\n\n\t            return clone;\n\t        },\n\n\t        /**\n\t         * Creates a word array filled with random bytes.\n\t         *\n\t         * @param {number} nBytes The number of random bytes to generate.\n\t         *\n\t         * @return {WordArray} The random word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.lib.WordArray.random(16);\n\t         */\n\t        random: function (nBytes) {\n\t            var words = [];\n\n\t            var r = (function (m_w) {\n\t                var m_w = m_w;\n\t                var m_z = 0x3ade68b1;\n\t                var mask = 0xffffffff;\n\n\t                return function () {\n\t                    m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;\n\t                    m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;\n\t                    var result = ((m_z << 0x10) + m_w) & mask;\n\t                    result /= 0x100000000;\n\t                    result += 0.5;\n\t                    return result * (Math.random() > .5 ? 1 : -1);\n\t                }\n\t            });\n\n\t            for (var i = 0, rcache; i < nBytes; i += 4) {\n\t                var _r = r((rcache || Math.random()) * 0x100000000);\n\n\t                rcache = _r() * 0x3ade67b7;\n\t                words.push((_r() * 0x100000000) | 0);\n\t            }\n\n\t            return new WordArray.init(words, nBytes);\n\t        }\n\t    });\n\n\t    /**\n\t     * Encoder namespace.\n\t     */\n\t    var C_enc = C.enc = {};\n\n\t    /**\n\t     * Hex encoding strategy.\n\t     */\n\t    var Hex = C_enc.Hex = {\n\t        /**\n\t         * Converts a word array to a hex string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The hex string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            // Shortcuts\n\t            var words = wordArray.words;\n\t            var sigBytes = wordArray.sigBytes;\n\n\t            // Convert\n\t            var hexChars = [];\n\t            for (var i = 0; i < sigBytes; i++) {\n\t                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n\t                hexChars.push((bite >>> 4).toString(16));\n\t                hexChars.push((bite & 0x0f).toString(16));\n\t            }\n\n\t            return hexChars.join('');\n\t        },\n\n\t        /**\n\t         * Converts a hex string to a word array.\n\t         *\n\t         * @param {string} hexStr The hex string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Hex.parse(hexString);\n\t         */\n\t        parse: function (hexStr) {\n\t            // Shortcut\n\t            var hexStrLength = hexStr.length;\n\n\t            // Convert\n\t            var words = [];\n\t            for (var i = 0; i < hexStrLength; i += 2) {\n\t                words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);\n\t            }\n\n\t            return new WordArray.init(words, hexStrLength / 2);\n\t        }\n\t    };\n\n\t    /**\n\t     * Latin1 encoding strategy.\n\t     */\n\t    var Latin1 = C_enc.Latin1 = {\n\t        /**\n\t         * Converts a word array to a Latin1 string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The Latin1 string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            // Shortcuts\n\t            var words = wordArray.words;\n\t            var sigBytes = wordArray.sigBytes;\n\n\t            // Convert\n\t            var latin1Chars = [];\n\t            for (var i = 0; i < sigBytes; i++) {\n\t                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;\n\t                latin1Chars.push(String.fromCharCode(bite));\n\t            }\n\n\t            return latin1Chars.join('');\n\t        },\n\n\t        /**\n\t         * Converts a Latin1 string to a word array.\n\t         *\n\t         * @param {string} latin1Str The Latin1 string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);\n\t         */\n\t        parse: function (latin1Str) {\n\t            // Shortcut\n\t            var latin1StrLength = latin1Str.length;\n\n\t            // Convert\n\t            var words = [];\n\t            for (var i = 0; i < latin1StrLength; i++) {\n\t                words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);\n\t            }\n\n\t            return new WordArray.init(words, latin1StrLength);\n\t        }\n\t    };\n\n\t    /**\n\t     * UTF-8 encoding strategy.\n\t     */\n\t    var Utf8 = C_enc.Utf8 = {\n\t        /**\n\t         * Converts a word array to a UTF-8 string.\n\t         *\n\t         * @param {WordArray} wordArray The word array.\n\t         *\n\t         * @return {string} The UTF-8 string.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);\n\t         */\n\t        stringify: function (wordArray) {\n\t            try {\n\t                return decodeURIComponent(escape(Latin1.stringify(wordArray)));\n\t            } catch (e) {\n\t                throw new Error('Malformed UTF-8 data');\n\t            }\n\t        },\n\n\t        /**\n\t         * Converts a UTF-8 string to a word array.\n\t         *\n\t         * @param {string} utf8Str The UTF-8 string.\n\t         *\n\t         * @return {WordArray} The word array.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);\n\t         */\n\t        parse: function (utf8Str) {\n\t            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));\n\t        }\n\t    };\n\n\t    /**\n\t     * Abstract buffered block algorithm template.\n\t     *\n\t     * The property blockSize must be implemented in a concrete subtype.\n\t     *\n\t     * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0\n\t     */\n\t    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({\n\t        /**\n\t         * Resets this block algorithm's data buffer to its initial state.\n\t         *\n\t         * @example\n\t         *\n\t         *     bufferedBlockAlgorithm.reset();\n\t         */\n\t        reset: function () {\n\t            // Initial values\n\t            this._data = new WordArray.init();\n\t            this._nDataBytes = 0;\n\t        },\n\n\t        /**\n\t         * Adds new data to this block algorithm's buffer.\n\t         *\n\t         * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.\n\t         *\n\t         * @example\n\t         *\n\t         *     bufferedBlockAlgorithm._append('data');\n\t         *     bufferedBlockAlgorithm._append(wordArray);\n\t         */\n\t        _append: function (data) {\n\t            // Convert string to WordArray, else assume WordArray already\n\t            if (typeof data == 'string') {\n\t                data = Utf8.parse(data);\n\t            }\n\n\t            // Append\n\t            this._data.concat(data);\n\t            this._nDataBytes += data.sigBytes;\n\t        },\n\n\t        /**\n\t         * Processes available data blocks.\n\t         *\n\t         * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.\n\t         *\n\t         * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.\n\t         *\n\t         * @return {WordArray} The processed data.\n\t         *\n\t         * @example\n\t         *\n\t         *     var processedData = bufferedBlockAlgorithm._process();\n\t         *     var processedData = bufferedBlockAlgorithm._process(!!'flush');\n\t         */\n\t        _process: function (doFlush) {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\t            var dataSigBytes = data.sigBytes;\n\t            var blockSize = this.blockSize;\n\t            var blockSizeBytes = blockSize * 4;\n\n\t            // Count blocks ready\n\t            var nBlocksReady = dataSigBytes / blockSizeBytes;\n\t            if (doFlush) {\n\t                // Round up to include partial blocks\n\t                nBlocksReady = Math.ceil(nBlocksReady);\n\t            } else {\n\t                // Round down to include only full blocks,\n\t                // less the number of blocks that must remain in the buffer\n\t                nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);\n\t            }\n\n\t            // Count words ready\n\t            var nWordsReady = nBlocksReady * blockSize;\n\n\t            // Count bytes ready\n\t            var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);\n\n\t            // Process blocks\n\t            if (nWordsReady) {\n\t                for (var offset = 0; offset < nWordsReady; offset += blockSize) {\n\t                    // Perform concrete-algorithm logic\n\t                    this._doProcessBlock(dataWords, offset);\n\t                }\n\n\t                // Remove processed words\n\t                var processedWords = dataWords.splice(0, nWordsReady);\n\t                data.sigBytes -= nBytesReady;\n\t            }\n\n\t            // Return processed words\n\t            return new WordArray.init(processedWords, nBytesReady);\n\t        },\n\n\t        /**\n\t         * Creates a copy of this object.\n\t         *\n\t         * @return {Object} The clone.\n\t         *\n\t         * @example\n\t         *\n\t         *     var clone = bufferedBlockAlgorithm.clone();\n\t         */\n\t        clone: function () {\n\t            var clone = Base.clone.call(this);\n\t            clone._data = this._data.clone();\n\n\t            return clone;\n\t        },\n\n\t        _minBufferSize: 0\n\t    });\n\n\t    /**\n\t     * Abstract hasher template.\n\t     *\n\t     * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)\n\t     */\n\t    var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({\n\t        /**\n\t         * Configuration options.\n\t         */\n\t        cfg: Base.extend(),\n\n\t        /**\n\t         * Initializes a newly created hasher.\n\t         *\n\t         * @param {Object} cfg (Optional) The configuration options to use for this hash computation.\n\t         *\n\t         * @example\n\t         *\n\t         *     var hasher = CryptoJS.algo.SHA256.create();\n\t         */\n\t        init: function (cfg) {\n\t            // Apply config defaults\n\t            this.cfg = this.cfg.extend(cfg);\n\n\t            // Set initial values\n\t            this.reset();\n\t        },\n\n\t        /**\n\t         * Resets this hasher to its initial state.\n\t         *\n\t         * @example\n\t         *\n\t         *     hasher.reset();\n\t         */\n\t        reset: function () {\n\t            // Reset data buffer\n\t            BufferedBlockAlgorithm.reset.call(this);\n\n\t            // Perform concrete-hasher logic\n\t            this._doReset();\n\t        },\n\n\t        /**\n\t         * Updates this hasher with a message.\n\t         *\n\t         * @param {WordArray|string} messageUpdate The message to append.\n\t         *\n\t         * @return {Hasher} This hasher.\n\t         *\n\t         * @example\n\t         *\n\t         *     hasher.update('message');\n\t         *     hasher.update(wordArray);\n\t         */\n\t        update: function (messageUpdate) {\n\t            // Append\n\t            this._append(messageUpdate);\n\n\t            // Update the hash\n\t            this._process();\n\n\t            // Chainable\n\t            return this;\n\t        },\n\n\t        /**\n\t         * Finalizes the hash computation.\n\t         * Note that the finalize operation is effectively a destructive, read-once operation.\n\t         *\n\t         * @param {WordArray|string} messageUpdate (Optional) A final message update.\n\t         *\n\t         * @return {WordArray} The hash.\n\t         *\n\t         * @example\n\t         *\n\t         *     var hash = hasher.finalize();\n\t         *     var hash = hasher.finalize('message');\n\t         *     var hash = hasher.finalize(wordArray);\n\t         */\n\t        finalize: function (messageUpdate) {\n\t            // Final message update\n\t            if (messageUpdate) {\n\t                this._append(messageUpdate);\n\t            }\n\n\t            // Perform concrete-hasher logic\n\t            var hash = this._doFinalize();\n\n\t            return hash;\n\t        },\n\n\t        blockSize: 512/32,\n\n\t        /**\n\t         * Creates a shortcut function to a hasher's object interface.\n\t         *\n\t         * @param {Hasher} hasher The hasher to create a helper for.\n\t         *\n\t         * @return {Function} The shortcut function.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);\n\t         */\n\t        _createHelper: function (hasher) {\n\t            return function (message, cfg) {\n\t                return new hasher.init(cfg).finalize(message);\n\t            };\n\t        },\n\n\t        /**\n\t         * Creates a shortcut function to the HMAC's object interface.\n\t         *\n\t         * @param {Hasher} hasher The hasher to use in this HMAC helper.\n\t         *\n\t         * @return {Function} The shortcut function.\n\t         *\n\t         * @static\n\t         *\n\t         * @example\n\t         *\n\t         *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);\n\t         */\n\t        _createHmacHelper: function (hasher) {\n\t            return function (message, key) {\n\t                return new C_algo.HMAC.init(hasher, key).finalize(message);\n\t            };\n\t        }\n\t    });\n\n\t    /**\n\t     * Algorithm namespace.\n\t     */\n\t    var C_algo = C.algo = {};\n\n\t    return C;\n\t}(Math));\n\n\n\treturn CryptoJS;\n\n}));\n\n/***/ }),\n\n/***/ \"./node_modules/crypto-js/sha256.js\":\n/*!******************************************!*\\\n  !*** ./node_modules/crypto-js/sha256.js ***!\n  \\******************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n;(function (root, factory) {\n\tif (true) {\n\t\t// CommonJS\n\t\tmodule.exports = exports = factory(__webpack_require__(/*! ./core */ \"./node_modules/crypto-js/core.js\"));\n\t}\n\telse {}\n}(this, function (CryptoJS) {\n\n\t(function (Math) {\n\t    // Shortcuts\n\t    var C = CryptoJS;\n\t    var C_lib = C.lib;\n\t    var WordArray = C_lib.WordArray;\n\t    var Hasher = C_lib.Hasher;\n\t    var C_algo = C.algo;\n\n\t    // Initialization and round constants tables\n\t    var H = [];\n\t    var K = [];\n\n\t    // Compute constants\n\t    (function () {\n\t        function isPrime(n) {\n\t            var sqrtN = Math.sqrt(n);\n\t            for (var factor = 2; factor <= sqrtN; factor++) {\n\t                if (!(n % factor)) {\n\t                    return false;\n\t                }\n\t            }\n\n\t            return true;\n\t        }\n\n\t        function getFractionalBits(n) {\n\t            return ((n - (n | 0)) * 0x100000000) | 0;\n\t        }\n\n\t        var n = 2;\n\t        var nPrime = 0;\n\t        while (nPrime < 64) {\n\t            if (isPrime(n)) {\n\t                if (nPrime < 8) {\n\t                    H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));\n\t                }\n\t                K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));\n\n\t                nPrime++;\n\t            }\n\n\t            n++;\n\t        }\n\t    }());\n\n\t    // Reusable object\n\t    var W = [];\n\n\t    /**\n\t     * SHA-256 hash algorithm.\n\t     */\n\t    var SHA256 = C_algo.SHA256 = Hasher.extend({\n\t        _doReset: function () {\n\t            this._hash = new WordArray.init(H.slice(0));\n\t        },\n\n\t        _doProcessBlock: function (M, offset) {\n\t            // Shortcut\n\t            var H = this._hash.words;\n\n\t            // Working variables\n\t            var a = H[0];\n\t            var b = H[1];\n\t            var c = H[2];\n\t            var d = H[3];\n\t            var e = H[4];\n\t            var f = H[5];\n\t            var g = H[6];\n\t            var h = H[7];\n\n\t            // Computation\n\t            for (var i = 0; i < 64; i++) {\n\t                if (i < 16) {\n\t                    W[i] = M[offset + i] | 0;\n\t                } else {\n\t                    var gamma0x = W[i - 15];\n\t                    var gamma0  = ((gamma0x << 25) | (gamma0x >>> 7))  ^\n\t                                  ((gamma0x << 14) | (gamma0x >>> 18)) ^\n\t                                   (gamma0x >>> 3);\n\n\t                    var gamma1x = W[i - 2];\n\t                    var gamma1  = ((gamma1x << 15) | (gamma1x >>> 17)) ^\n\t                                  ((gamma1x << 13) | (gamma1x >>> 19)) ^\n\t                                   (gamma1x >>> 10);\n\n\t                    W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];\n\t                }\n\n\t                var ch  = (e & f) ^ (~e & g);\n\t                var maj = (a & b) ^ (a & c) ^ (b & c);\n\n\t                var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));\n\t                var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7)  | (e >>> 25));\n\n\t                var t1 = h + sigma1 + ch + K[i] + W[i];\n\t                var t2 = sigma0 + maj;\n\n\t                h = g;\n\t                g = f;\n\t                f = e;\n\t                e = (d + t1) | 0;\n\t                d = c;\n\t                c = b;\n\t                b = a;\n\t                a = (t1 + t2) | 0;\n\t            }\n\n\t            // Intermediate hash value\n\t            H[0] = (H[0] + a) | 0;\n\t            H[1] = (H[1] + b) | 0;\n\t            H[2] = (H[2] + c) | 0;\n\t            H[3] = (H[3] + d) | 0;\n\t            H[4] = (H[4] + e) | 0;\n\t            H[5] = (H[5] + f) | 0;\n\t            H[6] = (H[6] + g) | 0;\n\t            H[7] = (H[7] + h) | 0;\n\t        },\n\n\t        _doFinalize: function () {\n\t            // Shortcuts\n\t            var data = this._data;\n\t            var dataWords = data.words;\n\n\t            var nBitsTotal = this._nDataBytes * 8;\n\t            var nBitsLeft = data.sigBytes * 8;\n\n\t            // Add padding\n\t            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);\n\t            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;\n\t            data.sigBytes = dataWords.length * 4;\n\n\t            // Hash final blocks\n\t            this._process();\n\n\t            // Return final computed hash\n\t            return this._hash;\n\t        },\n\n\t        clone: function () {\n\t            var clone = Hasher.clone.call(this);\n\t            clone._hash = this._hash.clone();\n\n\t            return clone;\n\t        }\n\t    });\n\n\t    /**\n\t     * Shortcut function to the hasher's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     *\n\t     * @return {WordArray} The hash.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hash = CryptoJS.SHA256('message');\n\t     *     var hash = CryptoJS.SHA256(wordArray);\n\t     */\n\t    C.SHA256 = Hasher._createHelper(SHA256);\n\n\t    /**\n\t     * Shortcut function to the HMAC's object interface.\n\t     *\n\t     * @param {WordArray|string} message The message to hash.\n\t     * @param {WordArray|string} key The secret key.\n\t     *\n\t     * @return {WordArray} The HMAC.\n\t     *\n\t     * @static\n\t     *\n\t     * @example\n\t     *\n\t     *     var hmac = CryptoJS.HmacSHA256(message, key);\n\t     */\n\t    C.HmacSHA256 = Hasher._createHmacHelper(SHA256);\n\t}(Math));\n\n\n\treturn CryptoJS.SHA256;\n\n}));\n\n/***/ }),\n\n/***/ \"./node_modules/jsbn/index.js\":\n/*!************************************!*\\\n  !*** ./node_modules/jsbn/index.js ***!\n  \\************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n(function(){\n\n    // Copyright (c) 2005  Tom Wu\n    // All Rights Reserved.\n    // See \"LICENSE\" for details.\n\n    // Basic JavaScript BN library - subset useful for RSA encryption.\n\n    // Bits per digit\n    var dbits;\n\n    // JavaScript engine analysis\n    var canary = 0xdeadbeefcafe;\n    var j_lm = ((canary&0xffffff)==0xefcafe);\n\n    // (public) Constructor\n    function BigInteger(a,b,c) {\n      if(a != null)\n        if(\"number\" == typeof a) this.fromNumber(a,b,c);\n        else if(b == null && \"string\" != typeof a) this.fromString(a,256);\n        else this.fromString(a,b);\n    }\n\n    // return new, unset BigInteger\n    function nbi() { return new BigInteger(null); }\n\n    // am: Compute w_j += (x*this_i), propagate carries,\n    // c is initial carry, returns final carry.\n    // c < 3*dvalue, x < 2*dvalue, this_i < dvalue\n    // We need to select the fastest one that works in this environment.\n\n    // am1: use a single mult and divide to get the high bits,\n    // max digit bits should be 26 because\n    // max internal value = 2*dvalue^2-2*dvalue (< 2^53)\n    function am1(i,x,w,j,c,n) {\n      while(--n >= 0) {\n        var v = x*this[i++]+w[j]+c;\n        c = Math.floor(v/0x4000000);\n        w[j++] = v&0x3ffffff;\n      }\n      return c;\n    }\n    // am2 avoids a big mult-and-extract completely.\n    // Max digit bits should be <= 30 because we do bitwise ops\n    // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)\n    function am2(i,x,w,j,c,n) {\n      var xl = x&0x7fff, xh = x>>15;\n      while(--n >= 0) {\n        var l = this[i]&0x7fff;\n        var h = this[i++]>>15;\n        var m = xh*l+h*xl;\n        l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);\n        c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);\n        w[j++] = l&0x3fffffff;\n      }\n      return c;\n    }\n    // Alternately, set max digit bits to 28 since some\n    // browsers slow down when dealing with 32-bit numbers.\n    function am3(i,x,w,j,c,n) {\n      var xl = x&0x3fff, xh = x>>14;\n      while(--n >= 0) {\n        var l = this[i]&0x3fff;\n        var h = this[i++]>>14;\n        var m = xh*l+h*xl;\n        l = xl*l+((m&0x3fff)<<14)+w[j]+c;\n        c = (l>>28)+(m>>14)+xh*h;\n        w[j++] = l&0xfffffff;\n      }\n      return c;\n    }\n    var inBrowser = typeof navigator !== \"undefined\";\n    if(inBrowser && j_lm && (navigator.appName == \"Microsoft Internet Explorer\")) {\n      BigInteger.prototype.am = am2;\n      dbits = 30;\n    }\n    else if(inBrowser && j_lm && (navigator.appName != \"Netscape\")) {\n      BigInteger.prototype.am = am1;\n      dbits = 26;\n    }\n    else { // Mozilla/Netscape seems to prefer am3\n      BigInteger.prototype.am = am3;\n      dbits = 28;\n    }\n\n    BigInteger.prototype.DB = dbits;\n    BigInteger.prototype.DM = ((1<<dbits)-1);\n    BigInteger.prototype.DV = (1<<dbits);\n\n    var BI_FP = 52;\n    BigInteger.prototype.FV = Math.pow(2,BI_FP);\n    BigInteger.prototype.F1 = BI_FP-dbits;\n    BigInteger.prototype.F2 = 2*dbits-BI_FP;\n\n    // Digit conversions\n    var BI_RM = \"0123456789abcdefghijklmnopqrstuvwxyz\";\n    var BI_RC = new Array();\n    var rr,vv;\n    rr = \"0\".charCodeAt(0);\n    for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;\n    rr = \"a\".charCodeAt(0);\n    for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;\n    rr = \"A\".charCodeAt(0);\n    for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;\n\n    function int2char(n) { return BI_RM.charAt(n); }\n    function intAt(s,i) {\n      var c = BI_RC[s.charCodeAt(i)];\n      return (c==null)?-1:c;\n    }\n\n    // (protected) copy this to r\n    function bnpCopyTo(r) {\n      for(var i = this.t-1; i >= 0; --i) r[i] = this[i];\n      r.t = this.t;\n      r.s = this.s;\n    }\n\n    // (protected) set from integer value x, -DV <= x < DV\n    function bnpFromInt(x) {\n      this.t = 1;\n      this.s = (x<0)?-1:0;\n      if(x > 0) this[0] = x;\n      else if(x < -1) this[0] = x+this.DV;\n      else this.t = 0;\n    }\n\n    // return bigint initialized to value\n    function nbv(i) { var r = nbi(); r.fromInt(i); return r; }\n\n    // (protected) set from string and radix\n    function bnpFromString(s,b) {\n      var k;\n      if(b == 16) k = 4;\n      else if(b == 8) k = 3;\n      else if(b == 256) k = 8; // byte array\n      else if(b == 2) k = 1;\n      else if(b == 32) k = 5;\n      else if(b == 4) k = 2;\n      else { this.fromRadix(s,b); return; }\n      this.t = 0;\n      this.s = 0;\n      var i = s.length, mi = false, sh = 0;\n      while(--i >= 0) {\n        var x = (k==8)?s[i]&0xff:intAt(s,i);\n        if(x < 0) {\n          if(s.charAt(i) == \"-\") mi = true;\n          continue;\n        }\n        mi = false;\n        if(sh == 0)\n          this[this.t++] = x;\n        else if(sh+k > this.DB) {\n          this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;\n          this[this.t++] = (x>>(this.DB-sh));\n        }\n        else\n          this[this.t-1] |= x<<sh;\n        sh += k;\n        if(sh >= this.DB) sh -= this.DB;\n      }\n      if(k == 8 && (s[0]&0x80) != 0) {\n        this.s = -1;\n        if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;\n      }\n      this.clamp();\n      if(mi) BigInteger.ZERO.subTo(this,this);\n    }\n\n    // (protected) clamp off excess high words\n    function bnpClamp() {\n      var c = this.s&this.DM;\n      while(this.t > 0 && this[this.t-1] == c) --this.t;\n    }\n\n    // (public) return string representation in given radix\n    function bnToString(b) {\n      if(this.s < 0) return \"-\"+this.negate().toString(b);\n      var k;\n      if(b == 16) k = 4;\n      else if(b == 8) k = 3;\n      else if(b == 2) k = 1;\n      else if(b == 32) k = 5;\n      else if(b == 4) k = 2;\n      else return this.toRadix(b);\n      var km = (1<<k)-1, d, m = false, r = \"\", i = this.t;\n      var p = this.DB-(i*this.DB)%k;\n      if(i-- > 0) {\n        if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }\n        while(i >= 0) {\n          if(p < k) {\n            d = (this[i]&((1<<p)-1))<<(k-p);\n            d |= this[--i]>>(p+=this.DB-k);\n          }\n          else {\n            d = (this[i]>>(p-=k))&km;\n            if(p <= 0) { p += this.DB; --i; }\n          }\n          if(d > 0) m = true;\n          if(m) r += int2char(d);\n        }\n      }\n      return m?r:\"0\";\n    }\n\n    // (public) -this\n    function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }\n\n    // (public) |this|\n    function bnAbs() { return (this.s<0)?this.negate():this; }\n\n    // (public) return + if this > a, - if this < a, 0 if equal\n    function bnCompareTo(a) {\n      var r = this.s-a.s;\n      if(r != 0) return r;\n      var i = this.t;\n      r = i-a.t;\n      if(r != 0) return (this.s<0)?-r:r;\n      while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;\n      return 0;\n    }\n\n    // returns bit length of the integer x\n    function nbits(x) {\n      var r = 1, t;\n      if((t=x>>>16) != 0) { x = t; r += 16; }\n      if((t=x>>8) != 0) { x = t; r += 8; }\n      if((t=x>>4) != 0) { x = t; r += 4; }\n      if((t=x>>2) != 0) { x = t; r += 2; }\n      if((t=x>>1) != 0) { x = t; r += 1; }\n      return r;\n    }\n\n    // (public) return the number of bits in \"this\"\n    function bnBitLength() {\n      if(this.t <= 0) return 0;\n      return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));\n    }\n\n    // (protected) r = this << n*DB\n    function bnpDLShiftTo(n,r) {\n      var i;\n      for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];\n      for(i = n-1; i >= 0; --i) r[i] = 0;\n      r.t = this.t+n;\n      r.s = this.s;\n    }\n\n    // (protected) r = this >> n*DB\n    function bnpDRShiftTo(n,r) {\n      for(var i = n; i < this.t; ++i) r[i-n] = this[i];\n      r.t = Math.max(this.t-n,0);\n      r.s = this.s;\n    }\n\n    // (protected) r = this << n\n    function bnpLShiftTo(n,r) {\n      var bs = n%this.DB;\n      var cbs = this.DB-bs;\n      var bm = (1<<cbs)-1;\n      var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;\n      for(i = this.t-1; i >= 0; --i) {\n        r[i+ds+1] = (this[i]>>cbs)|c;\n        c = (this[i]&bm)<<bs;\n      }\n      for(i = ds-1; i >= 0; --i) r[i] = 0;\n      r[ds] = c;\n      r.t = this.t+ds+1;\n      r.s = this.s;\n      r.clamp();\n    }\n\n    // (protected) r = this >> n\n    function bnpRShiftTo(n,r) {\n      r.s = this.s;\n      var ds = Math.floor(n/this.DB);\n      if(ds >= this.t) { r.t = 0; return; }\n      var bs = n%this.DB;\n      var cbs = this.DB-bs;\n      var bm = (1<<bs)-1;\n      r[0] = this[ds]>>bs;\n      for(var i = ds+1; i < this.t; ++i) {\n        r[i-ds-1] |= (this[i]&bm)<<cbs;\n        r[i-ds] = this[i]>>bs;\n      }\n      if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;\n      r.t = this.t-ds;\n      r.clamp();\n    }\n\n    // (protected) r = this - a\n    function bnpSubTo(a,r) {\n      var i = 0, c = 0, m = Math.min(a.t,this.t);\n      while(i < m) {\n        c += this[i]-a[i];\n        r[i++] = c&this.DM;\n        c >>= this.DB;\n      }\n      if(a.t < this.t) {\n        c -= a.s;\n        while(i < this.t) {\n          c += this[i];\n          r[i++] = c&this.DM;\n          c >>= this.DB;\n        }\n        c += this.s;\n      }\n      else {\n        c += this.s;\n        while(i < a.t) {\n          c -= a[i];\n          r[i++] = c&this.DM;\n          c >>= this.DB;\n        }\n        c -= a.s;\n      }\n      r.s = (c<0)?-1:0;\n      if(c < -1) r[i++] = this.DV+c;\n      else if(c > 0) r[i++] = c;\n      r.t = i;\n      r.clamp();\n    }\n\n    // (protected) r = this * a, r != this,a (HAC 14.12)\n    // \"this\" should be the larger one if appropriate.\n    function bnpMultiplyTo(a,r) {\n      var x = this.abs(), y = a.abs();\n      var i = x.t;\n      r.t = i+y.t;\n      while(--i >= 0) r[i] = 0;\n      for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);\n      r.s = 0;\n      r.clamp();\n      if(this.s != a.s) BigInteger.ZERO.subTo(r,r);\n    }\n\n    // (protected) r = this^2, r != this (HAC 14.16)\n    function bnpSquareTo(r) {\n      var x = this.abs();\n      var i = r.t = 2*x.t;\n      while(--i >= 0) r[i] = 0;\n      for(i = 0; i < x.t-1; ++i) {\n        var c = x.am(i,x[i],r,2*i,0,1);\n        if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {\n          r[i+x.t] -= x.DV;\n          r[i+x.t+1] = 1;\n        }\n      }\n      if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);\n      r.s = 0;\n      r.clamp();\n    }\n\n    // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)\n    // r != q, this != m.  q or r may be null.\n    function bnpDivRemTo(m,q,r) {\n      var pm = m.abs();\n      if(pm.t <= 0) return;\n      var pt = this.abs();\n      if(pt.t < pm.t) {\n        if(q != null) q.fromInt(0);\n        if(r != null) this.copyTo(r);\n        return;\n      }\n      if(r == null) r = nbi();\n      var y = nbi(), ts = this.s, ms = m.s;\n      var nsh = this.DB-nbits(pm[pm.t-1]);   // normalize modulus\n      if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }\n      else { pm.copyTo(y); pt.copyTo(r); }\n      var ys = y.t;\n      var y0 = y[ys-1];\n      if(y0 == 0) return;\n      var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);\n      var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;\n      var i = r.t, j = i-ys, t = (q==null)?nbi():q;\n      y.dlShiftTo(j,t);\n      if(r.compareTo(t) >= 0) {\n        r[r.t++] = 1;\n        r.subTo(t,r);\n      }\n      BigInteger.ONE.dlShiftTo(ys,t);\n      t.subTo(y,y);  // \"negative\" y so we can replace sub with am later\n      while(y.t < ys) y[y.t++] = 0;\n      while(--j >= 0) {\n        // Estimate quotient digit\n        var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);\n        if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {   // Try it out\n          y.dlShiftTo(j,t);\n          r.subTo(t,r);\n          while(r[i] < --qd) r.subTo(t,r);\n        }\n      }\n      if(q != null) {\n        r.drShiftTo(ys,q);\n        if(ts != ms) BigInteger.ZERO.subTo(q,q);\n      }\n      r.t = ys;\n      r.clamp();\n      if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder\n      if(ts < 0) BigInteger.ZERO.subTo(r,r);\n    }\n\n    // (public) this mod a\n    function bnMod(a) {\n      var r = nbi();\n      this.abs().divRemTo(a,null,r);\n      if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);\n      return r;\n    }\n\n    // Modular reduction using \"classic\" algorithm\n    function Classic(m) { this.m = m; }\n    function cConvert(x) {\n      if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);\n      else return x;\n    }\n    function cRevert(x) { return x; }\n    function cReduce(x) { x.divRemTo(this.m,null,x); }\n    function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\n    function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\n    Classic.prototype.convert = cConvert;\n    Classic.prototype.revert = cRevert;\n    Classic.prototype.reduce = cReduce;\n    Classic.prototype.mulTo = cMulTo;\n    Classic.prototype.sqrTo = cSqrTo;\n\n    // (protected) return \"-1/this % 2^DB\"; useful for Mont. reduction\n    // justification:\n    //         xy == 1 (mod m)\n    //         xy =  1+km\n    //   xy(2-xy) = (1+km)(1-km)\n    // x[y(2-xy)] = 1-k^2m^2\n    // x[y(2-xy)] == 1 (mod m^2)\n    // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2\n    // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.\n    // JS multiply \"overflows\" differently from C/C++, so care is needed here.\n    function bnpInvDigit() {\n      if(this.t < 1) return 0;\n      var x = this[0];\n      if((x&1) == 0) return 0;\n      var y = x&3;       // y == 1/x mod 2^2\n      y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4\n      y = (y*(2-(x&0xff)*y))&0xff;   // y == 1/x mod 2^8\n      y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;    // y == 1/x mod 2^16\n      // last step - calculate inverse mod DV directly;\n      // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints\n      y = (y*(2-x*y%this.DV))%this.DV;       // y == 1/x mod 2^dbits\n      // we really want the negative inverse, and -DV < y < DV\n      return (y>0)?this.DV-y:-y;\n    }\n\n    // Montgomery reduction\n    function Montgomery(m) {\n      this.m = m;\n      this.mp = m.invDigit();\n      this.mpl = this.mp&0x7fff;\n      this.mph = this.mp>>15;\n      this.um = (1<<(m.DB-15))-1;\n      this.mt2 = 2*m.t;\n    }\n\n    // xR mod m\n    function montConvert(x) {\n      var r = nbi();\n      x.abs().dlShiftTo(this.m.t,r);\n      r.divRemTo(this.m,null,r);\n      if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);\n      return r;\n    }\n\n    // x/R mod m\n    function montRevert(x) {\n      var r = nbi();\n      x.copyTo(r);\n      this.reduce(r);\n      return r;\n    }\n\n    // x = x/R mod m (HAC 14.32)\n    function montReduce(x) {\n      while(x.t <= this.mt2) // pad x so am has enough room later\n        x[x.t++] = 0;\n      for(var i = 0; i < this.m.t; ++i) {\n        // faster way of calculating u0 = x[i]*mp mod DV\n        var j = x[i]&0x7fff;\n        var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;\n        // use am to combine the multiply-shift-add into one call\n        j = i+this.m.t;\n        x[j] += this.m.am(0,u0,x,i,0,this.m.t);\n        // propagate carry\n        while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }\n      }\n      x.clamp();\n      x.drShiftTo(this.m.t,x);\n      if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);\n    }\n\n    // r = \"x^2/R mod m\"; x != r\n    function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\n    // r = \"xy/R mod m\"; x,y != r\n    function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\n\n    Montgomery.prototype.convert = montConvert;\n    Montgomery.prototype.revert = montRevert;\n    Montgomery.prototype.reduce = montReduce;\n    Montgomery.prototype.mulTo = montMulTo;\n    Montgomery.prototype.sqrTo = montSqrTo;\n\n    // (protected) true iff this is even\n    function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }\n\n    // (protected) this^e, e < 2^32, doing sqr and mul with \"r\" (HAC 14.79)\n    function bnpExp(e,z) {\n      if(e > 0xffffffff || e < 1) return BigInteger.ONE;\n      var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;\n      g.copyTo(r);\n      while(--i >= 0) {\n        z.sqrTo(r,r2);\n        if((e&(1<<i)) > 0) z.mulTo(r2,g,r);\n        else { var t = r; r = r2; r2 = t; }\n      }\n      return z.revert(r);\n    }\n\n    // (public) this^e % m, 0 <= e < 2^32\n    function bnModPowInt(e,m) {\n      var z;\n      if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);\n      return this.exp(e,z);\n    }\n\n    // protected\n    BigInteger.prototype.copyTo = bnpCopyTo;\n    BigInteger.prototype.fromInt = bnpFromInt;\n    BigInteger.prototype.fromString = bnpFromString;\n    BigInteger.prototype.clamp = bnpClamp;\n    BigInteger.prototype.dlShiftTo = bnpDLShiftTo;\n    BigInteger.prototype.drShiftTo = bnpDRShiftTo;\n    BigInteger.prototype.lShiftTo = bnpLShiftTo;\n    BigInteger.prototype.rShiftTo = bnpRShiftTo;\n    BigInteger.prototype.subTo = bnpSubTo;\n    BigInteger.prototype.multiplyTo = bnpMultiplyTo;\n    BigInteger.prototype.squareTo = bnpSquareTo;\n    BigInteger.prototype.divRemTo = bnpDivRemTo;\n    BigInteger.prototype.invDigit = bnpInvDigit;\n    BigInteger.prototype.isEven = bnpIsEven;\n    BigInteger.prototype.exp = bnpExp;\n\n    // public\n    BigInteger.prototype.toString = bnToString;\n    BigInteger.prototype.negate = bnNegate;\n    BigInteger.prototype.abs = bnAbs;\n    BigInteger.prototype.compareTo = bnCompareTo;\n    BigInteger.prototype.bitLength = bnBitLength;\n    BigInteger.prototype.mod = bnMod;\n    BigInteger.prototype.modPowInt = bnModPowInt;\n\n    // \"constants\"\n    BigInteger.ZERO = nbv(0);\n    BigInteger.ONE = nbv(1);\n\n    // Copyright (c) 2005-2009  Tom Wu\n    // All Rights Reserved.\n    // See \"LICENSE\" for details.\n\n    // Extended JavaScript BN functions, required for RSA private ops.\n\n    // Version 1.1: new BigInteger(\"0\", 10) returns \"proper\" zero\n    // Version 1.2: square() API, isProbablePrime fix\n\n    // (public)\n    function bnClone() { var r = nbi(); this.copyTo(r); return r; }\n\n    // (public) return value as integer\n    function bnIntValue() {\n      if(this.s < 0) {\n        if(this.t == 1) return this[0]-this.DV;\n        else if(this.t == 0) return -1;\n      }\n      else if(this.t == 1) return this[0];\n      else if(this.t == 0) return 0;\n      // assumes 16 < DB < 32\n      return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];\n    }\n\n    // (public) return value as byte\n    function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }\n\n    // (public) return value as short (assumes DB>=16)\n    function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }\n\n    // (protected) return x s.t. r^x < DV\n    function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }\n\n    // (public) 0 if this == 0, 1 if this > 0\n    function bnSigNum() {\n      if(this.s < 0) return -1;\n      else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;\n      else return 1;\n    }\n\n    // (protected) convert to radix string\n    function bnpToRadix(b) {\n      if(b == null) b = 10;\n      if(this.signum() == 0 || b < 2 || b > 36) return \"0\";\n      var cs = this.chunkSize(b);\n      var a = Math.pow(b,cs);\n      var d = nbv(a), y = nbi(), z = nbi(), r = \"\";\n      this.divRemTo(d,y,z);\n      while(y.signum() > 0) {\n        r = (a+z.intValue()).toString(b).substr(1) + r;\n        y.divRemTo(d,y,z);\n      }\n      return z.intValue().toString(b) + r;\n    }\n\n    // (protected) convert from radix string\n    function bnpFromRadix(s,b) {\n      this.fromInt(0);\n      if(b == null) b = 10;\n      var cs = this.chunkSize(b);\n      var d = Math.pow(b,cs), mi = false, j = 0, w = 0;\n      for(var i = 0; i < s.length; ++i) {\n        var x = intAt(s,i);\n        if(x < 0) {\n          if(s.charAt(i) == \"-\" && this.signum() == 0) mi = true;\n          continue;\n        }\n        w = b*w+x;\n        if(++j >= cs) {\n          this.dMultiply(d);\n          this.dAddOffset(w,0);\n          j = 0;\n          w = 0;\n        }\n      }\n      if(j > 0) {\n        this.dMultiply(Math.pow(b,j));\n        this.dAddOffset(w,0);\n      }\n      if(mi) BigInteger.ZERO.subTo(this,this);\n    }\n\n    // (protected) alternate constructor\n    function bnpFromNumber(a,b,c) {\n      if(\"number\" == typeof b) {\n        // new BigInteger(int,int,RNG)\n        if(a < 2) this.fromInt(1);\n        else {\n          this.fromNumber(a,c);\n          if(!this.testBit(a-1))    // force MSB set\n            this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);\n          if(this.isEven()) this.dAddOffset(1,0); // force odd\n          while(!this.isProbablePrime(b)) {\n            this.dAddOffset(2,0);\n            if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);\n          }\n        }\n      }\n      else {\n        // new BigInteger(int,RNG)\n        var x = new Array(), t = a&7;\n        x.length = (a>>3)+1;\n        b.nextBytes(x);\n        if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;\n        this.fromString(x,256);\n      }\n    }\n\n    // (public) convert to bigendian byte array\n    function bnToByteArray() {\n      var i = this.t, r = new Array();\n      r[0] = this.s;\n      var p = this.DB-(i*this.DB)%8, d, k = 0;\n      if(i-- > 0) {\n        if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)\n          r[k++] = d|(this.s<<(this.DB-p));\n        while(i >= 0) {\n          if(p < 8) {\n            d = (this[i]&((1<<p)-1))<<(8-p);\n            d |= this[--i]>>(p+=this.DB-8);\n          }\n          else {\n            d = (this[i]>>(p-=8))&0xff;\n            if(p <= 0) { p += this.DB; --i; }\n          }\n          if((d&0x80) != 0) d |= -256;\n          if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;\n          if(k > 0 || d != this.s) r[k++] = d;\n        }\n      }\n      return r;\n    }\n\n    function bnEquals(a) { return(this.compareTo(a)==0); }\n    function bnMin(a) { return(this.compareTo(a)<0)?this:a; }\n    function bnMax(a) { return(this.compareTo(a)>0)?this:a; }\n\n    // (protected) r = this op a (bitwise)\n    function bnpBitwiseTo(a,op,r) {\n      var i, f, m = Math.min(a.t,this.t);\n      for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);\n      if(a.t < this.t) {\n        f = a.s&this.DM;\n        for(i = m; i < this.t; ++i) r[i] = op(this[i],f);\n        r.t = this.t;\n      }\n      else {\n        f = this.s&this.DM;\n        for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);\n        r.t = a.t;\n      }\n      r.s = op(this.s,a.s);\n      r.clamp();\n    }\n\n    // (public) this & a\n    function op_and(x,y) { return x&y; }\n    function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }\n\n    // (public) this | a\n    function op_or(x,y) { return x|y; }\n    function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }\n\n    // (public) this ^ a\n    function op_xor(x,y) { return x^y; }\n    function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }\n\n    // (public) this & ~a\n    function op_andnot(x,y) { return x&~y; }\n    function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }\n\n    // (public) ~this\n    function bnNot() {\n      var r = nbi();\n      for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];\n      r.t = this.t;\n      r.s = ~this.s;\n      return r;\n    }\n\n    // (public) this << n\n    function bnShiftLeft(n) {\n      var r = nbi();\n      if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);\n      return r;\n    }\n\n    // (public) this >> n\n    function bnShiftRight(n) {\n      var r = nbi();\n      if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);\n      return r;\n    }\n\n    // return index of lowest 1-bit in x, x < 2^31\n    function lbit(x) {\n      if(x == 0) return -1;\n      var r = 0;\n      if((x&0xffff) == 0) { x >>= 16; r += 16; }\n      if((x&0xff) == 0) { x >>= 8; r += 8; }\n      if((x&0xf) == 0) { x >>= 4; r += 4; }\n      if((x&3) == 0) { x >>= 2; r += 2; }\n      if((x&1) == 0) ++r;\n      return r;\n    }\n\n    // (public) returns index of lowest 1-bit (or -1 if none)\n    function bnGetLowestSetBit() {\n      for(var i = 0; i < this.t; ++i)\n        if(this[i] != 0) return i*this.DB+lbit(this[i]);\n      if(this.s < 0) return this.t*this.DB;\n      return -1;\n    }\n\n    // return number of 1 bits in x\n    function cbit(x) {\n      var r = 0;\n      while(x != 0) { x &= x-1; ++r; }\n      return r;\n    }\n\n    // (public) return number of set bits\n    function bnBitCount() {\n      var r = 0, x = this.s&this.DM;\n      for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);\n      return r;\n    }\n\n    // (public) true iff nth bit is set\n    function bnTestBit(n) {\n      var j = Math.floor(n/this.DB);\n      if(j >= this.t) return(this.s!=0);\n      return((this[j]&(1<<(n%this.DB)))!=0);\n    }\n\n    // (protected) this op (1<<n)\n    function bnpChangeBit(n,op) {\n      var r = BigInteger.ONE.shiftLeft(n);\n      this.bitwiseTo(r,op,r);\n      return r;\n    }\n\n    // (public) this | (1<<n)\n    function bnSetBit(n) { return this.changeBit(n,op_or); }\n\n    // (public) this & ~(1<<n)\n    function bnClearBit(n) { return this.changeBit(n,op_andnot); }\n\n    // (public) this ^ (1<<n)\n    function bnFlipBit(n) { return this.changeBit(n,op_xor); }\n\n    // (protected) r = this + a\n    function bnpAddTo(a,r) {\n      var i = 0, c = 0, m = Math.min(a.t,this.t);\n      while(i < m) {\n        c += this[i]+a[i];\n        r[i++] = c&this.DM;\n        c >>= this.DB;\n      }\n      if(a.t < this.t) {\n        c += a.s;\n        while(i < this.t) {\n          c += this[i];\n          r[i++] = c&this.DM;\n          c >>= this.DB;\n        }\n        c += this.s;\n      }\n      else {\n        c += this.s;\n        while(i < a.t) {\n          c += a[i];\n          r[i++] = c&this.DM;\n          c >>= this.DB;\n        }\n        c += a.s;\n      }\n      r.s = (c<0)?-1:0;\n      if(c > 0) r[i++] = c;\n      else if(c < -1) r[i++] = this.DV+c;\n      r.t = i;\n      r.clamp();\n    }\n\n    // (public) this + a\n    function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }\n\n    // (public) this - a\n    function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }\n\n    // (public) this * a\n    function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }\n\n    // (public) this^2\n    function bnSquare() { var r = nbi(); this.squareTo(r); return r; }\n\n    // (public) this / a\n    function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }\n\n    // (public) this % a\n    function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }\n\n    // (public) [this/a,this%a]\n    function bnDivideAndRemainder(a) {\n      var q = nbi(), r = nbi();\n      this.divRemTo(a,q,r);\n      return new Array(q,r);\n    }\n\n    // (protected) this *= n, this >= 0, 1 < n < DV\n    function bnpDMultiply(n) {\n      this[this.t] = this.am(0,n-1,this,0,0,this.t);\n      ++this.t;\n      this.clamp();\n    }\n\n    // (protected) this += n << w words, this >= 0\n    function bnpDAddOffset(n,w) {\n      if(n == 0) return;\n      while(this.t <= w) this[this.t++] = 0;\n      this[w] += n;\n      while(this[w] >= this.DV) {\n        this[w] -= this.DV;\n        if(++w >= this.t) this[this.t++] = 0;\n        ++this[w];\n      }\n    }\n\n    // A \"null\" reducer\n    function NullExp() {}\n    function nNop(x) { return x; }\n    function nMulTo(x,y,r) { x.multiplyTo(y,r); }\n    function nSqrTo(x,r) { x.squareTo(r); }\n\n    NullExp.prototype.convert = nNop;\n    NullExp.prototype.revert = nNop;\n    NullExp.prototype.mulTo = nMulTo;\n    NullExp.prototype.sqrTo = nSqrTo;\n\n    // (public) this^e\n    function bnPow(e) { return this.exp(e,new NullExp()); }\n\n    // (protected) r = lower n words of \"this * a\", a.t <= n\n    // \"this\" should be the larger one if appropriate.\n    function bnpMultiplyLowerTo(a,n,r) {\n      var i = Math.min(this.t+a.t,n);\n      r.s = 0; // assumes a,this >= 0\n      r.t = i;\n      while(i > 0) r[--i] = 0;\n      var j;\n      for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);\n      for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);\n      r.clamp();\n    }\n\n    // (protected) r = \"this * a\" without lower n words, n > 0\n    // \"this\" should be the larger one if appropriate.\n    function bnpMultiplyUpperTo(a,n,r) {\n      --n;\n      var i = r.t = this.t+a.t-n;\n      r.s = 0; // assumes a,this >= 0\n      while(--i >= 0) r[i] = 0;\n      for(i = Math.max(n-this.t,0); i < a.t; ++i)\n        r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);\n      r.clamp();\n      r.drShiftTo(1,r);\n    }\n\n    // Barrett modular reduction\n    function Barrett(m) {\n      // setup Barrett\n      this.r2 = nbi();\n      this.q3 = nbi();\n      BigInteger.ONE.dlShiftTo(2*m.t,this.r2);\n      this.mu = this.r2.divide(m);\n      this.m = m;\n    }\n\n    function barrettConvert(x) {\n      if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);\n      else if(x.compareTo(this.m) < 0) return x;\n      else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }\n    }\n\n    function barrettRevert(x) { return x; }\n\n    // x = x mod m (HAC 14.42)\n    function barrettReduce(x) {\n      x.drShiftTo(this.m.t-1,this.r2);\n      if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }\n      this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);\n      this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);\n      while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);\n      x.subTo(this.r2,x);\n      while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);\n    }\n\n    // r = x^2 mod m; x != r\n    function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }\n\n    // r = x*y mod m; x,y != r\n    function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }\n\n    Barrett.prototype.convert = barrettConvert;\n    Barrett.prototype.revert = barrettRevert;\n    Barrett.prototype.reduce = barrettReduce;\n    Barrett.prototype.mulTo = barrettMulTo;\n    Barrett.prototype.sqrTo = barrettSqrTo;\n\n    // (public) this^e % m (HAC 14.85)\n    function bnModPow(e,m) {\n      var i = e.bitLength(), k, r = nbv(1), z;\n      if(i <= 0) return r;\n      else if(i < 18) k = 1;\n      else if(i < 48) k = 3;\n      else if(i < 144) k = 4;\n      else if(i < 768) k = 5;\n      else k = 6;\n      if(i < 8)\n        z = new Classic(m);\n      else if(m.isEven())\n        z = new Barrett(m);\n      else\n        z = new Montgomery(m);\n\n      // precomputation\n      var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;\n      g[1] = z.convert(this);\n      if(k > 1) {\n        var g2 = nbi();\n        z.sqrTo(g[1],g2);\n        while(n <= km) {\n          g[n] = nbi();\n          z.mulTo(g2,g[n-2],g[n]);\n          n += 2;\n        }\n      }\n\n      var j = e.t-1, w, is1 = true, r2 = nbi(), t;\n      i = nbits(e[j])-1;\n      while(j >= 0) {\n        if(i >= k1) w = (e[j]>>(i-k1))&km;\n        else {\n          w = (e[j]&((1<<(i+1))-1))<<(k1-i);\n          if(j > 0) w |= e[j-1]>>(this.DB+i-k1);\n        }\n\n        n = k;\n        while((w&1) == 0) { w >>= 1; --n; }\n        if((i -= n) < 0) { i += this.DB; --j; }\n        if(is1) {    // ret == 1, don't bother squaring or multiplying it\n          g[w].copyTo(r);\n          is1 = false;\n        }\n        else {\n          while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }\n          if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }\n          z.mulTo(r2,g[w],r);\n        }\n\n        while(j >= 0 && (e[j]&(1<<i)) == 0) {\n          z.sqrTo(r,r2); t = r; r = r2; r2 = t;\n          if(--i < 0) { i = this.DB-1; --j; }\n        }\n      }\n      return z.revert(r);\n    }\n\n    // (public) gcd(this,a) (HAC 14.54)\n    function bnGCD(a) {\n      var x = (this.s<0)?this.negate():this.clone();\n      var y = (a.s<0)?a.negate():a.clone();\n      if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }\n      var i = x.getLowestSetBit(), g = y.getLowestSetBit();\n      if(g < 0) return x;\n      if(i < g) g = i;\n      if(g > 0) {\n        x.rShiftTo(g,x);\n        y.rShiftTo(g,y);\n      }\n      while(x.signum() > 0) {\n        if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);\n        if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);\n        if(x.compareTo(y) >= 0) {\n          x.subTo(y,x);\n          x.rShiftTo(1,x);\n        }\n        else {\n          y.subTo(x,y);\n          y.rShiftTo(1,y);\n        }\n      }\n      if(g > 0) y.lShiftTo(g,y);\n      return y;\n    }\n\n    // (protected) this % n, n < 2^26\n    function bnpModInt(n) {\n      if(n <= 0) return 0;\n      var d = this.DV%n, r = (this.s<0)?n-1:0;\n      if(this.t > 0)\n        if(d == 0) r = this[0]%n;\n        else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;\n      return r;\n    }\n\n    // (public) 1/this % m (HAC 14.61)\n    function bnModInverse(m) {\n      var ac = m.isEven();\n      if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;\n      var u = m.clone(), v = this.clone();\n      var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);\n      while(u.signum() != 0) {\n        while(u.isEven()) {\n          u.rShiftTo(1,u);\n          if(ac) {\n            if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }\n            a.rShiftTo(1,a);\n          }\n          else if(!b.isEven()) b.subTo(m,b);\n          b.rShiftTo(1,b);\n        }\n        while(v.isEven()) {\n          v.rShiftTo(1,v);\n          if(ac) {\n            if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }\n            c.rShiftTo(1,c);\n          }\n          else if(!d.isEven()) d.subTo(m,d);\n          d.rShiftTo(1,d);\n        }\n        if(u.compareTo(v) >= 0) {\n          u.subTo(v,u);\n          if(ac) a.subTo(c,a);\n          b.subTo(d,b);\n        }\n        else {\n          v.subTo(u,v);\n          if(ac) c.subTo(a,c);\n          d.subTo(b,d);\n        }\n      }\n      if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;\n      if(d.compareTo(m) >= 0) return d.subtract(m);\n      if(d.signum() < 0) d.addTo(m,d); else return d;\n      if(d.signum() < 0) return d.add(m); else return d;\n    }\n\n    var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];\n    var lplim = (1<<26)/lowprimes[lowprimes.length-1];\n\n    // (public) test primality with certainty >= 1-.5^t\n    function bnIsProbablePrime(t) {\n      var i, x = this.abs();\n      if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {\n        for(i = 0; i < lowprimes.length; ++i)\n          if(x[0] == lowprimes[i]) return true;\n        return false;\n      }\n      if(x.isEven()) return false;\n      i = 1;\n      while(i < lowprimes.length) {\n        var m = lowprimes[i], j = i+1;\n        while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];\n        m = x.modInt(m);\n        while(i < j) if(m%lowprimes[i++] == 0) return false;\n      }\n      return x.millerRabin(t);\n    }\n\n    // (protected) true if probably prime (HAC 4.24, Miller-Rabin)\n    function bnpMillerRabin(t) {\n      var n1 = this.subtract(BigInteger.ONE);\n      var k = n1.getLowestSetBit();\n      if(k <= 0) return false;\n      var r = n1.shiftRight(k);\n      t = (t+1)>>1;\n      if(t > lowprimes.length) t = lowprimes.length;\n      var a = nbi();\n      for(var i = 0; i < t; ++i) {\n        //Pick bases at random, instead of starting at 2\n        a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]);\n        var y = a.modPow(r,this);\n        if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {\n          var j = 1;\n          while(j++ < k && y.compareTo(n1) != 0) {\n            y = y.modPowInt(2,this);\n            if(y.compareTo(BigInteger.ONE) == 0) return false;\n          }\n          if(y.compareTo(n1) != 0) return false;\n        }\n      }\n      return true;\n    }\n\n    // protected\n    BigInteger.prototype.chunkSize = bnpChunkSize;\n    BigInteger.prototype.toRadix = bnpToRadix;\n    BigInteger.prototype.fromRadix = bnpFromRadix;\n    BigInteger.prototype.fromNumber = bnpFromNumber;\n    BigInteger.prototype.bitwiseTo = bnpBitwiseTo;\n    BigInteger.prototype.changeBit = bnpChangeBit;\n    BigInteger.prototype.addTo = bnpAddTo;\n    BigInteger.prototype.dMultiply = bnpDMultiply;\n    BigInteger.prototype.dAddOffset = bnpDAddOffset;\n    BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;\n    BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;\n    BigInteger.prototype.modInt = bnpModInt;\n    BigInteger.prototype.millerRabin = bnpMillerRabin;\n\n    // public\n    BigInteger.prototype.clone = bnClone;\n    BigInteger.prototype.intValue = bnIntValue;\n    BigInteger.prototype.byteValue = bnByteValue;\n    BigInteger.prototype.shortValue = bnShortValue;\n    BigInteger.prototype.signum = bnSigNum;\n    BigInteger.prototype.toByteArray = bnToByteArray;\n    BigInteger.prototype.equals = bnEquals;\n    BigInteger.prototype.min = bnMin;\n    BigInteger.prototype.max = bnMax;\n    BigInteger.prototype.and = bnAnd;\n    BigInteger.prototype.or = bnOr;\n    BigInteger.prototype.xor = bnXor;\n    BigInteger.prototype.andNot = bnAndNot;\n    BigInteger.prototype.not = bnNot;\n    BigInteger.prototype.shiftLeft = bnShiftLeft;\n    BigInteger.prototype.shiftRight = bnShiftRight;\n    BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;\n    BigInteger.prototype.bitCount = bnBitCount;\n    BigInteger.prototype.testBit = bnTestBit;\n    BigInteger.prototype.setBit = bnSetBit;\n    BigInteger.prototype.clearBit = bnClearBit;\n    BigInteger.prototype.flipBit = bnFlipBit;\n    BigInteger.prototype.add = bnAdd;\n    BigInteger.prototype.subtract = bnSubtract;\n    BigInteger.prototype.multiply = bnMultiply;\n    BigInteger.prototype.divide = bnDivide;\n    BigInteger.prototype.remainder = bnRemainder;\n    BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;\n    BigInteger.prototype.modPow = bnModPow;\n    BigInteger.prototype.modInverse = bnModInverse;\n    BigInteger.prototype.pow = bnPow;\n    BigInteger.prototype.gcd = bnGCD;\n    BigInteger.prototype.isProbablePrime = bnIsProbablePrime;\n\n    // JSBN-specific extension\n    BigInteger.prototype.square = bnSquare;\n\n    // Expose the Barrett function\n    BigInteger.prototype.Barrett = Barrett\n\n    // BigInteger interfaces not implemented in jsbn:\n\n    // BigInteger(int signum, byte[] magnitude)\n    // double doubleValue()\n    // float floatValue()\n    // int hashCode()\n    // long longValue()\n    // static BigInteger valueOf(long val)\n\n    // Random number generator - requires a PRNG backend, e.g. prng4.js\n\n    // For best results, put code like\n    // <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>\n    // in your main HTML document.\n\n    var rng_state;\n    var rng_pool;\n    var rng_pptr;\n\n    // Mix in a 32-bit integer into the pool\n    function rng_seed_int(x) {\n      rng_pool[rng_pptr++] ^= x & 255;\n      rng_pool[rng_pptr++] ^= (x >> 8) & 255;\n      rng_pool[rng_pptr++] ^= (x >> 16) & 255;\n      rng_pool[rng_pptr++] ^= (x >> 24) & 255;\n      if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;\n    }\n\n    // Mix in the current time (w/milliseconds) into the pool\n    function rng_seed_time() {\n      rng_seed_int(new Date().getTime());\n    }\n\n    // Initialize the pool with junk if needed.\n    if(rng_pool == null) {\n      rng_pool = new Array();\n      rng_pptr = 0;\n      var t;\n      if(typeof window !== \"undefined\" && window.crypto) {\n        if (window.crypto.getRandomValues) {\n          // Use webcrypto if available\n          var ua = new Uint8Array(32);\n          window.crypto.getRandomValues(ua);\n          for(t = 0; t < 32; ++t)\n            rng_pool[rng_pptr++] = ua[t];\n        }\n        else if(navigator.appName == \"Netscape\" && navigator.appVersion < \"5\") {\n          // Extract entropy (256 bits) from NS4 RNG if available\n          var z = window.crypto.random(32);\n          for(t = 0; t < z.length; ++t)\n            rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;\n        }\n      }\n      while(rng_pptr < rng_psize) {  // extract some randomness from Math.random()\n        t = Math.floor(65536 * Math.random());\n        rng_pool[rng_pptr++] = t >>> 8;\n        rng_pool[rng_pptr++] = t & 255;\n      }\n      rng_pptr = 0;\n      rng_seed_time();\n      //rng_seed_int(window.screenX);\n      //rng_seed_int(window.screenY);\n    }\n\n    function rng_get_byte() {\n      if(rng_state == null) {\n        rng_seed_time();\n        rng_state = prng_newstate();\n        rng_state.init(rng_pool);\n        for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)\n          rng_pool[rng_pptr] = 0;\n        rng_pptr = 0;\n        //rng_pool = null;\n      }\n      // TODO: allow reseeding after first request\n      return rng_state.next();\n    }\n\n    function rng_get_bytes(ba) {\n      var i;\n      for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();\n    }\n\n    function SecureRandom() {}\n\n    SecureRandom.prototype.nextBytes = rng_get_bytes;\n\n    // prng4.js - uses Arcfour as a PRNG\n\n    function Arcfour() {\n      this.i = 0;\n      this.j = 0;\n      this.S = new Array();\n    }\n\n    // Initialize arcfour context from key, an array of ints, each from [0..255]\n    function ARC4init(key) {\n      var i, j, t;\n      for(i = 0; i < 256; ++i)\n        this.S[i] = i;\n      j = 0;\n      for(i = 0; i < 256; ++i) {\n        j = (j + this.S[i] + key[i % key.length]) & 255;\n        t = this.S[i];\n        this.S[i] = this.S[j];\n        this.S[j] = t;\n      }\n      this.i = 0;\n      this.j = 0;\n    }\n\n    function ARC4next() {\n      var t;\n      this.i = (this.i + 1) & 255;\n      this.j = (this.j + this.S[this.i]) & 255;\n      t = this.S[this.i];\n      this.S[this.i] = this.S[this.j];\n      this.S[this.j] = t;\n      return this.S[(t + this.S[this.i]) & 255];\n    }\n\n    Arcfour.prototype.init = ARC4init;\n    Arcfour.prototype.next = ARC4next;\n\n    // Plug in your RNG constructor here\n    function prng_newstate() {\n      return new Arcfour();\n    }\n\n    // Pool size must be a multiple of 4 and greater than 32.\n    // An array of bytes the size of the pool will be passed to init()\n    var rng_psize = 256;\n\n    if (true) {\n        exports = module.exports = {\n            default: BigInteger,\n            BigInteger: BigInteger,\n            SecureRandom: SecureRandom,\n        };\n    } else {}\n\n}).call(this);\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/bytesToUuid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/bytesToUuid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n  byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n  var i = offset || 0;\n  var bth = byteToHex;\n  // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n  return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/rng-browser.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/rng-browser.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// Unique ID creation requires a high quality random # generator.  In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API.  We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n                      (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n  // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n  var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n  module.exports = function whatwgRNG() {\n    getRandomValues(rnds8);\n    return rnds8;\n  };\n} else {\n  // Math.random()-based (RNG)\n  //\n  // If all else fails, use Math.random().  It's fast, but is of unspecified\n  // quality.\n  var rnds = new Array(16);\n\n  module.exports = function mathRNG() {\n    for (var i = 0, r; i < 16; i++) {\n      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n      rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n    }\n\n    return rnds;\n  };\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/v4.js\":\n/*!*********************************!*\\\n  !*** ./node_modules/uuid/v4.js ***!\n  \\*********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar rng = __webpack_require__(/*! ./lib/rng */ \"./node_modules/uuid/lib/rng-browser.js\");\nvar bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ \"./node_modules/uuid/lib/bytesToUuid.js\");\n\nfunction v4(options, buf, offset) {\n  var i = buf && offset || 0;\n\n  if (typeof(options) == 'string') {\n    buf = options === 'binary' ? new Array(16) : null;\n    options = null;\n  }\n  options = options || {};\n\n  var rnds = options.random || (options.rng || rng)();\n\n  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n  rnds[6] = (rnds[6] & 0x0f) | 0x40;\n  rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n  // Copy bytes to buffer, if provided\n  if (buf) {\n    for (var ii = 0; ii < 16; ++ii) {\n      buf[i + ii] = rnds[ii];\n    }\n  }\n\n  return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n\n\n/***/ }),\n\n/***/ \"./polyfills.js\":\n/*!**********************!*\\\n  !*** ./polyfills.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n__webpack_require__(/*! core-js/es6/promise */ \"./node_modules/core-js/es6/promise.js\");\n\n__webpack_require__(/*! core-js/fn/function/bind */ \"./node_modules/core-js/fn/function/bind.js\");\n\n__webpack_require__(/*! core-js/fn/object/assign */ \"./node_modules/core-js/fn/object/assign.js\");\n\n__webpack_require__(/*! core-js/fn/array/find */ \"./node_modules/core-js/fn/array/find.js\");\n\n__webpack_require__(/*! core-js/fn/array/some */ \"./node_modules/core-js/fn/array/some.js\");\n\n__webpack_require__(/*! core-js/fn/array/is-array */ \"./node_modules/core-js/fn/array/is-array.js\");\n\n__webpack_require__(/*! core-js/fn/array/splice */ \"./node_modules/core-js/fn/array/splice.js\");\n\n/***/ }),\n\n/***/ \"./src/AccessTokenEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/AccessTokenEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AccessTokenEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Timer = __webpack_require__(/*! ./Timer.js */ \"./src/Timer.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60; // seconds\n\nvar AccessTokenEvents = exports.AccessTokenEvents = function () {\n    function AccessTokenEvents() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$accessTokenExpir2 = _ref.accessTokenExpiringTimer,\n            accessTokenExpiringTimer = _ref$accessTokenExpir2 === undefined ? new _Timer.Timer(\"Access token expiring\") : _ref$accessTokenExpir2,\n            _ref$accessTokenExpir3 = _ref.accessTokenExpiredTimer,\n            accessTokenExpiredTimer = _ref$accessTokenExpir3 === undefined ? new _Timer.Timer(\"Access token expired\") : _ref$accessTokenExpir3;\n\n        _classCallCheck(this, AccessTokenEvents);\n\n        this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        this._accessTokenExpiring = accessTokenExpiringTimer;\n        this._accessTokenExpired = accessTokenExpiredTimer;\n    }\n\n    AccessTokenEvents.prototype.load = function load(container) {\n        // only register events if there's an access token and it has an expiration\n        if (container.access_token && container.expires_in !== undefined) {\n            var duration = container.expires_in;\n            _Log.Log.debug(\"AccessTokenEvents.load: access token present, remaining duration:\", duration);\n\n            if (duration > 0) {\n                // only register expiring if we still have time\n                var expiring = duration - this._accessTokenExpiringNotificationTime;\n                if (expiring <= 0) {\n                    expiring = 1;\n                }\n\n                _Log.Log.debug(\"AccessTokenEvents.load: registering expiring timer in:\", expiring);\n                this._accessTokenExpiring.init(expiring);\n            } else {\n                _Log.Log.debug(\"AccessTokenEvents.load: canceling existing expiring timer becase we're past expiration.\");\n                this._accessTokenExpiring.cancel();\n            }\n\n            // if it's negative, it will still fire\n            var expired = duration + 1;\n            _Log.Log.debug(\"AccessTokenEvents.load: registering expired timer in:\", expired);\n            this._accessTokenExpired.init(expired);\n        } else {\n            this._accessTokenExpiring.cancel();\n            this._accessTokenExpired.cancel();\n        }\n    };\n\n    AccessTokenEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"AccessTokenEvents.unload: canceling existing access token timers\");\n        this._accessTokenExpiring.cancel();\n        this._accessTokenExpired.cancel();\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpiring = function addAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpiring = function removeAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.removeHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpired = function addAccessTokenExpired(cb) {\n        this._accessTokenExpired.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpired = function removeAccessTokenExpired(cb) {\n        this._accessTokenExpired.removeHandler(cb);\n    };\n\n    return AccessTokenEvents;\n}();\n\n/***/ }),\n\n/***/ \"./src/CheckSessionIFrame.js\":\n/*!***********************************!*\\\n  !*** ./src/CheckSessionIFrame.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CheckSessionIFrame = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultInterval = 2000;\n\nvar CheckSessionIFrame = exports.CheckSessionIFrame = function () {\n    function CheckSessionIFrame(callback, client_id, url, interval) {\n        var stopOnError = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n\n        _classCallCheck(this, CheckSessionIFrame);\n\n        this._callback = callback;\n        this._client_id = client_id;\n        this._url = url;\n        this._interval = interval || DefaultInterval;\n        this._stopOnError = stopOnError;\n\n        var idx = url.indexOf(\"/\", url.indexOf(\"//\") + 2);\n        this._frame_origin = url.substr(0, idx);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        this._frame.src = url;\n    }\n\n    CheckSessionIFrame.prototype.load = function load() {\n        var _this = this;\n\n        return new Promise(function (resolve) {\n            _this._frame.onload = function () {\n                resolve();\n            };\n\n            window.document.body.appendChild(_this._frame);\n            _this._boundMessageEvent = _this._message.bind(_this);\n            window.addEventListener(\"message\", _this._boundMessageEvent, false);\n        });\n    };\n\n    CheckSessionIFrame.prototype._message = function _message(e) {\n        if (e.origin === this._frame_origin && e.source === this._frame.contentWindow) {\n            if (e.data === \"error\") {\n                _Log.Log.error(\"CheckSessionIFrame: error message from check session op iframe\");\n                if (this._stopOnError) {\n                    this.stop();\n                }\n            } else if (e.data === \"changed\") {\n                _Log.Log.debug(\"CheckSessionIFrame: changed message from check session op iframe\");\n                this.stop();\n                this._callback();\n            } else {\n                _Log.Log.debug(\"CheckSessionIFrame: \" + e.data + \" message from check session op iframe\");\n            }\n        }\n    };\n\n    CheckSessionIFrame.prototype.start = function start(session_state) {\n        var _this2 = this;\n\n        if (this._session_state !== session_state) {\n            _Log.Log.debug(\"CheckSessionIFrame.start\");\n\n            this.stop();\n\n            this._session_state = session_state;\n\n            var send = function send() {\n                _this2._frame.contentWindow.postMessage(_this2._client_id + \" \" + _this2._session_state, _this2._frame_origin);\n            };\n\n            // trigger now\n            send();\n\n            // and setup timer\n            this._timer = window.setInterval(send, this._interval);\n        }\n    };\n\n    CheckSessionIFrame.prototype.stop = function stop() {\n        this._session_state = null;\n\n        if (this._timer) {\n            _Log.Log.debug(\"CheckSessionIFrame.stop\");\n\n            window.clearInterval(this._timer);\n            this._timer = null;\n        }\n    };\n\n    return CheckSessionIFrame;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaIFrameNavigator.js\":\n/*!***************************************!*\\\n  !*** ./src/CordovaIFrameNavigator.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaIFrameNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaIFrameNavigator = exports.CordovaIFrameNavigator = function () {\n    function CordovaIFrameNavigator() {\n        _classCallCheck(this, CordovaIFrameNavigator);\n    }\n\n    CordovaIFrameNavigator.prototype.prepare = function prepare(params) {\n        params.popupWindowFeatures = 'hidden=yes';\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaIFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupNavigator.js\":\n/*!**************************************!*\\\n  !*** ./src/CordovaPopupNavigator.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaPopupNavigator = exports.CordovaPopupNavigator = function () {\n    function CordovaPopupNavigator() {\n        _classCallCheck(this, CordovaPopupNavigator);\n    }\n\n    CordovaPopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaPopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupWindow.js\":\n/*!***********************************!*\\\n  !*** ./src/CordovaPopupWindow.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultPopupFeatures = 'location=no,toolbar=no,zoom=no';\nvar DefaultPopupTarget = \"_blank\";\n\nvar CordovaPopupWindow = exports.CordovaPopupWindow = function () {\n    function CordovaPopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, CordovaPopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this.features = params.popupWindowFeatures || DefaultPopupFeatures;\n        this.target = params.popupWindowTarget || DefaultPopupTarget;\n\n        this.redirect_uri = params.startUrl;\n        _Log.Log.debug(\"CordovaPopupWindow.ctor: redirect_uri: \" + this.redirect_uri);\n    }\n\n    CordovaPopupWindow.prototype._isInAppBrowserInstalled = function _isInAppBrowserInstalled(cordovaMetadata) {\n        return [\"cordova-plugin-inappbrowser\", \"cordova-plugin-inappbrowser.inappbrowser\", \"org.apache.cordova.inappbrowser\"].some(function (name) {\n            return cordovaMetadata.hasOwnProperty(name);\n        });\n    };\n\n    CordovaPopupWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            if (!window.cordova) {\n                return this._error(\"cordova is undefined\");\n            }\n\n            var cordovaMetadata = window.cordova.require(\"cordova/plugin_list\").metadata;\n            if (this._isInAppBrowserInstalled(cordovaMetadata) === false) {\n                return this._error(\"InAppBrowser plugin not found\");\n            }\n            this._popup = cordova.InAppBrowser.open(params.url, this.target, this.features);\n            if (this._popup) {\n                _Log.Log.debug(\"CordovaPopupWindow.navigate: popup successfully created\");\n\n                this._exitCallbackEvent = this._exitCallback.bind(this);\n                this._loadStartCallbackEvent = this._loadStartCallback.bind(this);\n\n                this._popup.addEventListener(\"exit\", this._exitCallbackEvent, false);\n                this._popup.addEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            } else {\n                this._error(\"Error opening popup window\");\n            }\n        }\n        return this.promise;\n    };\n\n    CordovaPopupWindow.prototype._loadStartCallback = function _loadStartCallback(event) {\n        if (event.url.indexOf(this.redirect_uri) === 0) {\n            this._success({ url: event.url });\n        }\n    };\n\n    CordovaPopupWindow.prototype._exitCallback = function _exitCallback(message) {\n        this._error(message);\n    };\n\n    CordovaPopupWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"CordovaPopupWindow: Successful response from cordova popup window\");\n        this._resolve(data);\n    };\n\n    CordovaPopupWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    CordovaPopupWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    CordovaPopupWindow.prototype._cleanup = function _cleanup() {\n        if (this._popup) {\n            _Log.Log.debug(\"CordovaPopupWindow: cleaning up popup\");\n            this._popup.removeEventListener(\"exit\", this._exitCallbackEvent, false);\n            this._popup.removeEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    _createClass(CordovaPopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return CordovaPopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/ErrorResponse.js\":\n/*!******************************!*\\\n  !*** ./src/ErrorResponse.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.ErrorResponse = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ErrorResponse = exports.ErrorResponse = function (_Error) {\n        _inherits(ErrorResponse, _Error);\n\n        function ErrorResponse() {\n                var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n                    error = _ref.error,\n                    error_description = _ref.error_description,\n                    error_uri = _ref.error_uri,\n                    state = _ref.state,\n                    session_state = _ref.session_state;\n\n                _classCallCheck(this, ErrorResponse);\n\n                if (!error) {\n                        _Log.Log.error(\"No error passed to ErrorResponse\");\n                        throw new Error(\"error\");\n                }\n\n                var _this = _possibleConstructorReturn(this, _Error.call(this, error_description || error));\n\n                _this.name = \"ErrorResponse\";\n\n                _this.error = error;\n                _this.error_description = error_description;\n                _this.error_uri = error_uri;\n\n                _this.state = state;\n                _this.session_state = session_state;\n                return _this;\n        }\n\n        return ErrorResponse;\n}(Error);\n\n/***/ }),\n\n/***/ \"./src/Event.js\":\n/*!**********************!*\\\n  !*** ./src/Event.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Event = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar Event = exports.Event = function () {\n    function Event(name) {\n        _classCallCheck(this, Event);\n\n        this._name = name;\n        this._callbacks = [];\n    }\n\n    Event.prototype.addHandler = function addHandler(cb) {\n        this._callbacks.push(cb);\n    };\n\n    Event.prototype.removeHandler = function removeHandler(cb) {\n        var idx = this._callbacks.findIndex(function (item) {\n            return item === cb;\n        });\n        if (idx >= 0) {\n            this._callbacks.splice(idx, 1);\n        }\n    };\n\n    Event.prototype.raise = function raise() {\n        _Log.Log.debug(\"Event: Raising event: \" + this._name);\n        for (var i = 0; i < this._callbacks.length; i++) {\n            var _callbacks;\n\n            (_callbacks = this._callbacks)[i].apply(_callbacks, arguments);\n        }\n    };\n\n    return Event;\n}();\n\n/***/ }),\n\n/***/ \"./src/Global.js\":\n/*!***********************!*\\\n  !*** ./src/Global.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar timer = {\n    setInterval: function (_setInterval) {\n        function setInterval(_x, _x2) {\n            return _setInterval.apply(this, arguments);\n        }\n\n        setInterval.toString = function () {\n            return _setInterval.toString();\n        };\n\n        return setInterval;\n    }(function (cb, duration) {\n        return setInterval(cb, duration);\n    }),\n    clearInterval: function (_clearInterval) {\n        function clearInterval(_x3) {\n            return _clearInterval.apply(this, arguments);\n        }\n\n        clearInterval.toString = function () {\n            return _clearInterval.toString();\n        };\n\n        return clearInterval;\n    }(function (handle) {\n        return clearInterval(handle);\n    })\n};\n\nvar testing = false;\nvar request = null;\n\nvar Global = exports.Global = function () {\n    function Global() {\n        _classCallCheck(this, Global);\n    }\n\n    Global._testing = function _testing() {\n        testing = true;\n    };\n\n    Global.setXMLHttpRequest = function setXMLHttpRequest(newRequest) {\n        request = newRequest;\n    };\n\n    _createClass(Global, null, [{\n        key: 'location',\n        get: function get() {\n            if (!testing) {\n                return location;\n            }\n        }\n    }, {\n        key: 'localStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return localStorage;\n            }\n        }\n    }, {\n        key: 'sessionStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return sessionStorage;\n            }\n        }\n    }, {\n        key: 'XMLHttpRequest',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return request || XMLHttpRequest;\n            }\n        }\n    }, {\n        key: 'timer',\n        get: function get() {\n            if (!testing) {\n                return timer;\n            }\n        }\n    }]);\n\n    return Global;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameNavigator.js\":\n/*!********************************!*\\\n  !*** ./src/IFrameNavigator.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _IFrameWindow = __webpack_require__(/*! ./IFrameWindow.js */ \"./src/IFrameWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar IFrameNavigator = exports.IFrameNavigator = function () {\n    function IFrameNavigator() {\n        _classCallCheck(this, IFrameNavigator);\n    }\n\n    IFrameNavigator.prototype.prepare = function prepare(params) {\n        var frame = new _IFrameWindow.IFrameWindow(params);\n        return Promise.resolve(frame);\n    };\n\n    IFrameNavigator.prototype.callback = function callback(url) {\n        _Log.Log.debug(\"IFrameNavigator.callback\");\n\n        try {\n            _IFrameWindow.IFrameWindow.notifyParent(url);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return IFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameWindow.js\":\n/*!*****************************!*\\\n  !*** ./src/IFrameWindow.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultTimeout = 10000;\n\nvar IFrameWindow = exports.IFrameWindow = function () {\n    function IFrameWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, IFrameWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this._boundMessageEvent = this._message.bind(this);\n        window.addEventListener(\"message\", this._boundMessageEvent, false);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        window.document.body.appendChild(this._frame);\n    }\n\n    IFrameWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            var timeout = params.silentRequestTimeout || DefaultTimeout;\n            _Log.Log.debug(\"IFrameWindow.navigate: Using timeout of:\", timeout);\n            this._timer = window.setTimeout(this._timeout.bind(this), timeout);\n            this._frame.src = params.url;\n        }\n\n        return this.promise;\n    };\n\n    IFrameWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"IFrameWindow: Successful response from frame window\");\n        this._resolve(data);\n    };\n\n    IFrameWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    IFrameWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    IFrameWindow.prototype._cleanup = function _cleanup() {\n        if (this._frame) {\n            _Log.Log.debug(\"IFrameWindow: cleanup\");\n\n            window.removeEventListener(\"message\", this._boundMessageEvent, false);\n            window.clearTimeout(this._timer);\n            window.document.body.removeChild(this._frame);\n\n            this._timer = null;\n            this._frame = null;\n            this._boundMessageEvent = null;\n        }\n    };\n\n    IFrameWindow.prototype._timeout = function _timeout() {\n        _Log.Log.debug(\"IFrameWindow.timeout\");\n        this._error(\"Frame window timed out\");\n    };\n\n    IFrameWindow.prototype._message = function _message(e) {\n        _Log.Log.debug(\"IFrameWindow.message\");\n\n        if (this._timer && e.origin === this._origin && e.source === this._frame.contentWindow) {\n            var url = e.data;\n            if (url) {\n                this._success({ url: url });\n            } else {\n                this._error(\"Invalid response from frame\");\n            }\n        }\n    };\n\n    IFrameWindow.notifyParent = function notifyParent(url) {\n        _Log.Log.debug(\"IFrameWindow.notifyParent\");\n        if (window.frameElement) {\n            url = url || window.location.href;\n            if (url) {\n                _Log.Log.debug(\"IFrameWindow.notifyParent: posting url message to parent\");\n                window.parent.postMessage(url, location.protocol + \"//\" + location.host);\n            }\n        }\n    };\n\n    _createClass(IFrameWindow, [{\n        key: \"promise\",\n        get: function get() {\n            return this._promise;\n        }\n    }, {\n        key: \"_origin\",\n        get: function get() {\n            return location.protocol + \"//\" + location.host;\n        }\n    }]);\n\n    return IFrameWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/InMemoryWebStorage.js\":\n/*!***********************************!*\\\n  !*** ./src/InMemoryWebStorage.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.InMemoryWebStorage = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar InMemoryWebStorage = exports.InMemoryWebStorage = function () {\n    function InMemoryWebStorage() {\n        _classCallCheck(this, InMemoryWebStorage);\n\n        this._data = {};\n    }\n\n    InMemoryWebStorage.prototype.getItem = function getItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.getItem\", key);\n        return this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.setItem = function setItem(key, value) {\n        _Log.Log.debug(\"InMemoryWebStorage.setItem\", key);\n        this._data[key] = value;\n    };\n\n    InMemoryWebStorage.prototype.removeItem = function removeItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.removeItem\", key);\n        delete this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.key = function key(index) {\n        return Object.getOwnPropertyNames(this._data)[index];\n    };\n\n    _createClass(InMemoryWebStorage, [{\n        key: \"length\",\n        get: function get() {\n            return Object.getOwnPropertyNames(this._data).length;\n        }\n    }]);\n\n    return InMemoryWebStorage;\n}();\n\n/***/ }),\n\n/***/ \"./src/JoseUtilImpl.js\":\n/*!*****************************!*\\\n  !*** ./src/JoseUtilImpl.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.default = getJoseUtil;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nfunction getJoseUtil(_ref) {\n    var jws = _ref.jws,\n        KeyUtil = _ref.KeyUtil,\n        X509 = _ref.X509,\n        crypto = _ref.crypto,\n        hextob64u = _ref.hextob64u,\n        b64tohex = _ref.b64tohex,\n        AllowedSigningAlgs = _ref.AllowedSigningAlgs;\n\n    return function () {\n        function JoseUtil() {\n            _classCallCheck(this, JoseUtil);\n        }\n\n        JoseUtil.parseJwt = function parseJwt(jwt) {\n            _Log.Log.debug(\"JoseUtil.parseJwt\");\n            try {\n                var token = jws.JWS.parse(jwt);\n                return {\n                    header: token.headerObj,\n                    payload: token.payloadObj\n                };\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.validateJwt = function validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n            _Log.Log.debug(\"JoseUtil.validateJwt\");\n\n            try {\n                if (key.kty === \"RSA\") {\n                    if (key.e && key.n) {\n                        key = KeyUtil.getKey(key);\n                    } else if (key.x5c && key.x5c.length) {\n                        var hex = b64tohex(key.x5c[0]);\n                        key = X509.getPublicKeyFromCertHex(hex);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: RSA key missing key material\", key);\n                        return Promise.reject(new Error(\"RSA key missing key material\"));\n                    }\n                } else if (key.kty === \"EC\") {\n                    if (key.crv && key.x && key.y) {\n                        key = KeyUtil.getKey(key);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: EC key missing key material\", key);\n                        return Promise.reject(new Error(\"EC key missing key material\"));\n                    }\n                } else {\n                    _Log.Log.error(\"JoseUtil.validateJwt: Unsupported key type\", key && key.kty);\n                    return Promise.reject(new Error( true && key.kty));\n                }\n\n                return JoseUtil._validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive);\n            } catch (e) {\n                _Log.Log.error(e && e.message || e);\n                return Promise.reject(\"JWT validation failed\");\n            }\n        };\n\n        JoseUtil.validateJwtAttributes = function validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive) {\n            if (!clockSkew) {\n                clockSkew = 0;\n            }\n\n            if (!now) {\n                now = parseInt(Date.now() / 1000);\n            }\n\n            var payload = JoseUtil.parseJwt(jwt).payload;\n\n            if (!payload.iss) {\n                _Log.Log.error(\"JoseUtil._validateJwt: issuer was not provided\");\n                return Promise.reject(new Error(\"issuer was not provided\"));\n            }\n            if (payload.iss !== issuer) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid issuer in token\", payload.iss);\n                return Promise.reject(new Error(\"Invalid issuer in token: \" + payload.iss));\n            }\n\n            if (!payload.aud) {\n                _Log.Log.error(\"JoseUtil._validateJwt: aud was not provided\");\n                return Promise.reject(new Error(\"aud was not provided\"));\n            }\n            var validAudience = payload.aud === audience || Array.isArray(payload.aud) && payload.aud.indexOf(audience) >= 0;\n            if (!validAudience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid audience in token\", payload.aud);\n                return Promise.reject(new Error(\"Invalid audience in token: \" + payload.aud));\n            }\n            if (payload.azp && payload.azp !== audience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid azp in token\", payload.azp);\n                return Promise.reject(new Error(\"Invalid azp in token: \" + payload.azp));\n            }\n\n            if (!timeInsensitive) {\n                var lowerNow = now + clockSkew;\n                var upperNow = now - clockSkew;\n\n                if (!payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat was not provided\");\n                    return Promise.reject(new Error(\"iat was not provided\"));\n                }\n                if (lowerNow < payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat is in the future\", payload.iat);\n                    return Promise.reject(new Error(\"iat is in the future: \" + payload.iat));\n                }\n\n                if (payload.nbf && lowerNow < payload.nbf) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: nbf is in the future\", payload.nbf);\n                    return Promise.reject(new Error(\"nbf is in the future: \" + payload.nbf));\n                }\n\n                if (!payload.exp) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp was not provided\");\n                    return Promise.reject(new Error(\"exp was not provided\"));\n                }\n                if (payload.exp < upperNow) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp is in the past\", payload.exp);\n                    return Promise.reject(new Error(\"exp is in the past:\" + payload.exp));\n                }\n            }\n\n            return Promise.resolve(payload);\n        };\n\n        JoseUtil._validateJwt = function _validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n\n            return JoseUtil.validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive).then(function (payload) {\n                try {\n                    if (!jws.JWS.verify(jwt, key, AllowedSigningAlgs)) {\n                        _Log.Log.error(\"JoseUtil._validateJwt: signature validation failed\");\n                        return Promise.reject(new Error(\"signature validation failed\"));\n                    }\n\n                    return payload;\n                } catch (e) {\n                    _Log.Log.error(e && e.message || e);\n                    return Promise.reject(new Error(\"signature validation failed\"));\n                }\n            });\n        };\n\n        JoseUtil.hashString = function hashString(value, alg) {\n            try {\n                return crypto.Util.hashString(value, alg);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.hexToBase64Url = function hexToBase64Url(value) {\n            try {\n                return hextob64u(value);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        return JoseUtil;\n    }();\n}\nmodule.exports = exports[\"default\"];\n\n/***/ }),\n\n/***/ \"./src/JoseUtilRsa.js\":\n/*!****************************!*\\\n  !*** ./src/JoseUtilRsa.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.JoseUtil = undefined;\n\nvar _rsa = __webpack_require__(/*! ./crypto/rsa */ \"./src/crypto/rsa.js\");\n\nvar _JoseUtilImpl = __webpack_require__(/*! ./JoseUtilImpl */ \"./src/JoseUtilImpl.js\");\n\nvar _JoseUtilImpl2 = _interopRequireDefault(_JoseUtilImpl);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar JoseUtil = exports.JoseUtil = (0, _JoseUtilImpl2.default)({ jws: _rsa.jws, KeyUtil: _rsa.KeyUtil, X509: _rsa.X509, crypto: _rsa.crypto, hextob64u: _rsa.hextob64u, b64tohex: _rsa.b64tohex, AllowedSigningAlgs: _rsa.AllowedSigningAlgs });\n\n/***/ }),\n\n/***/ \"./src/JsonService.js\":\n/*!****************************!*\\\n  !*** ./src/JsonService.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.JsonService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar JsonService = exports.JsonService = function () {\n    function JsonService() {\n        var additionalContentTypes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var jwtHandler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n\n        _classCallCheck(this, JsonService);\n\n        if (additionalContentTypes && Array.isArray(additionalContentTypes)) {\n            this._contentTypes = additionalContentTypes.slice();\n        } else {\n            this._contentTypes = [];\n        }\n        this._contentTypes.push('application/json');\n        if (jwtHandler) {\n            this._contentTypes.push('application/jwt');\n        }\n\n        this._XMLHttpRequest = XMLHttpRequestCtor;\n        this._jwtHandler = jwtHandler;\n    }\n\n    JsonService.prototype.getJson = function getJson(url, token) {\n        var _this = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.getJson: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.getJson, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this._XMLHttpRequest();\n            req.open('GET', url);\n\n            var allowedContentTypes = _this._contentTypes;\n            var jwtHandler = _this._jwtHandler;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.getJson: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found == \"application/jwt\") {\n                            jwtHandler(req).then(resolve, reject);\n                            return;\n                        }\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.getJson: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                } else {\n                    reject(Error(req.statusText + \" (\" + req.status + \")\"));\n                }\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.getJson: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            if (token) {\n                _Log.Log.debug(\"JsonService.getJson: token passed, setting Authorization header\");\n                req.setRequestHeader(\"Authorization\", \"Bearer \" + token);\n            }\n\n            req.send();\n        });\n    };\n\n    JsonService.prototype.postForm = function postForm(url, payload) {\n        var _this2 = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.postForm: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.postForm, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this2._XMLHttpRequest();\n            req.open('POST', url);\n\n            var allowedContentTypes = _this2._contentTypes;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.postForm: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                    return;\n                }\n\n                if (req.status === 400) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                var payload = JSON.parse(req.responseText);\n                                if (payload && payload.error) {\n                                    _Log.Log.error(\"JsonService.postForm: Error from server: \", payload.error);\n                                    reject(new Error(payload.error));\n                                    return;\n                                }\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n                }\n\n                reject(Error(req.statusText + \" (\" + req.status + \")\"));\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.postForm: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            var body = \"\";\n            for (var key in payload) {\n\n                var value = payload[key];\n\n                if (value) {\n\n                    if (body.length > 0) {\n                        body += \"&\";\n                    }\n\n                    body += encodeURIComponent(key);\n                    body += \"=\";\n                    body += encodeURIComponent(value);\n                }\n            }\n\n            req.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            req.send(body);\n        });\n    };\n\n    return JsonService;\n}();\n\n/***/ }),\n\n/***/ \"./src/Log.js\":\n/*!********************!*\\\n  !*** ./src/Log.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar nopLogger = {\n    debug: function debug() {},\n    info: function info() {},\n    warn: function warn() {},\n    error: function error() {}\n};\n\nvar NONE = 0;\nvar ERROR = 1;\nvar WARN = 2;\nvar INFO = 3;\nvar DEBUG = 4;\n\nvar logger = void 0;\nvar level = void 0;\n\nvar Log = exports.Log = function () {\n    function Log() {\n        _classCallCheck(this, Log);\n    }\n\n    Log.reset = function reset() {\n        level = INFO;\n        logger = nopLogger;\n    };\n\n    Log.debug = function debug() {\n        if (level >= DEBUG) {\n            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n                args[_key] = arguments[_key];\n            }\n\n            logger.debug.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.info = function info() {\n        if (level >= INFO) {\n            for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n                args[_key2] = arguments[_key2];\n            }\n\n            logger.info.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.warn = function warn() {\n        if (level >= WARN) {\n            for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n                args[_key3] = arguments[_key3];\n            }\n\n            logger.warn.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.error = function error() {\n        if (level >= ERROR) {\n            for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n                args[_key4] = arguments[_key4];\n            }\n\n            logger.error.apply(logger, Array.from(args));\n        }\n    };\n\n    _createClass(Log, null, [{\n        key: \"NONE\",\n        get: function get() {\n            return NONE;\n        }\n    }, {\n        key: \"ERROR\",\n        get: function get() {\n            return ERROR;\n        }\n    }, {\n        key: \"WARN\",\n        get: function get() {\n            return WARN;\n        }\n    }, {\n        key: \"INFO\",\n        get: function get() {\n            return INFO;\n        }\n    }, {\n        key: \"DEBUG\",\n        get: function get() {\n            return DEBUG;\n        }\n    }, {\n        key: \"level\",\n        get: function get() {\n            return level;\n        },\n        set: function set(value) {\n            if (NONE <= value && value <= DEBUG) {\n                level = value;\n            } else {\n                throw new Error(\"Invalid log level\");\n            }\n        }\n    }, {\n        key: \"logger\",\n        get: function get() {\n            return logger;\n        },\n        set: function set(value) {\n            if (!value.debug && value.info) {\n                // just to stay backwards compat. can remove in 2.0\n                value.debug = value.info;\n            }\n\n            if (value.debug && value.info && value.warn && value.error) {\n                logger = value;\n            } else {\n                throw new Error(\"Invalid logger\");\n            }\n        }\n    }]);\n\n    return Log;\n}();\n\nLog.reset();\n\n/***/ }),\n\n/***/ \"./src/MetadataService.js\":\n/*!********************************!*\\\n  !*** ./src/MetadataService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.MetadataService = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar MetadataService = exports.MetadataService = function () {\n    function MetadataService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n\n        _classCallCheck(this, MetadataService);\n\n        if (!settings) {\n            _Log.Log.error(\"MetadataService: No settings passed to MetadataService\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(['application/jwk-set+json']);\n    }\n\n    MetadataService.prototype.getMetadata = function getMetadata() {\n        var _this = this;\n\n        if (this._settings.metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: Returning metadata from settings\");\n            return Promise.resolve(this._settings.metadata);\n        }\n\n        if (!this.metadataUrl) {\n            _Log.Log.error(\"MetadataService.getMetadata: No authority or metadataUrl configured on settings\");\n            return Promise.reject(new Error(\"No authority or metadataUrl configured on settings\"));\n        }\n\n        _Log.Log.debug(\"MetadataService.getMetadata: getting metadata from\", this.metadataUrl);\n\n        return this._jsonService.getJson(this.metadataUrl).then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: json received\");\n            _this._settings.metadata = metadata;\n            return metadata;\n        });\n    };\n\n    MetadataService.prototype.getIssuer = function getIssuer() {\n        return this._getMetadataProperty(\"issuer\");\n    };\n\n    MetadataService.prototype.getAuthorizationEndpoint = function getAuthorizationEndpoint() {\n        return this._getMetadataProperty(\"authorization_endpoint\");\n    };\n\n    MetadataService.prototype.getUserInfoEndpoint = function getUserInfoEndpoint() {\n        return this._getMetadataProperty(\"userinfo_endpoint\");\n    };\n\n    MetadataService.prototype.getTokenEndpoint = function getTokenEndpoint() {\n        var optional = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n        return this._getMetadataProperty(\"token_endpoint\", optional);\n    };\n\n    MetadataService.prototype.getCheckSessionIframe = function getCheckSessionIframe() {\n        return this._getMetadataProperty(\"check_session_iframe\", true);\n    };\n\n    MetadataService.prototype.getEndSessionEndpoint = function getEndSessionEndpoint() {\n        return this._getMetadataProperty(\"end_session_endpoint\", true);\n    };\n\n    MetadataService.prototype.getRevocationEndpoint = function getRevocationEndpoint() {\n        return this._getMetadataProperty(\"revocation_endpoint\", true);\n    };\n\n    MetadataService.prototype.getKeysEndpoint = function getKeysEndpoint() {\n        return this._getMetadataProperty(\"jwks_uri\", true);\n    };\n\n    MetadataService.prototype._getMetadataProperty = function _getMetadataProperty(name) {\n        var optional = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n        _Log.Log.debug(\"MetadataService.getMetadataProperty for: \" + name);\n\n        return this.getMetadata().then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadataProperty: metadata recieved\");\n\n            if (metadata[name] === undefined) {\n\n                if (optional === true) {\n                    _Log.Log.warn(\"MetadataService.getMetadataProperty: Metadata does not contain optional property \" + name);\n                    return undefined;\n                } else {\n                    _Log.Log.error(\"MetadataService.getMetadataProperty: Metadata does not contain property \" + name);\n                    throw new Error(\"Metadata does not contain property \" + name);\n                }\n            }\n\n            return metadata[name];\n        });\n    };\n\n    MetadataService.prototype.getSigningKeys = function getSigningKeys() {\n        var _this2 = this;\n\n        if (this._settings.signingKeys) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: Returning signingKeys from settings\");\n            return Promise.resolve(this._settings.signingKeys);\n        }\n\n        return this._getMetadataProperty(\"jwks_uri\").then(function (jwks_uri) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: jwks_uri received\", jwks_uri);\n\n            return _this2._jsonService.getJson(jwks_uri).then(function (keySet) {\n                _Log.Log.debug(\"MetadataService.getSigningKeys: key set received\", keySet);\n\n                if (!keySet.keys) {\n                    _Log.Log.error(\"MetadataService.getSigningKeys: Missing keys on keyset\");\n                    throw new Error(\"Missing keys on keyset\");\n                }\n\n                _this2._settings.signingKeys = keySet.keys;\n                return _this2._settings.signingKeys;\n            });\n        });\n    };\n\n    _createClass(MetadataService, [{\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                if (this._settings.metadataUrl) {\n                    this._metadataUrl = this._settings.metadataUrl;\n                } else {\n                    this._metadataUrl = this._settings.authority;\n\n                    if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                        if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                            this._metadataUrl += '/';\n                        }\n                        this._metadataUrl += OidcMetadataUrlPath;\n                    }\n                }\n            }\n\n            return this._metadataUrl;\n        }\n    }]);\n\n    return MetadataService;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClient.js\":\n/*!***************************!*\\\n  !*** ./src/OidcClient.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClient = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nvar _SigninResponse = __webpack_require__(/*! ./SigninResponse.js */ \"./src/SigninResponse.js\");\n\nvar _SignoutRequest = __webpack_require__(/*! ./SignoutRequest.js */ \"./src/SignoutRequest.js\");\n\nvar _SignoutResponse = __webpack_require__(/*! ./SignoutResponse.js */ \"./src/SignoutResponse.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcClient = exports.OidcClient = function () {\n    function OidcClient() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        _classCallCheck(this, OidcClient);\n\n        if (settings instanceof _OidcClientSettings.OidcClientSettings) {\n            this._settings = settings;\n        } else {\n            this._settings = new _OidcClientSettings.OidcClientSettings(settings);\n        }\n    }\n\n    OidcClient.prototype.createSigninRequest = function createSigninRequest() {\n        var _this = this;\n\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            redirect_uri = _ref.redirect_uri,\n            data = _ref.data,\n            state = _ref.state,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            response_mode = _ref.response_mode,\n            extraQueryParams = _ref.extraQueryParams,\n            extraTokenParams = _ref.extraTokenParams,\n            request_type = _ref.request_type,\n            skipUserInfo = _ref.skipUserInfo;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSigninRequest\");\n\n        var client_id = this._settings.client_id;\n        response_type = response_type || this._settings.response_type;\n        scope = scope || this._settings.scope;\n        redirect_uri = redirect_uri || this._settings.redirect_uri;\n\n        // id_token_hint, login_hint aren't allowed on _settings\n        prompt = prompt || this._settings.prompt;\n        display = display || this._settings.display;\n        max_age = max_age || this._settings.max_age;\n        ui_locales = ui_locales || this._settings.ui_locales;\n        acr_values = acr_values || this._settings.acr_values;\n        resource = resource || this._settings.resource;\n        response_mode = response_mode || this._settings.response_mode;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n        extraTokenParams = extraTokenParams || this._settings.extraTokenParams;\n\n        var authority = this._settings.authority;\n\n        if (_SigninRequest.SigninRequest.isCode(response_type) && response_type !== \"code\") {\n            return Promise.reject(new Error(\"OpenID Connect hybrid flow is not supported\"));\n        }\n\n        return this._metadataService.getAuthorizationEndpoint().then(function (url) {\n            _Log.Log.debug(\"OidcClient.createSigninRequest: Received authorization endpoint\", url);\n\n            var signinRequest = new _SigninRequest.SigninRequest({\n                url: url,\n                client_id: client_id,\n                redirect_uri: redirect_uri,\n                response_type: response_type,\n                scope: scope,\n                data: data || state,\n                authority: authority,\n                prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values,\n                resource: resource, request: request, request_uri: request_uri, extraQueryParams: extraQueryParams, extraTokenParams: extraTokenParams, request_type: request_type, response_mode: response_mode,\n                client_secret: _this._settings.client_secret,\n                skipUserInfo: skipUserInfo\n            });\n\n            var signinState = signinRequest.state;\n            stateStore = stateStore || _this._stateStore;\n\n            return stateStore.set(signinState.id, signinState.toStorageString()).then(function () {\n                return signinRequest;\n            });\n        });\n    };\n\n    OidcClient.prototype.readSigninResponseState = function readSigninResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSigninResponseState\");\n\n        var useQuery = this._settings.response_mode === \"query\" || !this._settings.response_mode && _SigninRequest.SigninRequest.isCode(this._settings.response_type);\n        var delimiter = useQuery ? \"?\" : \"#\";\n\n        var response = new _SigninResponse.SigninResponse(url, delimiter);\n\n        if (!response.state) {\n            _Log.Log.error(\"OidcClient.readSigninResponseState: No state in response\");\n            return Promise.reject(new Error(\"No state in response\"));\n        }\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n\n        return stateApi(response.state).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSigninResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _SigninState.SigninState.fromStorageString(storedStateString);\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSigninResponse = function processSigninResponse(url, stateStore) {\n        var _this2 = this;\n\n        _Log.Log.debug(\"OidcClient.processSigninResponse\");\n\n        return this.readSigninResponseState(url, stateStore, true).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            _Log.Log.debug(\"OidcClient.processSigninResponse: Received state from storage; validating response\");\n            return _this2._validator.validateSigninResponse(state, response);\n        });\n    };\n\n    OidcClient.prototype.createSignoutRequest = function createSignoutRequest() {\n        var _this3 = this;\n\n        var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id_token_hint = _ref3.id_token_hint,\n            data = _ref3.data,\n            state = _ref3.state,\n            post_logout_redirect_uri = _ref3.post_logout_redirect_uri,\n            extraQueryParams = _ref3.extraQueryParams,\n            request_type = _ref3.request_type;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSignoutRequest\");\n\n        post_logout_redirect_uri = post_logout_redirect_uri || this._settings.post_logout_redirect_uri;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n\n        return this._metadataService.getEndSessionEndpoint().then(function (url) {\n            if (!url) {\n                _Log.Log.error(\"OidcClient.createSignoutRequest: No end session endpoint url returned\");\n                throw new Error(\"no end session endpoint\");\n            }\n\n            _Log.Log.debug(\"OidcClient.createSignoutRequest: Received end session endpoint\", url);\n\n            var request = new _SignoutRequest.SignoutRequest({\n                url: url,\n                id_token_hint: id_token_hint,\n                post_logout_redirect_uri: post_logout_redirect_uri,\n                data: data || state,\n                extraQueryParams: extraQueryParams,\n                request_type: request_type\n            });\n\n            var signoutState = request.state;\n            if (signoutState) {\n                _Log.Log.debug(\"OidcClient.createSignoutRequest: Signout request has state to persist\");\n\n                stateStore = stateStore || _this3._stateStore;\n                stateStore.set(signoutState.id, signoutState.toStorageString());\n            }\n\n            return request;\n        });\n    };\n\n    OidcClient.prototype.readSignoutResponseState = function readSignoutResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSignoutResponseState\");\n\n        var response = new _SignoutResponse.SignoutResponse(url);\n        if (!response.state) {\n            _Log.Log.debug(\"OidcClient.readSignoutResponseState: No state in response\");\n\n            if (response.error) {\n                _Log.Log.warn(\"OidcClient.readSignoutResponseState: Response was error: \", response.error);\n                return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n            }\n\n            return Promise.resolve({ undefined: undefined, response: response });\n        }\n\n        var stateKey = response.state;\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n        return stateApi(stateKey).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSignoutResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _State.State.fromStorageString(storedStateString);\n\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSignoutResponse = function processSignoutResponse(url, stateStore) {\n        var _this4 = this;\n\n        _Log.Log.debug(\"OidcClient.processSignoutResponse\");\n\n        return this.readSignoutResponseState(url, stateStore, true).then(function (_ref4) {\n            var state = _ref4.state,\n                response = _ref4.response;\n\n            if (state) {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: Received state from storage; validating response\");\n                return _this4._validator.validateSignoutResponse(state, response);\n            } else {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: No state from storage; skipping validating response\");\n                return response;\n            }\n        });\n    };\n\n    OidcClient.prototype.clearStaleState = function clearStaleState(stateStore) {\n        _Log.Log.debug(\"OidcClient.clearStaleState\");\n\n        stateStore = stateStore || this._stateStore;\n\n        return _State.State.clearStaleState(stateStore, this.settings.staleStateAge);\n    };\n\n    _createClass(OidcClient, [{\n        key: '_stateStore',\n        get: function get() {\n            return this.settings.stateStore;\n        }\n    }, {\n        key: '_validator',\n        get: function get() {\n            return this.settings.validator;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this.settings.metadataService;\n        }\n    }, {\n        key: 'settings',\n        get: function get() {\n            return this._settings;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n    }]);\n\n    return OidcClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClientSettings.js\":\n/*!***********************************!*\\\n  !*** ./src/OidcClientSettings.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClientSettings = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _ResponseValidator = __webpack_require__(/*! ./ResponseValidator.js */ \"./src/ResponseValidator.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar DefaultResponseType = \"id_token\";\nvar DefaultScope = \"openid\";\nvar DefaultStaleStateAge = 60 * 15; // seconds\nvar DefaultClockSkewInSeconds = 60 * 5;\n\nvar OidcClientSettings = exports.OidcClientSettings = function () {\n    function OidcClientSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            authority = _ref.authority,\n            metadataUrl = _ref.metadataUrl,\n            metadata = _ref.metadata,\n            signingKeys = _ref.signingKeys,\n            client_id = _ref.client_id,\n            client_secret = _ref.client_secret,\n            _ref$response_type = _ref.response_type,\n            response_type = _ref$response_type === undefined ? DefaultResponseType : _ref$response_type,\n            _ref$scope = _ref.scope,\n            scope = _ref$scope === undefined ? DefaultScope : _ref$scope,\n            redirect_uri = _ref.redirect_uri,\n            post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            _ref$filterProtocolCl = _ref.filterProtocolClaims,\n            filterProtocolClaims = _ref$filterProtocolCl === undefined ? true : _ref$filterProtocolCl,\n            _ref$loadUserInfo = _ref.loadUserInfo,\n            loadUserInfo = _ref$loadUserInfo === undefined ? true : _ref$loadUserInfo,\n            _ref$staleStateAge = _ref.staleStateAge,\n            staleStateAge = _ref$staleStateAge === undefined ? DefaultStaleStateAge : _ref$staleStateAge,\n            _ref$clockSkew = _ref.clockSkew,\n            clockSkew = _ref$clockSkew === undefined ? DefaultClockSkewInSeconds : _ref$clockSkew,\n            _ref$userInfoJwtIssue = _ref.userInfoJwtIssuer,\n            userInfoJwtIssuer = _ref$userInfoJwtIssue === undefined ? 'OP' : _ref$userInfoJwtIssue,\n            _ref$stateStore = _ref.stateStore,\n            stateStore = _ref$stateStore === undefined ? new _WebStorageStateStore.WebStorageStateStore() : _ref$stateStore,\n            _ref$ResponseValidato = _ref.ResponseValidatorCtor,\n            ResponseValidatorCtor = _ref$ResponseValidato === undefined ? _ResponseValidator.ResponseValidator : _ref$ResponseValidato,\n            _ref$MetadataServiceC = _ref.MetadataServiceCtor,\n            MetadataServiceCtor = _ref$MetadataServiceC === undefined ? _MetadataService.MetadataService : _ref$MetadataServiceC,\n            _ref$extraQueryParams = _ref.extraQueryParams,\n            extraQueryParams = _ref$extraQueryParams === undefined ? {} : _ref$extraQueryParams,\n            _ref$extraTokenParams = _ref.extraTokenParams,\n            extraTokenParams = _ref$extraTokenParams === undefined ? {} : _ref$extraTokenParams;\n\n        _classCallCheck(this, OidcClientSettings);\n\n        this._authority = authority;\n        this._metadataUrl = metadataUrl;\n        this._metadata = metadata;\n        this._signingKeys = signingKeys;\n\n        this._client_id = client_id;\n        this._client_secret = client_secret;\n        this._response_type = response_type;\n        this._scope = scope;\n        this._redirect_uri = redirect_uri;\n        this._post_logout_redirect_uri = post_logout_redirect_uri;\n\n        this._prompt = prompt;\n        this._display = display;\n        this._max_age = max_age;\n        this._ui_locales = ui_locales;\n        this._acr_values = acr_values;\n        this._resource = resource;\n        this._response_mode = response_mode;\n\n        this._filterProtocolClaims = !!filterProtocolClaims;\n        this._loadUserInfo = !!loadUserInfo;\n        this._staleStateAge = staleStateAge;\n        this._clockSkew = clockSkew;\n        this._userInfoJwtIssuer = userInfoJwtIssuer;\n\n        this._stateStore = stateStore;\n        this._validator = new ResponseValidatorCtor(this);\n        this._metadataService = new MetadataServiceCtor(this);\n\n        this._extraQueryParams = (typeof extraQueryParams === 'undefined' ? 'undefined' : _typeof(extraQueryParams)) === 'object' ? extraQueryParams : {};\n        this._extraTokenParams = (typeof extraTokenParams === 'undefined' ? 'undefined' : _typeof(extraTokenParams)) === 'object' ? extraTokenParams : {};\n    }\n\n    // client config\n\n\n    _createClass(OidcClientSettings, [{\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        },\n        set: function set(value) {\n            if (!this._client_id) {\n                // one-time set only\n                this._client_id = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_client_id: client_id has already been assigned.\");\n                throw new Error(\"client_id has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'response_type',\n        get: function get() {\n            return this._response_type;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'post_logout_redirect_uri',\n        get: function get() {\n            return this._post_logout_redirect_uri;\n        }\n\n        // optional protocol params\n\n    }, {\n        key: 'prompt',\n        get: function get() {\n            return this._prompt;\n        }\n    }, {\n        key: 'display',\n        get: function get() {\n            return this._display;\n        }\n    }, {\n        key: 'max_age',\n        get: function get() {\n            return this._max_age;\n        }\n    }, {\n        key: 'ui_locales',\n        get: function get() {\n            return this._ui_locales;\n        }\n    }, {\n        key: 'acr_values',\n        get: function get() {\n            return this._acr_values;\n        }\n    }, {\n        key: 'resource',\n        get: function get() {\n            return this._resource;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n\n        // metadata\n\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        },\n        set: function set(value) {\n            if (!this._authority) {\n                // one-time set only\n                this._authority = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_authority: authority has already been assigned.\");\n                throw new Error(\"authority has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                this._metadataUrl = this.authority;\n\n                if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                    if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                        this._metadataUrl += '/';\n                    }\n                    this._metadataUrl += OidcMetadataUrlPath;\n                }\n            }\n\n            return this._metadataUrl;\n        }\n\n        // settable/cachable metadata values\n\n    }, {\n        key: 'metadata',\n        get: function get() {\n            return this._metadata;\n        },\n        set: function set(value) {\n            this._metadata = value;\n        }\n    }, {\n        key: 'signingKeys',\n        get: function get() {\n            return this._signingKeys;\n        },\n        set: function set(value) {\n            this._signingKeys = value;\n        }\n\n        // behavior flags\n\n    }, {\n        key: 'filterProtocolClaims',\n        get: function get() {\n            return this._filterProtocolClaims;\n        }\n    }, {\n        key: 'loadUserInfo',\n        get: function get() {\n            return this._loadUserInfo;\n        }\n    }, {\n        key: 'staleStateAge',\n        get: function get() {\n            return this._staleStateAge;\n        }\n    }, {\n        key: 'clockSkew',\n        get: function get() {\n            return this._clockSkew;\n        }\n    }, {\n        key: 'userInfoJwtIssuer',\n        get: function get() {\n            return this._userInfoJwtIssuer;\n        }\n    }, {\n        key: 'stateStore',\n        get: function get() {\n            return this._stateStore;\n        }\n    }, {\n        key: 'validator',\n        get: function get() {\n            return this._validator;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n\n        // extra query params\n\n    }, {\n        key: 'extraQueryParams',\n        get: function get() {\n            return this._extraQueryParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraQueryParams = value;\n            } else {\n                this._extraQueryParams = {};\n            }\n        }\n\n        // extra token params\n\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraTokenParams = value;\n            } else {\n                this._extraTokenParams = {};\n            }\n        }\n    }]);\n\n    return OidcClientSettings;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupNavigator.js\":\n/*!*******************************!*\\\n  !*** ./src/PopupNavigator.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _PopupWindow = __webpack_require__(/*! ./PopupWindow.js */ \"./src/PopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar PopupNavigator = exports.PopupNavigator = function () {\n    function PopupNavigator() {\n        _classCallCheck(this, PopupNavigator);\n    }\n\n    PopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _PopupWindow.PopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    PopupNavigator.prototype.callback = function callback(url, keepOpen, delimiter) {\n        _Log.Log.debug(\"PopupNavigator.callback\");\n\n        try {\n            _PopupWindow.PopupWindow.notifyOpener(url, keepOpen, delimiter);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return PopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupWindow.js\":\n/*!****************************!*\\\n  !*** ./src/PopupWindow.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar CheckForPopupClosedInterval = 500;\nvar DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;';\n//const DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;resizable=yes';\n\nvar DefaultPopupTarget = \"_blank\";\n\nvar PopupWindow = exports.PopupWindow = function () {\n    function PopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, PopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        var target = params.popupWindowTarget || DefaultPopupTarget;\n        var features = params.popupWindowFeatures || DefaultPopupFeatures;\n\n        this._popup = window.open('', target, features);\n        if (this._popup) {\n            _Log.Log.debug(\"PopupWindow.ctor: popup successfully created\");\n            this._checkForPopupClosedTimer = window.setInterval(this._checkForPopupClosed.bind(this), CheckForPopupClosedInterval);\n        }\n    }\n\n    PopupWindow.prototype.navigate = function navigate(params) {\n        if (!this._popup) {\n            this._error(\"PopupWindow.navigate: Error opening popup window\");\n        } else if (!params || !params.url) {\n            this._error(\"PopupWindow.navigate: no url provided\");\n            this._error(\"No url provided\");\n        } else {\n            _Log.Log.debug(\"PopupWindow.navigate: Setting URL in popup\");\n\n            this._id = params.id;\n            if (this._id) {\n                window[\"popupCallback_\" + params.id] = this._callback.bind(this);\n            }\n\n            this._popup.focus();\n            this._popup.window.location = params.url;\n        }\n\n        return this.promise;\n    };\n\n    PopupWindow.prototype._success = function _success(data) {\n        _Log.Log.debug(\"PopupWindow.callback: Successful response from popup window\");\n\n        this._cleanup();\n        this._resolve(data);\n    };\n\n    PopupWindow.prototype._error = function _error(message) {\n        _Log.Log.error(\"PopupWindow.error: \", message);\n\n        this._cleanup();\n        this._reject(new Error(message));\n    };\n\n    PopupWindow.prototype.close = function close() {\n        this._cleanup(false);\n    };\n\n    PopupWindow.prototype._cleanup = function _cleanup(keepOpen) {\n        _Log.Log.debug(\"PopupWindow.cleanup\");\n\n        window.clearInterval(this._checkForPopupClosedTimer);\n        this._checkForPopupClosedTimer = null;\n\n        delete window[\"popupCallback_\" + this._id];\n\n        if (this._popup && !keepOpen) {\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    PopupWindow.prototype._checkForPopupClosed = function _checkForPopupClosed() {\n        if (!this._popup || this._popup.closed) {\n            this._error(\"Popup window closed\");\n        }\n    };\n\n    PopupWindow.prototype._callback = function _callback(url, keepOpen) {\n        this._cleanup(keepOpen);\n\n        if (url) {\n            _Log.Log.debug(\"PopupWindow.callback success\");\n            this._success({ url: url });\n        } else {\n            _Log.Log.debug(\"PopupWindow.callback: Invalid response from popup\");\n            this._error(\"Invalid response from popup\");\n        }\n    };\n\n    PopupWindow.notifyOpener = function notifyOpener(url, keepOpen, delimiter) {\n        if (window.opener) {\n            url = url || window.location.href;\n            if (url) {\n                var data = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n                if (data.state) {\n                    var name = \"popupCallback_\" + data.state;\n                    var callback = window.opener[name];\n                    if (callback) {\n                        _Log.Log.debug(\"PopupWindow.notifyOpener: passing url message to opener\");\n                        callback(url, keepOpen);\n                    } else {\n                        _Log.Log.warn(\"PopupWindow.notifyOpener: no matching callback found on opener\");\n                    }\n                } else {\n                    _Log.Log.warn(\"PopupWindow.notifyOpener: no state found in response url\");\n                }\n            }\n        } else {\n            _Log.Log.warn(\"PopupWindow.notifyOpener: no window.opener. Can't complete notification.\");\n        }\n    };\n\n    _createClass(PopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return PopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/RedirectNavigator.js\":\n/*!**********************************!*\\\n  !*** ./src/RedirectNavigator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.RedirectNavigator = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar RedirectNavigator = exports.RedirectNavigator = function () {\n    function RedirectNavigator() {\n        _classCallCheck(this, RedirectNavigator);\n    }\n\n    RedirectNavigator.prototype.prepare = function prepare() {\n        return Promise.resolve(this);\n    };\n\n    RedirectNavigator.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            _Log.Log.error(\"RedirectNavigator.navigate: No url provided\");\n            return Promise.reject(new Error(\"No url provided\"));\n        }\n\n        if (params.useReplaceToNavigate) {\n            window.location.replace(params.url);\n        } else {\n            window.location = params.url;\n        }\n\n        return Promise.resolve();\n    };\n\n    _createClass(RedirectNavigator, [{\n        key: \"url\",\n        get: function get() {\n            return window.location.href;\n        }\n    }]);\n\n    return RedirectNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/ResponseValidator.js\":\n/*!**********************************!*\\\n  !*** ./src/ResponseValidator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.ResponseValidator = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _UserInfoService = __webpack_require__(/*! ./UserInfoService.js */ \"./src/UserInfoService.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtilRsa.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ProtocolClaims = [\"nonce\", \"at_hash\", \"iat\", \"nbf\", \"exp\", \"aud\", \"iss\", \"c_hash\"];\n\nvar ResponseValidator = exports.ResponseValidator = function () {\n    function ResponseValidator(settings) {\n        var MetadataServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _MetadataService.MetadataService;\n        var UserInfoServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _UserInfoService.UserInfoService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n\n        _classCallCheck(this, ResponseValidator);\n\n        if (!settings) {\n            _Log.Log.error(\"ResponseValidator.ctor: No settings passed to ResponseValidator\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._userInfoService = new UserInfoServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n        this._tokenClient = new TokenClientCtor(this._settings);\n    }\n\n    ResponseValidator.prototype.validateSigninResponse = function validateSigninResponse(state, response) {\n        var _this = this;\n\n        _Log.Log.debug(\"ResponseValidator.validateSigninResponse\");\n\n        return this._processSigninParams(state, response).then(function (response) {\n            _Log.Log.debug(\"ResponseValidator.validateSigninResponse: state processed\");\n            return _this._validateTokens(state, response).then(function (response) {\n                _Log.Log.debug(\"ResponseValidator.validateSigninResponse: tokens validated\");\n                return _this._processClaims(state, response).then(function (response) {\n                    _Log.Log.debug(\"ResponseValidator.validateSigninResponse: claims processed\");\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype.validateSignoutResponse = function validateSignoutResponse(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator.validateSignoutResponse: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator.validateSignoutResponse: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator.validateSignoutResponse: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processSigninParams = function _processSigninParams(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        if (!state.client_id) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No client_id on state\");\n            return Promise.reject(new Error(\"No client_id on state\"));\n        }\n\n        if (!state.authority) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No authority on state\");\n            return Promise.reject(new Error(\"No authority on state\"));\n        }\n\n        // this allows the authority to be loaded from the signin state\n        if (!this._settings.authority) {\n            this._settings.authority = state.authority;\n        }\n        // ensure we're using the correct authority if the authority is not loaded from signin state\n        else if (this._settings.authority && this._settings.authority !== state.authority) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: authority mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"authority mismatch on settings vs. signin state\"));\n            }\n        // this allows the client_id to be loaded from the signin state\n        if (!this._settings.client_id) {\n            this._settings.client_id = state.client_id;\n        }\n        // ensure we're using the correct client_id if the client_id is not loaded from signin state\n        else if (this._settings.client_id && this._settings.client_id !== state.client_id) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: client_id mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"client_id mismatch on settings vs. signin state\"));\n            }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator._processSigninParams: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator._processSigninParams: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        if (state.nonce && !response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting id_token in response\");\n            return Promise.reject(new Error(\"No id_token in response\"));\n        }\n\n        if (!state.nonce && response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting id_token in response\");\n            return Promise.reject(new Error(\"Unexpected id_token in response\"));\n        }\n\n        if (state.code_verifier && !response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting code in response\");\n            return Promise.reject(new Error(\"No code in response\"));\n        }\n\n        if (!state.code_verifier && response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting code in response\");\n            return Promise.reject(new Error(\"Unexpected code in response\"));\n        }\n\n        if (!response.scope) {\n            // if there's no scope on the response, then assume all scopes granted (per-spec) and copy over scopes from original request\n            response.scope = state.scope;\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processClaims = function _processClaims(state, response) {\n        var _this2 = this;\n\n        if (response.isOpenIdConnect) {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is OIDC, processing claims\");\n\n            response.profile = this._filterProtocolClaims(response.profile);\n\n            if (state.skipUserInfo !== true && this._settings.loadUserInfo && response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._processClaims: loading user info\");\n\n                return this._userInfoService.getClaims(response.access_token).then(function (claims) {\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received from user info endpoint\");\n\n                    if (claims.sub !== response.profile.sub) {\n                        _Log.Log.error(\"ResponseValidator._processClaims: sub from user info endpoint does not match sub in access_token\");\n                        return Promise.reject(new Error(\"sub from user info endpoint does not match sub in access_token\"));\n                    }\n\n                    response.profile = _this2._mergeClaims(response.profile, claims);\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received, updated profile:\", response.profile);\n\n                    return response;\n                });\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processClaims: not loading user info\");\n            }\n        } else {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is not OIDC, not processing claims\");\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._mergeClaims = function _mergeClaims(claims1, claims2) {\n        var result = Object.assign({}, claims1);\n\n        for (var name in claims2) {\n            var values = claims2[name];\n            if (!Array.isArray(values)) {\n                values = [values];\n            }\n\n            for (var i = 0; i < values.length; i++) {\n                var value = values[i];\n                if (!result[name]) {\n                    result[name] = value;\n                } else if (Array.isArray(result[name])) {\n                    if (result[name].indexOf(value) < 0) {\n                        result[name].push(value);\n                    }\n                } else if (result[name] !== value) {\n                    if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                        result[name] = this._mergeClaims(result[name], value);\n                    } else {\n                        result[name] = [result[name], value];\n                    }\n                }\n            }\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._filterProtocolClaims = function _filterProtocolClaims(claims) {\n        _Log.Log.debug(\"ResponseValidator._filterProtocolClaims, incoming claims:\", claims);\n\n        var result = Object.assign({}, claims);\n\n        if (this._settings._filterProtocolClaims) {\n            ProtocolClaims.forEach(function (type) {\n                delete result[type];\n            });\n\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims filtered\", result);\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims not filtered\");\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._validateTokens = function _validateTokens(state, response) {\n        if (response.code) {\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating code\");\n            return this._processCode(state, response);\n        }\n\n        if (response.id_token) {\n            if (response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token and access_token\");\n                return this._validateIdTokenAndAccessToken(state, response);\n            }\n\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token\");\n            return this._validateIdToken(state, response);\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateTokens: No code to process or id_token to validate\");\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processCode = function _processCode(state, response) {\n        var _this3 = this;\n\n        var request = {\n            client_id: state.client_id,\n            client_secret: state.client_secret,\n            code: response.code,\n            redirect_uri: state.redirect_uri,\n            code_verifier: state.code_verifier\n        };\n\n        if (state.extraTokenParams && _typeof(state.extraTokenParams) === 'object') {\n            Object.assign(request, state.extraTokenParams);\n        }\n\n        return this._tokenClient.exchangeCode(request).then(function (tokenResponse) {\n\n            for (var key in tokenResponse) {\n                response[key] = tokenResponse[key];\n            }\n\n            if (response.id_token) {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, processing id_token\");\n                return _this3._validateIdTokenAttributes(state, response);\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, returning response\");\n            }\n\n            return response;\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAttributes = function _validateIdTokenAttributes(state, response) {\n        var _this4 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n\n            var audience = state.client_id;\n            var clockSkewInSeconds = _this4._settings.clockSkew;\n            _Log.Log.debug(\"ResponseValidator._validateIdTokenAttributes: Validaing JWT attributes; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n            return _this4._joseUtil.validateJwtAttributes(response.id_token, issuer, audience, clockSkewInSeconds).then(function (payload) {\n\n                if (state.nonce && state.nonce !== payload.nonce) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: Invalid nonce in id_token\");\n                    return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n                }\n\n                if (!payload.sub) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: No sub present in id_token\");\n                    return Promise.reject(new Error(\"No sub present in id_token\"));\n                }\n\n                response.profile = payload;\n                return response;\n            });\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAndAccessToken = function _validateIdTokenAndAccessToken(state, response) {\n        var _this5 = this;\n\n        return this._validateIdToken(state, response).then(function (response) {\n            return _this5._validateAccessToken(response);\n        });\n    };\n\n    ResponseValidator.prototype._validateIdToken = function _validateIdToken(state, response) {\n        var _this6 = this;\n\n        if (!state.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: No nonce on state\");\n            return Promise.reject(new Error(\"No nonce on state\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header || !jwt.payload) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        if (state.nonce !== jwt.payload.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Invalid nonce in id_token\");\n            return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n        }\n\n        var kid = jwt.header.kid;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            _Log.Log.debug(\"ResponseValidator._validateIdToken: Received issuer\");\n\n            return _this6._metadataService.getSigningKeys().then(function (keys) {\n                if (!keys) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No signing keys from metadata\");\n                    return Promise.reject(new Error(\"No signing keys from metadata\"));\n                }\n\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Received signing keys\");\n                var key = void 0;\n                if (!kid) {\n                    keys = _this6._filterByAlg(keys, jwt.header.alg);\n\n                    if (keys.length > 1) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No kid found in id_token and more than one key found in metadata\");\n                        return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                    } else {\n                        // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                        // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                        key = keys[0];\n                    }\n                } else {\n                    key = keys.filter(function (key) {\n                        return key.kid === kid;\n                    })[0];\n                }\n\n                if (!key) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No key matching kid or alg found in signing keys\");\n                    return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                }\n\n                var audience = state.client_id;\n\n                var clockSkewInSeconds = _this6._settings.clockSkew;\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                return _this6._joseUtil.validateJwt(response.id_token, key, issuer, audience, clockSkewInSeconds).then(function () {\n                    _Log.Log.debug(\"ResponseValidator._validateIdToken: JWT validation successful\");\n\n                    if (!jwt.payload.sub) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No sub present in id_token\");\n                        return Promise.reject(new Error(\"No sub present in id_token\"));\n                    }\n\n                    response.profile = jwt.payload;\n\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    ResponseValidator.prototype._validateAccessToken = function _validateAccessToken(response) {\n        if (!response.profile) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No profile loaded from id_token\");\n            return Promise.reject(new Error(\"No profile loaded from id_token\"));\n        }\n\n        if (!response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No at_hash in id_token\");\n            return Promise.reject(new Error(\"No at_hash in id_token\"));\n        }\n\n        if (!response.id_token) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No id_token\");\n            return Promise.reject(new Error(\"No id_token\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        var hashAlg = jwt.header.alg;\n        if (!hashAlg || hashAlg.length !== 5) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var hashBits = hashAlg.substr(2, 3);\n        if (!hashBits) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        hashBits = parseInt(hashBits);\n        if (hashBits !== 256 && hashBits !== 384 && hashBits !== 512) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var sha = \"sha\" + hashBits;\n        var hash = this._joseUtil.hashString(response.access_token, sha);\n        if (!hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: access_token hash failed:\", sha);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        var left = hash.substr(0, hash.length / 2);\n        var left_b64u = this._joseUtil.hexToBase64Url(left);\n        if (left_b64u !== response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to validate at_hash\", left_b64u, response.profile.at_hash);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateAccessToken: success\");\n\n        return Promise.resolve(response);\n    };\n\n    return ResponseValidator;\n}();\n\n/***/ }),\n\n/***/ \"./src/SessionMonitor.js\":\n/*!*******************************!*\\\n  !*** ./src/SessionMonitor.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SessionMonitor = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar SessionMonitor = exports.SessionMonitor = function () {\n    function SessionMonitor(userManager) {\n        var _this = this;\n\n        var CheckSessionIFrameCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _CheckSessionIFrame.CheckSessionIFrame;\n        var timer = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global.timer;\n\n        _classCallCheck(this, SessionMonitor);\n\n        if (!userManager) {\n            _Log.Log.error(\"SessionMonitor.ctor: No user manager passed to SessionMonitor\");\n            throw new Error(\"userManager\");\n        }\n\n        this._userManager = userManager;\n        this._CheckSessionIFrameCtor = CheckSessionIFrameCtor;\n        this._timer = timer;\n\n        this._userManager.events.addUserLoaded(this._start.bind(this));\n        this._userManager.events.addUserUnloaded(this._stop.bind(this));\n\n        this._userManager.getUser().then(function (user) {\n            // doing this manually here since calling getUser \n            // doesn't trigger load event.\n            if (user) {\n                _this._start(user);\n            } else if (_this._settings.monitorAnonymousSession) {\n                _this._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a ctor\n                    _Log.Log.error(\"SessionMonitor ctor: error from querySessionStatus:\", err.message);\n                });\n            }\n        }).catch(function (err) {\n            // catch to suppress errors since we're in a ctor\n            _Log.Log.error(\"SessionMonitor ctor: error from getUser:\", err.message);\n        });\n    }\n\n    SessionMonitor.prototype._start = function _start(user) {\n        var _this2 = this;\n\n        var session_state = user.session_state;\n\n        if (session_state) {\n            if (user.profile) {\n                this._sub = user.profile.sub;\n                this._sid = user.profile.sid;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", sub:\", this._sub);\n            } else {\n                this._sub = undefined;\n                this._sid = undefined;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", anonymous user\");\n            }\n\n            if (!this._checkSessionIFrame) {\n                this._metadataService.getCheckSessionIframe().then(function (url) {\n                    if (url) {\n                        _Log.Log.debug(\"SessionMonitor._start: Initializing check session iframe\");\n\n                        var client_id = _this2._client_id;\n                        var interval = _this2._checkSessionInterval;\n                        var stopOnError = _this2._stopCheckSessionOnError;\n\n                        _this2._checkSessionIFrame = new _this2._CheckSessionIFrameCtor(_this2._callback.bind(_this2), client_id, url, interval, stopOnError);\n                        _this2._checkSessionIFrame.load().then(function () {\n                            _this2._checkSessionIFrame.start(session_state);\n                        });\n                    } else {\n                        _Log.Log.warn(\"SessionMonitor._start: No check session iframe found in the metadata\");\n                    }\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in non-promise callback\n                    _Log.Log.error(\"SessionMonitor._start: Error from getCheckSessionIframe:\", err.message);\n                });\n            } else {\n                this._checkSessionIFrame.start(session_state);\n            }\n        }\n    };\n\n    SessionMonitor.prototype._stop = function _stop() {\n        var _this3 = this;\n\n        this._sub = undefined;\n        this._sid = undefined;\n\n        if (this._checkSessionIFrame) {\n            _Log.Log.debug(\"SessionMonitor._stop\");\n            this._checkSessionIFrame.stop();\n        }\n\n        if (this._settings.monitorAnonymousSession) {\n            // using a timer to delay re-initialization to avoid race conditions during signout\n            var timerHandle = this._timer.setInterval(function () {\n                _this3._timer.clearInterval(timerHandle);\n\n                _this3._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this3._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a callback\n                    _Log.Log.error(\"SessionMonitor: error from querySessionStatus:\", err.message);\n                });\n            }, 1000);\n        }\n    };\n\n    SessionMonitor.prototype._callback = function _callback() {\n        var _this4 = this;\n\n        this._userManager.querySessionStatus().then(function (session) {\n            var raiseEvent = true;\n\n            if (session) {\n                if (session.sub === _this4._sub) {\n                    raiseEvent = false;\n                    _this4._checkSessionIFrame.start(session.session_state);\n\n                    if (session.sid === _this4._sid) {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:\", session.session_state);\n                    } else {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:\", session.session_state);\n                        _this4._userManager.events._raiseUserSessionChanged();\n                    }\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: Different subject signed into OP:\", session.sub);\n                }\n            } else {\n                _Log.Log.debug(\"SessionMonitor._callback: Subject no longer signed into OP\");\n            }\n\n            if (raiseEvent) {\n                if (_this4._sub) {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed out event\");\n                    _this4._userManager.events._raiseUserSignedOut();\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed in event\");\n                    _this4._userManager.events._raiseUserSignedIn();\n                }\n            }\n        }).catch(function (err) {\n            if (_this4._sub) {\n                _Log.Log.debug(\"SessionMonitor._callback: Error calling queryCurrentSigninSession; raising signed out event\", err.message);\n                _this4._userManager.events._raiseUserSignedOut();\n            }\n        });\n    };\n\n    _createClass(SessionMonitor, [{\n        key: '_settings',\n        get: function get() {\n            return this._userManager.settings;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this._userManager.metadataService;\n        }\n    }, {\n        key: '_client_id',\n        get: function get() {\n            return this._settings.client_id;\n        }\n    }, {\n        key: '_checkSessionInterval',\n        get: function get() {\n            return this._settings.checkSessionInterval;\n        }\n    }, {\n        key: '_stopCheckSessionOnError',\n        get: function get() {\n            return this._settings.stopCheckSessionOnError;\n        }\n    }]);\n\n    return SessionMonitor;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninRequest.js\":\n/*!******************************!*\\\n  !*** ./src/SigninRequest.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninRequest = exports.SigninRequest = function () {\n    function SigninRequest(_ref) {\n        var url = _ref.url,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            authority = _ref.authority,\n            data = _ref.data,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            extraQueryParams = _ref.extraQueryParams,\n            request_type = _ref.request_type,\n            client_secret = _ref.client_secret,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninRequest);\n\n        if (!url) {\n            _Log.Log.error(\"SigninRequest.ctor: No url passed\");\n            throw new Error(\"url\");\n        }\n        if (!client_id) {\n            _Log.Log.error(\"SigninRequest.ctor: No client_id passed\");\n            throw new Error(\"client_id\");\n        }\n        if (!redirect_uri) {\n            _Log.Log.error(\"SigninRequest.ctor: No redirect_uri passed\");\n            throw new Error(\"redirect_uri\");\n        }\n        if (!response_type) {\n            _Log.Log.error(\"SigninRequest.ctor: No response_type passed\");\n            throw new Error(\"response_type\");\n        }\n        if (!scope) {\n            _Log.Log.error(\"SigninRequest.ctor: No scope passed\");\n            throw new Error(\"scope\");\n        }\n        if (!authority) {\n            _Log.Log.error(\"SigninRequest.ctor: No authority passed\");\n            throw new Error(\"authority\");\n        }\n\n        var oidc = SigninRequest.isOidc(response_type);\n        var code = SigninRequest.isCode(response_type);\n\n        if (!response_mode) {\n            response_mode = SigninRequest.isCode(response_type) ? \"query\" : null;\n        }\n\n        this.state = new _SigninState.SigninState({ nonce: oidc,\n            data: data, client_id: client_id, authority: authority, redirect_uri: redirect_uri,\n            code_verifier: code,\n            request_type: request_type, response_mode: response_mode,\n            client_secret: client_secret, scope: scope, extraTokenParams: extraTokenParams, skipUserInfo: skipUserInfo });\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"client_id\", client_id);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"redirect_uri\", redirect_uri);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"response_type\", response_type);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"scope\", scope);\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        if (oidc) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"nonce\", this.state.nonce);\n        }\n        if (code) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge\", this.state.code_challenge);\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge_method\", \"S256\");\n        }\n\n        var optional = { prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values, resource: resource, request: request, request_uri: request_uri, response_mode: response_mode };\n        for (var key in optional) {\n            if (optional[key]) {\n                url = _UrlUtility.UrlUtility.addQueryParam(url, key, optional[key]);\n            }\n        }\n\n        for (var _key in extraQueryParams) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, _key, extraQueryParams[_key]);\n        }\n\n        this.url = url;\n    }\n\n    SigninRequest.isOidc = function isOidc(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"id_token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isOAuth = function isOAuth(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isCode = function isCode(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"code\";\n        });\n        return !!result[0];\n    };\n\n    return SigninRequest;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninResponse.js\":\n/*!*******************************!*\\\n  !*** ./src/SigninResponse.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninResponse = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcScope = \"openid\";\n\nvar SigninResponse = exports.SigninResponse = function () {\n    function SigninResponse(url) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n\n        _classCallCheck(this, SigninResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.code = values.code;\n        this.state = values.state;\n        this.id_token = values.id_token;\n        this.session_state = values.session_state;\n        this.access_token = values.access_token;\n        this.token_type = values.token_type;\n        this.scope = values.scope;\n        this.profile = undefined; // will be set from ResponseValidator\n\n        this.expires_in = values.expires_in;\n    }\n\n    _createClass(SigninResponse, [{\n        key: \"expires_in\",\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: \"expired\",\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: \"scopes\",\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }, {\n        key: \"isOpenIdConnect\",\n        get: function get() {\n            return this.scopes.indexOf(OidcScope) >= 0 || !!this.id_token;\n        }\n    }]);\n\n    return SigninResponse;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninState.js\":\n/*!****************************!*\\\n  !*** ./src/SigninState.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninState = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _State2 = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtilRsa.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninState = exports.SigninState = function (_State) {\n    _inherits(SigninState, _State);\n\n    function SigninState() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            nonce = _ref.nonce,\n            authority = _ref.authority,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            code_verifier = _ref.code_verifier,\n            response_mode = _ref.response_mode,\n            client_secret = _ref.client_secret,\n            scope = _ref.scope,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninState);\n\n        var _this = _possibleConstructorReturn(this, _State.call(this, arguments[0]));\n\n        if (nonce === true) {\n            _this._nonce = (0, _random2.default)();\n        } else if (nonce) {\n            _this._nonce = nonce;\n        }\n\n        if (code_verifier === true) {\n            // random() produces 32 length\n            _this._code_verifier = (0, _random2.default)() + (0, _random2.default)() + (0, _random2.default)();\n        } else if (code_verifier) {\n            _this._code_verifier = code_verifier;\n        }\n\n        if (_this.code_verifier) {\n            var hash = _JoseUtil.JoseUtil.hashString(_this.code_verifier, \"SHA256\");\n            _this._code_challenge = _JoseUtil.JoseUtil.hexToBase64Url(hash);\n        }\n\n        _this._redirect_uri = redirect_uri;\n        _this._authority = authority;\n        _this._client_id = client_id;\n        _this._response_mode = response_mode;\n        _this._client_secret = client_secret;\n        _this._scope = scope;\n        _this._extraTokenParams = extraTokenParams;\n        _this._skipUserInfo = skipUserInfo;\n        return _this;\n    }\n\n    SigninState.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"SigninState.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type,\n            nonce: this.nonce,\n            code_verifier: this.code_verifier,\n            redirect_uri: this.redirect_uri,\n            authority: this.authority,\n            client_id: this.client_id,\n            response_mode: this.response_mode,\n            client_secret: this.client_secret,\n            scope: this.scope,\n            extraTokenParams: this.extraTokenParams,\n            skipUserInfo: this.skipUserInfo\n        });\n    };\n\n    SigninState.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"SigninState.fromStorageString\");\n        var data = JSON.parse(storageString);\n        return new SigninState(data);\n    };\n\n    _createClass(SigninState, [{\n        key: 'nonce',\n        get: function get() {\n            return this._nonce;\n        }\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        }\n    }, {\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'code_verifier',\n        get: function get() {\n            return this._code_verifier;\n        }\n    }, {\n        key: 'code_challenge',\n        get: function get() {\n            return this._code_challenge;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        }\n    }, {\n        key: 'skipUserInfo',\n        get: function get() {\n            return this._skipUserInfo;\n        }\n    }]);\n\n    return SigninState;\n}(_State2.State);\n\n/***/ }),\n\n/***/ \"./src/SignoutRequest.js\":\n/*!*******************************!*\\\n  !*** ./src/SignoutRequest.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SignoutRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutRequest = exports.SignoutRequest = function SignoutRequest(_ref) {\n    var url = _ref.url,\n        id_token_hint = _ref.id_token_hint,\n        post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n        data = _ref.data,\n        extraQueryParams = _ref.extraQueryParams,\n        request_type = _ref.request_type;\n\n    _classCallCheck(this, SignoutRequest);\n\n    if (!url) {\n        _Log.Log.error(\"SignoutRequest.ctor: No url passed\");\n        throw new Error(\"url\");\n    }\n\n    if (id_token_hint) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"id_token_hint\", id_token_hint);\n    }\n\n    if (post_logout_redirect_uri) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"post_logout_redirect_uri\", post_logout_redirect_uri);\n\n        if (data) {\n            this.state = new _State.State({ data: data, request_type: request_type });\n\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        }\n    }\n\n    for (var key in extraQueryParams) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, key, extraQueryParams[key]);\n    }\n\n    this.url = url;\n};\n\n/***/ }),\n\n/***/ \"./src/SignoutResponse.js\":\n/*!********************************!*\\\n  !*** ./src/SignoutResponse.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.SignoutResponse = undefined;\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutResponse = exports.SignoutResponse = function SignoutResponse(url) {\n        _classCallCheck(this, SignoutResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, \"?\");\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.state = values.state;\n};\n\n/***/ }),\n\n/***/ \"./src/SilentRenewService.js\":\n/*!***********************************!*\\\n  !*** ./src/SilentRenewService.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SilentRenewService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SilentRenewService = exports.SilentRenewService = function () {\n    function SilentRenewService(userManager) {\n        _classCallCheck(this, SilentRenewService);\n\n        this._userManager = userManager;\n    }\n\n    SilentRenewService.prototype.start = function start() {\n        if (!this._callback) {\n            this._callback = this._tokenExpiring.bind(this);\n            this._userManager.events.addAccessTokenExpiring(this._callback);\n\n            // this will trigger loading of the user so the expiring events can be initialized\n            this._userManager.getUser().then(function (user) {\n                // deliberate nop\n            }).catch(function (err) {\n                // catch to suppress errors since we're in a ctor\n                _Log.Log.error(\"SilentRenewService.start: Error from getUser:\", err.message);\n            });\n        }\n    };\n\n    SilentRenewService.prototype.stop = function stop() {\n        if (this._callback) {\n            this._userManager.events.removeAccessTokenExpiring(this._callback);\n            delete this._callback;\n        }\n    };\n\n    SilentRenewService.prototype._tokenExpiring = function _tokenExpiring() {\n        var _this = this;\n\n        this._userManager.signinSilent().then(function (user) {\n            _Log.Log.debug(\"SilentRenewService._tokenExpiring: Silent token renewal successful\");\n        }, function (err) {\n            _Log.Log.error(\"SilentRenewService._tokenExpiring: Error from signinSilent:\", err.message);\n            _this._userManager.events._raiseSilentRenewError(err);\n        });\n    };\n\n    return SilentRenewService;\n}();\n\n/***/ }),\n\n/***/ \"./src/State.js\":\n/*!**********************!*\\\n  !*** ./src/State.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.State = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar State = exports.State = function () {\n    function State() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id = _ref.id,\n            data = _ref.data,\n            created = _ref.created,\n            request_type = _ref.request_type;\n\n        _classCallCheck(this, State);\n\n        this._id = id || (0, _random2.default)();\n        this._data = data;\n\n        if (typeof created === 'number' && created > 0) {\n            this._created = created;\n        } else {\n            this._created = parseInt(Date.now() / 1000);\n        }\n        this._request_type = request_type;\n    }\n\n    State.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"State.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type\n        });\n    };\n\n    State.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"State.fromStorageString\");\n        return new State(JSON.parse(storageString));\n    };\n\n    State.clearStaleState = function clearStaleState(storage, age) {\n\n        var cutoff = Date.now() / 1000 - age;\n\n        return storage.getAllKeys().then(function (keys) {\n            _Log.Log.debug(\"State.clearStaleState: got keys\", keys);\n\n            var promises = [];\n\n            var _loop = function _loop(i) {\n                var key = keys[i];\n                p = storage.get(key).then(function (item) {\n                    var remove = false;\n\n                    if (item) {\n                        try {\n                            var state = State.fromStorageString(item);\n\n                            _Log.Log.debug(\"State.clearStaleState: got item from key: \", key, state.created);\n\n                            if (state.created <= cutoff) {\n                                remove = true;\n                            }\n                        } catch (e) {\n                            _Log.Log.error(\"State.clearStaleState: Error parsing state for key\", key, e.message);\n                            remove = true;\n                        }\n                    } else {\n                        _Log.Log.debug(\"State.clearStaleState: no item in storage for key: \", key);\n                        remove = true;\n                    }\n\n                    if (remove) {\n                        _Log.Log.debug(\"State.clearStaleState: removed item for key: \", key);\n                        return storage.remove(key);\n                    }\n                });\n\n\n                promises.push(p);\n            };\n\n            for (var i = 0; i < keys.length; i++) {\n                var p;\n\n                _loop(i);\n            }\n\n            _Log.Log.debug(\"State.clearStaleState: waiting on promise count:\", promises.length);\n            return Promise.all(promises);\n        });\n    };\n\n    _createClass(State, [{\n        key: 'id',\n        get: function get() {\n            return this._id;\n        }\n    }, {\n        key: 'data',\n        get: function get() {\n            return this._data;\n        }\n    }, {\n        key: 'created',\n        get: function get() {\n            return this._created;\n        }\n    }, {\n        key: 'request_type',\n        get: function get() {\n            return this._request_type;\n        }\n    }]);\n\n    return State;\n}();\n\n/***/ }),\n\n/***/ \"./src/Timer.js\":\n/*!**********************!*\\\n  !*** ./src/Timer.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Timer = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _Event2 = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TimerDuration = 5; // seconds\n\nvar Timer = exports.Timer = function (_Event) {\n    _inherits(Timer, _Event);\n\n    function Timer(name) {\n        var timer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.timer;\n        var nowFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n\n        _classCallCheck(this, Timer);\n\n        var _this = _possibleConstructorReturn(this, _Event.call(this, name));\n\n        _this._timer = timer;\n\n        if (nowFunc) {\n            _this._nowFunc = nowFunc;\n        } else {\n            _this._nowFunc = function () {\n                return Date.now() / 1000;\n            };\n        }\n        return _this;\n    }\n\n    Timer.prototype.init = function init(duration) {\n        if (duration <= 0) {\n            duration = 1;\n        }\n        duration = parseInt(duration);\n\n        var expiration = this.now + duration;\n        if (this.expiration === expiration && this._timerHandle) {\n            // no need to reinitialize to same expiration, so bail out\n            _Log.Log.debug(\"Timer.init timer \" + this._name + \" skipping initialization since already initialized for expiration:\", this.expiration);\n            return;\n        }\n\n        this.cancel();\n\n        _Log.Log.debug(\"Timer.init timer \" + this._name + \" for duration:\", duration);\n        this._expiration = expiration;\n\n        // we're using a fairly short timer and then checking the expiration in the\n        // callback to handle scenarios where the browser device sleeps, and then\n        // the timers end up getting delayed.\n        var timerDuration = TimerDuration;\n        if (duration < timerDuration) {\n            timerDuration = duration;\n        }\n        this._timerHandle = this._timer.setInterval(this._callback.bind(this), timerDuration * 1000);\n    };\n\n    Timer.prototype.cancel = function cancel() {\n        if (this._timerHandle) {\n            _Log.Log.debug(\"Timer.cancel: \", this._name);\n            this._timer.clearInterval(this._timerHandle);\n            this._timerHandle = null;\n        }\n    };\n\n    Timer.prototype._callback = function _callback() {\n        var diff = this._expiration - this.now;\n        _Log.Log.debug(\"Timer.callback; \" + this._name + \" timer expires in:\", diff);\n\n        if (this._expiration <= this.now) {\n            this.cancel();\n            _Event.prototype.raise.call(this);\n        }\n    };\n\n    _createClass(Timer, [{\n        key: 'now',\n        get: function get() {\n            return parseInt(this._nowFunc());\n        }\n    }, {\n        key: 'expiration',\n        get: function get() {\n            return this._expiration;\n        }\n    }]);\n\n    return Timer;\n}(_Event2.Event);\n\n/***/ }),\n\n/***/ \"./src/TokenClient.js\":\n/*!****************************!*\\\n  !*** ./src/TokenClient.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenClient = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TokenClient = exports.TokenClient = function () {\n    function TokenClient(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenClient.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor();\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenClient.prototype.exchangeCode = function exchangeCode() {\n        var _this = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"authorization_code\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.redirect_uri = args.redirect_uri || this._settings.redirect_uri;\n\n        if (!args.code) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code passed\");\n            return Promise.reject(new Error(\"A code is required\"));\n        }\n        if (!args.redirect_uri) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No redirect_uri passed\");\n            return Promise.reject(new Error(\"A redirect_uri is required\"));\n        }\n        if (!args.code_verifier) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code_verifier passed\");\n            return Promise.reject(new Error(\"A code_verifier is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeCode: Received token endpoint\");\n\n            return _this._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeCode: response received\");\n                return response;\n            });\n        });\n    };\n\n    TokenClient.prototype.exchangeRefreshToken = function exchangeRefreshToken() {\n        var _this2 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"refresh_token\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.client_secret = args.client_secret || this._settings.client_secret;\n\n        if (!args.refresh_token) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No refresh_token passed\");\n            return Promise.reject(new Error(\"A refresh_token is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeRefreshToken: Received token endpoint\");\n\n            return _this2._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeRefreshToken: response received\");\n                return response;\n            });\n        });\n    };\n\n    return TokenClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/TokenRevocationClient.js\":\n/*!**************************************!*\\\n  !*** ./src/TokenRevocationClient.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenRevocationClient = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar AccessTokenTypeHint = \"access_token\";\nvar RefreshTokenTypeHint = \"refresh_token\";\n\nvar TokenRevocationClient = exports.TokenRevocationClient = function () {\n    function TokenRevocationClient(settings) {\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenRevocationClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenRevocationClient.ctor: No settings provided\");\n            throw new Error(\"No settings provided.\");\n        }\n\n        this._settings = settings;\n        this._XMLHttpRequestCtor = XMLHttpRequestCtor;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenRevocationClient.prototype.revoke = function revoke(token, required) {\n        var _this = this;\n\n        var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : \"access_token\";\n\n        if (!token) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: No token provided\");\n            throw new Error(\"No token provided.\");\n        }\n\n        if (type !== AccessTokenTypeHint && type != RefreshTokenTypeHint) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: Invalid token type\");\n            throw new Error(\"Invalid token type.\");\n        }\n\n        return this._metadataService.getRevocationEndpoint().then(function (url) {\n            if (!url) {\n                if (required) {\n                    _Log.Log.error(\"TokenRevocationClient.revoke: Revocation not supported\");\n                    throw new Error(\"Revocation not supported\");\n                }\n\n                // not required, so don't error and just return\n                return;\n            }\n\n            _Log.Log.debug(\"TokenRevocationClient.revoke: Revoking \" + type);\n            var client_id = _this._settings.client_id;\n            var client_secret = _this._settings.client_secret;\n            return _this._revoke(url, client_id, client_secret, token, type);\n        });\n    };\n\n    TokenRevocationClient.prototype._revoke = function _revoke(url, client_id, client_secret, token, type) {\n        var _this2 = this;\n\n        return new Promise(function (resolve, reject) {\n\n            var xhr = new _this2._XMLHttpRequestCtor();\n            xhr.open(\"POST\", url);\n\n            xhr.onload = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: HTTP response received, status\", xhr.status);\n\n                if (xhr.status === 200) {\n                    resolve();\n                } else {\n                    reject(Error(xhr.statusText + \" (\" + xhr.status + \")\"));\n                }\n            };\n            xhr.onerror = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: Network Error.\");\n                reject(\"Network Error\");\n            };\n\n            var body = \"client_id=\" + encodeURIComponent(client_id);\n            if (client_secret) {\n                body += \"&client_secret=\" + encodeURIComponent(client_secret);\n            }\n            body += \"&token_type_hint=\" + encodeURIComponent(type);\n            body += \"&token=\" + encodeURIComponent(token);\n\n            xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            xhr.send(body);\n        });\n    };\n\n    return TokenRevocationClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/UrlUtility.js\":\n/*!***************************!*\\\n  !*** ./src/UrlUtility.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UrlUtility = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UrlUtility = exports.UrlUtility = function () {\n    function UrlUtility() {\n        _classCallCheck(this, UrlUtility);\n    }\n\n    UrlUtility.addQueryParam = function addQueryParam(url, name, value) {\n        if (url.indexOf('?') < 0) {\n            url += \"?\";\n        }\n\n        if (url[url.length - 1] !== \"?\") {\n            url += \"&\";\n        }\n\n        url += encodeURIComponent(name);\n        url += \"=\";\n        url += encodeURIComponent(value);\n\n        return url;\n    };\n\n    UrlUtility.parseUrlFragment = function parseUrlFragment(value) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n        var global = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global;\n\n        if (typeof value !== 'string') {\n            value = global.location.href;\n        }\n\n        var idx = value.lastIndexOf(delimiter);\n        if (idx >= 0) {\n            value = value.substr(idx + 1);\n        }\n\n        if (delimiter === \"?\") {\n            // if we're doing query, then strip off hash fragment before we parse\n            idx = value.indexOf('#');\n            if (idx >= 0) {\n                value = value.substr(0, idx);\n            }\n        }\n\n        var params = {},\n            regex = /([^&=]+)=([^&]*)/g,\n            m;\n\n        var counter = 0;\n        while (m = regex.exec(value)) {\n            params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);\n            if (counter++ > 50) {\n                _Log.Log.error(\"UrlUtility.parseUrlFragment: response exceeded expected number of parameters\", value);\n                return {\n                    error: \"Response exceeded expected number of parameters\"\n                };\n            }\n        }\n\n        for (var prop in params) {\n            return params;\n        }\n\n        return {};\n    };\n\n    return UrlUtility;\n}();\n\n/***/ }),\n\n/***/ \"./src/User.js\":\n/*!*********************!*\\\n  !*** ./src/User.js ***!\n  \\*********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.User = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar User = exports.User = function () {\n    function User(_ref) {\n        var id_token = _ref.id_token,\n            session_state = _ref.session_state,\n            access_token = _ref.access_token,\n            refresh_token = _ref.refresh_token,\n            token_type = _ref.token_type,\n            scope = _ref.scope,\n            profile = _ref.profile,\n            expires_at = _ref.expires_at,\n            state = _ref.state;\n\n        _classCallCheck(this, User);\n\n        this.id_token = id_token;\n        this.session_state = session_state;\n        this.access_token = access_token;\n        this.refresh_token = refresh_token;\n        this.token_type = token_type;\n        this.scope = scope;\n        this.profile = profile;\n        this.expires_at = expires_at;\n        this.state = state;\n    }\n\n    User.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"User.toStorageString\");\n        return JSON.stringify({\n            id_token: this.id_token,\n            session_state: this.session_state,\n            access_token: this.access_token,\n            refresh_token: this.refresh_token,\n            token_type: this.token_type,\n            scope: this.scope,\n            profile: this.profile,\n            expires_at: this.expires_at\n        });\n    };\n\n    User.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"User.fromStorageString\");\n        return new User(JSON.parse(storageString));\n    };\n\n    _createClass(User, [{\n        key: 'expires_in',\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: 'expired',\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: 'scopes',\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }]);\n\n    return User;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserInfoService.js\":\n/*!********************************!*\\\n  !*** ./src/UserInfoService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserInfoService = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtilRsa.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserInfoService = exports.UserInfoService = function () {\n    function UserInfoService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserInfoService);\n\n        if (!settings) {\n            _Log.Log.error(\"UserInfoService.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(undefined, undefined, this._getClaimsFromJwt.bind(this));\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n    }\n\n    UserInfoService.prototype.getClaims = function getClaims(token) {\n        var _this = this;\n\n        if (!token) {\n            _Log.Log.error(\"UserInfoService.getClaims: No token passed\");\n            return Promise.reject(new Error(\"A token is required\"));\n        }\n\n        return this._metadataService.getUserInfoEndpoint().then(function (url) {\n            _Log.Log.debug(\"UserInfoService.getClaims: received userinfo url\", url);\n\n            return _this._jsonService.getJson(url, token).then(function (claims) {\n                _Log.Log.debug(\"UserInfoService.getClaims: claims received\", claims);\n                return claims;\n            });\n        });\n    };\n\n    UserInfoService.prototype._getClaimsFromJwt = function _getClaimsFromJwt(req) {\n        var _this2 = this;\n\n        try {\n            var jwt = this._joseUtil.parseJwt(req.responseText);\n            if (!jwt || !jwt.header || !jwt.payload) {\n                _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Failed to parse JWT\", jwt);\n                return Promise.reject(new Error(\"Failed to parse id_token\"));\n            }\n\n            var kid = jwt.header.kid;\n\n            var issuerPromise = void 0;\n            switch (this._settings.userInfoJwtIssuer) {\n                case 'OP':\n                    issuerPromise = this._metadataService.getIssuer();\n                    break;\n                case 'ANY':\n                    issuerPromise = Promise.resolve(jwt.payload.iss);\n                    break;\n                default:\n                    issuerPromise = Promise.resolve(this._settings.userInfoJwtIssuer);\n                    break;\n            }\n\n            return issuerPromise.then(function (issuer) {\n                _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received issuer:\" + issuer);\n\n                return _this2._metadataService.getSigningKeys().then(function (keys) {\n                    if (!keys) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No signing keys from metadata\");\n                        return Promise.reject(new Error(\"No signing keys from metadata\"));\n                    }\n\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received signing keys\");\n                    var key = void 0;\n                    if (!kid) {\n                        keys = _this2._filterByAlg(keys, jwt.header.alg);\n\n                        if (keys.length > 1) {\n                            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No kid found in id_token and more than one key found in metadata\");\n                            return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                        } else {\n                            // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                            // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                            key = keys[0];\n                        }\n                    } else {\n                        key = keys.filter(function (key) {\n                            return key.kid === kid;\n                        })[0];\n                    }\n\n                    if (!key) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No key matching kid or alg found in signing keys\");\n                        return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                    }\n\n                    var audience = _this2._settings.client_id;\n\n                    var clockSkewInSeconds = _this2._settings.clockSkew;\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                    return _this2._joseUtil.validateJwt(req.responseText, key, issuer, audience, clockSkewInSeconds, undefined, true).then(function () {\n                        _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: JWT validation successful\");\n                        return jwt.payload;\n                    });\n                });\n            });\n            return;\n        } catch (e) {\n            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Error parsing JWT response\", e.message);\n            reject(e);\n            return;\n        }\n    };\n\n    UserInfoService.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"UserInfoService._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    return UserInfoService;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserManager.js\":\n/*!****************************!*\\\n  !*** ./src/UserManager.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManager = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClient2 = __webpack_require__(/*! ./OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _UserManagerSettings = __webpack_require__(/*! ./UserManagerSettings.js */ \"./src/UserManagerSettings.js\");\n\nvar _User = __webpack_require__(/*! ./User.js */ \"./src/User.js\");\n\nvar _UserManagerEvents = __webpack_require__(/*! ./UserManagerEvents.js */ \"./src/UserManagerEvents.js\");\n\nvar _SilentRenewService = __webpack_require__(/*! ./SilentRenewService.js */ \"./src/SilentRenewService.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtilRsa.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManager = exports.UserManager = function (_OidcClient) {\n    _inherits(UserManager, _OidcClient);\n\n    function UserManager() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n        var SilentRenewServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _SilentRenewService.SilentRenewService;\n        var SessionMonitorCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _SessionMonitor.SessionMonitor;\n        var TokenRevocationClientCtor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _TokenRevocationClient.TokenRevocationClient;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n        var joseUtil = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserManager);\n\n        if (!(settings instanceof _UserManagerSettings.UserManagerSettings)) {\n            settings = new _UserManagerSettings.UserManagerSettings(settings);\n        }\n\n        var _this = _possibleConstructorReturn(this, _OidcClient.call(this, settings));\n\n        _this._events = new _UserManagerEvents.UserManagerEvents(settings);\n        _this._silentRenewService = new SilentRenewServiceCtor(_this);\n\n        // order is important for the following properties; these services depend upon the events.\n        if (_this.settings.automaticSilentRenew) {\n            _Log.Log.debug(\"UserManager.ctor: automaticSilentRenew is configured, setting up silent renew\");\n            _this.startSilentRenew();\n        }\n\n        if (_this.settings.monitorSession) {\n            _Log.Log.debug(\"UserManager.ctor: monitorSession is configured, setting up session monitor\");\n            _this._sessionMonitor = new SessionMonitorCtor(_this);\n        }\n\n        _this._tokenRevocationClient = new TokenRevocationClientCtor(_this._settings);\n        _this._tokenClient = new TokenClientCtor(_this._settings);\n        _this._joseUtil = joseUtil;\n        return _this;\n    }\n\n    UserManager.prototype.getUser = function getUser() {\n        var _this2 = this;\n\n        return this._loadUser().then(function (user) {\n            if (user) {\n                _Log.Log.info(\"UserManager.getUser: user loaded\");\n\n                _this2._events.load(user, false);\n\n                return user;\n            } else {\n                _Log.Log.info(\"UserManager.getUser: user not found in storage\");\n                return null;\n            }\n        });\n    };\n\n    UserManager.prototype.removeUser = function removeUser() {\n        var _this3 = this;\n\n        return this.storeUser(null).then(function () {\n            _Log.Log.info(\"UserManager.removeUser: user removed from storage\");\n            _this3._events.unload();\n        });\n    };\n\n    UserManager.prototype.signinRedirect = function signinRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:r\";\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signinStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signinRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signinRedirectCallback = function signinRedirectCallback(url) {\n        return this._signinEnd(url || this._redirectNavigator.url).then(function (user) {\n            if (user.profile && user.profile.sub) {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: successful, signed in sub: \", user.profile.sub);\n            } else {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: no sub\");\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopup = function signinPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:p\";\n        var url = args.redirect_uri || this.settings.popup_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinPopup: No popup_redirect_uri or redirect_uri configured\");\n            return Promise.reject(new Error(\"No popup_redirect_uri or redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.display = \"popup\";\n\n        return this._signin(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopup: signinPopup successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopup: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopupCallback = function signinPopupCallback(url) {\n        return this._signinCallback(url, this._popupNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: no sub\");\n                }\n            }\n\n            return user;\n        }).catch(function (err) {\n            _Log.Log.error( true && err.message);\n        });\n    };\n\n    UserManager.prototype.signinSilent = function signinSilent() {\n        var _this4 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\";\n        // first determine if we have a refresh token, or need to use iframe\n        return this._loadUser().then(function (user) {\n            if (user && user.refresh_token) {\n                args.refresh_token = user.refresh_token;\n                return _this4._useRefreshToken(args);\n            } else {\n                args.id_token_hint = args.id_token_hint || _this4.settings.includeIdTokenInSilentRenew && user && user.id_token;\n                if (user && _this4._settings.validateSubOnSilentRenew) {\n                    _Log.Log.debug(\"UserManager.signinSilent, subject prior to silent renew: \", user.profile.sub);\n                    args.current_sub = user.profile.sub;\n                }\n                return _this4._signinSilentIframe(args);\n            }\n        });\n    };\n\n    UserManager.prototype._useRefreshToken = function _useRefreshToken() {\n        var _this5 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        return this._tokenClient.exchangeRefreshToken(args).then(function (result) {\n            if (!result) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No response returned from token endpoint\");\n                return Promise.reject(\"No response returned from token endpoint\");\n            }\n            if (!result.access_token) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No access token returned from token endpoint\");\n                return Promise.reject(\"No access token returned from token endpoint\");\n            }\n\n            return _this5._loadUser().then(function (user) {\n                if (user) {\n                    var idTokenValidation = Promise.resolve();\n                    if (result.id_token) {\n                        idTokenValidation = _this5._validateIdTokenFromTokenRefreshToken(user.profile, result.id_token);\n                    }\n\n                    return idTokenValidation.then(function () {\n                        _Log.Log.debug(\"UserManager._useRefreshToken: refresh token response success\");\n                        user.id_token = result.id_token;\n                        user.access_token = result.access_token;\n                        user.refresh_token = result.refresh_token || user.refresh_token;\n                        user.expires_in = result.expires_in;\n\n                        return _this5.storeUser(user).then(function () {\n                            _this5._events.load(user);\n                            return user;\n                        });\n                    });\n                } else {\n                    return null;\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._validateIdTokenFromTokenRefreshToken = function _validateIdTokenFromTokenRefreshToken(profile, id_token) {\n        var _this6 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            return _this6._joseUtil.validateJwtAttributes(id_token, issuer, _this6._settings.client_id, _this6._settings.clockSkew).then(function (payload) {\n                if (!payload) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: Failed to validate id_token\");\n                    return Promise.reject(new Error(\"Failed to validate id_token\"));\n                }\n                if (payload.sub !== profile.sub) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: sub in id_token does not match current sub\");\n                    return Promise.reject(new Error(\"sub in id_token does not match current sub\"));\n                }\n                if (payload.auth_time && payload.auth_time !== profile.auth_time) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: auth_time in id_token does not match original auth_time\");\n                    return Promise.reject(new Error(\"auth_time in id_token does not match original auth_time\"));\n                }\n                if (payload.azp && payload.azp !== profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp in id_token does not match original azp\");\n                    return Promise.reject(new Error(\"azp in id_token does not match original azp\"));\n                }\n                if (!payload.azp && profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp not in id_token, but present in original id_token\");\n                    return Promise.reject(new Error(\"azp not in id_token, but present in original id_token\"));\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._signinSilentIframe = function _signinSilentIframe() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinSilent: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = args.prompt || \"none\";\n\n        return this._signin(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilent: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilent: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinSilentCallback = function signinSilentCallback(url) {\n        return this._signinCallback(url, this._iframeNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinCallback = function signinCallback(url) {\n        var _this7 = this;\n\n        return this.readSigninResponseState(url).then(function (_ref) {\n            var state = _ref.state,\n                response = _ref.response;\n\n            if (state.request_type === \"si:r\") {\n                return _this7.signinRedirectCallback(url);\n            }\n            if (state.request_type === \"si:p\") {\n                return _this7.signinPopupCallback(url);\n            }\n            if (state.request_type === \"si:s\") {\n                return _this7.signinSilentCallback(url);\n            }\n            return Promise.reject(new Error(\"invalid response_type in state\"));\n        });\n    };\n\n    UserManager.prototype.signoutCallback = function signoutCallback(url, keepOpen) {\n        var _this8 = this;\n\n        return this.readSignoutResponseState(url).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            if (state) {\n                if (state.request_type === \"so:r\") {\n                    return _this8.signoutRedirectCallback(url);\n                }\n                if (state.request_type === \"so:p\") {\n                    return _this8.signoutPopupCallback(url, keepOpen);\n                }\n                return Promise.reject(new Error(\"invalid response_type in state\"));\n            }\n            return response;\n        });\n    };\n\n    UserManager.prototype.querySessionStatus = function querySessionStatus() {\n        var _this9 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\"; // this acts like a signin silent\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.querySessionStatus: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = \"none\";\n        args.response_type = args.response_type || this.settings.query_status_response_type;\n        args.scope = args.scope || \"openid\";\n        args.skipUserInfo = true;\n\n        return this._signinStart(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (navResponse) {\n            return _this9.processSigninResponse(navResponse.url).then(function (signinResponse) {\n                _Log.Log.debug(\"UserManager.querySessionStatus: got signin response\");\n\n                if (signinResponse.session_state && signinResponse.profile.sub) {\n                    _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for sub: \", signinResponse.profile.sub);\n                    return {\n                        session_state: signinResponse.session_state,\n                        sub: signinResponse.profile.sub,\n                        sid: signinResponse.profile.sid\n                    };\n                } else {\n                    _Log.Log.info(\"querySessionStatus successful, user not authenticated\");\n                }\n            }).catch(function (err) {\n                if (err.session_state && _this9.settings.monitorAnonymousSession) {\n                    if (err.message == \"login_required\" || err.message == \"consent_required\" || err.message == \"interaction_required\" || err.message == \"account_selection_required\") {\n                        _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for anonymous user\");\n                        return {\n                            session_state: err.session_state\n                        };\n                    }\n                }\n\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signin = function _signin(args, navigator) {\n        var _this10 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signinStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this10._signinEnd(navResponse.url, args);\n        });\n    };\n\n    UserManager.prototype._signinStart = function _signinStart(args, navigator) {\n        var _this11 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signinStart: got navigator window handle\");\n\n            return _this11.createSigninRequest(args).then(function (signinRequest) {\n                _Log.Log.debug(\"UserManager._signinStart: got signin request\");\n\n                navigatorParams.url = signinRequest.url;\n                navigatorParams.id = signinRequest.state.id;\n\n                return handle.navigate(navigatorParams);\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signinStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signinEnd = function _signinEnd(url) {\n        var _this12 = this;\n\n        var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n        return this.processSigninResponse(url).then(function (signinResponse) {\n            _Log.Log.debug(\"UserManager._signinEnd: got signin response\");\n\n            var user = new _User.User(signinResponse);\n\n            if (args.current_sub) {\n                if (args.current_sub !== user.profile.sub) {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user does not match user returned from signin. sub from signin: \", user.profile.sub);\n                    return Promise.reject(new Error(\"login_required\"));\n                } else {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user matches user returned from signin\");\n                }\n            }\n\n            return _this12.storeUser(user).then(function () {\n                _Log.Log.debug(\"UserManager._signinEnd: user stored\");\n\n                _this12._events.load(user);\n\n                return user;\n            });\n        });\n    };\n\n    UserManager.prototype._signinCallback = function _signinCallback(url, navigator) {\n        _Log.Log.debug(\"UserManager._signinCallback\");\n        return navigator.callback(url);\n    };\n\n    UserManager.prototype.signoutRedirect = function signoutRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:r\";\n        var postLogoutRedirectUri = args.post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        if (postLogoutRedirectUri) {\n            args.post_logout_redirect_uri = postLogoutRedirectUri;\n        }\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signoutStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signoutRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutRedirectCallback = function signoutRedirectCallback(url) {\n        return this._signoutEnd(url || this._redirectNavigator.url).then(function (response) {\n            _Log.Log.info(\"UserManager.signoutRedirectCallback: successful\");\n            return response;\n        });\n    };\n\n    UserManager.prototype.signoutPopup = function signoutPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:p\";\n        var url = args.post_logout_redirect_uri || this.settings.popup_post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        args.post_logout_redirect_uri = url;\n        args.display = \"popup\";\n        if (args.post_logout_redirect_uri) {\n            // we're putting a dummy entry in here because we\n            // need a unique id from the state for notification\n            // to the parent window, which is necessary if we\n            // plan to return back to the client after signout\n            // and so we can close the popup after signout\n            args.state = args.state || {};\n        }\n\n        return this._signout(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopup: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutPopupCallback = function signoutPopupCallback(url, keepOpen) {\n        if (typeof keepOpen === 'undefined' && typeof url === 'boolean') {\n            keepOpen = url;\n            url = null;\n        }\n\n        var delimiter = '?';\n        return this._popupNavigator.callback(url, keepOpen, delimiter).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopupCallback: successful\");\n        });\n    };\n\n    UserManager.prototype._signout = function _signout(args, navigator) {\n        var _this13 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signoutStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this13._signoutEnd(navResponse.url);\n        });\n    };\n\n    UserManager.prototype._signoutStart = function _signoutStart() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var _this14 = this;\n\n        var navigator = arguments[1];\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signoutStart: got navigator window handle\");\n\n            return _this14._loadUser().then(function (user) {\n                _Log.Log.debug(\"UserManager._signoutStart: loaded current user from storage\");\n\n                var revokePromise = _this14._settings.revokeAccessTokenOnSignout ? _this14._revokeInternal(user) : Promise.resolve();\n                return revokePromise.then(function () {\n\n                    var id_token = args.id_token_hint || user && user.id_token;\n                    if (id_token) {\n                        _Log.Log.debug(\"UserManager._signoutStart: Setting id_token into signout request\");\n                        args.id_token_hint = id_token;\n                    }\n\n                    return _this14.removeUser().then(function () {\n                        _Log.Log.debug(\"UserManager._signoutStart: user removed, creating signout request\");\n\n                        return _this14.createSignoutRequest(args).then(function (signoutRequest) {\n                            _Log.Log.debug(\"UserManager._signoutStart: got signout request\");\n\n                            navigatorParams.url = signoutRequest.url;\n                            if (signoutRequest.state) {\n                                navigatorParams.id = signoutRequest.state.id;\n                            }\n                            return handle.navigate(navigatorParams);\n                        });\n                    });\n                });\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signoutStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signoutEnd = function _signoutEnd(url) {\n        return this.processSignoutResponse(url).then(function (signoutResponse) {\n            _Log.Log.debug(\"UserManager._signoutEnd: got signout response\");\n\n            return signoutResponse;\n        });\n    };\n\n    UserManager.prototype.revokeAccessToken = function revokeAccessToken() {\n        var _this15 = this;\n\n        return this._loadUser().then(function (user) {\n            return _this15._revokeInternal(user, true).then(function (success) {\n                if (success) {\n                    _Log.Log.debug(\"UserManager.revokeAccessToken: removing token properties from user and re-storing\");\n\n                    user.access_token = null;\n                    user.refresh_token = null;\n                    user.expires_at = null;\n                    user.token_type = null;\n\n                    return _this15.storeUser(user).then(function () {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: user stored\");\n                        _this15._events.load(user);\n                    });\n                }\n            });\n        }).then(function () {\n            _Log.Log.info(\"UserManager.revokeAccessToken: access token revoked successfully\");\n        });\n    };\n\n    UserManager.prototype._revokeInternal = function _revokeInternal(user, required) {\n        var _this16 = this;\n\n        if (user) {\n            var access_token = user.access_token;\n            var refresh_token = user.refresh_token;\n\n            return this._revokeAccessTokenInternal(access_token, required).then(function (atSuccess) {\n                return _this16._revokeRefreshTokenInternal(refresh_token, required).then(function (rtSuccess) {\n                    if (!atSuccess && !rtSuccess) {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: no need to revoke due to no token(s), or JWT format\");\n                    }\n\n                    return atSuccess || rtSuccess;\n                });\n            });\n        }\n\n        return Promise.resolve(false);\n    };\n\n    UserManager.prototype._revokeAccessTokenInternal = function _revokeAccessTokenInternal(access_token, required) {\n        // check for JWT vs. reference token\n        if (!access_token || access_token.indexOf('.') >= 0) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(access_token, required).then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype._revokeRefreshTokenInternal = function _revokeRefreshTokenInternal(refresh_token, required) {\n        if (!refresh_token) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(refresh_token, required, \"refresh_token\").then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype.startSilentRenew = function startSilentRenew() {\n        this._silentRenewService.start();\n    };\n\n    UserManager.prototype.stopSilentRenew = function stopSilentRenew() {\n        this._silentRenewService.stop();\n    };\n\n    UserManager.prototype._loadUser = function _loadUser() {\n        return this._userStore.get(this._userStoreKey).then(function (storageString) {\n            if (storageString) {\n                _Log.Log.debug(\"UserManager._loadUser: user storageString loaded\");\n                return _User.User.fromStorageString(storageString);\n            }\n\n            _Log.Log.debug(\"UserManager._loadUser: no user storageString\");\n            return null;\n        });\n    };\n\n    UserManager.prototype.storeUser = function storeUser(user) {\n        if (user) {\n            _Log.Log.debug(\"UserManager.storeUser: storing user\");\n\n            var storageString = user.toStorageString();\n            return this._userStore.set(this._userStoreKey, storageString);\n        } else {\n            _Log.Log.debug(\"storeUser.storeUser: removing user\");\n            return this._userStore.remove(this._userStoreKey);\n        }\n    };\n\n    _createClass(UserManager, [{\n        key: '_redirectNavigator',\n        get: function get() {\n            return this.settings.redirectNavigator;\n        }\n    }, {\n        key: '_popupNavigator',\n        get: function get() {\n            return this.settings.popupNavigator;\n        }\n    }, {\n        key: '_iframeNavigator',\n        get: function get() {\n            return this.settings.iframeNavigator;\n        }\n    }, {\n        key: '_userStore',\n        get: function get() {\n            return this.settings.userStore;\n        }\n    }, {\n        key: 'events',\n        get: function get() {\n            return this._events;\n        }\n    }, {\n        key: '_userStoreKey',\n        get: function get() {\n            return 'user:' + this.settings.authority + ':' + this.settings.client_id;\n        }\n    }]);\n\n    return UserManager;\n}(_OidcClient2.OidcClient);\n\n/***/ }),\n\n/***/ \"./src/UserManagerEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/UserManagerEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _AccessTokenEvents2 = __webpack_require__(/*! ./AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _Event = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManagerEvents = exports.UserManagerEvents = function (_AccessTokenEvents) {\n    _inherits(UserManagerEvents, _AccessTokenEvents);\n\n    function UserManagerEvents(settings) {\n        _classCallCheck(this, UserManagerEvents);\n\n        var _this = _possibleConstructorReturn(this, _AccessTokenEvents.call(this, settings));\n\n        _this._userLoaded = new _Event.Event(\"User loaded\");\n        _this._userUnloaded = new _Event.Event(\"User unloaded\");\n        _this._silentRenewError = new _Event.Event(\"Silent renew error\");\n        _this._userSignedIn = new _Event.Event(\"User signed in\");\n        _this._userSignedOut = new _Event.Event(\"User signed out\");\n        _this._userSessionChanged = new _Event.Event(\"User session changed\");\n        return _this;\n    }\n\n    UserManagerEvents.prototype.load = function load(user) {\n        var raiseEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n        _Log.Log.debug(\"UserManagerEvents.load\");\n        _AccessTokenEvents.prototype.load.call(this, user);\n        if (raiseEvent) {\n            this._userLoaded.raise(user);\n        }\n    };\n\n    UserManagerEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"UserManagerEvents.unload\");\n        _AccessTokenEvents.prototype.unload.call(this);\n        this._userUnloaded.raise();\n    };\n\n    UserManagerEvents.prototype.addUserLoaded = function addUserLoaded(cb) {\n        this._userLoaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserLoaded = function removeUserLoaded(cb) {\n        this._userLoaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addUserUnloaded = function addUserUnloaded(cb) {\n        this._userUnloaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserUnloaded = function removeUserUnloaded(cb) {\n        this._userUnloaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addSilentRenewError = function addSilentRenewError(cb) {\n        this._silentRenewError.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeSilentRenewError = function removeSilentRenewError(cb) {\n        this._silentRenewError.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseSilentRenewError = function _raiseSilentRenewError(e) {\n        _Log.Log.debug(\"UserManagerEvents._raiseSilentRenewError\", e.message);\n        this._silentRenewError.raise(e);\n    };\n\n    UserManagerEvents.prototype.addUserSignedIn = function addUserSignedIn(cb) {\n        this._userSignedIn.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedIn = function removeUserSignedIn(cb) {\n        this._userSignedIn.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedIn = function _raiseUserSignedIn() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedIn\");\n        this._userSignedIn.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSignedOut = function addUserSignedOut(cb) {\n        this._userSignedOut.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedOut = function removeUserSignedOut(cb) {\n        this._userSignedOut.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedOut = function _raiseUserSignedOut() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedOut\");\n        this._userSignedOut.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSessionChanged = function addUserSessionChanged(cb) {\n        this._userSessionChanged.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSessionChanged = function removeUserSessionChanged(cb) {\n        this._userSessionChanged.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSessionChanged = function _raiseUserSessionChanged() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSessionChanged\");\n        this._userSessionChanged.raise();\n    };\n\n    return UserManagerEvents;\n}(_AccessTokenEvents2.AccessTokenEvents);\n\n/***/ }),\n\n/***/ \"./src/UserManagerSettings.js\":\n/*!************************************!*\\\n  !*** ./src/UserManagerSettings.js ***!\n  \\************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerSettings = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings2 = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _RedirectNavigator = __webpack_require__(/*! ./RedirectNavigator.js */ \"./src/RedirectNavigator.js\");\n\nvar _PopupNavigator = __webpack_require__(/*! ./PopupNavigator.js */ \"./src/PopupNavigator.js\");\n\nvar _IFrameNavigator = __webpack_require__(/*! ./IFrameNavigator.js */ \"./src/IFrameNavigator.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60;\nvar DefaultCheckSessionInterval = 2000;\n\nvar UserManagerSettings = exports.UserManagerSettings = function (_OidcClientSettings) {\n    _inherits(UserManagerSettings, _OidcClientSettings);\n\n    function UserManagerSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            popup_redirect_uri = _ref.popup_redirect_uri,\n            popup_post_logout_redirect_uri = _ref.popup_post_logout_redirect_uri,\n            popupWindowFeatures = _ref.popupWindowFeatures,\n            popupWindowTarget = _ref.popupWindowTarget,\n            silent_redirect_uri = _ref.silent_redirect_uri,\n            silentRequestTimeout = _ref.silentRequestTimeout,\n            _ref$automaticSilentR = _ref.automaticSilentRenew,\n            automaticSilentRenew = _ref$automaticSilentR === undefined ? false : _ref$automaticSilentR,\n            _ref$validateSubOnSil = _ref.validateSubOnSilentRenew,\n            validateSubOnSilentRenew = _ref$validateSubOnSil === undefined ? false : _ref$validateSubOnSil,\n            _ref$includeIdTokenIn = _ref.includeIdTokenInSilentRenew,\n            includeIdTokenInSilentRenew = _ref$includeIdTokenIn === undefined ? true : _ref$includeIdTokenIn,\n            _ref$monitorSession = _ref.monitorSession,\n            monitorSession = _ref$monitorSession === undefined ? true : _ref$monitorSession,\n            _ref$monitorAnonymous = _ref.monitorAnonymousSession,\n            monitorAnonymousSession = _ref$monitorAnonymous === undefined ? false : _ref$monitorAnonymous,\n            _ref$checkSessionInte = _ref.checkSessionInterval,\n            checkSessionInterval = _ref$checkSessionInte === undefined ? DefaultCheckSessionInterval : _ref$checkSessionInte,\n            _ref$stopCheckSession = _ref.stopCheckSessionOnError,\n            stopCheckSessionOnError = _ref$stopCheckSession === undefined ? true : _ref$stopCheckSession,\n            query_status_response_type = _ref.query_status_response_type,\n            _ref$revokeAccessToke = _ref.revokeAccessTokenOnSignout,\n            revokeAccessTokenOnSignout = _ref$revokeAccessToke === undefined ? false : _ref$revokeAccessToke,\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$redirectNavigato = _ref.redirectNavigator,\n            redirectNavigator = _ref$redirectNavigato === undefined ? new _RedirectNavigator.RedirectNavigator() : _ref$redirectNavigato,\n            _ref$popupNavigator = _ref.popupNavigator,\n            popupNavigator = _ref$popupNavigator === undefined ? new _PopupNavigator.PopupNavigator() : _ref$popupNavigator,\n            _ref$iframeNavigator = _ref.iframeNavigator,\n            iframeNavigator = _ref$iframeNavigator === undefined ? new _IFrameNavigator.IFrameNavigator() : _ref$iframeNavigator,\n            _ref$userStore = _ref.userStore,\n            userStore = _ref$userStore === undefined ? new _WebStorageStateStore.WebStorageStateStore({ store: _Global.Global.sessionStorage }) : _ref$userStore;\n\n        _classCallCheck(this, UserManagerSettings);\n\n        var _this = _possibleConstructorReturn(this, _OidcClientSettings.call(this, arguments[0]));\n\n        _this._popup_redirect_uri = popup_redirect_uri;\n        _this._popup_post_logout_redirect_uri = popup_post_logout_redirect_uri;\n        _this._popupWindowFeatures = popupWindowFeatures;\n        _this._popupWindowTarget = popupWindowTarget;\n\n        _this._silent_redirect_uri = silent_redirect_uri;\n        _this._silentRequestTimeout = silentRequestTimeout;\n        _this._automaticSilentRenew = automaticSilentRenew;\n        _this._validateSubOnSilentRenew = validateSubOnSilentRenew;\n        _this._includeIdTokenInSilentRenew = includeIdTokenInSilentRenew;\n        _this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        _this._monitorSession = monitorSession;\n        _this._monitorAnonymousSession = monitorAnonymousSession;\n        _this._checkSessionInterval = checkSessionInterval;\n        _this._stopCheckSessionOnError = stopCheckSessionOnError;\n        if (query_status_response_type) {\n            _this._query_status_response_type = query_status_response_type;\n        } else if (arguments[0] && arguments[0].response_type) {\n            _this._query_status_response_type = _SigninRequest.SigninRequest.isOidc(arguments[0].response_type) ? \"id_token\" : \"code\";\n        } else {\n            _this._query_status_response_type = \"id_token\";\n        }\n        _this._revokeAccessTokenOnSignout = revokeAccessTokenOnSignout;\n\n        _this._redirectNavigator = redirectNavigator;\n        _this._popupNavigator = popupNavigator;\n        _this._iframeNavigator = iframeNavigator;\n\n        _this._userStore = userStore;\n        return _this;\n    }\n\n    _createClass(UserManagerSettings, [{\n        key: 'popup_redirect_uri',\n        get: function get() {\n            return this._popup_redirect_uri;\n        }\n    }, {\n        key: 'popup_post_logout_redirect_uri',\n        get: function get() {\n            return this._popup_post_logout_redirect_uri;\n        }\n    }, {\n        key: 'popupWindowFeatures',\n        get: function get() {\n            return this._popupWindowFeatures;\n        }\n    }, {\n        key: 'popupWindowTarget',\n        get: function get() {\n            return this._popupWindowTarget;\n        }\n    }, {\n        key: 'silent_redirect_uri',\n        get: function get() {\n            return this._silent_redirect_uri;\n        }\n    }, {\n        key: 'silentRequestTimeout',\n        get: function get() {\n            return this._silentRequestTimeout;\n        }\n    }, {\n        key: 'automaticSilentRenew',\n        get: function get() {\n            return this._automaticSilentRenew;\n        }\n    }, {\n        key: 'validateSubOnSilentRenew',\n        get: function get() {\n            return this._validateSubOnSilentRenew;\n        }\n    }, {\n        key: 'includeIdTokenInSilentRenew',\n        get: function get() {\n            return this._includeIdTokenInSilentRenew;\n        }\n    }, {\n        key: 'accessTokenExpiringNotificationTime',\n        get: function get() {\n            return this._accessTokenExpiringNotificationTime;\n        }\n    }, {\n        key: 'monitorSession',\n        get: function get() {\n            return this._monitorSession;\n        }\n    }, {\n        key: 'monitorAnonymousSession',\n        get: function get() {\n            return this._monitorAnonymousSession;\n        }\n    }, {\n        key: 'checkSessionInterval',\n        get: function get() {\n            return this._checkSessionInterval;\n        }\n    }, {\n        key: 'stopCheckSessionOnError',\n        get: function get() {\n            return this._stopCheckSessionOnError;\n        }\n    }, {\n        key: 'query_status_response_type',\n        get: function get() {\n            return this._query_status_response_type;\n        }\n    }, {\n        key: 'revokeAccessTokenOnSignout',\n        get: function get() {\n            return this._revokeAccessTokenOnSignout;\n        }\n    }, {\n        key: 'redirectNavigator',\n        get: function get() {\n            return this._redirectNavigator;\n        }\n    }, {\n        key: 'popupNavigator',\n        get: function get() {\n            return this._popupNavigator;\n        }\n    }, {\n        key: 'iframeNavigator',\n        get: function get() {\n            return this._iframeNavigator;\n        }\n    }, {\n        key: 'userStore',\n        get: function get() {\n            return this._userStore;\n        }\n    }]);\n\n    return UserManagerSettings;\n}(_OidcClientSettings2.OidcClientSettings);\n\n/***/ }),\n\n/***/ \"./src/WebStorageStateStore.js\":\n/*!*************************************!*\\\n  !*** ./src/WebStorageStateStore.js ***!\n  \\*************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.WebStorageStateStore = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar WebStorageStateStore = exports.WebStorageStateStore = function () {\n    function WebStorageStateStore() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$prefix = _ref.prefix,\n            prefix = _ref$prefix === undefined ? \"oidc.\" : _ref$prefix,\n            _ref$store = _ref.store,\n            store = _ref$store === undefined ? _Global.Global.localStorage : _ref$store;\n\n        _classCallCheck(this, WebStorageStateStore);\n\n        this._store = store;\n        this._prefix = prefix;\n    }\n\n    WebStorageStateStore.prototype.set = function set(key, value) {\n        _Log.Log.debug(\"WebStorageStateStore.set\", key);\n\n        key = this._prefix + key;\n\n        this._store.setItem(key, value);\n\n        return Promise.resolve();\n    };\n\n    WebStorageStateStore.prototype.get = function get(key) {\n        _Log.Log.debug(\"WebStorageStateStore.get\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.remove = function remove(key) {\n        _Log.Log.debug(\"WebStorageStateStore.remove\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n        this._store.removeItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.getAllKeys = function getAllKeys() {\n        _Log.Log.debug(\"WebStorageStateStore.getAllKeys\");\n\n        var keys = [];\n\n        for (var index = 0; index < this._store.length; index++) {\n            var key = this._store.key(index);\n\n            if (key.indexOf(this._prefix) === 0) {\n                keys.push(key.substr(this._prefix.length));\n            }\n        }\n\n        return Promise.resolve(keys);\n    };\n\n    return WebStorageStateStore;\n}();\n\n/***/ }),\n\n/***/ \"./src/crypto/rsa.js\":\n/*!***************************!*\\\n  !*** ./src/crypto/rsa.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AllowedSigningAlgs = exports.b64tohex = exports.hextob64u = exports.crypto = exports.X509 = exports.KeyUtil = exports.jws = undefined;\n\nvar _jsbn = __webpack_require__(/*! jsbn */ \"./node_modules/jsbn/index.js\");\n\nvar _jsbn2 = _interopRequireDefault(_jsbn);\n\nvar _sha = __webpack_require__(/*! crypto-js/sha256 */ \"./node_modules/crypto-js/sha256.js\");\n\nvar _sha2 = _interopRequireDefault(_sha);\n\nvar _base64Js = __webpack_require__(/*! base64-js */ \"./node_modules/base64-js/index.js\");\n\nvar _base64Js2 = _interopRequireDefault(_base64Js);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar BigInteger = _jsbn2.default.BigInteger;\n\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\n/*\nBased on the work of Auth0\nhttps://github.com/auth0/idtoken-verifier\nhttps://github.com/auth0/idtoken-verifier/blob/master/LICENSE\nWhich is based on the work of Tom Wu\nhttp://www-cs-students.stanford.edu/~tjw/jsbn/\nhttp://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE\n*/\n\n/*\n * To support most basic OpenId use cases (using RSA256), we can get away without\n * requiring the full jrsasign feature set (and resulting massive bundle).\n *\n * - Support RSA 256 algorithm (optionally could support RSA* family)\n * - Parse JWT tokens using the (n) parameter.\n * - Verify signature of id_tokens\n * - Verify at_hash of access_tokens\n * - Perform common base64 encoding/decoding tasks.\n */\n\nvar b64map = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nvar b64pad = \"=\";\n\nvar Base64 = {\n    b64tohex: function b64tohex(s) {\n        var ret = \"\";\n        var i;\n        var k = 0; // b64 state, 0-3\n        var slop;\n        for (i = 0; i < s.length; ++i) {\n            if (s.charAt(i) === b64pad) break;\n            var v = b64map.indexOf(s.charAt(i));\n            if (v < 0) continue;\n            if (k === 0) {\n                ret += String.fromCharCode(v >> 2);\n                slop = v & 3;\n                k = 1;\n            } else if (k === 1) {\n                ret += String.fromCharCode(slop << 2 | v >> 4);\n                slop = v & 0xf;\n                k = 2;\n            } else if (k === 2) {\n                ret += String.fromCharCode(slop);\n                ret += String.fromCharCode(v >> 2);\n                slop = v & 3;\n                k = 3;\n            } else {\n                ret += String.fromCharCode(slop << 2 | v >> 4);\n                ret += String.fromCharCode(v & 0xf);\n                k = 0;\n            }\n        }\n        if (k === 1) ret += String.fromCharCode(slop << 2);\n        return ret;\n    },\n    hexToBase64: function hexToBase64(h) {\n        var i;\n        var c;\n        var ret = \"\";\n        for (i = 0; i + 3 <= h.length; i += 3) {\n            c = parseInt(h.substring(i, i + 3), 16);\n            ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);\n        }\n        if (i + 1 === h.length) {\n            c = parseInt(h.substring(i, i + 1), 16);\n            ret += b64map.charAt(c << 2);\n        } else if (i + 2 === h.length) {\n            c = parseInt(h.substring(i, i + 2), 16);\n            ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);\n        }\n        if (b64pad) while ((ret.length & 3) > 0) {\n            ret += b64pad;\n        }return ret;\n    },\n    padding: function padding(str) {\n        var mod = str.length % 4;\n        var pad = 4 - mod;\n\n        if (mod === 0) {\n            return str;\n        }\n\n        return str + new Array(1 + pad).join('=');\n    },\n    byteArrayToHex: function byteArrayToHex(raw) {\n        var HEX = '';\n\n        for (var i = 0; i < raw.length; i++) {\n            var _hex = raw[i].toString(16);\n            HEX += _hex.length === 2 ? _hex : '0' + _hex;\n        }\n\n        return HEX;\n    },\n    decodeToHEX: function decodeToHEX(str) {\n        return Base64.byteArrayToHex(_base64Js2.default.toByteArray(Base64.padding(str)));\n    },\n    base64ToBase64Url: function base64ToBase64Url(s) {\n        s = s.replace(/=/g, \"\");\n        s = s.replace(/\\+/g, \"-\");\n        s = s.replace(/\\//g, \"_\");\n        return s;\n    },\n    urlDecode: function urlDecode(str) {\n        str = str.replace(/-/g, '+') // Convert '-' to '+'\n        .replace(/_/g, '/') // Convert '_' to '/'\n        .replace(/\\s/g, ' '); // Convert '\\s' to ' '\n\n        return atob(str);\n    }\n};\n\nvar DigestInfoHead = {\n    sha1: '3021300906052b0e03021a05000414',\n    sha224: '302d300d06096086480165030402040500041c',\n    sha256: '3031300d060960864801650304020105000420',\n    sha384: '3041300d060960864801650304020205000430',\n    sha512: '3051300d060960864801650304020305000440',\n    md2: '3020300c06082a864886f70d020205000410',\n    md5: '3020300c06082a864886f70d020505000410',\n    ripemd160: '3021300906052b2403020105000414'\n};\n\nvar DigestAlgs = {\n    sha256: _sha2.default,\n    SHA256: _sha2.default\n};\n\nfunction RSAVerifier(modulus, exp) {\n    this.n = null;\n    this.e = 0;\n\n    if (modulus != null && exp != null && modulus.length > 0 && exp.length > 0) {\n        this.n = new BigInteger(modulus, 16);\n        this.e = parseInt(exp, 16);\n    } else {\n        throw new Error('Invalid key data');\n    }\n}\n\nfunction getAlgorithmFromDigest(hDigestInfo) {\n    for (var algName in DigestInfoHead) {\n        var head = DigestInfoHead[algName];\n        var len = head.length;\n\n        if (hDigestInfo.substring(0, len) === head) {\n            return {\n                alg: algName,\n                hash: hDigestInfo.substring(len)\n            };\n        }\n    }\n    return [];\n}\n\nRSAVerifier.prototype.verify = function (msg, encsig) {\n    encsig = Base64.decodeToHEX(encsig);\n    encsig = encsig.replace(/[^0-9a-f]|[\\s\\n]]/ig, '');\n\n    var sig = new BigInteger(encsig, 16);\n\n    if (sig.bitLength() > this.n.bitLength()) {\n        throw new Error('Signature does not match with the key modulus.');\n    }\n\n    var decryptedSig = sig.modPowInt(this.e, this.n);\n    var digest = decryptedSig.toString(16).replace(/^1f+00/, '');\n    var digestInfo = getAlgorithmFromDigest(digest);\n\n    if (digestInfo.length === 0) {\n        return false;\n    }\n\n    if (!DigestAlgs.hasOwnProperty(digestInfo.alg)) {\n        throw new Error('Hashing algorithm is not supported.');\n    }\n\n    var msgHash = DigestAlgs[digestInfo.alg](msg).toString();\n    return digestInfo.hash === msgHash;\n};\n\nvar AllowedSigningAlgs = ['RS256'];\n\nvar jws = {\n    JWS: {\n        parse: function parse(token) {\n            var parts = token.split('.');\n            var header;\n            var payload;\n\n            // This diverges from Auth0's implementation, which throws rather than\n            // returning undefined\n            if (parts.length !== 3) {\n                return undefined;\n            }\n\n            try {\n                header = JSON.parse(Base64.urlDecode(parts[0]));\n                payload = JSON.parse(Base64.urlDecode(parts[1]));\n            } catch (e) {\n                return new Error('Token header or payload is not valid JSON');\n            }\n\n            return {\n                headerObj: header,\n                payloadObj: payload\n            };\n        },\n        verify: function verify(jwt, key) {\n            var allowedSigningAlgs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n\n            allowedSigningAlgs.forEach(function (alg) {\n                if (AllowedSigningAlgs.indexOf(alg) === -1) {\n                    throw new Error('Invalid signing algorithm: ' + alg);\n                }\n            });\n            var verify = new RSAVerifier(key.n, key.e);\n            var parts = jwt.split('.');\n\n            var headerAndPayload = [parts[0], parts[1]].join('.');\n            return verify.verify(headerAndPayload, parts[2]);\n        }\n    }\n};\n\nvar KeyUtil = {\n    /**\n     * Returns decoded keys in Hex format for use in crypto functions.\n     * Supports modulus/exponent-style keys.\n     *\n     * @param {object} key the security key\n     * @returns\n     */\n    getKey: function getKey(key) {\n        if (key.kty === 'RSA') {\n            return {\n                e: Base64.decodeToHEX(key.e),\n                n: Base64.decodeToHEX(key.n)\n            };\n        }\n\n        return null;\n    }\n};\n\nvar X509 = {\n    getPublicKeyFromCertPEM: function getPublicKeyFromCertPEM() {\n        throw new Error('Not implemented. Use the full oidc-client library if you need support for X509.');\n    }\n};\n\nvar crypto = {\n    Util: {\n        hashString: function hashString(value, alg) {\n            var hashFunc = DigestAlgs[alg];\n            return hashFunc(value).toString();\n        }\n    }\n};\n\nfunction hextob64u(s) {\n    if (s.length % 2 === 1) {\n        s = '0' + s;\n    }\n    return Base64.base64ToBase64Url(Base64.hexToBase64(s));\n}\n\nvar b64tohex = Base64.b64tohex;\nexports.jws = jws;\nexports.KeyUtil = KeyUtil;\nexports.X509 = X509;\nexports.crypto = crypto;\nexports.hextob64u = hextob64u;\nexports.b64tohex = b64tohex;\nexports.AllowedSigningAlgs = AllowedSigningAlgs;\n\n/***/ }),\n\n/***/ \"./src/random.js\":\n/*!***********************!*\\\n  !*** ./src/random.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = random;\n\nvar _v = __webpack_require__(/*! uuid/v4 */ \"./node_modules/uuid/v4.js\");\n\nvar _v2 = _interopRequireDefault(_v);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Generates RFC4122 version 4 guid ()\n */\n\nfunction random() {\n  return (0, _v2.default)().replace(/-/g, '');\n}\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./version.js\":\n/*!********************!*\\\n  !*** ./version.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nvar Version = \"1.10.1\";exports.Version = Version;\n\n/***/ }),\n\n/***/ 0:\n/*!***************************************!*\\\n  !*** multi ./polyfills.js ./index.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./polyfills.js */\"./polyfills.js\");\nmodule.exports = __webpack_require__(/*! ./index.js */\"./index.js\");\n\n\n/***/ })\n\n/******/ });\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9PaWRjL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL09pZGMvLi9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZXM2L3Byb21pc2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL2FycmF5L2ZpbmQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL2FycmF5L2lzLWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9hcnJheS9zb21lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9hcnJheS9zcGxpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL2Z1bmN0aW9uL2JpbmQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL29iamVjdC9hc3NpZ24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4taW5zdGFuY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktaW5jbHVkZXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LW1ldGhvZHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LXNwZWNpZXMtY29uc3RydWN0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LXNwZWNpZXMtY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19iaW5kLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jbGFzc29mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2YuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvcmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVmaW5lZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2V4cG9ydC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZnVuY3Rpb24tdG8tc3RyaW5nLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1jYWxsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItZGV0ZWN0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLXN0ZXAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXJhdG9ycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbGlicmFyeS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWljcm90YXNrLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19uZXctcHJvbWlzZS1jYXBhYmlsaXR5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy1pbnRlcm5hbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BlcmZvcm0uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb21pc2UtcmVzb2x2ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXNwZWNpZXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NldC10by1zdHJpbmctdGFnLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQta2V5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zaGFyZWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NwZWNpZXMtY29uc3RydWN0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmljdC1tZXRob2QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1hdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdGFzay5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tYWJzb2x1dGUtaW5kZXguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWludGVnZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWlvYmplY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWxlbmd0aC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tb2JqZWN0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1wcmltaXRpdmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3VpZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdXNlci1hZ2VudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmluZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zb21lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5iaW5kLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5wcm9taXNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NyeXB0by1qcy9jb3JlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY3J5cHRvLWpzL3NoYTI1Ni5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2pzYm4vaW5kZXguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy91dWlkL2xpYi9ieXRlc1RvVXVpZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vcG9seWZpbGxzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvQWNjZXNzVG9rZW5FdmVudHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9DaGVja1Nlc3Npb25JRnJhbWUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Db3Jkb3ZhSUZyYW1lTmF2aWdhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvQ29yZG92YVBvcHVwTmF2aWdhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvQ29yZG92YVBvcHVwV2luZG93LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvRXJyb3JSZXNwb25zZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0V2ZW50LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvR2xvYmFsLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSUZyYW1lTmF2aWdhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSUZyYW1lV2luZG93LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSW5NZW1vcnlXZWJTdG9yYWdlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSm9zZVV0aWxJbXBsLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSm9zZVV0aWxSc2EuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Kc29uU2VydmljZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0xvZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL01ldGFkYXRhU2VydmljZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL09pZGNDbGllbnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9PaWRjQ2xpZW50U2V0dGluZ3MuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Qb3B1cE5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1BvcHVwV2luZG93LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvUmVkaXJlY3ROYXZpZ2F0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9SZXNwb25zZVZhbGlkYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1Nlc3Npb25Nb25pdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2lnbmluUmVxdWVzdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpZ25pblJlc3BvbnNlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2lnbmluU3RhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWdub3V0UmVxdWVzdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpZ25vdXRSZXNwb25zZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpbGVudFJlbmV3U2VydmljZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1N0YXRlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVGltZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Ub2tlbkNsaWVudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1Rva2VuUmV2b2NhdGlvbkNsaWVudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VybFV0aWxpdHkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Vc2VyLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXNlckluZm9TZXJ2aWNlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXNlck1hbmFnZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Vc2VyTWFuYWdlckV2ZW50cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VzZXJNYW5hZ2VyU2V0dGluZ3MuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9XZWJTdG9yYWdlU3RhdGVTdG9yZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL2NyeXB0by9yc2EuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9yYW5kb20uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3ZlcnNpb24uanMiXSwibmFtZXMiOlsiVmVyc2lvbiIsIkxvZyIsIk9pZGNDbGllbnQiLCJPaWRjQ2xpZW50U2V0dGluZ3MiLCJXZWJTdG9yYWdlU3RhdGVTdG9yZSIsIkluTWVtb3J5V2ViU3RvcmFnZSIsIlVzZXJNYW5hZ2VyIiwiQWNjZXNzVG9rZW5FdmVudHMiLCJNZXRhZGF0YVNlcnZpY2UiLCJDb3Jkb3ZhUG9wdXBOYXZpZ2F0b3IiLCJDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yIiwiQ2hlY2tTZXNzaW9uSUZyYW1lIiwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50IiwiU2Vzc2lvbk1vbml0b3IiLCJHbG9iYWwiLCJVc2VyIiwiRGVmYXVsdEFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lIiwiYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUiLCJhY2Nlc3NUb2tlbkV4cGlyaW5nVGltZXIiLCJUaW1lciIsImFjY2Vzc1Rva2VuRXhwaXJlZFRpbWVyIiwiX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lIiwiX2FjY2Vzc1Rva2VuRXhwaXJpbmciLCJfYWNjZXNzVG9rZW5FeHBpcmVkIiwibG9hZCIsImNvbnRhaW5lciIsImFjY2Vzc190b2tlbiIsImV4cGlyZXNfaW4iLCJ1bmRlZmluZWQiLCJkdXJhdGlvbiIsImRlYnVnIiwiZXhwaXJpbmciLCJpbml0IiwiY2FuY2VsIiwiZXhwaXJlZCIsInVubG9hZCIsImFkZEFjY2Vzc1Rva2VuRXhwaXJpbmciLCJjYiIsImFkZEhhbmRsZXIiLCJyZW1vdmVBY2Nlc3NUb2tlbkV4cGlyaW5nIiwicmVtb3ZlSGFuZGxlciIsImFkZEFjY2Vzc1Rva2VuRXhwaXJlZCIsInJlbW92ZUFjY2Vzc1Rva2VuRXhwaXJlZCIsIkRlZmF1bHRJbnRlcnZhbCIsImNhbGxiYWNrIiwiY2xpZW50X2lkIiwidXJsIiwiaW50ZXJ2YWwiLCJzdG9wT25FcnJvciIsIl9jYWxsYmFjayIsIl9jbGllbnRfaWQiLCJfdXJsIiwiX2ludGVydmFsIiwiX3N0b3BPbkVycm9yIiwiaWR4IiwiaW5kZXhPZiIsIl9mcmFtZV9vcmlnaW4iLCJzdWJzdHIiLCJfZnJhbWUiLCJ3aW5kb3ciLCJkb2N1bWVudCIsImNyZWF0ZUVsZW1lbnQiLCJzdHlsZSIsInZpc2liaWxpdHkiLCJwb3NpdGlvbiIsImRpc3BsYXkiLCJ3aWR0aCIsImhlaWdodCIsInNyYyIsIlByb21pc2UiLCJyZXNvbHZlIiwib25sb2FkIiwiYm9keSIsImFwcGVuZENoaWxkIiwiX2JvdW5kTWVzc2FnZUV2ZW50IiwiX21lc3NhZ2UiLCJiaW5kIiwiYWRkRXZlbnRMaXN0ZW5lciIsImUiLCJvcmlnaW4iLCJzb3VyY2UiLCJjb250ZW50V2luZG93IiwiZGF0YSIsImVycm9yIiwic3RvcCIsInN0YXJ0Iiwic2Vzc2lvbl9zdGF0ZSIsIl9zZXNzaW9uX3N0YXRlIiwic2VuZCIsInBvc3RNZXNzYWdlIiwiX3RpbWVyIiwic2V0SW50ZXJ2YWwiLCJjbGVhckludGVydmFsIiwicHJlcGFyZSIsInBhcmFtcyIsInBvcHVwV2luZG93RmVhdHVyZXMiLCJwb3B1cCIsIkNvcmRvdmFQb3B1cFdpbmRvdyIsIkRlZmF1bHRQb3B1cEZlYXR1cmVzIiwiRGVmYXVsdFBvcHVwVGFyZ2V0IiwiX3Byb21pc2UiLCJyZWplY3QiLCJfcmVzb2x2ZSIsIl9yZWplY3QiLCJmZWF0dXJlcyIsInRhcmdldCIsInBvcHVwV2luZG93VGFyZ2V0IiwicmVkaXJlY3RfdXJpIiwic3RhcnRVcmwiLCJfaXNJbkFwcEJyb3dzZXJJbnN0YWxsZWQiLCJjb3Jkb3ZhTWV0YWRhdGEiLCJzb21lIiwibmFtZSIsImhhc093blByb3BlcnR5IiwibmF2aWdhdGUiLCJfZXJyb3IiLCJjb3Jkb3ZhIiwicmVxdWlyZSIsIm1ldGFkYXRhIiwiX3BvcHVwIiwiSW5BcHBCcm93c2VyIiwib3BlbiIsIl9leGl0Q2FsbGJhY2tFdmVudCIsIl9leGl0Q2FsbGJhY2siLCJfbG9hZFN0YXJ0Q2FsbGJhY2tFdmVudCIsIl9sb2FkU3RhcnRDYWxsYmFjayIsInByb21pc2UiLCJldmVudCIsIl9zdWNjZXNzIiwibWVzc2FnZSIsIl9jbGVhbnVwIiwiRXJyb3IiLCJjbG9zZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJFcnJvclJlc3BvbnNlIiwiZXJyb3JfZGVzY3JpcHRpb24iLCJlcnJvcl91cmkiLCJzdGF0ZSIsIkV2ZW50IiwiX25hbWUiLCJfY2FsbGJhY2tzIiwicHVzaCIsImZpbmRJbmRleCIsIml0ZW0iLCJzcGxpY2UiLCJyYWlzZSIsImkiLCJsZW5ndGgiLCJ0aW1lciIsImhhbmRsZSIsInRlc3RpbmciLCJyZXF1ZXN0IiwiX3Rlc3RpbmciLCJzZXRYTUxIdHRwUmVxdWVzdCIsIm5ld1JlcXVlc3QiLCJsb2NhdGlvbiIsImxvY2FsU3RvcmFnZSIsInNlc3Npb25TdG9yYWdlIiwiWE1MSHR0cFJlcXVlc3QiLCJJRnJhbWVOYXZpZ2F0b3IiLCJmcmFtZSIsIklGcmFtZVdpbmRvdyIsIm5vdGlmeVBhcmVudCIsIkRlZmF1bHRUaW1lb3V0IiwidGltZW91dCIsInNpbGVudFJlcXVlc3RUaW1lb3V0Iiwic2V0VGltZW91dCIsIl90aW1lb3V0IiwiY2xlYXJUaW1lb3V0IiwicmVtb3ZlQ2hpbGQiLCJfb3JpZ2luIiwiZnJhbWVFbGVtZW50IiwiaHJlZiIsInBhcmVudCIsInByb3RvY29sIiwiaG9zdCIsIl9kYXRhIiwiZ2V0SXRlbSIsImtleSIsInNldEl0ZW0iLCJ2YWx1ZSIsInJlbW92ZUl0ZW0iLCJpbmRleCIsIk9iamVjdCIsImdldE93blByb3BlcnR5TmFtZXMiLCJnZXRKb3NlVXRpbCIsImp3cyIsIktleVV0aWwiLCJYNTA5IiwiY3J5cHRvIiwiaGV4dG9iNjR1IiwiYjY0dG9oZXgiLCJBbGxvd2VkU2lnbmluZ0FsZ3MiLCJwYXJzZUp3dCIsImp3dCIsInRva2VuIiwiSldTIiwicGFyc2UiLCJoZWFkZXIiLCJoZWFkZXJPYmoiLCJwYXlsb2FkIiwicGF5bG9hZE9iaiIsInZhbGlkYXRlSnd0IiwiaXNzdWVyIiwiYXVkaWVuY2UiLCJjbG9ja1NrZXciLCJub3ciLCJ0aW1lSW5zZW5zaXRpdmUiLCJrdHkiLCJuIiwiZ2V0S2V5IiwieDVjIiwiaGV4IiwiZ2V0UHVibGljS2V5RnJvbUNlcnRIZXgiLCJjcnYiLCJ4IiwieSIsIkpvc2VVdGlsIiwiX3ZhbGlkYXRlSnd0IiwidmFsaWRhdGVKd3RBdHRyaWJ1dGVzIiwicGFyc2VJbnQiLCJEYXRlIiwiaXNzIiwiYXVkIiwidmFsaWRBdWRpZW5jZSIsIkFycmF5IiwiaXNBcnJheSIsImF6cCIsImxvd2VyTm93IiwidXBwZXJOb3ciLCJpYXQiLCJuYmYiLCJleHAiLCJ0aGVuIiwidmVyaWZ5IiwiaGFzaFN0cmluZyIsImFsZyIsIlV0aWwiLCJoZXhUb0Jhc2U2NFVybCIsIkpzb25TZXJ2aWNlIiwiYWRkaXRpb25hbENvbnRlbnRUeXBlcyIsIlhNTEh0dHBSZXF1ZXN0Q3RvciIsImp3dEhhbmRsZXIiLCJfY29udGVudFR5cGVzIiwic2xpY2UiLCJfWE1MSHR0cFJlcXVlc3QiLCJfand0SGFuZGxlciIsImdldEpzb24iLCJyZXEiLCJhbGxvd2VkQ29udGVudFR5cGVzIiwic3RhdHVzIiwiY29udGVudFR5cGUiLCJnZXRSZXNwb25zZUhlYWRlciIsImZvdW5kIiwiZmluZCIsInN0YXJ0c1dpdGgiLCJKU09OIiwicmVzcG9uc2VUZXh0Iiwic3RhdHVzVGV4dCIsIm9uZXJyb3IiLCJzZXRSZXF1ZXN0SGVhZGVyIiwicG9zdEZvcm0iLCJlbmNvZGVVUklDb21wb25lbnQiLCJub3BMb2dnZXIiLCJpbmZvIiwid2FybiIsIk5PTkUiLCJFUlJPUiIsIldBUk4iLCJJTkZPIiwiREVCVUciLCJsb2dnZXIiLCJsZXZlbCIsInJlc2V0IiwiYXJncyIsImFwcGx5IiwiZnJvbSIsIk9pZGNNZXRhZGF0YVVybFBhdGgiLCJzZXR0aW5ncyIsIkpzb25TZXJ2aWNlQ3RvciIsIl9zZXR0aW5ncyIsIl9qc29uU2VydmljZSIsImdldE1ldGFkYXRhIiwibWV0YWRhdGFVcmwiLCJnZXRJc3N1ZXIiLCJfZ2V0TWV0YWRhdGFQcm9wZXJ0eSIsImdldEF1dGhvcml6YXRpb25FbmRwb2ludCIsImdldFVzZXJJbmZvRW5kcG9pbnQiLCJnZXRUb2tlbkVuZHBvaW50Iiwib3B0aW9uYWwiLCJnZXRDaGVja1Nlc3Npb25JZnJhbWUiLCJnZXRFbmRTZXNzaW9uRW5kcG9pbnQiLCJnZXRSZXZvY2F0aW9uRW5kcG9pbnQiLCJnZXRLZXlzRW5kcG9pbnQiLCJnZXRTaWduaW5nS2V5cyIsInNpZ25pbmdLZXlzIiwiandrc191cmkiLCJrZXlTZXQiLCJrZXlzIiwiX21ldGFkYXRhVXJsIiwiYXV0aG9yaXR5IiwiY3JlYXRlU2lnbmluUmVxdWVzdCIsInJlc3BvbnNlX3R5cGUiLCJzY29wZSIsInByb21wdCIsIm1heF9hZ2UiLCJ1aV9sb2NhbGVzIiwiaWRfdG9rZW5faGludCIsImxvZ2luX2hpbnQiLCJhY3JfdmFsdWVzIiwicmVzb3VyY2UiLCJyZXF1ZXN0X3VyaSIsInJlc3BvbnNlX21vZGUiLCJleHRyYVF1ZXJ5UGFyYW1zIiwiZXh0cmFUb2tlblBhcmFtcyIsInJlcXVlc3RfdHlwZSIsInNraXBVc2VySW5mbyIsInN0YXRlU3RvcmUiLCJTaWduaW5SZXF1ZXN0IiwiaXNDb2RlIiwiX21ldGFkYXRhU2VydmljZSIsInNpZ25pblJlcXVlc3QiLCJjbGllbnRfc2VjcmV0Iiwic2lnbmluU3RhdGUiLCJfc3RhdGVTdG9yZSIsInNldCIsImlkIiwidG9TdG9yYWdlU3RyaW5nIiwicmVhZFNpZ25pblJlc3BvbnNlU3RhdGUiLCJyZW1vdmVTdGF0ZSIsInVzZVF1ZXJ5IiwiZGVsaW1pdGVyIiwicmVzcG9uc2UiLCJTaWduaW5SZXNwb25zZSIsInN0YXRlQXBpIiwicmVtb3ZlIiwiZ2V0Iiwic3RvcmVkU3RhdGVTdHJpbmciLCJTaWduaW5TdGF0ZSIsImZyb21TdG9yYWdlU3RyaW5nIiwicHJvY2Vzc1NpZ25pblJlc3BvbnNlIiwiX3ZhbGlkYXRvciIsInZhbGlkYXRlU2lnbmluUmVzcG9uc2UiLCJjcmVhdGVTaWdub3V0UmVxdWVzdCIsInBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIlNpZ25vdXRSZXF1ZXN0Iiwic2lnbm91dFN0YXRlIiwicmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlIiwiU2lnbm91dFJlc3BvbnNlIiwic3RhdGVLZXkiLCJTdGF0ZSIsInByb2Nlc3NTaWdub3V0UmVzcG9uc2UiLCJ2YWxpZGF0ZVNpZ25vdXRSZXNwb25zZSIsImNsZWFyU3RhbGVTdGF0ZSIsInN0YWxlU3RhdGVBZ2UiLCJ2YWxpZGF0b3IiLCJtZXRhZGF0YVNlcnZpY2UiLCJEZWZhdWx0UmVzcG9uc2VUeXBlIiwiRGVmYXVsdFNjb3BlIiwiRGVmYXVsdFN0YWxlU3RhdGVBZ2UiLCJEZWZhdWx0Q2xvY2tTa2V3SW5TZWNvbmRzIiwiZmlsdGVyUHJvdG9jb2xDbGFpbXMiLCJsb2FkVXNlckluZm8iLCJ1c2VySW5mb0p3dElzc3VlciIsIlJlc3BvbnNlVmFsaWRhdG9yQ3RvciIsIlJlc3BvbnNlVmFsaWRhdG9yIiwiTWV0YWRhdGFTZXJ2aWNlQ3RvciIsIl9hdXRob3JpdHkiLCJfbWV0YWRhdGEiLCJfc2lnbmluZ0tleXMiLCJfY2xpZW50X3NlY3JldCIsIl9yZXNwb25zZV90eXBlIiwiX3Njb3BlIiwiX3JlZGlyZWN0X3VyaSIsIl9wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkiLCJfcHJvbXB0IiwiX2Rpc3BsYXkiLCJfbWF4X2FnZSIsIl91aV9sb2NhbGVzIiwiX2Fjcl92YWx1ZXMiLCJfcmVzb3VyY2UiLCJfcmVzcG9uc2VfbW9kZSIsIl9maWx0ZXJQcm90b2NvbENsYWltcyIsIl9sb2FkVXNlckluZm8iLCJfc3RhbGVTdGF0ZUFnZSIsIl9jbG9ja1NrZXciLCJfdXNlckluZm9Kd3RJc3N1ZXIiLCJfZXh0cmFRdWVyeVBhcmFtcyIsIl9leHRyYVRva2VuUGFyYW1zIiwiUG9wdXBOYXZpZ2F0b3IiLCJQb3B1cFdpbmRvdyIsImtlZXBPcGVuIiwibm90aWZ5T3BlbmVyIiwiQ2hlY2tGb3JQb3B1cENsb3NlZEludGVydmFsIiwiX2NoZWNrRm9yUG9wdXBDbG9zZWRUaW1lciIsIl9jaGVja0ZvclBvcHVwQ2xvc2VkIiwiX2lkIiwiZm9jdXMiLCJjbG9zZWQiLCJvcGVuZXIiLCJVcmxVdGlsaXR5IiwicGFyc2VVcmxGcmFnbWVudCIsIlJlZGlyZWN0TmF2aWdhdG9yIiwidXNlUmVwbGFjZVRvTmF2aWdhdGUiLCJyZXBsYWNlIiwiUHJvdG9jb2xDbGFpbXMiLCJVc2VySW5mb1NlcnZpY2VDdG9yIiwiVXNlckluZm9TZXJ2aWNlIiwiam9zZVV0aWwiLCJUb2tlbkNsaWVudEN0b3IiLCJUb2tlbkNsaWVudCIsIl91c2VySW5mb1NlcnZpY2UiLCJfam9zZVV0aWwiLCJfdG9rZW5DbGllbnQiLCJfcHJvY2Vzc1NpZ25pblBhcmFtcyIsIl92YWxpZGF0ZVRva2VucyIsIl9wcm9jZXNzQ2xhaW1zIiwibm9uY2UiLCJpZF90b2tlbiIsImNvZGVfdmVyaWZpZXIiLCJjb2RlIiwiaXNPcGVuSWRDb25uZWN0IiwicHJvZmlsZSIsImdldENsYWltcyIsImNsYWltcyIsInN1YiIsIl9tZXJnZUNsYWltcyIsImNsYWltczEiLCJjbGFpbXMyIiwicmVzdWx0IiwiYXNzaWduIiwidmFsdWVzIiwiZm9yRWFjaCIsInR5cGUiLCJfcHJvY2Vzc0NvZGUiLCJfdmFsaWRhdGVJZFRva2VuQW5kQWNjZXNzVG9rZW4iLCJfdmFsaWRhdGVJZFRva2VuIiwiZXhjaGFuZ2VDb2RlIiwidG9rZW5SZXNwb25zZSIsIl92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzIiwiY2xvY2tTa2V3SW5TZWNvbmRzIiwiX3ZhbGlkYXRlQWNjZXNzVG9rZW4iLCJraWQiLCJfZmlsdGVyQnlBbGciLCJmaWx0ZXIiLCJhdF9oYXNoIiwiaGFzaEFsZyIsImhhc2hCaXRzIiwic2hhIiwiaGFzaCIsImxlZnQiLCJsZWZ0X2I2NHUiLCJ1c2VyTWFuYWdlciIsIkNoZWNrU2Vzc2lvbklGcmFtZUN0b3IiLCJfdXNlck1hbmFnZXIiLCJfQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvciIsImV2ZW50cyIsImFkZFVzZXJMb2FkZWQiLCJfc3RhcnQiLCJhZGRVc2VyVW5sb2FkZWQiLCJfc3RvcCIsImdldFVzZXIiLCJ1c2VyIiwibW9uaXRvckFub255bW91c1Nlc3Npb24iLCJxdWVyeVNlc3Npb25TdGF0dXMiLCJ0bXBVc2VyIiwic2Vzc2lvbiIsInNpZCIsImNhdGNoIiwiZXJyIiwiX3N1YiIsIl9zaWQiLCJfY2hlY2tTZXNzaW9uSUZyYW1lIiwiX2NoZWNrU2Vzc2lvbkludGVydmFsIiwiX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yIiwidGltZXJIYW5kbGUiLCJyYWlzZUV2ZW50IiwiX3JhaXNlVXNlclNlc3Npb25DaGFuZ2VkIiwiX3JhaXNlVXNlclNpZ25lZE91dCIsIl9yYWlzZVVzZXJTaWduZWRJbiIsImNoZWNrU2Vzc2lvbkludGVydmFsIiwic3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IiLCJvaWRjIiwiaXNPaWRjIiwiYWRkUXVlcnlQYXJhbSIsImNvZGVfY2hhbGxlbmdlIiwic3BsaXQiLCJpc09BdXRoIiwiT2lkY1Njb3BlIiwidG9rZW5fdHlwZSIsImV4cGlyZXNfYXQiLCJzY29wZXMiLCJhcmd1bWVudHMiLCJfbm9uY2UiLCJfY29kZV92ZXJpZmllciIsIl9jb2RlX2NoYWxsZW5nZSIsIl9za2lwVXNlckluZm8iLCJzdHJpbmdpZnkiLCJjcmVhdGVkIiwic3RvcmFnZVN0cmluZyIsIlNpbGVudFJlbmV3U2VydmljZSIsIl90b2tlbkV4cGlyaW5nIiwic2lnbmluU2lsZW50IiwiX3JhaXNlU2lsZW50UmVuZXdFcnJvciIsIl9jcmVhdGVkIiwiX3JlcXVlc3RfdHlwZSIsInN0b3JhZ2UiLCJhZ2UiLCJjdXRvZmYiLCJnZXRBbGxLZXlzIiwicHJvbWlzZXMiLCJwIiwiYWxsIiwiVGltZXJEdXJhdGlvbiIsIm5vd0Z1bmMiLCJfbm93RnVuYyIsImV4cGlyYXRpb24iLCJfdGltZXJIYW5kbGUiLCJfZXhwaXJhdGlvbiIsInRpbWVyRHVyYXRpb24iLCJkaWZmIiwiZ3JhbnRfdHlwZSIsImV4Y2hhbmdlUmVmcmVzaFRva2VuIiwicmVmcmVzaF90b2tlbiIsIkFjY2Vzc1Rva2VuVHlwZUhpbnQiLCJSZWZyZXNoVG9rZW5UeXBlSGludCIsIl9YTUxIdHRwUmVxdWVzdEN0b3IiLCJyZXZva2UiLCJyZXF1aXJlZCIsIl9yZXZva2UiLCJ4aHIiLCJnbG9iYWwiLCJsYXN0SW5kZXhPZiIsInJlZ2V4IiwibSIsImNvdW50ZXIiLCJleGVjIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwicHJvcCIsIl9nZXRDbGFpbXNGcm9tSnd0IiwiaXNzdWVyUHJvbWlzZSIsIlNpbGVudFJlbmV3U2VydmljZUN0b3IiLCJTZXNzaW9uTW9uaXRvckN0b3IiLCJUb2tlblJldm9jYXRpb25DbGllbnRDdG9yIiwiVXNlck1hbmFnZXJTZXR0aW5ncyIsIl9ldmVudHMiLCJVc2VyTWFuYWdlckV2ZW50cyIsIl9zaWxlbnRSZW5ld1NlcnZpY2UiLCJhdXRvbWF0aWNTaWxlbnRSZW5ldyIsInN0YXJ0U2lsZW50UmVuZXciLCJtb25pdG9yU2Vzc2lvbiIsIl9zZXNzaW9uTW9uaXRvciIsIl90b2tlblJldm9jYXRpb25DbGllbnQiLCJfbG9hZFVzZXIiLCJyZW1vdmVVc2VyIiwic3RvcmVVc2VyIiwic2lnbmluUmVkaXJlY3QiLCJuYXZQYXJhbXMiLCJfc2lnbmluU3RhcnQiLCJfcmVkaXJlY3ROYXZpZ2F0b3IiLCJzaWduaW5SZWRpcmVjdENhbGxiYWNrIiwiX3NpZ25pbkVuZCIsInNpZ25pblBvcHVwIiwicG9wdXBfcmVkaXJlY3RfdXJpIiwiX3NpZ25pbiIsIl9wb3B1cE5hdmlnYXRvciIsInNpZ25pblBvcHVwQ2FsbGJhY2siLCJfc2lnbmluQ2FsbGJhY2siLCJfdXNlUmVmcmVzaFRva2VuIiwiaW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3IiwidmFsaWRhdGVTdWJPblNpbGVudFJlbmV3IiwiY3VycmVudF9zdWIiLCJfc2lnbmluU2lsZW50SWZyYW1lIiwiaWRUb2tlblZhbGlkYXRpb24iLCJfdmFsaWRhdGVJZFRva2VuRnJvbVRva2VuUmVmcmVzaFRva2VuIiwiYXV0aF90aW1lIiwic2lsZW50X3JlZGlyZWN0X3VyaSIsIl9pZnJhbWVOYXZpZ2F0b3IiLCJzaWduaW5TaWxlbnRDYWxsYmFjayIsInNpZ25pbkNhbGxiYWNrIiwic2lnbm91dENhbGxiYWNrIiwic2lnbm91dFJlZGlyZWN0Q2FsbGJhY2siLCJzaWdub3V0UG9wdXBDYWxsYmFjayIsInF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlIiwibmF2UmVzcG9uc2UiLCJzaWduaW5SZXNwb25zZSIsIm5hdmlnYXRvciIsIm5hdmlnYXRvclBhcmFtcyIsInNpZ25vdXRSZWRpcmVjdCIsInBvc3RMb2dvdXRSZWRpcmVjdFVyaSIsIl9zaWdub3V0U3RhcnQiLCJfc2lnbm91dEVuZCIsInNpZ25vdXRQb3B1cCIsInBvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIl9zaWdub3V0IiwicmV2b2tlUHJvbWlzZSIsInJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0IiwiX3Jldm9rZUludGVybmFsIiwic2lnbm91dFJlcXVlc3QiLCJzaWdub3V0UmVzcG9uc2UiLCJyZXZva2VBY2Nlc3NUb2tlbiIsInN1Y2Nlc3MiLCJfcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbCIsIl9yZXZva2VSZWZyZXNoVG9rZW5JbnRlcm5hbCIsImF0U3VjY2VzcyIsInJ0U3VjY2VzcyIsInN0b3BTaWxlbnRSZW5ldyIsIl91c2VyU3RvcmUiLCJfdXNlclN0b3JlS2V5IiwicmVkaXJlY3ROYXZpZ2F0b3IiLCJwb3B1cE5hdmlnYXRvciIsImlmcmFtZU5hdmlnYXRvciIsInVzZXJTdG9yZSIsIl91c2VyTG9hZGVkIiwiX3VzZXJVbmxvYWRlZCIsIl9zaWxlbnRSZW5ld0Vycm9yIiwiX3VzZXJTaWduZWRJbiIsIl91c2VyU2lnbmVkT3V0IiwiX3VzZXJTZXNzaW9uQ2hhbmdlZCIsInJlbW92ZVVzZXJMb2FkZWQiLCJyZW1vdmVVc2VyVW5sb2FkZWQiLCJhZGRTaWxlbnRSZW5ld0Vycm9yIiwicmVtb3ZlU2lsZW50UmVuZXdFcnJvciIsImFkZFVzZXJTaWduZWRJbiIsInJlbW92ZVVzZXJTaWduZWRJbiIsImFkZFVzZXJTaWduZWRPdXQiLCJyZW1vdmVVc2VyU2lnbmVkT3V0IiwiYWRkVXNlclNlc3Npb25DaGFuZ2VkIiwicmVtb3ZlVXNlclNlc3Npb25DaGFuZ2VkIiwiRGVmYXVsdENoZWNrU2Vzc2lvbkludGVydmFsIiwic3RvcmUiLCJfcG9wdXBfcmVkaXJlY3RfdXJpIiwiX3BvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIl9wb3B1cFdpbmRvd0ZlYXR1cmVzIiwiX3BvcHVwV2luZG93VGFyZ2V0IiwiX3NpbGVudF9yZWRpcmVjdF91cmkiLCJfc2lsZW50UmVxdWVzdFRpbWVvdXQiLCJfYXV0b21hdGljU2lsZW50UmVuZXciLCJfdmFsaWRhdGVTdWJPblNpbGVudFJlbmV3IiwiX2luY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyIsIl9tb25pdG9yU2Vzc2lvbiIsIl9tb25pdG9yQW5vbnltb3VzU2Vzc2lvbiIsIl9xdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZSIsIl9yZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCIsInByZWZpeCIsIl9zdG9yZSIsIl9wcmVmaXgiLCJCaWdJbnRlZ2VyIiwiSlNCTiIsImI2NG1hcCIsImI2NHBhZCIsIkJhc2U2NCIsInMiLCJyZXQiLCJrIiwic2xvcCIsImNoYXJBdCIsInYiLCJTdHJpbmciLCJmcm9tQ2hhckNvZGUiLCJoZXhUb0Jhc2U2NCIsImgiLCJjIiwic3Vic3RyaW5nIiwicGFkZGluZyIsInN0ciIsIm1vZCIsInBhZCIsImpvaW4iLCJieXRlQXJyYXlUb0hleCIsInJhdyIsIkhFWCIsIl9oZXgiLCJ0b1N0cmluZyIsImRlY29kZVRvSEVYIiwiYmFzZTY0SnMiLCJ0b0J5dGVBcnJheSIsImJhc2U2NFRvQmFzZTY0VXJsIiwidXJsRGVjb2RlIiwiYXRvYiIsIkRpZ2VzdEluZm9IZWFkIiwic2hhMSIsInNoYTIyNCIsInNoYTI1NiIsInNoYTM4NCIsInNoYTUxMiIsIm1kMiIsIm1kNSIsInJpcGVtZDE2MCIsIkRpZ2VzdEFsZ3MiLCJTSEEyNTYiLCJSU0FWZXJpZmllciIsIm1vZHVsdXMiLCJnZXRBbGdvcml0aG1Gcm9tRGlnZXN0IiwiaERpZ2VzdEluZm8iLCJhbGdOYW1lIiwiaGVhZCIsImxlbiIsInByb3RvdHlwZSIsIm1zZyIsImVuY3NpZyIsInNpZyIsImJpdExlbmd0aCIsImRlY3J5cHRlZFNpZyIsIm1vZFBvd0ludCIsImRpZ2VzdCIsImRpZ2VzdEluZm8iLCJtc2dIYXNoIiwicGFydHMiLCJhbGxvd2VkU2lnbmluZ0FsZ3MiLCJoZWFkZXJBbmRQYXlsb2FkIiwiZ2V0UHVi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Ozs7Ozs7Ozs7OztrQkMvUm9CeWdCLE07O0FBTnhCOzs7Ozs7QUFFQTs7OztBQUllLFNBQVNBLE1BQVQsR0FBa0I7QUFDL0IsU0FBTyxtQkFBUXJULE9BQVIsQ0FBZ0IsSUFBaEIsRUFBc0IsRUFBdEIsQ0FBUDtBQUNEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNSRCxJQUFNcFosVUFBVSxRQUFoQixDLFFBQWtDQSxPLEdBQUFBLE8iLCJmaWxlIjoib2lkYy1jbGllbnQucnNhMjU2LnNsaW0uanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL3NyYy9Mb2cuanMnO1xyXG5pbXBvcnQgeyBPaWRjQ2xpZW50IH0gZnJvbSAnLi9zcmMvT2lkY0NsaWVudC5qcyc7XHJcbmltcG9ydCB7IE9pZGNDbGllbnRTZXR0aW5ncyB9IGZyb20gJy4vc3JjL09pZGNDbGllbnRTZXR0aW5ncy5qcyc7XHJcbmltcG9ydCB7IFdlYlN0b3JhZ2VTdGF0ZVN0b3JlIH0gZnJvbSAnLi9zcmMvV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMnO1xyXG5pbXBvcnQgeyBJbk1lbW9yeVdlYlN0b3JhZ2UgfSBmcm9tICcuL3NyYy9Jbk1lbW9yeVdlYlN0b3JhZ2UuanMnO1xyXG5pbXBvcnQgeyBVc2VyTWFuYWdlciB9IGZyb20gJy4vc3JjL1VzZXJNYW5hZ2VyLmpzJztcclxuaW1wb3J0IHsgQWNjZXNzVG9rZW5FdmVudHMgfSBmcm9tICcuL3NyYy9BY2Nlc3NUb2tlbkV2ZW50cy5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vc3JjL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IENvcmRvdmFQb3B1cE5hdmlnYXRvciB9IGZyb20gJy4vc3JjL0NvcmRvdmFQb3B1cE5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IENvcmRvdmFJRnJhbWVOYXZpZ2F0b3IgfSBmcm9tICcuL3NyYy9Db3Jkb3ZhSUZyYW1lTmF2aWdhdG9yLmpzJztcclxuaW1wb3J0IHsgQ2hlY2tTZXNzaW9uSUZyYW1lIH0gZnJvbSAnLi9zcmMvQ2hlY2tTZXNzaW9uSUZyYW1lLmpzJztcclxuaW1wb3J0IHsgVG9rZW5SZXZvY2F0aW9uQ2xpZW50IH0gZnJvbSAnLi9zcmMvVG9rZW5SZXZvY2F0aW9uQ2xpZW50LmpzJztcclxuaW1wb3J0IHsgU2Vzc2lvbk1vbml0b3IgfSBmcm9tICcuL3NyYy9TZXNzaW9uTW9uaXRvci5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vc3JjL0dsb2JhbC5qcyc7XHJcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuL3NyYy9Vc2VyLmpzJztcclxuXHJcbmltcG9ydCB7IFZlcnNpb24gfSBmcm9tICcuL3ZlcnNpb24uanMnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgVmVyc2lvbixcclxuICAgIExvZyxcclxuICAgIE9pZGNDbGllbnQsXHJcbiAgICBPaWRjQ2xpZW50U2V0dGluZ3MsXHJcbiAgICBXZWJTdG9yYWdlU3RhdGVTdG9yZSxcclxuICAgIEluTWVtb3J5V2ViU3RvcmFnZSxcclxuICAgIFVzZXJNYW5hZ2VyLFxyXG4gICAgQWNjZXNzVG9rZW5FdmVudHMsXHJcbiAgICBNZXRhZGF0YVNlcnZpY2UsXHJcbiAgICBDb3Jkb3ZhUG9wdXBOYXZpZ2F0b3IsXHJcbiAgICBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yLFxyXG4gICAgQ2hlY2tTZXNzaW9uSUZyYW1lLFxyXG4gICAgVG9rZW5SZXZvY2F0aW9uQ2xpZW50LFxyXG4gICAgU2Vzc2lvbk1vbml0b3IsXHJcbiAgICBHbG9iYWwsXHJcbiAgICBVc2VyXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0J1xuXG5leHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoXG5leHBvcnRzLnRvQnl0ZUFycmF5ID0gdG9CeXRlQXJyYXlcbmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IGZyb21CeXRlQXJyYXlcblxudmFyIGxvb2t1cCA9IFtdXG52YXIgcmV2TG9va3VwID0gW11cbnZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcgPyBVaW50OEFycmF5IDogQXJyYXlcblxudmFyIGNvZGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLydcbmZvciAodmFyIGkgPSAwLCBsZW4gPSBjb2RlLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gIGxvb2t1cFtpXSA9IGNvZGVbaV1cbiAgcmV2TG9va3VwW2NvZGUuY2hhckNvZGVBdChpKV0gPSBpXG59XG5cbi8vIFN1cHBvcnQgZGVjb2RpbmcgVVJMLXNhZmUgYmFzZTY0IHN0cmluZ3MsIGFzIE5vZGUuanMgZG9lcy5cbi8vIFNlZTogaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQmFzZTY0I1VSTF9hcHBsaWNhdGlvbnNcbnJldkxvb2t1cFsnLScuY2hhckNvZGVBdCgwKV0gPSA2MlxucmV2TG9va3VwWydfJy5jaGFyQ29kZUF0KDApXSA9IDYzXG5cbmZ1bmN0aW9uIGdldExlbnMgKGI2NCkge1xuICB2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXG4gIGlmIChsZW4gJSA0ID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCcpXG4gIH1cblxuICAvLyBUcmltIG9mZiBleHRyYSBieXRlcyBhZnRlciBwbGFjZWhvbGRlciBieXRlcyBhcmUgZm91bmRcbiAgLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vYmVhdGdhbW1pdC9iYXNlNjQtanMvaXNzdWVzLzQyXG4gIHZhciB2YWxpZExlbiA9IGI2NC5pbmRleE9mKCc9JylcbiAgaWYgKHZhbGlkTGVuID09PSAtMSkgdmFsaWRMZW4gPSBsZW5cblxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gdmFsaWRMZW4gPT09IGxlblxuICAgID8gMFxuICAgIDogNCAtICh2YWxpZExlbiAlIDQpXG5cbiAgcmV0dXJuIFt2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuXVxufVxuXG4vLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKGI2NCkge1xuICB2YXIgbGVucyA9IGdldExlbnMoYjY0KVxuICB2YXIgdmFsaWRMZW4gPSBsZW5zWzBdXG4gIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdXG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiBfYnl0ZUxlbmd0aCAoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSB7XG4gIHJldHVybiAoKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0KSAtIHBsYWNlSG9sZGVyc0xlblxufVxuXG5mdW5jdGlvbiB0b0J5dGVBcnJheSAoYjY0KSB7XG4gIHZhciB0bXBcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuXG4gIHZhciBhcnIgPSBuZXcgQXJyKF9ieXRlTGVuZ3RoKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikpXG5cbiAgdmFyIGN1ckJ5dGUgPSAwXG5cbiAgLy8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuICB2YXIgbGVuID0gcGxhY2VIb2xkZXJzTGVuID4gMFxuICAgID8gdmFsaWRMZW4gLSA0XG4gICAgOiB2YWxpZExlblxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTgpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCAxMikgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMildIDw8IDYpIHxcbiAgICAgIHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMyldXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDE2KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICBpZiAocGxhY2VIb2xkZXJzTGVuID09PSAyKSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA+PiA0KVxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMSkge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAxMCkgfFxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpICsgMSldIDw8IDQpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA+PiAyKVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiA4KSAmIDB4RkZcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBhcnJcbn1cblxuZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcbiAgcmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICtcbiAgICBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArXG4gICAgbG9va3VwW251bSAmIDB4M0ZdXG59XG5cbmZ1bmN0aW9uIGVuY29kZUNodW5rICh1aW50OCwgc3RhcnQsIGVuZCkge1xuICB2YXIgdG1wXG4gIHZhciBvdXRwdXQgPSBbXVxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkgKz0gMykge1xuICAgIHRtcCA9XG4gICAgICAoKHVpbnQ4W2ldIDw8IDE2KSAmIDB4RkYwMDAwKSArXG4gICAgICAoKHVpbnQ4W2kgKyAxXSA8PCA4KSAmIDB4RkYwMCkgK1xuICAgICAgKHVpbnQ4W2kgKyAyXSAmIDB4RkYpXG4gICAgb3V0cHV0LnB1c2godHJpcGxldFRvQmFzZTY0KHRtcCkpXG4gIH1cbiAgcmV0dXJuIG91dHB1dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmcm9tQnl0ZUFycmF5ICh1aW50OCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW4gPSB1aW50OC5sZW5ndGhcbiAgdmFyIGV4dHJhQnl0ZXMgPSBsZW4gJSAzIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG4gIHZhciBwYXJ0cyA9IFtdXG4gIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzIC8vIG11c3QgYmUgbXVsdGlwbGUgb2YgM1xuXG4gIC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcbiAgZm9yICh2YXIgaSA9IDAsIGxlbjIgPSBsZW4gLSBleHRyYUJ5dGVzOyBpIDwgbGVuMjsgaSArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgIHBhcnRzLnB1c2goZW5jb2RlQ2h1bmsoXG4gICAgICB1aW50OCwgaSwgKGkgKyBtYXhDaHVua0xlbmd0aCkgPiBsZW4yID8gbGVuMiA6IChpICsgbWF4Q2h1bmtMZW5ndGgpXG4gICAgKSlcbiAgfVxuXG4gIC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcbiAgaWYgKGV4dHJhQnl0ZXMgPT09IDEpIHtcbiAgICB0bXAgPSB1aW50OFtsZW4gLSAxXVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBsb29rdXBbdG1wID4+IDJdICtcbiAgICAgIGxvb2t1cFsodG1wIDw8IDQpICYgMHgzRl0gK1xuICAgICAgJz09J1xuICAgIClcbiAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgdG1wID0gKHVpbnQ4W2xlbiAtIDJdIDw8IDgpICsgdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAxMF0gK1xuICAgICAgbG9va3VwWyh0bXAgPj4gNCkgJiAweDNGXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCAyKSAmIDB4M0ZdICtcbiAgICAgICc9J1xuICAgIClcbiAgfVxuXG4gIHJldHVybiBwYXJ0cy5qb2luKCcnKVxufVxuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnByb21pc2UnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpLlByb21pc2U7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5maW5kO1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXknKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLkFycmF5LmlzQXJyYXk7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5hcnJheS5zb21lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5zb21lO1xuIiwiLy8gZm9yIGEgbGVnYWN5IGNvZGUgYW5kIGZ1dHVyZSBmaXhlc1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBGdW5jdGlvbi5jYWxsLmFwcGx5KEFycmF5LnByb3RvdHlwZS5zcGxpY2UsIGFyZ3VtZW50cyk7XG59O1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZCcpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuRnVuY3Rpb24uYmluZDtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24nKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLk9iamVjdC5hc3NpZ247XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIvLyAyMi4xLjMuMzEgQXJyYXkucHJvdG90eXBlW0BAdW5zY29wYWJsZXNdXG52YXIgVU5TQ09QQUJMRVMgPSByZXF1aXJlKCcuL193a3MnKSgndW5zY29wYWJsZXMnKTtcbnZhciBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xuaWYgKEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdID09IHVuZGVmaW5lZCkgcmVxdWlyZSgnLi9faGlkZScpKEFycmF5UHJvdG8sIFVOU0NPUEFCTEVTLCB7fSk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgQXJyYXlQcm90b1tVTlNDT1BBQkxFU11ba2V5XSA9IHRydWU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIENvbnN0cnVjdG9yLCBuYW1lLCBmb3JiaWRkZW5GaWVsZCkge1xuICBpZiAoIShpdCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSB8fCAoZm9yYmlkZGVuRmllbGQgIT09IHVuZGVmaW5lZCAmJiBmb3JiaWRkZW5GaWVsZCBpbiBpdCkpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IobmFtZSArICc6IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICB9IHJldHVybiBpdDtcbn07XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmICghaXNPYmplY3QoaXQpKSB0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhbiBvYmplY3QhJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIvLyBmYWxzZSAtPiBBcnJheSNpbmRleE9mXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChJU19JTkNMVURFUykge1xuICByZXR1cm4gZnVuY3Rpb24gKCR0aGlzLCBlbCwgZnJvbUluZGV4KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoJHRoaXMpO1xuICAgIHZhciBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgdmFyIGluZGV4ID0gdG9BYnNvbHV0ZUluZGV4KGZyb21JbmRleCwgbGVuZ3RoKTtcbiAgICB2YXIgdmFsdWU7XG4gICAgLy8gQXJyYXkjaW5jbHVkZXMgdXNlcyBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICBpZiAoSVNfSU5DTFVERVMgJiYgZWwgIT0gZWwpIHdoaWxlIChsZW5ndGggPiBpbmRleCkge1xuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgICAgaWYgKHZhbHVlICE9IHZhbHVlKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBBcnJheSNpbmRleE9mIGlnbm9yZXMgaG9sZXMsIEFycmF5I2luY2x1ZGVzIC0gbm90XG4gICAgfSBlbHNlIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoSVNfSU5DTFVERVMgfHwgaW5kZXggaW4gTykge1xuICAgICAgaWYgKE9baW5kZXhdID09PSBlbCkgcmV0dXJuIElTX0lOQ0xVREVTIHx8IGluZGV4IHx8IDA7XG4gICAgfSByZXR1cm4gIUlTX0lOQ0xVREVTICYmIC0xO1xuICB9O1xufTtcbiIsIi8vIDAgLT4gQXJyYXkjZm9yRWFjaFxuLy8gMSAtPiBBcnJheSNtYXBcbi8vIDIgLT4gQXJyYXkjZmlsdGVyXG4vLyAzIC0+IEFycmF5I3NvbWVcbi8vIDQgLT4gQXJyYXkjZXZlcnlcbi8vIDUgLT4gQXJyYXkjZmluZFxuLy8gNiAtPiBBcnJheSNmaW5kSW5kZXhcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBhc2MgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoVFlQRSwgJGNyZWF0ZSkge1xuICB2YXIgSVNfTUFQID0gVFlQRSA9PSAxO1xuICB2YXIgSVNfRklMVEVSID0gVFlQRSA9PSAyO1xuICB2YXIgSVNfU09NRSA9IFRZUEUgPT0gMztcbiAgdmFyIElTX0VWRVJZID0gVFlQRSA9PSA0O1xuICB2YXIgSVNfRklORF9JTkRFWCA9IFRZUEUgPT0gNjtcbiAgdmFyIE5PX0hPTEVTID0gVFlQRSA9PSA1IHx8IElTX0ZJTkRfSU5ERVg7XG4gIHZhciBjcmVhdGUgPSAkY3JlYXRlIHx8IGFzYztcbiAgcmV0dXJuIGZ1bmN0aW9uICgkdGhpcywgY2FsbGJhY2tmbiwgdGhhdCkge1xuICAgIHZhciBPID0gdG9PYmplY3QoJHRoaXMpO1xuICAgIHZhciBzZWxmID0gSU9iamVjdChPKTtcbiAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCB0aGF0LCAzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoc2VsZi5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHJlc3VsdCA9IElTX01BUCA/IGNyZWF0ZSgkdGhpcywgbGVuZ3RoKSA6IElTX0ZJTFRFUiA/IGNyZWF0ZSgkdGhpcywgMCkgOiB1bmRlZmluZWQ7XG4gICAgdmFyIHZhbCwgcmVzO1xuICAgIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoTk9fSE9MRVMgfHwgaW5kZXggaW4gc2VsZikge1xuICAgICAgdmFsID0gc2VsZltpbmRleF07XG4gICAgICByZXMgPSBmKHZhbCwgaW5kZXgsIE8pO1xuICAgICAgaWYgKFRZUEUpIHtcbiAgICAgICAgaWYgKElTX01BUCkgcmVzdWx0W2luZGV4XSA9IHJlczsgICAvLyBtYXBcbiAgICAgICAgZWxzZSBpZiAocmVzKSBzd2l0Y2ggKFRZUEUpIHtcbiAgICAgICAgICBjYXNlIDM6IHJldHVybiB0cnVlOyAgICAgICAgICAgICAvLyBzb21lXG4gICAgICAgICAgY2FzZSA1OiByZXR1cm4gdmFsOyAgICAgICAgICAgICAgLy8gZmluZFxuICAgICAgICAgIGNhc2UgNjogcmV0dXJuIGluZGV4OyAgICAgICAgICAgIC8vIGZpbmRJbmRleFxuICAgICAgICAgIGNhc2UgMjogcmVzdWx0LnB1c2godmFsKTsgICAgICAgIC8vIGZpbHRlclxuICAgICAgICB9IGVsc2UgaWYgKElTX0VWRVJZKSByZXR1cm4gZmFsc2U7IC8vIGV2ZXJ5XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBJU19GSU5EX0lOREVYID8gLTEgOiBJU19TT01FIHx8IElTX0VWRVJZID8gSVNfRVZFUlkgOiByZXN1bHQ7XG4gIH07XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9yaWdpbmFsKSB7XG4gIHZhciBDO1xuICBpZiAoaXNBcnJheShvcmlnaW5hbCkpIHtcbiAgICBDID0gb3JpZ2luYWwuY29uc3RydWN0b3I7XG4gICAgLy8gY3Jvc3MtcmVhbG0gZmFsbGJhY2tcbiAgICBpZiAodHlwZW9mIEMgPT0gJ2Z1bmN0aW9uJyAmJiAoQyA9PT0gQXJyYXkgfHwgaXNBcnJheShDLnByb3RvdHlwZSkpKSBDID0gdW5kZWZpbmVkO1xuICAgIGlmIChpc09iamVjdChDKSkge1xuICAgICAgQyA9IENbU1BFQ0lFU107XG4gICAgICBpZiAoQyA9PT0gbnVsbCkgQyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gcmV0dXJuIEMgPT09IHVuZGVmaW5lZCA/IEFycmF5IDogQztcbn07XG4iLCIvLyA5LjQuMi4zIEFycmF5U3BlY2llc0NyZWF0ZShvcmlnaW5hbEFycmF5LCBsZW5ndGgpXG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcmlnaW5hbCwgbGVuZ3RoKSB7XG4gIHJldHVybiBuZXcgKHNwZWNpZXNDb25zdHJ1Y3RvcihvcmlnaW5hbCkpKGxlbmd0aCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGFycmF5U2xpY2UgPSBbXS5zbGljZTtcbnZhciBmYWN0b3JpZXMgPSB7fTtcblxudmFyIGNvbnN0cnVjdCA9IGZ1bmN0aW9uIChGLCBsZW4sIGFyZ3MpIHtcbiAgaWYgKCEobGVuIGluIGZhY3RvcmllcykpIHtcbiAgICBmb3IgKHZhciBuID0gW10sIGkgPSAwOyBpIDwgbGVuOyBpKyspIG5baV0gPSAnYVsnICsgaSArICddJztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICBmYWN0b3JpZXNbbGVuXSA9IEZ1bmN0aW9uKCdGLGEnLCAncmV0dXJuIG5ldyBGKCcgKyBuLmpvaW4oJywnKSArICcpJyk7XG4gIH0gcmV0dXJuIGZhY3Rvcmllc1tsZW5dKEYsIGFyZ3MpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5iaW5kIHx8IGZ1bmN0aW9uIGJpbmQodGhhdCAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgdmFyIGZuID0gYUZ1bmN0aW9uKHRoaXMpO1xuICB2YXIgcGFydEFyZ3MgPSBhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgdmFyIGJvdW5kID0gZnVuY3Rpb24gKC8qIGFyZ3MuLi4gKi8pIHtcbiAgICB2YXIgYXJncyA9IHBhcnRBcmdzLmNvbmNhdChhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBib3VuZCA/IGNvbnN0cnVjdChmbiwgYXJncy5sZW5ndGgsIGFyZ3MpIDogaW52b2tlKGZuLCBhcmdzLCB0aGF0KTtcbiAgfTtcbiAgaWYgKGlzT2JqZWN0KGZuLnByb3RvdHlwZSkpIGJvdW5kLnByb3RvdHlwZSA9IGZuLnByb3RvdHlwZTtcbiAgcmV0dXJuIGJvdW5kO1xufTtcbiIsIi8vIGdldHRpbmcgdGFnIGZyb20gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgVEFHID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyk7XG4vLyBFUzMgd3JvbmcgaGVyZVxudmFyIEFSRyA9IGNvZihmdW5jdGlvbiAoKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPT0gJ0FyZ3VtZW50cyc7XG5cbi8vIGZhbGxiYWNrIGZvciBJRTExIFNjcmlwdCBBY2Nlc3MgRGVuaWVkIGVycm9yXG52YXIgdHJ5R2V0ID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gaXRba2V5XTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgTywgVCwgQjtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyAnVW5kZWZpbmVkJyA6IGl0ID09PSBudWxsID8gJ051bGwnXG4gICAgLy8gQEB0b1N0cmluZ1RhZyBjYXNlXG4gICAgOiB0eXBlb2YgKFQgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRBRykpID09ICdzdHJpbmcnID8gVFxuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQVJHID8gY29mKE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKEIgPSBjb2YoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiBCO1xufTtcbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTtcbiIsInZhciBjb3JlID0gbW9kdWxlLmV4cG9ydHMgPSB7IHZlcnNpb246ICcyLjYuNCcgfTtcbmlmICh0eXBlb2YgX19lID09ICdudW1iZXInKSBfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgdGhhdCwgbGVuZ3RoKSB7XG4gIGFGdW5jdGlvbihmbik7XG4gIGlmICh0aGF0ID09PSB1bmRlZmluZWQpIHJldHVybiBmbjtcbiAgc3dpdGNoIChsZW5ndGgpIHtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSk7XG4gICAgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKC8qIC4uLmFyZ3MgKi8pIHtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xuLy8gdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgaXMgJ29iamVjdCcgaW4gb2xkIElFXG52YXIgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXMgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG5cbnZhciAkZXhwb3J0ID0gZnVuY3Rpb24gKHR5cGUsIG5hbWUsIHNvdXJjZSkge1xuICB2YXIgSVNfRk9SQ0VEID0gdHlwZSAmICRleHBvcnQuRjtcbiAgdmFyIElTX0dMT0JBTCA9IHR5cGUgJiAkZXhwb3J0Lkc7XG4gIHZhciBJU19TVEFUSUMgPSB0eXBlICYgJGV4cG9ydC5TO1xuICB2YXIgSVNfUFJPVE8gPSB0eXBlICYgJGV4cG9ydC5QO1xuICB2YXIgSVNfQklORCA9IHR5cGUgJiAkZXhwb3J0LkI7XG4gIHZhciB0YXJnZXQgPSBJU19HTE9CQUwgPyBnbG9iYWwgOiBJU19TVEFUSUMgPyBnbG9iYWxbbmFtZV0gfHwgKGdsb2JhbFtuYW1lXSA9IHt9KSA6IChnbG9iYWxbbmFtZV0gfHwge30pW1BST1RPVFlQRV07XG4gIHZhciBleHBvcnRzID0gSVNfR0xPQkFMID8gY29yZSA6IGNvcmVbbmFtZV0gfHwgKGNvcmVbbmFtZV0gPSB7fSk7XG4gIHZhciBleHBQcm90byA9IGV4cG9ydHNbUFJPVE9UWVBFXSB8fCAoZXhwb3J0c1tQUk9UT1RZUEVdID0ge30pO1xuICB2YXIga2V5LCBvd24sIG91dCwgZXhwO1xuICBpZiAoSVNfR0xPQkFMKSBzb3VyY2UgPSBuYW1lO1xuICBmb3IgKGtleSBpbiBzb3VyY2UpIHtcbiAgICAvLyBjb250YWlucyBpbiBuYXRpdmVcbiAgICBvd24gPSAhSVNfRk9SQ0VEICYmIHRhcmdldCAmJiB0YXJnZXRba2V5XSAhPT0gdW5kZWZpbmVkO1xuICAgIC8vIGV4cG9ydCBuYXRpdmUgb3IgcGFzc2VkXG4gICAgb3V0ID0gKG93biA/IHRhcmdldCA6IHNvdXJjZSlba2V5XTtcbiAgICAvLyBiaW5kIHRpbWVycyB0byBnbG9iYWwgZm9yIGNhbGwgZnJvbSBleHBvcnQgY29udGV4dFxuICAgIGV4cCA9IElTX0JJTkQgJiYgb3duID8gY3R4KG91dCwgZ2xvYmFsKSA6IElTX1BST1RPICYmIHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJyA/IGN0eChGdW5jdGlvbi5jYWxsLCBvdXQpIDogb3V0O1xuICAgIC8vIGV4dGVuZCBnbG9iYWxcbiAgICBpZiAodGFyZ2V0KSByZWRlZmluZSh0YXJnZXQsIGtleSwgb3V0LCB0eXBlICYgJGV4cG9ydC5VKTtcbiAgICAvLyBleHBvcnRcbiAgICBpZiAoZXhwb3J0c1trZXldICE9IG91dCkgaGlkZShleHBvcnRzLCBrZXksIGV4cCk7XG4gICAgaWYgKElTX1BST1RPICYmIGV4cFByb3RvW2tleV0gIT0gb3V0KSBleHBQcm90b1trZXldID0gb3V0O1xuICB9XG59O1xuZ2xvYmFsLmNvcmUgPSBjb3JlO1xuLy8gdHlwZSBiaXRtYXBcbiRleHBvcnQuRiA9IDE7ICAgLy8gZm9yY2VkXG4kZXhwb3J0LkcgPSAyOyAgIC8vIGdsb2JhbFxuJGV4cG9ydC5TID0gNDsgICAvLyBzdGF0aWNcbiRleHBvcnQuUCA9IDg7ICAgLy8gcHJvdG9cbiRleHBvcnQuQiA9IDE2OyAgLy8gYmluZFxuJGV4cG9ydC5XID0gMzI7ICAvLyB3cmFwXG4kZXhwb3J0LlUgPSA2NDsgIC8vIHNhZmVcbiRleHBvcnQuUiA9IDEyODsgLy8gcmVhbCBwcm90byBtZXRob2QgZm9yIGBsaWJyYXJ5YFxubW9kdWxlLmV4cG9ydHMgPSAkZXhwb3J0O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYykge1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbnZhciBCUkVBSyA9IHt9O1xudmFyIFJFVFVSTiA9IHt9O1xudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgZW50cmllcywgZm4sIHRoYXQsIElURVJBVE9SKSB7XG4gIHZhciBpdGVyRm4gPSBJVEVSQVRPUiA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXJhYmxlOyB9IDogZ2V0SXRlckZuKGl0ZXJhYmxlKTtcbiAgdmFyIGYgPSBjdHgoZm4sIHRoYXQsIGVudHJpZXMgPyAyIDogMSk7XG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsZW5ndGgsIHN0ZXAsIGl0ZXJhdG9yLCByZXN1bHQ7XG4gIGlmICh0eXBlb2YgaXRlckZuICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdGVyYWJsZSArICcgaXMgbm90IGl0ZXJhYmxlIScpO1xuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcbiAgaWYgKGlzQXJyYXlJdGVyKGl0ZXJGbikpIGZvciAobGVuZ3RoID0gdG9MZW5ndGgoaXRlcmFibGUubGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICByZXN1bHQgPSBlbnRyaWVzID8gZihhbk9iamVjdChzdGVwID0gaXRlcmFibGVbaW5kZXhdKVswXSwgc3RlcFsxXSkgOiBmKGl0ZXJhYmxlW2luZGV4XSk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH0gZWxzZSBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoaXRlcmFibGUpOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7KSB7XG4gICAgcmVzdWx0ID0gY2FsbChpdGVyYXRvciwgZiwgc3RlcC52YWx1ZSwgZW50cmllcyk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH1cbn07XG5leHBvcnRzLkJSRUFLID0gQlJFQUs7XG5leHBvcnRzLlJFVFVSTiA9IFJFVFVSTjtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ25hdGl2ZS1mdW5jdGlvbi10by1zdHJpbmcnLCBGdW5jdGlvbi50b1N0cmluZyk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvODYjaXNzdWVjb21tZW50LTExNTc1OTAyOFxudmFyIGdsb2JhbCA9IG1vZHVsZS5leHBvcnRzID0gdHlwZW9mIHdpbmRvdyAhPSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuTWF0aCA9PSBNYXRoXG4gID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09IE1hdGggPyBzZWxmXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICA6IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5pZiAodHlwZW9mIF9fZyA9PSAnbnVtYmVyJykgX19nID0gZ2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIGRQLmYob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuIiwidmFyIGRvY3VtZW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnQ7XG5tb2R1bGUuZXhwb3J0cyA9IGRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiIsIm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnZGl2JyksICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCIvLyBmYXN0IGFwcGx5LCBodHRwOi8vanNwZXJmLmxua2l0LmNvbS9mYXN0LWFwcGx5LzVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCBhcmdzLCB0aGF0KSB7XG4gIHZhciB1biA9IHRoYXQgPT09IHVuZGVmaW5lZDtcbiAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgIGNhc2UgMDogcmV0dXJuIHVuID8gZm4oKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0KTtcbiAgICBjYXNlIDE6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0pO1xuICAgIGNhc2UgMjogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgY2FzZSAzOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICBjYXNlIDQ6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICB9IHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmdzKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QoJ3onKS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgwKSA/IE9iamVjdCA6IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gY29mKGl0KSA9PSAnU3RyaW5nJyA/IGl0LnNwbGl0KCcnKSA6IE9iamVjdChpdCk7XG59O1xuIiwiLy8gY2hlY2sgb24gZGVmYXVsdCBBcnJheSBpdGVyYXRvclxudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ICE9PSB1bmRlZmluZWQgJiYgKEl0ZXJhdG9ycy5BcnJheSA9PT0gaXQgfHwgQXJyYXlQcm90b1tJVEVSQVRPUl0gPT09IGl0KTtcbn07XG4iLCIvLyA3LjIuMiBJc0FycmF5KGFyZ3VtZW50KVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIHJldHVybiBjb2YoYXJnKSA9PSAnQXJyYXknO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0eXBlb2YgaXQgPT09ICdvYmplY3QnID8gaXQgIT09IG51bGwgOiB0eXBlb2YgaXQgPT09ICdmdW5jdGlvbic7XG59O1xuIiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcbiAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgfSBjYXRjaCAoZSkge1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkKSBhbk9iamVjdChyZXQuY2FsbChpdGVyYXRvcikpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGRlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG5cbi8vIDI1LjEuMi4xLjEgJUl0ZXJhdG9yUHJvdG90eXBlJVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19oaWRlJykoSXRlcmF0b3JQcm90b3R5cGUsIHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpLCBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpIHtcbiAgQ29uc3RydWN0b3IucHJvdG90eXBlID0gY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlLCB7IG5leHQ6IGRlc2NyaXB0b3IoMSwgbmV4dCkgfSk7XG4gIHNldFRvU3RyaW5nVGFnKENvbnN0cnVjdG9yLCBOQU1FICsgJyBJdGVyYXRvcicpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciAkaXRlckNyZWF0ZSA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQlVHR1kgPSAhKFtdLmtleXMgJiYgJ25leHQnIGluIFtdLmtleXMoKSk7IC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbnZhciBGRl9JVEVSQVRPUiA9ICdAQGl0ZXJhdG9yJztcbnZhciBLRVlTID0gJ2tleXMnO1xudmFyIFZBTFVFUyA9ICd2YWx1ZXMnO1xuXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEJhc2UsIE5BTUUsIENvbnN0cnVjdG9yLCBuZXh0LCBERUZBVUxULCBJU19TRVQsIEZPUkNFRCkge1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoa2luZCkge1xuICAgIGlmICghQlVHR1kgJiYga2luZCBpbiBwcm90bykgcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgPSBOQU1FICsgJyBJdGVyYXRvcic7XG4gIHZhciBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVM7XG4gIHZhciBWQUxVRVNfQlVHID0gZmFsc2U7XG4gIHZhciBwcm90byA9IEJhc2UucHJvdG90eXBlO1xuICB2YXIgJG5hdGl2ZSA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXTtcbiAgdmFyICRkZWZhdWx0ID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVCk7XG4gIHZhciAkZW50cmllcyA9IERFRkFVTFQgPyAhREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKCdlbnRyaWVzJykgOiB1bmRlZmluZWQ7XG4gIHZhciAkYW55TmF0aXZlID0gTkFNRSA9PSAnQXJyYXknID8gcHJvdG8uZW50cmllcyB8fCAkbmF0aXZlIDogJG5hdGl2ZTtcbiAgdmFyIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYgKCRhbnlOYXRpdmUpIHtcbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKCRhbnlOYXRpdmUuY2FsbChuZXcgQmFzZSgpKSk7XG4gICAgaWYgKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlICYmIEl0ZXJhdG9yUHJvdG90eXBlLm5leHQpIHtcbiAgICAgIC8vIFNldCBAQHRvU3RyaW5nVGFnIHRvIG5hdGl2ZSBpdGVyYXRvcnNcbiAgICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG4gICAgICBpZiAoIUxJQlJBUlkgJiYgdHlwZW9mIEl0ZXJhdG9yUHJvdG90eXBlW0lURVJBVE9SXSAhPSAnZnVuY3Rpb24nKSBoaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG4gICAgfVxuICB9XG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcbiAgaWYgKERFRl9WQUxVRVMgJiYgJG5hdGl2ZSAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUykge1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZiAoKCFMSUJSQVJZIHx8IEZPUkNFRCkgJiYgKEJVR0dZIHx8IFZBTFVFU19CVUcgfHwgIXByb3RvW0lURVJBVE9SXSkpIHtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddID0gcmV0dXJuVGhpcztcbiAgaWYgKERFRkFVTFQpIHtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6IElTX1NFVCA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKEtFWVMpLFxuICAgICAgZW50cmllczogJGVudHJpZXNcbiAgICB9O1xuICAgIGlmIChGT1JDRUQpIGZvciAoa2V5IGluIG1ldGhvZHMpIHtcbiAgICAgIGlmICghKGtleSBpbiBwcm90bykpIHJlZGVmaW5lKHByb3RvLCBrZXksIG1ldGhvZHNba2V5XSk7XG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcbiAgfVxuICByZXR1cm4gbWV0aG9kcztcbn07XG4iLCJ2YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbiAoKSB7IFNBRkVfQ0xPU0lORyA9IHRydWU7IH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uICgpIHsgdGhyb3cgMjsgfSk7XG59IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYywgc2tpcENsb3NpbmcpIHtcbiAgaWYgKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKSByZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IFs3XTtcbiAgICB2YXIgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB7IGRvbmU6IHNhZmUgPSB0cnVlIH07IH07XG4gICAgYXJyW0lURVJBVE9SXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZG9uZSwgdmFsdWUpIHtcbiAgcmV0dXJuIHsgdmFsdWU6IHZhbHVlLCBkb25lOiAhIWRvbmUgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmYWxzZTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBtYWNyb3Rhc2sgPSByZXF1aXJlKCcuL190YXNrJykuc2V0O1xudmFyIE9ic2VydmVyID0gZ2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgZ2xvYmFsLldlYktpdE11dGF0aW9uT2JzZXJ2ZXI7XG52YXIgcHJvY2VzcyA9IGdsb2JhbC5wcm9jZXNzO1xudmFyIFByb21pc2UgPSBnbG9iYWwuUHJvbWlzZTtcbnZhciBpc05vZGUgPSByZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaGVhZCwgbGFzdCwgbm90aWZ5O1xuXG4gIHZhciBmbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcGFyZW50LCBmbjtcbiAgICBpZiAoaXNOb2RlICYmIChwYXJlbnQgPSBwcm9jZXNzLmRvbWFpbikpIHBhcmVudC5leGl0KCk7XG4gICAgd2hpbGUgKGhlYWQpIHtcbiAgICAgIGZuID0gaGVhZC5mbjtcbiAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICB0cnkge1xuICAgICAgICBmbigpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaGVhZCkgbm90aWZ5KCk7XG4gICAgICAgIGVsc2UgbGFzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LmVudGVyKCk7XG4gIH07XG5cbiAgLy8gTm9kZS5qc1xuICBpZiAoaXNOb2RlKSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgfTtcbiAgLy8gYnJvd3NlcnMgd2l0aCBNdXRhdGlvbk9ic2VydmVyLCBleGNlcHQgaU9TIFNhZmFyaSAtIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8zMzlcbiAgfSBlbHNlIGlmIChPYnNlcnZlciAmJiAhKGdsb2JhbC5uYXZpZ2F0b3IgJiYgZ2xvYmFsLm5hdmlnYXRvci5zdGFuZGFsb25lKSkge1xuICAgIHZhciB0b2dnbGUgPSB0cnVlO1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICAgIG5ldyBPYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlID0gIXRvZ2dsZTtcbiAgICB9O1xuICAvLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxuICB9IGVsc2UgaWYgKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKSB7XG4gICAgLy8gUHJvbWlzZS5yZXNvbHZlIHdpdGhvdXQgYW4gYXJndW1lbnQgdGhyb3dzIGFuIGVycm9yIGluIExHIFdlYk9TIDJcbiAgICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHByb21pc2UudGhlbihmbHVzaCk7XG4gICAgfTtcbiAgLy8gZm9yIG90aGVyIGVudmlyb25tZW50cyAtIG1hY3JvdGFzayBiYXNlZCBvbjpcbiAgLy8gLSBzZXRJbW1lZGlhdGVcbiAgLy8gLSBNZXNzYWdlQ2hhbm5lbFxuICAvLyAtIHdpbmRvdy5wb3N0TWVzc2FnXG4gIC8vIC0gb25yZWFkeXN0YXRlY2hhbmdlXG4gIC8vIC0gc2V0VGltZW91dFxuICB9IGVsc2Uge1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHN0cmFuZ2UgSUUgKyB3ZWJwYWNrIGRldiBzZXJ2ZXIgYnVnIC0gdXNlIC5jYWxsKGdsb2JhbClcbiAgICAgIG1hY3JvdGFzay5jYWxsKGdsb2JhbCwgZmx1c2gpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKGZuKSB7XG4gICAgdmFyIHRhc2sgPSB7IGZuOiBmbiwgbmV4dDogdW5kZWZpbmVkIH07XG4gICAgaWYgKGxhc3QpIGxhc3QubmV4dCA9IHRhc2s7XG4gICAgaWYgKCFoZWFkKSB7XG4gICAgICBoZWFkID0gdGFzaztcbiAgICAgIG5vdGlmeSgpO1xuICAgIH0gbGFzdCA9IHRhc2s7XG4gIH07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjUuNC4xLjUgTmV3UHJvbWlzZUNhcGFiaWxpdHkoQylcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5cbmZ1bmN0aW9uIFByb21pc2VDYXBhYmlsaXR5KEMpIHtcbiAgdmFyIHJlc29sdmUsIHJlamVjdDtcbiAgdGhpcy5wcm9taXNlID0gbmV3IEMoZnVuY3Rpb24gKCQkcmVzb2x2ZSwgJCRyZWplY3QpIHtcbiAgICBpZiAocmVzb2x2ZSAhPT0gdW5kZWZpbmVkIHx8IHJlamVjdCAhPT0gdW5kZWZpbmVkKSB0aHJvdyBUeXBlRXJyb3IoJ0JhZCBQcm9taXNlIGNvbnN0cnVjdG9yJyk7XG4gICAgcmVzb2x2ZSA9ICQkcmVzb2x2ZTtcbiAgICByZWplY3QgPSAkJHJlamVjdDtcbiAgfSk7XG4gIHRoaXMucmVzb2x2ZSA9IGFGdW5jdGlvbihyZXNvbHZlKTtcbiAgdGhpcy5yZWplY3QgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZiA9IGZ1bmN0aW9uIChDKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZUNhcGFiaWxpdHkoQyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4yLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSwgLi4uKVxudmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIGdPUFMgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wcycpO1xudmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgJGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5cbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxubW9kdWxlLmV4cG9ydHMgPSAhJGFzc2lnbiB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgdmFyIEEgPSB7fTtcbiAgdmFyIEIgPSB7fTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIHZhciBTID0gU3ltYm9sKCk7XG4gIHZhciBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGspIHsgQltrXSA9IGs7IH0pO1xuICByZXR1cm4gJGFzc2lnbih7fSwgQSlbU10gIT0gNyB8fCBPYmplY3Qua2V5cygkYXNzaWduKHt9LCBCKSkuam9pbignJykgIT0gSztcbn0pID8gZnVuY3Rpb24gYXNzaWduKHRhcmdldCwgc291cmNlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgPSB0b09iamVjdCh0YXJnZXQpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IDE7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICB2YXIgaXNFbnVtID0gcElFLmY7XG4gIHdoaWxlIChhTGVuID4gaW5kZXgpIHtcbiAgICB2YXIgUyA9IElPYmplY3QoYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICB2YXIga2V5cyA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUyk7XG4gICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICAgIHZhciBqID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBqKSBpZiAoaXNFbnVtLmNhbGwoUywga2V5ID0ga2V5c1tqKytdKSkgVFtrZXldID0gU1trZXldO1xuICB9IHJldHVybiBUO1xufSA6ICRhc3NpZ247XG4iLCIvLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGRQcyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBFbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxudmFyIGNyZWF0ZURpY3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpO1xuICB2YXIgaSA9IGVudW1CdWdLZXlzLmxlbmd0aDtcbiAgdmFyIGx0ID0gJzwnO1xuICB2YXIgZ3QgPSAnPic7XG4gIHZhciBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xuICB3aGlsZSAoaS0tKSBkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0O1xuICBpZiAoTyAhPT0gbnVsbCkge1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcbiAgICByZXN1bHQgPSBuZXcgRW1wdHkoKTtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcbiAgICAvLyBhZGQgXCJfX3Byb3RvX19cIiBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mIHBvbHlmaWxsXG4gICAgcmVzdWx0W0lFX1BST1RPXSA9IE87XG4gIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XG4gIHJldHVybiBQcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiBkUHMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBkUCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgYW5PYmplY3QoQXR0cmlidXRlcyk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZFAoTywgUCwgQXR0cmlidXRlcyk7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICBpZiAoJ2dldCcgaW4gQXR0cmlidXRlcyB8fCAnc2V0JyBpbiBBdHRyaWJ1dGVzKSB0aHJvdyBUeXBlRXJyb3IoJ0FjY2Vzc29ycyBub3Qgc3VwcG9ydGVkIScpO1xuICBpZiAoJ3ZhbHVlJyBpbiBBdHRyaWJ1dGVzKSBPW1BdID0gQXR0cmlidXRlcy52YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIHZhciBrZXlzID0gZ2V0S2V5cyhQcm9wZXJ0aWVzKTtcbiAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICB2YXIgaSA9IDA7XG4gIHZhciBQO1xuICB3aGlsZSAobGVuZ3RoID4gaSkgZFAuZihPLCBQID0ga2V5c1tpKytdLCBQcm9wZXJ0aWVzW1BdKTtcbiAgcmV0dXJuIE87XG59O1xuIiwiZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcbiIsIi8vIDE5LjEuMi45IC8gMTUuMi4zLjIgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBPYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmdldFByb3RvdHlwZU9mIHx8IGZ1bmN0aW9uIChPKSB7XG4gIE8gPSB0b09iamVjdChPKTtcbiAgaWYgKGhhcyhPLCBJRV9QUk9UTykpIHJldHVybiBPW0lFX1BST1RPXTtcbiAgaWYgKHR5cGVvZiBPLmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgTyBpbnN0YW5jZW9mIE8uY29uc3RydWN0b3IpIHtcbiAgICByZXR1cm4gTy5jb25zdHJ1Y3Rvci5wcm90b3R5cGU7XG4gIH0gcmV0dXJuIE8gaW5zdGFuY2VvZiBPYmplY3QgPyBPYmplY3RQcm90byA6IG51bGw7XG59O1xuIiwidmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBhcnJheUluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lcykge1xuICB2YXIgTyA9IHRvSU9iamVjdChvYmplY3QpO1xuICB2YXIgaSA9IDA7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGtleTtcbiAgZm9yIChrZXkgaW4gTykgaWYgKGtleSAhPSBJRV9QUk9UTykgaGFzKE8sIGtleSkgJiYgcmVzdWx0LnB1c2goa2V5KTtcbiAgLy8gRG9uJ3QgZW51bSBidWcgJiBoaWRkZW4ga2V5c1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkgaWYgKGhhcyhPLCBrZXkgPSBuYW1lc1tpKytdKSkge1xuICAgIH5hcnJheUluZGV4T2YocmVzdWx0LCBrZXkpIHx8IHJlc3VsdC5wdXNoKGtleSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvLyAxOS4xLjIuMTQgLyAxNS4yLjMuMTQgT2JqZWN0LmtleXMoTylcbnZhciAka2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJyk7XG52YXIgZW51bUJ1Z0tleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyhPKSB7XG4gIHJldHVybiAka2V5cyhPLCBlbnVtQnVnS2V5cyk7XG59O1xuIiwiZXhwb3J0cy5mID0ge30ucHJvcGVydHlJc0VudW1lcmFibGU7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChleGVjKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHsgZTogZmFsc2UsIHY6IGV4ZWMoKSB9O1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHsgZTogdHJ1ZSwgdjogZSB9O1xuICB9XG59O1xuIiwidmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQywgeCkge1xuICBhbk9iamVjdChDKTtcbiAgaWYgKGlzT2JqZWN0KHgpICYmIHguY29uc3RydWN0b3IgPT09IEMpIHJldHVybiB4O1xuICB2YXIgcHJvbWlzZUNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eS5mKEMpO1xuICB2YXIgcmVzb2x2ZSA9IHByb21pc2VDYXBhYmlsaXR5LnJlc29sdmU7XG4gIHJlc29sdmUoeCk7XG4gIHJldHVybiBwcm9taXNlQ2FwYWJpbGl0eS5wcm9taXNlO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdG1hcCwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZTogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfTtcbn07XG4iLCJ2YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGFyZ2V0LCBzcmMsIHNhZmUpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykgcmVkZWZpbmUodGFyZ2V0LCBrZXksIHNyY1trZXldLCBzYWZlKTtcbiAgcmV0dXJuIHRhcmdldDtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBTUkMgPSByZXF1aXJlKCcuL191aWQnKSgnc3JjJyk7XG52YXIgJHRvU3RyaW5nID0gcmVxdWlyZSgnLi9fZnVuY3Rpb24tdG8tc3RyaW5nJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciBUUEwgPSAoJycgKyAkdG9TdHJpbmcpLnNwbGl0KFRPX1NUUklORyk7XG5cbnJlcXVpcmUoJy4vX2NvcmUnKS5pbnNwZWN0U291cmNlID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiAkdG9TdHJpbmcuY2FsbChpdCk7XG59O1xuXG4obW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTywga2V5LCB2YWwsIHNhZmUpIHtcbiAgdmFyIGlzRnVuY3Rpb24gPSB0eXBlb2YgdmFsID09ICdmdW5jdGlvbic7XG4gIGlmIChpc0Z1bmN0aW9uKSBoYXModmFsLCAnbmFtZScpIHx8IGhpZGUodmFsLCAnbmFtZScsIGtleSk7XG4gIGlmIChPW2tleV0gPT09IHZhbCkgcmV0dXJuO1xuICBpZiAoaXNGdW5jdGlvbikgaGFzKHZhbCwgU1JDKSB8fCBoaWRlKHZhbCwgU1JDLCBPW2tleV0gPyAnJyArIE9ba2V5XSA6IFRQTC5qb2luKFN0cmluZyhrZXkpKSk7XG4gIGlmIChPID09PSBnbG9iYWwpIHtcbiAgICBPW2tleV0gPSB2YWw7XG4gIH0gZWxzZSBpZiAoIXNhZmUpIHtcbiAgICBkZWxldGUgT1trZXldO1xuICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICB9IGVsc2UgaWYgKE9ba2V5XSkge1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIHtcbiAgICBoaWRlKE8sIGtleSwgdmFsKTtcbiAgfVxuLy8gYWRkIGZha2UgRnVuY3Rpb24jdG9TdHJpbmcgZm9yIGNvcnJlY3Qgd29yayB3cmFwcGVkIG1ldGhvZHMgLyBjb25zdHJ1Y3RvcnMgd2l0aCBtZXRob2RzIGxpa2UgTG9EYXNoIGlzTmF0aXZlXG59KShGdW5jdGlvbi5wcm90b3R5cGUsIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gIHJldHVybiB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nICYmIHRoaXNbU1JDXSB8fCAkdG9TdHJpbmcuY2FsbCh0aGlzKTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpO1xudmFyIFNQRUNJRVMgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChLRVkpIHtcbiAgdmFyIEMgPSBnbG9iYWxbS0VZXTtcbiAgaWYgKERFU0NSSVBUT1JTICYmIEMgJiYgIUNbU1BFQ0lFU10pIGRQLmYoQywgU1BFQ0lFUywge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH1cbiAgfSk7XG59O1xuIiwidmFyIGRlZiA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgVEFHID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCB0YWcsIHN0YXQpIHtcbiAgaWYgKGl0ICYmICFoYXMoaXQgPSBzdGF0ID8gaXQgOiBpdC5wcm90b3R5cGUsIFRBRykpIGRlZihpdCwgVEFHLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHRhZyB9KTtcbn07XG4iLCJ2YXIgc2hhcmVkID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ2tleXMnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICByZXR1cm4gc2hhcmVkW2tleV0gfHwgKHNoYXJlZFtrZXldID0gdWlkKGtleSkpO1xufTtcbiIsInZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIFNIQVJFRCA9ICdfX2NvcmUtanNfc2hhcmVkX18nO1xudmFyIHN0b3JlID0gZ2xvYmFsW1NIQVJFRF0gfHwgKGdsb2JhbFtTSEFSRURdID0ge30pO1xuXG4obW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICByZXR1cm4gc3RvcmVba2V5XSB8fCAoc3RvcmVba2V5XSA9IHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IHt9KTtcbn0pKCd2ZXJzaW9ucycsIFtdKS5wdXNoKHtcbiAgdmVyc2lvbjogY29yZS52ZXJzaW9uLFxuICBtb2RlOiByZXF1aXJlKCcuL19saWJyYXJ5JykgPyAncHVyZScgOiAnZ2xvYmFsJyxcbiAgY29weXJpZ2h0OiAnwqkgMjAxOSBEZW5pcyBQdXNoa2FyZXYgKHpsb2lyb2NrLnJ1KSdcbn0pO1xuIiwiLy8gNy4zLjIwIFNwZWNpZXNDb25zdHJ1Y3RvcihPLCBkZWZhdWx0Q29uc3RydWN0b3IpXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChPLCBEKSB7XG4gIHZhciBDID0gYW5PYmplY3QoTykuY29uc3RydWN0b3I7XG4gIHZhciBTO1xuICByZXR1cm4gQyA9PT0gdW5kZWZpbmVkIHx8IChTID0gYW5PYmplY3QoQylbU1BFQ0lFU10pID09IHVuZGVmaW5lZCA/IEQgOiBhRnVuY3Rpb24oUyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobWV0aG9kLCBhcmcpIHtcbiAgcmV0dXJuICEhbWV0aG9kICYmIGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1jYWxsXG4gICAgYXJnID8gbWV0aG9kLmNhbGwobnVsbCwgZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9LCAxKSA6IG1ldGhvZC5jYWxsKG51bGwpO1xuICB9KTtcbn07XG4iLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG4vLyB0cnVlICAtPiBTdHJpbmcjYXRcbi8vIGZhbHNlIC0+IFN0cmluZyNjb2RlUG9pbnRBdFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoVE9fU1RSSU5HKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGhhdCwgcG9zKSB7XG4gICAgdmFyIHMgPSBTdHJpbmcoZGVmaW5lZCh0aGF0KSk7XG4gICAgdmFyIGkgPSB0b0ludGVnZXIocG9zKTtcbiAgICB2YXIgbCA9IHMubGVuZ3RoO1xuICAgIHZhciBhLCBiO1xuICAgIGlmIChpIDwgMCB8fCBpID49IGwpIHJldHVybiBUT19TVFJJTkcgPyAnJyA6IHVuZGVmaW5lZDtcbiAgICBhID0gcy5jaGFyQ29kZUF0KGkpO1xuICAgIHJldHVybiBhIDwgMHhkODAwIHx8IGEgPiAweGRiZmYgfHwgaSArIDEgPT09IGwgfHwgKGIgPSBzLmNoYXJDb2RlQXQoaSArIDEpKSA8IDB4ZGMwMCB8fCBiID4gMHhkZmZmXG4gICAgICA/IFRPX1NUUklORyA/IHMuY2hhckF0KGkpIDogYVxuICAgICAgOiBUT19TVFJJTkcgPyBzLnNsaWNlKGksIGkgKyAyKSA6IChhIC0gMHhkODAwIDw8IDEwKSArIChiIC0gMHhkYzAwKSArIDB4MTAwMDA7XG4gIH07XG59O1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGh0bWwgPSByZXF1aXJlKCcuL19odG1sJyk7XG52YXIgY2VsID0gcmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIHByb2Nlc3MgPSBnbG9iYWwucHJvY2VzcztcbnZhciBzZXRUYXNrID0gZ2xvYmFsLnNldEltbWVkaWF0ZTtcbnZhciBjbGVhclRhc2sgPSBnbG9iYWwuY2xlYXJJbW1lZGlhdGU7XG52YXIgTWVzc2FnZUNoYW5uZWwgPSBnbG9iYWwuTWVzc2FnZUNoYW5uZWw7XG52YXIgRGlzcGF0Y2ggPSBnbG9iYWwuRGlzcGF0Y2g7XG52YXIgY291bnRlciA9IDA7XG52YXIgcXVldWUgPSB7fTtcbnZhciBPTlJFQURZU1RBVEVDSEFOR0UgPSAnb25yZWFkeXN0YXRlY2hhbmdlJztcbnZhciBkZWZlciwgY2hhbm5lbCwgcG9ydDtcbnZhciBydW4gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpZCA9ICt0aGlzO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gIGlmIChxdWV1ZS5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcbiAgICB2YXIgZm4gPSBxdWV1ZVtpZF07XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgICBmbigpO1xuICB9XG59O1xudmFyIGxpc3RlbmVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIHJ1bi5jYWxsKGV2ZW50LmRhdGEpO1xufTtcbi8vIE5vZGUuanMgMC45KyAmIElFMTArIGhhcyBzZXRJbW1lZGlhdGUsIG90aGVyd2lzZTpcbmlmICghc2V0VGFzayB8fCAhY2xlYXJUYXNrKSB7XG4gIHNldFRhc2sgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pIHtcbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIHZhciBpID0gMTtcbiAgICB3aGlsZSAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgcXVldWVbKytjb3VudGVyXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgaW52b2tlKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbiksIGFyZ3MpO1xuICAgIH07XG4gICAgZGVmZXIoY291bnRlcik7XG4gICAgcmV0dXJuIGNvdW50ZXI7XG4gIH07XG4gIGNsZWFyVGFzayA9IGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGlkKSB7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmIChyZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2VzcycpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjdHgocnVuLCBpZCwgMSkpO1xuICAgIH07XG4gIC8vIFNwaGVyZSAoSlMgZ2FtZSBlbmdpbmUpIERpc3BhdGNoIEFQSVxuICB9IGVsc2UgaWYgKERpc3BhdGNoICYmIERpc3BhdGNoLm5vdykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBEaXNwYXRjaC5ub3coY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBCcm93c2VycyB3aXRoIE1lc3NhZ2VDaGFubmVsLCBpbmNsdWRlcyBXZWJXb3JrZXJzXG4gIH0gZWxzZSBpZiAoTWVzc2FnZUNoYW5uZWwpIHtcbiAgICBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgcG9ydCA9IGNoYW5uZWwucG9ydDI7XG4gICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaXN0ZW5lcjtcbiAgICBkZWZlciA9IGN0eChwb3J0LnBvc3RNZXNzYWdlLCBwb3J0LCAxKTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBwb3N0TWVzc2FnZSwgc2tpcCBXZWJXb3JrZXJzXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIgJiYgdHlwZW9mIHBvc3RNZXNzYWdlID09ICdmdW5jdGlvbicgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShpZCArICcnLCAnKicpO1xuICAgIH07XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lciwgZmFsc2UpO1xuICAvLyBJRTgtXG4gIH0gZWxzZSBpZiAoT05SRUFEWVNUQVRFQ0hBTkdFIGluIGNlbCgnc2NyaXB0JykpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjZWwoJ3NjcmlwdCcpKVtPTlJFQURZU1RBVEVDSEFOR0VdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICBydW4uY2FsbChpZCk7XG4gICAgICB9O1xuICAgIH07XG4gIC8vIFJlc3Qgb2xkIGJyb3dzZXJzXG4gIH0gZWxzZSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIHNldFRpbWVvdXQoY3R4KHJ1biwgaWQsIDEpLCAwKTtcbiAgICB9O1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBzZXRUYXNrLFxuICBjbGVhcjogY2xlYXJUYXNrXG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBtYXggPSBNYXRoLm1heDtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGluZGV4LCBsZW5ndGgpIHtcbiAgaW5kZXggPSB0b0ludGVnZXIoaW5kZXgpO1xuICByZXR1cm4gaW5kZXggPCAwID8gbWF4KGluZGV4ICsgbGVuZ3RoLCAwKSA6IG1pbihpbmRleCwgbGVuZ3RoKTtcbn07XG4iLCIvLyA3LjEuNCBUb0ludGVnZXJcbnZhciBjZWlsID0gTWF0aC5jZWlsO1xudmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpc05hTihpdCA9ICtpdCkgPyAwIDogKGl0ID4gMCA/IGZsb29yIDogY2VpbCkoaXQpO1xufTtcbiIsIi8vIHRvIGluZGV4ZWQgb2JqZWN0LCB0b09iamVjdCB3aXRoIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgc3RyaW5nc1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBJT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG4iLCIvLyA3LjEuMTUgVG9MZW5ndGhcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgbWluID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgPiAwID8gbWluKHRvSW50ZWdlcihpdCksIDB4MWZmZmZmZmZmZmZmZmYpIDogMDsgLy8gcG93KDIsIDUzKSAtIDEgPT0gOTAwNzE5OTI1NDc0MDk5MVxufTtcbiIsIi8vIDcuMS4xMyBUb09iamVjdChhcmd1bWVudClcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIE9iamVjdChkZWZpbmVkKGl0KSk7XG59O1xuIiwiLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXG4vLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIFMpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHJldHVybiBpdDtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmIChTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgaWYgKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59O1xuIiwidmFyIGlkID0gMDtcbnZhciBweCA9IE1hdGgucmFuZG9tKCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuICdTeW1ib2woJy5jb25jYXQoa2V5ID09PSB1bmRlZmluZWQgPyAnJyA6IGtleSwgJylfJywgKCsraWQgKyBweCkudG9TdHJpbmcoMzYpKTtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgbmF2aWdhdG9yID0gZ2xvYmFsLm5hdmlnYXRvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBuYXZpZ2F0b3IgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCAnJztcbiIsInZhciBzdG9yZSA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCd3a3MnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5TeW1ib2w7XG52YXIgVVNFX1NZTUJPTCA9IHR5cGVvZiBTeW1ib2wgPT0gJ2Z1bmN0aW9uJztcblxudmFyICRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gc3RvcmVbbmFtZV0gfHwgKHN0b3JlW25hbWVdID1cbiAgICBVU0VfU1lNQk9MICYmIFN5bWJvbFtuYW1lXSB8fCAoVVNFX1NZTUJPTCA/IFN5bWJvbCA6IHVpZCkoJ1N5bWJvbC4nICsgbmFtZSkpO1xufTtcblxuJGV4cG9ydHMuc3RvcmUgPSBzdG9yZTtcbiIsInZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvcmUnKS5nZXRJdGVyYXRvck1ldGhvZCA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoaXQgIT0gdW5kZWZpbmVkKSByZXR1cm4gaXRbSVRFUkFUT1JdXG4gICAgfHwgaXRbJ0BAaXRlcmF0b3InXVxuICAgIHx8IEl0ZXJhdG9yc1tjbGFzc29mKGl0KV07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjIuMS4zLjggQXJyYXkucHJvdG90eXBlLmZpbmQocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZmluZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg1KTtcbnZhciBLRVkgPSAnZmluZCc7XG52YXIgZm9yY2VkID0gdHJ1ZTtcbi8vIFNob3VsZG4ndCBza2lwIGhvbGVzXG5pZiAoS0VZIGluIFtdKSBBcnJheSgxKVtLRVldKGZ1bmN0aW9uICgpIHsgZm9yY2VkID0gZmFsc2U7IH0pO1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmb3JjZWQsICdBcnJheScsIHtcbiAgZmluZDogZnVuY3Rpb24gZmluZChjYWxsYmFja2ZuIC8qICwgdGhhdCA9IHVuZGVmaW5lZCAqLykge1xuICAgIHJldHVybiAkZmluZCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoS0VZKTtcbiIsIi8vIDIyLjEuMi4yIC8gMTUuNC4zLjIgQXJyYXkuaXNBcnJheShhcmcpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0FycmF5JywgeyBpc0FycmF5OiByZXF1aXJlKCcuL19pcy1hcnJheScpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKTtcbnZhciBzdGVwID0gcmVxdWlyZSgnLi9faXRlci1zdGVwJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xuXG4vLyAyMi4xLjMuNCBBcnJheS5wcm90b3R5cGUuZW50cmllcygpXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmtleXMoKVxuLy8gMjIuMS4zLjI5IEFycmF5LnByb3RvdHlwZS52YWx1ZXMoKVxuLy8gMjIuMS4zLjMwIEFycmF5LnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIga2luZCA9IHRoaXMuX2s7XG4gIHZhciBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYgKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKSB7XG4gICAgdGhpcy5fdCA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gc3RlcCgxKTtcbiAgfVxuICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGluZGV4KTtcbiAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHNvbWUgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5zb21lLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMjMgLyAxNS40LjQuMTcgQXJyYXkucHJvdG90eXBlLnNvbWUoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgc29tZTogZnVuY3Rpb24gc29tZShjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgIHJldHVybiAkc29tZSh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIi8vIDE5LjIuMy4yIC8gMTUuMy40LjUgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQodGhpc0FyZywgYXJncy4uLilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnRnVuY3Rpb24nLCB7IGJpbmQ6IHJlcXVpcmUoJy4vX2JpbmQnKSB9KTtcbiIsIi8vIDE5LjEuMy4xIE9iamVjdC5hc3NpZ24odGFyZ2V0LCBzb3VyY2UpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiwgJ09iamVjdCcsIHsgYXNzaWduOiByZXF1aXJlKCcuL19vYmplY3QtYXNzaWduJykgfSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIHRlc3QgPSB7fTtcbnRlc3RbcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyldID0gJ3onO1xuaWYgKHRlc3QgKyAnJyAhPSAnW29iamVjdCB6XScpIHtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShPYmplY3QucHJvdG90eXBlLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gJ1tvYmplY3QgJyArIGNsYXNzb2YodGhpcykgKyAnXSc7XG4gIH0sIHRydWUpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcbnZhciBwZXJmb3JtID0gcmVxdWlyZSgnLi9fcGVyZm9ybScpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4vX3Byb21pc2UtcmVzb2x2ZScpO1xudmFyIFBST01JU0UgPSAnUHJvbWlzZSc7XG52YXIgVHlwZUVycm9yID0gZ2xvYmFsLlR5cGVFcnJvcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgdmVyc2lvbnMgPSBwcm9jZXNzICYmIHByb2Nlc3MudmVyc2lvbnM7XG52YXIgdjggPSB2ZXJzaW9ucyAmJiB2ZXJzaW9ucy52OCB8fCAnJztcbnZhciAkUHJvbWlzZSA9IGdsb2JhbFtQUk9NSVNFXTtcbnZhciBpc05vZGUgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJztcbnZhciBlbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBJbnRlcm5hbCwgbmV3R2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBPd25Qcm9taXNlQ2FwYWJpbGl0eSwgV3JhcHBlcjtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmY7XG5cbnZhciBVU0VfTkFUSVZFID0gISFmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgLy8gY29ycmVjdCBzdWJjbGFzc2luZyB3aXRoIEBAc3BlY2llcyBzdXBwb3J0XG4gICAgdmFyIHByb21pc2UgPSAkUHJvbWlzZS5yZXNvbHZlKDEpO1xuICAgIHZhciBGYWtlUHJvbWlzZSA9IChwcm9taXNlLmNvbnN0cnVjdG9yID0ge30pW3JlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyldID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgICAgIGV4ZWMoZW1wdHksIGVtcHR5KTtcbiAgICB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpXG4gICAgICAmJiBwcm9taXNlLnRoZW4oZW1wdHkpIGluc3RhbmNlb2YgRmFrZVByb21pc2VcbiAgICAgIC8vIHY4IDYuNiAoTm9kZSAxMCBhbmQgQ2hyb21lIDY2KSBoYXZlIGEgYnVnIHdpdGggcmVzb2x2aW5nIGN1c3RvbSB0aGVuYWJsZXNcbiAgICAgIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTgzMDU2NVxuICAgICAgLy8gd2UgY2FuJ3QgZGV0ZWN0IGl0IHN5bmNocm9ub3VzbHksIHNvIGp1c3QgY2hlY2sgdmVyc2lvbnNcbiAgICAgICYmIHY4LmluZGV4T2YoJzYuNicpICE9PSAwXG4gICAgICAmJiB1c2VyQWdlbnQuaW5kZXhPZignQ2hyb21lLzY2JykgPT09IC0xO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn0oKTtcblxuLy8gaGVscGVyc1xudmFyIGlzVGhlbmFibGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIHRoZW47XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcbn07XG52YXIgbm90aWZ5ID0gZnVuY3Rpb24gKHByb21pc2UsIGlzUmVqZWN0KSB7XG4gIGlmIChwcm9taXNlLl9uKSByZXR1cm47XG4gIHByb21pc2UuX24gPSB0cnVlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9jO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIG9rID0gcHJvbWlzZS5fcyA9PSAxO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24gKHJlYWN0aW9uKSB7XG4gICAgICB2YXIgaGFuZGxlciA9IG9rID8gcmVhY3Rpb24ub2sgOiByZWFjdGlvbi5mYWlsO1xuICAgICAgdmFyIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlO1xuICAgICAgdmFyIHJlamVjdCA9IHJlYWN0aW9uLnJlamVjdDtcbiAgICAgIHZhciBkb21haW4gPSByZWFjdGlvbi5kb21haW47XG4gICAgICB2YXIgcmVzdWx0LCB0aGVuLCBleGl0ZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgIGlmIChwcm9taXNlLl9oID09IDIpIG9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xuICAgICAgICAgICAgcHJvbWlzZS5faCA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChoYW5kbGVyID09PSB0cnVlKSByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkb21haW4pIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7IC8vIG1heSB0aHJvd1xuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICBleGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKSB7XG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGRvbWFpbiAmJiAhZXhpdGVkKSBkb21haW4uZXhpdCgpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aGlsZSAoY2hhaW4ubGVuZ3RoID4gaSkgcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYgKGlzUmVqZWN0ICYmICFwcm9taXNlLl9oKSBvblVuaGFuZGxlZChwcm9taXNlKTtcbiAgfSk7XG59O1xudmFyIG9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgdGFzay5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIHVuaGFuZGxlZCA9IGlzVW5oYW5kbGVkKHByb21pc2UpO1xuICAgIHZhciByZXN1bHQsIGhhbmRsZXIsIGNvbnNvbGU7XG4gICAgaWYgKHVuaGFuZGxlZCkge1xuICAgICAgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChpc05vZGUpIHtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYW5kbGVyID0gZ2xvYmFsLm9udW5oYW5kbGVkcmVqZWN0aW9uKSB7XG4gICAgICAgICAgaGFuZGxlcih7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKGNvbnNvbGUgPSBnbG9iYWwuY29uc29sZSkgJiYgY29uc29sZS5lcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZiAodW5oYW5kbGVkICYmIHJlc3VsdC5lKSB0aHJvdyByZXN1bHQudjtcbiAgfSk7XG59O1xudmFyIGlzVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgcmV0dXJuIHByb21pc2UuX2ggIT09IDEgJiYgKHByb21pc2UuX2EgfHwgcHJvbWlzZS5fYykubGVuZ3RoID09PSAwO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFuZGxlcjtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYgKGhhbmRsZXIgPSBnbG9iYWwub25yZWplY3Rpb25oYW5kbGVkKSB7XG4gICAgICBoYW5kbGVyKHsgcHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92IH0pO1xuICAgIH1cbiAgfSk7XG59O1xudmFyICRyZWplY3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fcyA9IDI7XG4gIGlmICghcHJvbWlzZS5fYSkgcHJvbWlzZS5fYSA9IHByb21pc2UuX2Muc2xpY2UoKTtcbiAgbm90aWZ5KHByb21pc2UsIHRydWUpO1xufTtcbnZhciAkcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIHZhciB0aGVuO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB0aHJvdyBUeXBlRXJyb3IoXCJQcm9taXNlIGNhbid0IGJlIHJlc29sdmVkIGl0c2VsZlwiKTtcbiAgICBpZiAodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKSB7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgd3JhcHBlciA9IHsgX3c6IHByb21pc2UsIF9kOiBmYWxzZSB9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgJHJlamVjdC5jYWxsKHdyYXBwZXIsIGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZS5fdiA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fcyA9IDE7XG4gICAgICBub3RpZnkocHJvbWlzZSwgZmFsc2UpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgICRyZWplY3QuY2FsbCh7IF93OiBwcm9taXNlLCBfZDogZmFsc2UgfSwgZSk7IC8vIHdyYXBcbiAgfVxufTtcblxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcbmlmICghVVNFX05BVElWRSkge1xuICAvLyAyNS40LjMuMSBQcm9taXNlKGV4ZWN1dG9yKVxuICAkUHJvbWlzZSA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRQcm9taXNlLCBQUk9NSVNFLCAnX2gnKTtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGN0eCgkcmVzb2x2ZSwgdGhpcywgMSksIGN0eCgkcmVqZWN0LCB0aGlzLCAxKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAkcmVqZWN0LmNhbGwodGhpcywgZXJyKTtcbiAgICB9XG4gIH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBJbnRlcm5hbCA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgIHZhciByZWFjdGlvbiA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkUHJvbWlzZSkpO1xuICAgICAgcmVhY3Rpb24ub2sgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgPSB0eXBlb2Ygb25SZWplY3RlZCA9PSAnZnVuY3Rpb24nICYmIG9uUmVqZWN0ZWQ7XG4gICAgICByZWFjdGlvbi5kb21haW4gPSBpc05vZGUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX2MucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAodGhpcy5fYSkgdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmICh0aGlzLl9zKSBub3RpZnkodGhpcywgZmFsc2UpO1xuICAgICAgcmV0dXJuIHJlYWN0aW9uLnByb21pc2U7XG4gICAgfSxcbiAgICAvLyAyNS40LjUuMSBQcm9taXNlLnByb3RvdHlwZS5jYXRjaChvblJlamVjdGVkKVxuICAgICdjYXRjaCc6IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy50aGVuKHVuZGVmaW5lZCwgb25SZWplY3RlZCk7XG4gICAgfVxuICB9KTtcbiAgT3duUHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgSW50ZXJuYWwoKTtcbiAgICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xuICAgIHRoaXMucmVzb2x2ZSA9IGN0eCgkcmVzb2x2ZSwgcHJvbWlzZSwgMSk7XG4gICAgdGhpcy5yZWplY3QgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG4gIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmYgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uIChDKSB7XG4gICAgcmV0dXJuIEMgPT09ICRQcm9taXNlIHx8IEMgPT09IFdyYXBwZXJcbiAgICAgID8gbmV3IE93blByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICA6IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgfTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgeyBQcm9taXNlOiAkUHJvbWlzZSB9KTtcbnJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJykoJFByb21pc2UsIFBST01JU0UpO1xucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShQUk9NSVNFKTtcbldyYXBwZXIgPSByZXF1aXJlKCcuL19jb3JlJylbUFJPTUlTRV07XG5cbi8vIHN0YXRpY3NcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjUgUHJvbWlzZS5yZWplY3QocilcbiAgcmVqZWN0OiBmdW5jdGlvbiByZWplY3Qocikge1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcyk7XG4gICAgdmFyICQkcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgJCRyZWplY3Qocik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChMSUJSQVJZIHx8ICFVU0VfTkFUSVZFKSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNiBQcm9taXNlLnJlc29sdmUoeClcbiAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKExJQlJBUlkgJiYgdGhpcyA9PT0gV3JhcHBlciA/ICRQcm9taXNlIDogdGhpcywgeCk7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKFVTRV9OQVRJVkUgJiYgcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikge1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICAgIHZhciBDID0gdGhpcztcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpO1xuICAgIHZhciByZXNvbHZlID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgIHZhciByZWplY3QgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgdmFyIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgIHZhciAkaW5kZXggPSBpbmRleCsrO1xuICAgICAgICB2YXIgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKGFscmVhZHlDYWxsZWQpIHJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuZSkgcmVqZWN0KHJlc3VsdC52KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICBDLnJlc29sdmUocHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmUpIHJlamVjdChyZXN1bHQudik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24gKGl0ZXJhdGVkKSB7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIgaW5kZXggPSB0aGlzLl9pO1xuICB2YXIgcG9pbnQ7XG4gIGlmIChpbmRleCA+PSBPLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4geyB2YWx1ZTogcG9pbnQsIGRvbmU6IGZhbHNlIH07XG59KTtcbiIsInZhciAkaXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciBJVEVSQVRPUiA9IHdrcygnaXRlcmF0b3InKTtcbnZhciBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xudmFyIEFycmF5VmFsdWVzID0gSXRlcmF0b3JzLkFycmF5O1xuXG52YXIgRE9NSXRlcmFibGVzID0ge1xuICBDU1NSdWxlTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIENTU1N0eWxlRGVjbGFyYXRpb246IGZhbHNlLFxuICBDU1NWYWx1ZUxpc3Q6IGZhbHNlLFxuICBDbGllbnRSZWN0TGlzdDogZmFsc2UsXG4gIERPTVJlY3RMaXN0OiBmYWxzZSxcbiAgRE9NU3RyaW5nTGlzdDogZmFsc2UsXG4gIERPTVRva2VuTGlzdDogdHJ1ZSxcbiAgRGF0YVRyYW5zZmVySXRlbUxpc3Q6IGZhbHNlLFxuICBGaWxlTGlzdDogZmFsc2UsXG4gIEhUTUxBbGxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTENvbGxlY3Rpb246IGZhbHNlLFxuICBIVE1MRm9ybUVsZW1lbnQ6IGZhbHNlLFxuICBIVE1MU2VsZWN0RWxlbWVudDogZmFsc2UsXG4gIE1lZGlhTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIE1pbWVUeXBlQXJyYXk6IGZhbHNlLFxuICBOYW1lZE5vZGVNYXA6IGZhbHNlLFxuICBOb2RlTGlzdDogdHJ1ZSxcbiAgUGFpbnRSZXF1ZXN0TGlzdDogZmFsc2UsXG4gIFBsdWdpbjogZmFsc2UsXG4gIFBsdWdpbkFycmF5OiBmYWxzZSxcbiAgU1ZHTGVuZ3RoTGlzdDogZmFsc2UsXG4gIFNWR051bWJlckxpc3Q6IGZhbHNlLFxuICBTVkdQYXRoU2VnTGlzdDogZmFsc2UsXG4gIFNWR1BvaW50TGlzdDogZmFsc2UsXG4gIFNWR1N0cmluZ0xpc3Q6IGZhbHNlLFxuICBTVkdUcmFuc2Zvcm1MaXN0OiBmYWxzZSxcbiAgU291cmNlQnVmZmVyTGlzdDogZmFsc2UsXG4gIFN0eWxlU2hlZXRMaXN0OiB0cnVlLCAvLyBUT0RPOiBOb3Qgc3BlYyBjb21wbGlhbnQsIHNob3VsZCBiZSBmYWxzZS5cbiAgVGV4dFRyYWNrQ3VlTGlzdDogZmFsc2UsXG4gIFRleHRUcmFja0xpc3Q6IGZhbHNlLFxuICBUb3VjaExpc3Q6IGZhbHNlXG59O1xuXG5mb3IgKHZhciBjb2xsZWN0aW9ucyA9IGdldEtleXMoRE9NSXRlcmFibGVzKSwgaSA9IDA7IGkgPCBjb2xsZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICB2YXIgTkFNRSA9IGNvbGxlY3Rpb25zW2ldO1xuICB2YXIgZXhwbGljaXQgPSBET01JdGVyYWJsZXNbTkFNRV07XG4gIHZhciBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgcHJvdG8gPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICB2YXIga2V5O1xuICBpZiAocHJvdG8pIHtcbiAgICBpZiAoIXByb3RvW0lURVJBVE9SXSkgaGlkZShwcm90bywgSVRFUkFUT1IsIEFycmF5VmFsdWVzKTtcbiAgICBpZiAoIXByb3RvW1RPX1NUUklOR19UQUddKSBoaWRlKHByb3RvLCBUT19TVFJJTkdfVEFHLCBOQU1FKTtcbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBBcnJheVZhbHVlcztcbiAgICBpZiAoZXhwbGljaXQpIGZvciAoa2V5IGluICRpdGVyYXRvcnMpIGlmICghcHJvdG9ba2V5XSkgcmVkZWZpbmUocHJvdG8sIGtleSwgJGl0ZXJhdG9yc1trZXldLCB0cnVlKTtcbiAgfVxufVxuIiwiOyhmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuXHRpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIpIHtcblx0XHQvLyBDb21tb25KU1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0fVxuXHRlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdHJvb3QuQ3J5cHRvSlMgPSBmYWN0b3J5KCk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuXG5cdC8qKlxuXHQgKiBDcnlwdG9KUyBjb3JlIGNvbXBvbmVudHMuXG5cdCAqL1xuXHR2YXIgQ3J5cHRvSlMgPSBDcnlwdG9KUyB8fCAoZnVuY3Rpb24gKE1hdGgsIHVuZGVmaW5lZCkge1xuXHQgICAgLypcblx0ICAgICAqIExvY2FsIHBvbHlmaWwgb2YgT2JqZWN0LmNyZWF0ZVxuXHQgICAgICovXG5cdCAgICB2YXIgY3JlYXRlID0gT2JqZWN0LmNyZWF0ZSB8fCAoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgIGZ1bmN0aW9uIEYoKSB7fTtcblxuXHQgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG5cdCAgICAgICAgICAgIHZhciBzdWJ0eXBlO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gb2JqO1xuXG5cdCAgICAgICAgICAgIHN1YnR5cGUgPSBuZXcgRigpO1xuXG5cdCAgICAgICAgICAgIEYucHJvdG90eXBlID0gbnVsbDtcblxuXHQgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICB9O1xuXHQgICAgfSgpKVxuXG5cdCAgICAvKipcblx0ICAgICAqIENyeXB0b0pTIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBMaWJyYXJ5IG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfbGliID0gQy5saWIgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gKGZ1bmN0aW9uICgpIHtcblxuXG5cdCAgICAgICAgcmV0dXJuIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG92ZXJyaWRlcyBQcm9wZXJ0aWVzIHRvIGNvcHkgaW50byB0aGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgbmV3IG9iamVjdC5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiAgICAgdmFyIE15VHlwZSA9IENyeXB0b0pTLmxpYi5CYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScsXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICAgICAgbWV0aG9kOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgfVxuXHQgICAgICAgICAgICAgKiAgICAgfSk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBleHRlbmQ6IGZ1bmN0aW9uIChvdmVycmlkZXMpIHtcblx0ICAgICAgICAgICAgICAgIC8vIFNwYXduXG5cdCAgICAgICAgICAgICAgICB2YXIgc3VidHlwZSA9IGNyZWF0ZSh0aGlzKTtcblxuXHQgICAgICAgICAgICAgICAgLy8gQXVnbWVudFxuXHQgICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1YnR5cGUubWl4SW4ob3ZlcnJpZGVzKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXJcblx0ICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgc3VidHlwZS5pbml0ID0gZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdCAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0XG5cdCAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTtcblxuXHQgICAgICAgICAgICAgICAgLy8gUmVmZXJlbmNlIHN1cGVydHlwZVxuXHQgICAgICAgICAgICAgICAgc3VidHlwZS4kc3VwZXIgPSB0aGlzO1xuXG5cdCAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogRXh0ZW5kcyB0aGlzIG9iamVjdCBhbmQgcnVucyB0aGUgaW5pdCBtZXRob2QuXG5cdCAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIG5ldyBvYmplY3QuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBpbnN0YW5jZSA9IE15VHlwZS5jcmVhdGUoKTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlID0gdGhpcy5leHRlbmQoKTtcblx0ICAgICAgICAgICAgICAgIGluc3RhbmNlLmluaXQuYXBwbHkoaW5zdGFuY2UsIGFyZ3VtZW50cyk7XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTtcblx0ICAgICAgICAgICAgfSxcblxuXHQgICAgICAgICAgICAvKipcblx0ICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG9iamVjdC5cblx0ICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHtcblx0ICAgICAgICAgICAgICogICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLlxuXHQgICAgICAgICAgICAgKiAgICAgICAgIH1cblx0ICAgICAgICAgICAgICogICAgIH0pO1xuXHQgICAgICAgICAgICAgKi9cblx0ICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB9LFxuXG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBUaGUgcHJvcGVydGllcyB0byBtaXggaW4uXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oe1xuXHQgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnXG5cdCAgICAgICAgICAgICAqICAgICB9KTtcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIG1peEluOiBmdW5jdGlvbiAocHJvcGVydGllcykge1xuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcGVydHlOYW1lIGluIHByb3BlcnRpZXMpIHtcblx0ICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIElFIHdvbid0IGNvcHkgdG9TdHJpbmcgdXNpbmcgdGhlIGxvb3AgYWJvdmVcblx0ICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KCd0b1N0cmluZycpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0sXG5cblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIENyZWF0ZXMgYSBjb3B5IG9mIHRoaXMgb2JqZWN0LlxuXHQgICAgICAgICAgICAgKlxuXHQgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgICAgICpcblx0ICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IGluc3RhbmNlLmNsb25lKCk7XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblx0ICAgIH0oKSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuXG5cdCAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgKi9cblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyAoT3B0aW9uYWwpIEFuIGFycmF5IG9mIDMyLWJpdCB3b3Jkcy5cblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7XG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10pO1xuXHQgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddLCA2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBpbml0OiBmdW5jdGlvbiAod29yZHMsIHNpZ0J5dGVzKSB7XG5cdCAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdO1xuXG5cdCAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQpIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSBzaWdCeXRlcztcblx0ICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgPSB3b3Jkcy5sZW5ndGggKiA0O1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIHRoaXMgd29yZCBhcnJheSB0byBhIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXhcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZ2lmaWVkIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJztcblx0ICAgICAgICAgKiAgICAgdmFyIHN0cmluZyA9IHdvcmRBcnJheS50b1N0cmluZygpO1xuXHQgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gd29yZEFycmF5LnRvU3RyaW5nKENyeXB0b0pTLmVuYy5VdGY4KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICB0b1N0cmluZzogZnVuY3Rpb24gKGVuY29kZXIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25jYXRlbmF0ZXMgYSB3b3JkIGFycmF5IHRvIHRoaXMgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbmNhdDogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGF0V29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciB0aGlzU2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXHQgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzXG5cdCAgICAgICAgICAgIHRoaXMuY2xhbXAoKTtcblxuXHQgICAgICAgICAgICAvLyBDb25jYXRcblx0ICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHtcblx0ICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lXG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIHRoYXRCeXRlID0gKHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gKDI0IC0gKGkgJSA0KSAqIDgpKSAmIDB4ZmY7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzWyh0aGlzU2lnQnl0ZXMgKyBpKSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgKDI0IC0gKCh0aGlzU2lnQnl0ZXMgKyBpKSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBDb3B5IG9uZSB3b3JkIGF0IGEgdGltZVxuXHQgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGF0U2lnQnl0ZXM7IGkgKz0gNCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXNXb3Jkc1sodGhpc1NpZ0J5dGVzICsgaSkgPj4+IDJdID0gdGhhdFdvcmRzW2kgPj4+IDJdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHRoaXMuc2lnQnl0ZXMgKz0gdGhhdFNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENoYWluYWJsZVxuXHQgICAgICAgICAgICByZXR1cm4gdGhpcztcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVtb3ZlcyBpbnNpZ25pZmljYW50IGJpdHMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsYW1wOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzO1xuXHQgICAgICAgICAgICB2YXIgc2lnQnl0ZXMgPSB0aGlzLnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENsYW1wXG5cdCAgICAgICAgICAgIHdvcmRzW3NpZ0J5dGVzID4+PiAyXSAmPSAweGZmZmZmZmZmIDw8ICgzMiAtIChzaWdCeXRlcyAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gd29yZEFycmF5LmNsb25lKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgdmFyIGNsb25lID0gQmFzZS5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgd29yZCBhcnJheSBmaWxsZWQgd2l0aCByYW5kb20gYnl0ZXMuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbkJ5dGVzIFRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcmFuZG9tOiBmdW5jdGlvbiAobkJ5dGVzKSB7XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXG5cdCAgICAgICAgICAgIHZhciByID0gKGZ1bmN0aW9uIChtX3cpIHtcblx0ICAgICAgICAgICAgICAgIHZhciBtX3cgPSBtX3c7XG5cdCAgICAgICAgICAgICAgICB2YXIgbV96ID0gMHgzYWRlNjhiMTtcblx0ICAgICAgICAgICAgICAgIHZhciBtYXNrID0gMHhmZmZmZmZmZjtcblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICBtX3ogPSAoMHg5MDY5ICogKG1feiAmIDB4RkZGRikgKyAobV96ID4+IDB4MTApKSAmIG1hc2s7XG5cdCAgICAgICAgICAgICAgICAgICAgbV93ID0gKDB4NDY1MCAqIChtX3cgJiAweEZGRkYpICsgKG1fdyA+PiAweDEwKSkgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSAoKG1feiA8PCAweDEwKSArIG1fdykgJiBtYXNrO1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc3VsdCAvPSAweDEwMDAwMDAwMDtcblx0ICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gMC41O1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgKiAoTWF0aC5yYW5kb20oKSA+IC41ID8gMSA6IC0xKTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIHJjYWNoZTsgaSA8IG5CeXRlczsgaSArPSA0KSB7XG5cdCAgICAgICAgICAgICAgICB2YXIgX3IgPSByKChyY2FjaGUgfHwgTWF0aC5yYW5kb20oKSkgKiAweDEwMDAwMDAwMCk7XG5cblx0ICAgICAgICAgICAgICAgIHJjYWNoZSA9IF9yKCkgKiAweDNhZGU2N2I3O1xuXHQgICAgICAgICAgICAgICAgd29yZHMucHVzaCgoX3IoKSAqIDB4MTAwMDAwMDAwKSB8IDApO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS5cblx0ICAgICAqL1xuXHQgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBIZXggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBIZXggPSBDX2VuYy5IZXggPSB7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkod29yZEFycmF5KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRzXG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IHdvcmRBcnJheS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzO1xuXG5cdCAgICAgICAgICAgIC8vIENvbnZlcnRcblx0ICAgICAgICAgICAgdmFyIGhleENoYXJzID0gW107XG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgdmFyIGJpdGUgPSAod29yZHNbaSA+Pj4gMl0gPj4+ICgyNCAtIChpICUgNCkgKiA4KSkgJiAweGZmO1xuXHQgICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTtcblx0ICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhleENoYXJzLmpvaW4oJycpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGhleFN0ciBUaGUgaGV4IHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAc3RhdGljXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGhleFN0cmluZyk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIGhleFN0ckxlbmd0aCA9IGhleFN0ci5sZW5ndGg7XG5cblx0ICAgICAgICAgICAgLy8gQ29udmVydFxuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTtcblx0ICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikge1xuXHQgICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8ICgyNCAtIChpICUgOCkgKiA0KTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQod29yZHMsIGhleFN0ckxlbmd0aCAvIDIpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogTGF0aW4xIGVuY29kaW5nIHN0cmF0ZWd5LlxuXHQgICAgICovXG5cdCAgICB2YXIgTGF0aW4xID0gQ19lbmMuTGF0aW4xID0ge1xuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgTGF0aW4xIHN0cmluZy5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGxhdGluMVN0cmluZyA9IENyeXB0b0pTLmVuYy5MYXRpbjEuc3RyaW5naWZ5KHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7XG5cdCAgICAgICAgICAgIC8vIFNob3J0Y3V0c1xuXHQgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7XG5cdCAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlcztcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpKyspIHtcblx0ICAgICAgICAgICAgICAgIHZhciBiaXRlID0gKHdvcmRzW2kgPj4+IDJdID4+PiAoMjQgLSAoaSAlIDQpICogOCkpICYgMHhmZjtcblx0ICAgICAgICAgICAgICAgIGxhdGluMUNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShiaXRlKSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbGF0aW4xQ2hhcnMuam9pbignJyk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIENvbnZlcnRzIGEgTGF0aW4xIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gbGF0aW4xU3RyIFRoZSBMYXRpbjEgc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBwYXJzZTogZnVuY3Rpb24gKGxhdGluMVN0cikge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dFxuXHQgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDtcblxuXHQgICAgICAgICAgICAvLyBDb252ZXJ0XG5cdCAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxhdGluMVN0ckxlbmd0aDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSAobGF0aW4xU3RyLmNoYXJDb2RlQXQoaSkgJiAweGZmKSA8PCAoMjQgLSAoaSAlIDQpICogOCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuXG5cdCAgICAgKi9cblx0ICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBVVEYtOCBzdHJpbmcuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHN0YXRpY1xuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKHdvcmRBcnJheSkge1xuXHQgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUoTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpKSk7XG5cdCAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmOFN0ciBUaGUgVVRGLTggc3RyaW5nLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5VdGY4LnBhcnNlKHV0ZjhTdHJpbmcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikge1xuXHQgICAgICAgICAgICByZXR1cm4gTGF0aW4xLnBhcnNlKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudCh1dGY4U3RyKSkpO1xuXHQgICAgICAgIH1cblx0ICAgIH07XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgYnVmZmVyZWQgYmxvY2sgYWxnb3JpdGhtIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIFRoZSBwcm9wZXJ0eSBibG9ja1NpemUgbXVzdCBiZSBpbXBsZW1lbnRlZCBpbiBhIGNvbmNyZXRlIHN1YnR5cGUuXG5cdCAgICAgKlxuXHQgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9taW5CdWZmZXJTaXplIFRoZSBudW1iZXIgb2YgYmxvY2tzIHRoYXQgc2hvdWxkIGJlIGtlcHQgdW5wcm9jZXNzZWQgaW4gdGhlIGJ1ZmZlci4gRGVmYXVsdDogMFxuXHQgICAgICovXG5cdCAgICB2YXIgQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IENfbGliLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBCYXNlLmV4dGVuZCh7XG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogUmVzZXRzIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgZGF0YSBidWZmZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQoKTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICByZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlc1xuXHQgICAgICAgICAgICB0aGlzLl9kYXRhID0gbmV3IFdvcmRBcnJheS5pbml0KCk7XG5cdCAgICAgICAgICAgIHRoaXMuX25EYXRhQnl0ZXMgPSAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBZGRzIG5ldyBkYXRhIHRvIHRoaXMgYmxvY2sgYWxnb3JpdGhtJ3MgYnVmZmVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGFwcGVuZC4gU3RyaW5ncyBhcmUgY29udmVydGVkIHRvIGEgV29yZEFycmF5IHVzaW5nIFVURi04LlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9hcHBlbmQoJ2RhdGEnKTtcblx0ICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2FwcGVuZDogZnVuY3Rpb24gKGRhdGEpIHtcblx0ICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeVxuXHQgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHtcblx0ICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gQXBwZW5kXG5cdCAgICAgICAgICAgIHRoaXMuX2RhdGEuY29uY2F0KGRhdGEpO1xuXHQgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzICs9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFByb2Nlc3NlcyBhdmFpbGFibGUgZGF0YSBibG9ja3MuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBUaGlzIG1ldGhvZCBpbnZva2VzIF9kb1Byb2Nlc3NCbG9jayhvZmZzZXQpLCB3aGljaCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGEgY29uY3JldGUgc3VidHlwZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBwcm9jZXNzZWQgZGF0YS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7XG5cdCAgICAgICAgICogICAgIHZhciBwcm9jZXNzZWREYXRhID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fcHJvY2VzcyghISdmbHVzaCcpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3Jkcztcblx0ICAgICAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7XG5cdCAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSB0aGlzLmJsb2NrU2l6ZTtcblx0ICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBibG9ja3MgcmVhZHlcblx0ICAgICAgICAgICAgdmFyIG5CbG9ja3NSZWFkeSA9IGRhdGFTaWdCeXRlcyAvIGJsb2NrU2l6ZUJ5dGVzO1xuXHQgICAgICAgICAgICBpZiAoZG9GbHVzaCkge1xuXHQgICAgICAgICAgICAgICAgLy8gUm91bmQgdXAgdG8gaW5jbHVkZSBwYXJ0aWFsIGJsb2Nrc1xuXHQgICAgICAgICAgICAgICAgbkJsb2Nrc1JlYWR5ID0gTWF0aC5jZWlsKG5CbG9ja3NSZWFkeSk7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAvLyBSb3VuZCBkb3duIHRvIGluY2x1ZGUgb25seSBmdWxsIGJsb2Nrcyxcblx0ICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgYnVmZmVyXG5cdCAgICAgICAgICAgICAgICBuQmxvY2tzUmVhZHkgPSBNYXRoLm1heCgobkJsb2Nrc1JlYWR5IHwgMCkgLSB0aGlzLl9taW5CdWZmZXJTaXplLCAwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIENvdW50IHdvcmRzIHJlYWR5XG5cdCAgICAgICAgICAgIHZhciBuV29yZHNSZWFkeSA9IG5CbG9ja3NSZWFkeSAqIGJsb2NrU2l6ZTtcblxuXHQgICAgICAgICAgICAvLyBDb3VudCBieXRlcyByZWFkeVxuXHQgICAgICAgICAgICB2YXIgbkJ5dGVzUmVhZHkgPSBNYXRoLm1pbihuV29yZHNSZWFkeSAqIDQsIGRhdGFTaWdCeXRlcyk7XG5cblx0ICAgICAgICAgICAgLy8gUHJvY2VzcyBibG9ja3Ncblx0ICAgICAgICAgICAgaWYgKG5Xb3Jkc1JlYWR5KSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKHZhciBvZmZzZXQgPSAwOyBvZmZzZXQgPCBuV29yZHNSZWFkeTsgb2Zmc2V0ICs9IGJsb2NrU2l6ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtYWxnb3JpdGhtIGxvZ2ljXG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5fZG9Qcm9jZXNzQmxvY2soZGF0YVdvcmRzLCBvZmZzZXQpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgICAgICB2YXIgcHJvY2Vzc2VkV29yZHMgPSBkYXRhV29yZHMuc3BsaWNlKDAsIG5Xb3Jkc1JlYWR5KTtcblx0ICAgICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gbkJ5dGVzUmVhZHk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBSZXR1cm4gcHJvY2Vzc2VkIHdvcmRzXG5cdCAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQocHJvY2Vzc2VkV29yZHMsIG5CeXRlc1JlYWR5KTtcblx0ICAgICAgICB9LFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBjbG9uZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIGNsb25lID0gYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5jbG9uZSgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTtcblx0ICAgICAgICAgICAgY2xvbmUuX2RhdGEgPSB0aGlzLl9kYXRhLmNsb25lKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGNsb25lO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfbWluQnVmZmVyU2l6ZTogMFxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQWJzdHJhY3QgaGFzaGVyIHRlbXBsYXRlLlxuXHQgICAgICpcblx0ICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBoYXNoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDE2ICg1MTIgYml0cylcblx0ICAgICAqL1xuXHQgICAgdmFyIEhhc2hlciA9IENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHtcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaGVyID0gQ3J5cHRvSlMuYWxnby5TSEEyNTYuY3JlYXRlKCk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykge1xuXHQgICAgICAgICAgICAvLyBBcHBseSBjb25maWcgZGVmYXVsdHNcblx0ICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTtcblxuXHQgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXNcblx0ICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBSZXNldHMgdGhpcyBoYXNoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAZXhhbXBsZVxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIC8vIFJlc2V0IGRhdGEgYnVmZmVyXG5cdCAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTtcblxuXHQgICAgICAgICAgICAvLyBQZXJmb3JtIGNvbmNyZXRlLWhhc2hlciBsb2dpY1xuXHQgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIFVwZGF0ZXMgdGhpcyBoYXNoZXIgd2l0aCBhIG1lc3NhZ2UuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7SGFzaGVyfSBUaGlzIGhhc2hlci5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICBoYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBBcHBlbmRcblx0ICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXG5cdCAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgaGFzaFxuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gQ2hhaW5hYmxlXG5cdCAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIGhhc2ggY29tcHV0YXRpb24uXG5cdCAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQGV4YW1wbGVcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpO1xuXHQgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSh3b3JkQXJyYXkpO1xuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAvLyBGaW5hbCBtZXNzYWdlIHVwZGF0ZVxuXHQgICAgICAgICAgICBpZiAobWVzc2FnZVVwZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgdGhpcy5fYXBwZW5kKG1lc3NhZ2VVcGRhdGUpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWNcblx0ICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIGhhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGJsb2NrU2l6ZTogNTEyLzMyLFxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIGEgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBwYXJhbSB7SGFzaGVyfSBoYXNoZXIgVGhlIGhhc2hlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7XG5cdCAgICAgICAgICovXG5cdCAgICAgICAgX2NyZWF0ZUhlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGNmZykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBoYXNoZXIuaW5pdChjZmcpLmZpbmFsaXplKG1lc3NhZ2UpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLlxuXHQgICAgICAgICAqXG5cdCAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi5cblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBzdGF0aWNcblx0ICAgICAgICAgKlxuXHQgICAgICAgICAqIEBleGFtcGxlXG5cdCAgICAgICAgICpcblx0ICAgICAgICAgKiAgICAgdmFyIEhtYWNTSEEyNTYgPSBDcnlwdG9KUy5saWIuSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKENyeXB0b0pTLmFsZ28uU0hBMjU2KTtcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBfY3JlYXRlSG1hY0hlbHBlcjogZnVuY3Rpb24gKGhhc2hlcikge1xuXHQgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTtcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cdCAgICB9KTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBBbGdvcml0aG0gbmFtZXNwYWNlLlxuXHQgICAgICovXG5cdCAgICB2YXIgQ19hbGdvID0gQy5hbGdvID0ge307XG5cblx0ICAgIHJldHVybiBDO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUztcblxufSkpOyIsIjsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSBcIm9iamVjdFwiKSB7XG5cdFx0Ly8gQ29tbW9uSlNcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoXCIuL2NvcmVcIikpO1xuXHR9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gQU1EXG5cdFx0ZGVmaW5lKFtcIi4vY29yZVwiXSwgZmFjdG9yeSk7XG5cdH1cblx0ZWxzZSB7XG5cdFx0Ly8gR2xvYmFsIChicm93c2VyKVxuXHRcdGZhY3Rvcnkocm9vdC5DcnlwdG9KUyk7XG5cdH1cbn0odGhpcywgZnVuY3Rpb24gKENyeXB0b0pTKSB7XG5cblx0KGZ1bmN0aW9uIChNYXRoKSB7XG5cdCAgICAvLyBTaG9ydGN1dHNcblx0ICAgIHZhciBDID0gQ3J5cHRvSlM7XG5cdCAgICB2YXIgQ19saWIgPSBDLmxpYjtcblx0ICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7XG5cdCAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyO1xuXHQgICAgdmFyIENfYWxnbyA9IEMuYWxnbztcblxuXHQgICAgLy8gSW5pdGlhbGl6YXRpb24gYW5kIHJvdW5kIGNvbnN0YW50cyB0YWJsZXNcblx0ICAgIHZhciBIID0gW107XG5cdCAgICB2YXIgSyA9IFtdO1xuXG5cdCAgICAvLyBDb21wdXRlIGNvbnN0YW50c1xuXHQgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICBmdW5jdGlvbiBpc1ByaW1lKG4pIHtcblx0ICAgICAgICAgICAgdmFyIHNxcnROID0gTWF0aC5zcXJ0KG4pO1xuXHQgICAgICAgICAgICBmb3IgKHZhciBmYWN0b3IgPSAyOyBmYWN0b3IgPD0gc3FydE47IGZhY3RvcisrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoIShuICUgZmFjdG9yKSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGZ1bmN0aW9uIGdldEZyYWN0aW9uYWxCaXRzKG4pIHtcblx0ICAgICAgICAgICAgcmV0dXJuICgobiAtIChuIHwgMCkpICogMHgxMDAwMDAwMDApIHwgMDtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB2YXIgbiA9IDI7XG5cdCAgICAgICAgdmFyIG5QcmltZSA9IDA7XG5cdCAgICAgICAgd2hpbGUgKG5QcmltZSA8IDY0KSB7XG5cdCAgICAgICAgICAgIGlmIChpc1ByaW1lKG4pKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoblByaW1lIDwgOCkge1xuXHQgICAgICAgICAgICAgICAgICAgIEhbblByaW1lXSA9IGdldEZyYWN0aW9uYWxCaXRzKE1hdGgucG93KG4sIDEgLyAyKSk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICBLW25QcmltZV0gPSBnZXRGcmFjdGlvbmFsQml0cyhNYXRoLnBvdyhuLCAxIC8gMykpO1xuXG5cdCAgICAgICAgICAgICAgICBuUHJpbWUrKztcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIG4rKztcblx0ICAgICAgICB9XG5cdCAgICB9KCkpO1xuXG5cdCAgICAvLyBSZXVzYWJsZSBvYmplY3Rcblx0ICAgIHZhciBXID0gW107XG5cblx0ICAgIC8qKlxuXHQgICAgICogU0hBLTI1NiBoYXNoIGFsZ29yaXRobS5cblx0ICAgICAqL1xuXHQgICAgdmFyIFNIQTI1NiA9IENfYWxnby5TSEEyNTYgPSBIYXNoZXIuZXh0ZW5kKHtcblx0ICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICB0aGlzLl9oYXNoID0gbmV3IFdvcmRBcnJheS5pbml0KEguc2xpY2UoMCkpO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHtcblx0ICAgICAgICAgICAgLy8gU2hvcnRjdXRcblx0ICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzO1xuXG5cdCAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzXG5cdCAgICAgICAgICAgIHZhciBhID0gSFswXTtcblx0ICAgICAgICAgICAgdmFyIGIgPSBIWzFdO1xuXHQgICAgICAgICAgICB2YXIgYyA9IEhbMl07XG5cdCAgICAgICAgICAgIHZhciBkID0gSFszXTtcblx0ICAgICAgICAgICAgdmFyIGUgPSBIWzRdO1xuXHQgICAgICAgICAgICB2YXIgZiA9IEhbNV07XG5cdCAgICAgICAgICAgIHZhciBnID0gSFs2XTtcblx0ICAgICAgICAgICAgdmFyIGggPSBIWzddO1xuXG5cdCAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uXG5cdCAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNjQ7IGkrKykge1xuXHQgICAgICAgICAgICAgICAgaWYgKGkgPCAxNikge1xuXHQgICAgICAgICAgICAgICAgICAgIFdbaV0gPSBNW29mZnNldCArIGldIHwgMDtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHggPSBXW2kgLSAxNV07XG5cdCAgICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMCAgPSAoKGdhbW1hMHggPDwgMjUpIHwgKGdhbW1hMHggPj4+IDcpKSAgXlxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChnYW1tYTB4IDw8IDE0KSB8IChnYW1tYTB4ID4+PiAxOCkpIF5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZ2FtbWEweCA+Pj4gMyk7XG5cblx0ICAgICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExeCA9IFdbaSAtIDJdO1xuXHQgICAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTEgID0gKChnYW1tYTF4IDw8IDE1KSB8IChnYW1tYTF4ID4+PiAxNykpIF5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoZ2FtbWExeCA8PCAxMykgfCAoZ2FtbWExeCA+Pj4gMTkpKSBeXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGdhbW1hMXggPj4+IDEwKTtcblxuXHQgICAgICAgICAgICAgICAgICAgIFdbaV0gPSBnYW1tYTAgKyBXW2kgLSA3XSArIGdhbW1hMSArIFdbaSAtIDE2XTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgdmFyIGNoICA9IChlICYgZikgXiAofmUgJiBnKTtcblx0ICAgICAgICAgICAgICAgIHZhciBtYWogPSAoYSAmIGIpIF4gKGEgJiBjKSBeIChiICYgYyk7XG5cblx0ICAgICAgICAgICAgICAgIHZhciBzaWdtYTAgPSAoKGEgPDwgMzApIHwgKGEgPj4+IDIpKSBeICgoYSA8PCAxOSkgfCAoYSA+Pj4gMTMpKSBeICgoYSA8PCAxMCkgfCAoYSA+Pj4gMjIpKTtcblx0ICAgICAgICAgICAgICAgIHZhciBzaWdtYTEgPSAoKGUgPDwgMjYpIHwgKGUgPj4+IDYpKSBeICgoZSA8PCAyMSkgfCAoZSA+Pj4gMTEpKSBeICgoZSA8PCA3KSAgfCAoZSA+Pj4gMjUpKTtcblxuXHQgICAgICAgICAgICAgICAgdmFyIHQxID0gaCArIHNpZ21hMSArIGNoICsgS1tpXSArIFdbaV07XG5cdCAgICAgICAgICAgICAgICB2YXIgdDIgPSBzaWdtYTAgKyBtYWo7XG5cblx0ICAgICAgICAgICAgICAgIGggPSBnO1xuXHQgICAgICAgICAgICAgICAgZyA9IGY7XG5cdCAgICAgICAgICAgICAgICBmID0gZTtcblx0ICAgICAgICAgICAgICAgIGUgPSAoZCArIHQxKSB8IDA7XG5cdCAgICAgICAgICAgICAgICBkID0gYztcblx0ICAgICAgICAgICAgICAgIGMgPSBiO1xuXHQgICAgICAgICAgICAgICAgYiA9IGE7XG5cdCAgICAgICAgICAgICAgICBhID0gKHQxICsgdDIpIHwgMDtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIEludGVybWVkaWF0ZSBoYXNoIHZhbHVlXG5cdCAgICAgICAgICAgIEhbMF0gPSAoSFswXSArIGEpIHwgMDtcblx0ICAgICAgICAgICAgSFsxXSA9IChIWzFdICsgYikgfCAwO1xuXHQgICAgICAgICAgICBIWzJdID0gKEhbMl0gKyBjKSB8IDA7XG5cdCAgICAgICAgICAgIEhbM10gPSAoSFszXSArIGQpIHwgMDtcblx0ICAgICAgICAgICAgSFs0XSA9IChIWzRdICsgZSkgfCAwO1xuXHQgICAgICAgICAgICBIWzVdID0gKEhbNV0gKyBmKSB8IDA7XG5cdCAgICAgICAgICAgIEhbNl0gPSAoSFs2XSArIGcpIHwgMDtcblx0ICAgICAgICAgICAgSFs3XSA9IChIWzddICsgaCkgfCAwO1xuXHQgICAgICAgIH0sXG5cblx0ICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAvLyBTaG9ydGN1dHNcblx0ICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuXHQgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkcztcblxuXHQgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4O1xuXHQgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7XG5cblx0ICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmdcblx0ICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBuQml0c0xlZnQgJSAzMik7XG5cdCAgICAgICAgICAgIGRhdGFXb3Jkc1soKChuQml0c0xlZnQgKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gTWF0aC5mbG9vcihuQml0c1RvdGFsIC8gMHgxMDAwMDAwMDApO1xuXHQgICAgICAgICAgICBkYXRhV29yZHNbKCgobkJpdHNMZWZ0ICsgNjQpID4+PiA5KSA8PCA0KSArIDE1XSA9IG5CaXRzVG90YWw7XG5cdCAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgPSBkYXRhV29yZHMubGVuZ3RoICogNDtcblxuXHQgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2Nrc1xuXHQgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7XG5cblx0ICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2hcblx0ICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hhc2g7XG5cdCAgICAgICAgfSxcblxuXHQgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgIHZhciBjbG9uZSA9IEhhc2hlci5jbG9uZS5jYWxsKHRoaXMpO1xuXHQgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTtcblxuXHQgICAgICAgICAgICByZXR1cm4gY2xvbmU7XG5cdCAgICAgICAgfVxuXHQgICAgfSk7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuXG5cdCAgICAgKlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC5cblx0ICAgICAqXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEEyNTYoJ21lc3NhZ2UnKTtcblx0ICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTI1Nih3b3JkQXJyYXkpO1xuXHQgICAgICovXG5cdCAgICBDLlNIQTI1NiA9IEhhc2hlci5fY3JlYXRlSGVscGVyKFNIQTI1Nik7XG5cblx0ICAgIC8qKlxuXHQgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLlxuXHQgICAgICpcblx0ICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLlxuXHQgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuXG5cdCAgICAgKlxuXHQgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy5cblx0ICAgICAqXG5cdCAgICAgKiBAc3RhdGljXG5cdCAgICAgKlxuXHQgICAgICogQGV4YW1wbGVcblx0ICAgICAqXG5cdCAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMjU2KG1lc3NhZ2UsIGtleSk7XG5cdCAgICAgKi9cblx0ICAgIEMuSG1hY1NIQTI1NiA9IEhhc2hlci5fY3JlYXRlSG1hY0hlbHBlcihTSEEyNTYpO1xuXHR9KE1hdGgpKTtcblxuXG5cdHJldHVybiBDcnlwdG9KUy5TSEEyNTY7XG5cbn0pKTsiLCIoZnVuY3Rpb24oKXtcblxuICAgIC8vIENvcHlyaWdodCAoYykgMjAwNSAgVG9tIFd1XG4gICAgLy8gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAgICAvLyBTZWUgXCJMSUNFTlNFXCIgZm9yIGRldGFpbHMuXG5cbiAgICAvLyBCYXNpYyBKYXZhU2NyaXB0IEJOIGxpYnJhcnkgLSBzdWJzZXQgdXNlZnVsIGZvciBSU0EgZW5jcnlwdGlvbi5cblxuICAgIC8vIEJpdHMgcGVyIGRpZ2l0XG4gICAgdmFyIGRiaXRzO1xuXG4gICAgLy8gSmF2YVNjcmlwdCBlbmdpbmUgYW5hbHlzaXNcbiAgICB2YXIgY2FuYXJ5ID0gMHhkZWFkYmVlZmNhZmU7XG4gICAgdmFyIGpfbG0gPSAoKGNhbmFyeSYweGZmZmZmZik9PTB4ZWZjYWZlKTtcblxuICAgIC8vIChwdWJsaWMpIENvbnN0cnVjdG9yXG4gICAgZnVuY3Rpb24gQmlnSW50ZWdlcihhLGIsYykge1xuICAgICAgaWYoYSAhPSBudWxsKVxuICAgICAgICBpZihcIm51bWJlclwiID09IHR5cGVvZiBhKSB0aGlzLmZyb21OdW1iZXIoYSxiLGMpO1xuICAgICAgICBlbHNlIGlmKGIgPT0gbnVsbCAmJiBcInN0cmluZ1wiICE9IHR5cGVvZiBhKSB0aGlzLmZyb21TdHJpbmcoYSwyNTYpO1xuICAgICAgICBlbHNlIHRoaXMuZnJvbVN0cmluZyhhLGIpO1xuICAgIH1cblxuICAgIC8vIHJldHVybiBuZXcsIHVuc2V0IEJpZ0ludGVnZXJcbiAgICBmdW5jdGlvbiBuYmkoKSB7IHJldHVybiBuZXcgQmlnSW50ZWdlcihudWxsKTsgfVxuXG4gICAgLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLFxuICAgIC8vIGMgaXMgaW5pdGlhbCBjYXJyeSwgcmV0dXJucyBmaW5hbCBjYXJyeS5cbiAgICAvLyBjIDwgMypkdmFsdWUsIHggPCAyKmR2YWx1ZSwgdGhpc19pIDwgZHZhbHVlXG4gICAgLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC5cblxuICAgIC8vIGFtMTogdXNlIGEgc2luZ2xlIG11bHQgYW5kIGRpdmlkZSB0byBnZXQgdGhlIGhpZ2ggYml0cyxcbiAgICAvLyBtYXggZGlnaXQgYml0cyBzaG91bGQgYmUgMjYgYmVjYXVzZVxuICAgIC8vIG1heCBpbnRlcm5hbCB2YWx1ZSA9IDIqZHZhbHVlXjItMipkdmFsdWUgKDwgMl41MylcbiAgICBmdW5jdGlvbiBhbTEoaSx4LHcsaixjLG4pIHtcbiAgICAgIHdoaWxlKC0tbiA+PSAwKSB7XG4gICAgICAgIHZhciB2ID0geCp0aGlzW2krK10rd1tqXStjO1xuICAgICAgICBjID0gTWF0aC5mbG9vcih2LzB4NDAwMDAwMCk7XG4gICAgICAgIHdbaisrXSA9IHYmMHgzZmZmZmZmO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICAgIC8vIGFtMiBhdm9pZHMgYSBiaWcgbXVsdC1hbmQtZXh0cmFjdCBjb21wbGV0ZWx5LlxuICAgIC8vIE1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSA8PSAzMCBiZWNhdXNlIHdlIGRvIGJpdHdpc2Ugb3BzXG4gICAgLy8gb24gdmFsdWVzIHVwIHRvIDIqaGR2YWx1ZV4yLWhkdmFsdWUtMSAoPCAyXjMxKVxuICAgIGZ1bmN0aW9uIGFtMihpLHgsdyxqLGMsbikge1xuICAgICAgdmFyIHhsID0geCYweDdmZmYsIHhoID0geD4+MTU7XG4gICAgICB3aGlsZSgtLW4gPj0gMCkge1xuICAgICAgICB2YXIgbCA9IHRoaXNbaV0mMHg3ZmZmO1xuICAgICAgICB2YXIgaCA9IHRoaXNbaSsrXT4+MTU7XG4gICAgICAgIHZhciBtID0geGgqbCtoKnhsO1xuICAgICAgICBsID0geGwqbCsoKG0mMHg3ZmZmKTw8MTUpK3dbal0rKGMmMHgzZmZmZmZmZik7XG4gICAgICAgIGMgPSAobD4+PjMwKSsobT4+PjE1KSt4aCpoKyhjPj4+MzApO1xuICAgICAgICB3W2orK10gPSBsJjB4M2ZmZmZmZmY7XG4gICAgICB9XG4gICAgICByZXR1cm4gYztcbiAgICB9XG4gICAgLy8gQWx0ZXJuYXRlbHksIHNldCBtYXggZGlnaXQgYml0cyB0byAyOCBzaW5jZSBzb21lXG4gICAgLy8gYnJvd3NlcnMgc2xvdyBkb3duIHdoZW4gZGVhbGluZyB3aXRoIDMyLWJpdCBudW1iZXJzLlxuICAgIGZ1bmN0aW9uIGFtMyhpLHgsdyxqLGMsbikge1xuICAgICAgdmFyIHhsID0geCYweDNmZmYsIHhoID0geD4+MTQ7XG4gICAgICB3aGlsZSgtLW4gPj0gMCkge1xuICAgICAgICB2YXIgbCA9IHRoaXNbaV0mMHgzZmZmO1xuICAgICAgICB2YXIgaCA9IHRoaXNbaSsrXT4+MTQ7XG4gICAgICAgIHZhciBtID0geGgqbCtoKnhsO1xuICAgICAgICBsID0geGwqbCsoKG0mMHgzZmZmKTw8MTQpK3dbal0rYztcbiAgICAgICAgYyA9IChsPj4yOCkrKG0+PjE0KSt4aCpoO1xuICAgICAgICB3W2orK10gPSBsJjB4ZmZmZmZmZjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjO1xuICAgIH1cbiAgICB2YXIgaW5Ccm93c2VyID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gXCJ1bmRlZmluZWRcIjtcbiAgICBpZihpbkJyb3dzZXIgJiYgal9sbSAmJiAobmF2aWdhdG9yLmFwcE5hbWUgPT0gXCJNaWNyb3NvZnQgSW50ZXJuZXQgRXhwbG9yZXJcIikpIHtcbiAgICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0yO1xuICAgICAgZGJpdHMgPSAzMDtcbiAgICB9XG4gICAgZWxzZSBpZihpbkJyb3dzZXIgJiYgal9sbSAmJiAobmF2aWdhdG9yLmFwcE5hbWUgIT0gXCJOZXRzY2FwZVwiKSkge1xuICAgICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTE7XG4gICAgICBkYml0cyA9IDI2O1xuICAgIH1cbiAgICBlbHNlIHsgLy8gTW96aWxsYS9OZXRzY2FwZSBzZWVtcyB0byBwcmVmZXIgYW0zXG4gICAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMztcbiAgICAgIGRiaXRzID0gMjg7XG4gICAgfVxuXG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuREIgPSBkYml0cztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMTw8ZGJpdHMpLTEpO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLkRWID0gKDE8PGRiaXRzKTtcblxuICAgIHZhciBCSV9GUCA9IDUyO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLkZWID0gTWF0aC5wb3coMixCSV9GUCk7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuRjEgPSBCSV9GUC1kYml0cztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5GMiA9IDIqZGJpdHMtQklfRlA7XG5cbiAgICAvLyBEaWdpdCBjb252ZXJzaW9uc1xuICAgIHZhciBCSV9STSA9IFwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCI7XG4gICAgdmFyIEJJX1JDID0gbmV3IEFycmF5KCk7XG4gICAgdmFyIHJyLHZ2O1xuICAgIHJyID0gXCIwXCIuY2hhckNvZGVBdCgwKTtcbiAgICBmb3IodnYgPSAwOyB2diA8PSA5OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2O1xuICAgIHJyID0gXCJhXCIuY2hhckNvZGVBdCgwKTtcbiAgICBmb3IodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbiAgICByciA9IFwiQVwiLmNoYXJDb2RlQXQoMCk7XG4gICAgZm9yKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5cbiAgICBmdW5jdGlvbiBpbnQyY2hhcihuKSB7IHJldHVybiBCSV9STS5jaGFyQXQobik7IH1cbiAgICBmdW5jdGlvbiBpbnRBdChzLGkpIHtcbiAgICAgIHZhciBjID0gQklfUkNbcy5jaGFyQ29kZUF0KGkpXTtcbiAgICAgIHJldHVybiAoYz09bnVsbCk/LTE6YztcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gclxuICAgIGZ1bmN0aW9uIGJucENvcHlUbyhyKSB7XG4gICAgICBmb3IodmFyIGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSB0aGlzW2ldO1xuICAgICAgci50ID0gdGhpcy50O1xuICAgICAgci5zID0gdGhpcy5zO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVlxuICAgIGZ1bmN0aW9uIGJucEZyb21JbnQoeCkge1xuICAgICAgdGhpcy50ID0gMTtcbiAgICAgIHRoaXMucyA9ICh4PDApPy0xOjA7XG4gICAgICBpZih4ID4gMCkgdGhpc1swXSA9IHg7XG4gICAgICBlbHNlIGlmKHggPCAtMSkgdGhpc1swXSA9IHgrdGhpcy5EVjtcbiAgICAgIGVsc2UgdGhpcy50ID0gMDtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gYmlnaW50IGluaXRpYWxpemVkIHRvIHZhbHVlXG4gICAgZnVuY3Rpb24gbmJ2KGkpIHsgdmFyIHIgPSBuYmkoKTsgci5mcm9tSW50KGkpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gc3RyaW5nIGFuZCByYWRpeFxuICAgIGZ1bmN0aW9uIGJucEZyb21TdHJpbmcocyxiKSB7XG4gICAgICB2YXIgaztcbiAgICAgIGlmKGIgPT0gMTYpIGsgPSA0O1xuICAgICAgZWxzZSBpZihiID09IDgpIGsgPSAzO1xuICAgICAgZWxzZSBpZihiID09IDI1NikgayA9IDg7IC8vIGJ5dGUgYXJyYXlcbiAgICAgIGVsc2UgaWYoYiA9PSAyKSBrID0gMTtcbiAgICAgIGVsc2UgaWYoYiA9PSAzMikgayA9IDU7XG4gICAgICBlbHNlIGlmKGIgPT0gNCkgayA9IDI7XG4gICAgICBlbHNlIHsgdGhpcy5mcm9tUmFkaXgocyxiKTsgcmV0dXJuOyB9XG4gICAgICB0aGlzLnQgPSAwO1xuICAgICAgdGhpcy5zID0gMDtcbiAgICAgIHZhciBpID0gcy5sZW5ndGgsIG1pID0gZmFsc2UsIHNoID0gMDtcbiAgICAgIHdoaWxlKC0taSA+PSAwKSB7XG4gICAgICAgIHZhciB4ID0gKGs9PTgpP3NbaV0mMHhmZjppbnRBdChzLGkpO1xuICAgICAgICBpZih4IDwgMCkge1xuICAgICAgICAgIGlmKHMuY2hhckF0KGkpID09IFwiLVwiKSBtaSA9IHRydWU7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgbWkgPSBmYWxzZTtcbiAgICAgICAgaWYoc2ggPT0gMClcbiAgICAgICAgICB0aGlzW3RoaXMudCsrXSA9IHg7XG4gICAgICAgIGVsc2UgaWYoc2grayA+IHRoaXMuREIpIHtcbiAgICAgICAgICB0aGlzW3RoaXMudC0xXSB8PSAoeCYoKDE8PCh0aGlzLkRCLXNoKSktMSkpPDxzaDtcbiAgICAgICAgICB0aGlzW3RoaXMudCsrXSA9ICh4Pj4odGhpcy5EQi1zaCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0aGlzW3RoaXMudC0xXSB8PSB4PDxzaDtcbiAgICAgICAgc2ggKz0gaztcbiAgICAgICAgaWYoc2ggPj0gdGhpcy5EQikgc2ggLT0gdGhpcy5EQjtcbiAgICAgIH1cbiAgICAgIGlmKGsgPT0gOCAmJiAoc1swXSYweDgwKSAhPSAwKSB7XG4gICAgICAgIHRoaXMucyA9IC0xO1xuICAgICAgICBpZihzaCA+IDApIHRoaXNbdGhpcy50LTFdIHw9ICgoMTw8KHRoaXMuREItc2gpKS0xKTw8c2g7XG4gICAgICB9XG4gICAgICB0aGlzLmNsYW1wKCk7XG4gICAgICBpZihtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzXG4gICAgZnVuY3Rpb24gYm5wQ2xhbXAoKSB7XG4gICAgICB2YXIgYyA9IHRoaXMucyZ0aGlzLkRNO1xuICAgICAgd2hpbGUodGhpcy50ID4gMCAmJiB0aGlzW3RoaXMudC0xXSA9PSBjKSAtLXRoaXMudDtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm4gc3RyaW5nIHJlcHJlc2VudGF0aW9uIGluIGdpdmVuIHJhZGl4XG4gICAgZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7XG4gICAgICBpZih0aGlzLnMgPCAwKSByZXR1cm4gXCItXCIrdGhpcy5uZWdhdGUoKS50b1N0cmluZyhiKTtcbiAgICAgIHZhciBrO1xuICAgICAgaWYoYiA9PSAxNikgayA9IDQ7XG4gICAgICBlbHNlIGlmKGIgPT0gOCkgayA9IDM7XG4gICAgICBlbHNlIGlmKGIgPT0gMikgayA9IDE7XG4gICAgICBlbHNlIGlmKGIgPT0gMzIpIGsgPSA1O1xuICAgICAgZWxzZSBpZihiID09IDQpIGsgPSAyO1xuICAgICAgZWxzZSByZXR1cm4gdGhpcy50b1JhZGl4KGIpO1xuICAgICAgdmFyIGttID0gKDE8PGspLTEsIGQsIG0gPSBmYWxzZSwgciA9IFwiXCIsIGkgPSB0aGlzLnQ7XG4gICAgICB2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklaztcbiAgICAgIGlmKGktLSA+IDApIHtcbiAgICAgICAgaWYocCA8IHRoaXMuREIgJiYgKGQgPSB0aGlzW2ldPj5wKSA+IDApIHsgbSA9IHRydWU7IHIgPSBpbnQyY2hhcihkKTsgfVxuICAgICAgICB3aGlsZShpID49IDApIHtcbiAgICAgICAgICBpZihwIDwgaykge1xuICAgICAgICAgICAgZCA9ICh0aGlzW2ldJigoMTw8cCktMSkpPDwoay1wKTtcbiAgICAgICAgICAgIGQgfD0gdGhpc1stLWldPj4ocCs9dGhpcy5EQi1rKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkID0gKHRoaXNbaV0+PihwLT1rKSkma207XG4gICAgICAgICAgICBpZihwIDw9IDApIHsgcCArPSB0aGlzLkRCOyAtLWk7IH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYoZCA+IDApIG0gPSB0cnVlO1xuICAgICAgICAgIGlmKG0pIHIgKz0gaW50MmNoYXIoZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBtP3I6XCIwXCI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgLXRoaXNcbiAgICBmdW5jdGlvbiBibk5lZ2F0ZSgpIHsgdmFyIHIgPSBuYmkoKTsgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB8dGhpc3xcbiAgICBmdW5jdGlvbiBibkFicygpIHsgcmV0dXJuICh0aGlzLnM8MCk/dGhpcy5uZWdhdGUoKTp0aGlzOyB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm4gKyBpZiB0aGlzID4gYSwgLSBpZiB0aGlzIDwgYSwgMCBpZiBlcXVhbFxuICAgIGZ1bmN0aW9uIGJuQ29tcGFyZVRvKGEpIHtcbiAgICAgIHZhciByID0gdGhpcy5zLWEucztcbiAgICAgIGlmKHIgIT0gMCkgcmV0dXJuIHI7XG4gICAgICB2YXIgaSA9IHRoaXMudDtcbiAgICAgIHIgPSBpLWEudDtcbiAgICAgIGlmKHIgIT0gMCkgcmV0dXJuICh0aGlzLnM8MCk/LXI6cjtcbiAgICAgIHdoaWxlKC0taSA+PSAwKSBpZigocj10aGlzW2ldLWFbaV0pICE9IDApIHJldHVybiByO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJucyBiaXQgbGVuZ3RoIG9mIHRoZSBpbnRlZ2VyIHhcbiAgICBmdW5jdGlvbiBuYml0cyh4KSB7XG4gICAgICB2YXIgciA9IDEsIHQ7XG4gICAgICBpZigodD14Pj4+MTYpICE9IDApIHsgeCA9IHQ7IHIgKz0gMTY7IH1cbiAgICAgIGlmKCh0PXg+PjgpICE9IDApIHsgeCA9IHQ7IHIgKz0gODsgfVxuICAgICAgaWYoKHQ9eD4+NCkgIT0gMCkgeyB4ID0gdDsgciArPSA0OyB9XG4gICAgICBpZigodD14Pj4yKSAhPSAwKSB7IHggPSB0OyByICs9IDI7IH1cbiAgICAgIGlmKCh0PXg+PjEpICE9IDApIHsgeCA9IHQ7IHIgKz0gMTsgfVxuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiBcInRoaXNcIlxuICAgIGZ1bmN0aW9uIGJuQml0TGVuZ3RoKCkge1xuICAgICAgaWYodGhpcy50IDw9IDApIHJldHVybiAwO1xuICAgICAgcmV0dXJuIHRoaXMuREIqKHRoaXMudC0xKStuYml0cyh0aGlzW3RoaXMudC0xXV4odGhpcy5zJnRoaXMuRE0pKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuKkRCXG4gICAgZnVuY3Rpb24gYm5wRExTaGlmdFRvKG4scikge1xuICAgICAgdmFyIGk7XG4gICAgICBmb3IoaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgcltpK25dID0gdGhpc1tpXTtcbiAgICAgIGZvcihpID0gbi0xOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gICAgICByLnQgPSB0aGlzLnQrbjtcbiAgICAgIHIucyA9IHRoaXMucztcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuKkRCXG4gICAgZnVuY3Rpb24gYm5wRFJTaGlmdFRvKG4scikge1xuICAgICAgZm9yKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByW2ktbl0gPSB0aGlzW2ldO1xuICAgICAgci50ID0gTWF0aC5tYXgodGhpcy50LW4sMCk7XG4gICAgICByLnMgPSB0aGlzLnM7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgblxuICAgIGZ1bmN0aW9uIGJucExTaGlmdFRvKG4scikge1xuICAgICAgdmFyIGJzID0gbiV0aGlzLkRCO1xuICAgICAgdmFyIGNicyA9IHRoaXMuREItYnM7XG4gICAgICB2YXIgYm0gPSAoMTw8Y2JzKS0xO1xuICAgICAgdmFyIGRzID0gTWF0aC5mbG9vcihuL3RoaXMuREIpLCBjID0gKHRoaXMuczw8YnMpJnRoaXMuRE0sIGk7XG4gICAgICBmb3IoaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkge1xuICAgICAgICByW2krZHMrMV0gPSAodGhpc1tpXT4+Y2JzKXxjO1xuICAgICAgICBjID0gKHRoaXNbaV0mYm0pPDxicztcbiAgICAgIH1cbiAgICAgIGZvcihpID0gZHMtMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSAwO1xuICAgICAgcltkc10gPSBjO1xuICAgICAgci50ID0gdGhpcy50K2RzKzE7XG4gICAgICByLnMgPSB0aGlzLnM7XG4gICAgICByLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gblxuICAgIGZ1bmN0aW9uIGJucFJTaGlmdFRvKG4scikge1xuICAgICAgci5zID0gdGhpcy5zO1xuICAgICAgdmFyIGRzID0gTWF0aC5mbG9vcihuL3RoaXMuREIpO1xuICAgICAgaWYoZHMgPj0gdGhpcy50KSB7IHIudCA9IDA7IHJldHVybjsgfVxuICAgICAgdmFyIGJzID0gbiV0aGlzLkRCO1xuICAgICAgdmFyIGNicyA9IHRoaXMuREItYnM7XG4gICAgICB2YXIgYm0gPSAoMTw8YnMpLTE7XG4gICAgICByWzBdID0gdGhpc1tkc10+PmJzO1xuICAgICAgZm9yKHZhciBpID0gZHMrMTsgaSA8IHRoaXMudDsgKytpKSB7XG4gICAgICAgIHJbaS1kcy0xXSB8PSAodGhpc1tpXSZibSk8PGNicztcbiAgICAgICAgcltpLWRzXSA9IHRoaXNbaV0+PmJzO1xuICAgICAgfVxuICAgICAgaWYoYnMgPiAwKSByW3RoaXMudC1kcy0xXSB8PSAodGhpcy5zJmJtKTw8Y2JzO1xuICAgICAgci50ID0gdGhpcy50LWRzO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIC0gYVxuICAgIGZ1bmN0aW9uIGJucFN1YlRvKGEscikge1xuICAgICAgdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpO1xuICAgICAgd2hpbGUoaSA8IG0pIHtcbiAgICAgICAgYyArPSB0aGlzW2ldLWFbaV07XG4gICAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgIH1cbiAgICAgIGlmKGEudCA8IHRoaXMudCkge1xuICAgICAgICBjIC09IGEucztcbiAgICAgICAgd2hpbGUoaSA8IHRoaXMudCkge1xuICAgICAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgICAgICByW2krK10gPSBjJnRoaXMuRE07XG4gICAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgICAgfVxuICAgICAgICBjICs9IHRoaXMucztcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjICs9IHRoaXMucztcbiAgICAgICAgd2hpbGUoaSA8IGEudCkge1xuICAgICAgICAgIGMgLT0gYVtpXTtcbiAgICAgICAgICByW2krK10gPSBjJnRoaXMuRE07XG4gICAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgICAgfVxuICAgICAgICBjIC09IGEucztcbiAgICAgIH1cbiAgICAgIHIucyA9IChjPDApPy0xOjA7XG4gICAgICBpZihjIDwgLTEpIHJbaSsrXSA9IHRoaXMuRFYrYztcbiAgICAgIGVsc2UgaWYoYyA+IDApIHJbaSsrXSA9IGM7XG4gICAgICByLnQgPSBpO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICogYSwgciAhPSB0aGlzLGEgKEhBQyAxNC4xMilcbiAgICAvLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG4gICAgZnVuY3Rpb24gYm5wTXVsdGlwbHlUbyhhLHIpIHtcbiAgICAgIHZhciB4ID0gdGhpcy5hYnMoKSwgeSA9IGEuYWJzKCk7XG4gICAgICB2YXIgaSA9IHgudDtcbiAgICAgIHIudCA9IGkreS50O1xuICAgICAgd2hpbGUoLS1pID49IDApIHJbaV0gPSAwO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgeS50OyArK2kpIHJbaSt4LnRdID0geC5hbSgwLHlbaV0scixpLDAseC50KTtcbiAgICAgIHIucyA9IDA7XG4gICAgICByLmNsYW1wKCk7XG4gICAgICBpZih0aGlzLnMgIT0gYS5zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocixyKTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gdGhpc14yLCByICE9IHRoaXMgKEhBQyAxNC4xNilcbiAgICBmdW5jdGlvbiBibnBTcXVhcmVUbyhyKSB7XG4gICAgICB2YXIgeCA9IHRoaXMuYWJzKCk7XG4gICAgICB2YXIgaSA9IHIudCA9IDIqeC50O1xuICAgICAgd2hpbGUoLS1pID49IDApIHJbaV0gPSAwO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgeC50LTE7ICsraSkge1xuICAgICAgICB2YXIgYyA9IHguYW0oaSx4W2ldLHIsMippLDAsMSk7XG4gICAgICAgIGlmKChyW2kreC50XSs9eC5hbShpKzEsMip4W2ldLHIsMippKzEsYyx4LnQtaS0xKSkgPj0geC5EVikge1xuICAgICAgICAgIHJbaSt4LnRdIC09IHguRFY7XG4gICAgICAgICAgcltpK3gudCsxXSA9IDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKHIudCA+IDApIHJbci50LTFdICs9IHguYW0oaSx4W2ldLHIsMippLDAsMSk7XG4gICAgICByLnMgPSAwO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIGRpdmlkZSB0aGlzIGJ5IG0sIHF1b3RpZW50IGFuZCByZW1haW5kZXIgdG8gcSwgciAoSEFDIDE0LjIwKVxuICAgIC8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLlxuICAgIGZ1bmN0aW9uIGJucERpdlJlbVRvKG0scSxyKSB7XG4gICAgICB2YXIgcG0gPSBtLmFicygpO1xuICAgICAgaWYocG0udCA8PSAwKSByZXR1cm47XG4gICAgICB2YXIgcHQgPSB0aGlzLmFicygpO1xuICAgICAgaWYocHQudCA8IHBtLnQpIHtcbiAgICAgICAgaWYocSAhPSBudWxsKSBxLmZyb21JbnQoMCk7XG4gICAgICAgIGlmKHIgIT0gbnVsbCkgdGhpcy5jb3B5VG8ocik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmKHIgPT0gbnVsbCkgciA9IG5iaSgpO1xuICAgICAgdmFyIHkgPSBuYmkoKSwgdHMgPSB0aGlzLnMsIG1zID0gbS5zO1xuICAgICAgdmFyIG5zaCA9IHRoaXMuREItbmJpdHMocG1bcG0udC0xXSk7ICAgLy8gbm9ybWFsaXplIG1vZHVsdXNcbiAgICAgIGlmKG5zaCA+IDApIHsgcG0ubFNoaWZ0VG8obnNoLHkpOyBwdC5sU2hpZnRUbyhuc2gscik7IH1cbiAgICAgIGVsc2UgeyBwbS5jb3B5VG8oeSk7IHB0LmNvcHlUbyhyKTsgfVxuICAgICAgdmFyIHlzID0geS50O1xuICAgICAgdmFyIHkwID0geVt5cy0xXTtcbiAgICAgIGlmKHkwID09IDApIHJldHVybjtcbiAgICAgIHZhciB5dCA9IHkwKigxPDx0aGlzLkYxKSsoKHlzPjEpP3lbeXMtMl0+PnRoaXMuRjI6MCk7XG4gICAgICB2YXIgZDEgPSB0aGlzLkZWL3l0LCBkMiA9ICgxPDx0aGlzLkYxKS95dCwgZSA9IDE8PHRoaXMuRjI7XG4gICAgICB2YXIgaSA9IHIudCwgaiA9IGkteXMsIHQgPSAocT09bnVsbCk/bmJpKCk6cTtcbiAgICAgIHkuZGxTaGlmdFRvKGosdCk7XG4gICAgICBpZihyLmNvbXBhcmVUbyh0KSA+PSAwKSB7XG4gICAgICAgIHJbci50KytdID0gMTtcbiAgICAgICAgci5zdWJUbyh0LHIpO1xuICAgICAgfVxuICAgICAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHlzLHQpO1xuICAgICAgdC5zdWJUbyh5LHkpOyAgLy8gXCJuZWdhdGl2ZVwiIHkgc28gd2UgY2FuIHJlcGxhY2Ugc3ViIHdpdGggYW0gbGF0ZXJcbiAgICAgIHdoaWxlKHkudCA8IHlzKSB5W3kudCsrXSA9IDA7XG4gICAgICB3aGlsZSgtLWogPj0gMCkge1xuICAgICAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdFxuICAgICAgICB2YXIgcWQgPSAoclstLWldPT15MCk/dGhpcy5ETTpNYXRoLmZsb29yKHJbaV0qZDErKHJbaS0xXStlKSpkMik7XG4gICAgICAgIGlmKChyW2ldKz15LmFtKDAscWQscixqLDAseXMpKSA8IHFkKSB7ICAgLy8gVHJ5IGl0IG91dFxuICAgICAgICAgIHkuZGxTaGlmdFRvKGosdCk7XG4gICAgICAgICAgci5zdWJUbyh0LHIpO1xuICAgICAgICAgIHdoaWxlKHJbaV0gPCAtLXFkKSByLnN1YlRvKHQscik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKHEgIT0gbnVsbCkge1xuICAgICAgICByLmRyU2hpZnRUbyh5cyxxKTtcbiAgICAgICAgaWYodHMgIT0gbXMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhxLHEpO1xuICAgICAgfVxuICAgICAgci50ID0geXM7XG4gICAgICByLmNsYW1wKCk7XG4gICAgICBpZihuc2ggPiAwKSByLnJTaGlmdFRvKG5zaCxyKTsgLy8gRGVub3JtYWxpemUgcmVtYWluZGVyXG4gICAgICBpZih0cyA8IDApIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLHIpO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgbW9kIGFcbiAgICBmdW5jdGlvbiBibk1vZChhKSB7XG4gICAgICB2YXIgciA9IG5iaSgpO1xuICAgICAgdGhpcy5hYnMoKS5kaXZSZW1UbyhhLG51bGwscik7XG4gICAgICBpZih0aGlzLnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSBhLnN1YlRvKHIscik7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyBNb2R1bGFyIHJlZHVjdGlvbiB1c2luZyBcImNsYXNzaWNcIiBhbGdvcml0aG1cbiAgICBmdW5jdGlvbiBDbGFzc2ljKG0pIHsgdGhpcy5tID0gbTsgfVxuICAgIGZ1bmN0aW9uIGNDb252ZXJ0KHgpIHtcbiAgICAgIGlmKHgucyA8IDAgfHwgeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSByZXR1cm4geC5tb2QodGhpcy5tKTtcbiAgICAgIGVsc2UgcmV0dXJuIHg7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNSZXZlcnQoeCkgeyByZXR1cm4geDsgfVxuICAgIGZ1bmN0aW9uIGNSZWR1Y2UoeCkgeyB4LmRpdlJlbVRvKHRoaXMubSxudWxsLHgpOyB9XG4gICAgZnVuY3Rpb24gY011bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfVxuICAgIGZ1bmN0aW9uIGNTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH1cblxuICAgIENsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQgPSBjQ29udmVydDtcbiAgICBDbGFzc2ljLnByb3RvdHlwZS5yZXZlcnQgPSBjUmV2ZXJ0O1xuICAgIENsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2U7XG4gICAgQ2xhc3NpYy5wcm90b3R5cGUubXVsVG8gPSBjTXVsVG87XG4gICAgQ2xhc3NpYy5wcm90b3R5cGUuc3FyVG8gPSBjU3FyVG87XG5cbiAgICAvLyAocHJvdGVjdGVkKSByZXR1cm4gXCItMS90aGlzICUgMl5EQlwiOyB1c2VmdWwgZm9yIE1vbnQuIHJlZHVjdGlvblxuICAgIC8vIGp1c3RpZmljYXRpb246XG4gICAgLy8gICAgICAgICB4eSA9PSAxIChtb2QgbSlcbiAgICAvLyAgICAgICAgIHh5ID0gIDEra21cbiAgICAvLyAgIHh5KDIteHkpID0gKDEra20pKDEta20pXG4gICAgLy8geFt5KDIteHkpXSA9IDEta14ybV4yXG4gICAgLy8geFt5KDIteHkpXSA9PSAxIChtb2QgbV4yKVxuICAgIC8vIGlmIHkgaXMgMS94IG1vZCBtLCB0aGVuIHkoMi14eSkgaXMgMS94IG1vZCBtXjJcbiAgICAvLyBzaG91bGQgcmVkdWNlIHggYW5kIHkoMi14eSkgYnkgbV4yIGF0IGVhY2ggc3RlcCB0byBrZWVwIHNpemUgYm91bmRlZC5cbiAgICAvLyBKUyBtdWx0aXBseSBcIm92ZXJmbG93c1wiIGRpZmZlcmVudGx5IGZyb20gQy9DKyssIHNvIGNhcmUgaXMgbmVlZGVkIGhlcmUuXG4gICAgZnVuY3Rpb24gYm5wSW52RGlnaXQoKSB7XG4gICAgICBpZih0aGlzLnQgPCAxKSByZXR1cm4gMDtcbiAgICAgIHZhciB4ID0gdGhpc1swXTtcbiAgICAgIGlmKCh4JjEpID09IDApIHJldHVybiAwO1xuICAgICAgdmFyIHkgPSB4JjM7ICAgICAgIC8vIHkgPT0gMS94IG1vZCAyXjJcbiAgICAgIHkgPSAoeSooMi0oeCYweGYpKnkpKSYweGY7IC8vIHkgPT0gMS94IG1vZCAyXjRcbiAgICAgIHkgPSAoeSooMi0oeCYweGZmKSp5KSkmMHhmZjsgICAvLyB5ID09IDEveCBtb2QgMl44XG4gICAgICB5ID0gKHkqKDItKCgoeCYweGZmZmYpKnkpJjB4ZmZmZikpKSYweGZmZmY7ICAgIC8vIHkgPT0gMS94IG1vZCAyXjE2XG4gICAgICAvLyBsYXN0IHN0ZXAgLSBjYWxjdWxhdGUgaW52ZXJzZSBtb2QgRFYgZGlyZWN0bHk7XG4gICAgICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHNcbiAgICAgIHkgPSAoeSooMi14KnkldGhpcy5EVikpJXRoaXMuRFY7ICAgICAgIC8vIHkgPT0gMS94IG1vZCAyXmRiaXRzXG4gICAgICAvLyB3ZSByZWFsbHkgd2FudCB0aGUgbmVnYXRpdmUgaW52ZXJzZSwgYW5kIC1EViA8IHkgPCBEVlxuICAgICAgcmV0dXJuICh5PjApP3RoaXMuRFYteToteTtcbiAgICB9XG5cbiAgICAvLyBNb250Z29tZXJ5IHJlZHVjdGlvblxuICAgIGZ1bmN0aW9uIE1vbnRnb21lcnkobSkge1xuICAgICAgdGhpcy5tID0gbTtcbiAgICAgIHRoaXMubXAgPSBtLmludkRpZ2l0KCk7XG4gICAgICB0aGlzLm1wbCA9IHRoaXMubXAmMHg3ZmZmO1xuICAgICAgdGhpcy5tcGggPSB0aGlzLm1wPj4xNTtcbiAgICAgIHRoaXMudW0gPSAoMTw8KG0uREItMTUpKS0xO1xuICAgICAgdGhpcy5tdDIgPSAyKm0udDtcbiAgICB9XG5cbiAgICAvLyB4UiBtb2QgbVxuICAgIGZ1bmN0aW9uIG1vbnRDb252ZXJ0KHgpIHtcbiAgICAgIHZhciByID0gbmJpKCk7XG4gICAgICB4LmFicygpLmRsU2hpZnRUbyh0aGlzLm0udCxyKTtcbiAgICAgIHIuZGl2UmVtVG8odGhpcy5tLG51bGwscik7XG4gICAgICBpZih4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ocixyKTtcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIHgvUiBtb2QgbVxuICAgIGZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkge1xuICAgICAgdmFyIHIgPSBuYmkoKTtcbiAgICAgIHguY29weVRvKHIpO1xuICAgICAgdGhpcy5yZWR1Y2Uocik7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyB4ID0geC9SIG1vZCBtIChIQUMgMTQuMzIpXG4gICAgZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7XG4gICAgICB3aGlsZSh4LnQgPD0gdGhpcy5tdDIpIC8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlclxuICAgICAgICB4W3gudCsrXSA9IDA7XG4gICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5tLnQ7ICsraSkge1xuICAgICAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geFtpXSptcCBtb2QgRFZcbiAgICAgICAgdmFyIGogPSB4W2ldJjB4N2ZmZjtcbiAgICAgICAgdmFyIHUwID0gKGoqdGhpcy5tcGwrKCgoaip0aGlzLm1waCsoeFtpXT4+MTUpKnRoaXMubXBsKSZ0aGlzLnVtKTw8MTUpKSZ4LkRNO1xuICAgICAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGxcbiAgICAgICAgaiA9IGkrdGhpcy5tLnQ7XG4gICAgICAgIHhbal0gKz0gdGhpcy5tLmFtKDAsdTAseCxpLDAsdGhpcy5tLnQpO1xuICAgICAgICAvLyBwcm9wYWdhdGUgY2FycnlcbiAgICAgICAgd2hpbGUoeFtqXSA+PSB4LkRWKSB7IHhbal0gLT0geC5EVjsgeFsrK2pdKys7IH1cbiAgICAgIH1cbiAgICAgIHguY2xhbXAoKTtcbiAgICAgIHguZHJTaGlmdFRvKHRoaXMubS50LHgpO1xuICAgICAgaWYoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSx4KTtcbiAgICB9XG5cbiAgICAvLyByID0gXCJ4XjIvUiBtb2QgbVwiOyB4ICE9IHJcbiAgICBmdW5jdGlvbiBtb250U3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbiAgICAvLyByID0gXCJ4eS9SIG1vZCBtXCI7IHgseSAhPSByXG4gICAgZnVuY3Rpb24gbW9udE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfVxuXG4gICAgTW9udGdvbWVyeS5wcm90b3R5cGUuY29udmVydCA9IG1vbnRDb252ZXJ0O1xuICAgIE1vbnRnb21lcnkucHJvdG90eXBlLnJldmVydCA9IG1vbnRSZXZlcnQ7XG4gICAgTW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlID0gbW9udFJlZHVjZTtcbiAgICBNb250Z29tZXJ5LnByb3RvdHlwZS5tdWxUbyA9IG1vbnRNdWxUbztcbiAgICBNb250Z29tZXJ5LnByb3RvdHlwZS5zcXJUbyA9IG1vbnRTcXJUbztcblxuICAgIC8vIChwcm90ZWN0ZWQpIHRydWUgaWZmIHRoaXMgaXMgZXZlblxuICAgIGZ1bmN0aW9uIGJucElzRXZlbigpIHsgcmV0dXJuICgodGhpcy50PjApPyh0aGlzWzBdJjEpOnRoaXMucykgPT0gMDsgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgdGhpc15lLCBlIDwgMl4zMiwgZG9pbmcgc3FyIGFuZCBtdWwgd2l0aCBcInJcIiAoSEFDIDE0Ljc5KVxuICAgIGZ1bmN0aW9uIGJucEV4cChlLHopIHtcbiAgICAgIGlmKGUgPiAweGZmZmZmZmZmIHx8IGUgPCAxKSByZXR1cm4gQmlnSW50ZWdlci5PTkU7XG4gICAgICB2YXIgciA9IG5iaSgpLCByMiA9IG5iaSgpLCBnID0gei5jb252ZXJ0KHRoaXMpLCBpID0gbmJpdHMoZSktMTtcbiAgICAgIGcuY29weVRvKHIpO1xuICAgICAgd2hpbGUoLS1pID49IDApIHtcbiAgICAgICAgei5zcXJUbyhyLHIyKTtcbiAgICAgICAgaWYoKGUmKDE8PGkpKSA+IDApIHoubXVsVG8ocjIsZyxyKTtcbiAgICAgICAgZWxzZSB7IHZhciB0ID0gcjsgciA9IHIyOyByMiA9IHQ7IH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB6LnJldmVydChyKTtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzXmUgJSBtLCAwIDw9IGUgPCAyXjMyXG4gICAgZnVuY3Rpb24gYm5Nb2RQb3dJbnQoZSxtKSB7XG4gICAgICB2YXIgejtcbiAgICAgIGlmKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pOyBlbHNlIHogPSBuZXcgTW9udGdvbWVyeShtKTtcbiAgICAgIHJldHVybiB0aGlzLmV4cChlLHopO1xuICAgIH1cblxuICAgIC8vIHByb3RlY3RlZFxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNvcHlUbyA9IGJucENvcHlUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tSW50ID0gYm5wRnJvbUludDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tU3RyaW5nID0gYm5wRnJvbVN0cmluZztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGFtcCA9IGJucENsYW1wO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRsU2hpZnRUbyA9IGJucERMU2hpZnRUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kclNoaWZ0VG8gPSBibnBEUlNoaWZ0VG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubFNoaWZ0VG8gPSBibnBMU2hpZnRUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5yU2hpZnRUbyA9IGJucFJTaGlmdFRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnN1YlRvID0gYm5wU3ViVG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlUbyA9IGJucE11bHRpcGx5VG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlVG8gPSBibnBTcXVhcmVUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZSZW1UbyA9IGJucERpdlJlbVRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmludkRpZ2l0ID0gYm5wSW52RGlnaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuaXNFdmVuID0gYm5wSXNFdmVuO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmV4cCA9IGJucEV4cDtcblxuICAgIC8vIHB1YmxpY1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnRvU3RyaW5nID0gYm5Ub1N0cmluZztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5uZWdhdGUgPSBibk5lZ2F0ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnMgPSBibkFicztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5jb21wYXJlVG8gPSBibkNvbXBhcmVUbztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRMZW5ndGggPSBibkJpdExlbmd0aDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2QgPSBibk1vZDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RQb3dJbnQgPSBibk1vZFBvd0ludDtcblxuICAgIC8vIFwiY29uc3RhbnRzXCJcbiAgICBCaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7XG4gICAgQmlnSW50ZWdlci5PTkUgPSBuYnYoMSk7XG5cbiAgICAvLyBDb3B5cmlnaHQgKGMpIDIwMDUtMjAwOSAgVG9tIFd1XG4gICAgLy8gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAgICAvLyBTZWUgXCJMSUNFTlNFXCIgZm9yIGRldGFpbHMuXG5cbiAgICAvLyBFeHRlbmRlZCBKYXZhU2NyaXB0IEJOIGZ1bmN0aW9ucywgcmVxdWlyZWQgZm9yIFJTQSBwcml2YXRlIG9wcy5cblxuICAgIC8vIFZlcnNpb24gMS4xOiBuZXcgQmlnSW50ZWdlcihcIjBcIiwgMTApIHJldHVybnMgXCJwcm9wZXJcIiB6ZXJvXG4gICAgLy8gVmVyc2lvbiAxLjI6IHNxdWFyZSgpIEFQSSwgaXNQcm9iYWJsZVByaW1lIGZpeFxuXG4gICAgLy8gKHB1YmxpYylcbiAgICBmdW5jdGlvbiBibkNsb25lKCkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmNvcHlUbyhyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBpbnRlZ2VyXG4gICAgZnVuY3Rpb24gYm5JbnRWYWx1ZSgpIHtcbiAgICAgIGlmKHRoaXMucyA8IDApIHtcbiAgICAgICAgaWYodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdLXRoaXMuRFY7XG4gICAgICAgIGVsc2UgaWYodGhpcy50ID09IDApIHJldHVybiAtMTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdO1xuICAgICAgZWxzZSBpZih0aGlzLnQgPT0gMCkgcmV0dXJuIDA7XG4gICAgICAvLyBhc3N1bWVzIDE2IDwgREIgPCAzMlxuICAgICAgcmV0dXJuICgodGhpc1sxXSYoKDE8PCgzMi10aGlzLkRCKSktMSkpPDx0aGlzLkRCKXx0aGlzWzBdO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBieXRlXG4gICAgZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXNbMF08PDI0KT4+MjQ7IH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBzaG9ydCAoYXNzdW1lcyBEQj49MTYpXG4gICAgZnVuY3Rpb24gYm5TaG9ydFZhbHVlKCkgeyByZXR1cm4gKHRoaXMudD09MCk/dGhpcy5zOih0aGlzWzBdPDwxNik+PjE2OyB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWXG4gICAgZnVuY3Rpb24gYm5wQ2h1bmtTaXplKHIpIHsgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5MTjIqdGhpcy5EQi9NYXRoLmxvZyhyKSk7IH1cblxuICAgIC8vIChwdWJsaWMpIDAgaWYgdGhpcyA9PSAwLCAxIGlmIHRoaXMgPiAwXG4gICAgZnVuY3Rpb24gYm5TaWdOdW0oKSB7XG4gICAgICBpZih0aGlzLnMgPCAwKSByZXR1cm4gLTE7XG4gICAgICBlbHNlIGlmKHRoaXMudCA8PSAwIHx8ICh0aGlzLnQgPT0gMSAmJiB0aGlzWzBdIDw9IDApKSByZXR1cm4gMDtcbiAgICAgIGVsc2UgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmdcbiAgICBmdW5jdGlvbiBibnBUb1JhZGl4KGIpIHtcbiAgICAgIGlmKGIgPT0gbnVsbCkgYiA9IDEwO1xuICAgICAgaWYodGhpcy5zaWdudW0oKSA9PSAwIHx8IGIgPCAyIHx8IGIgPiAzNikgcmV0dXJuIFwiMFwiO1xuICAgICAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gICAgICB2YXIgYSA9IE1hdGgucG93KGIsY3MpO1xuICAgICAgdmFyIGQgPSBuYnYoYSksIHkgPSBuYmkoKSwgeiA9IG5iaSgpLCByID0gXCJcIjtcbiAgICAgIHRoaXMuZGl2UmVtVG8oZCx5LHopO1xuICAgICAgd2hpbGUoeS5zaWdudW0oKSA+IDApIHtcbiAgICAgICAgciA9IChhK3ouaW50VmFsdWUoKSkudG9TdHJpbmcoYikuc3Vic3RyKDEpICsgcjtcbiAgICAgICAgeS5kaXZSZW1UbyhkLHkseik7XG4gICAgICB9XG4gICAgICByZXR1cm4gei5pbnRWYWx1ZSgpLnRvU3RyaW5nKGIpICsgcjtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSBjb252ZXJ0IGZyb20gcmFkaXggc3RyaW5nXG4gICAgZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsYikge1xuICAgICAgdGhpcy5mcm9tSW50KDApO1xuICAgICAgaWYoYiA9PSBudWxsKSBiID0gMTA7XG4gICAgICB2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTtcbiAgICAgIHZhciBkID0gTWF0aC5wb3coYixjcyksIG1pID0gZmFsc2UsIGogPSAwLCB3ID0gMDtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciB4ID0gaW50QXQocyxpKTtcbiAgICAgICAgaWYoeCA8IDApIHtcbiAgICAgICAgICBpZihzLmNoYXJBdChpKSA9PSBcIi1cIiAmJiB0aGlzLnNpZ251bSgpID09IDApIG1pID0gdHJ1ZTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB3ID0gYip3K3g7XG4gICAgICAgIGlmKCsraiA+PSBjcykge1xuICAgICAgICAgIHRoaXMuZE11bHRpcGx5KGQpO1xuICAgICAgICAgIHRoaXMuZEFkZE9mZnNldCh3LDApO1xuICAgICAgICAgIGogPSAwO1xuICAgICAgICAgIHcgPSAwO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZihqID4gMCkge1xuICAgICAgICB0aGlzLmRNdWx0aXBseShNYXRoLnBvdyhiLGopKTtcbiAgICAgICAgdGhpcy5kQWRkT2Zmc2V0KHcsMCk7XG4gICAgICB9XG4gICAgICBpZihtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgYWx0ZXJuYXRlIGNvbnN0cnVjdG9yXG4gICAgZnVuY3Rpb24gYm5wRnJvbU51bWJlcihhLGIsYykge1xuICAgICAgaWYoXCJudW1iZXJcIiA9PSB0eXBlb2YgYikge1xuICAgICAgICAvLyBuZXcgQmlnSW50ZWdlcihpbnQsaW50LFJORylcbiAgICAgICAgaWYoYSA8IDIpIHRoaXMuZnJvbUludCgxKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5mcm9tTnVtYmVyKGEsYyk7XG4gICAgICAgICAgaWYoIXRoaXMudGVzdEJpdChhLTEpKSAgICAvLyBmb3JjZSBNU0Igc2V0XG4gICAgICAgICAgICB0aGlzLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYS0xKSxvcF9vcix0aGlzKTtcbiAgICAgICAgICBpZih0aGlzLmlzRXZlbigpKSB0aGlzLmRBZGRPZmZzZXQoMSwwKTsgLy8gZm9yY2Ugb2RkXG4gICAgICAgICAgd2hpbGUoIXRoaXMuaXNQcm9iYWJsZVByaW1lKGIpKSB7XG4gICAgICAgICAgICB0aGlzLmRBZGRPZmZzZXQoMiwwKTtcbiAgICAgICAgICAgIGlmKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLHRoaXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpXG4gICAgICAgIHZhciB4ID0gbmV3IEFycmF5KCksIHQgPSBhJjc7XG4gICAgICAgIHgubGVuZ3RoID0gKGE+PjMpKzE7XG4gICAgICAgIGIubmV4dEJ5dGVzKHgpO1xuICAgICAgICBpZih0ID4gMCkgeFswXSAmPSAoKDE8PHQpLTEpOyBlbHNlIHhbMF0gPSAwO1xuICAgICAgICB0aGlzLmZyb21TdHJpbmcoeCwyNTYpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIGNvbnZlcnQgdG8gYmlnZW5kaWFuIGJ5dGUgYXJyYXlcbiAgICBmdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkge1xuICAgICAgdmFyIGkgPSB0aGlzLnQsIHIgPSBuZXcgQXJyYXkoKTtcbiAgICAgIHJbMF0gPSB0aGlzLnM7XG4gICAgICB2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklOCwgZCwgayA9IDA7XG4gICAgICBpZihpLS0gPiAwKSB7XG4gICAgICAgIGlmKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXT4+cCkgIT0gKHRoaXMucyZ0aGlzLkRNKT4+cClcbiAgICAgICAgICByW2srK10gPSBkfCh0aGlzLnM8PCh0aGlzLkRCLXApKTtcbiAgICAgICAgd2hpbGUoaSA+PSAwKSB7XG4gICAgICAgICAgaWYocCA8IDgpIHtcbiAgICAgICAgICAgIGQgPSAodGhpc1tpXSYoKDE8PHApLTEpKTw8KDgtcCk7XG4gICAgICAgICAgICBkIHw9IHRoaXNbLS1pXT4+KHArPXRoaXMuREItOCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZCA9ICh0aGlzW2ldPj4ocC09OCkpJjB4ZmY7XG4gICAgICAgICAgICBpZihwIDw9IDApIHsgcCArPSB0aGlzLkRCOyAtLWk7IH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYoKGQmMHg4MCkgIT0gMCkgZCB8PSAtMjU2O1xuICAgICAgICAgIGlmKGsgPT0gMCAmJiAodGhpcy5zJjB4ODApICE9IChkJjB4ODApKSArK2s7XG4gICAgICAgICAgaWYoayA+IDAgfHwgZCAhPSB0aGlzLnMpIHJbaysrXSA9IGQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJuRXF1YWxzKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPT0wKTsgfVxuICAgIGZ1bmN0aW9uIGJuTWluKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPDApP3RoaXM6YTsgfVxuICAgIGZ1bmN0aW9uIGJuTWF4KGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPjApP3RoaXM6YTsgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgb3AgYSAoYml0d2lzZSlcbiAgICBmdW5jdGlvbiBibnBCaXR3aXNlVG8oYSxvcCxyKSB7XG4gICAgICB2YXIgaSwgZiwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3AodGhpc1tpXSxhW2ldKTtcbiAgICAgIGlmKGEudCA8IHRoaXMudCkge1xuICAgICAgICBmID0gYS5zJnRoaXMuRE07XG4gICAgICAgIGZvcihpID0gbTsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gb3AodGhpc1tpXSxmKTtcbiAgICAgICAgci50ID0gdGhpcy50O1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGYgPSB0aGlzLnMmdGhpcy5ETTtcbiAgICAgICAgZm9yKGkgPSBtOyBpIDwgYS50OyArK2kpIHJbaV0gPSBvcChmLGFbaV0pO1xuICAgICAgICByLnQgPSBhLnQ7XG4gICAgICB9XG4gICAgICByLnMgPSBvcCh0aGlzLnMsYS5zKTtcbiAgICAgIHIuY2xhbXAoKTtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICYgYVxuICAgIGZ1bmN0aW9uIG9wX2FuZCh4LHkpIHsgcmV0dXJuIHgmeTsgfVxuICAgIGZ1bmN0aW9uIGJuQW5kKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9hbmQscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIHwgYVxuICAgIGZ1bmN0aW9uIG9wX29yKHgseSkgeyByZXR1cm4geHx5OyB9XG4gICAgZnVuY3Rpb24gYm5PcihhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3Bfb3Iscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIF4gYVxuICAgIGZ1bmN0aW9uIG9wX3hvcih4LHkpIHsgcmV0dXJuIHheeTsgfVxuICAgIGZ1bmN0aW9uIGJuWG9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF94b3Iscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICYgfmFcbiAgICBmdW5jdGlvbiBvcF9hbmRub3QoeCx5KSB7IHJldHVybiB4Jn55OyB9XG4gICAgZnVuY3Rpb24gYm5BbmROb3QoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmJpdHdpc2VUbyhhLG9wX2FuZG5vdCxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIH50aGlzXG4gICAgZnVuY3Rpb24gYm5Ob3QoKSB7XG4gICAgICB2YXIgciA9IG5iaSgpO1xuICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gdGhpcy5ETSZ+dGhpc1tpXTtcbiAgICAgIHIudCA9IHRoaXMudDtcbiAgICAgIHIucyA9IH50aGlzLnM7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIDw8IG5cbiAgICBmdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7XG4gICAgICB2YXIgciA9IG5iaSgpO1xuICAgICAgaWYobiA8IDApIHRoaXMuclNoaWZ0VG8oLW4scik7IGVsc2UgdGhpcy5sU2hpZnRUbyhuLHIpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyA+PiBuXG4gICAgZnVuY3Rpb24gYm5TaGlmdFJpZ2h0KG4pIHtcbiAgICAgIHZhciByID0gbmJpKCk7XG4gICAgICBpZihuIDwgMCkgdGhpcy5sU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLnJTaGlmdFRvKG4scik7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyByZXR1cm4gaW5kZXggb2YgbG93ZXN0IDEtYml0IGluIHgsIHggPCAyXjMxXG4gICAgZnVuY3Rpb24gbGJpdCh4KSB7XG4gICAgICBpZih4ID09IDApIHJldHVybiAtMTtcbiAgICAgIHZhciByID0gMDtcbiAgICAgIGlmKCh4JjB4ZmZmZikgPT0gMCkgeyB4ID4+PSAxNjsgciArPSAxNjsgfVxuICAgICAgaWYoKHgmMHhmZikgPT0gMCkgeyB4ID4+PSA4OyByICs9IDg7IH1cbiAgICAgIGlmKCh4JjB4ZikgPT0gMCkgeyB4ID4+PSA0OyByICs9IDQ7IH1cbiAgICAgIGlmKCh4JjMpID09IDApIHsgeCA+Pj0gMjsgciArPSAyOyB9XG4gICAgICBpZigoeCYxKSA9PSAwKSArK3I7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSByZXR1cm5zIGluZGV4IG9mIGxvd2VzdCAxLWJpdCAob3IgLTEgaWYgbm9uZSlcbiAgICBmdW5jdGlvbiBibkdldExvd2VzdFNldEJpdCgpIHtcbiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSlcbiAgICAgICAgaWYodGhpc1tpXSAhPSAwKSByZXR1cm4gaSp0aGlzLkRCK2xiaXQodGhpc1tpXSk7XG4gICAgICBpZih0aGlzLnMgPCAwKSByZXR1cm4gdGhpcy50KnRoaXMuREI7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuIG51bWJlciBvZiAxIGJpdHMgaW4geFxuICAgIGZ1bmN0aW9uIGNiaXQoeCkge1xuICAgICAgdmFyIHIgPSAwO1xuICAgICAgd2hpbGUoeCAhPSAwKSB7IHggJj0geC0xOyArK3I7IH1cbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHJldHVybiBudW1iZXIgb2Ygc2V0IGJpdHNcbiAgICBmdW5jdGlvbiBibkJpdENvdW50KCkge1xuICAgICAgdmFyIHIgPSAwLCB4ID0gdGhpcy5zJnRoaXMuRE07XG4gICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIgKz0gY2JpdCh0aGlzW2ldXngpO1xuICAgICAgcmV0dXJuIHI7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgdHJ1ZSBpZmYgbnRoIGJpdCBpcyBzZXRcbiAgICBmdW5jdGlvbiBiblRlc3RCaXQobikge1xuICAgICAgdmFyIGogPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7XG4gICAgICBpZihqID49IHRoaXMudCkgcmV0dXJuKHRoaXMucyE9MCk7XG4gICAgICByZXR1cm4oKHRoaXNbal0mKDE8PChuJXRoaXMuREIpKSkhPTApO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHRoaXMgb3AgKDE8PG4pXG4gICAgZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sb3ApIHtcbiAgICAgIHZhciByID0gQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KG4pO1xuICAgICAgdGhpcy5iaXR3aXNlVG8ocixvcCxyKTtcbiAgICAgIHJldHVybiByO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgfCAoMTw8bilcbiAgICBmdW5jdGlvbiBiblNldEJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX29yKTsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyAmIH4oMTw8bilcbiAgICBmdW5jdGlvbiBibkNsZWFyQml0KG4pIHsgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sb3BfYW5kbm90KTsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyBeICgxPDxuKVxuICAgIGZ1bmN0aW9uIGJuRmxpcEJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX3hvcik7IH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYVxuICAgIGZ1bmN0aW9uIGJucEFkZFRvKGEscikge1xuICAgICAgdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpO1xuICAgICAgd2hpbGUoaSA8IG0pIHtcbiAgICAgICAgYyArPSB0aGlzW2ldK2FbaV07XG4gICAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgIH1cbiAgICAgIGlmKGEudCA8IHRoaXMudCkge1xuICAgICAgICBjICs9IGEucztcbiAgICAgICAgd2hpbGUoaSA8IHRoaXMudCkge1xuICAgICAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgICAgICByW2krK10gPSBjJnRoaXMuRE07XG4gICAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgICAgfVxuICAgICAgICBjICs9IHRoaXMucztcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBjICs9IHRoaXMucztcbiAgICAgICAgd2hpbGUoaSA8IGEudCkge1xuICAgICAgICAgIGMgKz0gYVtpXTtcbiAgICAgICAgICByW2krK10gPSBjJnRoaXMuRE07XG4gICAgICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICAgICAgfVxuICAgICAgICBjICs9IGEucztcbiAgICAgIH1cbiAgICAgIHIucyA9IChjPDApPy0xOjA7XG4gICAgICBpZihjID4gMCkgcltpKytdID0gYztcbiAgICAgIGVsc2UgaWYoYyA8IC0xKSByW2krK10gPSB0aGlzLkRWK2M7XG4gICAgICByLnQgPSBpO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXMgKyBhXG4gICAgZnVuY3Rpb24gYm5BZGQoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmFkZFRvKGEscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzIC0gYVxuICAgIGZ1bmN0aW9uIGJuU3VidHJhY3QoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLnN1YlRvKGEscik7IHJldHVybiByOyB9XG5cbiAgICAvLyAocHVibGljKSB0aGlzICogYVxuICAgIGZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLm11bHRpcGx5VG8oYSxyKTsgcmV0dXJuIHI7IH1cblxuICAgIC8vIChwdWJsaWMpIHRoaXNeMlxuICAgIGZ1bmN0aW9uIGJuU3F1YXJlKCkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLnNxdWFyZVRvKHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyAvIGFcbiAgICBmdW5jdGlvbiBibkRpdmlkZShhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuZGl2UmVtVG8oYSxyLG51bGwpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgdGhpcyAlIGFcbiAgICBmdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuZGl2UmVtVG8oYSxudWxsLHIpOyByZXR1cm4gcjsgfVxuXG4gICAgLy8gKHB1YmxpYykgW3RoaXMvYSx0aGlzJWFdXG4gICAgZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYSkge1xuICAgICAgdmFyIHEgPSBuYmkoKSwgciA9IG5iaSgpO1xuICAgICAgdGhpcy5kaXZSZW1UbyhhLHEscik7XG4gICAgICByZXR1cm4gbmV3IEFycmF5KHEscik7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgdGhpcyAqPSBuLCB0aGlzID49IDAsIDEgPCBuIDwgRFZcbiAgICBmdW5jdGlvbiBibnBETXVsdGlwbHkobikge1xuICAgICAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLG4tMSx0aGlzLDAsMCx0aGlzLnQpO1xuICAgICAgKyt0aGlzLnQ7XG4gICAgICB0aGlzLmNsYW1wKCk7XG4gICAgfVxuXG4gICAgLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuICAgIGZ1bmN0aW9uIGJucERBZGRPZmZzZXQobix3KSB7XG4gICAgICBpZihuID09IDApIHJldHVybjtcbiAgICAgIHdoaWxlKHRoaXMudCA8PSB3KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gICAgICB0aGlzW3ddICs9IG47XG4gICAgICB3aGlsZSh0aGlzW3ddID49IHRoaXMuRFYpIHtcbiAgICAgICAgdGhpc1t3XSAtPSB0aGlzLkRWO1xuICAgICAgICBpZigrK3cgPj0gdGhpcy50KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gICAgICAgICsrdGhpc1t3XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBIFwibnVsbFwiIHJlZHVjZXJcbiAgICBmdW5jdGlvbiBOdWxsRXhwKCkge31cbiAgICBmdW5jdGlvbiBuTm9wKHgpIHsgcmV0dXJuIHg7IH1cbiAgICBmdW5jdGlvbiBuTXVsVG8oeCx5LHIpIHsgeC5tdWx0aXBseVRvKHkscik7IH1cbiAgICBmdW5jdGlvbiBuU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IH1cblxuICAgIE51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wO1xuICAgIE51bGxFeHAucHJvdG90eXBlLnJldmVydCA9IG5Ob3A7XG4gICAgTnVsbEV4cC5wcm90b3R5cGUubXVsVG8gPSBuTXVsVG87XG4gICAgTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87XG5cbiAgICAvLyAocHVibGljKSB0aGlzXmVcbiAgICBmdW5jdGlvbiBiblBvdyhlKSB7IHJldHVybiB0aGlzLmV4cChlLG5ldyBOdWxsRXhwKCkpOyB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSByID0gbG93ZXIgbiB3b3JkcyBvZiBcInRoaXMgKiBhXCIsIGEudCA8PSBuXG4gICAgLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuICAgIGZ1bmN0aW9uIGJucE11bHRpcGx5TG93ZXJUbyhhLG4scikge1xuICAgICAgdmFyIGkgPSBNYXRoLm1pbih0aGlzLnQrYS50LG4pO1xuICAgICAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMFxuICAgICAgci50ID0gaTtcbiAgICAgIHdoaWxlKGkgPiAwKSByWy0taV0gPSAwO1xuICAgICAgdmFyIGo7XG4gICAgICBmb3IoaiA9IHIudC10aGlzLnQ7IGkgPCBqOyArK2kpIHJbaSt0aGlzLnRdID0gdGhpcy5hbSgwLGFbaV0scixpLDAsdGhpcy50KTtcbiAgICAgIGZvcihqID0gTWF0aC5taW4oYS50LG4pOyBpIDwgajsgKytpKSB0aGlzLmFtKDAsYVtpXSxyLGksMCxuLWkpO1xuICAgICAgci5jbGFtcCgpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHIgPSBcInRoaXMgKiBhXCIgd2l0aG91dCBsb3dlciBuIHdvcmRzLCBuID4gMFxuICAgIC8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbiAgICBmdW5jdGlvbiBibnBNdWx0aXBseVVwcGVyVG8oYSxuLHIpIHtcbiAgICAgIC0tbjtcbiAgICAgIHZhciBpID0gci50ID0gdGhpcy50K2EudC1uO1xuICAgICAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMFxuICAgICAgd2hpbGUoLS1pID49IDApIHJbaV0gPSAwO1xuICAgICAgZm9yKGkgPSBNYXRoLm1heChuLXRoaXMudCwwKTsgaSA8IGEudDsgKytpKVxuICAgICAgICByW3RoaXMudCtpLW5dID0gdGhpcy5hbShuLWksYVtpXSxyLDAsMCx0aGlzLnQraS1uKTtcbiAgICAgIHIuY2xhbXAoKTtcbiAgICAgIHIuZHJTaGlmdFRvKDEscik7XG4gICAgfVxuXG4gICAgLy8gQmFycmV0dCBtb2R1bGFyIHJlZHVjdGlvblxuICAgIGZ1bmN0aW9uIEJhcnJldHQobSkge1xuICAgICAgLy8gc2V0dXAgQmFycmV0dFxuICAgICAgdGhpcy5yMiA9IG5iaSgpO1xuICAgICAgdGhpcy5xMyA9IG5iaSgpO1xuICAgICAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIqbS50LHRoaXMucjIpO1xuICAgICAgdGhpcy5tdSA9IHRoaXMucjIuZGl2aWRlKG0pO1xuICAgICAgdGhpcy5tID0gbTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBiYXJyZXR0Q29udmVydCh4KSB7XG4gICAgICBpZih4LnMgPCAwIHx8IHgudCA+IDIqdGhpcy5tLnQpIHJldHVybiB4Lm1vZCh0aGlzLm0pO1xuICAgICAgZWxzZSBpZih4LmNvbXBhcmVUbyh0aGlzLm0pIDwgMCkgcmV0dXJuIHg7XG4gICAgICBlbHNlIHsgdmFyIHIgPSBuYmkoKTsgeC5jb3B5VG8ocik7IHRoaXMucmVkdWNlKHIpOyByZXR1cm4gcjsgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkgeyByZXR1cm4geDsgfVxuXG4gICAgLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MilcbiAgICBmdW5jdGlvbiBiYXJyZXR0UmVkdWNlKHgpIHtcbiAgICAgIHguZHJTaGlmdFRvKHRoaXMubS50LTEsdGhpcy5yMik7XG4gICAgICBpZih4LnQgPiB0aGlzLm0udCsxKSB7IHgudCA9IHRoaXMubS50KzE7IHguY2xhbXAoKTsgfVxuICAgICAgdGhpcy5tdS5tdWx0aXBseVVwcGVyVG8odGhpcy5yMix0aGlzLm0udCsxLHRoaXMucTMpO1xuICAgICAgdGhpcy5tLm11bHRpcGx5TG93ZXJUbyh0aGlzLnEzLHRoaXMubS50KzEsdGhpcy5yMik7XG4gICAgICB3aGlsZSh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLHRoaXMubS50KzEpO1xuICAgICAgeC5zdWJUbyh0aGlzLnIyLHgpO1xuICAgICAgd2hpbGUoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSx4KTtcbiAgICB9XG5cbiAgICAvLyByID0geF4yIG1vZCBtOyB4ICE9IHJcbiAgICBmdW5jdGlvbiBiYXJyZXR0U3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbiAgICAvLyByID0geCp5IG1vZCBtOyB4LHkgIT0gclxuICAgIGZ1bmN0aW9uIGJhcnJldHRNdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgdGhpcy5yZWR1Y2Uocik7IH1cblxuICAgIEJhcnJldHQucHJvdG90eXBlLmNvbnZlcnQgPSBiYXJyZXR0Q29udmVydDtcbiAgICBCYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0O1xuICAgIEJhcnJldHQucHJvdG90eXBlLnJlZHVjZSA9IGJhcnJldHRSZWR1Y2U7XG4gICAgQmFycmV0dC5wcm90b3R5cGUubXVsVG8gPSBiYXJyZXR0TXVsVG87XG4gICAgQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87XG5cbiAgICAvLyAocHVibGljKSB0aGlzXmUgJSBtIChIQUMgMTQuODUpXG4gICAgZnVuY3Rpb24gYm5Nb2RQb3coZSxtKSB7XG4gICAgICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksIGssIHIgPSBuYnYoMSksIHo7XG4gICAgICBpZihpIDw9IDApIHJldHVybiByO1xuICAgICAgZWxzZSBpZihpIDwgMTgpIGsgPSAxO1xuICAgICAgZWxzZSBpZihpIDwgNDgpIGsgPSAzO1xuICAgICAgZWxzZSBpZihpIDwgMTQ0KSBrID0gNDtcbiAgICAgIGVsc2UgaWYoaSA8IDc2OCkgayA9IDU7XG4gICAgICBlbHNlIGsgPSA2O1xuICAgICAgaWYoaSA8IDgpXG4gICAgICAgIHogPSBuZXcgQ2xhc3NpYyhtKTtcbiAgICAgIGVsc2UgaWYobS5pc0V2ZW4oKSlcbiAgICAgICAgeiA9IG5ldyBCYXJyZXR0KG0pO1xuICAgICAgZWxzZVxuICAgICAgICB6ID0gbmV3IE1vbnRnb21lcnkobSk7XG5cbiAgICAgIC8vIHByZWNvbXB1dGF0aW9uXG4gICAgICB2YXIgZyA9IG5ldyBBcnJheSgpLCBuID0gMywgazEgPSBrLTEsIGttID0gKDE8PGspLTE7XG4gICAgICBnWzFdID0gei5jb252ZXJ0KHRoaXMpO1xuICAgICAgaWYoayA+IDEpIHtcbiAgICAgICAgdmFyIGcyID0gbmJpKCk7XG4gICAgICAgIHouc3FyVG8oZ1sxXSxnMik7XG4gICAgICAgIHdoaWxlKG4gPD0ga20pIHtcbiAgICAgICAgICBnW25dID0gbmJpKCk7XG4gICAgICAgICAgei5tdWxUbyhnMixnW24tMl0sZ1tuXSk7XG4gICAgICAgICAgbiArPSAyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBqID0gZS50LTEsIHcsIGlzMSA9IHRydWUsIHIyID0gbmJpKCksIHQ7XG4gICAgICBpID0gbmJpdHMoZVtqXSktMTtcbiAgICAgIHdoaWxlKGogPj0gMCkge1xuICAgICAgICBpZihpID49IGsxKSB3ID0gKGVbal0+PihpLWsxKSkma207XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHcgPSAoZVtqXSYoKDE8PChpKzEpKS0xKSk8PChrMS1pKTtcbiAgICAgICAgICBpZihqID4gMCkgdyB8PSBlW2otMV0+Pih0aGlzLkRCK2ktazEpO1xuICAgICAgICB9XG5cbiAgICAgICAgbiA9IGs7XG4gICAgICAgIHdoaWxlKCh3JjEpID09IDApIHsgdyA+Pj0gMTsgLS1uOyB9XG4gICAgICAgIGlmKChpIC09IG4pIDwgMCkgeyBpICs9IHRoaXMuREI7IC0tajsgfVxuICAgICAgICBpZihpczEpIHsgICAgLy8gcmV0ID09IDEsIGRvbid0IGJvdGhlciBzcXVhcmluZyBvciBtdWx0aXBseWluZyBpdFxuICAgICAgICAgIGdbd10uY29weVRvKHIpO1xuICAgICAgICAgIGlzMSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHdoaWxlKG4gPiAxKSB7IHouc3FyVG8ocixyMik7IHouc3FyVG8ocjIscik7IG4gLT0gMjsgfVxuICAgICAgICAgIGlmKG4gPiAwKSB6LnNxclRvKHIscjIpOyBlbHNlIHsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9XG4gICAgICAgICAgei5tdWxUbyhyMixnW3ddLHIpO1xuICAgICAgICB9XG5cbiAgICAgICAgd2hpbGUoaiA+PSAwICYmIChlW2pdJigxPDxpKSkgPT0gMCkge1xuICAgICAgICAgIHouc3FyVG8ocixyMik7IHQgPSByOyByID0gcjI7IHIyID0gdDtcbiAgICAgICAgICBpZigtLWkgPCAwKSB7IGkgPSB0aGlzLkRCLTE7IC0tajsgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gei5yZXZlcnQocik7XG4gICAgfVxuXG4gICAgLy8gKHB1YmxpYykgZ2NkKHRoaXMsYSkgKEhBQyAxNC41NClcbiAgICBmdW5jdGlvbiBibkdDRChhKSB7XG4gICAgICB2YXIgeCA9ICh0aGlzLnM8MCk/dGhpcy5uZWdhdGUoKTp0aGlzLmNsb25lKCk7XG4gICAgICB2YXIgeSA9IChhLnM8MCk/YS5uZWdhdGUoKTphLmNsb25lKCk7XG4gICAgICBpZih4LmNvbXBhcmVUbyh5KSA8IDApIHsgdmFyIHQgPSB4OyB4ID0geTsgeSA9IHQ7IH1cbiAgICAgIHZhciBpID0geC5nZXRMb3dlc3RTZXRCaXQoKSwgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gICAgICBpZihnIDwgMCkgcmV0dXJuIHg7XG4gICAgICBpZihpIDwgZykgZyA9IGk7XG4gICAgICBpZihnID4gMCkge1xuICAgICAgICB4LnJTaGlmdFRvKGcseCk7XG4gICAgICAgIHkuclNoaWZ0VG8oZyx5KTtcbiAgICAgIH1cbiAgICAgIHdoaWxlKHguc2lnbnVtKCkgPiAwKSB7XG4gICAgICAgIGlmKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGkseCk7XG4gICAgICAgIGlmKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGkseSk7XG4gICAgICAgIGlmKHguY29tcGFyZVRvKHkpID49IDApIHtcbiAgICAgICAgICB4LnN1YlRvKHkseCk7XG4gICAgICAgICAgeC5yU2hpZnRUbygxLHgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHkuc3ViVG8oeCx5KTtcbiAgICAgICAgICB5LnJTaGlmdFRvKDEseSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGcgPiAwKSB5LmxTaGlmdFRvKGcseSk7XG4gICAgICByZXR1cm4geTtcbiAgICB9XG5cbiAgICAvLyAocHJvdGVjdGVkKSB0aGlzICUgbiwgbiA8IDJeMjZcbiAgICBmdW5jdGlvbiBibnBNb2RJbnQobikge1xuICAgICAgaWYobiA8PSAwKSByZXR1cm4gMDtcbiAgICAgIHZhciBkID0gdGhpcy5EViVuLCByID0gKHRoaXMuczwwKT9uLTE6MDtcbiAgICAgIGlmKHRoaXMudCA+IDApXG4gICAgICAgIGlmKGQgPT0gMCkgciA9IHRoaXNbMF0lbjtcbiAgICAgICAgZWxzZSBmb3IodmFyIGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHIgPSAoZCpyK3RoaXNbaV0pJW47XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG5cbiAgICAvLyAocHVibGljKSAxL3RoaXMgJSBtIChIQUMgMTQuNjEpXG4gICAgZnVuY3Rpb24gYm5Nb2RJbnZlcnNlKG0pIHtcbiAgICAgIHZhciBhYyA9IG0uaXNFdmVuKCk7XG4gICAgICBpZigodGhpcy5pc0V2ZW4oKSAmJiBhYykgfHwgbS5zaWdudW0oKSA9PSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPO1xuICAgICAgdmFyIHUgPSBtLmNsb25lKCksIHYgPSB0aGlzLmNsb25lKCk7XG4gICAgICB2YXIgYSA9IG5idigxKSwgYiA9IG5idigwKSwgYyA9IG5idigwKSwgZCA9IG5idigxKTtcbiAgICAgIHdoaWxlKHUuc2lnbnVtKCkgIT0gMCkge1xuICAgICAgICB3aGlsZSh1LmlzRXZlbigpKSB7XG4gICAgICAgICAgdS5yU2hpZnRUbygxLHUpO1xuICAgICAgICAgIGlmKGFjKSB7XG4gICAgICAgICAgICBpZighYS5pc0V2ZW4oKSB8fCAhYi5pc0V2ZW4oKSkgeyBhLmFkZFRvKHRoaXMsYSk7IGIuc3ViVG8obSxiKTsgfVxuICAgICAgICAgICAgYS5yU2hpZnRUbygxLGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKCFiLmlzRXZlbigpKSBiLnN1YlRvKG0sYik7XG4gICAgICAgICAgYi5yU2hpZnRUbygxLGIpO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlKHYuaXNFdmVuKCkpIHtcbiAgICAgICAgICB2LnJTaGlmdFRvKDEsdik7XG4gICAgICAgICAgaWYoYWMpIHtcbiAgICAgICAgICAgIGlmKCFjLmlzRXZlbigpIHx8ICFkLmlzRXZlbigpKSB7IGMuYWRkVG8odGhpcyxjKTsgZC5zdWJUbyhtLGQpOyB9XG4gICAgICAgICAgICBjLnJTaGlmdFRvKDEsYyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoIWQuaXNFdmVuKCkpIGQuc3ViVG8obSxkKTtcbiAgICAgICAgICBkLnJTaGlmdFRvKDEsZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYodS5jb21wYXJlVG8odikgPj0gMCkge1xuICAgICAgICAgIHUuc3ViVG8odix1KTtcbiAgICAgICAgICBpZihhYykgYS5zdWJUbyhjLGEpO1xuICAgICAgICAgIGIuc3ViVG8oZCxiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB2LnN1YlRvKHUsdik7XG4gICAgICAgICAgaWYoYWMpIGMuc3ViVG8oYSxjKTtcbiAgICAgICAgICBkLnN1YlRvKGIsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKHYuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPO1xuICAgICAgaWYoZC5jb21wYXJlVG8obSkgPj0gMCkgcmV0dXJuIGQuc3VidHJhY3QobSk7XG4gICAgICBpZihkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLGQpOyBlbHNlIHJldHVybiBkO1xuICAgICAgaWYoZC5zaWdudW0oKSA8IDApIHJldHVybiBkLmFkZChtKTsgZWxzZSByZXR1cm4gZDtcbiAgICB9XG5cbiAgICB2YXIgbG93cHJpbWVzID0gWzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDksNTIxLDUyMyw1NDEsNTQ3LDU1Nyw1NjMsNTY5LDU3MSw1NzcsNTg3LDU5Myw1OTksNjAxLDYwNyw2MTMsNjE3LDYxOSw2MzEsNjQxLDY0Myw2NDcsNjUzLDY1OSw2NjEsNjczLDY3Nyw2ODMsNjkxLDcwMSw3MDksNzE5LDcyNyw3MzMsNzM5LDc0Myw3NTEsNzU3LDc2MSw3NjksNzczLDc4Nyw3OTcsODA5LDgxMSw4MjEsODIzLDgyNyw4MjksODM5LDg1Myw4NTcsODU5LDg2Myw4NzcsODgxLDg4Myw4ODcsOTA3LDkxMSw5MTksOTI5LDkzNyw5NDEsOTQ3LDk1Myw5NjcsOTcxLDk3Nyw5ODMsOTkxLDk5N107XG4gICAgdmFyIGxwbGltID0gKDE8PDI2KS9sb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXTtcblxuICAgIC8vIChwdWJsaWMpIHRlc3QgcHJpbWFsaXR5IHdpdGggY2VydGFpbnR5ID49IDEtLjVedFxuICAgIGZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHtcbiAgICAgIHZhciBpLCB4ID0gdGhpcy5hYnMoKTtcbiAgICAgIGlmKHgudCA9PSAxICYmIHhbMF0gPD0gbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGgtMV0pIHtcbiAgICAgICAgZm9yKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmKHhbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYoeC5pc0V2ZW4oKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaSA9IDE7XG4gICAgICB3aGlsZShpIDwgbG93cHJpbWVzLmxlbmd0aCkge1xuICAgICAgICB2YXIgbSA9IGxvd3ByaW1lc1tpXSwgaiA9IGkrMTtcbiAgICAgICAgd2hpbGUoaiA8IGxvd3ByaW1lcy5sZW5ndGggJiYgbSA8IGxwbGltKSBtICo9IGxvd3ByaW1lc1tqKytdO1xuICAgICAgICBtID0geC5tb2RJbnQobSk7XG4gICAgICAgIHdoaWxlKGkgPCBqKSBpZihtJWxvd3ByaW1lc1tpKytdID09IDApIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB4Lm1pbGxlclJhYmluKHQpO1xuICAgIH1cblxuICAgIC8vIChwcm90ZWN0ZWQpIHRydWUgaWYgcHJvYmFibHkgcHJpbWUgKEhBQyA0LjI0LCBNaWxsZXItUmFiaW4pXG4gICAgZnVuY3Rpb24gYm5wTWlsbGVyUmFiaW4odCkge1xuICAgICAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICB2YXIgayA9IG4xLmdldExvd2VzdFNldEJpdCgpO1xuICAgICAgaWYoayA8PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICB2YXIgciA9IG4xLnNoaWZ0UmlnaHQoayk7XG4gICAgICB0ID0gKHQrMSk+PjE7XG4gICAgICBpZih0ID4gbG93cHJpbWVzLmxlbmd0aCkgdCA9IGxvd3ByaW1lcy5sZW5ndGg7XG4gICAgICB2YXIgYSA9IG5iaSgpO1xuICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHQ7ICsraSkge1xuICAgICAgICAvL1BpY2sgYmFzZXMgYXQgcmFuZG9tLCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGF0IDJcbiAgICAgICAgYS5mcm9tSW50KGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqbG93cHJpbWVzLmxlbmd0aCldKTtcbiAgICAgICAgdmFyIHkgPSBhLm1vZFBvdyhyLHRoaXMpO1xuICAgICAgICBpZih5LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkge1xuICAgICAgICAgIHZhciBqID0gMTtcbiAgICAgICAgICB3aGlsZShqKysgPCBrICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7XG4gICAgICAgICAgICB5ID0geS5tb2RQb3dJbnQoMix0aGlzKTtcbiAgICAgICAgICAgIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKHkuY29tcGFyZVRvKG4xKSAhPSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIC8vIHByb3RlY3RlZFxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNodW5rU2l6ZSA9IGJucENodW5rU2l6ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1JhZGl4ID0gYm5wVG9SYWRpeDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbU51bWJlciA9IGJucEZyb21OdW1iZXI7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYml0d2lzZVRvID0gYm5wQml0d2lzZVRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGRUbyA9IGJucEFkZFRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRNdWx0aXBseSA9IGJucERNdWx0aXBseTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseUxvd2VyVG8gPSBibnBNdWx0aXBseUxvd2VyVG87XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlVcHBlclRvID0gYm5wTXVsdGlwbHlVcHBlclRvO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5taWxsZXJSYWJpbiA9IGJucE1pbGxlclJhYmluO1xuXG4gICAgLy8gcHVibGljXG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuY2xvbmUgPSBibkNsb25lO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmludFZhbHVlID0gYm5JbnRWYWx1ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5ieXRlVmFsdWUgPSBibkJ5dGVWYWx1ZTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnNpZ251bSA9IGJuU2lnTnVtO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5ID0gYm5Ub0J5dGVBcnJheTtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5lcXVhbHMgPSBibkVxdWFscztcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5taW4gPSBibk1pbjtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5tYXggPSBibk1heDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmQgPSBibkFuZDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5vciA9IGJuT3I7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUueG9yID0gYm5Yb3I7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kTm90ID0gYm5BbmROb3Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubm90ID0gYm5Ob3Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRMZWZ0ID0gYm5TaGlmdExlZnQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5nZXRMb3dlc3RTZXRCaXQgPSBibkdldExvd2VzdFNldEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRDb3VudCA9IGJuQml0Q291bnQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUudGVzdEJpdCA9IGJuVGVzdEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zZXRCaXQgPSBiblNldEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGVhckJpdCA9IGJuQ2xlYXJCaXQ7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZmxpcEJpdCA9IGJuRmxpcEJpdDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGQgPSBibkFkZDtcbiAgICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJ0cmFjdCA9IGJuU3VidHJhY3Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHkgPSBibk11bHRpcGx5O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZSA9IGJuRGl2aWRlO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnJlbWFpbmRlciA9IGJuUmVtYWluZGVyO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyO1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvdyA9IGJuTW9kUG93O1xuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludmVyc2UgPSBibk1vZEludmVyc2U7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUucG93ID0gYm5Qb3c7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuZ2NkID0gYm5HQ0Q7XG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuaXNQcm9iYWJsZVByaW1lID0gYm5Jc1Byb2JhYmxlUHJpbWU7XG5cbiAgICAvLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvblxuICAgIEJpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZSA9IGJuU3F1YXJlO1xuXG4gICAgLy8gRXhwb3NlIHRoZSBCYXJyZXR0IGZ1bmN0aW9uXG4gICAgQmlnSW50ZWdlci5wcm90b3R5cGUuQmFycmV0dCA9IEJhcnJldHRcblxuICAgIC8vIEJpZ0ludGVnZXIgaW50ZXJmYWNlcyBub3QgaW1wbGVtZW50ZWQgaW4ganNibjpcblxuICAgIC8vIEJpZ0ludGVnZXIoaW50IHNpZ251bSwgYnl0ZVtdIG1hZ25pdHVkZSlcbiAgICAvLyBkb3VibGUgZG91YmxlVmFsdWUoKVxuICAgIC8vIGZsb2F0IGZsb2F0VmFsdWUoKVxuICAgIC8vIGludCBoYXNoQ29kZSgpXG4gICAgLy8gbG9uZyBsb25nVmFsdWUoKVxuICAgIC8vIHN0YXRpYyBCaWdJbnRlZ2VyIHZhbHVlT2YobG9uZyB2YWwpXG5cbiAgICAvLyBSYW5kb20gbnVtYmVyIGdlbmVyYXRvciAtIHJlcXVpcmVzIGEgUFJORyBiYWNrZW5kLCBlLmcuIHBybmc0LmpzXG5cbiAgICAvLyBGb3IgYmVzdCByZXN1bHRzLCBwdXQgY29kZSBsaWtlXG4gICAgLy8gPGJvZHkgb25DbGljaz0ncm5nX3NlZWRfdGltZSgpOycgb25LZXlQcmVzcz0ncm5nX3NlZWRfdGltZSgpOyc+XG4gICAgLy8gaW4geW91ciBtYWluIEhUTUwgZG9jdW1lbnQuXG5cbiAgICB2YXIgcm5nX3N0YXRlO1xuICAgIHZhciBybmdfcG9vbDtcbiAgICB2YXIgcm5nX3BwdHI7XG5cbiAgICAvLyBNaXggaW4gYSAzMi1iaXQgaW50ZWdlciBpbnRvIHRoZSBwb29sXG4gICAgZnVuY3Rpb24gcm5nX3NlZWRfaW50KHgpIHtcbiAgICAgIHJuZ19wb29sW3JuZ19wcHRyKytdIF49IHggJiAyNTU7XG4gICAgICBybmdfcG9vbFtybmdfcHB0cisrXSBePSAoeCA+PiA4KSAmIDI1NTtcbiAgICAgIHJuZ19wb29sW3JuZ19wcHRyKytdIF49ICh4ID4+IDE2KSAmIDI1NTtcbiAgICAgIHJuZ19wb29sW3JuZ19wcHRyKytdIF49ICh4ID4+IDI0KSAmIDI1NTtcbiAgICAgIGlmKHJuZ19wcHRyID49IHJuZ19wc2l6ZSkgcm5nX3BwdHIgLT0gcm5nX3BzaXplO1xuICAgIH1cblxuICAgIC8vIE1peCBpbiB0aGUgY3VycmVudCB0aW1lICh3L21pbGxpc2Vjb25kcykgaW50byB0aGUgcG9vbFxuICAgIGZ1bmN0aW9uIHJuZ19zZWVkX3RpbWUoKSB7XG4gICAgICBybmdfc2VlZF9pbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuICAgIH1cblxuICAgIC8vIEluaXRpYWxpemUgdGhlIHBvb2wgd2l0aCBqdW5rIGlmIG5lZWRlZC5cbiAgICBpZihybmdfcG9vbCA9PSBudWxsKSB7XG4gICAgICBybmdfcG9vbCA9IG5ldyBBcnJheSgpO1xuICAgICAgcm5nX3BwdHIgPSAwO1xuICAgICAgdmFyIHQ7XG4gICAgICBpZih0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvdy5jcnlwdG8pIHtcbiAgICAgICAgaWYgKHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgICAgICAgLy8gVXNlIHdlYmNyeXB0byBpZiBhdmFpbGFibGVcbiAgICAgICAgICB2YXIgdWEgPSBuZXcgVWludDhBcnJheSgzMik7XG4gICAgICAgICAgd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXModWEpO1xuICAgICAgICAgIGZvcih0ID0gMDsgdCA8IDMyOyArK3QpXG4gICAgICAgICAgICBybmdfcG9vbFtybmdfcHB0cisrXSA9IHVhW3RdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYobmF2aWdhdG9yLmFwcE5hbWUgPT0gXCJOZXRzY2FwZVwiICYmIG5hdmlnYXRvci5hcHBWZXJzaW9uIDwgXCI1XCIpIHtcbiAgICAgICAgICAvLyBFeHRyYWN0IGVudHJvcHkgKDI1NiBiaXRzKSBmcm9tIE5TNCBSTkcgaWYgYXZhaWxhYmxlXG4gICAgICAgICAgdmFyIHogPSB3aW5kb3cuY3J5cHRvLnJhbmRvbSgzMik7XG4gICAgICAgICAgZm9yKHQgPSAwOyB0IDwgei5sZW5ndGg7ICsrdClcbiAgICAgICAgICAgIHJuZ19wb29sW3JuZ19wcHRyKytdID0gei5jaGFyQ29kZUF0KHQpICYgMjU1O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZShybmdfcHB0ciA8IHJuZ19wc2l6ZSkgeyAgLy8gZXh0cmFjdCBzb21lIHJhbmRvbW5lc3MgZnJvbSBNYXRoLnJhbmRvbSgpXG4gICAgICAgIHQgPSBNYXRoLmZsb29yKDY1NTM2ICogTWF0aC5yYW5kb20oKSk7XG4gICAgICAgIHJuZ19wb29sW3JuZ19wcHRyKytdID0gdCA+Pj4gODtcbiAgICAgICAgcm5nX3Bvb2xbcm5nX3BwdHIrK10gPSB0ICYgMjU1O1xuICAgICAgfVxuICAgICAgcm5nX3BwdHIgPSAwO1xuICAgICAgcm5nX3NlZWRfdGltZSgpO1xuICAgICAgLy9ybmdfc2VlZF9pbnQod2luZG93LnNjcmVlblgpO1xuICAgICAgLy9ybmdfc2VlZF9pbnQod2luZG93LnNjcmVlblkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJuZ19nZXRfYnl0ZSgpIHtcbiAgICAgIGlmKHJuZ19zdGF0ZSA9PSBudWxsKSB7XG4gICAgICAgIHJuZ19zZWVkX3RpbWUoKTtcbiAgICAgICAgcm5nX3N0YXRlID0gcHJuZ19uZXdzdGF0ZSgpO1xuICAgICAgICBybmdfc3RhdGUuaW5pdChybmdfcG9vbCk7XG4gICAgICAgIGZvcihybmdfcHB0ciA9IDA7IHJuZ19wcHRyIDwgcm5nX3Bvb2wubGVuZ3RoOyArK3JuZ19wcHRyKVxuICAgICAgICAgIHJuZ19wb29sW3JuZ19wcHRyXSA9IDA7XG4gICAgICAgIHJuZ19wcHRyID0gMDtcbiAgICAgICAgLy9ybmdfcG9vbCA9IG51bGw7XG4gICAgICB9XG4gICAgICAvLyBUT0RPOiBhbGxvdyByZXNlZWRpbmcgYWZ0ZXIgZmlyc3QgcmVxdWVzdFxuICAgICAgcmV0dXJuIHJuZ19zdGF0ZS5uZXh0KCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcm5nX2dldF9ieXRlcyhiYSkge1xuICAgICAgdmFyIGk7XG4gICAgICBmb3IoaSA9IDA7IGkgPCBiYS5sZW5ndGg7ICsraSkgYmFbaV0gPSBybmdfZ2V0X2J5dGUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBTZWN1cmVSYW5kb20oKSB7fVxuXG4gICAgU2VjdXJlUmFuZG9tLnByb3RvdHlwZS5uZXh0Qnl0ZXMgPSBybmdfZ2V0X2J5dGVzO1xuXG4gICAgLy8gcHJuZzQuanMgLSB1c2VzIEFyY2ZvdXIgYXMgYSBQUk5HXG5cbiAgICBmdW5jdGlvbiBBcmNmb3VyKCkge1xuICAgICAgdGhpcy5pID0gMDtcbiAgICAgIHRoaXMuaiA9IDA7XG4gICAgICB0aGlzLlMgPSBuZXcgQXJyYXkoKTtcbiAgICB9XG5cbiAgICAvLyBJbml0aWFsaXplIGFyY2ZvdXIgY29udGV4dCBmcm9tIGtleSwgYW4gYXJyYXkgb2YgaW50cywgZWFjaCBmcm9tIFswLi4yNTVdXG4gICAgZnVuY3Rpb24gQVJDNGluaXQoa2V5KSB7XG4gICAgICB2YXIgaSwgaiwgdDtcbiAgICAgIGZvcihpID0gMDsgaSA8IDI1NjsgKytpKVxuICAgICAgICB0aGlzLlNbaV0gPSBpO1xuICAgICAgaiA9IDA7XG4gICAgICBmb3IoaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICAgICAgICBqID0gKGogKyB0aGlzLlNbaV0gKyBrZXlbaSAlIGtleS5sZW5ndGhdKSAmIDI1NTtcbiAgICAgICAgdCA9IHRoaXMuU1tpXTtcbiAgICAgICAgdGhpcy5TW2ldID0gdGhpcy5TW2pdO1xuICAgICAgICB0aGlzLlNbal0gPSB0O1xuICAgICAgfVxuICAgICAgdGhpcy5pID0gMDtcbiAgICAgIHRoaXMuaiA9IDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gQVJDNG5leHQoKSB7XG4gICAgICB2YXIgdDtcbiAgICAgIHRoaXMuaSA9ICh0aGlzLmkgKyAxKSAmIDI1NTtcbiAgICAgIHRoaXMuaiA9ICh0aGlzLmogKyB0aGlzLlNbdGhpcy5pXSkgJiAyNTU7XG4gICAgICB0ID0gdGhpcy5TW3RoaXMuaV07XG4gICAgICB0aGlzLlNbdGhpcy5pXSA9IHRoaXMuU1t0aGlzLmpdO1xuICAgICAgdGhpcy5TW3RoaXMual0gPSB0O1xuICAgICAgcmV0dXJuIHRoaXMuU1sodCArIHRoaXMuU1t0aGlzLmldKSAmIDI1NV07XG4gICAgfVxuXG4gICAgQXJjZm91ci5wcm90b3R5cGUuaW5pdCA9IEFSQzRpbml0O1xuICAgIEFyY2ZvdXIucHJvdG90eXBlLm5leHQgPSBBUkM0bmV4dDtcblxuICAgIC8vIFBsdWcgaW4geW91ciBSTkcgY29uc3RydWN0b3IgaGVyZVxuICAgIGZ1bmN0aW9uIHBybmdfbmV3c3RhdGUoKSB7XG4gICAgICByZXR1cm4gbmV3IEFyY2ZvdXIoKTtcbiAgICB9XG5cbiAgICAvLyBQb29sIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQgYW5kIGdyZWF0ZXIgdGhhbiAzMi5cbiAgICAvLyBBbiBhcnJheSBvZiBieXRlcyB0aGUgc2l6ZSBvZiB0aGUgcG9vbCB3aWxsIGJlIHBhc3NlZCB0byBpbml0KClcbiAgICB2YXIgcm5nX3BzaXplID0gMjU2O1xuXG4gICAgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgICAgICAgICBkZWZhdWx0OiBCaWdJbnRlZ2VyLFxuICAgICAgICAgICAgQmlnSW50ZWdlcjogQmlnSW50ZWdlcixcbiAgICAgICAgICAgIFNlY3VyZVJhbmRvbTogU2VjdXJlUmFuZG9tLFxuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuanNibiA9IHtcbiAgICAgICAgICBCaWdJbnRlZ2VyOiBCaWdJbnRlZ2VyLFxuICAgICAgICAgIFNlY3VyZVJhbmRvbTogU2VjdXJlUmFuZG9tXG4gICAgICAgIH07XG4gICAgfVxuXG59KS5jYWxsKHRoaXMpO1xuIiwiLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG52YXIgYnl0ZVRvSGV4ID0gW107XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gIGJ5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG59XG5cbmZ1bmN0aW9uIGJ5dGVzVG9VdWlkKGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gb2Zmc2V0IHx8IDA7XG4gIHZhciBidGggPSBieXRlVG9IZXg7XG4gIC8vIGpvaW4gdXNlZCB0byBmaXggbWVtb3J5IGlzc3VlIGNhdXNlZCBieSBjb25jYXRlbmF0aW9uOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMTc1I2M0XG4gIHJldHVybiAoW2J0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sIFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV1dKS5qb2luKCcnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBieXRlc1RvVXVpZDtcbiIsIi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBJbiB0aGVcbi8vIGJyb3dzZXIgdGhpcyBpcyBhIGxpdHRsZSBjb21wbGljYXRlZCBkdWUgdG8gdW5rbm93biBxdWFsaXR5IG9mIE1hdGgucmFuZG9tKClcbi8vIGFuZCBpbmNvbnNpc3RlbnQgc3VwcG9ydCBmb3IgdGhlIGBjcnlwdG9gIEFQSS4gIFdlIGRvIHRoZSBiZXN0IHdlIGNhbiB2aWFcbi8vIGZlYXR1cmUtZGV0ZWN0aW9uXG5cbi8vIGdldFJhbmRvbVZhbHVlcyBuZWVkcyB0byBiZSBpbnZva2VkIGluIGEgY29udGV4dCB3aGVyZSBcInRoaXNcIiBpcyBhIENyeXB0b1xuLy8gaW1wbGVtZW50YXRpb24uIEFsc28sIGZpbmQgdGhlIGNvbXBsZXRlIGltcGxlbWVudGF0aW9uIG9mIGNyeXB0byBvbiBJRTExLlxudmFyIGdldFJhbmRvbVZhbHVlcyA9ICh0eXBlb2YoY3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICh0eXBlb2YobXNDcnlwdG8pICE9ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzID09ICdmdW5jdGlvbicgJiYgbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQobXNDcnlwdG8pKTtcblxuaWYgKGdldFJhbmRvbVZhbHVlcykge1xuICAvLyBXSEFUV0cgY3J5cHRvIFJORyAtIGh0dHA6Ly93aWtpLndoYXR3Zy5vcmcvd2lraS9DcnlwdG9cbiAgdmFyIHJuZHM4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB3aGF0d2dSTkcoKSB7XG4gICAgZ2V0UmFuZG9tVmFsdWVzKHJuZHM4KTtcbiAgICByZXR1cm4gcm5kczg7XG4gIH07XG59IGVsc2Uge1xuICAvLyBNYXRoLnJhbmRvbSgpLWJhc2VkIChSTkcpXG4gIC8vXG4gIC8vIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgTWF0aC5yYW5kb20oKS4gIEl0J3MgZmFzdCwgYnV0IGlzIG9mIHVuc3BlY2lmaWVkXG4gIC8vIHF1YWxpdHkuXG4gIHZhciBybmRzID0gbmV3IEFycmF5KDE2KTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1hdGhSTkcoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIHI7IGkgPCAxNjsgaSsrKSB7XG4gICAgICBpZiAoKGkgJiAweDAzKSA9PT0gMCkgciA9IE1hdGgucmFuZG9tKCkgKiAweDEwMDAwMDAwMDtcbiAgICAgIHJuZHNbaV0gPSByID4+PiAoKGkgJiAweDAzKSA8PCAzKSAmIDB4ZmY7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJuZHM7XG4gIH07XG59XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwiLy8gRGVjbGFyZSB0aGUgRVM2IGZlYXR1cmVzIHdlJ3JlIHVzaW5nXHJcblxyXG4vLyBUT0RPOiBDb25zaWRlciB1c2luZyB0aGUgbG9jYWwgZnVuY3Rpb24gdmVyc2lvbnMgb2YgdGhlc2UsIHNvIHRoYXQgd2VcclxuLy8gYXZvaWQgbW9kaWZ5aW5nIGJyb3dzZXIgZ2xvYmFscyAocG90ZW50aWFsIGZvciBpbnRlcm9wIGJ1Z3Mgd2l0aCBvdGhlciBsaWJyYXJpZXNcclxuLy8gb24gdGhlIHBhZ2UgdGhhdCBtaWdodCBiZSBwb2x5ZmlsbGluZyBFUzYgZmVhdHVyZXMpXHJcblxyXG5pbXBvcnQgJ2NvcmUtanMvZXM2L3Byb21pc2UnO1xyXG5pbXBvcnQgJ2NvcmUtanMvZm4vZnVuY3Rpb24vYmluZCc7XHJcbmltcG9ydCAnY29yZS1qcy9mbi9vYmplY3QvYXNzaWduJztcclxuaW1wb3J0ICdjb3JlLWpzL2ZuL2FycmF5L2ZpbmQnO1xyXG5pbXBvcnQgJ2NvcmUtanMvZm4vYXJyYXkvc29tZSc7XHJcbmltcG9ydCAnY29yZS1qcy9mbi9hcnJheS9pcy1hcnJheSc7XHJcbmltcG9ydCAnY29yZS1qcy9mbi9hcnJheS9zcGxpY2UnO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFRpbWVyIH0gZnJvbSAnLi9UaW1lci5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIEFjY2Vzc1Rva2VuRXZlbnRzIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ1RpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyaW5nXCIpLFxyXG4gICAgICAgIGFjY2Vzc1Rva2VuRXhwaXJlZFRpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyZWRcIilcclxuICAgIH0gPSB7fSkge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcgPSBhY2Nlc3NUb2tlbkV4cGlyaW5nVGltZXI7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkID0gYWNjZXNzVG9rZW5FeHBpcmVkVGltZXI7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZChjb250YWluZXIpIHtcclxuICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV2ZW50cyBpZiB0aGVyZSdzIGFuIGFjY2VzcyB0b2tlbiBhbmQgaXQgaGFzIGFuIGV4cGlyYXRpb25cclxuICAgICAgICBpZiAoY29udGFpbmVyLmFjY2Vzc190b2tlbiAmJiBjb250YWluZXIuZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbiA9IGNvbnRhaW5lci5leHBpcmVzX2luO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiBhY2Nlc3MgdG9rZW4gcHJlc2VudCwgcmVtYWluaW5nIGR1cmF0aW9uOlwiLCBkdXJhdGlvbik7XHJcblxyXG4gICAgICAgICAgICBpZiAoZHVyYXRpb24gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV4cGlyaW5nIGlmIHdlIHN0aWxsIGhhdmUgdGltZVxyXG4gICAgICAgICAgICAgICAgbGV0IGV4cGlyaW5nID0gZHVyYXRpb24gLSB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgICAgICAgICAgICAgIGlmIChleHBpcmluZyA8PSAwKXtcclxuICAgICAgICAgICAgICAgICAgICBleHBpcmluZyA9IDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkFjY2Vzc1Rva2VuRXZlbnRzLmxvYWQ6IHJlZ2lzdGVyaW5nIGV4cGlyaW5nIHRpbWVyIGluOlwiLCBleHBpcmluZyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmluaXQoZXhwaXJpbmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQWNjZXNzVG9rZW5FdmVudHMubG9hZDogY2FuY2VsaW5nIGV4aXN0aW5nIGV4cGlyaW5nIHRpbWVyIGJlY2FzZSB3ZSdyZSBwYXN0IGV4cGlyYXRpb24uXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmluZy5jYW5jZWwoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaWYgaXQncyBuZWdhdGl2ZSwgaXQgd2lsbCBzdGlsbCBmaXJlXHJcbiAgICAgICAgICAgIGxldCBleHBpcmVkID0gZHVyYXRpb24gKyAxO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiByZWdpc3RlcmluZyBleHBpcmVkIHRpbWVyIGluOlwiLCBleHBpcmVkKTtcclxuICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmluaXQoZXhwaXJlZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmNhbmNlbCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyZWQuY2FuY2VsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHVubG9hZCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy51bmxvYWQ6IGNhbmNlbGluZyBleGlzdGluZyBhY2Nlc3MgdG9rZW4gdGltZXJzXCIpO1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcuY2FuY2VsKCk7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmNhbmNlbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZEFjY2Vzc1Rva2VuRXhwaXJpbmcoY2IpIHtcclxuICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmluZyhjYikge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRJbnRlcnZhbCA9IDIwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgQ2hlY2tTZXNzaW9uSUZyYW1lIHtcclxuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCBjbGllbnRfaWQsIHVybCwgaW50ZXJ2YWwsIHN0b3BPbkVycm9yID0gdHJ1ZSkge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX3VybCA9IHVybDtcclxuICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IGludGVydmFsIHx8IERlZmF1bHRJbnRlcnZhbDtcclxuICAgICAgICB0aGlzLl9zdG9wT25FcnJvciA9IHN0b3BPbkVycm9yO1xyXG5cclxuICAgICAgICB2YXIgaWR4ID0gdXJsLmluZGV4T2YoXCIvXCIsIHVybC5pbmRleE9mKFwiLy9cIikgKyAyKTtcclxuICAgICAgICB0aGlzLl9mcmFtZV9vcmlnaW4gPSB1cmwuc3Vic3RyKDAsIGlkeCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpZnJhbWVcIik7XHJcblxyXG4gICAgICAgIC8vIHNob3RndW4gYXBwcm9hY2hcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUud2lkdGggPSAwO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmhlaWdodCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnNyYyA9IHVybDtcclxuICAgIH1cclxuICAgIGxvYWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfbWVzc2FnZShlKSB7XHJcbiAgICAgICAgaWYgKGUub3JpZ2luID09PSB0aGlzLl9mcmFtZV9vcmlnaW4gJiZcclxuICAgICAgICAgICAgZS5zb3VyY2UgPT09IHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3dcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgaWYgKGUuZGF0YSA9PT0gXCJlcnJvclwiKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJDaGVja1Nlc3Npb25JRnJhbWU6IGVycm9yIG1lc3NhZ2UgZnJvbSBjaGVjayBzZXNzaW9uIG9wIGlmcmFtZVwiKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdG9wT25FcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGUuZGF0YSA9PT0gXCJjaGFuZ2VkXCIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZTogY2hhbmdlZCBtZXNzYWdlIGZyb20gY2hlY2sgc2Vzc2lvbiBvcCBpZnJhbWVcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJDaGVja1Nlc3Npb25JRnJhbWU6IFwiICsgZS5kYXRhICsgXCIgbWVzc2FnZSBmcm9tIGNoZWNrIHNlc3Npb24gb3AgaWZyYW1lXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhcnQoc2Vzc2lvbl9zdGF0ZSkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXNzaW9uX3N0YXRlICE9PSBzZXNzaW9uX3N0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdGFydFwiKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcblxyXG4gICAgICAgICAgICBsZXQgc2VuZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UodGhpcy5fY2xpZW50X2lkICsgXCIgXCIgKyB0aGlzLl9zZXNzaW9uX3N0YXRlLCB0aGlzLl9mcmFtZV9vcmlnaW4pO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBub3dcclxuICAgICAgICAgICAgc2VuZCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gYW5kIHNldHVwIHRpbWVyXHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldEludGVydmFsKHNlbmQsIHRoaXMuX2ludGVydmFsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc3RvcCgpIHtcclxuICAgICAgICB0aGlzLl9zZXNzaW9uX3N0YXRlID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdG9wXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IENvcmRvdmFQb3B1cFdpbmRvdyB9IGZyb20gJy4vQ29yZG92YVBvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzID0gJ2hpZGRlbj15ZXMnO1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBDb3Jkb3ZhUG9wdXBXaW5kb3cgfSBmcm9tICcuL0NvcmRvdmFQb3B1cFdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgQ29yZG92YVBvcHVwTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHpvb209bm8nO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIENvcmRvdmFQb3B1cFdpbmRvdyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IocGFyYW1zKSB7XHJcbiAgICAgICAgdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZSA9IHJlc29sdmU7XHJcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdCA9IHJlamVjdDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5mZWF0dXJlcyA9IHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzIHx8IERlZmF1bHRQb3B1cEZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnJlZGlyZWN0X3VyaSA9IHBhcmFtcy5zdGFydFVybDtcclxuICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3cuY3RvcjogcmVkaXJlY3RfdXJpOiBcIiArIHRoaXMucmVkaXJlY3RfdXJpKTtcclxuICAgIH1cclxuXHJcbiAgICBfaXNJbkFwcEJyb3dzZXJJbnN0YWxsZWQoY29yZG92YU1ldGFkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIFtcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3NlclwiLCBcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3Nlci5pbmFwcGJyb3dzZXJcIiwgXCJvcmcuYXBhY2hlLmNvcmRvdmEuaW5hcHBicm93c2VyXCJdLnNvbWUoZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNvcmRvdmFNZXRhZGF0YS5oYXNPd25Qcm9wZXJ0eShuYW1lKVxyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbiAgICBcclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICghd2luZG93LmNvcmRvdmEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9lcnJvcihcImNvcmRvdmEgaXMgdW5kZWZpbmVkXCIpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHZhciBjb3Jkb3ZhTWV0YWRhdGEgPSB3aW5kb3cuY29yZG92YS5yZXF1aXJlKFwiY29yZG92YS9wbHVnaW5fbGlzdFwiKS5tZXRhZGF0YTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzSW5BcHBCcm93c2VySW5zdGFsbGVkKGNvcmRvdmFNZXRhZGF0YSkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3IoXCJJbkFwcEJyb3dzZXIgcGx1Z2luIG5vdCBmb3VuZFwiKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwID0gY29yZG92YS5JbkFwcEJyb3dzZXIub3BlbihwYXJhbXMudXJsLCB0aGlzLnRhcmdldCwgdGhpcy5mZWF0dXJlcyk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9wb3B1cCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQ29yZG92YVBvcHVwV2luZG93Lm5hdmlnYXRlOiBwb3B1cCBzdWNjZXNzZnVsbHkgY3JlYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQgPSB0aGlzLl9leGl0Q2FsbGJhY2suYmluZCh0aGlzKTsgXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkU3RhcnRDYWxsYmFja0V2ZW50ID0gdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2suYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcG9wdXAuYWRkRXZlbnRMaXN0ZW5lcihcImV4aXRcIiwgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BvcHVwLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2Fkc3RhcnRcIiwgdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJFcnJvciBvcGVuaW5nIHBvcHVwIHdpbmRvd1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwcm9taXNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkU3RhcnRDYWxsYmFjayhldmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC51cmwuaW5kZXhPZih0aGlzLnJlZGlyZWN0X3VyaSkgPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5fc3VjY2Vzcyh7IHVybDogZXZlbnQudXJsIH0pO1xyXG4gICAgICAgIH0gICAgXHJcbiAgICB9XHJcbiAgICBfZXhpdENhbGxiYWNrKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLl9lcnJvcihtZXNzYWdlKTsgICAgXHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICB0aGlzLl9jbGVhbnVwKCk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIkNvcmRvdmFQb3B1cFdpbmRvdzogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIGNvcmRvdmEgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fcG9wdXApe1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3c6IGNsZWFuaW5nIHVwIHBvcHVwXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXhpdFwiLCB0aGlzLl9leGl0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwibG9hZHN0YXJ0XCIsIHRoaXMuX2xvYWRTdGFydENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgdGhpcy5fcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSBudWxsO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFcnJvclJlc3BvbnNlIGV4dGVuZHMgRXJyb3Ige1xyXG4gICAgY29uc3RydWN0b3Ioe2Vycm9yLCBlcnJvcl9kZXNjcmlwdGlvbiwgZXJyb3JfdXJpLCBzdGF0ZSwgc2Vzc2lvbl9zdGF0ZX09e31cclxuICAgICkge1xyXG4gICAgICAgICBpZiAoIWVycm9yKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiTm8gZXJyb3IgcGFzc2VkIHRvIEVycm9yUmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImVycm9yXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3VwZXIoZXJyb3JfZGVzY3JpcHRpb24gfHwgZXJyb3IpO1xyXG5cclxuICAgICAgICB0aGlzLm5hbWUgPSBcIkVycm9yUmVzcG9uc2VcIjtcclxuXHJcbiAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSBlcnJvcl9kZXNjcmlwdGlvbjtcclxuICAgICAgICB0aGlzLmVycm9yX3VyaSA9IGVycm9yX3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEV2ZW50IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lKSB7XHJcbiAgICAgICAgdGhpcy5fbmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgYWRkSGFuZGxlcihjYikge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrcy5wdXNoKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVIYW5kbGVyKGNiKSB7XHJcbiAgICAgICAgdmFyIGlkeCA9IHRoaXMuX2NhbGxiYWNrcy5maW5kSW5kZXgoaXRlbSA9PiBpdGVtID09PSBjYik7XHJcbiAgICAgICAgaWYgKGlkeCA+PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmFpc2UoLi4ucGFyYW1zKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiRXZlbnQ6IFJhaXNpbmcgZXZlbnQ6IFwiICsgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9jYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzW2ldKC4uLnBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmNvbnN0IHRpbWVyID0ge1xyXG4gICAgc2V0SW50ZXJ2YWw6IGZ1bmN0aW9uIChjYiwgZHVyYXRpb24pIHtcclxuICAgICAgICByZXR1cm4gc2V0SW50ZXJ2YWwoY2IsIGR1cmF0aW9uKTtcclxuICAgIH0sXHJcbiAgICBjbGVhckludGVydmFsOiBmdW5jdGlvbiAoaGFuZGxlKSB7XHJcbiAgICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwoaGFuZGxlKTtcclxuICAgIH1cclxufTtcclxuXHJcbmxldCB0ZXN0aW5nID0gZmFsc2U7XHJcbmxldCByZXF1ZXN0ID0gbnVsbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBHbG9iYWwge1xyXG5cclxuICAgIHN0YXRpYyBfdGVzdGluZygpIHtcclxuICAgICAgICB0ZXN0aW5nID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IGxvY2F0aW9uKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgbG9jYWxTdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYWxTdG9yYWdlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IHNlc3Npb25TdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gc2Vzc2lvblN0b3JhZ2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBzZXRYTUxIdHRwUmVxdWVzdChuZXdSZXF1ZXN0KSB7XHJcbiAgICAgICAgcmVxdWVzdCA9IG5ld1JlcXVlc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGdldCBYTUxIdHRwUmVxdWVzdCgpIHtcclxuICAgICAgICBpZiAoIXRlc3RpbmcgJiYgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QgfHwgWE1MSHR0cFJlcXVlc3Q7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgdGltZXIoKSB7XHJcbiAgICAgICAgaWYgKCF0ZXN0aW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aW1lcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVXaW5kb3cgfSBmcm9tICcuL0lGcmFtZVdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBmcmFtZSA9IG5ldyBJRnJhbWVXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZyYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVOYXZpZ2F0b3IuY2FsbGJhY2tcIik7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIElGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQodXJsKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRUaW1lb3V0ID0gMTAwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZnJhbWUgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlmcmFtZVwiKTtcclxuXHJcbiAgICAgICAgLy8gc2hvdGd1biBhcHByb2FjaFxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnZpc2liaWxpdHkgPSBcImhpZGRlblwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS53aWR0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUuaGVpZ2h0ID0gMDtcclxuXHJcbiAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IHRpbWVvdXQgPSBwYXJhbXMuc2lsZW50UmVxdWVzdFRpbWVvdXQgfHwgRGVmYXVsdFRpbWVvdXQ7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5uYXZpZ2F0ZTogVXNpbmcgdGltZW91dCBvZjpcIiwgdGltZW91dCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldFRpbWVvdXQodGhpcy5fdGltZW91dC5iaW5kKHRoaXMpLCB0aW1lb3V0KTtcclxuICAgICAgICAgICAgdGhpcy5fZnJhbWUuc3JjID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHByb21pc2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgX3N1Y2Nlc3MoZGF0YSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBTdWNjZXNzZnVsIHJlc3BvbnNlIGZyb20gZnJhbWUgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fZnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBjbGVhbnVwXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLl9mcmFtZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lID0gbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdGltZW91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVXaW5kb3cudGltZW91dFwiKTtcclxuICAgICAgICB0aGlzLl9lcnJvcihcIkZyYW1lIHdpbmRvdyB0aW1lZCBvdXRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgX21lc3NhZ2UoZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5tZXNzYWdlXCIpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fdGltZXIgJiZcclxuICAgICAgICAgICAgZS5vcmlnaW4gPT09IHRoaXMuX29yaWdpbiAmJlxyXG4gICAgICAgICAgICBlLnNvdXJjZSA9PT0gdGhpcy5fZnJhbWUuY29udGVudFdpbmRvd1xyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICBsZXQgdXJsID0gZS5kYXRhO1xyXG4gICAgICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWNjZXNzKHsgdXJsOiB1cmwgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9lcnJvcihcIkludmFsaWQgcmVzcG9uc2UgZnJvbSBmcmFtZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX29yaWdpbigpIHtcclxuICAgICAgICByZXR1cm4gbG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyBsb2NhdGlvbi5ob3N0O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBub3RpZnlQYXJlbnQodXJsKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93Lm5vdGlmeVBhcmVudFwiKTtcclxuICAgICAgICBpZiAod2luZG93LmZyYW1lRWxlbWVudCkge1xyXG4gICAgICAgICAgICB1cmwgPSB1cmwgfHwgd2luZG93LmxvY2F0aW9uLmhyZWY7XHJcbiAgICAgICAgICAgIGlmICh1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQ6IHBvc3RpbmcgdXJsIG1lc3NhZ2UgdG8gcGFyZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZSh1cmwsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICsgbG9jYXRpb24uaG9zdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEluTWVtb3J5V2ViU3RvcmFnZXtcclxuICAgIGNvbnN0cnVjdG9yKCl7XHJcbiAgICAgICAgdGhpcy5fZGF0YSA9IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIGdldEl0ZW0oa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLmdldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIHNldEl0ZW0oa2V5LCB2YWx1ZSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnNldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICB0aGlzLl9kYXRhW2tleV0gPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVJdGVtKGtleSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnJlbW92ZUl0ZW1cIiwga2V5KTtcclxuICAgICAgICBkZWxldGUgdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBsZW5ndGgoKSB7XHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMuX2RhdGEpLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBrZXkoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcy5fZGF0YSlbaW5kZXhdO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEpvc2VVdGlsKHsgandzLCBLZXlVdGlsLCBYNTA5LCBjcnlwdG8sIGhleHRvYjY0dSwgYjY0dG9oZXgsIEFsbG93ZWRTaWduaW5nQWxncyB9KSB7XHJcbiAgICByZXR1cm4gY2xhc3MgSm9zZVV0aWwge1xyXG5cclxuICAgICAgICBzdGF0aWMgcGFyc2VKd3Qoand0KSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkpvc2VVdGlsLnBhcnNlSnd0XCIpO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHRva2VuID0gandzLkpXUy5wYXJzZShqd3QpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBoZWFkZXI6IHRva2VuLmhlYWRlck9iaixcclxuICAgICAgICAgICAgICAgICAgICBwYXlsb2FkOiB0b2tlbi5wYXlsb2FkT2JqXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3RhdGljIHZhbGlkYXRlSnd0KGp3dCwga2V5LCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXcsIG5vdywgdGltZUluc2Vuc2l0aXZlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkpvc2VVdGlsLnZhbGlkYXRlSnd0XCIpO1xyXG5cclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmIChrZXkua3R5ID09PSBcIlJTQVwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleS5lICYmIGtleS5uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IEtleVV0aWwuZ2V0S2V5KGtleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkueDVjICYmIGtleS54NWMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoZXggPSBiNjR0b2hleChrZXkueDVjWzBdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gWDUwOS5nZXRQdWJsaWNLZXlGcm9tQ2VydEhleChoZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLnZhbGlkYXRlSnd0OiBSU0Ega2V5IG1pc3Npbmcga2V5IG1hdGVyaWFsXCIsIGtleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJSU0Ega2V5IG1pc3Npbmcga2V5IG1hdGVyaWFsXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleS5rdHkgPT09IFwiRUNcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuY3J2ICYmIGtleS54ICYmIGtleS55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IEtleVV0aWwuZ2V0S2V5KGtleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwudmFsaWRhdGVKd3Q6IEVDIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRUMga2V5IG1pc3Npbmcga2V5IG1hdGVyaWFsXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLnZhbGlkYXRlSnd0OiBVbnN1cHBvcnRlZCBrZXkgdHlwZVwiLCBrZXkgJiYga2V5Lmt0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIGtleSB0eXBlOiBcIiArIGtleSAmJiBrZXkua3R5KSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIEpvc2VVdGlsLl92YWxpZGF0ZUp3dChqd3QsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3LCBub3csIHRpbWVJbnNlbnNpdGl2ZSk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihlICYmIGUubWVzc2FnZSB8fCBlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcIkpXVCB2YWxpZGF0aW9uIGZhaWxlZFwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3RhdGljIHZhbGlkYXRlSnd0QXR0cmlidXRlcyhqd3QsIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpIHtcclxuICAgICAgICAgICAgaWYgKCFjbG9ja1NrZXcpIHtcclxuICAgICAgICAgICAgICAgIGNsb2NrU2tldyA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghbm93KSB7XHJcbiAgICAgICAgICAgICAgICBub3cgPSBwYXJzZUludChEYXRlLm5vdygpIC8gMTAwMCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciBwYXlsb2FkID0gSm9zZVV0aWwucGFyc2VKd3Qoand0KS5wYXlsb2FkO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFwYXlsb2FkLmlzcykge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBpc3N1ZXIgd2FzIG5vdCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJpc3N1ZXIgd2FzIG5vdCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuaXNzICE9PSBpc3N1ZXIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogSW52YWxpZCBpc3N1ZXIgaW4gdG9rZW5cIiwgcGF5bG9hZC5pc3MpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgaXNzdWVyIGluIHRva2VuOiBcIiArIHBheWxvYWQuaXNzKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICghcGF5bG9hZC5hdWQpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogYXVkIHdhcyBub3QgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXVkIHdhcyBub3QgcHJvdmlkZWRcIikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciB2YWxpZEF1ZGllbmNlID0gcGF5bG9hZC5hdWQgPT09IGF1ZGllbmNlIHx8IChBcnJheS5pc0FycmF5KHBheWxvYWQuYXVkKSAmJiBwYXlsb2FkLmF1ZC5pbmRleE9mKGF1ZGllbmNlKSA+PSAwKTtcclxuICAgICAgICAgICAgaWYgKCF2YWxpZEF1ZGllbmNlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IEludmFsaWQgYXVkaWVuY2UgaW4gdG9rZW5cIiwgcGF5bG9hZC5hdWQpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgYXVkaWVuY2UgaW4gdG9rZW46IFwiICsgcGF5bG9hZC5hdWQpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocGF5bG9hZC5henAgJiYgcGF5bG9hZC5henAgIT09IGF1ZGllbmNlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IEludmFsaWQgYXpwIGluIHRva2VuXCIsIHBheWxvYWQuYXpwKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIGF6cCBpbiB0b2tlbjogXCIgKyBwYXlsb2FkLmF6cCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXRpbWVJbnNlbnNpdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGxvd2VyTm93ID0gbm93ICsgY2xvY2tTa2V3O1xyXG4gICAgICAgICAgICAgICAgdmFyIHVwcGVyTm93ID0gbm93IC0gY2xvY2tTa2V3O1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5pYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGlhdCB3YXMgbm90IHByb3ZpZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJpYXQgd2FzIG5vdCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAobG93ZXJOb3cgPCBwYXlsb2FkLmlhdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogaWF0IGlzIGluIHRoZSBmdXR1cmVcIiwgcGF5bG9hZC5pYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJpYXQgaXMgaW4gdGhlIGZ1dHVyZTogXCIgKyBwYXlsb2FkLmlhdCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLm5iZiAmJiBsb3dlck5vdyA8IHBheWxvYWQubmJmKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBuYmYgaXMgaW4gdGhlIGZ1dHVyZVwiLCBwYXlsb2FkLm5iZik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIm5iZiBpcyBpbiB0aGUgZnV0dXJlOiBcIiArIHBheWxvYWQubmJmKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCFwYXlsb2FkLmV4cCkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogZXhwIHdhcyBub3QgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImV4cCB3YXMgbm90IHByb3ZpZGVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLmV4cCA8IHVwcGVyTm93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBleHAgaXMgaW4gdGhlIHBhc3RcIiwgcGF5bG9hZC5leHApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJleHAgaXMgaW4gdGhlIHBhc3Q6XCIgKyBwYXlsb2FkLmV4cCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBheWxvYWQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3RhdGljIF92YWxpZGF0ZUp3dChqd3QsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3LCBub3csIHRpbWVJbnNlbnNpdGl2ZSkge1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIEpvc2VVdGlsLnZhbGlkYXRlSnd0QXR0cmlidXRlcyhqd3QsIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpLnRoZW4ocGF5bG9hZCA9PiB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghandzLkpXUy52ZXJpZnkoand0LCBrZXksIEFsbG93ZWRTaWduaW5nQWxncykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBzaWduYXR1cmUgdmFsaWRhdGlvbiBmYWlsZWRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJzaWduYXR1cmUgdmFsaWRhdGlvbiBmYWlsZWRcIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBheWxvYWQ7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKGUgJiYgZS5tZXNzYWdlIHx8IGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJzaWduYXR1cmUgdmFsaWRhdGlvbiBmYWlsZWRcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyBoYXNoU3RyaW5nKHZhbHVlLCBhbGcpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjcnlwdG8uVXRpbC5oYXNoU3RyaW5nKHZhbHVlLCBhbGcpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyBoZXhUb0Jhc2U2NFVybCh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGhleHRvYjY0dSh2YWx1ZSk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCJpbXBvcnQgeyBqd3MsIEtleVV0aWwsIFg1MDksIGNyeXB0bywgaGV4dG9iNjR1LCBiNjR0b2hleCwgQWxsb3dlZFNpZ25pbmdBbGdzIH0gZnJvbSAnLi9jcnlwdG8vcnNhJztcclxuaW1wb3J0IGdldEpvc2VVdGlsIGZyb20gJy4vSm9zZVV0aWxJbXBsJztcclxuXHJcbmV4cG9ydCBjb25zdCBKb3NlVXRpbCA9IGdldEpvc2VVdGlsKHsgandzLCBLZXlVdGlsLCBYNTA5LCBjcnlwdG8sIGhleHRvYjY0dSwgYjY0dG9oZXgsIEFsbG93ZWRTaWduaW5nQWxncyB9KTtcclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSnNvblNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgYWRkaXRpb25hbENvbnRlbnRUeXBlcyA9IG51bGwsIFxyXG4gICAgICAgIFhNTEh0dHBSZXF1ZXN0Q3RvciA9IEdsb2JhbC5YTUxIdHRwUmVxdWVzdCwgXHJcbiAgICAgICAgand0SGFuZGxlciA9IG51bGxcclxuICAgICkge1xyXG4gICAgICAgIGlmIChhZGRpdGlvbmFsQ29udGVudFR5cGVzICYmIEFycmF5LmlzQXJyYXkoYWRkaXRpb25hbENvbnRlbnRUeXBlcykpXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMgPSBhZGRpdGlvbmFsQ29udGVudFR5cGVzLnNsaWNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcyA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMucHVzaCgnYXBwbGljYXRpb24vanNvbicpO1xyXG4gICAgICAgIGlmIChqd3RIYW5kbGVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcy5wdXNoKCdhcHBsaWNhdGlvbi9qd3QnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX1hNTEh0dHBSZXF1ZXN0ID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX2p3dEhhbmRsZXIgPSBqd3RIYW5kbGVyO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEpzb24odXJsLCB0b2tlbikge1xyXG4gICAgICAgIGlmICghdXJsKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbiwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ0dFVCcsIHVybCk7XHJcblxyXG4gICAgICAgICAgICB2YXIgYWxsb3dlZENvbnRlbnRUeXBlcyA9IHRoaXMuX2NvbnRlbnRUeXBlcztcclxuICAgICAgICAgICAgdmFyIGp3dEhhbmRsZXIgPSB0aGlzLl9qd3RIYW5kbGVyO1xyXG5cclxuICAgICAgICAgICAgcmVxLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kID09IFwiYXBwbGljYXRpb24vand0XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp3dEhhbmRsZXIocmVxKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKEpTT04ucGFyc2UocmVxLnJlc3BvbnNlVGV4dCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IocmVxLnN0YXR1c1RleHQgKyBcIiAoXCIgKyByZXEuc3RhdHVzICsgXCIpXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5nZXRKc29uOiBuZXR3b3JrIGVycm9yXCIpO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiTmV0d29yayBFcnJvclwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkpzb25TZXJ2aWNlLmdldEpzb246IHRva2VuIHBhc3NlZCwgc2V0dGluZyBBdXRob3JpemF0aW9uIGhlYWRlclwiKTtcclxuICAgICAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyKFwiQXV0aG9yaXphdGlvblwiLCBcIkJlYXJlciBcIiArIHRva2VuKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNlbmQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwb3N0Rm9ybSh1cmwsIHBheWxvYWQpIHtcclxuICAgICAgICBpZiAoIXVybCl7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybSwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ1BPU1QnLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGFsbG93ZWRDb250ZW50VHlwZXMgPSB0aGlzLl9jb250ZW50VHlwZXM7XHJcblxyXG4gICAgICAgICAgICByZXEub25sb2FkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSA0MDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXlsb2FkID0gSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF5bG9hZCAmJiBwYXlsb2FkLmVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBFcnJvciBmcm9tIHNlcnZlcjogXCIsIHBheWxvYWQuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKHBheWxvYWQuZXJyb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IEVycm9yIHBhcnNpbmcgSlNPTiByZXNwb25zZVwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlcS5zdGF0dXNUZXh0ICsgXCIgKFwiICsgcmVxLnN0YXR1cyArIFwiKVwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IG5ldHdvcmsgZXJyb3JcIik7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IoXCJOZXR3b3JrIEVycm9yXCIpKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGxldCBib2R5ID0gXCJcIjtcclxuICAgICAgICAgICAgZm9yKGxldCBrZXkgaW4gcGF5bG9hZCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHBheWxvYWRba2V5XTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJvZHkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiJlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYm9keSArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KTtcclxuICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiPVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIik7XHJcbiAgICAgICAgICAgIHJlcS5zZW5kKGJvZHkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmxldCBub3BMb2dnZXIgPSB7XHJcbiAgICBkZWJ1Zygpe30sXHJcbiAgICBpbmZvKCl7fSxcclxuICAgIHdhcm4oKXt9LFxyXG4gICAgZXJyb3IoKXt9XHJcbn07XHJcblxyXG5jb25zdCBOT05FID0gMDtcclxuY29uc3QgRVJST1IgPSAxO1xyXG5jb25zdCBXQVJOID0gMjtcclxuY29uc3QgSU5GTyA9IDM7XHJcbmNvbnN0IERFQlVHID0gNDtcclxuXHJcbmxldCBsb2dnZXI7XHJcbmxldCBsZXZlbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBMb2cge1xyXG4gICAgc3RhdGljIGdldCBOT05FKCkge3JldHVybiBOT05FfTtcclxuICAgIHN0YXRpYyBnZXQgRVJST1IoKSB7cmV0dXJuIEVSUk9SfTtcclxuICAgIHN0YXRpYyBnZXQgV0FSTigpIHtyZXR1cm4gV0FSTn07XHJcbiAgICBzdGF0aWMgZ2V0IElORk8oKSB7cmV0dXJuIElORk99O1xyXG4gICAgc3RhdGljIGdldCBERUJVRygpIHtyZXR1cm4gREVCVUd9O1xyXG4gICAgXHJcbiAgICBzdGF0aWMgcmVzZXQoKXtcclxuICAgICAgICBsZXZlbCA9IElORk87XHJcbiAgICAgICAgbG9nZ2VyID0gbm9wTG9nZ2VyO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxldmVsKCl7XHJcbiAgICAgICAgcmV0dXJuIGxldmVsO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIHNldCBsZXZlbCh2YWx1ZSl7XHJcbiAgICAgICAgaWYgKE5PTkUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gREVCVUcpe1xyXG4gICAgICAgICAgICBsZXZlbCA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBsb2cgbGV2ZWxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxvZ2dlcigpe1xyXG4gICAgICAgIHJldHVybiBsb2dnZXI7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgc2V0IGxvZ2dlcih2YWx1ZSl7XHJcbiAgICAgICAgaWYgKCF2YWx1ZS5kZWJ1ZyAmJiB2YWx1ZS5pbmZvKSB7XHJcbiAgICAgICAgICAgIC8vIGp1c3QgdG8gc3RheSBiYWNrd2FyZHMgY29tcGF0LiBjYW4gcmVtb3ZlIGluIDIuMFxyXG4gICAgICAgICAgICB2YWx1ZS5kZWJ1ZyA9IHZhbHVlLmluZm87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmFsdWUuZGVidWcgJiYgdmFsdWUuaW5mbyAmJiB2YWx1ZS53YXJuICYmIHZhbHVlLmVycm9yKXtcclxuICAgICAgICAgICAgbG9nZ2VyID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGxvZ2dlclwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHN0YXRpYyBkZWJ1ZyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gREVCVUcpe1xyXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgaW5mbyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gSU5GTyl7XHJcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvLmFwcGx5KGxvZ2dlciwgQXJyYXkuZnJvbShhcmdzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIHdhcm4oLi4uYXJncyl7XHJcbiAgICAgICAgaWYgKGxldmVsID49IFdBUk4pe1xyXG4gICAgICAgICAgICBsb2dnZXIud2Fybi5hcHBseShsb2dnZXIsIEFycmF5LmZyb20oYXJncykpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHN0YXRpYyBlcnJvciguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gRVJST1Ipe1xyXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbkxvZy5yZXNldCgpO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmV4cG9ydCBjbGFzcyBNZXRhZGF0YVNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MsIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2U6IE5vIHNldHRpbmdzIHBhc3NlZCB0byBNZXRhZGF0YVNlcnZpY2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IoWydhcHBsaWNhdGlvbi9qd2stc2V0K2pzb24nXSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1ldGFkYXRhVXJsKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5fbWV0YWRhdGFVcmwpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgPSB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsICYmIHRoaXMuX21ldGFkYXRhVXJsLmluZGV4T2YoT2lkY01ldGFkYXRhVXJsUGF0aCkgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsW3RoaXMuX21ldGFkYXRhVXJsLmxlbmd0aCAtIDFdICE9PSAnLycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCArPSBPaWRjTWV0YWRhdGFVcmxQYXRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TWV0YWRhdGEoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogUmV0dXJuaW5nIG1ldGFkYXRhIGZyb20gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fc2V0dGluZ3MubWV0YWRhdGEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogTm8gYXV0aG9yaXR5IG9yIG1ldGFkYXRhVXJsIGNvbmZpZ3VyZWQgb24gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb3IgbWV0YWRhdGFVcmwgY29uZmlndXJlZCBvbiBzZXR0aW5nc1wiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGE6IGdldHRpbmcgbWV0YWRhdGEgZnJvbVwiLCB0aGlzLm1ldGFkYXRhVXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24odGhpcy5tZXRhZGF0YVVybClcclxuICAgICAgICAgICAgLnRoZW4obWV0YWRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiTWV0YWRhdGFTZXJ2aWNlLmdldE1ldGFkYXRhOiBqc29uIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MubWV0YWRhdGEgPSBtZXRhZGF0YTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0SXNzdWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiaXNzdWVyXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEF1dGhvcml6YXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImF1dGhvcml6YXRpb25fZW5kcG9pbnRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlckluZm9FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInVzZXJpbmZvX2VuZHBvaW50XCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFRva2VuRW5kcG9pbnQob3B0aW9uYWw9dHJ1ZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwidG9rZW5fZW5kcG9pbnRcIiwgb3B0aW9uYWwpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENoZWNrU2Vzc2lvbklmcmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImNoZWNrX3Nlc3Npb25faWZyYW1lXCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEVuZFNlc3Npb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImVuZF9zZXNzaW9uX2VuZHBvaW50XCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFJldm9jYXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInJldm9jYXRpb25fZW5kcG9pbnRcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0S2V5c0VuZHBvaW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldE1ldGFkYXRhUHJvcGVydHkobmFtZSwgb3B0aW9uYWw9ZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eSBmb3I6IFwiICsgbmFtZSk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1ldGFkYXRhKCkudGhlbihtZXRhZGF0YSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YVByb3BlcnR5OiBtZXRhZGF0YSByZWNpZXZlZFwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChtZXRhZGF0YVtuYW1lXSA9PT0gdW5kZWZpbmVkKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBvcHRpb25hbCBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGFkYXRhIGRvZXMgbm90IGNvbnRhaW4gcHJvcGVydHkgXCIgKyBuYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhW25hbWVdO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IFJldHVybmluZyBzaWduaW5nS2V5cyBmcm9tIHNldHRpbmdzXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIikudGhlbihqd2tzX3VyaSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czogandrc191cmkgcmVjZWl2ZWRcIiwgandrc191cmkpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24oandrc191cmkpLnRoZW4oa2V5U2V0ID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czoga2V5IHNldCByZWNlaXZlZFwiLCBrZXlTZXQpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICgha2V5U2V0LmtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IE1pc3Npbmcga2V5cyBvbiBrZXlzZXRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBrZXlzIG9uIGtleXNldFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cyA9IGtleVNldC5rZXlzO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE9pZGNDbGllbnRTZXR0aW5ncyB9IGZyb20gJy4vT2lkY0NsaWVudFNldHRpbmdzLmpzJztcclxuaW1wb3J0IHsgRXJyb3JSZXNwb25zZSB9IGZyb20gJy4vRXJyb3JSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblJlcXVlc3QgfSBmcm9tICcuL1NpZ25pblJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWduaW5SZXNwb25zZSB9IGZyb20gJy4vU2lnbmluUmVzcG9uc2UuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVxdWVzdCB9IGZyb20gJy4vU2lnbm91dFJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVzcG9uc2UgfSBmcm9tICcuL1NpZ25vdXRSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9KSB7XHJcbiAgICAgICAgaWYgKHNldHRpbmdzIGluc3RhbmNlb2YgT2lkY0NsaWVudFNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5ncyA9IG5ldyBPaWRjQ2xpZW50U2V0dGluZ3Moc2V0dGluZ3MpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3N0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3Muc3RhdGVTdG9yZTtcclxuICAgIH1cclxuICAgIGdldCBfdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnZhbGlkYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLm1ldGFkYXRhU2VydmljZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2V0dGluZ3MoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG5cclxuICAgIGNyZWF0ZVNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgIHJlc3BvbnNlX3R5cGUsIHNjb3BlLCByZWRpcmVjdF91cmksXHJcbiAgICAgICAgLy8gZGF0YSB3YXMgbWVhbnQgdG8gYmUgdGhlIHBsYWNlIGEgY2FsbGVyIGNvdWxkIGluZGljYXRlIHRoZSBkYXRhIHRvXHJcbiAgICAgICAgLy8gaGF2ZSByb3VuZCB0cmlwcGVkLCBidXQgcGVvcGxlIHdlcmUgZ2V0dGluZyBjb25mdXNlZCwgc28gaSBhZGRlZCBzdGF0ZSAoc2luY2UgdGhhdCBtYXRjaGVzIHRoZSBzcGVjKVxyXG4gICAgICAgIC8vIGFuZCBzbyBub3cgaWYgZGF0YSBpcyBub3QgcGFzc2VkLCBidXQgc3RhdGUgaXMgdGhlbiBzdGF0ZSB3aWxsIGJlIHVzZWRcclxuICAgICAgICBkYXRhLCBzdGF0ZSwgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBpZF90b2tlbl9oaW50LCBsb2dpbl9oaW50LCBhY3JfdmFsdWVzLFxyXG4gICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgcmVzcG9uc2VfbW9kZSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCBza2lwVXNlckluZm8gfSA9IHt9LFxyXG4gICAgICAgIHN0YXRlU3RvcmVcclxuICAgICkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbmluUmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICByZXNwb25zZV90eXBlID0gcmVzcG9uc2VfdHlwZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHNjb3BlID0gc2NvcGUgfHwgdGhpcy5fc2V0dGluZ3Muc2NvcGU7XHJcbiAgICAgICAgcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgLy8gaWRfdG9rZW5faGludCwgbG9naW5faGludCBhcmVuJ3QgYWxsb3dlZCBvbiBfc2V0dGluZ3NcclxuICAgICAgICBwcm9tcHQgPSBwcm9tcHQgfHwgdGhpcy5fc2V0dGluZ3MucHJvbXB0O1xyXG4gICAgICAgIGRpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuX3NldHRpbmdzLmRpc3BsYXk7XHJcbiAgICAgICAgbWF4X2FnZSA9IG1heF9hZ2UgfHwgdGhpcy5fc2V0dGluZ3MubWF4X2FnZTtcclxuICAgICAgICB1aV9sb2NhbGVzID0gdWlfbG9jYWxlcyB8fCB0aGlzLl9zZXR0aW5ncy51aV9sb2NhbGVzO1xyXG4gICAgICAgIGFjcl92YWx1ZXMgPSBhY3JfdmFsdWVzIHx8IHRoaXMuX3NldHRpbmdzLmFjcl92YWx1ZXM7XHJcbiAgICAgICAgcmVzb3VyY2UgPSByZXNvdXJjZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNvdXJjZTtcclxuICAgICAgICByZXNwb25zZV9tb2RlID0gcmVzcG9uc2VfbW9kZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlO1xyXG4gICAgICAgIGV4dHJhUXVlcnlQYXJhbXMgPSBleHRyYVF1ZXJ5UGFyYW1zIHx8IHRoaXMuX3NldHRpbmdzLmV4dHJhUXVlcnlQYXJhbXM7XHJcbiAgICAgICAgZXh0cmFUb2tlblBhcmFtcyA9IGV4dHJhVG9rZW5QYXJhbXMgfHwgdGhpcy5fc2V0dGluZ3MuZXh0cmFUb2tlblBhcmFtcztcclxuXHJcbiAgICAgICAgbGV0IGF1dGhvcml0eSA9IHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eTtcclxuXHJcbiAgICAgICAgaWYgKFNpZ25pblJlcXVlc3QuaXNDb2RlKHJlc3BvbnNlX3R5cGUpICYmIHJlc3BvbnNlX3R5cGUgIT09IFwiY29kZVwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJPcGVuSUQgQ29ubmVjdCBoeWJyaWQgZmxvdyBpcyBub3Qgc3VwcG9ydGVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0QXV0aG9yaXphdGlvbkVuZHBvaW50KCkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25pblJlcXVlc3Q6IFJlY2VpdmVkIGF1dGhvcml6YXRpb24gZW5kcG9pbnRcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBzaWduaW5SZXF1ZXN0ID0gbmV3IFNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X2lkLFxyXG4gICAgICAgICAgICAgICAgcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VfdHlwZSxcclxuICAgICAgICAgICAgICAgIHNjb3BlLFxyXG4gICAgICAgICAgICAgICAgZGF0YTogZGF0YSB8fCBzdGF0ZSxcclxuICAgICAgICAgICAgICAgIGF1dGhvcml0eSxcclxuICAgICAgICAgICAgICAgIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcyxcclxuICAgICAgICAgICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCByZXNwb25zZV9tb2RlLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X3NlY3JldDogdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgICAgIHNraXBVc2VySW5mb1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHZhciBzaWduaW5TdGF0ZSA9IHNpZ25pblJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gc3RhdGVTdG9yZS5zZXQoc2lnbmluU3RhdGUuaWQsIHNpZ25pblN0YXRlLnRvU3RvcmFnZVN0cmluZygpKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzaWduaW5SZXF1ZXN0O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbmluUmVzcG9uc2VTdGF0ZSh1cmwsIHN0YXRlU3RvcmUsIHJlbW92ZVN0YXRlID0gZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBsZXQgdXNlUXVlcnkgPSB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlID09PSBcInF1ZXJ5XCIgfHwgXHJcbiAgICAgICAgICAgICghdGhpcy5fc2V0dGluZ3MucmVzcG9uc2VfbW9kZSAmJiBTaWduaW5SZXF1ZXN0LmlzQ29kZSh0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlKSk7XHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9IHVzZVF1ZXJ5ID8gXCI/XCIgOiBcIiNcIjtcclxuXHJcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNpZ25pblJlc3BvbnNlKHVybCwgZGVsaW1pdGVyKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN0YXRlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUFwaSA9IHJlbW92ZVN0YXRlID8gc3RhdGVTdG9yZS5yZW1vdmUuYmluZChzdGF0ZVN0b3JlKSA6IHN0YXRlU3RvcmUuZ2V0LmJpbmQoc3RhdGVTdG9yZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShyZXNwb25zZS5zdGF0ZSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25pblJlc3BvbnNlU3RhdGU6IE5vIG1hdGNoaW5nIHN0YXRlIGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgc3RhdGUgPSBTaWduaW5TdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhzdG9yZWRTdGF0ZVN0cmluZyk7XHJcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGUsIHJlc3BvbnNlfTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcm9jZXNzU2lnbmluUmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCwgc3RhdGVTdG9yZSwgdHJ1ZSkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2U6IFJlY2VpdmVkIHN0YXRlIGZyb20gc3RvcmFnZTsgdmFsaWRhdGluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY3JlYXRlU2lnbm91dFJlcXVlc3Qoe2lkX3Rva2VuX2hpbnQsIGRhdGEsIHN0YXRlLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSB9ID0ge30sXHJcbiAgICAgICAgc3RhdGVTdG9yZVxyXG4gICAgKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5jcmVhdGVTaWdub3V0UmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zID0gZXh0cmFRdWVyeVBhcmFtcyB8fCB0aGlzLl9zZXR0aW5ncy5leHRyYVF1ZXJ5UGFyYW1zO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldEVuZFNlc3Npb25FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IE5vIGVuZCBzZXNzaW9uIGVuZHBvaW50IHVybCByZXR1cm5lZFwiKTtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vIGVuZCBzZXNzaW9uIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25vdXRSZXF1ZXN0OiBSZWNlaXZlZCBlbmQgc2Vzc2lvbiBlbmRwb2ludFwiLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgU2lnbm91dFJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgaWRfdG9rZW5faGludCxcclxuICAgICAgICAgICAgICAgIHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEgfHwgc3RhdGUsXHJcbiAgICAgICAgICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zLFxyXG4gICAgICAgICAgICAgICAgcmVxdWVzdF90eXBlXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdmFyIHNpZ25vdXRTdGF0ZSA9IHJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIGlmIChzaWdub3V0U3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IFNpZ25vdXQgcmVxdWVzdCBoYXMgc3RhdGUgdG8gcGVyc2lzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG4gICAgICAgICAgICAgICAgc3RhdGVTdG9yZS5zZXQoc2lnbm91dFN0YXRlLmlkLCBzaWdub3V0U3RhdGUudG9TdG9yYWdlU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCByZW1vdmVTdGF0ZSA9IGZhbHNlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGVcIik7XHJcblxyXG4gICAgICAgIHZhciByZXNwb25zZSA9IG5ldyBTaWdub3V0UmVzcG9uc2UodXJsKTtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLndhcm4oXCJPaWRjQ2xpZW50LnJlYWRTaWdub3V0UmVzcG9uc2VTdGF0ZTogUmVzcG9uc2Ugd2FzIGVycm9yOiBcIiwgcmVzcG9uc2UuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe3VuZGVmaW5lZCwgcmVzcG9uc2V9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUtleSA9IHJlc3BvbnNlLnN0YXRlO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICB2YXIgc3RhdGVBcGkgPSByZW1vdmVTdGF0ZSA/IHN0YXRlU3RvcmUucmVtb3ZlLmJpbmQoc3RhdGVTdG9yZSkgOiBzdGF0ZVN0b3JlLmdldC5iaW5kKHN0YXRlU3RvcmUpO1xyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShzdGF0ZUtleSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWF0Y2hpbmcgc3RhdGUgZm91bmQgaW4gc3RvcmFnZVwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IHN0YXRlID0gU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmVkU3RhdGVTdHJpbmcpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtzdGF0ZSwgcmVzcG9uc2V9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCB0cnVlKS50aGVuKCh7c3RhdGUsIHJlc3BvbnNlfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoc3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucHJvY2Vzc1NpZ25vdXRSZXNwb25zZTogUmVjZWl2ZWQgc3RhdGUgZnJvbSBzdG9yYWdlOyB2YWxpZGF0aW5nIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlOiBObyBzdGF0ZSBmcm9tIHN0b3JhZ2U7IHNraXBwaW5nIHZhbGlkYXRpbmcgcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhclN0YWxlU3RhdGUoc3RhdGVTdG9yZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY2xlYXJTdGFsZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICByZXR1cm4gU3RhdGUuY2xlYXJTdGFsZVN0YXRlKHN0YXRlU3RvcmUsIHRoaXMuc2V0dGluZ3Muc3RhbGVTdGF0ZUFnZSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB9IGZyb20gJy4vV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMnO1xyXG5pbXBvcnQgeyBSZXNwb25zZVZhbGlkYXRvciB9IGZyb20gJy4vUmVzcG9uc2VWYWxpZGF0b3IuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmNvbnN0IERlZmF1bHRSZXNwb25zZVR5cGUgPSBcImlkX3Rva2VuXCI7XHJcbmNvbnN0IERlZmF1bHRTY29wZSA9IFwib3BlbmlkXCI7XHJcbmNvbnN0IERlZmF1bHRTdGFsZVN0YXRlQWdlID0gNjAgKiAxNTsgLy8gc2Vjb25kc1xyXG5jb25zdCBEZWZhdWx0Q2xvY2tTa2V3SW5TZWNvbmRzID0gNjAgKiA1O1xyXG5cclxuZXhwb3J0IGNsYXNzIE9pZGNDbGllbnRTZXR0aW5ncyB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWV0YWRhdGEgcmVsYXRlZFxyXG4gICAgICAgIGF1dGhvcml0eSwgbWV0YWRhdGFVcmwsIG1ldGFkYXRhLCBzaWduaW5nS2V5cyxcclxuICAgICAgICAvLyBjbGllbnQgcmVsYXRlZFxyXG4gICAgICAgIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgcmVzcG9uc2VfdHlwZSA9IERlZmF1bHRSZXNwb25zZVR5cGUsIHNjb3BlID0gRGVmYXVsdFNjb3BlLFxyXG4gICAgICAgIHJlZGlyZWN0X3VyaSwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIC8vIG9wdGlvbmFsIHByb3RvY29sXHJcbiAgICAgICAgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBhY3JfdmFsdWVzLCByZXNvdXJjZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAvLyBiZWhhdmlvciBmbGFnc1xyXG4gICAgICAgIGZpbHRlclByb3RvY29sQ2xhaW1zID0gdHJ1ZSwgbG9hZFVzZXJJbmZvID0gdHJ1ZSxcclxuICAgICAgICBzdGFsZVN0YXRlQWdlID0gRGVmYXVsdFN0YWxlU3RhdGVBZ2UsIGNsb2NrU2tldyA9IERlZmF1bHRDbG9ja1NrZXdJblNlY29uZHMsXHJcbiAgICAgICAgdXNlckluZm9Kd3RJc3N1ZXIgPSAnT1AnLFxyXG4gICAgICAgIC8vIG90aGVyIGJlaGF2aW9yXHJcbiAgICAgICAgc3RhdGVTdG9yZSA9IG5ldyBXZWJTdG9yYWdlU3RhdGVTdG9yZSgpLFxyXG4gICAgICAgIFJlc3BvbnNlVmFsaWRhdG9yQ3RvciA9IFJlc3BvbnNlVmFsaWRhdG9yLFxyXG4gICAgICAgIE1ldGFkYXRhU2VydmljZUN0b3IgPSBNZXRhZGF0YVNlcnZpY2UsXHJcbiAgICAgICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICAgICAgZXh0cmFRdWVyeVBhcmFtcyA9IHt9LFxyXG4gICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgPSB7fVxyXG4gICAgfSA9IHt9KSB7XHJcblxyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IG1ldGFkYXRhVXJsO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gbWV0YWRhdGE7XHJcbiAgICAgICAgdGhpcy5fc2lnbmluZ0tleXMgPSBzaWduaW5nS2V5cztcclxuXHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX2NsaWVudF9zZWNyZXQgPSBjbGllbnRfc2VjcmV0O1xyXG4gICAgICAgIHRoaXMuX3Jlc3BvbnNlX3R5cGUgPSByZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHRoaXMuX3Njb3BlID0gc2NvcGU7XHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSA9IHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5fcHJvbXB0ID0gcHJvbXB0O1xyXG4gICAgICAgIHRoaXMuX2Rpc3BsYXkgPSBkaXNwbGF5O1xyXG4gICAgICAgIHRoaXMuX21heF9hZ2UgPSBtYXhfYWdlO1xyXG4gICAgICAgIHRoaXMuX3VpX2xvY2FsZXMgPSB1aV9sb2NhbGVzO1xyXG4gICAgICAgIHRoaXMuX2Fjcl92YWx1ZXMgPSBhY3JfdmFsdWVzO1xyXG4gICAgICAgIHRoaXMuX3Jlc291cmNlID0gcmVzb3VyY2U7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZpbHRlclByb3RvY29sQ2xhaW1zID0gISFmaWx0ZXJQcm90b2NvbENsYWltcztcclxuICAgICAgICB0aGlzLl9sb2FkVXNlckluZm8gPSAhIWxvYWRVc2VySW5mbztcclxuICAgICAgICB0aGlzLl9zdGFsZVN0YXRlQWdlID0gc3RhbGVTdGF0ZUFnZTtcclxuICAgICAgICB0aGlzLl9jbG9ja1NrZXcgPSBjbG9ja1NrZXc7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXIgPSB1c2VySW5mb0p3dElzc3VlcjtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RhdGVTdG9yZSA9IHN0YXRlU3RvcmU7XHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yID0gbmV3IFJlc3BvbnNlVmFsaWRhdG9yQ3Rvcih0aGlzKTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHR5cGVvZiBleHRyYVF1ZXJ5UGFyYW1zID09PSAnb2JqZWN0JyA/IGV4dHJhUXVlcnlQYXJhbXMgOiB7fTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gdHlwZW9mIGV4dHJhVG9rZW5QYXJhbXMgPT09ICdvYmplY3QnID8gZXh0cmFUb2tlblBhcmFtcyA6IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGNsaWVudCBjb25maWdcclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIHNldCBjbGllbnRfaWQodmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NsaWVudF9pZCkge1xyXG4gICAgICAgICAgICAvLyBvbmUtdGltZSBzZXQgb25seVxyXG4gICAgICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnRTZXR0aW5ncy5zZXRfY2xpZW50X2lkOiBjbGllbnRfaWQgaGFzIGFscmVhZHkgYmVlbiBhc3NpZ25lZC5cIilcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkIGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzcG9uc2VfdHlwZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVzcG9uc2VfdHlwZTtcclxuICAgIH1cclxuICAgIGdldCBzY29wZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2NvcGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG9wdGlvbmFsIHByb3RvY29sIHBhcmFtc1xyXG4gICAgZ2V0IHByb21wdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbXB0O1xyXG4gICAgfVxyXG4gICAgZ2V0IGRpc3BsYXkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3BsYXk7XHJcbiAgICB9XHJcbiAgICBnZXQgbWF4X2FnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWF4X2FnZTtcclxuICAgIH1cclxuICAgIGdldCB1aV9sb2NhbGVzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl91aV9sb2NhbGVzO1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjcl92YWx1ZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Fjcl92YWx1ZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzb3VyY2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc291cmNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IHJlc3BvbnNlX21vZGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc3BvbnNlX21vZGU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG1ldGFkYXRhXHJcbiAgICBnZXQgYXV0aG9yaXR5KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hdXRob3JpdHk7XHJcbiAgICB9XHJcbiAgICBzZXQgYXV0aG9yaXR5KHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgLy8gb25lLXRpbWUgc2V0IG9ubHlcclxuICAgICAgICAgICAgdGhpcy5fYXV0aG9yaXR5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50U2V0dGluZ3Muc2V0X2F1dGhvcml0eTogYXV0aG9yaXR5IGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eSBoYXMgYWxyZWFkeSBiZWVuIGFzc2lnbmVkLlwiKVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBtZXRhZGF0YVVybCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX21ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhVXJsID0gdGhpcy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5fbWV0YWRhdGFVcmwgJiYgdGhpcy5fbWV0YWRhdGFVcmwuaW5kZXhPZihPaWRjTWV0YWRhdGFVcmxQYXRoKSA8IDApIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9tZXRhZGF0YVVybFt0aGlzLl9tZXRhZGF0YVVybC5sZW5ndGggLSAxXSAhPT0gJy8nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gT2lkY01ldGFkYXRhVXJsUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhVXJsO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHNldHRhYmxlL2NhY2hhYmxlIG1ldGFkYXRhIHZhbHVlc1xyXG4gICAgZ2V0IG1ldGFkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YTtcclxuICAgIH1cclxuICAgIHNldCBtZXRhZGF0YSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5nS2V5cztcclxuICAgIH1cclxuICAgIHNldCBzaWduaW5nS2V5cyh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX3NpZ25pbmdLZXlzID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYmVoYXZpb3IgZmxhZ3NcclxuICAgIGdldCBmaWx0ZXJQcm90b2NvbENsYWltcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyUHJvdG9jb2xDbGFpbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgbG9hZFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBnZXQgc3RhbGVTdGF0ZUFnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhbGVTdGF0ZUFnZTtcclxuICAgIH1cclxuICAgIGdldCBjbG9ja1NrZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrU2tldztcclxuICAgIH1cclxuICAgIGdldCB1c2VySW5mb0p3dElzc3VlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHN0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlU3RvcmU7XHJcbiAgICB9XHJcbiAgICBnZXQgdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICBnZXQgZXh0cmFRdWVyeVBhcmFtcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZXh0cmFRdWVyeVBhcmFtcztcclxuICAgIH1cclxuICAgIHNldCBleHRyYVF1ZXJ5UGFyYW1zKHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpe1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVF1ZXJ5UGFyYW1zID0gdmFsdWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHt9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBleHRyYSB0b2tlbiBwYXJhbXNcclxuICAgIGdldCBleHRyYVRva2VuUGFyYW1zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHRyYVRva2VuUGFyYW1zO1xyXG4gICAgfVxyXG4gICAgc2V0IGV4dHJhVG9rZW5QYXJhbXModmFsdWUpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jyl7XHJcbiAgICAgICAgICAgIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXMgPSB2YWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0ge307XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgUG9wdXBXaW5kb3cgfSBmcm9tICcuL1BvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBQb3B1cE5hdmlnYXRvciB7XHJcblxyXG4gICAgcHJlcGFyZShwYXJhbXMpIHtcclxuICAgICAgICBsZXQgcG9wdXAgPSBuZXcgUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwsIGtlZXBPcGVuLCBkZWxpbWl0ZXIpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cE5hdmlnYXRvci5jYWxsYmFja1wiKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgUG9wdXBXaW5kb3cubm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgQ2hlY2tGb3JQb3B1cENsb3NlZEludGVydmFsID0gNTAwO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7JztcclxuLy9jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7cmVzaXphYmxlPXllcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFBvcHVwV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsZXQgdGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBsZXQgZmVhdHVyZXMgPSBwYXJhbXMucG9wdXBXaW5kb3dGZWF0dXJlcyB8fCBEZWZhdWx0UG9wdXBGZWF0dXJlcztcclxuXHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSB3aW5kb3cub3BlbignJywgdGFyZ2V0LCBmZWF0dXJlcyk7XHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmN0b3I6IHBvcHVwIHN1Y2Nlc3NmdWxseSBjcmVhdGVkXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSB3aW5kb3cuc2V0SW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZC5iaW5kKHRoaXMpLCBDaGVja0ZvclBvcHVwQ2xvc2VkSW50ZXJ2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgcHJvbWlzZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICBuYXZpZ2F0ZShwYXJhbXMpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IEVycm9yIG9wZW5pbmcgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IG5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJObyB1cmwgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5uYXZpZ2F0ZTogU2V0dGluZyBVUkwgaW4gcG9wdXBcIik7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9pZCA9IHBhcmFtcy5pZDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lkKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3dbXCJwb3B1cENhbGxiYWNrX1wiICsgcGFyYW1zLmlkXSA9IHRoaXMuX2NhbGxiYWNrLmJpbmQodGhpcyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLndpbmRvdy5sb2NhdGlvbiA9IHBhcmFtcy51cmw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5jYWxsYmFjazogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIHBvcHVwIHdpbmRvd1wiKTtcclxuXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIExvZy5lcnJvcihcIlBvcHVwV2luZG93LmVycm9yOiBcIiwgbWVzc2FnZSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIF9jbGVhbnVwKGtlZXBPcGVuKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUG9wdXBXaW5kb3cuY2xlYW51cFwiKTtcclxuXHJcbiAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZFRpbWVyKTtcclxuICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSBudWxsO1xyXG5cclxuICAgICAgICBkZWxldGUgd2luZG93W1wicG9wdXBDYWxsYmFja19cIiArIHRoaXMuX2lkXTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwICYmICFrZWVwT3Blbikge1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5jbG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9wb3B1cCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgX2NoZWNrRm9yUG9wdXBDbG9zZWQoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9wb3B1cCB8fCB0aGlzLl9wb3B1cC5jbG9zZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJQb3B1cCB3aW5kb3cgY2xvc2VkXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfY2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoa2VlcE9wZW4pO1xyXG5cclxuICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrIHN1Y2Nlc3NcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX3N1Y2Nlc3MoeyB1cmw6IHVybCB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrOiBJbnZhbGlkIHJlc3BvbnNlIGZyb20gcG9wdXBcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiSW52YWxpZCByZXNwb25zZSBmcm9tIHBvcHVwXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgbm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcikge1xyXG4gICAgICAgIGlmICh3aW5kb3cub3BlbmVyKSB7XHJcbiAgICAgICAgICAgIHVybCA9IHVybCB8fCB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWUgPSBcInBvcHVwQ2FsbGJhY2tfXCIgKyBkYXRhLnN0YXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IHdpbmRvdy5vcGVuZXJbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogcGFzc2luZyB1cmwgbWVzc2FnZSB0byBvcGVuZXJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJQb3B1cFdpbmRvdy5ub3RpZnlPcGVuZXI6IG5vIG1hdGNoaW5nIGNhbGxiYWNrIGZvdW5kIG9uIG9wZW5lclwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gc3RhdGUgZm91bmQgaW4gcmVzcG9uc2UgdXJsXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gd2luZG93Lm9wZW5lci4gQ2FuJ3QgY29tcGxldGUgbm90aWZpY2F0aW9uLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlZGlyZWN0TmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKCkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgbmF2aWdhdGUocGFyYW1zKSB7XHJcbiAgICAgICAgaWYgKCFwYXJhbXMgfHwgIXBhcmFtcy51cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVkaXJlY3ROYXZpZ2F0b3IubmF2aWdhdGU6IE5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHVybCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyYW1zLnVzZVJlcGxhY2VUb05hdmlnYXRlKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHBhcmFtcy51cmwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdXJsKCkge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgVXNlckluZm9TZXJ2aWNlIH0gZnJvbSAnLi9Vc2VySW5mb1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBUb2tlbkNsaWVudCB9IGZyb20gJy4vVG9rZW5DbGllbnQuanMnO1xyXG5pbXBvcnQgeyBFcnJvclJlc3BvbnNlIH0gZnJvbSAnLi9FcnJvclJlc3BvbnNlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmNvbnN0IFByb3RvY29sQ2xhaW1zID0gW1wibm9uY2VcIiwgXCJhdF9oYXNoXCIsIFwiaWF0XCIsIFwibmJmXCIsIFwiZXhwXCIsIFwiYXVkXCIsIFwiaXNzXCIsIFwiY19oYXNoXCJdO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlc3BvbnNlVmFsaWRhdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgXHJcbiAgICAgICAgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSxcclxuICAgICAgICBVc2VySW5mb1NlcnZpY2VDdG9yID0gVXNlckluZm9TZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsLFxyXG4gICAgICAgIFRva2VuQ2xpZW50Q3RvciA9IFRva2VuQ2xpZW50KSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWQgdG8gUmVzcG9uc2VWYWxpZGF0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9TZXJ2aWNlID0gbmV3IFVzZXJJbmZvU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICAgICAgdGhpcy5fdG9rZW5DbGllbnQgPSBuZXcgVG9rZW5DbGllbnRDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzU2lnbmluUGFyYW1zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2U6IHN0YXRlIHByb2Nlc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlVG9rZW5zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiB0b2tlbnMgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3NDbGFpbXMoc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiBjbGFpbXMgcHJvY2Vzc2VkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoc3RhdGUuaWQgIT09IHJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbm91dFJlc3BvbnNlOiBTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlN0YXRlIGRvZXMgbm90IG1hdGNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG5vdyB0aGF0IHdlIGtub3cgdGhlIHN0YXRlIG1hdGNoZXMsIHRha2UgdGhlIHN0b3JlZCBkYXRhXHJcbiAgICAgICAgLy8gYW5kIHNldCBpdCBpbnRvIHRoZSByZXNwb25zZSBzbyBjYWxsZXJzIGNhbiBnZXQgdGhlaXIgc3RhdGVcclxuICAgICAgICAvLyB0aGlzIGlzIGltcG9ydGFudCBmb3IgYm90aCBzdWNjZXNzICYgZXJyb3Igb3V0Y29tZXNcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZTogc3RhdGUgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgIHJlc3BvbnNlLnN0YXRlID0gc3RhdGUuZGF0YTtcclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmVycm9yKSB7XHJcbiAgICAgICAgICAgIExvZy53YXJuKFwiUmVzcG9uc2VWYWxpZGF0b3IudmFsaWRhdGVTaWdub3V0UmVzcG9uc2U6IFJlc3BvbnNlIHdhcyBlcnJvclwiLCByZXNwb25zZS5lcnJvcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3JSZXNwb25zZShyZXNwb25zZSkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NTaWduaW5QYXJhbXMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHN0YXRlLmlkICE9PSByZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogU3RhdGUgZG9lcyBub3QgbWF0Y2hcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuYXV0aG9yaXR5KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBObyBhdXRob3JpdHkgb24gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb24gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gdGhpcyBhbGxvd3MgdGhlIGF1dGhvcml0eSB0byBiZSBsb2FkZWQgZnJvbSB0aGUgc2lnbmluIHN0YXRlXHJcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MuYXV0aG9yaXR5ID0gc3RhdGUuYXV0aG9yaXR5O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBlbnN1cmUgd2UncmUgdXNpbmcgdGhlIGNvcnJlY3QgYXV0aG9yaXR5IGlmIHRoZSBhdXRob3JpdHkgaXMgbm90IGxvYWRlZCBmcm9tIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eSAmJiB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkgIT09IHN0YXRlLmF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogYXV0aG9yaXR5IG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJhdXRob3JpdHkgbWlzbWF0Y2ggb24gc2V0dGluZ3MgdnMuIHNpZ25pbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRoaXMgYWxsb3dzIHRoZSBjbGllbnRfaWQgdG8gYmUgbG9hZGVkIGZyb20gdGhlIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZCA9IHN0YXRlLmNsaWVudF9pZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZW5zdXJlIHdlJ3JlIHVzaW5nIHRoZSBjb3JyZWN0IGNsaWVudF9pZCBpZiB0aGUgY2xpZW50X2lkIGlzIG5vdCBsb2FkZWQgZnJvbSBzaWduaW4gc3RhdGVcclxuICAgICAgICBlbHNlIGlmICh0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQgJiYgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkICE9PSBzdGF0ZS5jbGllbnRfaWQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NTaWduaW5QYXJhbXM6IGNsaWVudF9pZCBtaXNtYXRjaCBvbiBzZXR0aW5ncyB2cy4gc2lnbmluIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiY2xpZW50X2lkIG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gbm93IHRoYXQgd2Uga25vdyB0aGUgc3RhdGUgbWF0Y2hlcywgdGFrZSB0aGUgc3RvcmVkIGRhdGFcclxuICAgICAgICAvLyBhbmQgc2V0IGl0IGludG8gdGhlIHJlc3BvbnNlIHNvIGNhbGxlcnMgY2FuIGdldCB0aGVpciBzdGF0ZVxyXG4gICAgICAgIC8vIHRoaXMgaXMgaW1wb3J0YW50IGZvciBib3RoIHN1Y2Nlc3MgJiBlcnJvciBvdXRjb21lc1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBzdGF0ZSB2YWxpZGF0ZWRcIik7XHJcbiAgICAgICAgcmVzcG9uc2Uuc3RhdGUgPSBzdGF0ZS5kYXRhO1xyXG5cclxuICAgICAgICBpZiAocmVzcG9uc2UuZXJyb3IpIHtcclxuICAgICAgICAgICAgTG9nLndhcm4oXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogUmVzcG9uc2Ugd2FzIGVycm9yXCIsIHJlc3BvbnNlLmVycm9yKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUubm9uY2UgJiYgIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBFeHBlY3RpbmcgaWRfdG9rZW4gaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLm5vbmNlICYmIHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGlkX3Rva2VuIGluIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5leHBlY3RlZCBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUuY29kZV92ZXJpZmllciAmJiAhcmVzcG9uc2UuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogRXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBjb2RlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuY29kZV92ZXJpZmllciAmJiByZXNwb25zZS5jb2RlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGNvZGUgaW4gcmVzcG9uc2VcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zY29wZSkge1xyXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSdzIG5vIHNjb3BlIG9uIHRoZSByZXNwb25zZSwgdGhlbiBhc3N1bWUgYWxsIHNjb3BlcyBncmFudGVkIChwZXItc3BlYykgYW5kIGNvcHkgb3ZlciBzY29wZXMgZnJvbSBvcmlnaW5hbCByZXF1ZXN0XHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnNjb3BlID0gc3RhdGUuc2NvcGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcHJvY2Vzc0NsYWltcyhzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAocmVzcG9uc2UuaXNPcGVuSWRDb25uZWN0KSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiByZXNwb25zZSBpcyBPSURDLCBwcm9jZXNzaW5nIGNsYWltc1wiKTtcclxuXHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnByb2ZpbGUgPSB0aGlzLl9maWx0ZXJQcm90b2NvbENsYWltcyhyZXNwb25zZS5wcm9maWxlKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5za2lwVXNlckluZm8gIT09IHRydWUgJiYgdGhpcy5fc2V0dGluZ3MubG9hZFVzZXJJbmZvICYmIHJlc3BvbnNlLmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IGxvYWRpbmcgdXNlciBpbmZvXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zKHJlc3BvbnNlLmFjY2Vzc190b2tlbikudGhlbihjbGFpbXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiB1c2VyIGluZm8gY2xhaW1zIHJlY2VpdmVkIGZyb20gdXNlciBpbmZvIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xhaW1zLnN1YiAhPT0gcmVzcG9uc2UucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHN1YiBmcm9tIHVzZXIgaW5mbyBlbmRwb2ludCBkb2VzIG5vdCBtYXRjaCBzdWIgaW4gYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic3ViIGZyb20gdXNlciBpbmZvIGVuZHBvaW50IGRvZXMgbm90IG1hdGNoIHN1YiBpbiBhY2Nlc3NfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UucHJvZmlsZSA9IHRoaXMuX21lcmdlQ2xhaW1zKHJlc3BvbnNlLnByb2ZpbGUsIGNsYWltcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHVzZXIgaW5mbyBjbGFpbXMgcmVjZWl2ZWQsIHVwZGF0ZWQgcHJvZmlsZTpcIiwgcmVzcG9uc2UucHJvZmlsZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IG5vdCBsb2FkaW5nIHVzZXIgaW5mb1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHJlc3BvbnNlIGlzIG5vdCBPSURDLCBub3QgcHJvY2Vzc2luZyBjbGFpbXNcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfbWVyZ2VDbGFpbXMoY2xhaW1zMSwgY2xhaW1zMikge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSBPYmplY3QuYXNzaWduKHt9LCBjbGFpbXMxKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBjbGFpbXMyKSB7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBjbGFpbXMyW25hbWVdO1xyXG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzID0gW3ZhbHVlc107XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSB2YWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdFtuYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRbbmFtZV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtuYW1lXS5pbmRleE9mKHZhbHVlKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W25hbWVdLnB1c2godmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdFtuYW1lXSAhPT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSB0aGlzLl9tZXJnZUNsYWltcyhyZXN1bHRbbmFtZV0sIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSBbcmVzdWx0W25hbWVdLCB2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIF9maWx0ZXJQcm90b2NvbENsYWltcyhjbGFpbXMpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyUHJvdG9jb2xDbGFpbXMsIGluY29taW5nIGNsYWltczpcIiwgY2xhaW1zKTtcclxuXHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oe30sIGNsYWltcyk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5fZmlsdGVyUHJvdG9jb2xDbGFpbXMpIHtcclxuICAgICAgICAgICAgUHJvdG9jb2xDbGFpbXMuZm9yRWFjaCh0eXBlID0+IHtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRbdHlwZV07XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlclByb3RvY29sQ2xhaW1zOiBwcm90b2NvbCBjbGFpbXMgZmlsdGVyZWRcIiwgcmVzdWx0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJQcm90b2NvbENsYWltczogcHJvdG9jb2wgY2xhaW1zIG5vdCBmaWx0ZXJlZFwiKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBfdmFsaWRhdGVUb2tlbnMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmNvZGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBWYWxpZGF0aW5nIGNvZGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzQ29kZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5hY2Nlc3NfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlbiBhbmQgYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbihzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBObyBjb2RlIHRvIHByb2Nlc3Mgb3IgaWRfdG9rZW4gdG8gdmFsaWRhdGVcIik7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NDb2RlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHZhciByZXF1ZXN0ID0ge1xyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHN0YXRlLmNsaWVudF9pZCxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldDogc3RhdGUuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgY29kZSA6IHJlc3BvbnNlLmNvZGUsXHJcbiAgICAgICAgICAgIHJlZGlyZWN0X3VyaTogc3RhdGUucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBjb2RlX3ZlcmlmaWVyOiBzdGF0ZS5jb2RlX3ZlcmlmaWVyXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMgJiYgdHlwZW9mKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHJlcXVlc3QsIHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5DbGllbnQuZXhjaGFuZ2VDb2RlKHJlcXVlc3QpLnRoZW4odG9rZW5SZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBmb3IodmFyIGtleSBpbiB0b2tlblJlc3BvbnNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gdG9rZW5SZXNwb25zZVtrZXldO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuaWRfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ29kZTogdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc2Z1bCwgcHJvY2Vzc2luZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc0NvZGU6IHRva2VuIHJlc3BvbnNlIHN1Y2Nlc3NmdWwsIHJldHVybmluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCkudGhlbihpc3N1ZXIgPT4ge1xyXG5cclxuICAgICAgICAgICAgbGV0IGF1ZGllbmNlID0gc3RhdGUuY2xpZW50X2lkO1xyXG4gICAgICAgICAgICBsZXQgY2xvY2tTa2V3SW5TZWNvbmRzID0gdGhpcy5fc2V0dGluZ3MuY2xvY2tTa2V3O1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogVmFsaWRhaW5nIEpXVCBhdHRyaWJ1dGVzOyB1c2luZyBjbG9jayBza2V3IChpbiBzZWNvbmRzKSBvZjogXCIsIGNsb2NrU2tld0luU2Vjb25kcyk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3RBdHRyaWJ1dGVzKHJlc3BvbnNlLmlkX3Rva2VuLCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXdJblNlY29uZHMpLnRoZW4ocGF5bG9hZCA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLm5vbmNlICYmIHN0YXRlLm5vbmNlICE9PSBwYXlsb2FkLm5vbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbkF0dHJpYnV0ZXM6IEludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN1YiBwcmVzZW50IGluIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gcGF5bG9hZDtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKCFzdGF0ZS5ub25jZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBub25jZSBvbiBzdGF0ZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIG5vbmNlIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzdGF0ZS5ub25jZSAhPT0gand0LnBheWxvYWQubm9uY2UpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSW52YWxpZCBub25jZSBpbiBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGtpZCA9IGp3dC5oZWFkZXIua2lkO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogUmVjZWl2ZWQgaXNzdWVyXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5cygpLnRoZW4oa2V5cyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gc2lnbmluZyBrZXlzIGZyb20gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFJlY2VpdmVkIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleXMgPSB0aGlzLl9maWx0ZXJCeUFsZyhrZXlzLCBqd3QuaGVhZGVyLmFsZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGtpZCBmb3VuZCBpbiBpZF90b2tlbiBhbmQgbW9yZSB0aGFuIG9uZSBrZXkgZm91bmQgaW4gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8ga2lkIGlzIG1hbmRhdG9yeSBvbmx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIGtleXMgaW4gdGhlIHJlZmVyZW5jZWQgSldLIFNldCBkb2N1bWVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cDovL29wZW5pZC5uZXQvc3BlY3Mvb3BlbmlkLWNvbm5lY3QtY29yZS0xXzAuaHRtbCNTaWduaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5cy5maWx0ZXIoa2V5ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5raWQgPT09IGtpZDtcclxuICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IE5vIGtleSBtYXRjaGluZyBraWQgb3IgYWxnIGZvdW5kIGluIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgYXVkaWVuY2UgPSBzdGF0ZS5jbGllbnRfaWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3QocmVzcG9uc2UuaWRfdG9rZW4sIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzKS50aGVuKCgpPT57XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSldUIHZhbGlkYXRpb24gc3VjY2Vzc2Z1bFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqd3QucGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzdWIgcHJlc2VudCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gand0LnBheWxvYWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKXtcclxuICAgICAgICB2YXIga3R5ID0gbnVsbDtcclxuICAgICAgICBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJSU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlJTQVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChhbGcuc3RhcnRzV2l0aChcIlBTXCIpKSB7XHJcbiAgICAgICAgICAgIGt0eSA9IFwiUFNcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJFU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIkVDXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyQnlBbGc6IGFsZyBub3Qgc3VwcG9ydGVkOiBcIiwgYWxnKTtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJCeUFsZzogTnVtYmVyIG9mIGtleXMgdGhhdCBtYXRjaCBrdHk6IFwiLCBrdHksIGtleXMubGVuZ3RoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGtleXM7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnByb2ZpbGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IE5vIHByb2ZpbGUgbG9hZGVkIGZyb20gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBwcm9maWxlIGxvYWRlZCBmcm9tIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBhdF9oYXNoIGluIGlkX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gYXRfaGFzaCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQWxnID0gand0LmhlYWRlci5hbGc7XHJcbiAgICAgICAgaWYgKCFoYXNoQWxnIHx8IGhhc2hBbGcubGVuZ3RoICE9PSA1KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBVbnN1cHBvcnRlZCBhbGc6XCIsIGhhc2hBbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQml0cyA9IGhhc2hBbGcuc3Vic3RyKDIsIDMpO1xyXG4gICAgICAgIGlmICghaGFzaEJpdHMpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IFVuc3VwcG9ydGVkIGFsZzpcIiwgaGFzaEFsZywgaGFzaEJpdHMpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGhhc2hCaXRzID0gcGFyc2VJbnQoaGFzaEJpdHMpO1xyXG4gICAgICAgIGlmIChoYXNoQml0cyAhPT0gMjU2ICYmIGhhc2hCaXRzICE9PSAzODQgJiYgaGFzaEJpdHMgIT09IDUxMikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogVW5zdXBwb3J0ZWQgYWxnOlwiLCBoYXNoQWxnLCBoYXNoQml0cyk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBhbGc6IFwiICsgaGFzaEFsZykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHNoYSA9IFwic2hhXCIgKyBoYXNoQml0cztcclxuICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2pvc2VVdGlsLmhhc2hTdHJpbmcocmVzcG9uc2UuYWNjZXNzX3Rva2VuLCBzaGEpO1xyXG4gICAgICAgIGlmICghaGFzaCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogYWNjZXNzX3Rva2VuIGhhc2ggZmFpbGVkOlwiLCBzaGEpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGF0X2hhc2hcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGxlZnQgPSBoYXNoLnN1YnN0cigwLCBoYXNoLmxlbmd0aCAvIDIpO1xyXG4gICAgICAgIHZhciBsZWZ0X2I2NHUgPSB0aGlzLl9qb3NlVXRpbC5oZXhUb0Jhc2U2NFVybChsZWZ0KTtcclxuICAgICAgICBpZiAobGVmdF9iNjR1ICE9PSByZXNwb25zZS5wcm9maWxlLmF0X2hhc2gpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIsIGxlZnRfYjY0dSwgcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBzdWNjZXNzXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IENoZWNrU2Vzc2lvbklGcmFtZSB9IGZyb20gJy4vQ2hlY2tTZXNzaW9uSUZyYW1lLmpzJztcclxuaW1wb3J0IHsgR2xvYmFsIH0gZnJvbSAnLi9HbG9iYWwuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNlc3Npb25Nb25pdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih1c2VyTWFuYWdlciwgQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvciA9IENoZWNrU2Vzc2lvbklGcmFtZSwgdGltZXIgPSBHbG9iYWwudGltZXIpIHtcclxuICAgICAgICBpZiAoIXVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLmN0b3I6IE5vIHVzZXIgbWFuYWdlciBwYXNzZWQgdG8gU2Vzc2lvbk1vbml0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVzZXJNYW5hZ2VyXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgICAgICB0aGlzLl9DaGVja1Nlc3Npb25JRnJhbWVDdG9yID0gQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvcjtcclxuICAgICAgICB0aGlzLl90aW1lciA9IHRpbWVyO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlckxvYWRlZCh0aGlzLl9zdGFydC5iaW5kKHRoaXMpKTtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlclVubG9hZGVkKHRoaXMuX3N0b3AuYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICAvLyBkb2luZyB0aGlzIG1hbnVhbGx5IGhlcmUgc2luY2UgY2FsbGluZyBnZXRVc2VyIFxyXG4gICAgICAgICAgICAvLyBkb2Vzbid0IHRyaWdnZXIgbG9hZCBldmVudC5cclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHVzZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLm1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXMoKS50aGVuKHNlc3Npb24gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0bXBVc2VyID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uX3N0YXRlIDogc2Vzc2lvbi5zZXNzaW9uX3N0YXRlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgJiYgc2Vzc2lvbi5zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG1wVXNlci5wcm9maWxlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViOiBzZXNzaW9uLnN1YixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2Vzc2lvbi5zaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodG1wVXNlcik7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yIGN0b3I6IGVycm9yIGZyb20gcXVlcnlTZXNzaW9uU3RhdHVzOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBhIGN0b3JcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2Vzc2lvbk1vbml0b3IgY3RvcjogZXJyb3IgZnJvbSBnZXRVc2VyOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IF9zZXR0aW5ncygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIuc2V0dGluZ3M7XHJcbiAgICB9XHJcbiAgICBnZXQgX21ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIubWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9jbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCBfY2hlY2tTZXNzaW9uSW50ZXJ2YWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9zdG9wQ2hlY2tTZXNzaW9uT25FcnJvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3Muc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgX3N0YXJ0KHVzZXIpIHtcclxuICAgICAgICBsZXQgc2Vzc2lvbl9zdGF0ZSA9IHVzZXIuc2Vzc2lvbl9zdGF0ZTtcclxuXHJcbiAgICAgICAgaWYgKHNlc3Npb25fc3RhdGUpIHtcclxuICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3ViID0gdXNlci5wcm9maWxlLnN1YjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NpZCA9IHVzZXIucHJvZmlsZS5zaWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBzdWI6XCIsIHRoaXMuX3N1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWIgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBhbm9ueW1vdXMgdXNlclwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRDaGVja1Nlc3Npb25JZnJhbWUoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IEluaXRpYWxpemluZyBjaGVjayBzZXNzaW9uIGlmcmFtZVwiKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX2NsaWVudF9pZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGludGVydmFsID0gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdG9wT25FcnJvciA9IHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lID0gbmV3IHRoaXMuX0NoZWNrU2Vzc2lvbklGcmFtZUN0b3IodGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKSwgY2xpZW50X2lkLCB1cmwsIGludGVydmFsLCBzdG9wT25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5sb2FkKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IE5vIGNoZWNrIHNlc3Npb24gaWZyYW1lIGZvdW5kIGluIHRoZSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBub24tcHJvbWlzZSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLl9zdGFydDogRXJyb3IgZnJvbSBnZXRDaGVja1Nlc3Npb25JZnJhbWU6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lLnN0YXJ0KHNlc3Npb25fc3RhdGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9zdG9wKCkge1xyXG4gICAgICAgIHRoaXMuX3N1YiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX3N0b3BcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5zdG9wKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fc2V0dGluZ3MubW9uaXRvckFub255bW91c1Nlc3Npb24pIHtcclxuICAgICAgICAgICAgLy8gdXNpbmcgYSB0aW1lciB0byBkZWxheSByZS1pbml0aWFsaXphdGlvbiB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnMgZHVyaW5nIHNpZ25vdXRcclxuICAgICAgICAgICAgbGV0IHRpbWVySGFuZGxlID0gdGhpcy5fdGltZXIuc2V0SW50ZXJ2YWwoKCk9PntcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGltZXJIYW5kbGUpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRtcFVzZXIgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGUgOiBzZXNzaW9uLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uLnN1YiAmJiBzZXNzaW9uLnNpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0bXBVc2VyLnByb2ZpbGUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWI6IHNlc3Npb24uc3ViLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lkOiBzZXNzaW9uLnNpZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0bXBVc2VyKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjYXRjaCB0byBzdXBwcmVzcyBlcnJvcnMgc2luY2Ugd2UncmUgaW4gYSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yOiBlcnJvciBmcm9tIHF1ZXJ5U2Vzc2lvblN0YXR1czpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB9LCAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgX2NhbGxiYWNrKCkge1xyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgIHZhciByYWlzZUV2ZW50ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgPT09IHRoaXMuX3N1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJhaXNlRXZlbnQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24uc2lkID09PSB0aGlzLl9zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTYW1lIHN1YiBzdGlsbCBsb2dnZWQgaW4gYXQgT1AsIHJlc3RhcnRpbmcgY2hlY2sgc2Vzc2lvbiBpZnJhbWU7IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb24uc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s6IFNhbWUgc3ViIHN0aWxsIGxvZ2dlZCBpbiBhdCBPUCwgc2Vzc2lvbiBzdGF0ZSBoYXMgY2hhbmdlZCwgcmVzdGFydGluZyBjaGVjayBzZXNzaW9uIGlmcmFtZTsgc2Vzc2lvbl9zdGF0ZTpcIiwgc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTZXNzaW9uQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRGlmZmVyZW50IHN1YmplY3Qgc2lnbmVkIGludG8gT1A6XCIsIHNlc3Npb24uc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogU3ViamVjdCBubyBsb25nZXIgc2lnbmVkIGludG8gT1BcIik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIG91dCBldmVudFwiKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlVXNlclNpZ25lZE91dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIGluIGV2ZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkSW4oKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdWIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRXJyb3IgY2FsbGluZyBxdWVyeUN1cnJlbnRTaWduaW5TZXNzaW9uOyByYWlzaW5nIHNpZ25lZCBvdXQgZXZlbnRcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTaWduZWRPdXQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluUmVxdWVzdCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWFuZGF0b3J5XHJcbiAgICAgICAgdXJsLCBjbGllbnRfaWQsIHJlZGlyZWN0X3VyaSwgcmVzcG9uc2VfdHlwZSwgc2NvcGUsIGF1dGhvcml0eSxcclxuICAgICAgICAvLyBvcHRpb25hbFxyXG4gICAgICAgIGRhdGEsIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgcmVxdWVzdCwgcmVxdWVzdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSwgY2xpZW50X3NlY3JldCwgZXh0cmFUb2tlblBhcmFtcywgc2tpcFVzZXJJbmZvXHJcbiAgICB9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlZGlyZWN0X3VyaVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gcmVzcG9uc2VfdHlwZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlc3BvbnNlX3R5cGVcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghc2NvcGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyBzY29wZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNjb3BlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIGF1dGhvcml0eSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eVwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBvaWRjID0gU2lnbmluUmVxdWVzdC5pc09pZGMocmVzcG9uc2VfdHlwZSk7XHJcbiAgICAgICAgbGV0IGNvZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV9tb2RlKSB7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlX21vZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKSA/IFwicXVlcnlcIiA6IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFNpZ25pblN0YXRlKHsgbm9uY2U6IG9pZGMsIFxyXG4gICAgICAgICAgICBkYXRhLCBjbGllbnRfaWQsIGF1dGhvcml0eSwgcmVkaXJlY3RfdXJpLCBcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogY29kZSwgXHJcbiAgICAgICAgICAgIHJlcXVlc3RfdHlwZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldCwgc2NvcGUsIGV4dHJhVG9rZW5QYXJhbXMsIHNraXBVc2VySW5mbyB9KTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJjbGllbnRfaWRcIiwgY2xpZW50X2lkKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInJlZGlyZWN0X3VyaVwiLCByZWRpcmVjdF91cmkpO1xyXG4gICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIFwicmVzcG9uc2VfdHlwZVwiLCByZXNwb25zZV90eXBlKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInNjb3BlXCIsIHNjb3BlKTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICBpZiAob2lkYykge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcIm5vbmNlXCIsIHRoaXMuc3RhdGUubm9uY2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29kZSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlXCIsIHRoaXMuc3RhdGUuY29kZV9jaGFsbGVuZ2UpO1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlX21ldGhvZFwiLCBcIlMyNTZcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgb3B0aW9uYWwgPSB7IHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlcXVlc3QsIHJlcXVlc3RfdXJpLCByZXNwb25zZV9tb2RlIH07XHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gb3B0aW9uYWwpe1xyXG4gICAgICAgICAgICBpZiAob3B0aW9uYWxba2V5XSkge1xyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwga2V5LCBvcHRpb25hbFtrZXldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGlzT2lkYyhyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiaWRfdG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgaXNPQXV0aChyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwidG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgc3RhdGljIGlzQ29kZShyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiY29kZVwiO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiAhIShyZXN1bHRbMF0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgT2lkY1Njb3BlID0gXCJvcGVuaWRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWduaW5SZXNwb25zZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih1cmwsIGRlbGltaXRlciA9IFwiI1wiKSB7XHJcblxyXG4gICAgICAgIHZhciB2YWx1ZXMgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLmNvZGUgPSB2YWx1ZXMuY29kZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgICAgIHRoaXMuaWRfdG9rZW4gPSB2YWx1ZXMuaWRfdG9rZW47XHJcbiAgICAgICAgdGhpcy5zZXNzaW9uX3N0YXRlID0gdmFsdWVzLnNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSB2YWx1ZXMuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgIHRoaXMudG9rZW5fdHlwZSA9IHZhbHVlcy50b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSB2YWx1ZXMuc2NvcGU7XHJcbiAgICAgICAgdGhpcy5wcm9maWxlID0gdW5kZWZpbmVkOyAvLyB3aWxsIGJlIHNldCBmcm9tIFJlc3BvbnNlVmFsaWRhdG9yXHJcblxyXG4gICAgICAgIHRoaXMuZXhwaXJlc19pbiA9IHZhbHVlcy5leHBpcmVzX2luO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKXtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHBhcnNlSW50KHZhbHVlKTtcclxuICAgICAgICBpZiAodHlwZW9mIGV4cGlyZXNfaW4gPT09ICdudW1iZXInICYmIGV4cGlyZXNfaW4gPiAwKSB7XHJcbiAgICAgICAgICAgIGxldCBub3cgPSBwYXJzZUludChEYXRlLm5vdygpIC8gMTAwMCk7XHJcbiAgICAgICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IG5vdyArIGV4cGlyZXNfaW47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVkKCkge1xyXG4gICAgICAgIGxldCBleHBpcmVzX2luID0gdGhpcy5leHBpcmVzX2luO1xyXG4gICAgICAgIGlmIChleHBpcmVzX2luICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4cGlyZXNfaW4gPD0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2NvcGVzKCkge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5zY29wZSB8fCBcIlwiKS5zcGxpdChcIiBcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGlzT3BlbklkQ29ubmVjdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zY29wZXMuaW5kZXhPZihPaWRjU2NvcGUpID49IDAgfHwgISF0aGlzLmlkX3Rva2VuO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuL1N0YXRlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluU3RhdGUgZXh0ZW5kcyBTdGF0ZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7bm9uY2UsIGF1dGhvcml0eSwgY2xpZW50X2lkLCByZWRpcmVjdF91cmksIGNvZGVfdmVyaWZpZXIsIHJlc3BvbnNlX21vZGUsIGNsaWVudF9zZWNyZXQsIHNjb3BlLCBleHRyYVRva2VuUGFyYW1zLCBza2lwVXNlckluZm99ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICBpZiAobm9uY2UgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSByYW5kb20oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAobm9uY2UpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSBub25jZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjb2RlX3ZlcmlmaWVyID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIC8vIHJhbmRvbSgpIHByb2R1Y2VzIDMyIGxlbmd0aFxyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX3ZlcmlmaWVyID0gcmFuZG9tKCkgKyByYW5kb20oKSArIHJhbmRvbSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChjb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvZGVfdmVyaWZpZXIgPSBjb2RlX3ZlcmlmaWVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAodGhpcy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIGxldCBoYXNoID0gSm9zZVV0aWwuaGFzaFN0cmluZyh0aGlzLmNvZGVfdmVyaWZpZXIsIFwiU0hBMjU2XCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX2NoYWxsZW5nZSA9IEpvc2VVdGlsLmhleFRvQmFzZTY0VXJsKGhhc2gpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSBjbGllbnRfaWQ7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X3NlY3JldCA9IGNsaWVudF9zZWNyZXQ7XHJcbiAgICAgICAgdGhpcy5fc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gZXh0cmFUb2tlblBhcmFtcztcclxuICAgICAgICB0aGlzLl9za2lwVXNlckluZm8gPSBza2lwVXNlckluZm87XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG5vbmNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub25jZTtcclxuICAgIH1cclxuICAgIGdldCBhdXRob3JpdHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dGhvcml0eTtcclxuICAgIH1cclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCByZWRpcmVjdF91cmkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZGlyZWN0X3VyaTtcclxuICAgIH1cclxuICAgIGdldCBjb2RlX3ZlcmlmaWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX3ZlcmlmaWVyO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNvZGVfY2hhbGxlbmdlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX2NoYWxsZW5nZTtcclxuICAgIH1cclxuICAgIGdldCByZXNwb25zZV9tb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNwb25zZV9tb2RlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgc2NvcGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Njb3BlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGV4dHJhVG9rZW5QYXJhbXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgc2tpcFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9za2lwVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJTaWduaW5TdGF0ZS50b1N0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgICAgICAgaWQ6IHRoaXMuaWQsXHJcbiAgICAgICAgICAgIGRhdGE6IHRoaXMuZGF0YSxcclxuICAgICAgICAgICAgY3JlYXRlZDogdGhpcy5jcmVhdGVkLFxyXG4gICAgICAgICAgICByZXF1ZXN0X3R5cGU6IHRoaXMucmVxdWVzdF90eXBlLFxyXG4gICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogdGhpcy5jb2RlX3ZlcmlmaWVyLFxyXG4gICAgICAgICAgICByZWRpcmVjdF91cmk6IHRoaXMucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBhdXRob3JpdHk6IHRoaXMuYXV0aG9yaXR5LFxyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY2xpZW50X2lkLFxyXG4gICAgICAgICAgICByZXNwb25zZV9tb2RlOiB0aGlzLnJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgICAgIGNsaWVudF9zZWNyZXQ6IHRoaXMuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgOiB0aGlzLmV4dHJhVG9rZW5QYXJhbXMsXHJcbiAgICAgICAgICAgIHNraXBVc2VySW5mbzogdGhpcy5za2lwVXNlckluZm9cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmFnZVN0cmluZykge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlNpZ25pblN0YXRlLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHZhciBkYXRhID0gSlNPTi5wYXJzZShzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICByZXR1cm4gbmV3IFNpZ25pblN0YXRlKGRhdGEpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlcXVlc3Qge1xyXG4gICAgY29uc3RydWN0b3Ioe3VybCwgaWRfdG9rZW5faGludCwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLCBkYXRhLCBleHRyYVF1ZXJ5UGFyYW1zLCByZXF1ZXN0X3R5cGV9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbm91dFJlcXVlc3QuY3RvcjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGlkX3Rva2VuX2hpbnQpIHtcclxuICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJpZF90b2tlbl9oaW50XCIsIGlkX3Rva2VuX2hpbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaVwiLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBuZXcgU3RhdGUoeyBkYXRhLCByZXF1ZXN0X3R5cGUgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlc3BvbnNlIHtcclxuICAgIGNvbnN0cnVjdG9yKHVybCkge1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVzID0gVXJsVXRpbGl0eS5wYXJzZVVybEZyYWdtZW50KHVybCwgXCI/XCIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWxlbnRSZW5ld1NlcnZpY2Uge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgIH1cclxuXHJcbiAgICBzdGFydCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrID0gdGhpcy5fdG9rZW5FeHBpcmluZy5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkQWNjZXNzVG9rZW5FeHBpcmluZyh0aGlzLl9jYWxsYmFjayk7XHJcblxyXG4gICAgICAgICAgICAvLyB0aGlzIHdpbGwgdHJpZ2dlciBsb2FkaW5nIG9mIHRoZSB1c2VyIHNvIHRoZSBleHBpcmluZyBldmVudHMgY2FuIGJlIGluaXRpYWxpemVkXHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXI9PntcclxuICAgICAgICAgICAgICAgIC8vIGRlbGliZXJhdGUgbm9wXHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVycj0+e1xyXG4gICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLnN0YXJ0OiBFcnJvciBmcm9tIGdldFVzZXI6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0b3AoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5yZW1vdmVBY2Nlc3NUb2tlbkV4cGlyaW5nKHRoaXMuX2NhbGxiYWNrKTtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdG9rZW5FeHBpcmluZygpIHtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5zaWduaW5TaWxlbnQoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTaWxlbnRSZW5ld1NlcnZpY2UuX3Rva2VuRXhwaXJpbmc6IFNpbGVudCB0b2tlbiByZW5ld2FsIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgfSwgZXJyID0+IHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLl90b2tlbkV4cGlyaW5nOiBFcnJvciBmcm9tIHNpZ25pblNpbGVudDpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlcnIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU3RhdGUge1xyXG4gICAgY29uc3RydWN0b3Ioe2lkLCBkYXRhLCBjcmVhdGVkLCByZXF1ZXN0X3R5cGV9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9pZCA9IGlkIHx8IHJhbmRvbSgpO1xyXG4gICAgICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xyXG5cclxuICAgICAgICBpZiAodHlwZW9mIGNyZWF0ZWQgPT09ICdudW1iZXInICYmIGNyZWF0ZWQgPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZWQgPSBjcmVhdGVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fY3JlYXRlZCA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdF90eXBlID0gIHJlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lkO1xyXG4gICAgfVxyXG4gICAgZ2V0IGRhdGEoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XHJcbiAgICB9XHJcbiAgICBnZXQgY3JlYXRlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlZDtcclxuICAgIH1cclxuICAgIGdldCByZXF1ZXN0X3R5cGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICB0b1N0b3JhZ2VTdHJpbmcoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUudG9TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxyXG4gICAgICAgICAgICBkYXRhOiB0aGlzLmRhdGEsXHJcbiAgICAgICAgICAgIGNyZWF0ZWQ6IHRoaXMuY3JlYXRlZCxcclxuICAgICAgICAgICAgcmVxdWVzdF90eXBlOiB0aGlzLnJlcXVlc3RfdHlwZVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBmcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBTdGF0ZShKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgY2xlYXJTdGFsZVN0YXRlKHN0b3JhZ2UsIGFnZSkge1xyXG5cclxuICAgICAgICB2YXIgY3V0b2ZmID0gRGF0ZS5ub3coKSAvIDEwMDAgLSBhZ2U7XHJcblxyXG4gICAgICAgIHJldHVybiBzdG9yYWdlLmdldEFsbEtleXMoKS50aGVuKGtleXMgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IGdvdCBrZXlzXCIsIGtleXMpO1xyXG5cclxuICAgICAgICAgICAgdmFyIHByb21pc2VzID0gW107XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGtleSA9IGtleXNbaV07XHJcbiAgICAgICAgICAgICAgICB2YXIgcCA9IHN0b3JhZ2UuZ2V0KGtleSkudGhlbihpdGVtID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVtb3ZlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBTdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhpdGVtKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogZ290IGl0ZW0gZnJvbSBrZXk6IFwiLCBrZXksIHN0YXRlLmNyZWF0ZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5jcmVhdGVkIDw9IGN1dG9mZikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogRXJyb3IgcGFyc2luZyBzdGF0ZSBmb3Iga2V5XCIsIGtleSwgZS5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogbm8gaXRlbSBpbiBzdG9yYWdlIGZvciBrZXk6IFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IHJlbW92ZWQgaXRlbSBmb3Iga2V5OiBcIiwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0b3JhZ2UucmVtb3ZlKGtleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChwKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuY2xlYXJTdGFsZVN0YXRlOiB3YWl0aW5nIG9uIHByb21pc2UgY291bnQ6XCIsIHByb21pc2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5jb25zdCBUaW1lckR1cmF0aW9uID0gNTsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIFRpbWVyIGV4dGVuZHMgRXZlbnQge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKG5hbWUsIHRpbWVyID0gR2xvYmFsLnRpbWVyLCBub3dGdW5jID0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc3VwZXIobmFtZSk7XHJcbiAgICAgICAgdGhpcy5fdGltZXIgPSB0aW1lcjtcclxuXHJcbiAgICAgICAgaWYgKG5vd0Z1bmMpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm93RnVuYyA9IG5vd0Z1bmM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9ub3dGdW5jID0gKCkgPT4gRGF0ZS5ub3coKSAvIDEwMDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBub3coKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuX25vd0Z1bmMoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdChkdXJhdGlvbikge1xyXG4gICAgICAgIGlmIChkdXJhdGlvbiA8PSAwKSB7XHJcbiAgICAgICAgICAgIGR1cmF0aW9uID0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZHVyYXRpb24gPSBwYXJzZUludChkdXJhdGlvbik7XHJcblxyXG4gICAgICAgIHZhciBleHBpcmF0aW9uID0gdGhpcy5ub3cgKyBkdXJhdGlvbjtcclxuICAgICAgICBpZiAodGhpcy5leHBpcmF0aW9uID09PSBleHBpcmF0aW9uICYmIHRoaXMuX3RpbWVySGFuZGxlKSB7XHJcbiAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gcmVpbml0aWFsaXplIHRvIHNhbWUgZXhwaXJhdGlvbiwgc28gYmFpbCBvdXRcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuaW5pdCB0aW1lciBcIiArIHRoaXMuX25hbWUgKyBcIiBza2lwcGluZyBpbml0aWFsaXphdGlvbiBzaW5jZSBhbHJlYWR5IGluaXRpYWxpemVkIGZvciBleHBpcmF0aW9uOlwiLCB0aGlzLmV4cGlyYXRpb24pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmNhbmNlbCgpO1xyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5pbml0IHRpbWVyIFwiICsgdGhpcy5fbmFtZSArIFwiIGZvciBkdXJhdGlvbjpcIiwgZHVyYXRpb24pO1xyXG4gICAgICAgIHRoaXMuX2V4cGlyYXRpb24gPSBleHBpcmF0aW9uO1xyXG5cclxuICAgICAgICAvLyB3ZSdyZSB1c2luZyBhIGZhaXJseSBzaG9ydCB0aW1lciBhbmQgdGhlbiBjaGVja2luZyB0aGUgZXhwaXJhdGlvbiBpbiB0aGVcclxuICAgICAgICAvLyBjYWxsYmFjayB0byBoYW5kbGUgc2NlbmFyaW9zIHdoZXJlIHRoZSBicm93c2VyIGRldmljZSBzbGVlcHMsIGFuZCB0aGVuXHJcbiAgICAgICAgLy8gdGhlIHRpbWVycyBlbmQgdXAgZ2V0dGluZyBkZWxheWVkLlxyXG4gICAgICAgIHZhciB0aW1lckR1cmF0aW9uID0gVGltZXJEdXJhdGlvbjtcclxuICAgICAgICBpZiAoZHVyYXRpb24gPCB0aW1lckR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHRpbWVyRHVyYXRpb24gPSBkdXJhdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fdGltZXJIYW5kbGUgPSB0aGlzLl90aW1lci5zZXRJbnRlcnZhbCh0aGlzLl9jYWxsYmFjay5iaW5kKHRoaXMpLCB0aW1lckR1cmF0aW9uICogMTAwMCk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCBleHBpcmF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHBpcmF0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGNhbmNlbCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fdGltZXJIYW5kbGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuY2FuY2VsOiBcIiwgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXJIYW5kbGUpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lckhhbmRsZSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9jYWxsYmFjaygpIHtcclxuICAgICAgICB2YXIgZGlmZiA9IHRoaXMuX2V4cGlyYXRpb24gLSB0aGlzLm5vdztcclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5jYWxsYmFjazsgXCIgKyB0aGlzLl9uYW1lICsgXCIgdGltZXIgZXhwaXJlcyBpbjpcIiwgZGlmZik7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9leHBpcmF0aW9uIDw9IHRoaXMubm93KSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsKCk7XHJcbiAgICAgICAgICAgIHN1cGVyLnJhaXNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuQ2xpZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHNldHRpbmdzLCBKc29uU2VydmljZUN0b3IgPSBKc29uU2VydmljZSwgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSkge1xyXG4gICAgICAgIGlmICghc2V0dGluZ3MpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZXR0aW5nc1wiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fanNvblNlcnZpY2UgPSBuZXcgSnNvblNlcnZpY2VDdG9yKCk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGV4Y2hhbmdlQ29kZShhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcImF1dGhvcml6YXRpb25fY29kZVwiO1xyXG4gICAgICAgIGFyZ3MuY2xpZW50X2lkID0gYXJncy5jbGllbnRfaWQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkO1xyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gYXJncy5yZWRpcmVjdF91cmkgfHwgdGhpcy5fc2V0dGluZ3MucmVkaXJlY3RfdXJpO1xyXG5cclxuICAgICAgICBpZiAoIWFyZ3MuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIGNvZGUgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSBjb2RlIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHJlZGlyZWN0X3VyaSBpcyByZXF1aXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghYXJncy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY29kZV92ZXJpZmllciBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIGNvZGVfdmVyaWZpZXIgaXMgcmVxdWlyZWRcIikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWFyZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IFJlY2VpdmVkIHRva2VuIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLnBvc3RGb3JtKHVybCwgYXJncykudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IHJlc3BvbnNlIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBleGNoYW5nZVJlZnJlc2hUb2tlbihhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcInJlZnJlc2hfdG9rZW5cIjtcclxuICAgICAgICBhcmdzLmNsaWVudF9pZCA9IGFyZ3MuY2xpZW50X2lkIHx8IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICBhcmdzLmNsaWVudF9zZWNyZXQgPSBhcmdzLmNsaWVudF9zZWNyZXQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuXHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuZXhjaGFuZ2VSZWZyZXNoVG9rZW46IE5vIHJlZnJlc2hfdG9rZW4gcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSByZWZyZXNoX3Rva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogUmVjZWl2ZWQgdG9rZW4gZW5kcG9pbnRcIik7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UucG9zdEZvcm0odXJsLCBhcmdzKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuOiByZXNwb25zZSByZWNlaXZlZFwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmNvbnN0IEFjY2Vzc1Rva2VuVHlwZUhpbnQgPSBcImFjY2Vzc190b2tlblwiO1xyXG5jb25zdCBSZWZyZXNoVG9rZW5UeXBlSGludCA9IFwicmVmcmVzaF90b2tlblwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuUmV2b2NhdGlvbkNsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgWE1MSHR0cFJlcXVlc3RDdG9yID0gR2xvYmFsLlhNTEh0dHBSZXF1ZXN0LCBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHNldHRpbmdzIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fWE1MSHR0cFJlcXVlc3RDdG9yID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZSA9IG5ldyBNZXRhZGF0YVNlcnZpY2VDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICByZXZva2UodG9rZW4sIHJlcXVpcmVkLCB0eXBlID0gXCJhY2Nlc3NfdG9rZW5cIikge1xyXG4gICAgICAgIGlmICghdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogTm8gdG9rZW4gcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHRva2VuIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0eXBlICE9PSBBY2Nlc3NUb2tlblR5cGVIaW50ICYmIHR5cGUgIT0gUmVmcmVzaFRva2VuVHlwZUhpbnQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogSW52YWxpZCB0b2tlbiB0eXBlXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRva2VuIHR5cGUuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRSZXZvY2F0aW9uRW5kcG9pbnQoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdXJsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBSZXZvY2F0aW9uIG5vdCBzdXBwb3J0ZWRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmV2b2NhdGlvbiBub3Qgc3VwcG9ydGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIG5vdCByZXF1aXJlZCwgc28gZG9uJ3QgZXJyb3IgYW5kIGp1c3QgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2U6IFJldm9raW5nIFwiICsgdHlwZSk7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfaWQgPSB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQ7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfc2VjcmV0ID0gdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZSh1cmwsIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgdG9rZW4sIHR5cGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2UodXJsLCBjbGllbnRfaWQsIGNsaWVudF9zZWNyZXQsIHRva2VuLCB0eXBlKSB7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblxyXG4gICAgICAgICAgICB2YXIgeGhyID0gbmV3IHRoaXMuX1hNTEh0dHBSZXF1ZXN0Q3RvcigpO1xyXG4gICAgICAgICAgICB4aHIub3BlbihcIlBPU1RcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIHhoci5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBIVFRQIHJlc3BvbnNlIHJlY2VpdmVkLCBzdGF0dXNcIiwgeGhyLnN0YXR1cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcih4aHIuc3RhdHVzVGV4dCArIFwiIChcIiArIHhoci5zdGF0dXMgKyBcIilcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB4aHIub25lcnJvciA9ICgpID0+IHsgXHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBOZXR3b3JrIEVycm9yLlwiKVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KFwiTmV0d29yayBFcnJvclwiKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHZhciBib2R5ID0gXCJjbGllbnRfaWQ9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoY2xpZW50X2lkKTtcclxuICAgICAgICAgICAgaWYgKGNsaWVudF9zZWNyZXQpIHtcclxuICAgICAgICAgICAgICAgIGJvZHkgKz0gXCImY2xpZW50X3NlY3JldD1cIiArIGVuY29kZVVSSUNvbXBvbmVudChjbGllbnRfc2VjcmV0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBib2R5ICs9IFwiJnRva2VuX3R5cGVfaGludD1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0eXBlKTtcclxuICAgICAgICAgICAgYm9keSArPSBcIiZ0b2tlbj1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0b2tlbik7XHJcblxyXG4gICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKTtcclxuICAgICAgICAgICAgeGhyLnNlbmQoYm9keSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXJsVXRpbGl0eSB7XHJcbiAgICBzdGF0aWMgYWRkUXVlcnlQYXJhbSh1cmwsIG5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKCc/JykgPCAwKSB7XHJcbiAgICAgICAgICAgIHVybCArPSBcIj9cIjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh1cmxbdXJsLmxlbmd0aCAtIDFdICE9PSBcIj9cIikge1xyXG4gICAgICAgICAgICB1cmwgKz0gXCImXCI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KG5hbWUpO1xyXG4gICAgICAgIHVybCArPSBcIj1cIjtcclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHVybDtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgcGFyc2VVcmxGcmFnbWVudCh2YWx1ZSwgZGVsaW1pdGVyID0gXCIjXCIsIGdsb2JhbCA9IEdsb2JhbCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKXtcclxuICAgICAgICAgICAgdmFsdWUgPSBnbG9iYWwubG9jYXRpb24uaHJlZjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBpZHggPSB2YWx1ZS5sYXN0SW5kZXhPZihkZWxpbWl0ZXIpO1xyXG4gICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cihpZHggKyAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChkZWxpbWl0ZXIgPT09IFwiP1wiKSB7XHJcbiAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGRvaW5nIHF1ZXJ5LCB0aGVuIHN0cmlwIG9mZiBoYXNoIGZyYWdtZW50IGJlZm9yZSB3ZSBwYXJzZVxyXG4gICAgICAgICAgICBpZHggPSB2YWx1ZS5pbmRleE9mKCcjJyk7XHJcbiAgICAgICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHIoMCwgaWR4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHBhcmFtcyA9IHt9LFxyXG4gICAgICAgICAgICByZWdleCA9IC8oW14mPV0rKT0oW14mXSopL2csXHJcbiAgICAgICAgICAgIG07XHJcblxyXG4gICAgICAgIHZhciBjb3VudGVyID0gMDtcclxuICAgICAgICB3aGlsZSAobSA9IHJlZ2V4LmV4ZWModmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHBhcmFtc1tkZWNvZGVVUklDb21wb25lbnQobVsxXSldID0gZGVjb2RlVVJJQ29tcG9uZW50KG1bMl0pO1xyXG4gICAgICAgICAgICBpZiAoY291bnRlcisrID4gNTApIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVybFV0aWxpdHkucGFyc2VVcmxGcmFnbWVudDogcmVzcG9uc2UgZXhjZWVkZWQgZXhwZWN0ZWQgbnVtYmVyIG9mIHBhcmFtZXRlcnNcIiwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogXCJSZXNwb25zZSBleGNlZWRlZCBleHBlY3RlZCBudW1iZXIgb2YgcGFyYW1ldGVyc1wiXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHBhcmFtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gcGFyYW1zO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHt9O1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyIHtcclxuICAgIGNvbnN0cnVjdG9yKHtpZF90b2tlbiwgc2Vzc2lvbl9zdGF0ZSwgYWNjZXNzX3Rva2VuLCByZWZyZXNoX3Rva2VuLCB0b2tlbl90eXBlLCBzY29wZSwgcHJvZmlsZSwgZXhwaXJlc19hdCwgc3RhdGV9KSB7XHJcbiAgICAgICAgdGhpcy5pZF90b2tlbiA9IGlkX3Rva2VuO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSBhY2Nlc3NfdG9rZW47XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoX3Rva2VuID0gcmVmcmVzaF90b2tlbjtcclxuICAgICAgICB0aGlzLnRva2VuX3R5cGUgPSB0b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLnByb2ZpbGUgPSBwcm9maWxlO1xyXG4gICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IGV4cGlyZXNfYXQ7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKSB7XHJcbiAgICAgICAgbGV0IGV4cGlyZXNfaW4gPSBwYXJzZUludCh2YWx1ZSk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBleHBpcmVzX2luID09PSAnbnVtYmVyJyAmJiBleHBpcmVzX2luID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgbm93ID0gcGFyc2VJbnQoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG4gICAgICAgICAgICB0aGlzLmV4cGlyZXNfYXQgPSBub3cgKyBleHBpcmVzX2luO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXhwaXJlZCgpIHtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHRoaXMuZXhwaXJlc19pbjtcclxuICAgICAgICBpZiAoZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHBpcmVzX2luIDw9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNjb3BlcygpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuc2NvcGUgfHwgXCJcIikuc3BsaXQoXCIgXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLnRvU3RvcmFnZVN0cmluZ1wiKTtcclxuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xyXG4gICAgICAgICAgICBpZF90b2tlbjogdGhpcy5pZF90b2tlbixcclxuICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogdGhpcy5zZXNzaW9uX3N0YXRlLFxyXG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46IHRoaXMuYWNjZXNzX3Rva2VuLFxyXG4gICAgICAgICAgICByZWZyZXNoX3Rva2VuOiB0aGlzLnJlZnJlc2hfdG9rZW4sXHJcbiAgICAgICAgICAgIHRva2VuX3R5cGU6IHRoaXMudG9rZW5fdHlwZSxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIHByb2ZpbGU6IHRoaXMucHJvZmlsZSxcclxuICAgICAgICAgICAgZXhwaXJlc19hdDogdGhpcy5leHBpcmVzX2F0XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGZyb21TdG9yYWdlU3RyaW5nKHN0b3JhZ2VTdHJpbmcpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgVXNlcihKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBKc29uU2VydmljZSB9IGZyb20gJy4vSnNvblNlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VySW5mb1NlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgc2V0dGluZ3MsIFxyXG4gICAgICAgIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlLCBcclxuICAgICAgICBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuICAgICAgICBpZiAoIXNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IodW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMuX2dldENsYWltc0Zyb21Kd3QuYmluZCh0aGlzKSk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Q2xhaW1zKHRva2VuKSB7XHJcbiAgICAgICAgaWYgKCF0b2tlbikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBObyB0b2tlbiBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHRva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VXNlckluZm9FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLmdldENsYWltczogcmVjZWl2ZWQgdXNlcmluZm8gdXJsXCIsIHVybCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UuZ2V0SnNvbih1cmwsIHRva2VuKS50aGVuKGNsYWltcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBjbGFpbXMgcmVjZWl2ZWRcIiwgY2xhaW1zKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjbGFpbXM7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRDbGFpbXNGcm9tSnd0KHJlcSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEZhaWxlZCB0byBwYXJzZSBKV1RcIiwgand0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcGFyc2UgaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIga2lkID0gand0LmhlYWRlci5raWQ7XHJcblxyXG4gICAgICAgICAgICBsZXQgaXNzdWVyUHJvbWlzZTtcclxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnT1AnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdBTlknOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoand0LnBheWxvYWQuaXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVyUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBpc3N1ZXJQcm9taXNlLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgaXNzdWVyOlwiICsgaXNzdWVyKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldFNpZ25pbmdLZXlzKCkudGhlbihrZXlzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlckluZm9TZXJ2aWNlLl9nZXRDbGFpbXNGcm9tSnd0OiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpZ25pbmcga2V5cyBmcm9tIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFraWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5cyA9IHRoaXMuX2ZpbHRlckJ5QWxnKGtleXMsIGp3dC5oZWFkZXIuYWxnKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBraWQgZm91bmQgaW4gaWRfdG9rZW4gYW5kIG1vcmUgdGhhbiBvbmUga2V5IGZvdW5kIGluIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGtpZCBpcyBtYW5kYXRvcnkgb25seSB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBrZXlzIGluIHRoZSByZWZlcmVuY2VkIEpXSyBTZXQgZG9jdW1lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwOi8vb3BlbmlkLm5ldC9zcGVjcy9vcGVuaWQtY29ubmVjdC1jb3JlLTFfMC5odG1sI1NpZ25pbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5LmtpZCA9PT0ga2lkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgha2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhdWRpZW5jZSA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0KHJlcS5yZXNwb25zZVRleHQsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzLCB1bmRlZmluZWQsIHRydWUpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEpXVCB2YWxpZGF0aW9uIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBqd3QucGF5bG9hZDtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEVycm9yIHBhcnNpbmcgSldUIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKSB7XHJcbiAgICAgICAgdmFyIGt0eSA9IG51bGw7XHJcbiAgICAgICAgaWYgKGFsZy5zdGFydHNXaXRoKFwiUlNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJSU0FcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJQU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlBTXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGFsZy5zdGFydHNXaXRoKFwiRVNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJFQ1wiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLl9maWx0ZXJCeUFsZzogYWxnIG5vdCBzdXBwb3J0ZWQ6IFwiLCBhbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZmlsdGVyQnlBbGc6IE51bWJlciBvZiBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5LCBrZXlzLmxlbmd0aCk7XHJcblxyXG4gICAgICAgIHJldHVybiBrZXlzO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudCB9IGZyb20gJy4vT2lkY0NsaWVudC5qcyc7XHJcbmltcG9ydCB7IFVzZXJNYW5hZ2VyU2V0dGluZ3MgfSBmcm9tICcuL1VzZXJNYW5hZ2VyU2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi9Vc2VyLmpzJztcclxuaW1wb3J0IHsgVXNlck1hbmFnZXJFdmVudHMgfSBmcm9tICcuL1VzZXJNYW5hZ2VyRXZlbnRzLmpzJztcclxuaW1wb3J0IHsgU2lsZW50UmVuZXdTZXJ2aWNlIH0gZnJvbSAnLi9TaWxlbnRSZW5ld1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBTZXNzaW9uTW9uaXRvciB9IGZyb20gJy4vU2Vzc2lvbk1vbml0b3IuanMnO1xyXG5pbXBvcnQgeyBUb2tlblJldm9jYXRpb25DbGllbnQgfSBmcm9tICcuL1Rva2VuUmV2b2NhdGlvbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IFRva2VuQ2xpZW50IH0gZnJvbSAnLi9Ub2tlbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IEpvc2VVdGlsIH0gZnJvbSAnLi9Kb3NlVXRpbC5qcyc7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFVzZXJNYW5hZ2VyIGV4dGVuZHMgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9LFxyXG4gICAgICAgIFNpbGVudFJlbmV3U2VydmljZUN0b3IgPSBTaWxlbnRSZW5ld1NlcnZpY2UsXHJcbiAgICAgICAgU2Vzc2lvbk1vbml0b3JDdG9yID0gU2Vzc2lvbk1vbml0b3IsXHJcbiAgICAgICAgVG9rZW5SZXZvY2F0aW9uQ2xpZW50Q3RvciA9IFRva2VuUmV2b2NhdGlvbkNsaWVudCxcclxuICAgICAgICBUb2tlbkNsaWVudEN0b3IgPSBUb2tlbkNsaWVudCxcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuXHJcbiAgICAgICAgaWYgKCEoc2V0dGluZ3MgaW5zdGFuY2VvZiBVc2VyTWFuYWdlclNldHRpbmdzKSkge1xyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IG5ldyBVc2VyTWFuYWdlclNldHRpbmdzKHNldHRpbmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xyXG5cclxuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVXNlck1hbmFnZXJFdmVudHMoc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3U2VydmljZSA9IG5ldyBTaWxlbnRSZW5ld1NlcnZpY2VDdG9yKHRoaXMpO1xyXG5cclxuICAgICAgICAvLyBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczsgdGhlc2Ugc2VydmljZXMgZGVwZW5kIHVwb24gdGhlIGV2ZW50cy5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5hdXRvbWF0aWNTaWxlbnRSZW5ldykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBhdXRvbWF0aWNTaWxlbnRSZW5ldyBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNpbGVudCByZW5ld1wiKTtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNpbGVudFJlbmV3KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5tb25pdG9yU2Vzc2lvbikge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBtb25pdG9yU2Vzc2lvbiBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNlc3Npb24gbW9uaXRvclwiKTtcclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbk1vbml0b3IgPSBuZXcgU2Vzc2lvbk1vbml0b3JDdG9yKHRoaXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50ID0gbmV3IFRva2VuUmV2b2NhdGlvbkNsaWVudEN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3Rva2VuQ2xpZW50ID0gbmV3IFRva2VuQ2xpZW50Q3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fam9zZVV0aWwgPSBqb3NlVXRpbDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3JlZGlyZWN0TmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9wb3B1cE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5ncy5wb3B1cE5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfaWZyYW1lTmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLmlmcmFtZU5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfdXNlclN0b3JlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnVzZXJTdG9yZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXZlbnRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5nZXRVc2VyOiB1c2VyIGxvYWRlZFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMubG9hZCh1c2VyLCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLmdldFVzZXI6IHVzZXIgbm90IGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVVzZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKG51bGwpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnJlbW92ZVVzZXI6IHVzZXIgcmVtb3ZlZCBmcm9tIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy51bmxvYWQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5SZWRpcmVjdChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpyXCI7XHJcbiAgICAgICAgbGV0IG5hdlBhcmFtcyA9IHtcclxuICAgICAgICAgICAgdXNlUmVwbGFjZVRvTmF2aWdhdGUgOiBhcmdzLnVzZVJlcGxhY2VUb05hdmlnYXRlXHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0OiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbmluUmVkaXJlY3RDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5SZWRpcmVjdENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmluUG9wdXAoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6cFwiO1xyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnBvcHVwX3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cDogTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pbihhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IHNpZ25pblBvcHVwIHN1Y2Nlc3NmdWwsIHNpZ25lZCBpbiBzdWI6IFwiLCB1c2VyLnByb2ZpbGUuc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBzaWduaW5Qb3B1cENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5DYWxsYmFjayh1cmwsIHRoaXMuX3BvcHVwTmF2aWdhdG9yKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSAmJiB1c2VyLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSkuY2F0Y2goZXJyPT57XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2sgZXJyb3I6IFwiICsgZXJyICYmIGVyci5tZXNzYWdlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnQoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6c1wiO1xyXG4gICAgICAgIC8vIGZpcnN0IGRldGVybWluZSBpZiB3ZSBoYXZlIGEgcmVmcmVzaCB0b2tlbiwgb3IgbmVlZCB0byB1c2UgaWZyYW1lXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIgJiYgdXNlci5yZWZyZXNoX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICBhcmdzLnJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlUmVmcmVzaFRva2VuKGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYXJncy5pZF90b2tlbl9oaW50ID0gYXJncy5pZF90b2tlbl9oaW50IHx8ICh0aGlzLnNldHRpbmdzLmluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyAmJiB1c2VyICYmIHVzZXIuaWRfdG9rZW4pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIgJiYgdGhpcy5fc2V0dGluZ3MudmFsaWRhdGVTdWJPblNpbGVudFJlbmV3KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50LCBzdWJqZWN0IHByaW9yIHRvIHNpbGVudCByZW5ldzogXCIsIHVzZXIucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MuY3VycmVudF9zdWIgPSB1c2VyLnByb2ZpbGUuc3ViO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblNpbGVudElmcmFtZShhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF91c2VSZWZyZXNoVG9rZW4oYXJncyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuKGFyZ3MpLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IE5vIHJlc3BvbnNlIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyByZXNwb25zZSByZXR1cm5lZCBmcm9tIHRva2VuIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghcmVzdWx0LmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3VzZVJlZnJlc2hUb2tlbjogTm8gYWNjZXNzIHRva2VuIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyBhY2Nlc3MgdG9rZW4gcmV0dXJuZWQgZnJvbSB0b2tlbiBlbmRwb2ludFwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGlkVG9rZW5WYWxpZGF0aW9uID0gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pZF90b2tlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZFRva2VuVmFsaWRhdGlvbiA9IHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbih1c2VyLnByb2ZpbGUsIHJlc3VsdC5pZF90b2tlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWRUb2tlblZhbGlkYXRpb24udGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IHJlZnJlc2ggdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc1wiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5pZF90b2tlbiA9IHJlc3VsdC5pZF90b2tlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSByZXN1bHQuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VyLnJlZnJlc2hfdG9rZW4gPSByZXN1bHQucmVmcmVzaF90b2tlbiB8fCB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXIuZXhwaXJlc19pbiA9IHJlc3VsdC5leHBpcmVzX2luO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKHVzZXIpLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW4ocHJvZmlsZSwgaWRfdG9rZW4pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0QXR0cmlidXRlcyhpZF90b2tlbiwgaXNzdWVyLCB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQsIHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldykudGhlbihwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLnN1YiAhPT0gcHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5fdmFsaWRhdGVJZFRva2VuRnJvbVRva2VuUmVmcmVzaFRva2VuOiBzdWIgaW4gaWRfdG9rZW4gZG9lcyBub3QgbWF0Y2ggY3VycmVudCBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcInN1YiBpbiBpZF90b2tlbiBkb2VzIG5vdCBtYXRjaCBjdXJyZW50IHN1YlwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5hdXRoX3RpbWUgJiYgcGF5bG9hZC5hdXRoX3RpbWUgIT09IHByb2ZpbGUuYXV0aF90aW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5henAgJiYgcGF5bG9hZC5henAgIT09IHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIXBheWxvYWQuYXpwICYmIHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIG5vdCBpbiBpZF90b2tlbiwgYnV0IHByZXNlbnQgaW4gb3JpZ2luYWwgaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImF6cCBub3QgaW4gaWRfdG9rZW4sIGJ1dCBwcmVzZW50IGluIG9yaWdpbmFsIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zaWduaW5TaWxlbnRJZnJhbWUoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3Muc2lsZW50X3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5TaWxlbnQ6IE5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhcmdzLnJlZGlyZWN0X3VyaSA9IHVybDtcclxuICAgICAgICBhcmdzLnByb21wdCA9IGFyZ3MucHJvbXB0IHx8IFwibm9uZVwiO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluKGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50OiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudDogbm8gc3ViXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdXNlcjtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluQ2FsbGJhY2sodXJsLCB0aGlzLl9pZnJhbWVOYXZpZ2F0b3IpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodXNlci5wcm9maWxlICYmIHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBubyBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25pbkNhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlLnJlcXVlc3RfdHlwZSA9PT0gXCJzaTpyXCIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2sodXJsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNpOnBcIikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2lnbmluUG9wdXBDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5yZXF1ZXN0X3R5cGUgPT09IFwic2k6c1wiKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJpbnZhbGlkIHJlc3BvbnNlX3R5cGUgaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRDYWxsYmFjayh1cmwsIGtlZXBPcGVuKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnBcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRQb3B1cENhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImludmFsaWQgcmVzcG9uc2VfdHlwZSBpbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHF1ZXJ5U2Vzc2lvblN0YXR1cyhhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpzXCI7IC8vIHRoaXMgYWN0cyBsaWtlIGEgc2lnbmluIHNpbGVudFxyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnNpbGVudF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXJncy5yZWRpcmVjdF91cmkgPSB1cmw7XHJcbiAgICAgICAgYXJncy5wcm9tcHQgPSBcIm5vbmVcIjtcclxuICAgICAgICBhcmdzLnJlc3BvbnNlX3R5cGUgPSBhcmdzLnJlc3BvbnNlX3R5cGUgfHwgdGhpcy5zZXR0aW5ncy5xdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZTtcclxuICAgICAgICBhcmdzLnNjb3BlID0gYXJncy5zY29wZSB8fCBcIm9wZW5pZFwiO1xyXG4gICAgICAgIGFyZ3Muc2tpcFVzZXJJbmZvID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblN0YXJ0KGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZShuYXZSZXNwb25zZS51cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzaWduaW5SZXNwb25zZS5zZXNzaW9uX3N0YXRlICYmIHNpZ25pblJlc3BvbnNlLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXM6IHF1ZXJ5U2Vzc2lvblN0YXR1cyBzdWNjZXNzIGZvciBzdWI6IFwiLCAgc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGU6IHNpZ25pblJlc3BvbnNlLnNlc3Npb25fc3RhdGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Yjogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zaWRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJxdWVyeVNlc3Npb25TdGF0dXMgc3VjY2Vzc2Z1bCwgdXNlciBub3QgYXV0aGVudGljYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyLnNlc3Npb25fc3RhdGUgJiYgdGhpcy5zZXR0aW5ncy5tb25pdG9yQW5vbnltb3VzU2Vzc2lvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIubWVzc2FnZSA9PSBcImxvZ2luX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiY29uc2VudF9yZXF1aXJlZFwiIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnIubWVzc2FnZSA9PSBcImludGVyYWN0aW9uX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiYWNjb3VudF9zZWxlY3Rpb25fcmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1czogcXVlcnlTZXNzaW9uU3RhdHVzIHN1Y2Nlc3MgZm9yIGFub255bW91cyB1c2VyXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogZXJyLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbmluKGFyZ3MsIG5hdmlnYXRvciwgbmF2aWdhdG9yUGFyYW1zID0ge30pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMpLnRoZW4obmF2UmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKG5hdlJlc3BvbnNlLnVybCwgYXJncyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG5cclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnByZXBhcmUobmF2aWdhdG9yUGFyYW1zKS50aGVuKGhhbmRsZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5TdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2lnbmluUmVxdWVzdChhcmdzKS50aGVuKHNpZ25pblJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBnb3Qgc2lnbmluIHJlcXVlc3RcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLnVybCA9IHNpZ25pblJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbmluUmVxdWVzdC5zdGF0ZS5pZDtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBFcnJvciBhZnRlciBwcmVwYXJpbmcgbmF2aWdhdG9yLCBjbG9zaW5nIG5hdmlnYXRvciB3aW5kb3dcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgX3NpZ25pbkVuZCh1cmwsIGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZSh1cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHVzZXIgPSBuZXcgVXNlcihzaWduaW5SZXNwb25zZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoYXJncy5jdXJyZW50X3N1Yikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MuY3VycmVudF9zdWIgIT09IHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBjdXJyZW50IHVzZXIgZG9lcyBub3QgbWF0Y2ggdXNlciByZXR1cm5lZCBmcm9tIHNpZ25pbi4gc3ViIGZyb20gc2lnbmluOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImxvZ2luX3JlcXVpcmVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IGN1cnJlbnQgdXNlciBtYXRjaGVzIHVzZXIgcmV0dXJuZWQgZnJvbSBzaWduaW5cIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0b3JlVXNlcih1c2VyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IHVzZXIgc3RvcmVkXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWduaW5DYWxsYmFjayh1cmwsIG5hdmlnYXRvcikge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5DYWxsYmFja1wiKTtcclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLmNhbGxiYWNrKHVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbm91dFJlZGlyZWN0KGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIGFyZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBhcmdzKTtcclxuXHJcbiAgICAgICAgYXJncy5yZXF1ZXN0X3R5cGUgPSBcInNvOnJcIjtcclxuICAgICAgICBsZXQgcG9zdExvZ291dFJlZGlyZWN0VXJpID0gYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKHBvc3RMb2dvdXRSZWRpcmVjdFVyaSl7XHJcbiAgICAgICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdExvZ291dFJlZGlyZWN0VXJpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgbmF2UGFyYW1zID0ge1xyXG4gICAgICAgICAgICB1c2VSZXBsYWNlVG9OYXZpZ2F0ZSA6IGFyZ3MudXNlUmVwbGFjZVRvTmF2aWdhdGVcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0U3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25vdXRSZWRpcmVjdDogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4ocmVzcG9uc2U9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UmVkaXJlY3RDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRQb3B1cChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzbzpwXCI7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuICAgICAgICBpZiAoYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpe1xyXG4gICAgICAgICAgICAvLyB3ZSdyZSBwdXR0aW5nIGEgZHVtbXkgZW50cnkgaW4gaGVyZSBiZWNhdXNlIHdlXHJcbiAgICAgICAgICAgIC8vIG5lZWQgYSB1bmlxdWUgaWQgZnJvbSB0aGUgc3RhdGUgZm9yIG5vdGlmaWNhdGlvblxyXG4gICAgICAgICAgICAvLyB0byB0aGUgcGFyZW50IHdpbmRvdywgd2hpY2ggaXMgbmVjZXNzYXJ5IGlmIHdlXHJcbiAgICAgICAgICAgIC8vIHBsYW4gdG8gcmV0dXJuIGJhY2sgdG8gdGhlIGNsaWVudCBhZnRlciBzaWdub3V0XHJcbiAgICAgICAgICAgIC8vIGFuZCBzbyB3ZSBjYW4gY2xvc2UgdGhlIHBvcHVwIGFmdGVyIHNpZ25vdXRcclxuICAgICAgICAgICAgYXJncy5zdGF0ZSA9IGFyZ3Muc3RhdGUgfHwge307XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbm91dChhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbm91dFBvcHVwOiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbm91dFBvcHVwQ2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Yoa2VlcE9wZW4pID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YodXJsKSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgICAgICAgIGtlZXBPcGVuID0gdXJsO1xyXG4gICAgICAgICAgICB1cmwgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9ICc/JztcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBOYXZpZ2F0b3IuY2FsbGJhY2sodXJsLCBrZWVwT3BlbiwgZGVsaW1pdGVyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UG9wdXBDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbm91dChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25vdXRTdGFydChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcykudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKG5hdlJlc3BvbnNlLnVybCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbm91dFN0YXJ0KGFyZ3MgPSB7fSwgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiBuYXZpZ2F0b3IucHJlcGFyZShuYXZpZ2F0b3JQYXJhbXMpLnRoZW4oaGFuZGxlID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IGxvYWRlZCBjdXJyZW50IHVzZXIgZnJvbSBzdG9yYWdlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciByZXZva2VQcm9taXNlID0gdGhpcy5fc2V0dGluZ3MucmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQgPyB0aGlzLl9yZXZva2VJbnRlcm5hbCh1c2VyKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldm9rZVByb21pc2UudGhlbigoKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZF90b2tlbiA9IGFyZ3MuaWRfdG9rZW5faGludCB8fCB1c2VyICYmIHVzZXIuaWRfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IFNldHRpbmcgaWRfdG9rZW4gaW50byBzaWdub3V0IHJlcXVlc3RcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MuaWRfdG9rZW5faGludCA9IGlkX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlVXNlcigpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbm91dFN0YXJ0OiB1c2VyIHJlbW92ZWQsIGNyZWF0aW5nIHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVNpZ25vdXRSZXF1ZXN0KGFyZ3MpLnRoZW4oc2lnbm91dFJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3JQYXJhbXMudXJsID0gc2lnbm91dFJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpZ25vdXRSZXF1ZXN0LnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbm91dFJlcXVlc3Quc3RhdGUuaWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogRXJyb3IgYWZ0ZXIgcHJlcGFyaW5nIG5hdmlnYXRvciwgY2xvc2luZyBuYXZpZ2F0b3Igd2luZG93XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZS5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWdub3V0RW5kKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsKS50aGVuKHNpZ25vdXRSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0RW5kOiBnb3Qgc2lnbm91dCByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBzaWdub3V0UmVzcG9uc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV2b2tlQWNjZXNzVG9rZW4oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUludGVybmFsKHVzZXIsIHRydWUpLnRoZW4oc3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3VjY2Vzcykge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiByZW1vdmluZyB0b2tlbiBwcm9wZXJ0aWVzIGZyb20gdXNlciBhbmQgcmUtc3RvcmluZ1wiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHVzZXIucmVmcmVzaF90b2tlbiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5leHBpcmVzX2F0ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB1c2VyLnRva2VuX3R5cGUgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdG9yZVVzZXIodXNlcikudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiB1c2VyIHN0b3JlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmxvYWQodXNlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5yZXZva2VBY2Nlc3NUb2tlbjogYWNjZXNzIHRva2VuIHJldm9rZWQgc3VjY2Vzc2Z1bGx5XCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2VJbnRlcm5hbCh1c2VyLCByZXF1aXJlZCkge1xyXG4gICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgIHZhciBhY2Nlc3NfdG9rZW4gPSB1c2VyLmFjY2Vzc190b2tlbjtcclxuICAgICAgICAgICAgdmFyIHJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oYXRTdWNjZXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJ0U3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0U3VjY2VzcyAmJiAhcnRTdWNjZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucmV2b2tlQWNjZXNzVG9rZW46IG5vIG5lZWQgdG8gcmV2b2tlIGR1ZSB0byBubyB0b2tlbihzKSwgb3IgSldUIGZvcm1hdFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0U3VjY2VzcyB8fCBydFN1Y2Nlc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKSB7XHJcbiAgICAgICAgLy8gY2hlY2sgZm9yIEpXVCB2cy4gcmVmZXJlbmNlIHRva2VuXHJcbiAgICAgICAgaWYgKCFhY2Nlc3NfdG9rZW4gfHwgYWNjZXNzX3Rva2VuLmluZGV4T2YoJy4nKSA+PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2UoYWNjZXNzX3Rva2VuLCByZXF1aXJlZCkudGhlbigoKSA9PiB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpIHtcclxuICAgICAgICBpZiAoIXJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZShyZWZyZXNoX3Rva2VuLCByZXF1aXJlZCwgXCJyZWZyZXNoX3Rva2VuXCIpLnRoZW4oKCkgPT4gdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhcnRTaWxlbnRSZW5ldygpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld1NlcnZpY2Uuc3RhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBzdG9wU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdTZXJ2aWNlLnN0b3AoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3VzZXJTdG9yZUtleSgpIHtcclxuICAgICAgICByZXR1cm4gYHVzZXI6JHt0aGlzLnNldHRpbmdzLmF1dGhvcml0eX06JHt0aGlzLnNldHRpbmdzLmNsaWVudF9pZH1gO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkVXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLmdldCh0aGlzLl91c2VyU3RvcmVLZXkpLnRoZW4oc3RvcmFnZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmIChzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fbG9hZFVzZXI6IHVzZXIgc3RvcmFnZVN0cmluZyBsb2FkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXNlci5mcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX2xvYWRVc2VyOiBubyB1c2VyIHN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0b3JlVXNlcih1c2VyKSB7XHJcbiAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc3RvcmVVc2VyOiBzdG9yaW5nIHVzZXJcIik7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RvcmFnZVN0cmluZyA9IHVzZXIudG9TdG9yYWdlU3RyaW5nKCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VyU3RvcmUuc2V0KHRoaXMuX3VzZXJTdG9yZUtleSwgc3RvcmFnZVN0cmluZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJzdG9yZVVzZXIuc3RvcmVVc2VyOiByZW1vdmluZyB1c2VyXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLnJlbW92ZSh0aGlzLl91c2VyU3RvcmVLZXkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEFjY2Vzc1Rva2VuRXZlbnRzIH0gZnJvbSAnLi9BY2Nlc3NUb2tlbkV2ZW50cy5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXNlck1hbmFnZXJFdmVudHMgZXh0ZW5kcyBBY2Nlc3NUb2tlbkV2ZW50cyB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcclxuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgbG9hZGVkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgdW5sb2FkZWRcIik7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvciA9IG5ldyBFdmVudChcIlNpbGVudCByZW5ldyBlcnJvclwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4gPSBuZXcgRXZlbnQoXCJVc2VyIHNpZ25lZCBpblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0ID0gbmV3IEV2ZW50KFwiVXNlciBzaWduZWQgb3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZCA9IG5ldyBFdmVudChcIlVzZXIgc2Vzc2lvbiBjaGFuZ2VkXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGxvYWQodXNlciwgcmFpc2VFdmVudD10cnVlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMubG9hZFwiKTtcclxuICAgICAgICBzdXBlci5sb2FkKHVzZXIpO1xyXG4gICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJMb2FkZWQucmFpc2UodXNlcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdW5sb2FkKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLnVubG9hZFwiKTtcclxuICAgICAgICBzdXBlci51bmxvYWQoKTtcclxuICAgICAgICB0aGlzLl91c2VyVW5sb2FkZWQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyTG9hZGVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJMb2FkZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyTG9hZGVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZFVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5yZW1vdmVIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRTaWxlbnRSZW5ld0Vycm9yKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvci5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVNpbGVudFJlbmV3RXJyb3IoY2IpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld0Vycm9yLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvclwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3RXJyb3IucmFpc2UoZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZEluKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLl9yYWlzZVVzZXJTaWduZWRJblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4ucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2lnbmVkT3V0KGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZE91dC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJTaWduZWRPdXQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0LnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZE91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlckV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkT3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTaWduZWRPdXQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQuYWRkSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICByZW1vdmVVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICBfcmFpc2VVc2VyU2Vzc2lvbkNoYW5nZWQoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlVXNlclNlc3Npb25DaGFuZ2VkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZC5yYWlzZSgpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudFNldHRpbmdzIH0gZnJvbSAnLi9PaWRjQ2xpZW50U2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBSZWRpcmVjdE5hdmlnYXRvciB9IGZyb20gJy4vUmVkaXJlY3ROYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBQb3B1cE5hdmlnYXRvciB9IGZyb20gJy4vUG9wdXBOYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVOYXZpZ2F0b3IgfSBmcm9tICcuL0lGcmFtZU5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IFdlYlN0b3JhZ2VTdGF0ZVN0b3JlIH0gZnJvbSAnLi9XZWJTdG9yYWdlU3RhdGVTdG9yZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuaW1wb3J0IHsgU2lnbmluUmVxdWVzdCB9IGZyb20gJy4vU2lnbmluUmVxdWVzdC5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDtcclxuY29uc3QgRGVmYXVsdENoZWNrU2Vzc2lvbkludGVydmFsID0gMjAwMDtcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyTWFuYWdlclNldHRpbmdzIGV4dGVuZHMgT2lkY0NsaWVudFNldHRpbmdzIHtcclxuICAgIGNvbnN0cnVjdG9yKHtcclxuICAgICAgICBwb3B1cF9yZWRpcmVjdF91cmksXHJcbiAgICAgICAgcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIHBvcHVwV2luZG93RmVhdHVyZXMsXHJcbiAgICAgICAgcG9wdXBXaW5kb3dUYXJnZXQsXHJcbiAgICAgICAgc2lsZW50X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dCxcclxuICAgICAgICBhdXRvbWF0aWNTaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyA9IHRydWUsXHJcbiAgICAgICAgbW9uaXRvclNlc3Npb24gPSB0cnVlLFxyXG4gICAgICAgIG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uID0gZmFsc2UsXHJcbiAgICAgICAgY2hlY2tTZXNzaW9uSW50ZXJ2YWwgPSBEZWZhdWx0Q2hlY2tTZXNzaW9uSW50ZXJ2YWwsXHJcbiAgICAgICAgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IgPSB0cnVlLFxyXG4gICAgICAgIHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlLFxyXG4gICAgICAgIHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0ID0gZmFsc2UsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgcmVkaXJlY3ROYXZpZ2F0b3IgPSBuZXcgUmVkaXJlY3ROYXZpZ2F0b3IoKSxcclxuICAgICAgICBwb3B1cE5hdmlnYXRvciA9IG5ldyBQb3B1cE5hdmlnYXRvcigpLFxyXG4gICAgICAgIGlmcmFtZU5hdmlnYXRvciA9IG5ldyBJRnJhbWVOYXZpZ2F0b3IoKSxcclxuICAgICAgICB1c2VyU3RvcmUgPSBuZXcgV2ViU3RvcmFnZVN0YXRlU3RvcmUoeyBzdG9yZTogR2xvYmFsLnNlc3Npb25TdG9yYWdlIH0pXHJcbiAgICB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICB0aGlzLl9wb3B1cF9yZWRpcmVjdF91cmkgPSBwb3B1cF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXMgPSBwb3B1cFdpbmRvd0ZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0ID0gcG9wdXBXaW5kb3dUYXJnZXQ7XHJcblxyXG4gICAgICAgIHRoaXMuX3NpbGVudF9yZWRpcmVjdF91cmkgPSBzaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlcXVlc3RUaW1lb3V0ID0gc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICAgICAgdGhpcy5fYXV0b21hdGljU2lsZW50UmVuZXcgPSBhdXRvbWF0aWNTaWxlbnRSZW5ldztcclxuICAgICAgICB0aGlzLl92YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXcgPSB2YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXc7XHJcbiAgICAgICAgdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3ID0gaW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX21vbml0b3JTZXNzaW9uID0gbW9uaXRvclNlc3Npb247XHJcbiAgICAgICAgdGhpcy5fbW9uaXRvckFub255bW91c1Nlc3Npb24gPSBtb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JbnRlcnZhbCA9IGNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgICAgIHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yID0gc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICAgICAgaWYgKHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICAgICAgfSBcclxuICAgICAgICBlbHNlIGlmIChhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnJlc3BvbnNlX3R5cGUpIHtcclxuICAgICAgICAgICAgdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUgPSBTaWduaW5SZXF1ZXN0LmlzT2lkYyhhcmd1bWVudHNbMF0ucmVzcG9uc2VfdHlwZSkgPyBcImlkX3Rva2VuXCIgOiBcImNvZGVcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gXCJpZF90b2tlblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9yZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCA9IHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG5cclxuICAgICAgICB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvciA9IHJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwTmF2aWdhdG9yID0gcG9wdXBOYXZpZ2F0b3I7XHJcbiAgICAgICAgdGhpcy5faWZyYW1lTmF2aWdhdG9yID0gaWZyYW1lTmF2aWdhdG9yO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyU3RvcmUgPSB1c2VyU3RvcmU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHBvcHVwX3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwV2luZG93RmVhdHVyZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBXaW5kb3dUYXJnZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzaWxlbnRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgIGdldCBzaWxlbnRSZXF1ZXN0VGltZW91dCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgYXV0b21hdGljU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9tYXRpY1NpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVTdWJPblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9uaXRvclNlc3Npb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vbml0b3JTZXNzaW9uO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgIH1cclxuICAgIGdldCBjaGVja1Nlc3Npb25JbnRlcnZhbCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICB9XHJcbiAgICBnZXQgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCByZWRpcmVjdE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBOYXZpZ2F0b3IoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwTmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IGlmcmFtZU5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faWZyYW1lTmF2aWdhdG9yO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB1c2VyU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VzZXJTdG9yZTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7cHJlZml4ID0gXCJvaWRjLlwiLCBzdG9yZSA9IEdsb2JhbC5sb2NhbFN0b3JhZ2V9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9zdG9yZSA9IHN0b3JlO1xyXG4gICAgICAgIHRoaXMuX3ByZWZpeCA9IHByZWZpeDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnNldFwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIHRoaXMuX3N0b3JlLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQoa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiV2ViU3RvcmFnZVN0YXRlU3RvcmUuZ2V0XCIsIGtleSk7XHJcblxyXG4gICAgICAgIGtleSA9IHRoaXMuX3ByZWZpeCArIGtleTtcclxuXHJcbiAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLl9zdG9yZS5nZXRJdGVtKGtleSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoaXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlKGtleSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnJlbW92ZVwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIGxldCBpdGVtID0gdGhpcy5fc3RvcmUuZ2V0SXRlbShrZXkpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlLnJlbW92ZUl0ZW0oa2V5KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpdGVtKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRBbGxLZXlzKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLmdldEFsbEtleXNcIik7XHJcblxyXG4gICAgICAgIHZhciBrZXlzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLl9zdG9yZS5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgbGV0IGtleSA9IHRoaXMuX3N0b3JlLmtleShpbmRleCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YodGhpcy5fcHJlZml4KSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleS5zdWJzdHIodGhpcy5fcHJlZml4Lmxlbmd0aCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGtleXMpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8qXHJcbkJhc2VkIG9uIHRoZSB3b3JrIG9mIEF1dGgwXHJcbmh0dHBzOi8vZ2l0aHViLmNvbS9hdXRoMC9pZHRva2VuLXZlcmlmaWVyXHJcbmh0dHBzOi8vZ2l0aHViLmNvbS9hdXRoMC9pZHRva2VuLXZlcmlmaWVyL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcclxuV2hpY2ggaXMgYmFzZWQgb24gdGhlIHdvcmsgb2YgVG9tIFd1XHJcbmh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi9cclxuaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL0xJQ0VOU0VcclxuKi9cclxuXHJcbi8qXHJcbiAqIFRvIHN1cHBvcnQgbW9zdCBiYXNpYyBPcGVuSWQgdXNlIGNhc2VzICh1c2luZyBSU0EyNTYpLCB3ZSBjYW4gZ2V0IGF3YXkgd2l0aG91dFxyXG4gKiByZXF1aXJpbmcgdGhlIGZ1bGwganJzYXNpZ24gZmVhdHVyZSBzZXQgKGFuZCByZXN1bHRpbmcgbWFzc2l2ZSBidW5kbGUpLlxyXG4gKlxyXG4gKiAtIFN1cHBvcnQgUlNBIDI1NiBhbGdvcml0aG0gKG9wdGlvbmFsbHkgY291bGQgc3VwcG9ydCBSU0EqIGZhbWlseSlcclxuICogLSBQYXJzZSBKV1QgdG9rZW5zIHVzaW5nIHRoZSAobikgcGFyYW1ldGVyLlxyXG4gKiAtIFZlcmlmeSBzaWduYXR1cmUgb2YgaWRfdG9rZW5zXHJcbiAqIC0gVmVyaWZ5IGF0X2hhc2ggb2YgYWNjZXNzX3Rva2Vuc1xyXG4gKiAtIFBlcmZvcm0gY29tbW9uIGJhc2U2NCBlbmNvZGluZy9kZWNvZGluZyB0YXNrcy5cclxuICovXHJcblxyXG5pbXBvcnQgSlNCTiBmcm9tICdqc2JuJztcclxuaW1wb3J0IFNIQTI1NiBmcm9tICdjcnlwdG8tanMvc2hhMjU2JztcclxuaW1wb3J0IGJhc2U2NEpzIGZyb20gJ2Jhc2U2NC1qcyc7XHJcblxyXG52YXIgQmlnSW50ZWdlciA9IEpTQk4uQmlnSW50ZWdlcjtcclxuXHJcbi8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xyXG4gKi9cclxudmFyIGI2NG1hcCA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiO1xyXG52YXIgYjY0cGFkID0gXCI9XCI7XHJcblxyXG5jb25zdCBCYXNlNjQgPSB7XHJcbiAgICBiNjR0b2hleChzKSB7XHJcbiAgICAgICAgdmFyIHJldCA9IFwiXCI7XHJcbiAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgdmFyIGsgPSAwOyAvLyBiNjQgc3RhdGUsIDAtM1xyXG4gICAgICAgIHZhciBzbG9wO1xyXG4gICAgICAgIGZvcihpID0gMDsgaSA8IHMubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICAgICAgaWYocy5jaGFyQXQoaSkgPT09IGI2NHBhZCkgYnJlYWs7XHJcbiAgICAgICAgICAgIHZhciB2ID0gYjY0bWFwLmluZGV4T2Yocy5jaGFyQXQoaSkpO1xyXG4gICAgICAgICAgICBpZih2IDwgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmKGsgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHYgPj4gMik7XHJcbiAgICAgICAgICAgICAgICBzbG9wID0gdiAmIDM7XHJcbiAgICAgICAgICAgICAgICBrID0gMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmKGsgPT09IDEpIHtcclxuICAgICAgICAgICAgICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChzbG9wIDw8IDIpIHwgKHYgPj4gNCkpO1xyXG4gICAgICAgICAgICAgICAgc2xvcCA9IHYgJiAweGY7XHJcbiAgICAgICAgICAgICAgICBrID0gMjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmKGsgPT09IDIpIHtcclxuICAgICAgICAgICAgICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNsb3ApO1xyXG4gICAgICAgICAgICAgICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodiA+PiAyKTtcclxuICAgICAgICAgICAgICAgIHNsb3AgPSB2ICYgMztcclxuICAgICAgICAgICAgICAgIGsgPSAzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKHNsb3AgPDwgMikgfCAodiA+PiA0KSk7XHJcbiAgICAgICAgICAgICAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh2ICYgMHhmKTtcclxuICAgICAgICAgICAgICAgIGsgPSAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKGsgPT09IDEpXHJcbiAgICAgICAgICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNsb3AgPDwgMik7XHJcbiAgICAgICAgcmV0dXJuIHJldDtcclxuICAgIH0sXHJcbiAgICBoZXhUb0Jhc2U2NChoKSB7XHJcbiAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgdmFyIGM7XHJcbiAgICAgICAgdmFyIHJldCA9IFwiXCI7XHJcbiAgICAgICAgZm9yKGkgPSAwOyBpKzMgPD0gaC5sZW5ndGg7IGkrPTMpIHtcclxuICAgICAgICAgICAgYyA9IHBhcnNlSW50KGguc3Vic3RyaW5nKGksaSszKSwxNik7XHJcbiAgICAgICAgICAgIHJldCArPSBiNjRtYXAuY2hhckF0KGMgPj4gNikgKyBiNjRtYXAuY2hhckF0KGMgJiA2Myk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKGkrMSA9PT0gaC5sZW5ndGgpIHtcclxuICAgICAgICAgICAgYyA9IHBhcnNlSW50KGguc3Vic3RyaW5nKGksaSsxKSwxNik7XHJcbiAgICAgICAgICAgIHJldCArPSBiNjRtYXAuY2hhckF0KGMgPDwgMik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYoaSsyID09PSBoLmxlbmd0aCkge1xyXG4gICAgICAgICAgICBjID0gcGFyc2VJbnQoaC5zdWJzdHJpbmcoaSxpKzIpLDE2KTtcclxuICAgICAgICAgICAgcmV0ICs9IGI2NG1hcC5jaGFyQXQoYyA+PiAyKSArIGI2NG1hcC5jaGFyQXQoKGMgJiAzKSA8PCA0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGI2NHBhZCkgd2hpbGUoKHJldC5sZW5ndGggJiAzKSA+IDApIHJldCArPSBiNjRwYWQ7XHJcbiAgICAgICAgcmV0dXJuIHJldDtcclxuICAgIH0sXHJcblxyXG4gICAgcGFkZGluZyhzdHIpIHtcclxuICAgICAgICB2YXIgbW9kID0gKHN0ci5sZW5ndGggJSA0KTtcclxuICAgICAgICB2YXIgcGFkID0gNCAtIG1vZDtcclxuXHJcbiAgICAgICAgaWYgKG1vZCA9PT0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gc3RyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHN0ciArIChuZXcgQXJyYXkoMSArIHBhZCkpLmpvaW4oJz0nKTtcclxuICAgIH0sXHJcblxyXG4gICAgYnl0ZUFycmF5VG9IZXgocmF3KSB7XHJcbiAgICAgICAgdmFyIEhFWCA9ICcnO1xyXG5cclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhdy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgX2hleCA9IHJhd1tpXS50b1N0cmluZygxNik7XHJcbiAgICAgICAgICAgIEhFWCArPSAoX2hleC5sZW5ndGggPT09IDIgPyBfaGV4IDogJzAnICsgX2hleCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gSEVYO1xyXG4gICAgfSxcclxuXHJcbiAgICBkZWNvZGVUb0hFWChzdHIpIHtcclxuICAgICAgICByZXR1cm4gQmFzZTY0LmJ5dGVBcnJheVRvSGV4KGJhc2U2NEpzLnRvQnl0ZUFycmF5KEJhc2U2NC5wYWRkaW5nKHN0cikpKTtcclxuICAgIH0sXHJcblxyXG4gICAgYmFzZTY0VG9CYXNlNjRVcmwocykge1xyXG4gICAgICAgIHMgPSBzLnJlcGxhY2UoLz0vZywgXCJcIik7XHJcbiAgICAgICAgcyA9IHMucmVwbGFjZSgvXFwrL2csIFwiLVwiKTtcclxuICAgICAgICBzID0gcy5yZXBsYWNlKC9cXC8vZywgXCJfXCIpO1xyXG4gICAgICAgIHJldHVybiBzO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cmxEZWNvZGUoc3RyKSB7XHJcbiAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UoLy0vZywgJysnKSAvLyBDb252ZXJ0ICctJyB0byAnKydcclxuICAgICAgICAgICAgLnJlcGxhY2UoL18vZywgJy8nKSAvLyBDb252ZXJ0ICdfJyB0byAnLydcclxuICAgICAgICAgICAgLnJlcGxhY2UoL1xccy9nLCAnICcpOyAvLyBDb252ZXJ0ICdcXHMnIHRvICcgJ1xyXG5cclxuICAgICAgICByZXR1cm4gYXRvYihzdHIpO1xyXG4gICAgfVxyXG59O1xyXG5cclxuXHJcbnZhciBEaWdlc3RJbmZvSGVhZCA9IHtcclxuICAgIHNoYTE6ICczMDIxMzAwOTA2MDUyYjBlMDMwMjFhMDUwMDA0MTQnLFxyXG4gICAgc2hhMjI0OiAnMzAyZDMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjA0MDUwMDA0MWMnLFxyXG4gICAgc2hhMjU2OiAnMzAzMTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAxMDUwMDA0MjAnLFxyXG4gICAgc2hhMzg0OiAnMzA0MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAyMDUwMDA0MzAnLFxyXG4gICAgc2hhNTEyOiAnMzA1MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAzMDUwMDA0NDAnLFxyXG4gICAgbWQyOiAnMzAyMDMwMGMwNjA4MmE4NjQ4ODZmNzBkMDIwMjA1MDAwNDEwJyxcclxuICAgIG1kNTogJzMwMjAzMDBjMDYwODJhODY0ODg2ZjcwZDAyMDUwNTAwMDQxMCcsXHJcbiAgICByaXBlbWQxNjA6ICczMDIxMzAwOTA2MDUyYjI0MDMwMjAxMDUwMDA0MTQnXHJcbn07XHJcblxyXG52YXIgRGlnZXN0QWxncyA9IHtcclxuICAgIHNoYTI1NjogU0hBMjU2LFxyXG4gICAgU0hBMjU2OlNIQTI1NlxyXG59O1xyXG5cclxuZnVuY3Rpb24gUlNBVmVyaWZpZXIobW9kdWx1cywgZXhwKSB7XHJcbiAgICB0aGlzLm4gPSBudWxsO1xyXG4gICAgdGhpcy5lID0gMDtcclxuXHJcbiAgICBpZiAobW9kdWx1cyAhPSBudWxsICYmIGV4cCAhPSBudWxsICYmIG1vZHVsdXMubGVuZ3RoID4gMCAmJiBleHAubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHRoaXMubiA9IG5ldyBCaWdJbnRlZ2VyKG1vZHVsdXMsIDE2KTtcclxuICAgICAgICB0aGlzLmUgPSBwYXJzZUludChleHAsIDE2KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGtleSBkYXRhJyk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEFsZ29yaXRobUZyb21EaWdlc3QoaERpZ2VzdEluZm8pIHtcclxuICAgIGZvciAodmFyIGFsZ05hbWUgaW4gRGlnZXN0SW5mb0hlYWQpIHtcclxuICAgICAgICB2YXIgaGVhZCA9IERpZ2VzdEluZm9IZWFkW2FsZ05hbWVdO1xyXG4gICAgICAgIHZhciBsZW4gPSBoZWFkLmxlbmd0aDtcclxuXHJcbiAgICAgICAgaWYgKGhEaWdlc3RJbmZvLnN1YnN0cmluZygwLCBsZW4pID09PSBoZWFkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBhbGc6IGFsZ05hbWUsXHJcbiAgICAgICAgICAgICAgICBoYXNoOiBoRGlnZXN0SW5mby5zdWJzdHJpbmcobGVuKVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBbXTtcclxufVxyXG5cclxuXHJcblJTQVZlcmlmaWVyLnByb3RvdHlwZS52ZXJpZnkgPSBmdW5jdGlvbiAobXNnLCBlbmNzaWcpIHtcclxuICAgIGVuY3NpZyA9IEJhc2U2NC5kZWNvZGVUb0hFWChlbmNzaWcpO1xyXG4gICAgZW5jc2lnID0gZW5jc2lnLnJlcGxhY2UoL1teMC05YS1mXXxbXFxzXFxuXV0vaWcsICcnKTtcclxuXHJcbiAgICB2YXIgc2lnID0gbmV3IEJpZ0ludGVnZXIoZW5jc2lnLCAxNik7XHJcblxyXG4gICAgaWYgKHNpZy5iaXRMZW5ndGgoKSA+IHRoaXMubi5iaXRMZW5ndGgoKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignU2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoIHdpdGggdGhlIGtleSBtb2R1bHVzLicpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBkZWNyeXB0ZWRTaWcgPSBzaWcubW9kUG93SW50KHRoaXMuZSwgdGhpcy5uKTtcclxuICAgIHZhciBkaWdlc3QgPSBkZWNyeXB0ZWRTaWcudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sICcnKTtcclxuICAgIHZhciBkaWdlc3RJbmZvID0gZ2V0QWxnb3JpdGhtRnJvbURpZ2VzdChkaWdlc3QpO1xyXG5cclxuICAgIGlmIChkaWdlc3RJbmZvLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIURpZ2VzdEFsZ3MuaGFzT3duUHJvcGVydHkoZGlnZXN0SW5mby5hbGcpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdIYXNoaW5nIGFsZ29yaXRobSBpcyBub3Qgc3VwcG9ydGVkLicpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBtc2dIYXNoID0gRGlnZXN0QWxnc1tkaWdlc3RJbmZvLmFsZ10obXNnKS50b1N0cmluZygpO1xyXG4gICAgcmV0dXJuIChkaWdlc3RJbmZvLmhhc2ggPT09IG1zZ0hhc2gpO1xyXG59O1xyXG5cclxuY29uc3QgQWxsb3dlZFNpZ25pbmdBbGdzID0gWydSUzI1NiddO1xyXG5cclxuY29uc3QgandzID0ge1xyXG4gICAgSldTOiB7XHJcbiAgICAgICAgcGFyc2U6IGZ1bmN0aW9uKHRva2VuKSB7XHJcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHRva2VuLnNwbGl0KCcuJyk7XHJcbiAgICAgICAgICAgIHZhciBoZWFkZXI7XHJcbiAgICAgICAgICAgIHZhciBwYXlsb2FkO1xyXG5cclxuICAgICAgICAgICAgLy8gVGhpcyBkaXZlcmdlcyBmcm9tIEF1dGgwJ3MgaW1wbGVtZW50YXRpb24sIHdoaWNoIHRocm93cyByYXRoZXIgdGhhblxyXG4gICAgICAgICAgICAvLyByZXR1cm5pbmcgdW5kZWZpbmVkXHJcbiAgICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBoZWFkZXIgPSBKU09OLnBhcnNlKEJhc2U2NC51cmxEZWNvZGUocGFydHNbMF0pKTtcclxuICAgICAgICAgICAgICAgIHBheWxvYWQgPSBKU09OLnBhcnNlKEJhc2U2NC51cmxEZWNvZGUocGFydHNbMV0pKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFcnJvcignVG9rZW4gaGVhZGVyIG9yIHBheWxvYWQgaXMgbm90IHZhbGlkIEpTT04nKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGhlYWRlck9iajogaGVhZGVyLFxyXG4gICAgICAgICAgICAgICAgcGF5bG9hZE9iajogcGF5bG9hZCxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHZlcmlmeTogZnVuY3Rpb24oand0LCBrZXksIGFsbG93ZWRTaWduaW5nQWxncyA9IFtdKSB7XHJcbiAgICAgICAgICAgIGFsbG93ZWRTaWduaW5nQWxncy5mb3JFYWNoKChhbGcpID0+IHtcclxuICAgICAgICAgICAgICAgIGlmIChBbGxvd2VkU2lnbmluZ0FsZ3MuaW5kZXhPZihhbGcpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBzaWduaW5nIGFsZ29yaXRobTogJyArIGFsZyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB2YXIgdmVyaWZ5ID0gbmV3IFJTQVZlcmlmaWVyKGtleS5uLCBrZXkuZSk7XHJcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IGp3dC5zcGxpdCgnLicpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGhlYWRlckFuZFBheWxvYWQgPSBbcGFydHNbMF0sIHBhcnRzWzFdXS5qb2luKCcuJyk7XHJcbiAgICAgICAgICAgIHJldHVybiB2ZXJpZnkudmVyaWZ5KGhlYWRlckFuZFBheWxvYWQsIHBhcnRzWzJdKTtcclxuICAgICAgICB9LFxyXG4gICAgfSxcclxufTtcclxuXHJcbmNvbnN0IEtleVV0aWwgPSB7XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgZGVjb2RlZCBrZXlzIGluIEhleCBmb3JtYXQgZm9yIHVzZSBpbiBjcnlwdG8gZnVuY3Rpb25zLlxyXG4gICAgICogU3VwcG9ydHMgbW9kdWx1cy9leHBvbmVudC1zdHlsZSBrZXlzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBrZXkgdGhlIHNlY3VyaXR5IGtleVxyXG4gICAgICogQHJldHVybnNcclxuICAgICAqL1xyXG4gICAgZ2V0S2V5KGtleSkge1xyXG4gICAgICAgIGlmIChrZXkua3R5ID09PSAnUlNBJykge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgZTogQmFzZTY0LmRlY29kZVRvSEVYKGtleS5lKSxcclxuICAgICAgICAgICAgICAgIG46IEJhc2U2NC5kZWNvZGVUb0hFWChrZXkubiksXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgIH0sXHJcbn07XHJcblxyXG5jb25zdCBYNTA5ID0ge1xyXG4gICAgZ2V0UHVibGljS2V5RnJvbUNlcnRQRU06IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkLiBVc2UgdGhlIGZ1bGwgb2lkYy1jbGllbnQgbGlicmFyeSBpZiB5b3UgbmVlZCBzdXBwb3J0IGZvciBYNTA5LicpO1xyXG4gICAgfSxcclxufTtcclxuXHJcbmNvbnN0IGNyeXB0byA9IHtcclxuICAgIFV0aWw6IHtcclxuICAgICAgICBoYXNoU3RyaW5nOiBmdW5jdGlvbih2YWx1ZSwgYWxnKSB7XHJcbiAgICAgICAgICAgIHZhciBoYXNoRnVuYyA9IERpZ2VzdEFsZ3NbYWxnXTtcclxuICAgICAgICAgICAgcmV0dXJuIGhhc2hGdW5jKHZhbHVlKS50b1N0cmluZygpO1xyXG4gICAgICAgIH0sXHJcbiAgICB9XHJcbn07XHJcblxyXG5mdW5jdGlvbiBoZXh0b2I2NHUocykge1xyXG4gICAgaWYgKHMubGVuZ3RoICUgMiA9PT0gMSkge1xyXG4gICAgICAgIHMgPSAnMCcgKyBzO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIEJhc2U2NC5iYXNlNjRUb0Jhc2U2NFVybChCYXNlNjQuaGV4VG9CYXNlNjQocykpO1xyXG59XHJcblxyXG5jb25zdCB7YjY0dG9oZXh9ID0gQmFzZTY0O1xyXG5cclxuZXhwb3J0IHtcclxuICAgIGp3cyxcclxuICAgIEtleVV0aWwsXHJcbiAgICBYNTA5LFxyXG4gICAgY3J5cHRvLFxyXG4gICAgaGV4dG9iNjR1LFxyXG4gICAgYjY0dG9oZXgsXHJcbiAgICBBbGxvd2VkU2lnbmluZ0FsZ3NcclxufTtcclxuIiwiaW1wb3J0IHV1aWQ0IGZyb20gJ3V1aWQvdjQnO1xyXG5cclxuLyoqXHJcbiAqIEdlbmVyYXRlcyBSRkM0MTIyIHZlcnNpb24gNCBndWlkICgpXHJcbiAqL1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmFuZG9tKCkge1xyXG4gIHJldHVybiB1dWlkNCgpLnJlcGxhY2UoLy0vZywgJycpO1xyXG59XHJcbiIsImNvbnN0IFZlcnNpb24gPSBcIjEuMTAuMVwiOyBleHBvcnQge1ZlcnNpb259OyJdLCJzb3VyY2VSb290IjoiIn0="
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/libs/oidc-client.slim.js",
    "content": "var Oidc =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ \"./index.js\":\n/*!******************!*\\\n  !*** ./index.js ***!\n  \\******************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _Log = __webpack_require__(/*! ./src/Log.js */ \"./src/Log.js\");\n\nvar _OidcClient = __webpack_require__(/*! ./src/OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./src/OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./src/WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _InMemoryWebStorage = __webpack_require__(/*! ./src/InMemoryWebStorage.js */ \"./src/InMemoryWebStorage.js\");\n\nvar _UserManager = __webpack_require__(/*! ./src/UserManager.js */ \"./src/UserManager.js\");\n\nvar _AccessTokenEvents = __webpack_require__(/*! ./src/AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./src/MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _CordovaPopupNavigator = __webpack_require__(/*! ./src/CordovaPopupNavigator.js */ \"./src/CordovaPopupNavigator.js\");\n\nvar _CordovaIFrameNavigator = __webpack_require__(/*! ./src/CordovaIFrameNavigator.js */ \"./src/CordovaIFrameNavigator.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./src/CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./src/TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./src/SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _Global = __webpack_require__(/*! ./src/Global.js */ \"./src/Global.js\");\n\nvar _User = __webpack_require__(/*! ./src/User.js */ \"./src/User.js\");\n\nvar _version = __webpack_require__(/*! ./version.js */ \"./version.js\");\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nexports.default = {\n    Version: _version.Version,\n    Log: _Log.Log,\n    OidcClient: _OidcClient.OidcClient,\n    OidcClientSettings: _OidcClientSettings.OidcClientSettings,\n    WebStorageStateStore: _WebStorageStateStore.WebStorageStateStore,\n    InMemoryWebStorage: _InMemoryWebStorage.InMemoryWebStorage,\n    UserManager: _UserManager.UserManager,\n    AccessTokenEvents: _AccessTokenEvents.AccessTokenEvents,\n    MetadataService: _MetadataService.MetadataService,\n    CordovaPopupNavigator: _CordovaPopupNavigator.CordovaPopupNavigator,\n    CordovaIFrameNavigator: _CordovaIFrameNavigator.CordovaIFrameNavigator,\n    CheckSessionIFrame: _CheckSessionIFrame.CheckSessionIFrame,\n    TokenRevocationClient: _TokenRevocationClient.TokenRevocationClient,\n    SessionMonitor: _SessionMonitor.SessionMonitor,\n    Global: _Global.Global,\n    User: _User.User\n};\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./jsrsasign/dist/jsrsasign.js\":\n/*!*************************************!*\\\n  !*** ./jsrsasign/dist/jsrsasign.js ***!\n  \\*************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(Buffer) {\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/*\n * jsrsasign(all) 8.0.12 (2018-04-22) (c) 2010-2018 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n\nvar navigator = {};\nnavigator.userAgent = false;\n\nvar window = {};\n\n/*!\nCopyright (c) 2011, Yahoo! Inc. All rights reserved.\nCode licensed under the BSD License:\nhttp://developer.yahoo.com/yui/license.html\nversion: 2.9.0\n*/\nif (YAHOO === undefined) {\n  var YAHOO = {};\n}YAHOO.lang = { extend: function extend(g, h, f) {\n    if (!h || !g) {\n      throw new Error(\"YAHOO.lang.extend failed, please check that all dependencies are included.\");\n    }var d = function d() {};d.prototype = h.prototype;g.prototype = new d();g.prototype.constructor = g;g.superclass = h.prototype;if (h.prototype.constructor == Object.prototype.constructor) {\n      h.prototype.constructor = h;\n    }if (f) {\n      var b;for (b in f) {\n        g.prototype[b] = f[b];\n      }var e = function e() {},\n          c = [\"toString\", \"valueOf\"];try {\n        if (/MSIE/.test(navigator.userAgent)) {\n          e = function e(j, i) {\n            for (b = 0; b < c.length; b = b + 1) {\n              var l = c[b],\n                  k = i[l];if (typeof k === \"function\" && k != Object.prototype[l]) {\n                j[l] = k;\n              }\n            }\n          };\n        }\n      } catch (a) {}e(g.prototype, f);\n    }\n  } };\n/*! CryptoJS v3.1.2 core-fix.js\n * code.google.com/p/crypto-js\n * (c) 2009-2013 by Jeff Mott. All rights reserved.\n * code.google.com/p/crypto-js/wiki/License\n * THIS IS FIX of 'core.js' to fix Hmac issue.\n * https://code.google.com/p/crypto-js/issues/detail?id=84\n * https://crypto-js.googlecode.com/svn-history/r667/branches/3.x/src/core.js\n */\nvar CryptoJS = CryptoJS || function (e, g) {\n  var a = {};var b = a.lib = {};var j = b.Base = function () {\n    function n() {}return { extend: function extend(p) {\n        n.prototype = this;var o = new n();if (p) {\n          o.mixIn(p);\n        }if (!o.hasOwnProperty(\"init\")) {\n          o.init = function () {\n            o.$super.init.apply(this, arguments);\n          };\n        }o.init.prototype = o;o.$super = this;return o;\n      }, create: function create() {\n        var o = this.extend();o.init.apply(o, arguments);return o;\n      }, init: function init() {}, mixIn: function mixIn(p) {\n        for (var o in p) {\n          if (p.hasOwnProperty(o)) {\n            this[o] = p[o];\n          }\n        }if (p.hasOwnProperty(\"toString\")) {\n          this.toString = p.toString;\n        }\n      }, clone: function clone() {\n        return this.init.prototype.extend(this);\n      } };\n  }();var l = b.WordArray = j.extend({ init: function init(o, n) {\n      o = this.words = o || [];if (n != g) {\n        this.sigBytes = n;\n      } else {\n        this.sigBytes = o.length * 4;\n      }\n    }, toString: function toString(n) {\n      return (n || h).stringify(this);\n    }, concat: function concat(t) {\n      var q = this.words;var p = t.words;var n = this.sigBytes;var s = t.sigBytes;this.clamp();if (n % 4) {\n        for (var r = 0; r < s; r++) {\n          var o = p[r >>> 2] >>> 24 - r % 4 * 8 & 255;q[n + r >>> 2] |= o << 24 - (n + r) % 4 * 8;\n        }\n      } else {\n        for (var r = 0; r < s; r += 4) {\n          q[n + r >>> 2] = p[r >>> 2];\n        }\n      }this.sigBytes += s;return this;\n    }, clamp: function clamp() {\n      var o = this.words;var n = this.sigBytes;o[n >>> 2] &= 4294967295 << 32 - n % 4 * 8;o.length = e.ceil(n / 4);\n    }, clone: function clone() {\n      var n = j.clone.call(this);n.words = this.words.slice(0);return n;\n    }, random: function random(p) {\n      var o = [];for (var n = 0; n < p; n += 4) {\n        o.push(e.random() * 4294967296 | 0);\n      }return new l.init(o, p);\n    } });var m = a.enc = {};var h = m.Hex = { stringify: function stringify(p) {\n      var r = p.words;var o = p.sigBytes;var q = [];for (var n = 0; n < o; n++) {\n        var s = r[n >>> 2] >>> 24 - n % 4 * 8 & 255;q.push((s >>> 4).toString(16));q.push((s & 15).toString(16));\n      }return q.join(\"\");\n    }, parse: function parse(p) {\n      var n = p.length;var q = [];for (var o = 0; o < n; o += 2) {\n        q[o >>> 3] |= parseInt(p.substr(o, 2), 16) << 24 - o % 8 * 4;\n      }return new l.init(q, n / 2);\n    } };var d = m.Latin1 = { stringify: function stringify(q) {\n      var r = q.words;var p = q.sigBytes;var n = [];for (var o = 0; o < p; o++) {\n        var s = r[o >>> 2] >>> 24 - o % 4 * 8 & 255;n.push(String.fromCharCode(s));\n      }return n.join(\"\");\n    }, parse: function parse(p) {\n      var n = p.length;var q = [];for (var o = 0; o < n; o++) {\n        q[o >>> 2] |= (p.charCodeAt(o) & 255) << 24 - o % 4 * 8;\n      }return new l.init(q, n);\n    } };var c = m.Utf8 = { stringify: function stringify(n) {\n      try {\n        return decodeURIComponent(escape(d.stringify(n)));\n      } catch (o) {\n        throw new Error(\"Malformed UTF-8 data\");\n      }\n    }, parse: function parse(n) {\n      return d.parse(unescape(encodeURIComponent(n)));\n    } };var i = b.BufferedBlockAlgorithm = j.extend({ reset: function reset() {\n      this._data = new l.init();this._nDataBytes = 0;\n    }, _append: function _append(n) {\n      if (typeof n == \"string\") {\n        n = c.parse(n);\n      }this._data.concat(n);this._nDataBytes += n.sigBytes;\n    }, _process: function _process(w) {\n      var q = this._data;var x = q.words;var n = q.sigBytes;var t = this.blockSize;var v = t * 4;var u = n / v;if (w) {\n        u = e.ceil(u);\n      } else {\n        u = e.max((u | 0) - this._minBufferSize, 0);\n      }var s = u * t;var r = e.min(s * 4, n);if (s) {\n        for (var p = 0; p < s; p += t) {\n          this._doProcessBlock(x, p);\n        }var o = x.splice(0, s);q.sigBytes -= r;\n      }return new l.init(o, r);\n    }, clone: function clone() {\n      var n = j.clone.call(this);n._data = this._data.clone();return n;\n    }, _minBufferSize: 0 });var f = b.Hasher = i.extend({ cfg: j.extend(), init: function init(n) {\n      this.cfg = this.cfg.extend(n);this.reset();\n    }, reset: function reset() {\n      i.reset.call(this);this._doReset();\n    }, update: function update(n) {\n      this._append(n);this._process();return this;\n    }, finalize: function finalize(n) {\n      if (n) {\n        this._append(n);\n      }var o = this._doFinalize();return o;\n    }, blockSize: 512 / 32, _createHelper: function _createHelper(n) {\n      return function (p, o) {\n        return new n.init(o).finalize(p);\n      };\n    }, _createHmacHelper: function _createHmacHelper(n) {\n      return function (p, o) {\n        return new k.HMAC.init(n, o).finalize(p);\n      };\n    } });var k = a.algo = {};return a;\n}(Math);\n/*\nCryptoJS v3.1.2 x64-core-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (g) {\n  var a = CryptoJS,\n      f = a.lib,\n      e = f.Base,\n      h = f.WordArray,\n      a = a.x64 = {};a.Word = e.extend({ init: function init(b, c) {\n      this.high = b;this.low = c;\n    } });a.WordArray = e.extend({ init: function init(b, c) {\n      b = this.words = b || [];this.sigBytes = c != g ? c : 8 * b.length;\n    }, toX32: function toX32() {\n      for (var b = this.words, c = b.length, a = [], d = 0; d < c; d++) {\n        var e = b[d];a.push(e.high);a.push(e.low);\n      }return h.create(a, this.sigBytes);\n    }, clone: function clone() {\n      for (var b = e.clone.call(this), c = b.words = this.words.slice(0), a = c.length, d = 0; d < a; d++) {\n        c[d] = c[d].clone();\n      }return b;\n    } });\n})();\n\n/*\nCryptoJS v3.1.2 enc-base64.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  var h = CryptoJS,\n      j = h.lib.WordArray;h.enc.Base64 = { stringify: function stringify(b) {\n      var e = b.words,\n          f = b.sigBytes,\n          c = this._map;b.clamp();b = [];for (var a = 0; a < f; a += 3) {\n        for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) {\n          b.push(c.charAt(d >>> 6 * (3 - g) & 63));\n        }\n      }if (e = c.charAt(64)) for (; b.length % 4;) {\n        b.push(e);\n      }return b.join(\"\");\n    }, parse: function parse(b) {\n      var e = b.length,\n          f = this._map,\n          c = f.charAt(64);c && (c = b.indexOf(c), -1 != c && (e = c));for (var c = [], a = 0, d = 0; d < e; d++) {\n        if (d % 4) {\n          var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4),\n              h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4);c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4);a++;\n        }\n      }return j.create(c, a);\n    }, _map: \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\" };\n})();\n\n/*\nCryptoJS v3.1.2 sha256-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (k) {\n  for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function u(q) {\n    return 4294967296 * (q - (q | 0)) | 0;\n  }, l = 2, b = 0; 64 > b;) {\n    var d;a: {\n      d = l;for (var w = k.sqrt(d), r = 2; r <= w; r++) {\n        if (!(d % r)) {\n          d = !1;break a;\n        }\n      }d = !0;\n    }d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++);l++;\n  }var n = [],\n      h = h.SHA256 = j.extend({ _doReset: function _doReset() {\n      this._hash = new v.init(s.slice(0));\n    }, _doProcessBlock: function _doProcessBlock(q, h) {\n      for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) {\n        if (16 > e) n[e] = q[h + e] | 0;else {\n          var m = n[e - 15],\n              p = n[e - 2];n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16];\n        }m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e];p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b);l = j;j = g;g = f;f = k + m | 0;k = b;b = d;d = c;c = m + p | 0;\n      }a[0] = a[0] + c | 0;a[1] = a[1] + d | 0;a[2] = a[2] + b | 0;a[3] = a[3] + k | 0;a[4] = a[4] + f | 0;a[5] = a[5] + g | 0;a[6] = a[6] + j | 0;a[7] = a[7] + l | 0;\n    }, _doFinalize: function _doFinalize() {\n      var d = this._data,\n          b = d.words,\n          a = 8 * this._nDataBytes,\n          c = 8 * d.sigBytes;\n      b[c >>> 5] |= 128 << 24 - c % 32;b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296);b[(c + 64 >>> 9 << 4) + 15] = a;d.sigBytes = 4 * b.length;this._process();return this._hash;\n    }, clone: function clone() {\n      var b = j.clone.call(this);b._hash = this._hash.clone();return b;\n    } });g.SHA256 = j._createHelper(h);g.HmacSHA256 = j._createHmacHelper(h);\n})(Math);\n\n/*\nCryptoJS v3.1.2 sha512-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  function a() {\n    return d.create.apply(d, arguments);\n  }for (var n = CryptoJS, r = n.lib.Hasher, e = n.x64, d = e.Word, T = e.WordArray, e = n.algo, ea = [a(1116352408, 3609767458), a(1899447441, 602891725), a(3049323471, 3964484399), a(3921009573, 2173295548), a(961987163, 4081628472), a(1508970993, 3053834265), a(2453635748, 2937671579), a(2870763221, 3664609560), a(3624381080, 2734883394), a(310598401, 1164996542), a(607225278, 1323610764), a(1426881987, 3590304994), a(1925078388, 4068182383), a(2162078206, 991336113), a(2614888103, 633803317), a(3248222580, 3479774868), a(3835390401, 2666613458), a(4022224774, 944711139), a(264347078, 2341262773), a(604807628, 2007800933), a(770255983, 1495990901), a(1249150122, 1856431235), a(1555081692, 3175218132), a(1996064986, 2198950837), a(2554220882, 3999719339), a(2821834349, 766784016), a(2952996808, 2566594879), a(3210313671, 3203337956), a(3336571891, 1034457026), a(3584528711, 2466948901), a(113926993, 3758326383), a(338241895, 168717936), a(666307205, 1188179964), a(773529912, 1546045734), a(1294757372, 1522805485), a(1396182291, 2643833823), a(1695183700, 2343527390), a(1986661051, 1014477480), a(2177026350, 1206759142), a(2456956037, 344077627), a(2730485921, 1290863460), a(2820302411, 3158454273), a(3259730800, 3505952657), a(3345764771, 106217008), a(3516065817, 3606008344), a(3600352804, 1432725776), a(4094571909, 1467031594), a(275423344, 851169720), a(430227734, 3100823752), a(506948616, 1363258195), a(659060556, 3750685593), a(883997877, 3785050280), a(958139571, 3318307427), a(1322822218, 3812723403), a(1537002063, 2003034995), a(1747873779, 3602036899), a(1955562222, 1575990012), a(2024104815, 1125592928), a(2227730452, 2716904306), a(2361852424, 442776044), a(2428436474, 593698344), a(2756734187, 3733110249), a(3204031479, 2999351573), a(3329325298, 3815920427), a(3391569614, 3928383900), a(3515267271, 566280711), a(3940187606, 3454069534), a(4118630271, 4000239992), a(116418474, 1914138554), a(174292421, 2731055270), a(289380356, 3203993006), a(460393269, 320620315), a(685471733, 587496836), a(852142971, 1086792851), a(1017036298, 365543100), a(1126000580, 2618297676), a(1288033470, 3409855158), a(1501505948, 4234509866), a(1607167915, 987167468), a(1816402316, 1246189591)], v = [], w = 0; 80 > w; w++) {\n    v[w] = a();\n  }e = e.SHA512 = r.extend({ _doReset: function _doReset() {\n      this._hash = new T.init([new d.init(1779033703, 4089235720), new d.init(3144134277, 2227873595), new d.init(1013904242, 4271175723), new d.init(2773480762, 1595750129), new d.init(1359893119, 2917565137), new d.init(2600822924, 725511199), new d.init(528734635, 4215389547), new d.init(1541459225, 327033209)]);\n    }, _doProcessBlock: function _doProcessBlock(a, d) {\n      for (var f = this._hash.words, F = f[0], e = f[1], n = f[2], r = f[3], G = f[4], H = f[5], I = f[6], f = f[7], w = F.high, J = F.low, X = e.high, K = e.low, Y = n.high, L = n.low, Z = r.high, M = r.low, $ = G.high, N = G.low, aa = H.high, O = H.low, ba = I.high, P = I.low, ca = f.high, Q = f.low, k = w, g = J, z = X, x = K, A = Y, y = L, U = Z, B = M, l = $, h = N, R = aa, C = O, S = ba, D = P, V = ca, E = Q, m = 0; 80 > m; m++) {\n        var s = v[m];if (16 > m) var j = s.high = a[d + 2 * m] | 0,\n            b = s.low = a[d + 2 * m + 1] | 0;else {\n          var j = v[m - 15],\n              b = j.high,\n              p = j.low,\n              j = (b >>> 1 | p << 31) ^ (b >>> 8 | p << 24) ^ b >>> 7,\n              p = (p >>> 1 | b << 31) ^ (p >>> 8 | b << 24) ^ (p >>> 7 | b << 25),\n              u = v[m - 2],\n              b = u.high,\n              c = u.low,\n              u = (b >>> 19 | c << 13) ^ (b << 3 | c >>> 29) ^ b >>> 6,\n              c = (c >>> 19 | b << 13) ^ (c << 3 | b >>> 29) ^ (c >>> 6 | b << 26),\n              b = v[m - 7],\n              W = b.high,\n              t = v[m - 16],\n              q = t.high,\n              t = t.low,\n              b = p + b.low,\n              j = j + W + (b >>> 0 < p >>> 0 ? 1 : 0),\n              b = b + c,\n              j = j + u + (b >>> 0 < c >>> 0 ? 1 : 0),\n              b = b + t,\n              j = j + q + (b >>> 0 < t >>> 0 ? 1 : 0);s.high = j;s.low = b;\n        }var W = l & R ^ ~l & S,\n            t = h & C ^ ~h & D,\n            s = k & z ^ k & A ^ z & A,\n            T = g & x ^ g & y ^ x & y,\n            p = (k >>> 28 | g << 4) ^ (k << 30 | g >>> 2) ^ (k << 25 | g >>> 7),\n            u = (g >>> 28 | k << 4) ^ (g << 30 | k >>> 2) ^ (g << 25 | k >>> 7),\n            c = ea[m],\n            fa = c.high,\n            da = c.low,\n            c = E + ((h >>> 14 | l << 18) ^ (h >>> 18 | l << 14) ^ (h << 23 | l >>> 9)),\n            q = V + ((l >>> 14 | h << 18) ^ (l >>> 18 | h << 14) ^ (l << 23 | h >>> 9)) + (c >>> 0 < E >>> 0 ? 1 : 0),\n            c = c + t,\n            q = q + W + (c >>> 0 < t >>> 0 ? 1 : 0),\n            c = c + da,\n            q = q + fa + (c >>> 0 < da >>> 0 ? 1 : 0),\n            c = c + b,\n            q = q + j + (c >>> 0 < b >>> 0 ? 1 : 0),\n            b = u + T,\n            s = p + s + (b >>> 0 < u >>> 0 ? 1 : 0),\n            V = S,\n            E = D,\n            S = R,\n            D = C,\n            R = l,\n            C = h,\n            h = B + c | 0,\n            l = U + q + (h >>> 0 < B >>> 0 ? 1 : 0) | 0,\n            U = A,\n            B = y,\n            A = z,\n            y = x,\n            z = k,\n            x = g,\n            g = c + b | 0,\n            k = q + s + (g >>> 0 < c >>> 0 ? 1 : 0) | 0;\n      }J = F.low = J + g;F.high = w + k + (J >>> 0 < g >>> 0 ? 1 : 0);K = e.low = K + x;e.high = X + z + (K >>> 0 < x >>> 0 ? 1 : 0);L = n.low = L + y;n.high = Y + A + (L >>> 0 < y >>> 0 ? 1 : 0);M = r.low = M + B;r.high = Z + U + (M >>> 0 < B >>> 0 ? 1 : 0);N = G.low = N + h;G.high = $ + l + (N >>> 0 < h >>> 0 ? 1 : 0);O = H.low = O + C;H.high = aa + R + (O >>> 0 < C >>> 0 ? 1 : 0);P = I.low = P + D;\n      I.high = ba + S + (P >>> 0 < D >>> 0 ? 1 : 0);Q = f.low = Q + E;f.high = ca + V + (Q >>> 0 < E >>> 0 ? 1 : 0);\n    }, _doFinalize: function _doFinalize() {\n      var a = this._data,\n          d = a.words,\n          f = 8 * this._nDataBytes,\n          e = 8 * a.sigBytes;d[e >>> 5] |= 128 << 24 - e % 32;d[(e + 128 >>> 10 << 5) + 30] = Math.floor(f / 4294967296);d[(e + 128 >>> 10 << 5) + 31] = f;a.sigBytes = 4 * d.length;this._process();return this._hash.toX32();\n    }, clone: function clone() {\n      var a = r.clone.call(this);a._hash = this._hash.clone();return a;\n    }, blockSize: 32 });n.SHA512 = r._createHelper(e);n.HmacSHA512 = r._createHmacHelper(e);\n})();\n\n/*\nCryptoJS v3.1.2 sha384-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  var c = CryptoJS,\n      a = c.x64,\n      b = a.Word,\n      e = a.WordArray,\n      a = c.algo,\n      d = a.SHA512,\n      a = a.SHA384 = d.extend({ _doReset: function _doReset() {\n      this._hash = new e.init([new b.init(3418070365, 3238371032), new b.init(1654270250, 914150663), new b.init(2438529370, 812702999), new b.init(355462360, 4144912697), new b.init(1731405415, 4290775857), new b.init(2394180231, 1750603025), new b.init(3675008525, 1694076839), new b.init(1203062813, 3204075428)]);\n    }, _doFinalize: function _doFinalize() {\n      var a = d._doFinalize.call(this);a.sigBytes -= 16;return a;\n    } });c.SHA384 = d._createHelper(a);c.HmacSHA384 = d._createHmacHelper(a);\n})();\n\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar b64map = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";var b64pad = \"=\";function hex2b64(d) {\n  var b;var e;var a = \"\";for (b = 0; b + 3 <= d.length; b += 3) {\n    e = parseInt(d.substring(b, b + 3), 16);a += b64map.charAt(e >> 6) + b64map.charAt(e & 63);\n  }if (b + 1 == d.length) {\n    e = parseInt(d.substring(b, b + 1), 16);a += b64map.charAt(e << 2);\n  } else {\n    if (b + 2 == d.length) {\n      e = parseInt(d.substring(b, b + 2), 16);a += b64map.charAt(e >> 2) + b64map.charAt((e & 3) << 4);\n    }\n  }if (b64pad) {\n    while ((a.length & 3) > 0) {\n      a += b64pad;\n    }\n  }return a;\n}function b64tohex(f) {\n  var d = \"\";var e;var b = 0;var c;var a;for (e = 0; e < f.length; ++e) {\n    if (f.charAt(e) == b64pad) {\n      break;\n    }a = b64map.indexOf(f.charAt(e));if (a < 0) {\n      continue;\n    }if (b == 0) {\n      d += int2char(a >> 2);c = a & 3;b = 1;\n    } else {\n      if (b == 1) {\n        d += int2char(c << 2 | a >> 4);c = a & 15;b = 2;\n      } else {\n        if (b == 2) {\n          d += int2char(c);d += int2char(a >> 2);c = a & 3;b = 3;\n        } else {\n          d += int2char(c << 2 | a >> 4);d += int2char(a & 15);b = 0;\n        }\n      }\n    }\n  }if (b == 1) {\n    d += int2char(c << 2);\n  }return d;\n}function b64toBA(e) {\n  var d = b64tohex(e);var c;var b = new Array();for (c = 0; 2 * c < d.length; ++c) {\n    b[c] = parseInt(d.substring(2 * c, 2 * c + 2), 16);\n  }return b;\n};\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar dbits;var canary = 244837814094590;var j_lm = (canary & 16777215) == 15715070;function BigInteger(e, d, f) {\n  if (e != null) {\n    if (\"number\" == typeof e) {\n      this.fromNumber(e, d, f);\n    } else {\n      if (d == null && \"string\" != typeof e) {\n        this.fromString(e, 256);\n      } else {\n        this.fromString(e, d);\n      }\n    }\n  }\n}function nbi() {\n  return new BigInteger(null);\n}function am1(f, a, b, e, h, g) {\n  while (--g >= 0) {\n    var d = a * this[f++] + b[e] + h;h = Math.floor(d / 67108864);b[e++] = d & 67108863;\n  }return h;\n}function am2(f, q, r, e, o, a) {\n  var k = q & 32767,\n      p = q >> 15;while (--a >= 0) {\n    var d = this[f] & 32767;var g = this[f++] >> 15;var b = p * d + g * k;d = k * d + ((b & 32767) << 15) + r[e] + (o & 1073741823);o = (d >>> 30) + (b >>> 15) + p * g + (o >>> 30);r[e++] = d & 1073741823;\n  }return o;\n}function am3(f, q, r, e, o, a) {\n  var k = q & 16383,\n      p = q >> 14;while (--a >= 0) {\n    var d = this[f] & 16383;var g = this[f++] >> 14;var b = p * d + g * k;d = k * d + ((b & 16383) << 14) + r[e] + o;o = (d >> 28) + (b >> 14) + p * g;r[e++] = d & 268435455;\n  }return o;\n}if (j_lm && navigator.appName == \"Microsoft Internet Explorer\") {\n  BigInteger.prototype.am = am2;dbits = 30;\n} else {\n  if (j_lm && navigator.appName != \"Netscape\") {\n    BigInteger.prototype.am = am1;dbits = 26;\n  } else {\n    BigInteger.prototype.am = am3;dbits = 28;\n  }\n}BigInteger.prototype.DB = dbits;BigInteger.prototype.DM = (1 << dbits) - 1;BigInteger.prototype.DV = 1 << dbits;var BI_FP = 52;BigInteger.prototype.FV = Math.pow(2, BI_FP);BigInteger.prototype.F1 = BI_FP - dbits;BigInteger.prototype.F2 = 2 * dbits - BI_FP;var BI_RM = \"0123456789abcdefghijklmnopqrstuvwxyz\";var BI_RC = new Array();var rr, vv;rr = \"0\".charCodeAt(0);for (vv = 0; vv <= 9; ++vv) {\n  BI_RC[rr++] = vv;\n}rr = \"a\".charCodeAt(0);for (vv = 10; vv < 36; ++vv) {\n  BI_RC[rr++] = vv;\n}rr = \"A\".charCodeAt(0);for (vv = 10; vv < 36; ++vv) {\n  BI_RC[rr++] = vv;\n}function int2char(a) {\n  return BI_RM.charAt(a);\n}function intAt(b, a) {\n  var d = BI_RC[b.charCodeAt(a)];return d == null ? -1 : d;\n}function bnpCopyTo(b) {\n  for (var a = this.t - 1; a >= 0; --a) {\n    b[a] = this[a];\n  }b.t = this.t;b.s = this.s;\n}function bnpFromInt(a) {\n  this.t = 1;this.s = a < 0 ? -1 : 0;if (a > 0) {\n    this[0] = a;\n  } else {\n    if (a < -1) {\n      this[0] = a + this.DV;\n    } else {\n      this.t = 0;\n    }\n  }\n}function nbv(a) {\n  var b = nbi();b.fromInt(a);return b;\n}function bnpFromString(h, c) {\n  var e;if (c == 16) {\n    e = 4;\n  } else {\n    if (c == 8) {\n      e = 3;\n    } else {\n      if (c == 256) {\n        e = 8;\n      } else {\n        if (c == 2) {\n          e = 1;\n        } else {\n          if (c == 32) {\n            e = 5;\n          } else {\n            if (c == 4) {\n              e = 2;\n            } else {\n              this.fromRadix(h, c);return;\n            }\n          }\n        }\n      }\n    }\n  }this.t = 0;this.s = 0;var g = h.length,\n      d = false,\n      f = 0;while (--g >= 0) {\n    var a = e == 8 ? h[g] & 255 : intAt(h, g);if (a < 0) {\n      if (h.charAt(g) == \"-\") {\n        d = true;\n      }continue;\n    }d = false;if (f == 0) {\n      this[this.t++] = a;\n    } else {\n      if (f + e > this.DB) {\n        this[this.t - 1] |= (a & (1 << this.DB - f) - 1) << f;this[this.t++] = a >> this.DB - f;\n      } else {\n        this[this.t - 1] |= a << f;\n      }\n    }f += e;if (f >= this.DB) {\n      f -= this.DB;\n    }\n  }if (e == 8 && (h[0] & 128) != 0) {\n    this.s = -1;if (f > 0) {\n      this[this.t - 1] |= (1 << this.DB - f) - 1 << f;\n    }\n  }this.clamp();if (d) {\n    BigInteger.ZERO.subTo(this, this);\n  }\n}function bnpClamp() {\n  var a = this.s & this.DM;while (this.t > 0 && this[this.t - 1] == a) {\n    --this.t;\n  }\n}function bnToString(c) {\n  if (this.s < 0) {\n    return \"-\" + this.negate().toString(c);\n  }var e;if (c == 16) {\n    e = 4;\n  } else {\n    if (c == 8) {\n      e = 3;\n    } else {\n      if (c == 2) {\n        e = 1;\n      } else {\n        if (c == 32) {\n          e = 5;\n        } else {\n          if (c == 4) {\n            e = 2;\n          } else {\n            return this.toRadix(c);\n          }\n        }\n      }\n    }\n  }var g = (1 << e) - 1,\n      l,\n      a = false,\n      h = \"\",\n      f = this.t;var j = this.DB - f * this.DB % e;if (f-- > 0) {\n    if (j < this.DB && (l = this[f] >> j) > 0) {\n      a = true;h = int2char(l);\n    }while (f >= 0) {\n      if (j < e) {\n        l = (this[f] & (1 << j) - 1) << e - j;l |= this[--f] >> (j += this.DB - e);\n      } else {\n        l = this[f] >> (j -= e) & g;if (j <= 0) {\n          j += this.DB;--f;\n        }\n      }if (l > 0) {\n        a = true;\n      }if (a) {\n        h += int2char(l);\n      }\n    }\n  }return a ? h : \"0\";\n}function bnNegate() {\n  var a = nbi();BigInteger.ZERO.subTo(this, a);return a;\n}function bnAbs() {\n  return this.s < 0 ? this.negate() : this;\n}function bnCompareTo(b) {\n  var d = this.s - b.s;if (d != 0) {\n    return d;\n  }var c = this.t;d = c - b.t;if (d != 0) {\n    return this.s < 0 ? -d : d;\n  }while (--c >= 0) {\n    if ((d = this[c] - b[c]) != 0) {\n      return d;\n    }\n  }return 0;\n}function nbits(a) {\n  var c = 1,\n      b;if ((b = a >>> 16) != 0) {\n    a = b;c += 16;\n  }if ((b = a >> 8) != 0) {\n    a = b;c += 8;\n  }if ((b = a >> 4) != 0) {\n    a = b;c += 4;\n  }if ((b = a >> 2) != 0) {\n    a = b;c += 2;\n  }if ((b = a >> 1) != 0) {\n    a = b;c += 1;\n  }return c;\n}function bnBitLength() {\n  if (this.t <= 0) {\n    return 0;\n  }return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ this.s & this.DM);\n}function bnpDLShiftTo(c, b) {\n  var a;for (a = this.t - 1; a >= 0; --a) {\n    b[a + c] = this[a];\n  }for (a = c - 1; a >= 0; --a) {\n    b[a] = 0;\n  }b.t = this.t + c;b.s = this.s;\n}function bnpDRShiftTo(c, b) {\n  for (var a = c; a < this.t; ++a) {\n    b[a - c] = this[a];\n  }b.t = Math.max(this.t - c, 0);b.s = this.s;\n}function bnpLShiftTo(j, e) {\n  var b = j % this.DB;var a = this.DB - b;var g = (1 << a) - 1;var f = Math.floor(j / this.DB),\n      h = this.s << b & this.DM,\n      d;for (d = this.t - 1; d >= 0; --d) {\n    e[d + f + 1] = this[d] >> a | h;h = (this[d] & g) << b;\n  }for (d = f - 1; d >= 0; --d) {\n    e[d] = 0;\n  }e[f] = h;e.t = this.t + f + 1;e.s = this.s;e.clamp();\n}function bnpRShiftTo(g, d) {\n  d.s = this.s;var e = Math.floor(g / this.DB);if (e >= this.t) {\n    d.t = 0;return;\n  }var b = g % this.DB;var a = this.DB - b;var f = (1 << b) - 1;d[0] = this[e] >> b;for (var c = e + 1; c < this.t; ++c) {\n    d[c - e - 1] |= (this[c] & f) << a;d[c - e] = this[c] >> b;\n  }if (b > 0) {\n    d[this.t - e - 1] |= (this.s & f) << a;\n  }d.t = this.t - e;d.clamp();\n}function bnpSubTo(d, f) {\n  var e = 0,\n      g = 0,\n      b = Math.min(d.t, this.t);while (e < b) {\n    g += this[e] - d[e];f[e++] = g & this.DM;g >>= this.DB;\n  }if (d.t < this.t) {\n    g -= d.s;while (e < this.t) {\n      g += this[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += this.s;\n  } else {\n    g += this.s;while (e < d.t) {\n      g -= d[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g -= d.s;\n  }f.s = g < 0 ? -1 : 0;if (g < -1) {\n    f[e++] = this.DV + g;\n  } else {\n    if (g > 0) {\n      f[e++] = g;\n    }\n  }f.t = e;f.clamp();\n}function bnpMultiplyTo(c, e) {\n  var b = this.abs(),\n      f = c.abs();var d = b.t;e.t = d + f.t;while (--d >= 0) {\n    e[d] = 0;\n  }for (d = 0; d < f.t; ++d) {\n    e[d + b.t] = b.am(0, f[d], e, d, 0, b.t);\n  }e.s = 0;e.clamp();if (this.s != c.s) {\n    BigInteger.ZERO.subTo(e, e);\n  }\n}function bnpSquareTo(d) {\n  var a = this.abs();var b = d.t = 2 * a.t;while (--b >= 0) {\n    d[b] = 0;\n  }for (b = 0; b < a.t - 1; ++b) {\n    var e = a.am(b, a[b], d, 2 * b, 0, 1);if ((d[b + a.t] += a.am(b + 1, 2 * a[b], d, 2 * b + 1, e, a.t - b - 1)) >= a.DV) {\n      d[b + a.t] -= a.DV;d[b + a.t + 1] = 1;\n    }\n  }if (d.t > 0) {\n    d[d.t - 1] += a.am(b, a[b], d, 2 * b, 0, 1);\n  }d.s = 0;d.clamp();\n}function bnpDivRemTo(n, h, g) {\n  var w = n.abs();if (w.t <= 0) {\n    return;\n  }var k = this.abs();if (k.t < w.t) {\n    if (h != null) {\n      h.fromInt(0);\n    }if (g != null) {\n      this.copyTo(g);\n    }return;\n  }if (g == null) {\n    g = nbi();\n  }var d = nbi(),\n      a = this.s,\n      l = n.s;var v = this.DB - nbits(w[w.t - 1]);if (v > 0) {\n    w.lShiftTo(v, d);k.lShiftTo(v, g);\n  } else {\n    w.copyTo(d);k.copyTo(g);\n  }var p = d.t;var b = d[p - 1];if (b == 0) {\n    return;\n  }var o = b * (1 << this.F1) + (p > 1 ? d[p - 2] >> this.F2 : 0);var A = this.FV / o,\n      z = (1 << this.F1) / o,\n      x = 1 << this.F2;var u = g.t,\n      s = u - p,\n      f = h == null ? nbi() : h;d.dlShiftTo(s, f);if (g.compareTo(f) >= 0) {\n    g[g.t++] = 1;g.subTo(f, g);\n  }BigInteger.ONE.dlShiftTo(p, f);f.subTo(d, d);while (d.t < p) {\n    d[d.t++] = 0;\n  }while (--s >= 0) {\n    var c = g[--u] == b ? this.DM : Math.floor(g[u] * A + (g[u - 1] + x) * z);if ((g[u] += d.am(0, c, g, s, 0, p)) < c) {\n      d.dlShiftTo(s, f);g.subTo(f, g);while (g[u] < --c) {\n        g.subTo(f, g);\n      }\n    }\n  }if (h != null) {\n    g.drShiftTo(p, h);if (a != l) {\n      BigInteger.ZERO.subTo(h, h);\n    }\n  }g.t = p;g.clamp();if (v > 0) {\n    g.rShiftTo(v, g);\n  }if (a < 0) {\n    BigInteger.ZERO.subTo(g, g);\n  }\n}function bnMod(b) {\n  var c = nbi();this.abs().divRemTo(b, null, c);if (this.s < 0 && c.compareTo(BigInteger.ZERO) > 0) {\n    b.subTo(c, c);\n  }return c;\n}function Classic(a) {\n  this.m = a;\n}function cConvert(a) {\n  if (a.s < 0 || a.compareTo(this.m) >= 0) {\n    return a.mod(this.m);\n  } else {\n    return a;\n  }\n}function cRevert(a) {\n  return a;\n}function cReduce(a) {\n  a.divRemTo(this.m, null, a);\n}function cMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}function cSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}Classic.prototype.convert = cConvert;Classic.prototype.revert = cRevert;Classic.prototype.reduce = cReduce;Classic.prototype.mulTo = cMulTo;Classic.prototype.sqrTo = cSqrTo;function bnpInvDigit() {\n  if (this.t < 1) {\n    return 0;\n  }var a = this[0];if ((a & 1) == 0) {\n    return 0;\n  }var b = a & 3;b = b * (2 - (a & 15) * b) & 15;b = b * (2 - (a & 255) * b) & 255;b = b * (2 - ((a & 65535) * b & 65535)) & 65535;b = b * (2 - a * b % this.DV) % this.DV;return b > 0 ? this.DV - b : -b;\n}function Montgomery(a) {\n  this.m = a;this.mp = a.invDigit();this.mpl = this.mp & 32767;this.mph = this.mp >> 15;this.um = (1 << a.DB - 15) - 1;this.mt2 = 2 * a.t;\n}function montConvert(a) {\n  var b = nbi();a.abs().dlShiftTo(this.m.t, b);b.divRemTo(this.m, null, b);if (a.s < 0 && b.compareTo(BigInteger.ZERO) > 0) {\n    this.m.subTo(b, b);\n  }return b;\n}function montRevert(a) {\n  var b = nbi();a.copyTo(b);this.reduce(b);return b;\n}function montReduce(a) {\n  while (a.t <= this.mt2) {\n    a[a.t++] = 0;\n  }for (var c = 0; c < this.m.t; ++c) {\n    var b = a[c] & 32767;var d = b * this.mpl + ((b * this.mph + (a[c] >> 15) * this.mpl & this.um) << 15) & a.DM;b = c + this.m.t;a[b] += this.m.am(0, d, a, c, 0, this.m.t);while (a[b] >= a.DV) {\n      a[b] -= a.DV;a[++b]++;\n    }\n  }a.clamp();a.drShiftTo(this.m.t, a);if (a.compareTo(this.m) >= 0) {\n    a.subTo(this.m, a);\n  }\n}function montSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}function montMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}Montgomery.prototype.convert = montConvert;Montgomery.prototype.revert = montRevert;Montgomery.prototype.reduce = montReduce;Montgomery.prototype.mulTo = montMulTo;Montgomery.prototype.sqrTo = montSqrTo;function bnpIsEven() {\n  return (this.t > 0 ? this[0] & 1 : this.s) == 0;\n}function bnpExp(h, j) {\n  if (h > 4294967295 || h < 1) {\n    return BigInteger.ONE;\n  }var f = nbi(),\n      a = nbi(),\n      d = j.convert(this),\n      c = nbits(h) - 1;d.copyTo(f);while (--c >= 0) {\n    j.sqrTo(f, a);if ((h & 1 << c) > 0) {\n      j.mulTo(a, d, f);\n    } else {\n      var b = f;f = a;a = b;\n    }\n  }return j.revert(f);\n}function bnModPowInt(b, a) {\n  var c;if (b < 256 || a.isEven()) {\n    c = new Classic(a);\n  } else {\n    c = new Montgomery(a);\n  }return this.exp(b, c);\n}BigInteger.prototype.copyTo = bnpCopyTo;BigInteger.prototype.fromInt = bnpFromInt;BigInteger.prototype.fromString = bnpFromString;BigInteger.prototype.clamp = bnpClamp;BigInteger.prototype.dlShiftTo = bnpDLShiftTo;BigInteger.prototype.drShiftTo = bnpDRShiftTo;BigInteger.prototype.lShiftTo = bnpLShiftTo;BigInteger.prototype.rShiftTo = bnpRShiftTo;BigInteger.prototype.subTo = bnpSubTo;BigInteger.prototype.multiplyTo = bnpMultiplyTo;BigInteger.prototype.squareTo = bnpSquareTo;BigInteger.prototype.divRemTo = bnpDivRemTo;BigInteger.prototype.invDigit = bnpInvDigit;BigInteger.prototype.isEven = bnpIsEven;BigInteger.prototype.exp = bnpExp;BigInteger.prototype.toString = bnToString;BigInteger.prototype.negate = bnNegate;BigInteger.prototype.abs = bnAbs;BigInteger.prototype.compareTo = bnCompareTo;BigInteger.prototype.bitLength = bnBitLength;BigInteger.prototype.mod = bnMod;BigInteger.prototype.modPowInt = bnModPowInt;BigInteger.ZERO = nbv(0);BigInteger.ONE = nbv(1);\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction bnClone() {\n  var a = nbi();this.copyTo(a);return a;\n}function bnIntValue() {\n  if (this.s < 0) {\n    if (this.t == 1) {\n      return this[0] - this.DV;\n    } else {\n      if (this.t == 0) {\n        return -1;\n      }\n    }\n  } else {\n    if (this.t == 1) {\n      return this[0];\n    } else {\n      if (this.t == 0) {\n        return 0;\n      }\n    }\n  }return (this[1] & (1 << 32 - this.DB) - 1) << this.DB | this[0];\n}function bnByteValue() {\n  return this.t == 0 ? this.s : this[0] << 24 >> 24;\n}function bnShortValue() {\n  return this.t == 0 ? this.s : this[0] << 16 >> 16;\n}function bnpChunkSize(a) {\n  return Math.floor(Math.LN2 * this.DB / Math.log(a));\n}function bnSigNum() {\n  if (this.s < 0) {\n    return -1;\n  } else {\n    if (this.t <= 0 || this.t == 1 && this[0] <= 0) {\n      return 0;\n    } else {\n      return 1;\n    }\n  }\n}function bnpToRadix(c) {\n  if (c == null) {\n    c = 10;\n  }if (this.signum() == 0 || c < 2 || c > 36) {\n    return \"0\";\n  }var f = this.chunkSize(c);var e = Math.pow(c, f);var i = nbv(e),\n      j = nbi(),\n      h = nbi(),\n      g = \"\";this.divRemTo(i, j, h);while (j.signum() > 0) {\n    g = (e + h.intValue()).toString(c).substr(1) + g;j.divRemTo(i, j, h);\n  }return h.intValue().toString(c) + g;\n}function bnpFromRadix(m, h) {\n  this.fromInt(0);if (h == null) {\n    h = 10;\n  }var f = this.chunkSize(h);var g = Math.pow(h, f),\n      e = false,\n      a = 0,\n      l = 0;for (var c = 0; c < m.length; ++c) {\n    var k = intAt(m, c);if (k < 0) {\n      if (m.charAt(c) == \"-\" && this.signum() == 0) {\n        e = true;\n      }continue;\n    }l = h * l + k;if (++a >= f) {\n      this.dMultiply(g);this.dAddOffset(l, 0);a = 0;l = 0;\n    }\n  }if (a > 0) {\n    this.dMultiply(Math.pow(h, a));this.dAddOffset(l, 0);\n  }if (e) {\n    BigInteger.ZERO.subTo(this, this);\n  }\n}function bnpFromNumber(f, e, h) {\n  if (\"number\" == typeof e) {\n    if (f < 2) {\n      this.fromInt(1);\n    } else {\n      this.fromNumber(f, h);if (!this.testBit(f - 1)) {\n        this.bitwiseTo(BigInteger.ONE.shiftLeft(f - 1), op_or, this);\n      }if (this.isEven()) {\n        this.dAddOffset(1, 0);\n      }while (!this.isProbablePrime(e)) {\n        this.dAddOffset(2, 0);if (this.bitLength() > f) {\n          this.subTo(BigInteger.ONE.shiftLeft(f - 1), this);\n        }\n      }\n    }\n  } else {\n    var d = new Array(),\n        g = f & 7;d.length = (f >> 3) + 1;e.nextBytes(d);if (g > 0) {\n      d[0] &= (1 << g) - 1;\n    } else {\n      d[0] = 0;\n    }this.fromString(d, 256);\n  }\n}function bnToByteArray() {\n  var b = this.t,\n      c = new Array();c[0] = this.s;var e = this.DB - b * this.DB % 8,\n      f,\n      a = 0;if (b-- > 0) {\n    if (e < this.DB && (f = this[b] >> e) != (this.s & this.DM) >> e) {\n      c[a++] = f | this.s << this.DB - e;\n    }while (b >= 0) {\n      if (e < 8) {\n        f = (this[b] & (1 << e) - 1) << 8 - e;f |= this[--b] >> (e += this.DB - 8);\n      } else {\n        f = this[b] >> (e -= 8) & 255;if (e <= 0) {\n          e += this.DB;--b;\n        }\n      }if ((f & 128) != 0) {\n        f |= -256;\n      }if (a == 0 && (this.s & 128) != (f & 128)) {\n        ++a;\n      }if (a > 0 || f != this.s) {\n        c[a++] = f;\n      }\n    }\n  }return c;\n}function bnEquals(b) {\n  return this.compareTo(b) == 0;\n}function bnMin(b) {\n  return this.compareTo(b) < 0 ? this : b;\n}function bnMax(b) {\n  return this.compareTo(b) > 0 ? this : b;\n}function bnpBitwiseTo(c, h, e) {\n  var d,\n      g,\n      b = Math.min(c.t, this.t);for (d = 0; d < b; ++d) {\n    e[d] = h(this[d], c[d]);\n  }if (c.t < this.t) {\n    g = c.s & this.DM;for (d = b; d < this.t; ++d) {\n      e[d] = h(this[d], g);\n    }e.t = this.t;\n  } else {\n    g = this.s & this.DM;for (d = b; d < c.t; ++d) {\n      e[d] = h(g, c[d]);\n    }e.t = c.t;\n  }e.s = h(this.s, c.s);e.clamp();\n}function op_and(a, b) {\n  return a & b;\n}function bnAnd(b) {\n  var c = nbi();this.bitwiseTo(b, op_and, c);return c;\n}function op_or(a, b) {\n  return a | b;\n}function bnOr(b) {\n  var c = nbi();this.bitwiseTo(b, op_or, c);return c;\n}function op_xor(a, b) {\n  return a ^ b;\n}function bnXor(b) {\n  var c = nbi();this.bitwiseTo(b, op_xor, c);return c;\n}function op_andnot(a, b) {\n  return a & ~b;\n}function bnAndNot(b) {\n  var c = nbi();this.bitwiseTo(b, op_andnot, c);return c;\n}function bnNot() {\n  var b = nbi();for (var a = 0; a < this.t; ++a) {\n    b[a] = this.DM & ~this[a];\n  }b.t = this.t;b.s = ~this.s;return b;\n}function bnShiftLeft(b) {\n  var a = nbi();if (b < 0) {\n    this.rShiftTo(-b, a);\n  } else {\n    this.lShiftTo(b, a);\n  }return a;\n}function bnShiftRight(b) {\n  var a = nbi();if (b < 0) {\n    this.lShiftTo(-b, a);\n  } else {\n    this.rShiftTo(b, a);\n  }return a;\n}function lbit(a) {\n  if (a == 0) {\n    return -1;\n  }var b = 0;if ((a & 65535) == 0) {\n    a >>= 16;b += 16;\n  }if ((a & 255) == 0) {\n    a >>= 8;b += 8;\n  }if ((a & 15) == 0) {\n    a >>= 4;b += 4;\n  }if ((a & 3) == 0) {\n    a >>= 2;b += 2;\n  }if ((a & 1) == 0) {\n    ++b;\n  }return b;\n}function bnGetLowestSetBit() {\n  for (var a = 0; a < this.t; ++a) {\n    if (this[a] != 0) {\n      return a * this.DB + lbit(this[a]);\n    }\n  }if (this.s < 0) {\n    return this.t * this.DB;\n  }return -1;\n}function cbit(a) {\n  var b = 0;while (a != 0) {\n    a &= a - 1;++b;\n  }return b;\n}function bnBitCount() {\n  var c = 0,\n      a = this.s & this.DM;for (var b = 0; b < this.t; ++b) {\n    c += cbit(this[b] ^ a);\n  }return c;\n}function bnTestBit(b) {\n  var a = Math.floor(b / this.DB);if (a >= this.t) {\n    return this.s != 0;\n  }return (this[a] & 1 << b % this.DB) != 0;\n}function bnpChangeBit(c, b) {\n  var a = BigInteger.ONE.shiftLeft(c);this.bitwiseTo(a, b, a);return a;\n}function bnSetBit(a) {\n  return this.changeBit(a, op_or);\n}function bnClearBit(a) {\n  return this.changeBit(a, op_andnot);\n}function bnFlipBit(a) {\n  return this.changeBit(a, op_xor);\n}function bnpAddTo(d, f) {\n  var e = 0,\n      g = 0,\n      b = Math.min(d.t, this.t);while (e < b) {\n    g += this[e] + d[e];f[e++] = g & this.DM;g >>= this.DB;\n  }if (d.t < this.t) {\n    g += d.s;while (e < this.t) {\n      g += this[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += this.s;\n  } else {\n    g += this.s;while (e < d.t) {\n      g += d[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += d.s;\n  }f.s = g < 0 ? -1 : 0;if (g > 0) {\n    f[e++] = g;\n  } else {\n    if (g < -1) {\n      f[e++] = this.DV + g;\n    }\n  }f.t = e;f.clamp();\n}function bnAdd(b) {\n  var c = nbi();this.addTo(b, c);return c;\n}function bnSubtract(b) {\n  var c = nbi();this.subTo(b, c);return c;\n}function bnMultiply(b) {\n  var c = nbi();this.multiplyTo(b, c);return c;\n}function bnSquare() {\n  var a = nbi();this.squareTo(a);return a;\n}function bnDivide(b) {\n  var c = nbi();this.divRemTo(b, c, null);return c;\n}function bnRemainder(b) {\n  var c = nbi();this.divRemTo(b, null, c);return c;\n}function bnDivideAndRemainder(b) {\n  var d = nbi(),\n      c = nbi();this.divRemTo(b, d, c);return new Array(d, c);\n}function bnpDMultiply(a) {\n  this[this.t] = this.am(0, a - 1, this, 0, 0, this.t);++this.t;this.clamp();\n}function bnpDAddOffset(b, a) {\n  if (b == 0) {\n    return;\n  }while (this.t <= a) {\n    this[this.t++] = 0;\n  }this[a] += b;while (this[a] >= this.DV) {\n    this[a] -= this.DV;if (++a >= this.t) {\n      this[this.t++] = 0;\n    }++this[a];\n  }\n}function NullExp() {}function nNop(a) {\n  return a;\n}function nMulTo(a, c, b) {\n  a.multiplyTo(c, b);\n}function nSqrTo(a, b) {\n  a.squareTo(b);\n}NullExp.prototype.convert = nNop;NullExp.prototype.revert = nNop;NullExp.prototype.mulTo = nMulTo;NullExp.prototype.sqrTo = nSqrTo;function bnPow(a) {\n  return this.exp(a, new NullExp());\n}function bnpMultiplyLowerTo(b, f, e) {\n  var d = Math.min(this.t + b.t, f);e.s = 0;e.t = d;while (d > 0) {\n    e[--d] = 0;\n  }var c;for (c = e.t - this.t; d < c; ++d) {\n    e[d + this.t] = this.am(0, b[d], e, d, 0, this.t);\n  }for (c = Math.min(b.t, f); d < c; ++d) {\n    this.am(0, b[d], e, d, 0, f - d);\n  }e.clamp();\n}function bnpMultiplyUpperTo(b, e, d) {\n  --e;var c = d.t = this.t + b.t - e;d.s = 0;while (--c >= 0) {\n    d[c] = 0;\n  }for (c = Math.max(e - this.t, 0); c < b.t; ++c) {\n    d[this.t + c - e] = this.am(e - c, b[c], d, 0, 0, this.t + c - e);\n  }d.clamp();d.drShiftTo(1, d);\n}function Barrett(a) {\n  this.r2 = nbi();this.q3 = nbi();BigInteger.ONE.dlShiftTo(2 * a.t, this.r2);this.mu = this.r2.divide(a);this.m = a;\n}function barrettConvert(a) {\n  if (a.s < 0 || a.t > 2 * this.m.t) {\n    return a.mod(this.m);\n  } else {\n    if (a.compareTo(this.m) < 0) {\n      return a;\n    } else {\n      var b = nbi();a.copyTo(b);this.reduce(b);return b;\n    }\n  }\n}function barrettRevert(a) {\n  return a;\n}function barrettReduce(a) {\n  a.drShiftTo(this.m.t - 1, this.r2);if (a.t > this.m.t + 1) {\n    a.t = this.m.t + 1;a.clamp();\n  }this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);while (a.compareTo(this.r2) < 0) {\n    a.dAddOffset(1, this.m.t + 1);\n  }a.subTo(this.r2, a);while (a.compareTo(this.m) >= 0) {\n    a.subTo(this.m, a);\n  }\n}function barrettSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}function barrettMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}Barrett.prototype.convert = barrettConvert;Barrett.prototype.revert = barrettRevert;Barrett.prototype.reduce = barrettReduce;Barrett.prototype.mulTo = barrettMulTo;Barrett.prototype.sqrTo = barrettSqrTo;function bnModPow(q, f) {\n  var o = q.bitLength(),\n      h,\n      b = nbv(1),\n      v;if (o <= 0) {\n    return b;\n  } else {\n    if (o < 18) {\n      h = 1;\n    } else {\n      if (o < 48) {\n        h = 3;\n      } else {\n        if (o < 144) {\n          h = 4;\n        } else {\n          if (o < 768) {\n            h = 5;\n          } else {\n            h = 6;\n          }\n        }\n      }\n    }\n  }if (o < 8) {\n    v = new Classic(f);\n  } else {\n    if (f.isEven()) {\n      v = new Barrett(f);\n    } else {\n      v = new Montgomery(f);\n    }\n  }var p = new Array(),\n      d = 3,\n      s = h - 1,\n      a = (1 << h) - 1;p[1] = v.convert(this);if (h > 1) {\n    var A = nbi();v.sqrTo(p[1], A);while (d <= a) {\n      p[d] = nbi();v.mulTo(A, p[d - 2], p[d]);d += 2;\n    }\n  }var l = q.t - 1,\n      x,\n      u = true,\n      c = nbi(),\n      y;o = nbits(q[l]) - 1;while (l >= 0) {\n    if (o >= s) {\n      x = q[l] >> o - s & a;\n    } else {\n      x = (q[l] & (1 << o + 1) - 1) << s - o;if (l > 0) {\n        x |= q[l - 1] >> this.DB + o - s;\n      }\n    }d = h;while ((x & 1) == 0) {\n      x >>= 1;--d;\n    }if ((o -= d) < 0) {\n      o += this.DB;--l;\n    }if (u) {\n      p[x].copyTo(b);u = false;\n    } else {\n      while (d > 1) {\n        v.sqrTo(b, c);v.sqrTo(c, b);d -= 2;\n      }if (d > 0) {\n        v.sqrTo(b, c);\n      } else {\n        y = b;b = c;c = y;\n      }v.mulTo(c, p[x], b);\n    }while (l >= 0 && (q[l] & 1 << o) == 0) {\n      v.sqrTo(b, c);y = b;b = c;c = y;if (--o < 0) {\n        o = this.DB - 1;--l;\n      }\n    }\n  }return v.revert(b);\n}function bnGCD(c) {\n  var b = this.s < 0 ? this.negate() : this.clone();var h = c.s < 0 ? c.negate() : c.clone();if (b.compareTo(h) < 0) {\n    var e = b;b = h;h = e;\n  }var d = b.getLowestSetBit(),\n      f = h.getLowestSetBit();if (f < 0) {\n    return b;\n  }if (d < f) {\n    f = d;\n  }if (f > 0) {\n    b.rShiftTo(f, b);h.rShiftTo(f, h);\n  }while (b.signum() > 0) {\n    if ((d = b.getLowestSetBit()) > 0) {\n      b.rShiftTo(d, b);\n    }if ((d = h.getLowestSetBit()) > 0) {\n      h.rShiftTo(d, h);\n    }if (b.compareTo(h) >= 0) {\n      b.subTo(h, b);b.rShiftTo(1, b);\n    } else {\n      h.subTo(b, h);h.rShiftTo(1, h);\n    }\n  }if (f > 0) {\n    h.lShiftTo(f, h);\n  }return h;\n}function bnpModInt(e) {\n  if (e <= 0) {\n    return 0;\n  }var c = this.DV % e,\n      b = this.s < 0 ? e - 1 : 0;if (this.t > 0) {\n    if (c == 0) {\n      b = this[0] % e;\n    } else {\n      for (var a = this.t - 1; a >= 0; --a) {\n        b = (c * b + this[a]) % e;\n      }\n    }\n  }return b;\n}function bnModInverse(f) {\n  var j = f.isEven();if (this.isEven() && j || f.signum() == 0) {\n    return BigInteger.ZERO;\n  }var i = f.clone(),\n      h = this.clone();var g = nbv(1),\n      e = nbv(0),\n      l = nbv(0),\n      k = nbv(1);while (i.signum() != 0) {\n    while (i.isEven()) {\n      i.rShiftTo(1, i);if (j) {\n        if (!g.isEven() || !e.isEven()) {\n          g.addTo(this, g);e.subTo(f, e);\n        }g.rShiftTo(1, g);\n      } else {\n        if (!e.isEven()) {\n          e.subTo(f, e);\n        }\n      }e.rShiftTo(1, e);\n    }while (h.isEven()) {\n      h.rShiftTo(1, h);if (j) {\n        if (!l.isEven() || !k.isEven()) {\n          l.addTo(this, l);k.subTo(f, k);\n        }l.rShiftTo(1, l);\n      } else {\n        if (!k.isEven()) {\n          k.subTo(f, k);\n        }\n      }k.rShiftTo(1, k);\n    }if (i.compareTo(h) >= 0) {\n      i.subTo(h, i);if (j) {\n        g.subTo(l, g);\n      }e.subTo(k, e);\n    } else {\n      h.subTo(i, h);if (j) {\n        l.subTo(g, l);\n      }k.subTo(e, k);\n    }\n  }if (h.compareTo(BigInteger.ONE) != 0) {\n    return BigInteger.ZERO;\n  }if (k.compareTo(f) >= 0) {\n    return k.subtract(f);\n  }if (k.signum() < 0) {\n    k.addTo(f, k);\n  } else {\n    return k;\n  }if (k.signum() < 0) {\n    return k.add(f);\n  } else {\n    return k;\n  }\n}var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];function bnIsProbablePrime(e) {\n  var d,\n      b = this.abs();if (b.t == 1 && b[0] <= lowprimes[lowprimes.length - 1]) {\n    for (d = 0; d < lowprimes.length; ++d) {\n      if (b[0] == lowprimes[d]) {\n        return true;\n      }\n    }return false;\n  }if (b.isEven()) {\n    return false;\n  }d = 1;while (d < lowprimes.length) {\n    var a = lowprimes[d],\n        c = d + 1;while (c < lowprimes.length && a < lplim) {\n      a *= lowprimes[c++];\n    }a = b.modInt(a);while (d < c) {\n      if (a % lowprimes[d++] == 0) {\n        return false;\n      }\n    }\n  }return b.millerRabin(e);\n}function bnpMillerRabin(f) {\n  var g = this.subtract(BigInteger.ONE);var c = g.getLowestSetBit();if (c <= 0) {\n    return false;\n  }var h = g.shiftRight(c);f = f + 1 >> 1;if (f > lowprimes.length) {\n    f = lowprimes.length;\n  }var b = nbi();for (var e = 0; e < f; ++e) {\n    b.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);var l = b.modPow(h, this);if (l.compareTo(BigInteger.ONE) != 0 && l.compareTo(g) != 0) {\n      var d = 1;while (d++ < c && l.compareTo(g) != 0) {\n        l = l.modPowInt(2, this);if (l.compareTo(BigInteger.ONE) == 0) {\n          return false;\n        }\n      }if (l.compareTo(g) != 0) {\n        return false;\n      }\n    }\n  }return true;\n}BigInteger.prototype.chunkSize = bnpChunkSize;BigInteger.prototype.toRadix = bnpToRadix;BigInteger.prototype.fromRadix = bnpFromRadix;BigInteger.prototype.fromNumber = bnpFromNumber;BigInteger.prototype.bitwiseTo = bnpBitwiseTo;BigInteger.prototype.changeBit = bnpChangeBit;BigInteger.prototype.addTo = bnpAddTo;BigInteger.prototype.dMultiply = bnpDMultiply;BigInteger.prototype.dAddOffset = bnpDAddOffset;BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;BigInteger.prototype.modInt = bnpModInt;BigInteger.prototype.millerRabin = bnpMillerRabin;BigInteger.prototype.clone = bnClone;BigInteger.prototype.intValue = bnIntValue;BigInteger.prototype.byteValue = bnByteValue;BigInteger.prototype.shortValue = bnShortValue;BigInteger.prototype.signum = bnSigNum;BigInteger.prototype.toByteArray = bnToByteArray;BigInteger.prototype.equals = bnEquals;BigInteger.prototype.min = bnMin;BigInteger.prototype.max = bnMax;BigInteger.prototype.and = bnAnd;BigInteger.prototype.or = bnOr;BigInteger.prototype.xor = bnXor;BigInteger.prototype.andNot = bnAndNot;BigInteger.prototype.not = bnNot;BigInteger.prototype.shiftLeft = bnShiftLeft;BigInteger.prototype.shiftRight = bnShiftRight;BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;BigInteger.prototype.bitCount = bnBitCount;BigInteger.prototype.testBit = bnTestBit;BigInteger.prototype.setBit = bnSetBit;BigInteger.prototype.clearBit = bnClearBit;BigInteger.prototype.flipBit = bnFlipBit;BigInteger.prototype.add = bnAdd;BigInteger.prototype.subtract = bnSubtract;BigInteger.prototype.multiply = bnMultiply;BigInteger.prototype.divide = bnDivide;BigInteger.prototype.remainder = bnRemainder;BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;BigInteger.prototype.modPow = bnModPow;BigInteger.prototype.modInverse = bnModInverse;BigInteger.prototype.pow = bnPow;BigInteger.prototype.gcd = bnGCD;BigInteger.prototype.isProbablePrime = bnIsProbablePrime;BigInteger.prototype.square = bnSquare;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction Arcfour() {\n  this.i = 0;this.j = 0;this.S = new Array();\n}function ARC4init(d) {\n  var c, a, b;for (c = 0; c < 256; ++c) {\n    this.S[c] = c;\n  }a = 0;for (c = 0; c < 256; ++c) {\n    a = a + this.S[c] + d[c % d.length] & 255;b = this.S[c];this.S[c] = this.S[a];this.S[a] = b;\n  }this.i = 0;this.j = 0;\n}function ARC4next() {\n  var a;this.i = this.i + 1 & 255;this.j = this.j + this.S[this.i] & 255;a = this.S[this.i];this.S[this.i] = this.S[this.j];this.S[this.j] = a;return this.S[a + this.S[this.i] & 255];\n}Arcfour.prototype.init = ARC4init;Arcfour.prototype.next = ARC4next;function prng_newstate() {\n  return new Arcfour();\n}var rng_psize = 256;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar rng_state;var rng_pool;var rng_pptr;function rng_seed_int(a) {\n  rng_pool[rng_pptr++] ^= a & 255;rng_pool[rng_pptr++] ^= a >> 8 & 255;rng_pool[rng_pptr++] ^= a >> 16 & 255;rng_pool[rng_pptr++] ^= a >> 24 & 255;if (rng_pptr >= rng_psize) {\n    rng_pptr -= rng_psize;\n  }\n}function rng_seed_time() {\n  rng_seed_int(new Date().getTime());\n}if (rng_pool == null) {\n  rng_pool = new Array();rng_pptr = 0;var t;if (window !== undefined && (window.crypto !== undefined || window.msCrypto !== undefined)) {\n    var crypto = window.crypto || window.msCrypto;if (crypto.getRandomValues) {\n      var ua = new Uint8Array(32);crypto.getRandomValues(ua);for (t = 0; t < 32; ++t) {\n        rng_pool[rng_pptr++] = ua[t];\n      }\n    } else {\n      if (navigator.appName == \"Netscape\" && navigator.appVersion < \"5\") {\n        var z = window.crypto.random(32);for (t = 0; t < z.length; ++t) {\n          rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;\n        }\n      }\n    }\n  }while (rng_pptr < rng_psize) {\n    t = Math.floor(65536 * Math.random());rng_pool[rng_pptr++] = t >>> 8;rng_pool[rng_pptr++] = t & 255;\n  }rng_pptr = 0;rng_seed_time();\n}function rng_get_byte() {\n  if (rng_state == null) {\n    rng_seed_time();rng_state = prng_newstate();rng_state.init(rng_pool);for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {\n      rng_pool[rng_pptr] = 0;\n    }rng_pptr = 0;\n  }return rng_state.next();\n}function rng_get_bytes(b) {\n  var a;for (a = 0; a < b.length; ++a) {\n    b[a] = rng_get_byte();\n  }\n}function SecureRandom() {}SecureRandom.prototype.nextBytes = rng_get_bytes;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction parseBigInt(b, a) {\n  return new BigInteger(b, a);\n}function linebrk(c, d) {\n  var a = \"\";var b = 0;while (b + d < c.length) {\n    a += c.substring(b, b + d) + \"\\n\";b += d;\n  }return a + c.substring(b, c.length);\n}function byte2Hex(a) {\n  if (a < 16) {\n    return \"0\" + a.toString(16);\n  } else {\n    return a.toString(16);\n  }\n}function pkcs1pad2(e, h) {\n  if (h < e.length + 11) {\n    throw \"Message too long for RSA\";return null;\n  }var g = new Array();var d = e.length - 1;while (d >= 0 && h > 0) {\n    var f = e.charCodeAt(d--);if (f < 128) {\n      g[--h] = f;\n    } else {\n      if (f > 127 && f < 2048) {\n        g[--h] = f & 63 | 128;g[--h] = f >> 6 | 192;\n      } else {\n        g[--h] = f & 63 | 128;g[--h] = f >> 6 & 63 | 128;g[--h] = f >> 12 | 224;\n      }\n    }\n  }g[--h] = 0;var b = new SecureRandom();var a = new Array();while (h > 2) {\n    a[0] = 0;while (a[0] == 0) {\n      b.nextBytes(a);\n    }g[--h] = a[0];\n  }g[--h] = 2;g[--h] = 0;return new BigInteger(g);\n}function oaep_mgf1_arr(c, a, e) {\n  var b = \"\",\n      d = 0;while (b.length < a) {\n    b += e(String.fromCharCode.apply(String, c.concat([(d & 4278190080) >> 24, (d & 16711680) >> 16, (d & 65280) >> 8, d & 255])));d += 1;\n  }return b;\n}function oaep_pad(q, a, f, l) {\n  var c = KJUR.crypto.MessageDigest;var o = KJUR.crypto.Util;var b = null;if (!f) {\n    f = \"sha1\";\n  }if (typeof f === \"string\") {\n    b = c.getCanonicalAlgName(f);l = c.getHashLength(b);f = function f(i) {\n      return hextorstr(o.hashHex(rstrtohex(i), b));\n    };\n  }if (q.length + 2 * l + 2 > a) {\n    throw \"Message too long for RSA\";\n  }var k = \"\",\n      e;for (e = 0; e < a - q.length - 2 * l - 2; e += 1) {\n    k += \"\\x00\";\n  }var h = f(\"\") + k + \"\\x01\" + q;var g = new Array(l);new SecureRandom().nextBytes(g);var j = oaep_mgf1_arr(g, h.length, f);var p = [];for (e = 0; e < h.length; e += 1) {\n    p[e] = h.charCodeAt(e) ^ j.charCodeAt(e);\n  }var m = oaep_mgf1_arr(p, g.length, f);var d = [0];for (e = 0; e < g.length; e += 1) {\n    d[e + 1] = g[e] ^ m.charCodeAt(e);\n  }return new BigInteger(d.concat(p));\n}function RSAKey() {\n  this.n = null;this.e = 0;this.d = null;this.p = null;this.q = null;this.dmp1 = null;this.dmq1 = null;this.coeff = null;\n}function RSASetPublic(b, a) {\n  this.isPublic = true;this.isPrivate = false;if (typeof b !== \"string\") {\n    this.n = b;this.e = a;\n  } else {\n    if (b != null && a != null && b.length > 0 && a.length > 0) {\n      this.n = parseBigInt(b, 16);this.e = parseInt(a, 16);\n    } else {\n      throw \"Invalid RSA public key\";\n    }\n  }\n}function RSADoPublic(a) {\n  return a.modPowInt(this.e, this.n);\n}function RSAEncrypt(d) {\n  var a = pkcs1pad2(d, this.n.bitLength() + 7 >> 3);if (a == null) {\n    return null;\n  }var e = this.doPublic(a);if (e == null) {\n    return null;\n  }var b = e.toString(16);if ((b.length & 1) == 0) {\n    return b;\n  } else {\n    return \"0\" + b;\n  }\n}function RSAEncryptOAEP(f, e, b) {\n  var a = oaep_pad(f, this.n.bitLength() + 7 >> 3, e, b);if (a == null) {\n    return null;\n  }var g = this.doPublic(a);if (g == null) {\n    return null;\n  }var d = g.toString(16);if ((d.length & 1) == 0) {\n    return d;\n  } else {\n    return \"0\" + d;\n  }\n}RSAKey.prototype.doPublic = RSADoPublic;RSAKey.prototype.setPublic = RSASetPublic;RSAKey.prototype.encrypt = RSAEncrypt;RSAKey.prototype.encryptOAEP = RSAEncryptOAEP;RSAKey.prototype.type = \"RSA\";\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction ECFieldElementFp(b, a) {\n  this.x = a;this.q = b;\n}function feFpEquals(a) {\n  if (a == this) {\n    return true;\n  }return this.q.equals(a.q) && this.x.equals(a.x);\n}function feFpToBigInteger() {\n  return this.x;\n}function feFpNegate() {\n  return new ECFieldElementFp(this.q, this.x.negate().mod(this.q));\n}function feFpAdd(a) {\n  return new ECFieldElementFp(this.q, this.x.add(a.toBigInteger()).mod(this.q));\n}function feFpSubtract(a) {\n  return new ECFieldElementFp(this.q, this.x.subtract(a.toBigInteger()).mod(this.q));\n}function feFpMultiply(a) {\n  return new ECFieldElementFp(this.q, this.x.multiply(a.toBigInteger()).mod(this.q));\n}function feFpSquare() {\n  return new ECFieldElementFp(this.q, this.x.square().mod(this.q));\n}function feFpDivide(a) {\n  return new ECFieldElementFp(this.q, this.x.multiply(a.toBigInteger().modInverse(this.q)).mod(this.q));\n}ECFieldElementFp.prototype.equals = feFpEquals;ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger;ECFieldElementFp.prototype.negate = feFpNegate;ECFieldElementFp.prototype.add = feFpAdd;ECFieldElementFp.prototype.subtract = feFpSubtract;ECFieldElementFp.prototype.multiply = feFpMultiply;ECFieldElementFp.prototype.square = feFpSquare;ECFieldElementFp.prototype.divide = feFpDivide;function ECPointFp(c, a, d, b) {\n  this.curve = c;this.x = a;this.y = d;if (b == null) {\n    this.z = BigInteger.ONE;\n  } else {\n    this.z = b;\n  }this.zinv = null;\n}function pointFpGetX() {\n  if (this.zinv == null) {\n    this.zinv = this.z.modInverse(this.curve.q);\n  }return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}function pointFpGetY() {\n  if (this.zinv == null) {\n    this.zinv = this.z.modInverse(this.curve.q);\n  }return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}function pointFpEquals(a) {\n  if (a == this) {\n    return true;\n  }if (this.isInfinity()) {\n    return a.isInfinity();\n  }if (a.isInfinity()) {\n    return this.isInfinity();\n  }var c, b;c = a.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(a.z)).mod(this.curve.q);if (!c.equals(BigInteger.ZERO)) {\n    return false;\n  }b = a.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(a.z)).mod(this.curve.q);return b.equals(BigInteger.ZERO);\n}function pointFpIsInfinity() {\n  if (this.x == null && this.y == null) {\n    return true;\n  }return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);\n}function pointFpNegate() {\n  return new ECPointFp(this.curve, this.x, this.y.negate(), this.z);\n}function pointFpAdd(l) {\n  if (this.isInfinity()) {\n    return l;\n  }if (l.isInfinity()) {\n    return this;\n  }var p = l.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(l.z)).mod(this.curve.q);var o = l.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(l.z)).mod(this.curve.q);if (BigInteger.ZERO.equals(o)) {\n    if (BigInteger.ZERO.equals(p)) {\n      return this.twice();\n    }return this.curve.getInfinity();\n  }var j = new BigInteger(\"3\");var e = this.x.toBigInteger();var n = this.y.toBigInteger();var c = l.x.toBigInteger();var k = l.y.toBigInteger();var m = o.square();var i = m.multiply(o);var d = e.multiply(m);var g = p.square().multiply(this.z);var a = g.subtract(d.shiftLeft(1)).multiply(l.z).subtract(i).multiply(o).mod(this.curve.q);var h = d.multiply(j).multiply(p).subtract(n.multiply(i)).subtract(g.multiply(p)).multiply(l.z).add(p.multiply(i)).mod(this.curve.q);var f = i.multiply(this.z).multiply(l.z).mod(this.curve.q);return new ECPointFp(this.curve, this.curve.fromBigInteger(a), this.curve.fromBigInteger(h), f);\n}function pointFpTwice() {\n  if (this.isInfinity()) {\n    return this;\n  }if (this.y.toBigInteger().signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = new BigInteger(\"3\");var c = this.x.toBigInteger();var h = this.y.toBigInteger();var e = h.multiply(this.z);var j = e.multiply(h).mod(this.curve.q);var i = this.curve.a.toBigInteger();var k = c.square().multiply(g);if (!BigInteger.ZERO.equals(i)) {\n    k = k.add(this.z.square().multiply(i));\n  }k = k.mod(this.curve.q);var b = k.square().subtract(c.shiftLeft(3).multiply(j)).shiftLeft(1).multiply(e).mod(this.curve.q);var f = k.multiply(g).multiply(c).subtract(j.shiftLeft(1)).shiftLeft(2).multiply(j).subtract(k.square().multiply(k)).mod(this.curve.q);var d = e.square().multiply(e).shiftLeft(3).mod(this.curve.q);return new ECPointFp(this.curve, this.curve.fromBigInteger(b), this.curve.fromBigInteger(f), d);\n}function pointFpMultiply(b) {\n  if (this.isInfinity()) {\n    return this;\n  }if (b.signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = b;var f = g.multiply(new BigInteger(\"3\"));var l = this.negate();var d = this;var c;for (c = f.bitLength() - 2; c > 0; --c) {\n    d = d.twice();var a = f.testBit(c);var j = g.testBit(c);if (a != j) {\n      d = d.add(a ? this : l);\n    }\n  }return d;\n}function pointFpMultiplyTwo(c, a, b) {\n  var d;if (c.bitLength() > b.bitLength()) {\n    d = c.bitLength() - 1;\n  } else {\n    d = b.bitLength() - 1;\n  }var f = this.curve.getInfinity();var e = this.add(a);while (d >= 0) {\n    f = f.twice();if (c.testBit(d)) {\n      if (b.testBit(d)) {\n        f = f.add(e);\n      } else {\n        f = f.add(this);\n      }\n    } else {\n      if (b.testBit(d)) {\n        f = f.add(a);\n      }\n    }--d;\n  }return f;\n}ECPointFp.prototype.getX = pointFpGetX;ECPointFp.prototype.getY = pointFpGetY;ECPointFp.prototype.equals = pointFpEquals;ECPointFp.prototype.isInfinity = pointFpIsInfinity;ECPointFp.prototype.negate = pointFpNegate;ECPointFp.prototype.add = pointFpAdd;ECPointFp.prototype.twice = pointFpTwice;ECPointFp.prototype.multiply = pointFpMultiply;ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo;function ECCurveFp(e, d, c) {\n  this.q = e;this.a = this.fromBigInteger(d);this.b = this.fromBigInteger(c);this.infinity = new ECPointFp(this, null, null);\n}function curveFpGetQ() {\n  return this.q;\n}function curveFpGetA() {\n  return this.a;\n}function curveFpGetB() {\n  return this.b;\n}function curveFpEquals(a) {\n  if (a == this) {\n    return true;\n  }return this.q.equals(a.q) && this.a.equals(a.a) && this.b.equals(a.b);\n}function curveFpGetInfinity() {\n  return this.infinity;\n}function curveFpFromBigInteger(a) {\n  return new ECFieldElementFp(this.q, a);\n}function curveFpDecodePointHex(d) {\n  switch (parseInt(d.substr(0, 2), 16)) {case 0:\n      return this.infinity;case 2:case 3:\n      return null;case 4:case 6:case 7:\n      var a = (d.length - 2) / 2;var c = d.substr(2, a);var b = d.substr(a + 2, a);return new ECPointFp(this, this.fromBigInteger(new BigInteger(c, 16)), this.fromBigInteger(new BigInteger(b, 16)));default:\n      return null;}\n}ECCurveFp.prototype.getQ = curveFpGetQ;ECCurveFp.prototype.getA = curveFpGetA;ECCurveFp.prototype.getB = curveFpGetB;ECCurveFp.prototype.equals = curveFpEquals;ECCurveFp.prototype.getInfinity = curveFpGetInfinity;ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger;ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex;\n/*! (c) Stefan Thomas | https://github.com/bitcoinjs/bitcoinjs-lib\n */\nECFieldElementFp.prototype.getByteLength = function () {\n  return Math.floor((this.toBigInteger().bitLength() + 7) / 8);\n};ECPointFp.prototype.getEncoded = function (c) {\n  var d = function d(h, f) {\n    var g = h.toByteArrayUnsigned();if (f < g.length) {\n      g = g.slice(g.length - f);\n    } else {\n      while (f > g.length) {\n        g.unshift(0);\n      }\n    }return g;\n  };var a = this.getX().toBigInteger();var e = this.getY().toBigInteger();var b = d(a, 32);if (c) {\n    if (e.isEven()) {\n      b.unshift(2);\n    } else {\n      b.unshift(3);\n    }\n  } else {\n    b.unshift(4);b = b.concat(d(e, 32));\n  }return b;\n};ECPointFp.decodeFrom = function (g, c) {\n  var f = c[0];var e = c.length - 1;var d = c.slice(1, 1 + e / 2);var b = c.slice(1 + e / 2, 1 + e);d.unshift(0);b.unshift(0);var a = new BigInteger(d);var h = new BigInteger(b);return new ECPointFp(g, g.fromBigInteger(a), g.fromBigInteger(h));\n};ECPointFp.decodeFromHex = function (g, c) {\n  var f = c.substr(0, 2);var e = c.length - 2;var d = c.substr(2, e / 2);var b = c.substr(2 + e / 2, e / 2);var a = new BigInteger(d, 16);var h = new BigInteger(b, 16);return new ECPointFp(g, g.fromBigInteger(a), g.fromBigInteger(h));\n};ECPointFp.prototype.add2D = function (c) {\n  if (this.isInfinity()) {\n    return c;\n  }if (c.isInfinity()) {\n    return this;\n  }if (this.x.equals(c.x)) {\n    if (this.y.equals(c.y)) {\n      return this.twice();\n    }return this.curve.getInfinity();\n  }var g = c.x.subtract(this.x);var e = c.y.subtract(this.y);var a = e.divide(g);var d = a.square().subtract(this.x).subtract(c.x);var f = a.multiply(this.x.subtract(d)).subtract(this.y);return new ECPointFp(this.curve, d, f);\n};ECPointFp.prototype.twice2D = function () {\n  if (this.isInfinity()) {\n    return this;\n  }if (this.y.toBigInteger().signum() == 0) {\n    return this.curve.getInfinity();\n  }var b = this.curve.fromBigInteger(BigInteger.valueOf(2));var e = this.curve.fromBigInteger(BigInteger.valueOf(3));var a = this.x.square().multiply(e).add(this.curve.a).divide(this.y.multiply(b));var c = a.square().subtract(this.x.multiply(b));var d = a.multiply(this.x.subtract(c)).subtract(this.y);return new ECPointFp(this.curve, c, d);\n};ECPointFp.prototype.multiply2D = function (b) {\n  if (this.isInfinity()) {\n    return this;\n  }if (b.signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = b;var f = g.multiply(new BigInteger(\"3\"));var l = this.negate();var d = this;var c;for (c = f.bitLength() - 2; c > 0; --c) {\n    d = d.twice();var a = f.testBit(c);var j = g.testBit(c);if (a != j) {\n      d = d.add2D(a ? this : l);\n    }\n  }return d;\n};ECPointFp.prototype.isOnCurve = function () {\n  var d = this.getX().toBigInteger();var i = this.getY().toBigInteger();var f = this.curve.getA().toBigInteger();var c = this.curve.getB().toBigInteger();var h = this.curve.getQ();var e = i.multiply(i).mod(h);var g = d.multiply(d).multiply(d).add(f.multiply(d)).add(c).mod(h);return e.equals(g);\n};ECPointFp.prototype.toString = function () {\n  return \"(\" + this.getX().toBigInteger().toString() + \",\" + this.getY().toBigInteger().toString() + \")\";\n};ECPointFp.prototype.validate = function () {\n  var c = this.curve.getQ();if (this.isInfinity()) {\n    throw new Error(\"Point is at infinity.\");\n  }var a = this.getX().toBigInteger();var b = this.getY().toBigInteger();if (a.compareTo(BigInteger.ONE) < 0 || a.compareTo(c.subtract(BigInteger.ONE)) > 0) {\n    throw new Error(\"x coordinate out of bounds\");\n  }if (b.compareTo(BigInteger.ONE) < 0 || b.compareTo(c.subtract(BigInteger.ONE)) > 0) {\n    throw new Error(\"y coordinate out of bounds\");\n  }if (!this.isOnCurve()) {\n    throw new Error(\"Point is not on the curve.\");\n  }if (this.multiply(c).isInfinity()) {\n    throw new Error(\"Point is not a scalar multiple of G.\");\n  }return true;\n};\n/*! Mike Samuel (c) 2009 | code.google.com/p/json-sans-eval\n */\nvar jsonParse = function () {\n  var e = \"(?:-?\\\\b(?:0|[1-9][0-9]*)(?:\\\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\\\b)\";var j = '(?:[^\\\\0-\\\\x08\\\\x0a-\\\\x1f\"\\\\\\\\]|\\\\\\\\(?:[\"/\\\\\\\\bfnrt]|u[0-9A-Fa-f]{4}))';var i = '(?:\"' + j + '*\")';var d = new RegExp(\"(?:false|true|null|[\\\\{\\\\}\\\\[\\\\]]|\" + e + \"|\" + i + \")\", \"g\");var k = new RegExp(\"\\\\\\\\(?:([^u])|u(.{4}))\", \"g\");var g = { '\"': '\"', \"/\": \"/\", \"\\\\\": \"\\\\\", b: \"\\b\", f: \"\\f\", n: \"\\n\", r: \"\\r\", t: \"\\t\" };function h(l, m, n) {\n    return m ? g[m] : String.fromCharCode(parseInt(n, 16));\n  }var c = new String(\"\");var a = \"\\\\\";var f = { \"{\": Object, \"[\": Array };var b = Object.hasOwnProperty;return function (u, q) {\n    var p = u.match(d);var x;var v = p[0];var l = false;if (\"{\" === v) {\n      x = {};\n    } else {\n      if (\"[\" === v) {\n        x = [];\n      } else {\n        x = [];l = true;\n      }\n    }var t;var r = [x];for (var o = 1 - l, m = p.length; o < m; ++o) {\n      v = p[o];var w;switch (v.charCodeAt(0)) {default:\n          w = r[0];w[t || w.length] = +v;t = void 0;break;case 34:\n          v = v.substring(1, v.length - 1);if (v.indexOf(a) !== -1) {\n            v = v.replace(k, h);\n          }w = r[0];if (!t) {\n            if (w instanceof Array) {\n              t = w.length;\n            } else {\n              t = v || c;break;\n            }\n          }w[t] = v;t = void 0;break;case 91:\n          w = r[0];r.unshift(w[t || w.length] = []);t = void 0;break;case 93:\n          r.shift();break;case 102:\n          w = r[0];w[t || w.length] = false;t = void 0;break;case 110:\n          w = r[0];w[t || w.length] = null;t = void 0;break;case 116:\n          w = r[0];w[t || w.length] = true;t = void 0;break;case 123:\n          w = r[0];r.unshift(w[t || w.length] = {});t = void 0;break;case 125:\n          r.shift();break;}\n    }if (l) {\n      if (r.length !== 1) {\n        throw new Error();\n      }x = x[0];\n    } else {\n      if (r.length) {\n        throw new Error();\n      }\n    }if (q) {\n      var s = function s(C, B) {\n        var D = C[B];if (D && (typeof D === \"undefined\" ? \"undefined\" : _typeof(D)) === \"object\") {\n          var n = null;for (var z in D) {\n            if (b.call(D, z) && D !== C) {\n              var y = s(D, z);if (y !== void 0) {\n                D[z] = y;\n              } else {\n                if (!n) {\n                  n = [];\n                }n.push(z);\n              }\n            }\n          }if (n) {\n            for (var A = n.length; --A >= 0;) {\n              delete D[n[A]];\n            }\n          }\n        }return q.call(C, B, D);\n      };x = s({ \"\": x }, \"\");\n    }return x;\n  };\n}();\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1) {\n  KJUR.asn1 = {};\n}KJUR.asn1.ASN1Util = new function () {\n  this.integerToByteHex = function (a) {\n    var b = a.toString(16);if (b.length % 2 == 1) {\n      b = \"0\" + b;\n    }return b;\n  };this.bigIntToMinTwosComplementsHex = function (j) {\n    var f = j.toString(16);if (f.substr(0, 1) != \"-\") {\n      if (f.length % 2 == 1) {\n        f = \"0\" + f;\n      } else {\n        if (!f.match(/^[0-7]/)) {\n          f = \"00\" + f;\n        }\n      }\n    } else {\n      var a = f.substr(1);var e = a.length;if (e % 2 == 1) {\n        e += 1;\n      } else {\n        if (!f.match(/^[0-7]/)) {\n          e += 2;\n        }\n      }var g = \"\";for (var d = 0; d < e; d++) {\n        g += \"f\";\n      }var c = new BigInteger(g, 16);var b = c.xor(j).add(BigInteger.ONE);f = b.toString(16).replace(/^-/, \"\");\n    }return f;\n  };this.getPEMStringFromHex = function (a, b) {\n    return hextopem(a, b);\n  };this.newObject = function (k) {\n    var D = KJUR,\n        n = D.asn1,\n        z = n.DERBoolean,\n        e = n.DERInteger,\n        s = n.DERBitString,\n        h = n.DEROctetString,\n        v = n.DERNull,\n        w = n.DERObjectIdentifier,\n        l = n.DEREnumerated,\n        g = n.DERUTF8String,\n        f = n.DERNumericString,\n        y = n.DERPrintableString,\n        u = n.DERTeletexString,\n        p = n.DERIA5String,\n        C = n.DERUTCTime,\n        j = n.DERGeneralizedTime,\n        m = n.DERSequence,\n        c = n.DERSet,\n        r = n.DERTaggedObject,\n        o = n.ASN1Util.newObject;var t = Object.keys(k);if (t.length != 1) {\n      throw \"key of param shall be only one.\";\n    }var F = t[0];if (\":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:\".indexOf(\":\" + F + \":\") == -1) {\n      throw \"undefined key: \" + F;\n    }if (F == \"bool\") {\n      return new z(k[F]);\n    }if (F == \"int\") {\n      return new e(k[F]);\n    }if (F == \"bitstr\") {\n      return new s(k[F]);\n    }if (F == \"octstr\") {\n      return new h(k[F]);\n    }if (F == \"null\") {\n      return new v(k[F]);\n    }if (F == \"oid\") {\n      return new w(k[F]);\n    }if (F == \"enum\") {\n      return new l(k[F]);\n    }if (F == \"utf8str\") {\n      return new g(k[F]);\n    }if (F == \"numstr\") {\n      return new f(k[F]);\n    }if (F == \"prnstr\") {\n      return new y(k[F]);\n    }if (F == \"telstr\") {\n      return new u(k[F]);\n    }if (F == \"ia5str\") {\n      return new p(k[F]);\n    }if (F == \"utctime\") {\n      return new C(k[F]);\n    }if (F == \"gentime\") {\n      return new j(k[F]);\n    }if (F == \"seq\") {\n      var d = k[F];var E = [];for (var x = 0; x < d.length; x++) {\n        var B = o(d[x]);E.push(B);\n      }return new m({ array: E });\n    }if (F == \"set\") {\n      var d = k[F];var E = [];for (var x = 0; x < d.length; x++) {\n        var B = o(d[x]);E.push(B);\n      }return new c({ array: E });\n    }if (F == \"tag\") {\n      var A = k[F];if (Object.prototype.toString.call(A) === \"[object Array]\" && A.length == 3) {\n        var q = o(A[2]);return new r({ tag: A[0], explicit: A[1], obj: q });\n      } else {\n        var b = {};if (A.explicit !== undefined) {\n          b.explicit = A.explicit;\n        }if (A.tag !== undefined) {\n          b.tag = A.tag;\n        }if (A.obj === undefined) {\n          throw \"obj shall be specified for 'tag'.\";\n        }b.obj = o(A.obj);return new r(b);\n      }\n    }\n  };this.jsonToASN1HEX = function (b) {\n    var a = this.newObject(b);return a.getEncodedHex();\n  };\n}();KJUR.asn1.ASN1Util.oidHexToInt = function (a) {\n  var j = \"\";var k = parseInt(a.substr(0, 2), 16);var d = Math.floor(k / 40);var c = k % 40;var j = d + \".\" + c;var e = \"\";for (var f = 2; f < a.length; f += 2) {\n    var g = parseInt(a.substr(f, 2), 16);var h = (\"00000000\" + g.toString(2)).slice(-8);e = e + h.substr(1, 7);if (h.substr(0, 1) == \"0\") {\n      var b = new BigInteger(e, 2);j = j + \".\" + b.toString(10);e = \"\";\n    }\n  }return j;\n};KJUR.asn1.ASN1Util.oidIntToHex = function (f) {\n  var e = function e(a) {\n    var k = a.toString(16);if (k.length == 1) {\n      k = \"0\" + k;\n    }return k;\n  };var d = function d(o) {\n    var n = \"\";var k = new BigInteger(o, 10);var a = k.toString(2);var l = 7 - a.length % 7;if (l == 7) {\n      l = 0;\n    }var q = \"\";for (var m = 0; m < l; m++) {\n      q += \"0\";\n    }a = q + a;for (var m = 0; m < a.length - 1; m += 7) {\n      var p = a.substr(m, 7);if (m != a.length - 7) {\n        p = \"1\" + p;\n      }n += e(parseInt(p, 2));\n    }return n;\n  };if (!f.match(/^[0-9.]+$/)) {\n    throw \"malformed oid string: \" + f;\n  }var g = \"\";var b = f.split(\".\");var j = parseInt(b[0]) * 40 + parseInt(b[1]);g += e(j);b.splice(0, 2);for (var c = 0; c < b.length; c++) {\n    g += d(b[c]);\n  }return g;\n};KJUR.asn1.ASN1Object = function () {\n  var c = true;var b = null;var d = \"00\";var e = \"00\";var a = \"\";this.getLengthHexFromValue = function () {\n    if (typeof this.hV == \"undefined\" || this.hV == null) {\n      throw \"this.hV is null or undefined.\";\n    }if (this.hV.length % 2 == 1) {\n      throw \"value hex must be even length: n=\" + a.length + \",v=\" + this.hV;\n    }var i = this.hV.length / 2;var h = i.toString(16);if (h.length % 2 == 1) {\n      h = \"0\" + h;\n    }if (i < 128) {\n      return h;\n    } else {\n      var g = h.length / 2;if (g > 15) {\n        throw \"ASN.1 length too long to represent by 8x: n = \" + i.toString(16);\n      }var f = 128 + g;return f.toString(16) + h;\n    }\n  };this.getEncodedHex = function () {\n    if (this.hTLV == null || this.isModified) {\n      this.hV = this.getFreshValueHex();this.hL = this.getLengthHexFromValue();this.hTLV = this.hT + this.hL + this.hV;this.isModified = false;\n    }return this.hTLV;\n  };this.getValueHex = function () {\n    this.getEncodedHex();return this.hV;\n  };this.getFreshValueHex = function () {\n    return \"\";\n  };\n};KJUR.asn1.DERAbstractString = function (c) {\n  KJUR.asn1.DERAbstractString.superclass.constructor.call(this);var b = null;var a = null;this.getString = function () {\n    return this.s;\n  };this.setString = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = d;this.hV = utf8tohex(this.s).toLowerCase();\n  };this.setStringHex = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = null;this.hV = d;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof c != \"undefined\") {\n    if (typeof c == \"string\") {\n      this.setString(c);\n    } else {\n      if (typeof c.str != \"undefined\") {\n        this.setString(c.str);\n      } else {\n        if (typeof c.hex != \"undefined\") {\n          this.setStringHex(c.hex);\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);KJUR.asn1.DERAbstractTime = function (c) {\n  KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);var b = null;var a = null;this.localDateToUTC = function (f) {\n    utc = f.getTime() + f.getTimezoneOffset() * 60000;var e = new Date(utc);return e;\n  };this.formatDate = function (m, o, e) {\n    var g = this.zeroPadding;var n = this.localDateToUTC(m);var p = String(n.getFullYear());if (o == \"utc\") {\n      p = p.substr(2, 2);\n    }var l = g(String(n.getMonth() + 1), 2);var q = g(String(n.getDate()), 2);var h = g(String(n.getHours()), 2);var i = g(String(n.getMinutes()), 2);var j = g(String(n.getSeconds()), 2);var r = p + l + q + h + i + j;if (e === true) {\n      var f = n.getMilliseconds();if (f != 0) {\n        var k = g(String(f), 3);k = k.replace(/[0]+$/, \"\");r = r + \".\" + k;\n      }\n    }return r + \"Z\";\n  };this.zeroPadding = function (e, d) {\n    if (e.length >= d) {\n      return e;\n    }return new Array(d - e.length + 1).join(\"0\") + e;\n  };this.getString = function () {\n    return this.s;\n  };this.setString = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = d;this.hV = stohex(d);\n  };this.setByDateValue = function (h, j, e, d, f, g) {\n    var i = new Date(Date.UTC(h, j - 1, e, d, f, g, 0));this.setByDate(i);\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);KJUR.asn1.DERAbstractStructured = function (b) {\n  KJUR.asn1.DERAbstractString.superclass.constructor.call(this);var a = null;this.setByASN1ObjectArray = function (c) {\n    this.hTLV = null;this.isModified = true;this.asn1Array = c;\n  };this.appendASN1Object = function (c) {\n    this.hTLV = null;this.isModified = true;this.asn1Array.push(c);\n  };this.asn1Array = new Array();if (typeof b != \"undefined\") {\n    if (typeof b.array != \"undefined\") {\n      this.asn1Array = b.array;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);KJUR.asn1.DERBoolean = function () {\n  KJUR.asn1.DERBoolean.superclass.constructor.call(this);this.hT = \"01\";this.hTLV = \"0101ff\";\n};YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);KJUR.asn1.DERInteger = function (a) {\n  KJUR.asn1.DERInteger.superclass.constructor.call(this);this.hT = \"02\";this.setByBigInteger = function (b) {\n    this.hTLV = null;this.isModified = true;this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(b);\n  };this.setByInteger = function (c) {\n    var b = new BigInteger(String(c), 10);this.setByBigInteger(b);\n  };this.setValueHex = function (b) {\n    this.hV = b;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.bigint != \"undefined\") {\n      this.setByBigInteger(a.bigint);\n    } else {\n      if (typeof a[\"int\"] != \"undefined\") {\n        this.setByInteger(a[\"int\"]);\n      } else {\n        if (typeof a == \"number\") {\n          this.setByInteger(a);\n        } else {\n          if (typeof a.hex != \"undefined\") {\n            this.setValueHex(a.hex);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);KJUR.asn1.DERBitString = function (b) {\n  if (b !== undefined && typeof b.obj !== \"undefined\") {\n    var a = KJUR.asn1.ASN1Util.newObject(b.obj);b.hex = \"00\" + a.getEncodedHex();\n  }KJUR.asn1.DERBitString.superclass.constructor.call(this);this.hT = \"03\";this.setHexValueIncludingUnusedBits = function (c) {\n    this.hTLV = null;this.isModified = true;this.hV = c;\n  };this.setUnusedBitsAndHexValue = function (c, e) {\n    if (c < 0 || 7 < c) {\n      throw \"unused bits shall be from 0 to 7: u = \" + c;\n    }var d = \"0\" + c;this.hTLV = null;this.isModified = true;this.hV = d + e;\n  };this.setByBinaryString = function (e) {\n    e = e.replace(/0+$/, \"\");var f = 8 - e.length % 8;if (f == 8) {\n      f = 0;\n    }for (var g = 0; g <= f; g++) {\n      e += \"0\";\n    }var j = \"\";for (var g = 0; g < e.length - 1; g += 8) {\n      var d = e.substr(g, 8);var c = parseInt(d, 2).toString(16);if (c.length == 1) {\n        c = \"0\" + c;\n      }j += c;\n    }this.hTLV = null;this.isModified = true;this.hV = \"0\" + f + j;\n  };this.setByBooleanArray = function (e) {\n    var d = \"\";for (var c = 0; c < e.length; c++) {\n      if (e[c] == true) {\n        d += \"1\";\n      } else {\n        d += \"0\";\n      }\n    }this.setByBinaryString(d);\n  };this.newFalseArray = function (e) {\n    var c = new Array(e);for (var d = 0; d < e; d++) {\n      c[d] = false;\n    }return c;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof b != \"undefined\") {\n    if (typeof b == \"string\" && b.toLowerCase().match(/^[0-9a-f]+$/)) {\n      this.setHexValueIncludingUnusedBits(b);\n    } else {\n      if (typeof b.hex != \"undefined\") {\n        this.setHexValueIncludingUnusedBits(b.hex);\n      } else {\n        if (typeof b.bin != \"undefined\") {\n          this.setByBinaryString(b.bin);\n        } else {\n          if (typeof b.array != \"undefined\") {\n            this.setByBooleanArray(b.array);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);KJUR.asn1.DEROctetString = function (b) {\n  if (b !== undefined && typeof b.obj !== \"undefined\") {\n    var a = KJUR.asn1.ASN1Util.newObject(b.obj);b.hex = a.getEncodedHex();\n  }KJUR.asn1.DEROctetString.superclass.constructor.call(this, b);this.hT = \"04\";\n};YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERNull = function () {\n  KJUR.asn1.DERNull.superclass.constructor.call(this);this.hT = \"05\";this.hTLV = \"0500\";\n};YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);KJUR.asn1.DERObjectIdentifier = function (c) {\n  var b = function b(d) {\n    var e = d.toString(16);if (e.length == 1) {\n      e = \"0\" + e;\n    }return e;\n  };var a = function a(k) {\n    var j = \"\";var e = new BigInteger(k, 10);var d = e.toString(2);var f = 7 - d.length % 7;if (f == 7) {\n      f = 0;\n    }var m = \"\";for (var g = 0; g < f; g++) {\n      m += \"0\";\n    }d = m + d;for (var g = 0; g < d.length - 1; g += 7) {\n      var l = d.substr(g, 7);if (g != d.length - 7) {\n        l = \"1\" + l;\n      }j += b(parseInt(l, 2));\n    }return j;\n  };KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);this.hT = \"06\";this.setValueHex = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = null;this.hV = d;\n  };this.setValueOidString = function (f) {\n    if (!f.match(/^[0-9.]+$/)) {\n      throw \"malformed oid string: \" + f;\n    }var g = \"\";var d = f.split(\".\");var j = parseInt(d[0]) * 40 + parseInt(d[1]);g += b(j);d.splice(0, 2);for (var e = 0; e < d.length; e++) {\n      g += a(d[e]);\n    }this.hTLV = null;this.isModified = true;this.s = null;this.hV = g;\n  };this.setValueName = function (e) {\n    var d = KJUR.asn1.x509.OID.name2oid(e);if (d !== \"\") {\n      this.setValueOidString(d);\n    } else {\n      throw \"DERObjectIdentifier oidName undefined: \" + e;\n    }\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (c !== undefined) {\n    if (typeof c === \"string\") {\n      if (c.match(/^[0-2].[0-9.]+$/)) {\n        this.setValueOidString(c);\n      } else {\n        this.setValueName(c);\n      }\n    } else {\n      if (c.oid !== undefined) {\n        this.setValueOidString(c.oid);\n      } else {\n        if (c.hex !== undefined) {\n          this.setValueHex(c.hex);\n        } else {\n          if (c.name !== undefined) {\n            this.setValueName(c.name);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);KJUR.asn1.DEREnumerated = function (a) {\n  KJUR.asn1.DEREnumerated.superclass.constructor.call(this);this.hT = \"0a\";this.setByBigInteger = function (b) {\n    this.hTLV = null;this.isModified = true;this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(b);\n  };this.setByInteger = function (c) {\n    var b = new BigInteger(String(c), 10);this.setByBigInteger(b);\n  };this.setValueHex = function (b) {\n    this.hV = b;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a[\"int\"] != \"undefined\") {\n      this.setByInteger(a[\"int\"]);\n    } else {\n      if (typeof a == \"number\") {\n        this.setByInteger(a);\n      } else {\n        if (typeof a.hex != \"undefined\") {\n          this.setValueHex(a.hex);\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);KJUR.asn1.DERUTF8String = function (a) {\n  KJUR.asn1.DERUTF8String.superclass.constructor.call(this, a);this.hT = \"0c\";\n};YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);KJUR.asn1.DERNumericString = function (a) {\n  KJUR.asn1.DERNumericString.superclass.constructor.call(this, a);this.hT = \"12\";\n};YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERPrintableString = function (a) {\n  KJUR.asn1.DERPrintableString.superclass.constructor.call(this, a);this.hT = \"13\";\n};YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERTeletexString = function (a) {\n  KJUR.asn1.DERTeletexString.superclass.constructor.call(this, a);this.hT = \"14\";\n};YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERIA5String = function (a) {\n  KJUR.asn1.DERIA5String.superclass.constructor.call(this, a);this.hT = \"16\";\n};YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);KJUR.asn1.DERUTCTime = function (a) {\n  KJUR.asn1.DERUTCTime.superclass.constructor.call(this, a);this.hT = \"17\";this.setByDate = function (b) {\n    this.hTLV = null;this.isModified = true;this.date = b;this.s = this.formatDate(this.date, \"utc\");this.hV = stohex(this.s);\n  };this.getFreshValueHex = function () {\n    if (typeof this.date == \"undefined\" && typeof this.s == \"undefined\") {\n      this.date = new Date();this.s = this.formatDate(this.date, \"utc\");this.hV = stohex(this.s);\n    }return this.hV;\n  };if (a !== undefined) {\n    if (a.str !== undefined) {\n      this.setString(a.str);\n    } else {\n      if (typeof a == \"string\" && a.match(/^[0-9]{12}Z$/)) {\n        this.setString(a);\n      } else {\n        if (a.hex !== undefined) {\n          this.setStringHex(a.hex);\n        } else {\n          if (a.date !== undefined) {\n            this.setByDate(a.date);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);KJUR.asn1.DERGeneralizedTime = function (a) {\n  KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, a);this.hT = \"18\";this.withMillis = false;this.setByDate = function (b) {\n    this.hTLV = null;this.isModified = true;this.date = b;this.s = this.formatDate(this.date, \"gen\", this.withMillis);this.hV = stohex(this.s);\n  };this.getFreshValueHex = function () {\n    if (this.date === undefined && this.s === undefined) {\n      this.date = new Date();this.s = this.formatDate(this.date, \"gen\", this.withMillis);this.hV = stohex(this.s);\n    }return this.hV;\n  };if (a !== undefined) {\n    if (a.str !== undefined) {\n      this.setString(a.str);\n    } else {\n      if (typeof a == \"string\" && a.match(/^[0-9]{14}Z$/)) {\n        this.setString(a);\n      } else {\n        if (a.hex !== undefined) {\n          this.setStringHex(a.hex);\n        } else {\n          if (a.date !== undefined) {\n            this.setByDate(a.date);\n          }\n        }\n      }\n    }if (a.millis === true) {\n      this.withMillis = true;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);KJUR.asn1.DERSequence = function (a) {\n  KJUR.asn1.DERSequence.superclass.constructor.call(this, a);this.hT = \"30\";this.getFreshValueHex = function () {\n    var c = \"\";for (var b = 0; b < this.asn1Array.length; b++) {\n      var d = this.asn1Array[b];c += d.getEncodedHex();\n    }this.hV = c;return this.hV;\n  };\n};YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);KJUR.asn1.DERSet = function (a) {\n  KJUR.asn1.DERSet.superclass.constructor.call(this, a);this.hT = \"31\";this.sortFlag = true;this.getFreshValueHex = function () {\n    var b = new Array();for (var c = 0; c < this.asn1Array.length; c++) {\n      var d = this.asn1Array[c];b.push(d.getEncodedHex());\n    }if (this.sortFlag == true) {\n      b.sort();\n    }this.hV = b.join(\"\");return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.sortflag != \"undefined\" && a.sortflag == false) {\n      this.sortFlag = false;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);KJUR.asn1.DERTaggedObject = function (a) {\n  KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);this.hT = \"a0\";this.hV = \"\";this.isExplicit = true;this.asn1Object = null;this.setASN1Object = function (b, c, d) {\n    this.hT = c;this.isExplicit = b;this.asn1Object = d;if (this.isExplicit) {\n      this.hV = this.asn1Object.getEncodedHex();this.hTLV = null;this.isModified = true;\n    } else {\n      this.hV = null;this.hTLV = d.getEncodedHex();this.hTLV = this.hTLV.replace(/^../, c);this.isModified = false;\n    }\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.tag != \"undefined\") {\n      this.hT = a.tag;\n    }if (typeof a.explicit != \"undefined\") {\n      this.isExplicit = a.explicit;\n    }if (typeof a.obj != \"undefined\") {\n      this.asn1Object = a.obj;this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);\nvar ASN1HEX = new function () {}();ASN1HEX.getLblen = function (c, a) {\n  if (c.substr(a + 2, 1) != \"8\") {\n    return 1;\n  }var b = parseInt(c.substr(a + 3, 1));if (b == 0) {\n    return -1;\n  }if (0 < b && b < 10) {\n    return b + 1;\n  }return -2;\n};ASN1HEX.getL = function (c, b) {\n  var a = ASN1HEX.getLblen(c, b);if (a < 1) {\n    return \"\";\n  }return c.substr(b + 2, a * 2);\n};ASN1HEX.getVblen = function (d, a) {\n  var c, b;c = ASN1HEX.getL(d, a);if (c == \"\") {\n    return -1;\n  }if (c.substr(0, 1) === \"8\") {\n    b = new BigInteger(c.substr(2), 16);\n  } else {\n    b = new BigInteger(c, 16);\n  }return b.intValue();\n};ASN1HEX.getVidx = function (c, b) {\n  var a = ASN1HEX.getLblen(c, b);if (a < 0) {\n    return a;\n  }return b + (a + 1) * 2;\n};ASN1HEX.getV = function (d, a) {\n  var c = ASN1HEX.getVidx(d, a);var b = ASN1HEX.getVblen(d, a);return d.substr(c, b * 2);\n};ASN1HEX.getTLV = function (b, a) {\n  return b.substr(a, 2) + ASN1HEX.getL(b, a) + ASN1HEX.getV(b, a);\n};ASN1HEX.getNextSiblingIdx = function (d, a) {\n  var c = ASN1HEX.getVidx(d, a);var b = ASN1HEX.getVblen(d, a);return c + b * 2;\n};ASN1HEX.getChildIdx = function (e, f) {\n  var j = ASN1HEX;var g = new Array();var i = j.getVidx(e, f);if (e.substr(f, 2) == \"03\") {\n    g.push(i + 2);\n  } else {\n    g.push(i);\n  }var l = j.getVblen(e, f);var c = i;var d = 0;while (1) {\n    var b = j.getNextSiblingIdx(e, c);if (b == null || b - i >= l * 2) {\n      break;\n    }if (d >= 200) {\n      break;\n    }g.push(b);c = b;d++;\n  }return g;\n};ASN1HEX.getNthChildIdx = function (d, b, e) {\n  var c = ASN1HEX.getChildIdx(d, b);return c[e];\n};ASN1HEX.getIdxbyList = function (e, d, c, i) {\n  var g = ASN1HEX;var f, b;if (c.length == 0) {\n    if (i !== undefined) {\n      if (e.substr(d, 2) !== i) {\n        throw \"checking tag doesn't match: \" + e.substr(d, 2) + \"!=\" + i;\n      }\n    }return d;\n  }f = c.shift();b = g.getChildIdx(e, d);return g.getIdxbyList(e, b[f], c, i);\n};ASN1HEX.getTLVbyList = function (d, c, b, f) {\n  var e = ASN1HEX;var a = e.getIdxbyList(d, c, b);if (a === undefined) {\n    throw \"can't find nthList object\";\n  }if (f !== undefined) {\n    if (d.substr(a, 2) != f) {\n      throw \"checking tag doesn't match: \" + d.substr(a, 2) + \"!=\" + f;\n    }\n  }return e.getTLV(d, a);\n};ASN1HEX.getVbyList = function (e, c, b, g, i) {\n  var f = ASN1HEX;var a, d;a = f.getIdxbyList(e, c, b, g);if (a === undefined) {\n    throw \"can't find nthList object\";\n  }d = f.getV(e, a);if (i === true) {\n    d = d.substr(2);\n  }return d;\n};ASN1HEX.hextooidstr = function (e) {\n  var h = function h(b, a) {\n    if (b.length >= a) {\n      return b;\n    }return new Array(a - b.length + 1).join(\"0\") + b;\n  };var l = [];var o = e.substr(0, 2);var f = parseInt(o, 16);l[0] = new String(Math.floor(f / 40));l[1] = new String(f % 40);var m = e.substr(2);var k = [];for (var g = 0; g < m.length / 2; g++) {\n    k.push(parseInt(m.substr(g * 2, 2), 16));\n  }var j = [];var d = \"\";for (var g = 0; g < k.length; g++) {\n    if (k[g] & 128) {\n      d = d + h((k[g] & 127).toString(2), 7);\n    } else {\n      d = d + h((k[g] & 127).toString(2), 7);j.push(new String(parseInt(d, 2)));d = \"\";\n    }\n  }var n = l.join(\".\");if (j.length > 0) {\n    n = n + \".\" + j.join(\".\");\n  }return n;\n};ASN1HEX.dump = function (t, c, l, g) {\n  var p = ASN1HEX;var j = p.getV;var y = p.dump;var w = p.getChildIdx;var e = t;if (t instanceof KJUR.asn1.ASN1Object) {\n    e = t.getEncodedHex();\n  }var q = function q(A, i) {\n    if (A.length <= i * 2) {\n      return A;\n    } else {\n      var v = A.substr(0, i) + \"..(total \" + A.length / 2 + \"bytes)..\" + A.substr(A.length - i, i);return v;\n    }\n  };if (c === undefined) {\n    c = { ommit_long_octet: 32 };\n  }if (l === undefined) {\n    l = 0;\n  }if (g === undefined) {\n    g = \"\";\n  }var x = c.ommit_long_octet;if (e.substr(l, 2) == \"01\") {\n    var h = j(e, l);if (h == \"00\") {\n      return g + \"BOOLEAN FALSE\\n\";\n    } else {\n      return g + \"BOOLEAN TRUE\\n\";\n    }\n  }if (e.substr(l, 2) == \"02\") {\n    var h = j(e, l);return g + \"INTEGER \" + q(h, x) + \"\\n\";\n  }if (e.substr(l, 2) == \"03\") {\n    var h = j(e, l);return g + \"BITSTRING \" + q(h, x) + \"\\n\";\n  }if (e.substr(l, 2) == \"04\") {\n    var h = j(e, l);if (p.isASN1HEX(h)) {\n      var k = g + \"OCTETSTRING, encapsulates\\n\";k = k + y(h, c, 0, g + \"  \");return k;\n    } else {\n      return g + \"OCTETSTRING \" + q(h, x) + \"\\n\";\n    }\n  }if (e.substr(l, 2) == \"05\") {\n    return g + \"NULL\\n\";\n  }if (e.substr(l, 2) == \"06\") {\n    var m = j(e, l);var a = KJUR.asn1.ASN1Util.oidHexToInt(m);var o = KJUR.asn1.x509.OID.oid2name(a);var b = a.replace(/\\./g, \" \");if (o != \"\") {\n      return g + \"ObjectIdentifier \" + o + \" (\" + b + \")\\n\";\n    } else {\n      return g + \"ObjectIdentifier (\" + b + \")\\n\";\n    }\n  }if (e.substr(l, 2) == \"0c\") {\n    return g + \"UTF8String '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"13\") {\n    return g + \"PrintableString '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"14\") {\n    return g + \"TeletexString '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"16\") {\n    return g + \"IA5String '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"17\") {\n    return g + \"UTCTime \" + hextoutf8(j(e, l)) + \"\\n\";\n  }if (e.substr(l, 2) == \"18\") {\n    return g + \"GeneralizedTime \" + hextoutf8(j(e, l)) + \"\\n\";\n  }if (e.substr(l, 2) == \"30\") {\n    if (e.substr(l, 4) == \"3000\") {\n      return g + \"SEQUENCE {}\\n\";\n    }var k = g + \"SEQUENCE\\n\";var d = w(e, l);var f = c;if ((d.length == 2 || d.length == 3) && e.substr(d[0], 2) == \"06\" && e.substr(d[d.length - 1], 2) == \"04\") {\n      var o = p.oidname(j(e, d[0]));var r = JSON.parse(JSON.stringify(c));r.x509ExtName = o;f = r;\n    }for (var u = 0; u < d.length; u++) {\n      k = k + y(e, f, d[u], g + \"  \");\n    }return k;\n  }if (e.substr(l, 2) == \"31\") {\n    var k = g + \"SET\\n\";var d = w(e, l);for (var u = 0; u < d.length; u++) {\n      k = k + y(e, c, d[u], g + \"  \");\n    }return k;\n  }var z = parseInt(e.substr(l, 2), 16);if ((z & 128) != 0) {\n    var n = z & 31;if ((z & 32) != 0) {\n      var k = g + \"[\" + n + \"]\\n\";var d = w(e, l);for (var u = 0; u < d.length; u++) {\n        k = k + y(e, c, d[u], g + \"  \");\n      }return k;\n    } else {\n      var h = j(e, l);if (h.substr(0, 8) == \"68747470\") {\n        h = hextoutf8(h);\n      }if (c.x509ExtName === \"subjectAltName\" && n == 2) {\n        h = hextoutf8(h);\n      }var k = g + \"[\" + n + \"] \" + h + \"\\n\";return k;\n    }\n  }return g + \"UNKNOWN(\" + e.substr(l, 2) + \") \" + j(e, l) + \"\\n\";\n};ASN1HEX.isASN1HEX = function (e) {\n  var d = ASN1HEX;if (e.length % 2 == 1) {\n    return false;\n  }var c = d.getVblen(e, 0);var b = e.substr(0, 2);var f = d.getL(e, 0);var a = e.length - b.length - f.length;if (a == c * 2) {\n    return true;\n  }return false;\n};ASN1HEX.oidname = function (a) {\n  var c = KJUR.asn1;if (KJUR.lang.String.isHex(a)) {\n    a = c.ASN1Util.oidHexToInt(a);\n  }var b = c.x509.OID.oid2name(a);if (b === \"\") {\n    b = a;\n  }return b;\n};\nvar KJUR;if (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.lang == \"undefined\" || !KJUR.lang) {\n  KJUR.lang = {};\n}KJUR.lang.String = function () {};function Base64x() {}function stoBA(d) {\n  var b = new Array();for (var c = 0; c < d.length; c++) {\n    b[c] = d.charCodeAt(c);\n  }return b;\n}function BAtos(b) {\n  var d = \"\";for (var c = 0; c < b.length; c++) {\n    d = d + String.fromCharCode(b[c]);\n  }return d;\n}function BAtohex(b) {\n  var e = \"\";for (var d = 0; d < b.length; d++) {\n    var c = b[d].toString(16);if (c.length == 1) {\n      c = \"0\" + c;\n    }e = e + c;\n  }return e;\n}function stohex(a) {\n  return BAtohex(stoBA(a));\n}function stob64(a) {\n  return hex2b64(stohex(a));\n}function stob64u(a) {\n  return b64tob64u(hex2b64(stohex(a)));\n}function b64utos(a) {\n  return BAtos(b64toBA(b64utob64(a)));\n}function b64tob64u(a) {\n  a = a.replace(/\\=/g, \"\");a = a.replace(/\\+/g, \"-\");a = a.replace(/\\//g, \"_\");return a;\n}function b64utob64(a) {\n  if (a.length % 4 == 2) {\n    a = a + \"==\";\n  } else {\n    if (a.length % 4 == 3) {\n      a = a + \"=\";\n    }\n  }a = a.replace(/-/g, \"+\");a = a.replace(/_/g, \"/\");return a;\n}function hextob64u(a) {\n  if (a.length % 2 == 1) {\n    a = \"0\" + a;\n  }return b64tob64u(hex2b64(a));\n}function b64utohex(a) {\n  return b64tohex(b64utob64(a));\n}var utf8tob64u, b64utoutf8;if (typeof Buffer === \"function\") {\n  exports.utf8tob64u = utf8tob64u = function utf8tob64u(a) {\n    return b64tob64u(new Buffer(a, \"utf8\").toString(\"base64\"));\n  };exports.b64utoutf8 = b64utoutf8 = function b64utoutf8(a) {\n    return new Buffer(b64utob64(a), \"base64\").toString(\"utf8\");\n  };\n} else {\n  exports.utf8tob64u = utf8tob64u = function utf8tob64u(a) {\n    return hextob64u(uricmptohex(encodeURIComponentAll(a)));\n  };exports.b64utoutf8 = b64utoutf8 = function b64utoutf8(a) {\n    return decodeURIComponent(hextouricmp(b64utohex(a)));\n  };\n}function utf8tob64(a) {\n  return hex2b64(uricmptohex(encodeURIComponentAll(a)));\n}function b64toutf8(a) {\n  return decodeURIComponent(hextouricmp(b64tohex(a)));\n}function utf8tohex(a) {\n  return uricmptohex(encodeURIComponentAll(a));\n}function hextoutf8(a) {\n  return decodeURIComponent(hextouricmp(a));\n}function hextorstr(c) {\n  var b = \"\";for (var a = 0; a < c.length - 1; a += 2) {\n    b += String.fromCharCode(parseInt(c.substr(a, 2), 16));\n  }return b;\n}function rstrtohex(c) {\n  var a = \"\";for (var b = 0; b < c.length; b++) {\n    a += (\"0\" + c.charCodeAt(b).toString(16)).slice(-2);\n  }return a;\n}function hextob64(a) {\n  return hex2b64(a);\n}function hextob64nl(b) {\n  var a = hextob64(b);var c = a.replace(/(.{64})/g, \"$1\\r\\n\");c = c.replace(/\\r\\n$/, \"\");return c;\n}function b64nltohex(b) {\n  var a = b.replace(/[^0-9A-Za-z\\/+=]*/g, \"\");var c = b64tohex(a);return c;\n}function hextopem(a, b) {\n  var c = hextob64nl(a);return \"-----BEGIN \" + b + \"-----\\r\\n\" + c + \"\\r\\n-----END \" + b + \"-----\\r\\n\";\n}function pemtohex(a, b) {\n  if (a.indexOf(\"-----BEGIN \") == -1) {\n    throw \"can't find PEM header: \" + b;\n  }if (b !== undefined) {\n    a = a.replace(\"-----BEGIN \" + b + \"-----\", \"\");a = a.replace(\"-----END \" + b + \"-----\", \"\");\n  } else {\n    a = a.replace(/-----BEGIN [^-]+-----/, \"\");a = a.replace(/-----END [^-]+-----/, \"\");\n  }return b64nltohex(a);\n}function hextoArrayBuffer(d) {\n  if (d.length % 2 != 0) {\n    throw \"input is not even length\";\n  }if (d.match(/^[0-9A-Fa-f]+$/) == null) {\n    throw \"input is not hexadecimal\";\n  }var b = new ArrayBuffer(d.length / 2);var a = new DataView(b);for (var c = 0; c < d.length / 2; c++) {\n    a.setUint8(c, parseInt(d.substr(c * 2, 2), 16));\n  }return b;\n}function ArrayBuffertohex(b) {\n  var d = \"\";var a = new DataView(b);for (var c = 0; c < b.byteLength; c++) {\n    d += (\"00\" + a.getUint8(c).toString(16)).slice(-2);\n  }return d;\n}function zulutomsec(n) {\n  var l, j, m, e, f, i, b, k;var a, h, g, c;c = n.match(/^(\\d{2}|\\d{4})(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(|\\.\\d+)Z$/);if (c) {\n    a = c[1];l = parseInt(a);if (a.length === 2) {\n      if (50 <= l && l < 100) {\n        l = 1900 + l;\n      } else {\n        if (0 <= l && l < 50) {\n          l = 2000 + l;\n        }\n      }\n    }j = parseInt(c[2]) - 1;m = parseInt(c[3]);e = parseInt(c[4]);f = parseInt(c[5]);i = parseInt(c[6]);b = 0;h = c[7];if (h !== \"\") {\n      g = (h.substr(1) + \"00\").substr(0, 3);b = parseInt(g);\n    }return Date.UTC(l, j, m, e, f, i, b);\n  }throw \"unsupported zulu format: \" + n;\n}function zulutosec(a) {\n  var b = zulutomsec(a);return ~~(b / 1000);\n}function zulutodate(a) {\n  return new Date(zulutomsec(a));\n}function datetozulu(g, e, f) {\n  var b;var a = g.getUTCFullYear();if (e) {\n    if (a < 1950 || 2049 < a) {\n      throw \"not proper year for UTCTime: \" + a;\n    }b = (\"\" + a).slice(-2);\n  } else {\n    b = (\"000\" + a).slice(-4);\n  }b += (\"0\" + (g.getUTCMonth() + 1)).slice(-2);b += (\"0\" + g.getUTCDate()).slice(-2);b += (\"0\" + g.getUTCHours()).slice(-2);b += (\"0\" + g.getUTCMinutes()).slice(-2);b += (\"0\" + g.getUTCSeconds()).slice(-2);if (f) {\n    var c = g.getUTCMilliseconds();if (c !== 0) {\n      c = (\"00\" + c).slice(-3);c = c.replace(/0+$/g, \"\");b += \".\" + c;\n    }\n  }b += \"Z\";return b;\n}function uricmptohex(a) {\n  return a.replace(/%/g, \"\");\n}function hextouricmp(a) {\n  return a.replace(/(..)/g, \"%$1\");\n}function ipv6tohex(g) {\n  var b = \"malformed IPv6 address\";if (!g.match(/^[0-9A-Fa-f:]+$/)) {\n    throw b;\n  }g = g.toLowerCase();var d = g.split(\":\").length - 1;if (d < 2) {\n    throw b;\n  }var e = \":\".repeat(7 - d + 2);g = g.replace(\"::\", e);var c = g.split(\":\");if (c.length != 8) {\n    throw b;\n  }for (var f = 0; f < 8; f++) {\n    c[f] = (\"0000\" + c[f]).slice(-4);\n  }return c.join(\"\");\n}function hextoipv6(e) {\n  if (!e.match(/^[0-9A-Fa-f]{32}$/)) {\n    throw \"malformed IPv6 address octet\";\n  }e = e.toLowerCase();var b = e.match(/.{1,4}/g);for (var d = 0; d < 8; d++) {\n    b[d] = b[d].replace(/^0+/, \"\");if (b[d] == \"\") {\n      b[d] = \"0\";\n    }\n  }e = \":\" + b.join(\":\") + \":\";var c = e.match(/:(0:){2,}/g);if (c === null) {\n    return e.slice(1, -1);\n  }var f = \"\";for (var d = 0; d < c.length; d++) {\n    if (c[d].length > f.length) {\n      f = c[d];\n    }\n  }e = e.replace(f, \"::\");return e.slice(1, -1);\n}function hextoip(b) {\n  var d = \"malformed hex value\";if (!b.match(/^([0-9A-Fa-f][0-9A-Fa-f]){1,}$/)) {\n    throw d;\n  }if (b.length == 8) {\n    var c;try {\n      c = parseInt(b.substr(0, 2), 16) + \".\" + parseInt(b.substr(2, 2), 16) + \".\" + parseInt(b.substr(4, 2), 16) + \".\" + parseInt(b.substr(6, 2), 16);return c;\n    } catch (a) {\n      throw d;\n    }\n  } else {\n    if (b.length == 32) {\n      return hextoipv6(b);\n    } else {\n      return b;\n    }\n  }\n}function iptohex(f) {\n  var j = \"malformed IP address\";f = f.toLowerCase(f);if (f.match(/^[0-9.]+$/)) {\n    var b = f.split(\".\");if (b.length !== 4) {\n      throw j;\n    }var g = \"\";try {\n      for (var e = 0; e < 4; e++) {\n        var h = parseInt(b[e]);g += (\"0\" + h.toString(16)).slice(-2);\n      }return g;\n    } catch (c) {\n      throw j;\n    }\n  } else {\n    if (f.match(/^[0-9a-f:]+$/) && f.indexOf(\":\") !== -1) {\n      return ipv6tohex(f);\n    } else {\n      throw j;\n    }\n  }\n}function encodeURIComponentAll(a) {\n  var d = encodeURIComponent(a);var b = \"\";for (var c = 0; c < d.length; c++) {\n    if (d[c] == \"%\") {\n      b = b + d.substr(c, 3);c = c + 2;\n    } else {\n      b = b + \"%\" + stohex(d[c]);\n    }\n  }return b;\n}function newline_toUnix(a) {\n  a = a.replace(/\\r\\n/mg, \"\\n\");return a;\n}function newline_toDos(a) {\n  a = a.replace(/\\r\\n/mg, \"\\n\");a = a.replace(/\\n/mg, \"\\r\\n\");return a;\n}KJUR.lang.String.isInteger = function (a) {\n  if (a.match(/^[0-9]+$/)) {\n    return true;\n  } else {\n    if (a.match(/^-[0-9]+$/)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n};KJUR.lang.String.isHex = function (a) {\n  if (a.length % 2 == 0 && (a.match(/^[0-9a-f]+$/) || a.match(/^[0-9A-F]+$/))) {\n    return true;\n  } else {\n    return false;\n  }\n};KJUR.lang.String.isBase64 = function (a) {\n  a = a.replace(/\\s+/g, \"\");if (a.match(/^[0-9A-Za-z+\\/]+={0,3}$/) && a.length % 4 == 0) {\n    return true;\n  } else {\n    return false;\n  }\n};KJUR.lang.String.isBase64URL = function (a) {\n  if (a.match(/[+/=]/)) {\n    return false;\n  }a = b64utob64(a);return KJUR.lang.String.isBase64(a);\n};KJUR.lang.String.isIntegerArray = function (a) {\n  a = a.replace(/\\s+/g, \"\");if (a.match(/^\\[[0-9,]+\\]$/)) {\n    return true;\n  } else {\n    return false;\n  }\n};function hextoposhex(a) {\n  if (a.length % 2 == 1) {\n    return \"0\" + a;\n  }if (a.substr(0, 1) > \"7\") {\n    return \"00\" + a;\n  }return a;\n}function intarystrtohex(b) {\n  b = b.replace(/^\\s*\\[\\s*/, \"\");b = b.replace(/\\s*\\]\\s*$/, \"\");b = b.replace(/\\s*/g, \"\");try {\n    var c = b.split(/,/).map(function (g, e, h) {\n      var f = parseInt(g);if (f < 0 || 255 < f) {\n        throw \"integer not in range 0-255\";\n      }var d = (\"00\" + f.toString(16)).slice(-2);return d;\n    }).join(\"\");return c;\n  } catch (a) {\n    throw \"malformed integer array string: \" + a;\n  }\n}var strdiffidx = function strdiffidx(c, a) {\n  var d = c.length;if (c.length > a.length) {\n    d = a.length;\n  }for (var b = 0; b < d; b++) {\n    if (c.charCodeAt(b) != a.charCodeAt(b)) {\n      return b;\n    }\n  }if (c.length != a.length) {\n    return d;\n  }return -1;\n};\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.Util = new function () {\n  this.DIGESTINFOHEAD = { sha1: \"3021300906052b0e03021a05000414\", sha224: \"302d300d06096086480165030402040500041c\", sha256: \"3031300d060960864801650304020105000420\", sha384: \"3041300d060960864801650304020205000430\", sha512: \"3051300d060960864801650304020305000440\", md2: \"3020300c06082a864886f70d020205000410\", md5: \"3020300c06082a864886f70d020505000410\", ripemd160: \"3021300906052b2403020105000414\" };this.DEFAULTPROVIDER = { md5: \"cryptojs\", sha1: \"cryptojs\", sha224: \"cryptojs\", sha256: \"cryptojs\", sha384: \"cryptojs\", sha512: \"cryptojs\", ripemd160: \"cryptojs\", hmacmd5: \"cryptojs\", hmacsha1: \"cryptojs\", hmacsha224: \"cryptojs\", hmacsha256: \"cryptojs\", hmacsha384: \"cryptojs\", hmacsha512: \"cryptojs\", hmacripemd160: \"cryptojs\", MD5withRSA: \"cryptojs/jsrsa\", SHA1withRSA: \"cryptojs/jsrsa\", SHA224withRSA: \"cryptojs/jsrsa\", SHA256withRSA: \"cryptojs/jsrsa\", SHA384withRSA: \"cryptojs/jsrsa\", SHA512withRSA: \"cryptojs/jsrsa\", RIPEMD160withRSA: \"cryptojs/jsrsa\", MD5withECDSA: \"cryptojs/jsrsa\", SHA1withECDSA: \"cryptojs/jsrsa\", SHA224withECDSA: \"cryptojs/jsrsa\", SHA256withECDSA: \"cryptojs/jsrsa\", SHA384withECDSA: \"cryptojs/jsrsa\", SHA512withECDSA: \"cryptojs/jsrsa\", RIPEMD160withECDSA: \"cryptojs/jsrsa\", SHA1withDSA: \"cryptojs/jsrsa\", SHA224withDSA: \"cryptojs/jsrsa\", SHA256withDSA: \"cryptojs/jsrsa\", MD5withRSAandMGF1: \"cryptojs/jsrsa\", SHA1withRSAandMGF1: \"cryptojs/jsrsa\", SHA224withRSAandMGF1: \"cryptojs/jsrsa\", SHA256withRSAandMGF1: \"cryptojs/jsrsa\", SHA384withRSAandMGF1: \"cryptojs/jsrsa\", SHA512withRSAandMGF1: \"cryptojs/jsrsa\", RIPEMD160withRSAandMGF1: \"cryptojs/jsrsa\" };this.CRYPTOJSMESSAGEDIGESTNAME = { md5: CryptoJS.algo.MD5, sha1: CryptoJS.algo.SHA1, sha224: CryptoJS.algo.SHA224, sha256: CryptoJS.algo.SHA256, sha384: CryptoJS.algo.SHA384, sha512: CryptoJS.algo.SHA512, ripemd160: CryptoJS.algo.RIPEMD160 };this.getDigestInfoHex = function (a, b) {\n    if (typeof this.DIGESTINFOHEAD[b] == \"undefined\") {\n      throw \"alg not supported in Util.DIGESTINFOHEAD: \" + b;\n    }return this.DIGESTINFOHEAD[b] + a;\n  };this.getPaddedDigestInfoHex = function (h, a, j) {\n    var c = this.getDigestInfoHex(h, a);var d = j / 4;if (c.length + 22 > d) {\n      throw \"key is too short for SigAlg: keylen=\" + j + \",\" + a;\n    }var b = \"0001\";var k = \"00\" + c;var g = \"\";var l = d - b.length - k.length;for (var f = 0; f < l; f += 2) {\n      g += \"ff\";\n    }var e = b + g + k;return e;\n  };this.hashString = function (a, c) {\n    var b = new KJUR.crypto.MessageDigest({ alg: c });return b.digestString(a);\n  };this.hashHex = function (b, c) {\n    var a = new KJUR.crypto.MessageDigest({ alg: c });return a.digestHex(b);\n  };this.sha1 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha1\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha256 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha256\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha256Hex = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha256\", prov: \"cryptojs\" });return b.digestHex(a);\n  };this.sha512 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha512\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha512Hex = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha512\", prov: \"cryptojs\" });return b.digestHex(a);\n  };\n}();KJUR.crypto.Util.md5 = function (a) {\n  var b = new KJUR.crypto.MessageDigest({ alg: \"md5\", prov: \"cryptojs\" });return b.digestString(a);\n};KJUR.crypto.Util.ripemd160 = function (a) {\n  var b = new KJUR.crypto.MessageDigest({ alg: \"ripemd160\", prov: \"cryptojs\" });return b.digestString(a);\n};KJUR.crypto.Util.SECURERANDOMGEN = new SecureRandom();KJUR.crypto.Util.getRandomHexOfNbytes = function (b) {\n  var a = new Array(b);KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(a);return BAtohex(a);\n};KJUR.crypto.Util.getRandomBigIntegerOfNbytes = function (a) {\n  return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbytes(a), 16);\n};KJUR.crypto.Util.getRandomHexOfNbits = function (d) {\n  var c = d % 8;var a = (d - c) / 8;var b = new Array(a + 1);KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(b);b[0] = (255 << c & 255 ^ 255) & b[0];return BAtohex(b);\n};KJUR.crypto.Util.getRandomBigIntegerOfNbits = function (a) {\n  return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbits(a), 16);\n};KJUR.crypto.Util.getRandomBigIntegerZeroToMax = function (b) {\n  var a = b.bitLength();while (1) {\n    var c = KJUR.crypto.Util.getRandomBigIntegerOfNbits(a);if (b.compareTo(c) != -1) {\n      return c;\n    }\n  }\n};KJUR.crypto.Util.getRandomBigIntegerMinToMax = function (e, b) {\n  var c = e.compareTo(b);if (c == 1) {\n    throw \"biMin is greater than biMax\";\n  }if (c == 0) {\n    return e;\n  }var a = b.subtract(e);var d = KJUR.crypto.Util.getRandomBigIntegerZeroToMax(a);return d.add(e);\n};KJUR.crypto.MessageDigest = function (c) {\n  var b = null;var a = null;var d = null;this.setAlgAndProvider = function (g, f) {\n    g = KJUR.crypto.MessageDigest.getCanonicalAlgName(g);if (g !== null && f === undefined) {\n      f = KJUR.crypto.Util.DEFAULTPROVIDER[g];\n    }if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(g) != -1 && f == \"cryptojs\") {\n      try {\n        this.md = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[g].create();\n      } catch (e) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + g + \"/\" + e;\n      }this.updateString = function (h) {\n        this.md.update(h);\n      };this.updateHex = function (h) {\n        var i = CryptoJS.enc.Hex.parse(h);this.md.update(i);\n      };this.digest = function () {\n        var h = this.md.finalize();return h.toString(CryptoJS.enc.Hex);\n      };this.digestString = function (h) {\n        this.updateString(h);return this.digest();\n      };this.digestHex = function (h) {\n        this.updateHex(h);return this.digest();\n      };\n    }if (\":sha256:\".indexOf(g) != -1 && f == \"sjcl\") {\n      try {\n        this.md = new sjcl.hash.sha256();\n      } catch (e) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + g + \"/\" + e;\n      }this.updateString = function (h) {\n        this.md.update(h);\n      };this.updateHex = function (i) {\n        var h = sjcl.codec.hex.toBits(i);this.md.update(h);\n      };this.digest = function () {\n        var h = this.md.finalize();return sjcl.codec.hex.fromBits(h);\n      };this.digestString = function (h) {\n        this.updateString(h);return this.digest();\n      };this.digestHex = function (h) {\n        this.updateHex(h);return this.digest();\n      };\n    }\n  };this.updateString = function (e) {\n    throw \"updateString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.updateHex = function (e) {\n    throw \"updateHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digest = function () {\n    throw \"digest() not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digestString = function (e) {\n    throw \"digestString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digestHex = function (e) {\n    throw \"digestHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };if (c !== undefined) {\n    if (c.alg !== undefined) {\n      this.algName = c.alg;if (c.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      }this.setAlgAndProvider(this.algName, this.provName);\n    }\n  }\n};KJUR.crypto.MessageDigest.getCanonicalAlgName = function (a) {\n  if (typeof a === \"string\") {\n    a = a.toLowerCase();a = a.replace(/-/, \"\");\n  }return a;\n};KJUR.crypto.MessageDigest.getHashLength = function (c) {\n  var b = KJUR.crypto.MessageDigest;var a = b.getCanonicalAlgName(c);if (b.HASHLENGTH[a] === undefined) {\n    throw \"not supported algorithm: \" + c;\n  }return b.HASHLENGTH[a];\n};KJUR.crypto.MessageDigest.HASHLENGTH = { md5: 16, sha1: 20, sha224: 28, sha256: 32, sha384: 48, sha512: 64, ripemd160: 20 };KJUR.crypto.Mac = function (d) {\n  var f = null;var c = null;var a = null;var e = null;var b = null;this.setAlgAndProvider = function (k, i) {\n    k = k.toLowerCase();if (k == null) {\n      k = \"hmacsha1\";\n    }k = k.toLowerCase();if (k.substr(0, 4) != \"hmac\") {\n      throw \"setAlgAndProvider unsupported HMAC alg: \" + k;\n    }if (i === undefined) {\n      i = KJUR.crypto.Util.DEFAULTPROVIDER[k];\n    }this.algProv = k + \"/\" + i;var g = k.substr(4);if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(g) != -1 && i == \"cryptojs\") {\n      try {\n        var j = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[g];this.mac = CryptoJS.algo.HMAC.create(j, this.pass);\n      } catch (h) {\n        throw \"setAlgAndProvider hash alg set fail hashAlg=\" + g + \"/\" + h;\n      }this.updateString = function (l) {\n        this.mac.update(l);\n      };this.updateHex = function (l) {\n        var m = CryptoJS.enc.Hex.parse(l);this.mac.update(m);\n      };this.doFinal = function () {\n        var l = this.mac.finalize();return l.toString(CryptoJS.enc.Hex);\n      };this.doFinalString = function (l) {\n        this.updateString(l);return this.doFinal();\n      };this.doFinalHex = function (l) {\n        this.updateHex(l);return this.doFinal();\n      };\n    }\n  };this.updateString = function (g) {\n    throw \"updateString(str) not supported for this alg/prov: \" + this.algProv;\n  };this.updateHex = function (g) {\n    throw \"updateHex(hex) not supported for this alg/prov: \" + this.algProv;\n  };this.doFinal = function () {\n    throw \"digest() not supported for this alg/prov: \" + this.algProv;\n  };this.doFinalString = function (g) {\n    throw \"digestString(str) not supported for this alg/prov: \" + this.algProv;\n  };this.doFinalHex = function (g) {\n    throw \"digestHex(hex) not supported for this alg/prov: \" + this.algProv;\n  };this.setPassword = function (h) {\n    if (typeof h == \"string\") {\n      var g = h;if (h.length % 2 == 1 || !h.match(/^[0-9A-Fa-f]+$/)) {\n        g = rstrtohex(h);\n      }this.pass = CryptoJS.enc.Hex.parse(g);return;\n    }if ((typeof h === \"undefined\" ? \"undefined\" : _typeof(h)) != \"object\") {\n      throw \"KJUR.crypto.Mac unsupported password type: \" + h;\n    }var g = null;if (h.hex !== undefined) {\n      if (h.hex.length % 2 != 0 || !h.hex.match(/^[0-9A-Fa-f]+$/)) {\n        throw \"Mac: wrong hex password: \" + h.hex;\n      }g = h.hex;\n    }if (h.utf8 !== undefined) {\n      g = utf8tohex(h.utf8);\n    }if (h.rstr !== undefined) {\n      g = rstrtohex(h.rstr);\n    }if (h.b64 !== undefined) {\n      g = b64tohex(h.b64);\n    }if (h.b64u !== undefined) {\n      g = b64utohex(h.b64u);\n    }if (g == null) {\n      throw \"KJUR.crypto.Mac unsupported password type: \" + h;\n    }this.pass = CryptoJS.enc.Hex.parse(g);\n  };if (d !== undefined) {\n    if (d.pass !== undefined) {\n      this.setPassword(d.pass);\n    }if (d.alg !== undefined) {\n      this.algName = d.alg;if (d.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      }this.setAlgAndProvider(this.algName, this.provName);\n    }\n  }\n};KJUR.crypto.Signature = function (o) {\n  var q = null;var n = null;var r = null;var c = null;var l = null;var d = null;var k = null;var h = null;var p = null;var e = null;var b = -1;var g = null;var j = null;var a = null;var i = null;var f = null;this._setAlgNames = function () {\n    var s = this.algName.match(/^(.+)with(.+)$/);if (s) {\n      this.mdAlgName = s[1].toLowerCase();this.pubkeyAlgName = s[2].toLowerCase();\n    }\n  };this._zeroPaddingOfSignature = function (x, w) {\n    var v = \"\";var t = w / 4 - x.length;for (var u = 0; u < t; u++) {\n      v = v + \"0\";\n    }return v + x;\n  };this.setAlgAndProvider = function (u, t) {\n    this._setAlgNames();if (t != \"cryptojs/jsrsa\") {\n      throw \"provider not supported: \" + t;\n    }if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(this.mdAlgName) != -1) {\n      try {\n        this.md = new KJUR.crypto.MessageDigest({ alg: this.mdAlgName });\n      } catch (s) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + this.mdAlgName + \"/\" + s;\n      }this.init = function (w, x) {\n        var y = null;try {\n          if (x === undefined) {\n            y = KEYUTIL.getKey(w);\n          } else {\n            y = KEYUTIL.getKey(w, x);\n          }\n        } catch (v) {\n          throw \"init failed:\" + v;\n        }if (y.isPrivate === true) {\n          this.prvKey = y;this.state = \"SIGN\";\n        } else {\n          if (y.isPublic === true) {\n            this.pubKey = y;this.state = \"VERIFY\";\n          } else {\n            throw \"init failed.:\" + y;\n          }\n        }\n      };this.updateString = function (v) {\n        this.md.updateString(v);\n      };this.updateHex = function (v) {\n        this.md.updateHex(v);\n      };this.sign = function () {\n        this.sHashHex = this.md.digest();if (typeof this.ecprvhex != \"undefined\" && typeof this.eccurvename != \"undefined\") {\n          var v = new KJUR.crypto.ECDSA({ curve: this.eccurvename });this.hSign = v.signHex(this.sHashHex, this.ecprvhex);\n        } else {\n          if (this.prvKey instanceof RSAKey && this.pubkeyAlgName === \"rsaandmgf1\") {\n            this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex, this.mdAlgName, this.pssSaltLen);\n          } else {\n            if (this.prvKey instanceof RSAKey && this.pubkeyAlgName === \"rsa\") {\n              this.hSign = this.prvKey.signWithMessageHash(this.sHashHex, this.mdAlgName);\n            } else {\n              if (this.prvKey instanceof KJUR.crypto.ECDSA) {\n                this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n              } else {\n                if (this.prvKey instanceof KJUR.crypto.DSA) {\n                  this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n                } else {\n                  throw \"Signature: unsupported private key alg: \" + this.pubkeyAlgName;\n                }\n              }\n            }\n          }\n        }return this.hSign;\n      };this.signString = function (v) {\n        this.updateString(v);return this.sign();\n      };this.signHex = function (v) {\n        this.updateHex(v);return this.sign();\n      };this.verify = function (v) {\n        this.sHashHex = this.md.digest();if (typeof this.ecpubhex != \"undefined\" && typeof this.eccurvename != \"undefined\") {\n          var w = new KJUR.crypto.ECDSA({ curve: this.eccurvename });return w.verifyHex(this.sHashHex, v, this.ecpubhex);\n        } else {\n          if (this.pubKey instanceof RSAKey && this.pubkeyAlgName === \"rsaandmgf1\") {\n            return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, v, this.mdAlgName, this.pssSaltLen);\n          } else {\n            if (this.pubKey instanceof RSAKey && this.pubkeyAlgName === \"rsa\") {\n              return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n            } else {\n              if (KJUR.crypto.ECDSA !== undefined && this.pubKey instanceof KJUR.crypto.ECDSA) {\n                return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n              } else {\n                if (KJUR.crypto.DSA !== undefined && this.pubKey instanceof KJUR.crypto.DSA) {\n                  return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n                } else {\n                  throw \"Signature: unsupported public key alg: \" + this.pubkeyAlgName;\n                }\n              }\n            }\n          }\n        }\n      };\n    }\n  };this.init = function (s, t) {\n    throw \"init(key, pass) not supported for this alg:prov=\" + this.algProvName;\n  };this.updateString = function (s) {\n    throw \"updateString(str) not supported for this alg:prov=\" + this.algProvName;\n  };this.updateHex = function (s) {\n    throw \"updateHex(hex) not supported for this alg:prov=\" + this.algProvName;\n  };this.sign = function () {\n    throw \"sign() not supported for this alg:prov=\" + this.algProvName;\n  };this.signString = function (s) {\n    throw \"digestString(str) not supported for this alg:prov=\" + this.algProvName;\n  };this.signHex = function (s) {\n    throw \"digestHex(hex) not supported for this alg:prov=\" + this.algProvName;\n  };this.verify = function (s) {\n    throw \"verify(hSigVal) not supported for this alg:prov=\" + this.algProvName;\n  };this.initParams = o;if (o !== undefined) {\n    if (o.alg !== undefined) {\n      this.algName = o.alg;if (o.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      } else {\n        this.provName = o.prov;\n      }this.algProvName = this.algName + \":\" + this.provName;this.setAlgAndProvider(this.algName, this.provName);this._setAlgNames();\n    }if (o.psssaltlen !== undefined) {\n      this.pssSaltLen = o.psssaltlen;\n    }if (o.prvkeypem !== undefined) {\n      if (o.prvkeypas !== undefined) {\n        throw \"both prvkeypem and prvkeypas parameters not supported\";\n      } else {\n        try {\n          var q = KEYUTIL.getKey(o.prvkeypem);this.init(q);\n        } catch (m) {\n          throw \"fatal error to load pem private key: \" + m;\n        }\n      }\n    }\n  }\n};KJUR.crypto.Cipher = function (a) {};KJUR.crypto.Cipher.encrypt = function (e, f, d) {\n  if (f instanceof RSAKey && f.isPublic) {\n    var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);if (c === \"RSA\") {\n      return f.encrypt(e);\n    }if (c === \"RSAOAEP\") {\n      return f.encryptOAEP(e, \"sha1\");\n    }var b = c.match(/^RSAOAEP(\\d+)$/);if (b !== null) {\n      return f.encryptOAEP(e, \"sha\" + b[1]);\n    }throw \"Cipher.encrypt: unsupported algorithm for RSAKey: \" + d;\n  } else {\n    throw \"Cipher.encrypt: unsupported key or algorithm\";\n  }\n};KJUR.crypto.Cipher.decrypt = function (e, f, d) {\n  if (f instanceof RSAKey && f.isPrivate) {\n    var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);if (c === \"RSA\") {\n      return f.decrypt(e);\n    }if (c === \"RSAOAEP\") {\n      return f.decryptOAEP(e, \"sha1\");\n    }var b = c.match(/^RSAOAEP(\\d+)$/);if (b !== null) {\n      return f.decryptOAEP(e, \"sha\" + b[1]);\n    }throw \"Cipher.decrypt: unsupported algorithm for RSAKey: \" + d;\n  } else {\n    throw \"Cipher.decrypt: unsupported key or algorithm\";\n  }\n};KJUR.crypto.Cipher.getAlgByKeyAndName = function (b, a) {\n  if (b instanceof RSAKey) {\n    if (\":RSA:RSAOAEP:RSAOAEP224:RSAOAEP256:RSAOAEP384:RSAOAEP512:\".indexOf(a) != -1) {\n      return a;\n    }if (a === null || a === undefined) {\n      return \"RSA\";\n    }throw \"getAlgByKeyAndName: not supported algorithm name for RSAKey: \" + a;\n  }throw \"getAlgByKeyAndName: not supported algorithm name: \" + a;\n};KJUR.crypto.OID = new function () {\n  this.oidhex2name = { \"2a864886f70d010101\": \"rsaEncryption\", \"2a8648ce3d0201\": \"ecPublicKey\", \"2a8648ce380401\": \"dsa\", \"2a8648ce3d030107\": \"secp256r1\", \"2b8104001f\": \"secp192k1\", \"2b81040021\": \"secp224r1\", \"2b8104000a\": \"secp256k1\", \"2b81040023\": \"secp521r1\", \"2b81040022\": \"secp384r1\", \"2a8648ce380403\": \"SHA1withDSA\", \"608648016503040301\": \"SHA224withDSA\", \"608648016503040302\": \"SHA256withDSA\" };\n}();\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.ECDSA = function (h) {\n  var e = \"secp256r1\";var g = null;var b = null;var f = null;var a = new SecureRandom();var d = null;this.type = \"EC\";this.isPrivate = false;this.isPublic = false;function c(s, o, r, n) {\n    var j = Math.max(o.bitLength(), n.bitLength());var t = s.add2D(r);var q = s.curve.getInfinity();for (var p = j - 1; p >= 0; --p) {\n      q = q.twice2D();q.z = BigInteger.ONE;if (o.testBit(p)) {\n        if (n.testBit(p)) {\n          q = q.add2D(t);\n        } else {\n          q = q.add2D(s);\n        }\n      } else {\n        if (n.testBit(p)) {\n          q = q.add2D(r);\n        }\n      }\n    }return q;\n  }this.getBigRandom = function (i) {\n    return new BigInteger(i.bitLength(), a).mod(i.subtract(BigInteger.ONE)).add(BigInteger.ONE);\n  };this.setNamedCurve = function (i) {\n    this.ecparams = KJUR.crypto.ECParameterDB.getByName(i);this.prvKeyHex = null;this.pubKeyHex = null;this.curveName = i;\n  };this.setPrivateKeyHex = function (i) {\n    this.isPrivate = true;this.prvKeyHex = i;\n  };this.setPublicKeyHex = function (i) {\n    this.isPublic = true;this.pubKeyHex = i;\n  };this.getPublicKeyXYHex = function () {\n    var k = this.pubKeyHex;if (k.substr(0, 2) !== \"04\") {\n      throw \"this method supports uncompressed format(04) only\";\n    }var j = this.ecparams.keylen / 4;if (k.length !== 2 + j * 2) {\n      throw \"malformed public key hex length\";\n    }var i = {};i.x = k.substr(2, j);i.y = k.substr(2 + j);return i;\n  };this.getShortNISTPCurveName = function () {\n    var i = this.curveName;if (i === \"secp256r1\" || i === \"NIST P-256\" || i === \"P-256\" || i === \"prime256v1\") {\n      return \"P-256\";\n    }if (i === \"secp384r1\" || i === \"NIST P-384\" || i === \"P-384\") {\n      return \"P-384\";\n    }return null;\n  };this.generateKeyPairHex = function () {\n    var k = this.ecparams.n;var n = this.getBigRandom(k);var l = this.ecparams.G.multiply(n);var q = l.getX().toBigInteger();var o = l.getY().toBigInteger();var i = this.ecparams.keylen / 4;var m = (\"0000000000\" + n.toString(16)).slice(-i);var r = (\"0000000000\" + q.toString(16)).slice(-i);var p = (\"0000000000\" + o.toString(16)).slice(-i);var j = \"04\" + r + p;this.setPrivateKeyHex(m);this.setPublicKeyHex(j);return { ecprvhex: m, ecpubhex: j };\n  };this.signWithMessageHash = function (i) {\n    return this.signHex(i, this.prvKeyHex);\n  };this.signHex = function (o, j) {\n    var t = new BigInteger(j, 16);var l = this.ecparams.n;var q = new BigInteger(o, 16);do {\n      var m = this.getBigRandom(l);var u = this.ecparams.G;var p = u.multiply(m);var i = p.getX().toBigInteger().mod(l);\n    } while (i.compareTo(BigInteger.ZERO) <= 0);var v = m.modInverse(l).multiply(q.add(t.multiply(i))).mod(l);return KJUR.crypto.ECDSA.biRSSigToASN1Sig(i, v);\n  };this.sign = function (m, u) {\n    var q = u;var j = this.ecparams.n;var p = BigInteger.fromByteArrayUnsigned(m);do {\n      var l = this.getBigRandom(j);var t = this.ecparams.G;var o = t.multiply(l);var i = o.getX().toBigInteger().mod(j);\n    } while (i.compareTo(BigInteger.ZERO) <= 0);var v = l.modInverse(j).multiply(p.add(q.multiply(i))).mod(j);return this.serializeSig(i, v);\n  };this.verifyWithMessageHash = function (j, i) {\n    return this.verifyHex(j, i, this.pubKeyHex);\n  };this.verifyHex = function (m, i, p) {\n    var l, j;var o = KJUR.crypto.ECDSA.parseSigHex(i);l = o.r;j = o.s;var k;k = ECPointFp.decodeFromHex(this.ecparams.curve, p);var n = new BigInteger(m, 16);return this.verifyRaw(n, l, j, k);\n  };this.verify = function (o, p, j) {\n    var l, i;if (Bitcoin.Util.isArray(p)) {\n      var n = this.parseSig(p);l = n.r;i = n.s;\n    } else {\n      if (\"object\" === (typeof p === \"undefined\" ? \"undefined\" : _typeof(p)) && p.r && p.s) {\n        l = p.r;i = p.s;\n      } else {\n        throw \"Invalid value for signature\";\n      }\n    }var k;if (j instanceof ECPointFp) {\n      k = j;\n    } else {\n      if (Bitcoin.Util.isArray(j)) {\n        k = ECPointFp.decodeFrom(this.ecparams.curve, j);\n      } else {\n        throw \"Invalid format for pubkey value, must be byte array or ECPointFp\";\n      }\n    }var m = BigInteger.fromByteArrayUnsigned(o);return this.verifyRaw(m, l, i, k);\n  };this.verifyRaw = function (o, i, w, m) {\n    var l = this.ecparams.n;var u = this.ecparams.G;if (i.compareTo(BigInteger.ONE) < 0 || i.compareTo(l) >= 0) {\n      return false;\n    }if (w.compareTo(BigInteger.ONE) < 0 || w.compareTo(l) >= 0) {\n      return false;\n    }var p = w.modInverse(l);var k = o.multiply(p).mod(l);var j = i.multiply(p).mod(l);var q = u.multiply(k).add(m.multiply(j));var t = q.getX().toBigInteger().mod(l);return t.equals(i);\n  };this.serializeSig = function (k, j) {\n    var l = k.toByteArraySigned();var i = j.toByteArraySigned();var m = [];m.push(2);m.push(l.length);m = m.concat(l);m.push(2);m.push(i.length);m = m.concat(i);m.unshift(m.length);m.unshift(48);return m;\n  };this.parseSig = function (n) {\n    var m;if (n[0] != 48) {\n      throw new Error(\"Signature not a valid DERSequence\");\n    }m = 2;if (n[m] != 2) {\n      throw new Error(\"First element in signature must be a DERInteger\");\n    }var l = n.slice(m + 2, m + 2 + n[m + 1]);m += 2 + n[m + 1];if (n[m] != 2) {\n      throw new Error(\"Second element in signature must be a DERInteger\");\n    }var i = n.slice(m + 2, m + 2 + n[m + 1]);m += 2 + n[m + 1];var k = BigInteger.fromByteArrayUnsigned(l);var j = BigInteger.fromByteArrayUnsigned(i);return { r: k, s: j };\n  };this.parseSigCompact = function (m) {\n    if (m.length !== 65) {\n      throw \"Signature has the wrong length\";\n    }var j = m[0] - 27;if (j < 0 || j > 7) {\n      throw \"Invalid signature type\";\n    }var o = this.ecparams.n;var l = BigInteger.fromByteArrayUnsigned(m.slice(1, 33)).mod(o);var k = BigInteger.fromByteArrayUnsigned(m.slice(33, 65)).mod(o);return { r: l, s: k, i: j };\n  };this.readPKCS5PrvKeyHex = function (l) {\n    var n = ASN1HEX;var m = KJUR.crypto.ECDSA.getName;var p = n.getVbyList;if (n.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var i, k, o;try {\n      i = p(l, 0, [2, 0], \"06\");k = p(l, 0, [1], \"04\");try {\n        o = p(l, 0, [3, 0], \"03\").substr(2);\n      } catch (j) {}\n    } catch (j) {\n      throw \"malformed PKCS#1/5 plain ECC private key\";\n    }this.curveName = m(i);if (this.curveName === undefined) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(o);this.setPrivateKeyHex(k);this.isPublic = false;\n  };this.readPKCS8PrvKeyHex = function (l) {\n    var q = ASN1HEX;var i = KJUR.crypto.ECDSA.getName;var n = q.getVbyList;if (q.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var j, p, m, k;try {\n      j = n(l, 0, [1, 0], \"06\");p = n(l, 0, [1, 1], \"06\");m = n(l, 0, [2, 0, 1], \"04\");try {\n        k = n(l, 0, [2, 0, 2, 0], \"03\").substr(2);\n      } catch (o) {}\n    } catch (o) {\n      throw \"malformed PKCS#8 plain ECC private key\";\n    }this.curveName = i(p);if (this.curveName === undefined) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(k);this.setPrivateKeyHex(m);this.isPublic = false;\n  };this.readPKCS8PubKeyHex = function (l) {\n    var n = ASN1HEX;var m = KJUR.crypto.ECDSA.getName;var p = n.getVbyList;if (n.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var k, i, o;try {\n      k = p(l, 0, [0, 0], \"06\");i = p(l, 0, [0, 1], \"06\");o = p(l, 0, [1], \"03\").substr(2);\n    } catch (j) {\n      throw \"malformed PKCS#8 ECC public key\";\n    }this.curveName = m(i);if (this.curveName === null) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(o);\n  };this.readCertPubKeyHex = function (k, p) {\n    if (p !== 5) {\n      p = 6;\n    }var m = ASN1HEX;var l = KJUR.crypto.ECDSA.getName;var o = m.getVbyList;if (m.isASN1HEX(k) === false) {\n      throw \"not ASN.1 hex string\";\n    }var i, n;try {\n      i = o(k, 0, [0, p, 0, 1], \"06\");n = o(k, 0, [0, p, 1], \"03\").substr(2);\n    } catch (j) {\n      throw \"malformed X.509 certificate ECC public key\";\n    }this.curveName = l(i);if (this.curveName === null) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(n);\n  };if (h !== undefined) {\n    if (h.curve !== undefined) {\n      this.curveName = h.curve;\n    }\n  }if (this.curveName === undefined) {\n    this.curveName = e;\n  }this.setNamedCurve(this.curveName);if (h !== undefined) {\n    if (h.prv !== undefined) {\n      this.setPrivateKeyHex(h.prv);\n    }if (h.pub !== undefined) {\n      this.setPublicKeyHex(h.pub);\n    }\n  }\n};KJUR.crypto.ECDSA.parseSigHex = function (a) {\n  var b = KJUR.crypto.ECDSA.parseSigHexInHexRS(a);var d = new BigInteger(b.r, 16);var c = new BigInteger(b.s, 16);return { r: d, s: c };\n};KJUR.crypto.ECDSA.parseSigHexInHexRS = function (f) {\n  var j = ASN1HEX;var i = j.getChildIdx;var g = j.getV;if (f.substr(0, 2) != \"30\") {\n    throw \"signature is not a ASN.1 sequence\";\n  }var h = i(f, 0);if (h.length != 2) {\n    throw \"number of signature ASN.1 sequence elements seem wrong\";\n  }var e = h[0];var d = h[1];if (f.substr(e, 2) != \"02\") {\n    throw \"1st item of sequene of signature is not ASN.1 integer\";\n  }if (f.substr(d, 2) != \"02\") {\n    throw \"2nd item of sequene of signature is not ASN.1 integer\";\n  }var c = g(f, e);var b = g(f, d);return { r: c, s: b };\n};KJUR.crypto.ECDSA.asn1SigToConcatSig = function (c) {\n  var d = KJUR.crypto.ECDSA.parseSigHexInHexRS(c);var b = d.r;var a = d.s;if (b.substr(0, 2) == \"00\" && b.length % 32 == 2) {\n    b = b.substr(2);\n  }if (a.substr(0, 2) == \"00\" && a.length % 32 == 2) {\n    a = a.substr(2);\n  }if (b.length % 32 == 30) {\n    b = \"00\" + b;\n  }if (a.length % 32 == 30) {\n    a = \"00\" + a;\n  }if (b.length % 32 != 0) {\n    throw \"unknown ECDSA sig r length error\";\n  }if (a.length % 32 != 0) {\n    throw \"unknown ECDSA sig s length error\";\n  }return b + a;\n};KJUR.crypto.ECDSA.concatSigToASN1Sig = function (a) {\n  if (a.length / 2 * 8 % (16 * 8) != 0) {\n    throw \"unknown ECDSA concatinated r-s sig  length error\";\n  }var c = a.substr(0, a.length / 2);var b = a.substr(a.length / 2);return KJUR.crypto.ECDSA.hexRSSigToASN1Sig(c, b);\n};KJUR.crypto.ECDSA.hexRSSigToASN1Sig = function (b, a) {\n  var d = new BigInteger(b, 16);var c = new BigInteger(a, 16);return KJUR.crypto.ECDSA.biRSSigToASN1Sig(d, c);\n};KJUR.crypto.ECDSA.biRSSigToASN1Sig = function (f, d) {\n  var c = KJUR.asn1;var b = new c.DERInteger({ bigint: f });var a = new c.DERInteger({ bigint: d });var e = new c.DERSequence({ array: [b, a] });return e.getEncodedHex();\n};KJUR.crypto.ECDSA.getName = function (a) {\n  if (a === \"2a8648ce3d030107\") {\n    return \"secp256r1\";\n  }if (a === \"2b8104000a\") {\n    return \"secp256k1\";\n  }if (a === \"2b81040022\") {\n    return \"secp384r1\";\n  }if (\"|secp256r1|NIST P-256|P-256|prime256v1|\".indexOf(a) !== -1) {\n    return \"secp256r1\";\n  }if (\"|secp256k1|\".indexOf(a) !== -1) {\n    return \"secp256k1\";\n  }if (\"|secp384r1|NIST P-384|P-384|\".indexOf(a) !== -1) {\n    return \"secp384r1\";\n  }return null;\n};\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.ECParameterDB = new function () {\n  var b = {};var c = {};function a(d) {\n    return new BigInteger(d, 16);\n  }this.getByName = function (e) {\n    var d = e;if (typeof c[d] != \"undefined\") {\n      d = c[e];\n    }if (typeof b[d] != \"undefined\") {\n      return b[d];\n    }throw \"unregistered EC curve name: \" + d;\n  };this.regist = function (A, l, o, g, m, e, j, f, k, u, d, x) {\n    b[A] = {};var s = a(o);var z = a(g);var y = a(m);var t = a(e);var w = a(j);var r = new ECCurveFp(s, z, y);var q = r.decodePointHex(\"04\" + f + k);b[A][\"name\"] = A;b[A][\"keylen\"] = l;b[A][\"curve\"] = r;b[A][\"G\"] = q;b[A][\"n\"] = t;b[A][\"h\"] = w;b[A][\"oid\"] = d;b[A][\"info\"] = x;for (var v = 0; v < u.length; v++) {\n      c[u[v]] = A;\n    }\n  };\n}();KJUR.crypto.ECParameterDB.regist(\"secp128r1\", 128, \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF\", \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC\", \"E87579C11079F43DD824993C2CEE5ED3\", \"FFFFFFFE0000000075A30D1B9038A115\", \"1\", \"161FF7528B899B2D0C28607CA52C5B86\", \"CF5AC8395BAFEB13C02DA292DDED7A83\", [], \"\", \"secp128r1 : SECG curve over a 128 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp160k1\", 160, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73\", \"0\", \"7\", \"0100000000000000000001B8FA16DFAB9ACA16B6B3\", \"1\", \"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB\", \"938CF935318FDCED6BC28286531733C3F03C4FEE\", [], \"\", \"secp160k1 : SECG curve over a 160 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp160r1\", 160, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC\", \"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45\", \"0100000000000000000001F4C8F927AED3CA752257\", \"1\", \"4A96B5688EF573284664698968C38BB913CBFC82\", \"23A628553168947D59DCC912042351377AC5FB32\", [], \"\", \"secp160r1 : SECG curve over a 160 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp192k1\", 192, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37\", \"0\", \"3\", \"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D\", \"1\", \"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D\", \"9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D\", []);KJUR.crypto.ECParameterDB.regist(\"secp192r1\", 192, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", \"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1\", \"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831\", \"1\", \"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012\", \"07192B95FFC8DA78631011ED6B24CDD573F977A11E794811\", []);KJUR.crypto.ECParameterDB.regist(\"secp224r1\", 224, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE\", \"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D\", \"1\", \"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21\", \"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34\", []);KJUR.crypto.ECParameterDB.regist(\"secp256k1\", 256, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\", \"0\", \"7\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\", \"1\", \"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\", \"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\", []);KJUR.crypto.ECParameterDB.regist(\"secp256r1\", 256, \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\", \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC\", \"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B\", \"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551\", \"1\", \"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296\", \"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5\", [\"NIST P-256\", \"P-256\", \"prime256v1\"]);KJUR.crypto.ECParameterDB.regist(\"secp384r1\", 384, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC\", \"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973\", \"1\", \"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7\", \"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f\", [\"NIST P-384\", \"P-384\"]);KJUR.crypto.ECParameterDB.regist(\"secp521r1\", 521, \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\", \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC\", \"051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00\", \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409\", \"1\", \"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66\", \"011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650\", [\"NIST P-521\", \"P-521\"]);\nvar KEYUTIL = function () {\n  var d = function d(p, r, q) {\n    return k(CryptoJS.AES, p, r, q);\n  };var e = function e(p, r, q) {\n    return k(CryptoJS.TripleDES, p, r, q);\n  };var a = function a(p, r, q) {\n    return k(CryptoJS.DES, p, r, q);\n  };var k = function k(s, x, u, q) {\n    var r = CryptoJS.enc.Hex.parse(x);var w = CryptoJS.enc.Hex.parse(u);var p = CryptoJS.enc.Hex.parse(q);var t = {};t.key = w;t.iv = p;t.ciphertext = r;var v = s.decrypt(t, w, { iv: p });return CryptoJS.enc.Hex.stringify(v);\n  };var l = function l(p, r, q) {\n    return g(CryptoJS.AES, p, r, q);\n  };var o = function o(p, r, q) {\n    return g(CryptoJS.TripleDES, p, r, q);\n  };var f = function f(p, r, q) {\n    return g(CryptoJS.DES, p, r, q);\n  };var g = function g(t, y, v, q) {\n    var s = CryptoJS.enc.Hex.parse(y);var x = CryptoJS.enc.Hex.parse(v);var p = CryptoJS.enc.Hex.parse(q);var w = t.encrypt(s, x, { iv: p });var r = CryptoJS.enc.Hex.parse(w.toString());var u = CryptoJS.enc.Base64.stringify(r);return u;\n  };var i = { \"AES-256-CBC\": { proc: d, eproc: l, keylen: 32, ivlen: 16 }, \"AES-192-CBC\": { proc: d, eproc: l, keylen: 24, ivlen: 16 }, \"AES-128-CBC\": { proc: d, eproc: l, keylen: 16, ivlen: 16 }, \"DES-EDE3-CBC\": { proc: e, eproc: o, keylen: 24, ivlen: 8 }, \"DES-CBC\": { proc: a, eproc: f, keylen: 8, ivlen: 8 } };var c = function c(p) {\n    return i[p][\"proc\"];\n  };var m = function m(p) {\n    var r = CryptoJS.lib.WordArray.random(p);var q = CryptoJS.enc.Hex.stringify(r);return q;\n  };var n = function n(v) {\n    var w = {};var q = v.match(new RegExp(\"DEK-Info: ([^,]+),([0-9A-Fa-f]+)\", \"m\"));if (q) {\n      w.cipher = q[1];w.ivsalt = q[2];\n    }var p = v.match(new RegExp(\"-----BEGIN ([A-Z]+) PRIVATE KEY-----\"));if (p) {\n      w.type = p[1];\n    }var u = -1;var x = 0;if (v.indexOf(\"\\r\\n\\r\\n\") != -1) {\n      u = v.indexOf(\"\\r\\n\\r\\n\");x = 2;\n    }if (v.indexOf(\"\\n\\n\") != -1) {\n      u = v.indexOf(\"\\n\\n\");x = 1;\n    }var t = v.indexOf(\"-----END\");if (u != -1 && t != -1) {\n      var r = v.substring(u + x * 2, t - x);r = r.replace(/\\s+/g, \"\");w.data = r;\n    }return w;\n  };var j = function j(q, y, p) {\n    var v = p.substring(0, 16);var t = CryptoJS.enc.Hex.parse(v);var r = CryptoJS.enc.Utf8.parse(y);var u = i[q][\"keylen\"] + i[q][\"ivlen\"];var x = \"\";var w = null;for (;;) {\n      var s = CryptoJS.algo.MD5.create();if (w != null) {\n        s.update(w);\n      }s.update(r);s.update(t);w = s.finalize();x = x + CryptoJS.enc.Hex.stringify(w);if (x.length >= u * 2) {\n        break;\n      }\n    }var z = {};z.keyhex = x.substr(0, i[q][\"keylen\"] * 2);z.ivhex = x.substr(i[q][\"keylen\"] * 2, i[q][\"ivlen\"] * 2);return z;\n  };var b = function b(p, v, r, w) {\n    var s = CryptoJS.enc.Base64.parse(p);var q = CryptoJS.enc.Hex.stringify(s);var u = i[v][\"proc\"];var t = u(q, r, w);return t;\n  };var h = function h(p, s, q, u) {\n    var r = i[s][\"eproc\"];var t = r(p, q, u);return t;\n  };return { version: \"1.0.0\", parsePKCS5PEM: function parsePKCS5PEM(p) {\n      return n(p);\n    }, getKeyAndUnusedIvByPasscodeAndIvsalt: function getKeyAndUnusedIvByPasscodeAndIvsalt(q, p, r) {\n      return j(q, p, r);\n    }, decryptKeyB64: function decryptKeyB64(p, r, q, s) {\n      return b(p, r, q, s);\n    }, getDecryptedKeyHex: function getDecryptedKeyHex(y, x) {\n      var q = n(y);var t = q.type;var r = q.cipher;var p = q.ivsalt;var s = q.data;var w = j(r, x, p);var v = w.keyhex;var u = b(s, r, v, p);return u;\n    }, getEncryptedPKCS5PEMFromPrvKeyHex: function getEncryptedPKCS5PEMFromPrvKeyHex(x, s, A, t, r) {\n      var p = \"\";if (typeof t == \"undefined\" || t == null) {\n        t = \"AES-256-CBC\";\n      }if (typeof i[t] == \"undefined\") {\n        throw \"KEYUTIL unsupported algorithm: \" + t;\n      }if (typeof r == \"undefined\" || r == null) {\n        var v = i[t][\"ivlen\"];var u = m(v);r = u.toUpperCase();\n      }var z = j(t, A, r);var y = z.keyhex;var w = h(s, t, y, r);var q = w.replace(/(.{64})/g, \"$1\\r\\n\");var p = \"-----BEGIN \" + x + \" PRIVATE KEY-----\\r\\n\";p += \"Proc-Type: 4,ENCRYPTED\\r\\n\";p += \"DEK-Info: \" + t + \",\" + r + \"\\r\\n\";p += \"\\r\\n\";p += q;p += \"\\r\\n-----END \" + x + \" PRIVATE KEY-----\\r\\n\";return p;\n    }, parseHexOfEncryptedPKCS8: function parseHexOfEncryptedPKCS8(y) {\n      var B = ASN1HEX;var z = B.getChildIdx;var w = B.getV;var t = {};var r = z(y, 0);if (r.length != 2) {\n        throw \"malformed format: SEQUENCE(0).items != 2: \" + r.length;\n      }t.ciphertext = w(y, r[1]);var A = z(y, r[0]);if (A.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0).items != 2: \" + A.length;\n      }if (w(y, A[0]) != \"2a864886f70d01050d\") {\n        throw \"this only supports pkcs5PBES2\";\n      }var p = z(y, A[1]);if (A.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1).items != 2: \" + p.length;\n      }var q = z(y, p[1]);if (q.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.1).items != 2: \" + q.length;\n      }if (w(y, q[0]) != \"2a864886f70d0307\") {\n        throw \"this only supports TripleDES\";\n      }t.encryptionSchemeAlg = \"TripleDES\";t.encryptionSchemeIV = w(y, q[1]);var s = z(y, p[0]);if (s.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.0).items != 2: \" + s.length;\n      }if (w(y, s[0]) != \"2a864886f70d01050c\") {\n        throw \"this only supports pkcs5PBKDF2\";\n      }var x = z(y, s[1]);if (x.length < 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.0.1).items < 2: \" + x.length;\n      }t.pbkdf2Salt = w(y, x[0]);var u = w(y, x[1]);try {\n        t.pbkdf2Iter = parseInt(u, 16);\n      } catch (v) {\n        throw \"malformed format pbkdf2Iter: \" + u;\n      }return t;\n    }, getPBKDF2KeyHexFromParam: function getPBKDF2KeyHexFromParam(u, p) {\n      var t = CryptoJS.enc.Hex.parse(u.pbkdf2Salt);var q = u.pbkdf2Iter;var s = CryptoJS.PBKDF2(p, t, { keySize: 192 / 32, iterations: q });var r = CryptoJS.enc.Hex.stringify(s);return r;\n    }, _getPlainPKCS8HexFromEncryptedPKCS8PEM: function _getPlainPKCS8HexFromEncryptedPKCS8PEM(x, y) {\n      var r = pemtohex(x, \"ENCRYPTED PRIVATE KEY\");var p = this.parseHexOfEncryptedPKCS8(r);var u = KEYUTIL.getPBKDF2KeyHexFromParam(p, y);var v = {};v.ciphertext = CryptoJS.enc.Hex.parse(p.ciphertext);var t = CryptoJS.enc.Hex.parse(u);var s = CryptoJS.enc.Hex.parse(p.encryptionSchemeIV);var w = CryptoJS.TripleDES.decrypt(v, t, { iv: s });var q = CryptoJS.enc.Hex.stringify(w);return q;\n    }, getKeyFromEncryptedPKCS8PEM: function getKeyFromEncryptedPKCS8PEM(s, q) {\n      var p = this._getPlainPKCS8HexFromEncryptedPKCS8PEM(s, q);var r = this.getKeyFromPlainPrivatePKCS8Hex(p);return r;\n    }, parsePlainPrivatePKCS8Hex: function parsePlainPrivatePKCS8Hex(s) {\n      var v = ASN1HEX;var u = v.getChildIdx;var t = v.getV;var q = {};q.algparam = null;if (s.substr(0, 2) != \"30\") {\n        throw \"malformed plain PKCS8 private key(code:001)\";\n      }var r = u(s, 0);if (r.length != 3) {\n        throw \"malformed plain PKCS8 private key(code:002)\";\n      }if (s.substr(r[1], 2) != \"30\") {\n        throw \"malformed PKCS8 private key(code:003)\";\n      }var p = u(s, r[1]);if (p.length != 2) {\n        throw \"malformed PKCS8 private key(code:004)\";\n      }if (s.substr(p[0], 2) != \"06\") {\n        throw \"malformed PKCS8 private key(code:005)\";\n      }q.algoid = t(s, p[0]);if (s.substr(p[1], 2) == \"06\") {\n        q.algparam = t(s, p[1]);\n      }if (s.substr(r[2], 2) != \"04\") {\n        throw \"malformed PKCS8 private key(code:006)\";\n      }q.keyidx = v.getVidx(s, r[2]);return q;\n    }, getKeyFromPlainPrivatePKCS8PEM: function getKeyFromPlainPrivatePKCS8PEM(q) {\n      var p = pemtohex(q, \"PRIVATE KEY\");var r = this.getKeyFromPlainPrivatePKCS8Hex(p);return r;\n    }, getKeyFromPlainPrivatePKCS8Hex: function getKeyFromPlainPrivatePKCS8Hex(p) {\n      var q = this.parsePlainPrivatePKCS8Hex(p);var r;if (q.algoid == \"2a864886f70d010101\") {\n        r = new RSAKey();\n      } else {\n        if (q.algoid == \"2a8648ce380401\") {\n          r = new KJUR.crypto.DSA();\n        } else {\n          if (q.algoid == \"2a8648ce3d0201\") {\n            r = new KJUR.crypto.ECDSA();\n          } else {\n            throw \"unsupported private key algorithm\";\n          }\n        }\n      }r.readPKCS8PrvKeyHex(p);return r;\n    }, _getKeyFromPublicPKCS8Hex: function _getKeyFromPublicPKCS8Hex(q) {\n      var p;var r = ASN1HEX.getVbyList(q, 0, [0, 0], \"06\");if (r === \"2a864886f70d010101\") {\n        p = new RSAKey();\n      } else {\n        if (r === \"2a8648ce380401\") {\n          p = new KJUR.crypto.DSA();\n        } else {\n          if (r === \"2a8648ce3d0201\") {\n            p = new KJUR.crypto.ECDSA();\n          } else {\n            throw \"unsupported PKCS#8 public key hex\";\n          }\n        }\n      }p.readPKCS8PubKeyHex(q);return p;\n    }, parsePublicRawRSAKeyHex: function parsePublicRawRSAKeyHex(r) {\n      var u = ASN1HEX;var t = u.getChildIdx;var s = u.getV;var p = {};if (r.substr(0, 2) != \"30\") {\n        throw \"malformed RSA key(code:001)\";\n      }var q = t(r, 0);if (q.length != 2) {\n        throw \"malformed RSA key(code:002)\";\n      }if (r.substr(q[0], 2) != \"02\") {\n        throw \"malformed RSA key(code:003)\";\n      }p.n = s(r, q[0]);if (r.substr(q[1], 2) != \"02\") {\n        throw \"malformed RSA key(code:004)\";\n      }p.e = s(r, q[1]);return p;\n    }, parsePublicPKCS8Hex: function parsePublicPKCS8Hex(t) {\n      var v = ASN1HEX;var u = v.getChildIdx;var s = v.getV;var q = {};q.algparam = null;var r = u(t, 0);if (r.length != 2) {\n        throw \"outer DERSequence shall have 2 elements: \" + r.length;\n      }var w = r[0];if (t.substr(w, 2) != \"30\") {\n        throw \"malformed PKCS8 public key(code:001)\";\n      }var p = u(t, w);if (p.length != 2) {\n        throw \"malformed PKCS8 public key(code:002)\";\n      }if (t.substr(p[0], 2) != \"06\") {\n        throw \"malformed PKCS8 public key(code:003)\";\n      }q.algoid = s(t, p[0]);if (t.substr(p[1], 2) == \"06\") {\n        q.algparam = s(t, p[1]);\n      } else {\n        if (t.substr(p[1], 2) == \"30\") {\n          q.algparam = {};q.algparam.p = v.getVbyList(t, p[1], [0], \"02\");q.algparam.q = v.getVbyList(t, p[1], [1], \"02\");q.algparam.g = v.getVbyList(t, p[1], [2], \"02\");\n        }\n      }if (t.substr(r[1], 2) != \"03\") {\n        throw \"malformed PKCS8 public key(code:004)\";\n      }q.key = s(t, r[1]).substr(2);return q;\n    } };\n}();KEYUTIL.getKey = function (l, k, n) {\n  var G = ASN1HEX,\n      L = G.getChildIdx,\n      v = G.getV,\n      d = G.getVbyList,\n      c = KJUR.crypto,\n      i = c.ECDSA,\n      C = c.DSA,\n      w = RSAKey,\n      M = pemtohex,\n      F = KEYUTIL;if (typeof w != \"undefined\" && l instanceof w) {\n    return l;\n  }if (typeof i != \"undefined\" && l instanceof i) {\n    return l;\n  }if (typeof C != \"undefined\" && l instanceof C) {\n    return l;\n  }if (l.curve !== undefined && l.xy !== undefined && l.d === undefined) {\n    return new i({ pub: l.xy, curve: l.curve });\n  }if (l.curve !== undefined && l.d !== undefined) {\n    return new i({ prv: l.d, curve: l.curve });\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d === undefined) {\n    var P = new w();P.setPublic(l.n, l.e);return P;\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p !== undefined && l.q !== undefined && l.dp !== undefined && l.dq !== undefined && l.co !== undefined && l.qi === undefined) {\n    var P = new w();P.setPrivateEx(l.n, l.e, l.d, l.p, l.q, l.dp, l.dq, l.co);return P;\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p === undefined) {\n    var P = new w();P.setPrivate(l.n, l.e, l.d);return P;\n  }if (l.p !== undefined && l.q !== undefined && l.g !== undefined && l.y !== undefined && l.x === undefined) {\n    var P = new C();P.setPublic(l.p, l.q, l.g, l.y);return P;\n  }if (l.p !== undefined && l.q !== undefined && l.g !== undefined && l.y !== undefined && l.x !== undefined) {\n    var P = new C();P.setPrivate(l.p, l.q, l.g, l.y, l.x);return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d === undefined) {\n    var P = new w();P.setPublic(b64utohex(l.n), b64utohex(l.e));return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p !== undefined && l.q !== undefined && l.dp !== undefined && l.dq !== undefined && l.qi !== undefined) {\n    var P = new w();P.setPrivateEx(b64utohex(l.n), b64utohex(l.e), b64utohex(l.d), b64utohex(l.p), b64utohex(l.q), b64utohex(l.dp), b64utohex(l.dq), b64utohex(l.qi));return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d !== undefined) {\n    var P = new w();P.setPrivate(b64utohex(l.n), b64utohex(l.e), b64utohex(l.d));return P;\n  }if (l.kty === \"EC\" && l.crv !== undefined && l.x !== undefined && l.y !== undefined && l.d === undefined) {\n    var j = new i({ curve: l.crv });var t = j.ecparams.keylen / 4;var B = (\"0000000000\" + b64utohex(l.x)).slice(-t);var z = (\"0000000000\" + b64utohex(l.y)).slice(-t);var u = \"04\" + B + z;j.setPublicKeyHex(u);return j;\n  }if (l.kty === \"EC\" && l.crv !== undefined && l.x !== undefined && l.y !== undefined && l.d !== undefined) {\n    var j = new i({ curve: l.crv });var t = j.ecparams.keylen / 4;var B = (\"0000000000\" + b64utohex(l.x)).slice(-t);var z = (\"0000000000\" + b64utohex(l.y)).slice(-t);var u = \"04\" + B + z;var b = (\"0000000000\" + b64utohex(l.d)).slice(-t);j.setPublicKeyHex(u);j.setPrivateKeyHex(b);return j;\n  }if (n === \"pkcs5prv\") {\n    var J = l,\n        G = ASN1HEX,\n        N,\n        P;N = L(J, 0);if (N.length === 9) {\n      P = new w();P.readPKCS5PrvKeyHex(J);\n    } else {\n      if (N.length === 6) {\n        P = new C();P.readPKCS5PrvKeyHex(J);\n      } else {\n        if (N.length > 2 && J.substr(N[1], 2) === \"04\") {\n          P = new i();P.readPKCS5PrvKeyHex(J);\n        } else {\n          throw \"unsupported PKCS#1/5 hexadecimal key\";\n        }\n      }\n    }return P;\n  }if (n === \"pkcs8prv\") {\n    var P = F.getKeyFromPlainPrivatePKCS8Hex(l);return P;\n  }if (n === \"pkcs8pub\") {\n    return F._getKeyFromPublicPKCS8Hex(l);\n  }if (n === \"x509pub\") {\n    return X509.getPublicKeyFromCertHex(l);\n  }if (l.indexOf(\"-END CERTIFICATE-\", 0) != -1 || l.indexOf(\"-END X509 CERTIFICATE-\", 0) != -1 || l.indexOf(\"-END TRUSTED CERTIFICATE-\", 0) != -1) {\n    return X509.getPublicKeyFromCertPEM(l);\n  }if (l.indexOf(\"-END PUBLIC KEY-\") != -1) {\n    var O = pemtohex(l, \"PUBLIC KEY\");return F._getKeyFromPublicPKCS8Hex(O);\n  }if (l.indexOf(\"-END RSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") == -1) {\n    var m = M(l, \"RSA PRIVATE KEY\");return F.getKey(m, null, \"pkcs5prv\");\n  }if (l.indexOf(\"-END DSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") == -1) {\n    var I = M(l, \"DSA PRIVATE KEY\");var E = d(I, 0, [1], \"02\");var D = d(I, 0, [2], \"02\");var K = d(I, 0, [3], \"02\");var r = d(I, 0, [4], \"02\");var s = d(I, 0, [5], \"02\");var P = new C();P.setPrivate(new BigInteger(E, 16), new BigInteger(D, 16), new BigInteger(K, 16), new BigInteger(r, 16), new BigInteger(s, 16));return P;\n  }if (l.indexOf(\"-END PRIVATE KEY-\") != -1) {\n    return F.getKeyFromPlainPrivatePKCS8PEM(l);\n  }if (l.indexOf(\"-END RSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var o = F.getDecryptedKeyHex(l, k);var H = new RSAKey();H.readPKCS5PrvKeyHex(o);return H;\n  }if (l.indexOf(\"-END EC PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var I = F.getDecryptedKeyHex(l, k);var P = d(I, 0, [1], \"04\");var f = d(I, 0, [2, 0], \"06\");var A = d(I, 0, [3, 0], \"03\").substr(2);var e = \"\";if (KJUR.crypto.OID.oidhex2name[f] !== undefined) {\n      e = KJUR.crypto.OID.oidhex2name[f];\n    } else {\n      throw \"undefined OID(hex) in KJUR.crypto.OID: \" + f;\n    }var j = new i({ curve: e });j.setPublicKeyHex(A);j.setPrivateKeyHex(P);j.isPublic = false;return j;\n  }if (l.indexOf(\"-END DSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var I = F.getDecryptedKeyHex(l, k);var E = d(I, 0, [1], \"02\");var D = d(I, 0, [2], \"02\");var K = d(I, 0, [3], \"02\");var r = d(I, 0, [4], \"02\");var s = d(I, 0, [5], \"02\");var P = new C();P.setPrivate(new BigInteger(E, 16), new BigInteger(D, 16), new BigInteger(K, 16), new BigInteger(r, 16), new BigInteger(s, 16));return P;\n  }if (l.indexOf(\"-END ENCRYPTED PRIVATE KEY-\") != -1) {\n    return F.getKeyFromEncryptedPKCS8PEM(l, k);\n  }throw \"not supported argument\";\n};KEYUTIL.generateKeypair = function (a, c) {\n  if (a == \"RSA\") {\n    var b = c;var h = new RSAKey();h.generate(b, \"10001\");h.isPrivate = true;h.isPublic = true;var f = new RSAKey();var e = h.n.toString(16);var i = h.e.toString(16);f.setPublic(e, i);f.isPrivate = false;f.isPublic = true;var k = {};k.prvKeyObj = h;k.pubKeyObj = f;return k;\n  } else {\n    if (a == \"EC\") {\n      var d = c;var g = new KJUR.crypto.ECDSA({ curve: d });var j = g.generateKeyPairHex();var h = new KJUR.crypto.ECDSA({ curve: d });h.setPublicKeyHex(j.ecpubhex);h.setPrivateKeyHex(j.ecprvhex);h.isPrivate = true;h.isPublic = false;var f = new KJUR.crypto.ECDSA({ curve: d });f.setPublicKeyHex(j.ecpubhex);f.isPrivate = false;f.isPublic = true;var k = {};k.prvKeyObj = h;k.pubKeyObj = f;return k;\n    } else {\n      throw \"unknown algorithm: \" + a;\n    }\n  }\n};KEYUTIL.getPEM = function (b, D, y, m, q, j) {\n  var F = KJUR,\n      k = F.asn1,\n      z = k.DERObjectIdentifier,\n      f = k.DERInteger,\n      l = k.ASN1Util.newObject,\n      a = k.x509,\n      C = a.SubjectPublicKeyInfo,\n      e = F.crypto,\n      u = e.DSA,\n      r = e.ECDSA,\n      n = RSAKey;function A(s) {\n    var G = l({ seq: [{ \"int\": 0 }, { \"int\": { bigint: s.n } }, { \"int\": s.e }, { \"int\": { bigint: s.d } }, { \"int\": { bigint: s.p } }, { \"int\": { bigint: s.q } }, { \"int\": { bigint: s.dmp1 } }, { \"int\": { bigint: s.dmq1 } }, { \"int\": { bigint: s.coeff } }] });return G;\n  }function B(G) {\n    var s = l({ seq: [{ \"int\": 1 }, { octstr: { hex: G.prvKeyHex } }, { tag: [\"a0\", true, { oid: { name: G.curveName } }] }, { tag: [\"a1\", true, { bitstr: { hex: \"00\" + G.pubKeyHex } }] }] });return s;\n  }function x(s) {\n    var G = l({ seq: [{ \"int\": 0 }, { \"int\": { bigint: s.p } }, { \"int\": { bigint: s.q } }, { \"int\": { bigint: s.g } }, { \"int\": { bigint: s.y } }, { \"int\": { bigint: s.x } }] });return G;\n  }if ((n !== undefined && b instanceof n || u !== undefined && b instanceof u || r !== undefined && b instanceof r) && b.isPublic == true && (D === undefined || D == \"PKCS8PUB\")) {\n    var E = new C(b);var w = E.getEncodedHex();return hextopem(w, \"PUBLIC KEY\");\n  }if (D == \"PKCS1PRV\" && n !== undefined && b instanceof n && (y === undefined || y == null) && b.isPrivate == true) {\n    var E = A(b);var w = E.getEncodedHex();return hextopem(w, \"RSA PRIVATE KEY\");\n  }if (D == \"PKCS1PRV\" && r !== undefined && b instanceof r && (y === undefined || y == null) && b.isPrivate == true) {\n    var i = new z({ name: b.curveName });var v = i.getEncodedHex();var h = B(b);var t = h.getEncodedHex();var p = \"\";p += hextopem(v, \"EC PARAMETERS\");p += hextopem(t, \"EC PRIVATE KEY\");return p;\n  }if (D == \"PKCS1PRV\" && u !== undefined && b instanceof u && (y === undefined || y == null) && b.isPrivate == true) {\n    var E = x(b);var w = E.getEncodedHex();return hextopem(w, \"DSA PRIVATE KEY\");\n  }if (D == \"PKCS5PRV\" && n !== undefined && b instanceof n && y !== undefined && y != null && b.isPrivate == true) {\n    var E = A(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"RSA\", w, y, m, j);\n  }if (D == \"PKCS5PRV\" && r !== undefined && b instanceof r && y !== undefined && y != null && b.isPrivate == true) {\n    var E = B(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"EC\", w, y, m, j);\n  }if (D == \"PKCS5PRV\" && u !== undefined && b instanceof u && y !== undefined && y != null && b.isPrivate == true) {\n    var E = x(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"DSA\", w, y, m, j);\n  }var o = function o(G, s) {\n    var I = c(G, s);var H = new l({ seq: [{ seq: [{ oid: { name: \"pkcs5PBES2\" } }, { seq: [{ seq: [{ oid: { name: \"pkcs5PBKDF2\" } }, { seq: [{ octstr: { hex: I.pbkdf2Salt } }, { \"int\": I.pbkdf2Iter }] }] }, { seq: [{ oid: { name: \"des-EDE3-CBC\" } }, { octstr: { hex: I.encryptionSchemeIV } }] }] }] }, { octstr: { hex: I.ciphertext } }] });return H.getEncodedHex();\n  };var c = function c(N, O) {\n    var H = 100;var M = CryptoJS.lib.WordArray.random(8);var L = \"DES-EDE3-CBC\";var s = CryptoJS.lib.WordArray.random(8);var I = CryptoJS.PBKDF2(O, M, { keySize: 192 / 32, iterations: H });var J = CryptoJS.enc.Hex.parse(N);var K = CryptoJS.TripleDES.encrypt(J, I, { iv: s }) + \"\";var G = {};G.ciphertext = K;G.pbkdf2Salt = CryptoJS.enc.Hex.stringify(M);G.pbkdf2Iter = H;G.encryptionSchemeAlg = L;G.encryptionSchemeIV = CryptoJS.enc.Hex.stringify(s);return G;\n  };if (D == \"PKCS8PRV\" && n != undefined && b instanceof n && b.isPrivate == true) {\n    var g = A(b);var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"rsaEncryption\" } }, { \"null\": true }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }if (D == \"PKCS8PRV\" && r !== undefined && b instanceof r && b.isPrivate == true) {\n    var g = new l({ seq: [{ \"int\": 1 }, { octstr: { hex: b.prvKeyHex } }, { tag: [\"a1\", true, { bitstr: { hex: \"00\" + b.pubKeyHex } }] }] });var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"ecPublicKey\" } }, { oid: { name: b.curveName } }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }if (D == \"PKCS8PRV\" && u !== undefined && b instanceof u && b.isPrivate == true) {\n    var g = new f({ bigint: b.x });var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"dsa\" } }, { seq: [{ \"int\": { bigint: b.p } }, { \"int\": { bigint: b.q } }, { \"int\": { bigint: b.g } }] }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }throw \"unsupported object nor format\";\n};KEYUTIL.getKeyFromCSRPEM = function (b) {\n  var a = pemtohex(b, \"CERTIFICATE REQUEST\");var c = KEYUTIL.getKeyFromCSRHex(a);return c;\n};KEYUTIL.getKeyFromCSRHex = function (a) {\n  var c = KEYUTIL.parseCSRHex(a);var b = KEYUTIL.getKey(c.p8pubkeyhex, null, \"pkcs8pub\");return b;\n};KEYUTIL.parseCSRHex = function (d) {\n  var i = ASN1HEX;var f = i.getChildIdx;var c = i.getTLV;var b = {};var g = d;if (g.substr(0, 2) != \"30\") {\n    throw \"malformed CSR(code:001)\";\n  }var e = f(g, 0);if (e.length < 1) {\n    throw \"malformed CSR(code:002)\";\n  }if (g.substr(e[0], 2) != \"30\") {\n    throw \"malformed CSR(code:003)\";\n  }var a = f(g, e[0]);if (a.length < 3) {\n    throw \"malformed CSR(code:004)\";\n  }b.p8pubkeyhex = c(g, a[2]);return b;\n};KEYUTIL.getJWKFromKey = function (d) {\n  var b = {};if (d instanceof RSAKey && d.isPrivate) {\n    b.kty = \"RSA\";b.n = hextob64u(d.n.toString(16));b.e = hextob64u(d.e.toString(16));b.d = hextob64u(d.d.toString(16));b.p = hextob64u(d.p.toString(16));b.q = hextob64u(d.q.toString(16));b.dp = hextob64u(d.dmp1.toString(16));b.dq = hextob64u(d.dmq1.toString(16));b.qi = hextob64u(d.coeff.toString(16));return b;\n  } else {\n    if (d instanceof RSAKey && d.isPublic) {\n      b.kty = \"RSA\";b.n = hextob64u(d.n.toString(16));b.e = hextob64u(d.e.toString(16));return b;\n    } else {\n      if (d instanceof KJUR.crypto.ECDSA && d.isPrivate) {\n        var a = d.getShortNISTPCurveName();if (a !== \"P-256\" && a !== \"P-384\") {\n          throw \"unsupported curve name for JWT: \" + a;\n        }var c = d.getPublicKeyXYHex();b.kty = \"EC\";b.crv = a;b.x = hextob64u(c.x);b.y = hextob64u(c.y);b.d = hextob64u(d.prvKeyHex);return b;\n      } else {\n        if (d instanceof KJUR.crypto.ECDSA && d.isPublic) {\n          var a = d.getShortNISTPCurveName();if (a !== \"P-256\" && a !== \"P-384\") {\n            throw \"unsupported curve name for JWT: \" + a;\n          }var c = d.getPublicKeyXYHex();b.kty = \"EC\";b.crv = a;b.x = hextob64u(c.x);b.y = hextob64u(c.y);return b;\n        }\n      }\n    }\n  }throw \"not supported key object\";\n};\nRSAKey.getPosArrayOfChildrenFromHex = function (a) {\n  return ASN1HEX.getChildIdx(a, 0);\n};RSAKey.getHexValueArrayOfChildrenFromHex = function (f) {\n  var n = ASN1HEX;var i = n.getV;var k = RSAKey.getPosArrayOfChildrenFromHex(f);var e = i(f, k[0]);var j = i(f, k[1]);var b = i(f, k[2]);var c = i(f, k[3]);var h = i(f, k[4]);var g = i(f, k[5]);var m = i(f, k[6]);var l = i(f, k[7]);var d = i(f, k[8]);var k = new Array();k.push(e, j, b, c, h, g, m, l, d);return k;\n};RSAKey.prototype.readPrivateKeyFromPEMString = function (d) {\n  var c = pemtohex(d);var b = RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]);\n};RSAKey.prototype.readPKCS5PrvKeyHex = function (c) {\n  var b = RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]);\n};RSAKey.prototype.readPKCS8PrvKeyHex = function (e) {\n  var c, j, l, b, a, f, d, k;var m = ASN1HEX;var g = m.getVbyList;if (m.isASN1HEX(e) === false) {\n    throw \"not ASN.1 hex string\";\n  }try {\n    c = g(e, 0, [2, 0, 1], \"02\");j = g(e, 0, [2, 0, 2], \"02\");l = g(e, 0, [2, 0, 3], \"02\");b = g(e, 0, [2, 0, 4], \"02\");a = g(e, 0, [2, 0, 5], \"02\");f = g(e, 0, [2, 0, 6], \"02\");d = g(e, 0, [2, 0, 7], \"02\");k = g(e, 0, [2, 0, 8], \"02\");\n  } catch (i) {\n    throw \"malformed PKCS#8 plain RSA private key\";\n  }this.setPrivateEx(c, j, l, b, a, f, d, k);\n};RSAKey.prototype.readPKCS5PubKeyHex = function (c) {\n  var e = ASN1HEX;var b = e.getV;if (e.isASN1HEX(c) === false) {\n    throw \"keyHex is not ASN.1 hex string\";\n  }var a = e.getChildIdx(c, 0);if (a.length !== 2 || c.substr(a[0], 2) !== \"02\" || c.substr(a[1], 2) !== \"02\") {\n    throw \"wrong hex for PKCS#5 public key\";\n  }var f = b(c, a[0]);var d = b(c, a[1]);this.setPublic(f, d);\n};RSAKey.prototype.readPKCS8PubKeyHex = function (b) {\n  var c = ASN1HEX;if (c.isASN1HEX(b) === false) {\n    throw \"not ASN.1 hex string\";\n  }if (c.getTLVbyList(b, 0, [0, 0]) !== \"06092a864886f70d010101\") {\n    throw \"not PKCS8 RSA public key\";\n  }var a = c.getTLVbyList(b, 0, [1, 0]);this.readPKCS5PubKeyHex(a);\n};RSAKey.prototype.readCertPubKeyHex = function (b, d) {\n  var a, c;a = new X509();a.readCertHex(b);c = a.getPublicKeyHex();this.readPKCS8PubKeyHex(c);\n};\nvar _RE_HEXDECONLY = new RegExp(\"\");_RE_HEXDECONLY.compile(\"[^0-9a-f]\", \"gi\");function _rsasign_getHexPaddedDigestInfoForString(d, e, a) {\n  var b = function b(f) {\n    return KJUR.crypto.Util.hashString(f, a);\n  };var c = b(d);return KJUR.crypto.Util.getPaddedDigestInfoHex(c, a, e);\n}function _zeroPaddingOfSignature(e, d) {\n  var c = \"\";var a = d / 4 - e.length;for (var b = 0; b < a; b++) {\n    c = c + \"0\";\n  }return c + e;\n}RSAKey.prototype.sign = function (d, a) {\n  var b = function b(e) {\n    return KJUR.crypto.Util.hashString(e, a);\n  };var c = b(d);return this.signWithMessageHash(c, a);\n};RSAKey.prototype.signWithMessageHash = function (e, c) {\n  var f = KJUR.crypto.Util.getPaddedDigestInfoHex(e, c, this.n.bitLength());var b = parseBigInt(f, 16);var d = this.doPrivate(b);var a = d.toString(16);return _zeroPaddingOfSignature(a, this.n.bitLength());\n};function pss_mgf1_str(c, a, e) {\n  var b = \"\",\n      d = 0;while (b.length < a) {\n    b += hextorstr(e(rstrtohex(c + String.fromCharCode.apply(String, [(d & 4278190080) >> 24, (d & 16711680) >> 16, (d & 65280) >> 8, d & 255]))));d += 1;\n  }return b;\n}RSAKey.prototype.signPSS = function (e, a, d) {\n  var c = function c(f) {\n    return KJUR.crypto.Util.hashHex(f, a);\n  };var b = c(rstrtohex(e));if (d === undefined) {\n    d = -1;\n  }return this.signWithMessageHashPSS(b, a, d);\n};RSAKey.prototype.signWithMessageHashPSS = function (l, a, k) {\n  var b = hextorstr(l);var g = b.length;var m = this.n.bitLength() - 1;var c = Math.ceil(m / 8);var d;var o = function o(i) {\n    return KJUR.crypto.Util.hashHex(i, a);\n  };if (k === -1 || k === undefined) {\n    k = g;\n  } else {\n    if (k === -2) {\n      k = c - g - 2;\n    } else {\n      if (k < -2) {\n        throw \"invalid salt length\";\n      }\n    }\n  }if (c < g + k + 2) {\n    throw \"data too long\";\n  }var f = \"\";if (k > 0) {\n    f = new Array(k);new SecureRandom().nextBytes(f);f = String.fromCharCode.apply(String, f);\n  }var n = hextorstr(o(rstrtohex(\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + b + f)));var j = [];for (d = 0; d < c - k - g - 2; d += 1) {\n    j[d] = 0;\n  }var e = String.fromCharCode.apply(String, j) + \"\\x01\" + f;var h = pss_mgf1_str(n, e.length, o);var q = [];for (d = 0; d < e.length; d += 1) {\n    q[d] = e.charCodeAt(d) ^ h.charCodeAt(d);\n  }var p = 65280 >> 8 * c - m & 255;q[0] &= ~p;for (d = 0; d < g; d++) {\n    q.push(n.charCodeAt(d));\n  }q.push(188);return _zeroPaddingOfSignature(this.doPrivate(new BigInteger(q)).toString(16), this.n.bitLength());\n};function _rsasign_getDecryptSignatureBI(a, d, c) {\n  var b = new RSAKey();b.setPublic(d, c);var e = b.doPublic(a);return e;\n}function _rsasign_getHexDigestInfoFromSig(a, c, b) {\n  var e = _rsasign_getDecryptSignatureBI(a, c, b);var d = e.toString(16).replace(/^1f+00/, \"\");return d;\n}function _rsasign_getAlgNameAndHashFromHexDisgestInfo(f) {\n  for (var e in KJUR.crypto.Util.DIGESTINFOHEAD) {\n    var d = KJUR.crypto.Util.DIGESTINFOHEAD[e];var b = d.length;if (f.substring(0, b) == d) {\n      var c = [e, f.substring(b)];return c;\n    }\n  }return [];\n}RSAKey.prototype.verify = function (f, j) {\n  j = j.replace(_RE_HEXDECONLY, \"\");j = j.replace(/[ \\n]+/g, \"\");var b = parseBigInt(j, 16);if (b.bitLength() > this.n.bitLength()) {\n    return 0;\n  }var i = this.doPublic(b);var e = i.toString(16).replace(/^1f+00/, \"\");var g = _rsasign_getAlgNameAndHashFromHexDisgestInfo(e);if (g.length == 0) {\n    return false;\n  }var d = g[0];var h = g[1];var a = function a(k) {\n    return KJUR.crypto.Util.hashString(k, d);\n  };var c = a(f);return h == c;\n};RSAKey.prototype.verifyWithMessageHash = function (e, a) {\n  a = a.replace(_RE_HEXDECONLY, \"\");a = a.replace(/[ \\n]+/g, \"\");var b = parseBigInt(a, 16);if (b.bitLength() > this.n.bitLength()) {\n    return 0;\n  }var h = this.doPublic(b);var g = h.toString(16).replace(/^1f+00/, \"\");var c = _rsasign_getAlgNameAndHashFromHexDisgestInfo(g);if (c.length == 0) {\n    return false;\n  }var d = c[0];var f = c[1];return f == e;\n};RSAKey.prototype.verifyPSS = function (c, b, a, f) {\n  var e = function e(g) {\n    return KJUR.crypto.Util.hashHex(g, a);\n  };var d = e(rstrtohex(c));if (f === undefined) {\n    f = -1;\n  }return this.verifyWithMessageHashPSS(d, b, a, f);\n};RSAKey.prototype.verifyWithMessageHashPSS = function (f, s, l, c) {\n  var k = new BigInteger(s, 16);if (k.bitLength() > this.n.bitLength()) {\n    return false;\n  }var r = function r(i) {\n    return KJUR.crypto.Util.hashHex(i, l);\n  };var j = hextorstr(f);var h = j.length;var g = this.n.bitLength() - 1;var m = Math.ceil(g / 8);var q;if (c === -1 || c === undefined) {\n    c = h;\n  } else {\n    if (c === -2) {\n      c = m - h - 2;\n    } else {\n      if (c < -2) {\n        throw \"invalid salt length\";\n      }\n    }\n  }if (m < h + c + 2) {\n    throw \"data too long\";\n  }var a = this.doPublic(k).toByteArray();for (q = 0; q < a.length; q += 1) {\n    a[q] &= 255;\n  }while (a.length < m) {\n    a.unshift(0);\n  }if (a[m - 1] !== 188) {\n    throw \"encoded message does not end in 0xbc\";\n  }a = String.fromCharCode.apply(String, a);var d = a.substr(0, m - h - 1);var e = a.substr(d.length, h);var p = 65280 >> 8 * m - g & 255;if ((d.charCodeAt(0) & p) !== 0) {\n    throw \"bits beyond keysize not zero\";\n  }var n = pss_mgf1_str(e, d.length, r);var o = [];for (q = 0; q < d.length; q += 1) {\n    o[q] = d.charCodeAt(q) ^ n.charCodeAt(q);\n  }o[0] &= ~p;var b = m - h - c - 2;for (q = 0; q < b; q += 1) {\n    if (o[q] !== 0) {\n      throw \"leftmost octets not zero\";\n    }\n  }if (o[b] !== 1) {\n    throw \"0x01 marker not found\";\n  }return e === hextorstr(r(rstrtohex(\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + j + String.fromCharCode.apply(String, o.slice(-c)))));\n};RSAKey.SALT_LEN_HLEN = -1;RSAKey.SALT_LEN_MAX = -2;RSAKey.SALT_LEN_RECOVER = -2;\nfunction X509() {\n  var k = ASN1HEX,\n      j = k.getChildIdx,\n      h = k.getV,\n      b = k.getTLV,\n      f = k.getVbyList,\n      c = k.getTLVbyList,\n      g = k.getIdxbyList,\n      d = k.getVidx,\n      i = k.oidname,\n      a = X509,\n      e = pemtohex;this.hex = null;this.version = 0;this.foffset = 0;this.aExtInfo = null;this.getVersion = function () {\n    if (this.hex === null || this.version !== 0) {\n      return this.version;\n    }if (c(this.hex, 0, [0, 0]) !== \"a003020102\") {\n      this.version = 1;this.foffset = -1;return 1;\n    }this.version = 3;return 3;\n  };this.getSerialNumberHex = function () {\n    return f(this.hex, 0, [0, 1 + this.foffset], \"02\");\n  };this.getSignatureAlgorithmField = function () {\n    return i(f(this.hex, 0, [0, 2 + this.foffset, 0], \"06\"));\n  };this.getIssuerHex = function () {\n    return c(this.hex, 0, [0, 3 + this.foffset], \"30\");\n  };this.getIssuerString = function () {\n    return a.hex2dn(this.getIssuerHex());\n  };this.getSubjectHex = function () {\n    return c(this.hex, 0, [0, 5 + this.foffset], \"30\");\n  };this.getSubjectString = function () {\n    return a.hex2dn(this.getSubjectHex());\n  };this.getNotBefore = function () {\n    var l = f(this.hex, 0, [0, 4 + this.foffset, 0]);l = l.replace(/(..)/g, \"%$1\");l = decodeURIComponent(l);return l;\n  };this.getNotAfter = function () {\n    var l = f(this.hex, 0, [0, 4 + this.foffset, 1]);l = l.replace(/(..)/g, \"%$1\");l = decodeURIComponent(l);return l;\n  };this.getPublicKeyHex = function () {\n    return k.getTLVbyList(this.hex, 0, [0, 6 + this.foffset], \"30\");\n  };this.getPublicKeyIdx = function () {\n    return g(this.hex, 0, [0, 6 + this.foffset], \"30\");\n  };this.getPublicKeyContentIdx = function () {\n    var l = this.getPublicKeyIdx();return g(this.hex, l, [1, 0], \"30\");\n  };this.getPublicKey = function () {\n    return KEYUTIL.getKey(this.getPublicKeyHex(), null, \"pkcs8pub\");\n  };this.getSignatureAlgorithmName = function () {\n    return i(f(this.hex, 0, [1, 0], \"06\"));\n  };this.getSignatureValueHex = function () {\n    return f(this.hex, 0, [2], \"03\", true);\n  };this.verifySignature = function (n) {\n    var o = this.getSignatureAlgorithmName();var l = this.getSignatureValueHex();var m = c(this.hex, 0, [0], \"30\");var p = new KJUR.crypto.Signature({ alg: o });p.init(n);p.updateHex(m);return p.verify(l);\n  };this.parseExt = function () {\n    if (this.version !== 3) {\n      return -1;\n    }var p = g(this.hex, 0, [0, 7, 0], \"30\");var m = j(this.hex, p);this.aExtInfo = new Array();for (var n = 0; n < m.length; n++) {\n      var q = {};q.critical = false;var l = j(this.hex, m[n]);var r = 0;if (l.length === 3) {\n        q.critical = true;r = 1;\n      }q.oid = k.hextooidstr(f(this.hex, m[n], [0], \"06\"));var o = g(this.hex, m[n], [1 + r]);q.vidx = d(this.hex, o);this.aExtInfo.push(q);\n    }\n  };this.getExtInfo = function (n) {\n    var l = this.aExtInfo;var o = n;if (!n.match(/^[0-9.]+$/)) {\n      o = KJUR.asn1.x509.OID.name2oid(n);\n    }if (o === \"\") {\n      return undefined;\n    }for (var m = 0; m < l.length; m++) {\n      if (l[m].oid === o) {\n        return l[m];\n      }\n    }return undefined;\n  };this.getExtBasicConstraints = function () {\n    var n = this.getExtInfo(\"basicConstraints\");if (n === undefined) {\n      return n;\n    }var l = h(this.hex, n.vidx);if (l === \"\") {\n      return {};\n    }if (l === \"0101ff\") {\n      return { cA: true };\n    }if (l.substr(0, 8) === \"0101ff02\") {\n      var o = h(l, 6);var m = parseInt(o, 16);return { cA: true, pathLen: m };\n    }throw \"basicConstraints parse error\";\n  };this.getExtKeyUsageBin = function () {\n    var o = this.getExtInfo(\"keyUsage\");if (o === undefined) {\n      return \"\";\n    }var m = h(this.hex, o.vidx);if (m.length % 2 != 0 || m.length <= 2) {\n      throw \"malformed key usage value\";\n    }var l = parseInt(m.substr(0, 2));var n = parseInt(m.substr(2), 16).toString(2);return n.substr(0, n.length - l);\n  };this.getExtKeyUsageString = function () {\n    var n = this.getExtKeyUsageBin();var l = new Array();for (var m = 0; m < n.length; m++) {\n      if (n.substr(m, 1) == \"1\") {\n        l.push(X509.KEYUSAGE_NAME[m]);\n      }\n    }return l.join(\",\");\n  };this.getExtSubjectKeyIdentifier = function () {\n    var l = this.getExtInfo(\"subjectKeyIdentifier\");if (l === undefined) {\n      return l;\n    }return h(this.hex, l.vidx);\n  };this.getExtAuthorityKeyIdentifier = function () {\n    var p = this.getExtInfo(\"authorityKeyIdentifier\");if (p === undefined) {\n      return p;\n    }var l = {};var o = b(this.hex, p.vidx);var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      if (o.substr(m[n], 2) === \"80\") {\n        l.kid = h(o, m[n]);\n      }\n    }return l;\n  };this.getExtExtKeyUsageName = function () {\n    var p = this.getExtInfo(\"extKeyUsage\");if (p === undefined) {\n      return p;\n    }var l = new Array();var o = b(this.hex, p.vidx);if (o === \"\") {\n      return l;\n    }var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      l.push(i(h(o, m[n])));\n    }return l;\n  };this.getExtSubjectAltName = function () {\n    var m = this.getExtSubjectAltName2();var l = new Array();for (var n = 0; n < m.length; n++) {\n      if (m[n][0] === \"DNS\") {\n        l.push(m[n][1]);\n      }\n    }return l;\n  };this.getExtSubjectAltName2 = function () {\n    var p, s, r;var q = this.getExtInfo(\"subjectAltName\");if (q === undefined) {\n      return q;\n    }var l = new Array();var o = b(this.hex, q.vidx);var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      r = o.substr(m[n], 2);p = h(o, m[n]);if (r === \"81\") {\n        s = hextoutf8(p);l.push([\"MAIL\", s]);\n      }if (r === \"82\") {\n        s = hextoutf8(p);l.push([\"DNS\", s]);\n      }if (r === \"84\") {\n        s = X509.hex2dn(p, 0);l.push([\"DN\", s]);\n      }if (r === \"86\") {\n        s = hextoutf8(p);l.push([\"URI\", s]);\n      }if (r === \"87\") {\n        s = hextoip(p);l.push([\"IP\", s]);\n      }\n    }return l;\n  };this.getExtCRLDistributionPointsURI = function () {\n    var q = this.getExtInfo(\"cRLDistributionPoints\");if (q === undefined) {\n      return q;\n    }var l = new Array();var m = j(this.hex, q.vidx);for (var o = 0; o < m.length; o++) {\n      try {\n        var r = f(this.hex, m[o], [0, 0, 0], \"86\");var p = hextoutf8(r);l.push(p);\n      } catch (n) {}\n    }return l;\n  };this.getExtAIAInfo = function () {\n    var p = this.getExtInfo(\"authorityInfoAccess\");if (p === undefined) {\n      return p;\n    }var l = { ocsp: [], caissuer: [] };var m = j(this.hex, p.vidx);for (var n = 0; n < m.length; n++) {\n      var q = f(this.hex, m[n], [0], \"06\");var o = f(this.hex, m[n], [1], \"86\");if (q === \"2b06010505073001\") {\n        l.ocsp.push(hextoutf8(o));\n      }if (q === \"2b06010505073002\") {\n        l.caissuer.push(hextoutf8(o));\n      }\n    }return l;\n  };this.getExtCertificatePolicies = function () {\n    var o = this.getExtInfo(\"certificatePolicies\");if (o === undefined) {\n      return o;\n    }var l = b(this.hex, o.vidx);var u = [];var s = j(l, 0);for (var r = 0; r < s.length; r++) {\n      var t = {};var n = j(l, s[r]);t.id = i(h(l, n[0]));if (n.length === 2) {\n        var m = j(l, n[1]);for (var q = 0; q < m.length; q++) {\n          var p = f(l, m[q], [0], \"06\");if (p === \"2b06010505070201\") {\n            t.cps = hextoutf8(f(l, m[q], [1]));\n          } else {\n            if (p === \"2b06010505070202\") {\n              t.unotice = hextoutf8(f(l, m[q], [1, 0]));\n            }\n          }\n        }\n      }u.push(t);\n    }return u;\n  };this.readCertPEM = function (l) {\n    this.readCertHex(e(l));\n  };this.readCertHex = function (l) {\n    this.hex = l;this.getVersion();try {\n      g(this.hex, 0, [0, 7], \"a3\");this.parseExt();\n    } catch (m) {}\n  };this.getInfo = function () {\n    var m = X509;var B, u, z;B = \"Basic Fields\\n\";B += \"  serial number: \" + this.getSerialNumberHex() + \"\\n\";B += \"  signature algorithm: \" + this.getSignatureAlgorithmField() + \"\\n\";B += \"  issuer: \" + this.getIssuerString() + \"\\n\";B += \"  notBefore: \" + this.getNotBefore() + \"\\n\";B += \"  notAfter: \" + this.getNotAfter() + \"\\n\";B += \"  subject: \" + this.getSubjectString() + \"\\n\";B += \"  subject public key info: \\n\";u = this.getPublicKey();B += \"    key algorithm: \" + u.type + \"\\n\";if (u.type === \"RSA\") {\n      B += \"    n=\" + hextoposhex(u.n.toString(16)).substr(0, 16) + \"...\\n\";B += \"    e=\" + hextoposhex(u.e.toString(16)) + \"\\n\";\n    }z = this.aExtInfo;if (z !== undefined && z !== null) {\n      B += \"X509v3 Extensions:\\n\";for (var r = 0; r < z.length; r++) {\n        var n = z[r];var A = KJUR.asn1.x509.OID.oid2name(n.oid);if (A === \"\") {\n          A = n.oid;\n        }var x = \"\";if (n.critical === true) {\n          x = \"CRITICAL\";\n        }B += \"  \" + A + \" \" + x + \":\\n\";if (A === \"basicConstraints\") {\n          var v = this.getExtBasicConstraints();if (v.cA === undefined) {\n            B += \"    {}\\n\";\n          } else {\n            B += \"    cA=true\";if (v.pathLen !== undefined) {\n              B += \", pathLen=\" + v.pathLen;\n            }B += \"\\n\";\n          }\n        } else {\n          if (A === \"keyUsage\") {\n            B += \"    \" + this.getExtKeyUsageString() + \"\\n\";\n          } else {\n            if (A === \"subjectKeyIdentifier\") {\n              B += \"    \" + this.getExtSubjectKeyIdentifier() + \"\\n\";\n            } else {\n              if (A === \"authorityKeyIdentifier\") {\n                var l = this.getExtAuthorityKeyIdentifier();if (l.kid !== undefined) {\n                  B += \"    kid=\" + l.kid + \"\\n\";\n                }\n              } else {\n                if (A === \"extKeyUsage\") {\n                  var w = this.getExtExtKeyUsageName();B += \"    \" + w.join(\", \") + \"\\n\";\n                } else {\n                  if (A === \"subjectAltName\") {\n                    var t = this.getExtSubjectAltName2();B += \"    \" + t + \"\\n\";\n                  } else {\n                    if (A === \"cRLDistributionPoints\") {\n                      var y = this.getExtCRLDistributionPointsURI();B += \"    \" + y + \"\\n\";\n                    } else {\n                      if (A === \"authorityInfoAccess\") {\n                        var p = this.getExtAIAInfo();if (p.ocsp !== undefined) {\n                          B += \"    ocsp: \" + p.ocsp.join(\",\") + \"\\n\";\n                        }if (p.caissuer !== undefined) {\n                          B += \"    caissuer: \" + p.caissuer.join(\",\") + \"\\n\";\n                        }\n                      } else {\n                        if (A === \"certificatePolicies\") {\n                          var o = this.getExtCertificatePolicies();for (var q = 0; q < o.length; q++) {\n                            if (o[q].id !== undefined) {\n                              B += \"    policy oid: \" + o[q].id + \"\\n\";\n                            }if (o[q].cps !== undefined) {\n                              B += \"    cps: \" + o[q].cps + \"\\n\";\n                            }\n                          }\n                        }\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }B += \"signature algorithm: \" + this.getSignatureAlgorithmName() + \"\\n\";B += \"signature: \" + this.getSignatureValueHex().substr(0, 16) + \"...\\n\";return B;\n  };\n}X509.hex2dn = function (f, b) {\n  if (b === undefined) {\n    b = 0;\n  }if (f.substr(b, 2) !== \"30\") {\n    throw \"malformed DN\";\n  }var c = new Array();var d = ASN1HEX.getChildIdx(f, b);for (var e = 0; e < d.length; e++) {\n    c.push(X509.hex2rdn(f, d[e]));\n  }c = c.map(function (a) {\n    return a.replace(\"/\", \"\\\\/\");\n  });return \"/\" + c.join(\"/\");\n};X509.hex2rdn = function (f, b) {\n  if (b === undefined) {\n    b = 0;\n  }if (f.substr(b, 2) !== \"31\") {\n    throw \"malformed RDN\";\n  }var c = new Array();var d = ASN1HEX.getChildIdx(f, b);for (var e = 0; e < d.length; e++) {\n    c.push(X509.hex2attrTypeValue(f, d[e]));\n  }c = c.map(function (a) {\n    return a.replace(\"+\", \"\\\\+\");\n  });return c.join(\"+\");\n};X509.hex2attrTypeValue = function (d, i) {\n  var j = ASN1HEX;var h = j.getV;if (i === undefined) {\n    i = 0;\n  }if (d.substr(i, 2) !== \"30\") {\n    throw \"malformed attribute type and value\";\n  }var g = j.getChildIdx(d, i);if (g.length !== 2 || d.substr(g[0], 2) !== \"06\") {\n    \"malformed attribute type and value\";\n  }var b = h(d, g[0]);var f = KJUR.asn1.ASN1Util.oidHexToInt(b);var e = KJUR.asn1.x509.OID.oid2atype(f);var a = h(d, g[1]);var c = hextorstr(a);return e + \"=\" + c;\n};X509.getPublicKeyFromCertHex = function (b) {\n  var a = new X509();a.readCertHex(b);return a.getPublicKey();\n};X509.getPublicKeyFromCertPEM = function (b) {\n  var a = new X509();a.readCertPEM(b);return a.getPublicKey();\n};X509.getPublicKeyInfoPropOfCertPEM = function (c) {\n  var e = ASN1HEX;var g = e.getVbyList;var b = {};var a, f, d;b.algparam = null;a = new X509();a.readCertPEM(c);f = a.getPublicKeyHex();b.keyhex = g(f, 0, [1], \"03\").substr(2);b.algoid = g(f, 0, [0, 0], \"06\");if (b.algoid === \"2a8648ce3d0201\") {\n    b.algparam = g(f, 0, [0, 1], \"06\");\n  }return b;\n};X509.KEYUSAGE_NAME = [\"digitalSignature\", \"nonRepudiation\", \"keyEncipherment\", \"dataEncipherment\", \"keyAgreement\", \"keyCertSign\", \"cRLSign\", \"encipherOnly\", \"decipherOnly\"];\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.jws == \"undefined\" || !KJUR.jws) {\n  KJUR.jws = {};\n}KJUR.jws.JWS = function () {\n  var b = KJUR,\n      a = b.jws.JWS,\n      c = a.isSafeJSONString;this.parseJWS = function (g, j) {\n    if (this.parsedJWS !== undefined && (j || this.parsedJWS.sigvalH !== undefined)) {\n      return;\n    }var i = g.match(/^([^.]+)\\.([^.]+)\\.([^.]+)$/);if (i == null) {\n      throw \"JWS signature is not a form of 'Head.Payload.SigValue'.\";\n    }var k = i[1];var e = i[2];var l = i[3];var n = k + \".\" + e;this.parsedJWS = {};this.parsedJWS.headB64U = k;this.parsedJWS.payloadB64U = e;this.parsedJWS.sigvalB64U = l;this.parsedJWS.si = n;if (!j) {\n      var h = b64utohex(l);var f = parseBigInt(h, 16);this.parsedJWS.sigvalH = h;this.parsedJWS.sigvalBI = f;\n    }var d = b64utoutf8(k);var m = b64utoutf8(e);this.parsedJWS.headS = d;this.parsedJWS.payloadS = m;if (!c(d, this.parsedJWS, \"headP\")) {\n      throw \"malformed JSON string for JWS Head: \" + d;\n    }\n  };\n};KJUR.jws.JWS.sign = function (i, v, y, z, a) {\n  var w = KJUR,\n      m = w.jws,\n      q = m.JWS,\n      g = q.readSafeJSONString,\n      p = q.isSafeJSONString,\n      d = w.crypto,\n      k = d.ECDSA,\n      o = d.Mac,\n      c = d.Signature,\n      t = JSON;var s, j, n;if (typeof v != \"string\" && (typeof v === \"undefined\" ? \"undefined\" : _typeof(v)) != \"object\") {\n    throw \"spHeader must be JSON string or object: \" + v;\n  }if ((typeof v === \"undefined\" ? \"undefined\" : _typeof(v)) == \"object\") {\n    j = v;s = t.stringify(j);\n  }if (typeof v == \"string\") {\n    s = v;if (!p(s)) {\n      throw \"JWS Head is not safe JSON string: \" + s;\n    }j = g(s);\n  }n = y;if ((typeof y === \"undefined\" ? \"undefined\" : _typeof(y)) == \"object\") {\n    n = t.stringify(y);\n  }if ((i == \"\" || i == null) && j.alg !== undefined) {\n    i = j.alg;\n  }if (i != \"\" && i != null && j.alg === undefined) {\n    j.alg = i;s = t.stringify(j);\n  }if (i !== j.alg) {\n    throw \"alg and sHeader.alg doesn't match: \" + i + \"!=\" + j.alg;\n  }var r = null;if (q.jwsalg2sigalg[i] === undefined) {\n    throw \"unsupported alg name: \" + i;\n  } else {\n    r = q.jwsalg2sigalg[i];\n  }var e = utf8tob64u(s);var l = utf8tob64u(n);var b = e + \".\" + l;var x = \"\";if (r.substr(0, 4) == \"Hmac\") {\n    if (z === undefined) {\n      throw \"mac key shall be specified for HS* alg\";\n    }var h = new o({ alg: r, prov: \"cryptojs\", pass: z });h.updateString(b);x = h.doFinal();\n  } else {\n    if (r.indexOf(\"withECDSA\") != -1) {\n      var f = new c({ alg: r });f.init(z, a);f.updateString(b);hASN1Sig = f.sign();x = KJUR.crypto.ECDSA.asn1SigToConcatSig(hASN1Sig);\n    } else {\n      if (r != \"none\") {\n        var f = new c({ alg: r });f.init(z, a);f.updateString(b);x = f.sign();\n      }\n    }\n  }var u = hextob64u(x);return b + \".\" + u;\n};KJUR.jws.JWS.verify = function (w, B, n) {\n  var x = KJUR,\n      q = x.jws,\n      t = q.JWS,\n      i = t.readSafeJSONString,\n      e = x.crypto,\n      p = e.ECDSA,\n      s = e.Mac,\n      d = e.Signature,\n      m;if ((typeof RSAKey === \"undefined\" ? \"undefined\" : _typeof(RSAKey)) !== undefined) {\n    m = RSAKey;\n  }var y = w.split(\".\");if (y.length !== 3) {\n    return false;\n  }var f = y[0];var r = y[1];var c = f + \".\" + r;var A = b64utohex(y[2]);var l = i(b64utoutf8(y[0]));var k = null;var z = null;if (l.alg === undefined) {\n    throw \"algorithm not specified in header\";\n  } else {\n    k = l.alg;z = k.substr(0, 2);\n  }if (n != null && Object.prototype.toString.call(n) === \"[object Array]\" && n.length > 0) {\n    var b = \":\" + n.join(\":\") + \":\";if (b.indexOf(\":\" + k + \":\") == -1) {\n      throw \"algorithm '\" + k + \"' not accepted in the list\";\n    }\n  }if (k != \"none\" && B === null) {\n    throw \"key shall be specified to verify.\";\n  }if (typeof B == \"string\" && B.indexOf(\"-----BEGIN \") != -1) {\n    B = KEYUTIL.getKey(B);\n  }if (z == \"RS\" || z == \"PS\") {\n    if (!(B instanceof m)) {\n      throw \"key shall be a RSAKey obj for RS* and PS* algs\";\n    }\n  }if (z == \"ES\") {\n    if (!(B instanceof p)) {\n      throw \"key shall be a ECDSA obj for ES* algs\";\n    }\n  }if (k == \"none\") {}var u = null;if (t.jwsalg2sigalg[l.alg] === undefined) {\n    throw \"unsupported alg name: \" + k;\n  } else {\n    u = t.jwsalg2sigalg[k];\n  }if (u == \"none\") {\n    throw \"not supported\";\n  } else {\n    if (u.substr(0, 4) == \"Hmac\") {\n      var o = null;if (B === undefined) {\n        throw \"hexadecimal key shall be specified for HMAC\";\n      }var j = new s({ alg: u, pass: B });j.updateString(c);o = j.doFinal();return A == o;\n    } else {\n      if (u.indexOf(\"withECDSA\") != -1) {\n        var h = null;try {\n          h = p.concatSigToASN1Sig(A);\n        } catch (v) {\n          return false;\n        }var g = new d({ alg: u });g.init(B);g.updateString(c);return g.verify(h);\n      } else {\n        var g = new d({ alg: u });g.init(B);g.updateString(c);return g.verify(A);\n      }\n    }\n  }\n};KJUR.jws.JWS.parse = function (g) {\n  var c = g.split(\".\");var b = {};var f, e, d;if (c.length != 2 && c.length != 3) {\n    throw \"malformed sJWS: wrong number of '.' splitted elements\";\n  }f = c[0];e = c[1];if (c.length == 3) {\n    d = c[2];\n  }b.headerObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(f));b.payloadObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(e));b.headerPP = JSON.stringify(b.headerObj, null, \"  \");if (b.payloadObj == null) {\n    b.payloadPP = b64utoutf8(e);\n  } else {\n    b.payloadPP = JSON.stringify(b.payloadObj, null, \"  \");\n  }if (d !== undefined) {\n    b.sigHex = b64utohex(d);\n  }return b;\n};KJUR.jws.JWS.verifyJWT = function (e, l, r) {\n  var d = KJUR,\n      j = d.jws,\n      o = j.JWS,\n      n = o.readSafeJSONString,\n      p = o.inArray,\n      f = o.includedArray;var k = e.split(\".\");var c = k[0];var i = k[1];var q = c + \".\" + i;var m = b64utohex(k[2]);var h = n(b64utoutf8(c));var g = n(b64utoutf8(i));if (h.alg === undefined) {\n    return false;\n  }if (r.alg === undefined) {\n    throw \"acceptField.alg shall be specified\";\n  }if (!p(h.alg, r.alg)) {\n    return false;\n  }if (g.iss !== undefined && _typeof(r.iss) === \"object\") {\n    if (!p(g.iss, r.iss)) {\n      return false;\n    }\n  }if (g.sub !== undefined && _typeof(r.sub) === \"object\") {\n    if (!p(g.sub, r.sub)) {\n      return false;\n    }\n  }if (g.aud !== undefined && _typeof(r.aud) === \"object\") {\n    if (typeof g.aud == \"string\") {\n      if (!p(g.aud, r.aud)) {\n        return false;\n      }\n    } else {\n      if (_typeof(g.aud) == \"object\") {\n        if (!f(g.aud, r.aud)) {\n          return false;\n        }\n      }\n    }\n  }var b = j.IntDate.getNow();if (r.verifyAt !== undefined && typeof r.verifyAt === \"number\") {\n    b = r.verifyAt;\n  }if (r.gracePeriod === undefined || typeof r.gracePeriod !== \"number\") {\n    r.gracePeriod = 0;\n  }if (g.exp !== undefined && typeof g.exp == \"number\") {\n    if (g.exp + r.gracePeriod < b) {\n      return false;\n    }\n  }if (g.nbf !== undefined && typeof g.nbf == \"number\") {\n    if (b < g.nbf - r.gracePeriod) {\n      return false;\n    }\n  }if (g.iat !== undefined && typeof g.iat == \"number\") {\n    if (b < g.iat - r.gracePeriod) {\n      return false;\n    }\n  }if (g.jti !== undefined && r.jti !== undefined) {\n    if (g.jti !== r.jti) {\n      return false;\n    }\n  }if (!o.verify(e, l, r.alg)) {\n    return false;\n  }return true;\n};KJUR.jws.JWS.includedArray = function (b, a) {\n  var c = KJUR.jws.JWS.inArray;if (b === null) {\n    return false;\n  }if ((typeof b === \"undefined\" ? \"undefined\" : _typeof(b)) !== \"object\") {\n    return false;\n  }if (typeof b.length !== \"number\") {\n    return false;\n  }for (var d = 0; d < b.length; d++) {\n    if (!c(b[d], a)) {\n      return false;\n    }\n  }return true;\n};KJUR.jws.JWS.inArray = function (d, b) {\n  if (b === null) {\n    return false;\n  }if ((typeof b === \"undefined\" ? \"undefined\" : _typeof(b)) !== \"object\") {\n    return false;\n  }if (typeof b.length !== \"number\") {\n    return false;\n  }for (var c = 0; c < b.length; c++) {\n    if (b[c] == d) {\n      return true;\n    }\n  }return false;\n};KJUR.jws.JWS.jwsalg2sigalg = { HS256: \"HmacSHA256\", HS384: \"HmacSHA384\", HS512: \"HmacSHA512\", RS256: \"SHA256withRSA\", RS384: \"SHA384withRSA\", RS512: \"SHA512withRSA\", ES256: \"SHA256withECDSA\", ES384: \"SHA384withECDSA\", PS256: \"SHA256withRSAandMGF1\", PS384: \"SHA384withRSAandMGF1\", PS512: \"SHA512withRSAandMGF1\", none: \"none\" };KJUR.jws.JWS.isSafeJSONString = function (c, b, d) {\n  var e = null;try {\n    e = jsonParse(c);if ((typeof e === \"undefined\" ? \"undefined\" : _typeof(e)) != \"object\") {\n      return 0;\n    }if (e.constructor === Array) {\n      return 0;\n    }if (b) {\n      b[d] = e;\n    }return 1;\n  } catch (a) {\n    return 0;\n  }\n};KJUR.jws.JWS.readSafeJSONString = function (b) {\n  var c = null;try {\n    c = jsonParse(b);if ((typeof c === \"undefined\" ? \"undefined\" : _typeof(c)) != \"object\") {\n      return null;\n    }if (c.constructor === Array) {\n      return null;\n    }return c;\n  } catch (a) {\n    return null;\n  }\n};KJUR.jws.JWS.getEncodedSignatureValueFromJWS = function (b) {\n  var a = b.match(/^[^.]+\\.[^.]+\\.([^.]+)$/);if (a == null) {\n    throw \"JWS signature is not a form of 'Head.Payload.SigValue'.\";\n  }return a[1];\n};KJUR.jws.JWS.getJWKthumbprint = function (d) {\n  if (d.kty !== \"RSA\" && d.kty !== \"EC\" && d.kty !== \"oct\") {\n    throw \"unsupported algorithm for JWK Thumprint\";\n  }var a = \"{\";if (d.kty === \"RSA\") {\n    if (typeof d.n != \"string\" || typeof d.e != \"string\") {\n      throw \"wrong n and e value for RSA key\";\n    }a += '\"e\":\"' + d.e + '\",';a += '\"kty\":\"' + d.kty + '\",';a += '\"n\":\"' + d.n + '\"}';\n  } else {\n    if (d.kty === \"EC\") {\n      if (typeof d.crv != \"string\" || typeof d.x != \"string\" || typeof d.y != \"string\") {\n        throw \"wrong crv, x and y value for EC key\";\n      }a += '\"crv\":\"' + d.crv + '\",';a += '\"kty\":\"' + d.kty + '\",';a += '\"x\":\"' + d.x + '\",';a += '\"y\":\"' + d.y + '\"}';\n    } else {\n      if (d.kty === \"oct\") {\n        if (typeof d.k != \"string\") {\n          throw \"wrong k value for oct(symmetric) key\";\n        }a += '\"kty\":\"' + d.kty + '\",';a += '\"k\":\"' + d.k + '\"}';\n      }\n    }\n  }var b = rstrtohex(a);var c = KJUR.crypto.Util.hashHex(b, \"sha256\");var e = hextob64u(c);return e;\n};KJUR.jws.IntDate = {};KJUR.jws.IntDate.get = function (c) {\n  var b = KJUR.jws.IntDate,\n      d = b.getNow,\n      a = b.getZulu;if (c == \"now\") {\n    return d();\n  } else {\n    if (c == \"now + 1hour\") {\n      return d() + 60 * 60;\n    } else {\n      if (c == \"now + 1day\") {\n        return d() + 60 * 60 * 24;\n      } else {\n        if (c == \"now + 1month\") {\n          return d() + 60 * 60 * 24 * 30;\n        } else {\n          if (c == \"now + 1year\") {\n            return d() + 60 * 60 * 24 * 365;\n          } else {\n            if (c.match(/Z$/)) {\n              return a(c);\n            } else {\n              if (c.match(/^[0-9]+$/)) {\n                return parseInt(c);\n              }\n            }\n          }\n        }\n      }\n    }\n  }throw \"unsupported format: \" + c;\n};KJUR.jws.IntDate.getZulu = function (a) {\n  return zulutosec(a);\n};KJUR.jws.IntDate.getNow = function () {\n  var a = ~~(new Date() / 1000);return a;\n};KJUR.jws.IntDate.intDate2UTCString = function (a) {\n  var b = new Date(a * 1000);return b.toUTCString();\n};KJUR.jws.IntDate.intDate2Zulu = function (e) {\n  var i = new Date(e * 1000),\n      h = (\"0000\" + i.getUTCFullYear()).slice(-4),\n      g = (\"00\" + (i.getUTCMonth() + 1)).slice(-2),\n      b = (\"00\" + i.getUTCDate()).slice(-2),\n      a = (\"00\" + i.getUTCHours()).slice(-2),\n      c = (\"00\" + i.getUTCMinutes()).slice(-2),\n      f = (\"00\" + i.getUTCSeconds()).slice(-2);return h + g + b + a + c + f + \"Z\";\n};\nexports.SecureRandom = SecureRandom;\nexports.rng_seed_time = rng_seed_time;\nexports.BigInteger = BigInteger;\nexports.RSAKey = RSAKey;\nvar EDSA = KJUR.crypto.EDSA;\nexports.EDSA = EDSA;\nvar DSA = KJUR.crypto.DSA;\nexports.DSA = DSA;\nvar Signature = KJUR.crypto.Signature;\nexports.Signature = Signature;\nvar MessageDigest = KJUR.crypto.MessageDigest;\nexports.MessageDigest = MessageDigest;\nvar Mac = KJUR.crypto.Mac;\nexports.Mac = Mac;\nvar Cipher = KJUR.crypto.Cipher;\nexports.Cipher = Cipher;\nexports.KEYUTIL = KEYUTIL;\nexports.ASN1HEX = ASN1HEX;\nexports.X509 = X509;\nexports.CryptoJS = CryptoJS;\n\n// ext/base64.js\n\nexports.b64tohex = b64tohex;\nexports.b64toBA = b64toBA;\n\n// base64x.js\n\nexports.stoBA = stoBA;\nexports.BAtos = BAtos;\nexports.BAtohex = BAtohex;\nexports.stohex = stohex;\nexports.stob64 = stob64;\nexports.stob64u = stob64u;\nexports.b64utos = b64utos;\nexports.b64tob64u = b64tob64u;\nexports.b64utob64 = b64utob64;\nexports.hex2b64 = hex2b64;\nexports.hextob64u = hextob64u;\nexports.b64utohex = b64utohex;\nexports.utf8tob64u = utf8tob64u;\nexports.b64utoutf8 = b64utoutf8;\nexports.utf8tob64 = utf8tob64;\nexports.b64toutf8 = b64toutf8;\nexports.utf8tohex = utf8tohex;\nexports.hextoutf8 = hextoutf8;\nexports.hextorstr = hextorstr;\nexports.rstrtohex = rstrtohex;\nexports.hextob64 = hextob64;\nexports.hextob64nl = hextob64nl;\nexports.b64nltohex = b64nltohex;\nexports.hextopem = hextopem;\nexports.pemtohex = pemtohex;\nexports.hextoArrayBuffer = hextoArrayBuffer;\nexports.ArrayBuffertohex = ArrayBuffertohex;\nexports.zulutomsec = zulutomsec;\nexports.zulutosec = zulutosec;\nexports.zulutodate = zulutodate;\nexports.datetozulu = datetozulu;\nexports.uricmptohex = uricmptohex;\nexports.hextouricmp = hextouricmp;\nexports.ipv6tohex = ipv6tohex;\nexports.hextoipv6 = hextoipv6;\nexports.hextoip = hextoip;\nexports.iptohex = iptohex;\nexports.encodeURIComponentAll = encodeURIComponentAll;\nexports.newline_toUnix = newline_toUnix;\nexports.newline_toDos = newline_toDos;\nexports.hextoposhex = hextoposhex;\nexports.intarystrtohex = intarystrtohex;\nexports.strdiffidx = strdiffidx;\n\n// name spaces\n\nexports.KJUR = KJUR;\n\nvar _crypto = KJUR.crypto;\nexports.crypto = _crypto;\nvar _KJUR = KJUR;\nvar asn1 = _KJUR.asn1;\nexports.asn1 = asn1;\nvar _KJUR2 = KJUR;\nvar jws = _KJUR2.jws;\nexports.jws = jws;\nvar _KJUR3 = KJUR;\nvar lang = _KJUR3.lang;\nexports.lang = lang;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/buffer/index.js */ \"./node_modules/buffer/index.js\").Buffer))\n\n/***/ }),\n\n/***/ \"./node_modules/base64-js/index.js\":\n/*!*****************************************!*\\\n  !*** ./node_modules/base64-js/index.js ***!\n  \\*****************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  var validLen = b64.indexOf('=')\n  if (validLen === -1) validLen = len\n\n  var placeHoldersLen = validLen === len\n    ? 0\n    : 4 - (validLen % 4)\n\n  return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n  var tmp\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n\n  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n  var curByte = 0\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  var len = placeHoldersLen > 0\n    ? validLen - 4\n    : validLen\n\n  for (var i = 0; i < len; i += 4) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 18) |\n      (revLookup[b64.charCodeAt(i + 1)] << 12) |\n      (revLookup[b64.charCodeAt(i + 2)] << 6) |\n      revLookup[b64.charCodeAt(i + 3)]\n    arr[curByte++] = (tmp >> 16) & 0xFF\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 2) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 2) |\n      (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 1) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 10) |\n      (revLookup[b64.charCodeAt(i + 1)] << 4) |\n      (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] +\n    lookup[num >> 12 & 0x3F] +\n    lookup[num >> 6 & 0x3F] +\n    lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp =\n      ((uint8[i] << 16) & 0xFF0000) +\n      ((uint8[i + 1] << 8) & 0xFF00) +\n      (uint8[i + 2] & 0xFF)\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(\n      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n    ))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 2] +\n      lookup[(tmp << 4) & 0x3F] +\n      '=='\n    )\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 10] +\n      lookup[(tmp >> 4) & 0x3F] +\n      lookup[(tmp << 2) & 0x3F] +\n      '='\n    )\n  }\n\n  return parts.join('')\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/buffer/index.js\":\n/*!**************************************!*\\\n  !*** ./node_modules/buffer/index.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(/*! base64-js */ \"./node_modules/base64-js/index.js\")\nvar ieee754 = __webpack_require__(/*! ieee754 */ \"./node_modules/ieee754/index.js\")\nvar isArray = __webpack_require__(/*! isarray */ \"./node_modules/buffer/node_modules/isarray/index.js\")\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./node_modules/buffer/node_modules/isarray/index.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/buffer/node_modules/isarray/index.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/es6/promise.js\":\n/*!*********************************************!*\\\n  !*** ./node_modules/core-js/es6/promise.js ***!\n  \\*********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../modules/es6.object.to-string */ \"./node_modules/core-js/modules/es6.object.to-string.js\");\n__webpack_require__(/*! ../modules/es6.string.iterator */ \"./node_modules/core-js/modules/es6.string.iterator.js\");\n__webpack_require__(/*! ../modules/web.dom.iterable */ \"./node_modules/core-js/modules/web.dom.iterable.js\");\n__webpack_require__(/*! ../modules/es6.promise */ \"./node_modules/core-js/modules/es6.promise.js\");\nmodule.exports = __webpack_require__(/*! ../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Promise;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/find.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/fn/array/find.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.array.find */ \"./node_modules/core-js/modules/es6.array.find.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Array.find;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/is-array.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/fn/array/is-array.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.array.is-array */ \"./node_modules/core-js/modules/es6.array.is-array.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Array.isArray;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/some.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/fn/array/some.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.array.some */ \"./node_modules/core-js/modules/es6.array.some.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Array.some;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/array/splice.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/fn/array/splice.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// for a legacy code and future fixes\nmodule.exports = function () {\n  return Function.call.apply(Array.prototype.splice, arguments);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/function/bind.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/fn/function/bind.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.function.bind */ \"./node_modules/core-js/modules/es6.function.bind.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Function.bind;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/object/assign.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/fn/object/assign.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/es6.object.assign */ \"./node_modules/core-js/modules/es6.object.assign.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").Object.assign;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_a-function.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_a-function.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_add-to-unscopables.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_add-to-unscopables.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.31 Array.prototype[@@unscopables]\nvar UNSCOPABLES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('unscopables');\nvar ArrayProto = Array.prototype;\nif (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(ArrayProto, UNSCOPABLES, {});\nmodule.exports = function (key) {\n  ArrayProto[UNSCOPABLES][key] = true;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-instance.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-instance.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it, Constructor, name, forbiddenField) {\n  if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {\n    throw TypeError(name + ': incorrect invocation!');\n  } return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nmodule.exports = function (it) {\n  if (!isObject(it)) throw TypeError(it + ' is not an object!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-includes.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-includes.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// false -> Array#indexOf\n// true  -> Array#includes\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nmodule.exports = function (IS_INCLUDES) {\n  return function ($this, el, fromIndex) {\n    var O = toIObject($this);\n    var length = toLength(O.length);\n    var index = toAbsoluteIndex(fromIndex, length);\n    var value;\n    // Array#includes uses SameValueZero equality algorithm\n    // eslint-disable-next-line no-self-compare\n    if (IS_INCLUDES && el != el) while (length > index) {\n      value = O[index++];\n      // eslint-disable-next-line no-self-compare\n      if (value != value) return true;\n    // Array#indexOf ignores holes, Array#includes - not\n    } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n      if (O[index] === el) return IS_INCLUDES || index || 0;\n    } return !IS_INCLUDES && -1;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-methods.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-methods.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 0 -> Array#forEach\n// 1 -> Array#map\n// 2 -> Array#filter\n// 3 -> Array#some\n// 4 -> Array#every\n// 5 -> Array#find\n// 6 -> Array#findIndex\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar asc = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\nmodule.exports = function (TYPE, $create) {\n  var IS_MAP = TYPE == 1;\n  var IS_FILTER = TYPE == 2;\n  var IS_SOME = TYPE == 3;\n  var IS_EVERY = TYPE == 4;\n  var IS_FIND_INDEX = TYPE == 6;\n  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;\n  var create = $create || asc;\n  return function ($this, callbackfn, that) {\n    var O = toObject($this);\n    var self = IObject(O);\n    var f = ctx(callbackfn, that, 3);\n    var length = toLength(self.length);\n    var index = 0;\n    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;\n    var val, res;\n    for (;length > index; index++) if (NO_HOLES || index in self) {\n      val = self[index];\n      res = f(val, index, O);\n      if (TYPE) {\n        if (IS_MAP) result[index] = res;   // map\n        else if (res) switch (TYPE) {\n          case 3: return true;             // some\n          case 5: return val;              // find\n          case 6: return index;            // findIndex\n          case 2: result.push(val);        // filter\n        } else if (IS_EVERY) return false; // every\n      }\n    }\n    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-constructor.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-constructor.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (original) {\n  var C;\n  if (isArray(original)) {\n    C = original.constructor;\n    // cross-realm fallback\n    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;\n    if (isObject(C)) {\n      C = C[SPECIES];\n      if (C === null) C = undefined;\n    }\n  } return C === undefined ? Array : C;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-create.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-create.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 9.4.2.3 ArraySpeciesCreate(originalArray, length)\nvar speciesConstructor = __webpack_require__(/*! ./_array-species-constructor */ \"./node_modules/core-js/modules/_array-species-constructor.js\");\n\nmodule.exports = function (original, length) {\n  return new (speciesConstructor(original))(length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_bind.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_bind.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar arraySlice = [].slice;\nvar factories = {};\n\nvar construct = function (F, len, args) {\n  if (!(len in factories)) {\n    for (var n = [], i = 0; i < len; i++) n[i] = 'a[' + i + ']';\n    // eslint-disable-next-line no-new-func\n    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');\n  } return factories[len](F, args);\n};\n\nmodule.exports = Function.bind || function bind(that /* , ...args */) {\n  var fn = aFunction(this);\n  var partArgs = arraySlice.call(arguments, 1);\n  var bound = function (/* args... */) {\n    var args = partArgs.concat(arraySlice.call(arguments));\n    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);\n  };\n  if (isObject(fn.prototype)) bound.prototype = fn.prototype;\n  return bound;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_classof.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_classof.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n  try {\n    return it[key];\n  } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n  var O, T, B;\n  return it === undefined ? 'Undefined' : it === null ? 'Null'\n    // @@toStringTag case\n    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n    // builtinTag case\n    : ARG ? cof(O)\n    // ES3 arguments fallback\n    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_cof.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_cof.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = function (it) {\n  return toString.call(it).slice(8, -1);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_core.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_core.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar core = module.exports = { version: '2.6.4' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ctx.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_ctx.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// optional / simple context binding\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nmodule.exports = function (fn, that, length) {\n  aFunction(fn);\n  if (that === undefined) return fn;\n  switch (length) {\n    case 1: return function (a) {\n      return fn.call(that, a);\n    };\n    case 2: return function (a, b) {\n      return fn.call(that, a, b);\n    };\n    case 3: return function (a, b, c) {\n      return fn.call(that, a, b, c);\n    };\n  }\n  return function (/* ...args */) {\n    return fn.apply(that, arguments);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_defined.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_defined.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n  if (it == undefined) throw TypeError(\"Can't call method on  \" + it);\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_descriptors.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_descriptors.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_dom-create.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_dom-create.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n  return is ? document.createElement(it) : {};\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_enum-bug-keys.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_enum-bug-keys.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// IE 8- don't enum bug keys\nmodule.exports = (\n  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_export.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_export.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n  var IS_FORCED = type & $export.F;\n  var IS_GLOBAL = type & $export.G;\n  var IS_STATIC = type & $export.S;\n  var IS_PROTO = type & $export.P;\n  var IS_BIND = type & $export.B;\n  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n  var key, own, out, exp;\n  if (IS_GLOBAL) source = name;\n  for (key in source) {\n    // contains in native\n    own = !IS_FORCED && target && target[key] !== undefined;\n    // export native or passed\n    out = (own ? target : source)[key];\n    // bind timers to global for call from export context\n    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n    // extend global\n    if (target) redefine(target, key, out, type & $export.U);\n    // export\n    if (exports[key] != out) hide(exports, key, exp);\n    if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n  }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1;   // forced\n$export.G = 2;   // global\n$export.S = 4;   // static\n$export.P = 8;   // proto\n$export.B = 16;  // bind\n$export.W = 32;  // wrap\n$export.U = 64;  // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fails.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fails.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return !!exec();\n  } catch (e) {\n    return true;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_for-of.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_for-of.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar call = __webpack_require__(/*! ./_iter-call */ \"./node_modules/core-js/modules/_iter-call.js\");\nvar isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\nvar BREAK = {};\nvar RETURN = {};\nvar exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {\n  var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);\n  var f = ctx(fn, that, entries ? 2 : 1);\n  var index = 0;\n  var length, step, iterator, result;\n  if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');\n  // fast case for arrays with default iterator\n  if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {\n    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n    if (result === BREAK || result === RETURN) return result;\n  } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {\n    result = call(iterator, f, step.value, entries);\n    if (result === BREAK || result === RETURN) return result;\n  }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_function-to-string.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_function-to-string.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('native-function-to-string', Function.toString);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_global.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_global.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n  ? window : typeof self != 'undefined' && self.Math == Math ? self\n  // eslint-disable-next-line no-new-func\n  : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_has.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_has.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n  return hasOwnProperty.call(it, key);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_hide.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_hide.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? function (object, key, value) {\n  return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n  object[key] = value;\n  return object;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_html.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_html.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\nmodule.exports = document && document.documentElement;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ie8-dom-define.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_ie8-dom-define.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_invoke.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_invoke.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function (fn, args, that) {\n  var un = that === undefined;\n  switch (args.length) {\n    case 0: return un ? fn()\n                      : fn.call(that);\n    case 1: return un ? fn(args[0])\n                      : fn.call(that, args[0]);\n    case 2: return un ? fn(args[0], args[1])\n                      : fn.call(that, args[0], args[1]);\n    case 3: return un ? fn(args[0], args[1], args[2])\n                      : fn.call(that, args[0], args[1], args[2]);\n    case 4: return un ? fn(args[0], args[1], args[2], args[3])\n                      : fn.call(that, args[0], args[1], args[2], args[3]);\n  } return fn.apply(that, args);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iobject.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iobject.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n  return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array-iter.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array-iter.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// check on default Array iterator\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar ArrayProto = Array.prototype;\n\nmodule.exports = function (it) {\n  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.2.2 IsArray(argument)\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nmodule.exports = Array.isArray || function isArray(arg) {\n  return cof(arg) == 'Array';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-call.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-call.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// call something on iterator step with safe closing on error\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nmodule.exports = function (iterator, fn, value, entries) {\n  try {\n    return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n  // 7.4.6 IteratorClose(iterator, completion)\n  } catch (e) {\n    var ret = iterator['return'];\n    if (ret !== undefined) anObject(ret.call(iterator));\n    throw e;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-create.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-create.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar descriptor = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\n__webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(IteratorPrototype, __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n  Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n  setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-define.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-define.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar $iterCreate = __webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n  $iterCreate(Constructor, NAME, next);\n  var getMethod = function (kind) {\n    if (!BUGGY && kind in proto) return proto[kind];\n    switch (kind) {\n      case KEYS: return function keys() { return new Constructor(this, kind); };\n      case VALUES: return function values() { return new Constructor(this, kind); };\n    } return function entries() { return new Constructor(this, kind); };\n  };\n  var TAG = NAME + ' Iterator';\n  var DEF_VALUES = DEFAULT == VALUES;\n  var VALUES_BUG = false;\n  var proto = Base.prototype;\n  var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n  var $default = $native || getMethod(DEFAULT);\n  var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n  var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n  var methods, key, IteratorPrototype;\n  // Fix native\n  if ($anyNative) {\n    IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n    if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n      // Set @@toStringTag to native iterators\n      setToStringTag(IteratorPrototype, TAG, true);\n      // fix for some old engines\n      if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n    }\n  }\n  // fix Array#{values, @@iterator}.name in V8 / FF\n  if (DEF_VALUES && $native && $native.name !== VALUES) {\n    VALUES_BUG = true;\n    $default = function values() { return $native.call(this); };\n  }\n  // Define iterator\n  if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n    hide(proto, ITERATOR, $default);\n  }\n  // Plug for library\n  Iterators[NAME] = $default;\n  Iterators[TAG] = returnThis;\n  if (DEFAULT) {\n    methods = {\n      values: DEF_VALUES ? $default : getMethod(VALUES),\n      keys: IS_SET ? $default : getMethod(KEYS),\n      entries: $entries\n    };\n    if (FORCED) for (key in methods) {\n      if (!(key in proto)) redefine(proto, key, methods[key]);\n    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n  }\n  return methods;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-detect.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-detect.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n  var riter = [7][ITERATOR]();\n  riter['return'] = function () { SAFE_CLOSING = true; };\n  // eslint-disable-next-line no-throw-literal\n  Array.from(riter, function () { throw 2; });\n} catch (e) { /* empty */ }\n\nmodule.exports = function (exec, skipClosing) {\n  if (!skipClosing && !SAFE_CLOSING) return false;\n  var safe = false;\n  try {\n    var arr = [7];\n    var iter = arr[ITERATOR]();\n    iter.next = function () { return { done: safe = true }; };\n    arr[ITERATOR] = function () { return iter; };\n    exec(arr);\n  } catch (e) { /* empty */ }\n  return safe;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-step.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-step.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (done, value) {\n  return { value: value, done: !!done };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iterators.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iterators.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = {};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_library.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_library.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = false;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_microtask.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_microtask.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar macrotask = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar Observer = global.MutationObserver || global.WebKitMutationObserver;\nvar process = global.process;\nvar Promise = global.Promise;\nvar isNode = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process';\n\nmodule.exports = function () {\n  var head, last, notify;\n\n  var flush = function () {\n    var parent, fn;\n    if (isNode && (parent = process.domain)) parent.exit();\n    while (head) {\n      fn = head.fn;\n      head = head.next;\n      try {\n        fn();\n      } catch (e) {\n        if (head) notify();\n        else last = undefined;\n        throw e;\n      }\n    } last = undefined;\n    if (parent) parent.enter();\n  };\n\n  // Node.js\n  if (isNode) {\n    notify = function () {\n      process.nextTick(flush);\n    };\n  // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339\n  } else if (Observer && !(global.navigator && global.navigator.standalone)) {\n    var toggle = true;\n    var node = document.createTextNode('');\n    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new\n    notify = function () {\n      node.data = toggle = !toggle;\n    };\n  // environments with maybe non-completely correct, but existent Promise\n  } else if (Promise && Promise.resolve) {\n    // Promise.resolve without an argument throws an error in LG WebOS 2\n    var promise = Promise.resolve(undefined);\n    notify = function () {\n      promise.then(flush);\n    };\n  // for other environments - macrotask based on:\n  // - setImmediate\n  // - MessageChannel\n  // - window.postMessag\n  // - onreadystatechange\n  // - setTimeout\n  } else {\n    notify = function () {\n      // strange IE + webpack dev server bug - use .call(global)\n      macrotask.call(global, flush);\n    };\n  }\n\n  return function (fn) {\n    var task = { fn: fn, next: undefined };\n    if (last) last.next = task;\n    if (!head) {\n      head = task;\n      notify();\n    } last = task;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_new-promise-capability.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_new-promise-capability.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 25.4.1.5 NewPromiseCapability(C)\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\n\nfunction PromiseCapability(C) {\n  var resolve, reject;\n  this.promise = new C(function ($$resolve, $$reject) {\n    if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n    resolve = $$resolve;\n    reject = $$reject;\n  });\n  this.resolve = aFunction(resolve);\n  this.reject = aFunction(reject);\n}\n\nmodule.exports.f = function (C) {\n  return new PromiseCapability(C);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-assign.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-assign.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  var A = {};\n  var B = {};\n  // eslint-disable-next-line no-undef\n  var S = Symbol();\n  var K = 'abcdefghijklmnopqrst';\n  A[S] = 7;\n  K.split('').forEach(function (k) { B[k] = k; });\n  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source) { // eslint-disable-line no-unused-vars\n  var T = toObject(target);\n  var aLen = arguments.length;\n  var index = 1;\n  var getSymbols = gOPS.f;\n  var isEnum = pIE.f;\n  while (aLen > index) {\n    var S = IObject(arguments[index++]);\n    var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);\n    var length = keys.length;\n    var j = 0;\n    var key;\n    while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];\n  } return T;\n} : $assign;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-create.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-create.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar dPs = __webpack_require__(/*! ./_object-dps */ \"./node_modules/core-js/modules/_object-dps.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n  // Thrash, waste and sodomy: IE GC bug\n  var iframe = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('iframe');\n  var i = enumBugKeys.length;\n  var lt = '<';\n  var gt = '>';\n  var iframeDocument;\n  iframe.style.display = 'none';\n  __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\").appendChild(iframe);\n  iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n  // createDict = iframe.contentWindow.Object;\n  // html.removeChild(iframe);\n  iframeDocument = iframe.contentWindow.document;\n  iframeDocument.open();\n  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n  iframeDocument.close();\n  createDict = iframeDocument.F;\n  while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n  return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n  var result;\n  if (O !== null) {\n    Empty[PROTOTYPE] = anObject(O);\n    result = new Empty();\n    Empty[PROTOTYPE] = null;\n    // add \"__proto__\" for Object.getPrototypeOf polyfill\n    result[IE_PROTO] = O;\n  } else result = createDict();\n  return Properties === undefined ? result : dPs(result, Properties);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dp.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dp.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ \"./node_modules/core-js/modules/_ie8-dom-define.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar dP = Object.defineProperty;\n\nexports.f = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n  anObject(O);\n  P = toPrimitive(P, true);\n  anObject(Attributes);\n  if (IE8_DOM_DEFINE) try {\n    return dP(O, P, Attributes);\n  } catch (e) { /* empty */ }\n  if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n  if ('value' in Attributes) O[P] = Attributes.value;\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dps.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dps.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\n\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperties : function defineProperties(O, Properties) {\n  anObject(O);\n  var keys = getKeys(Properties);\n  var length = keys.length;\n  var i = 0;\n  var P;\n  while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gops.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gops.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = Object.getOwnPropertySymbols;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gpo.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gpo.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n  O = toObject(O);\n  if (has(O, IE_PROTO)) return O[IE_PROTO];\n  if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n    return O.constructor.prototype;\n  } return O instanceof Object ? ObjectProto : null;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys-internal.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys-internal.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar arrayIndexOf = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(false);\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\n\nmodule.exports = function (object, names) {\n  var O = toIObject(object);\n  var i = 0;\n  var result = [];\n  var key;\n  for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n  // Don't enum bug & hidden keys\n  while (names.length > i) if (has(O, key = names[i++])) {\n    ~arrayIndexOf(result, key) || result.push(key);\n  }\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = __webpack_require__(/*! ./_object-keys-internal */ \"./node_modules/core-js/modules/_object-keys-internal.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\n\nmodule.exports = Object.keys || function keys(O) {\n  return $keys(O, enumBugKeys);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-pie.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-pie.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = {}.propertyIsEnumerable;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_perform.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_perform.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return { e: false, v: exec() };\n  } catch (e) {\n    return { e: true, v: e };\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_promise-resolve.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_promise-resolve.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar newPromiseCapability = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\n\nmodule.exports = function (C, x) {\n  anObject(C);\n  if (isObject(x) && x.constructor === C) return x;\n  var promiseCapability = newPromiseCapability.f(C);\n  var resolve = promiseCapability.resolve;\n  resolve(x);\n  return promiseCapability.promise;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_property-desc.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_property-desc.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (bitmap, value) {\n  return {\n    enumerable: !(bitmap & 1),\n    configurable: !(bitmap & 2),\n    writable: !(bitmap & 4),\n    value: value\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine-all.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine-all.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nmodule.exports = function (target, src, safe) {\n  for (var key in src) redefine(target, key, src[key], safe);\n  return target;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar SRC = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\")('src');\nvar $toString = __webpack_require__(/*! ./_function-to-string */ \"./node_modules/core-js/modules/_function-to-string.js\");\nvar TO_STRING = 'toString';\nvar TPL = ('' + $toString).split(TO_STRING);\n\n__webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").inspectSource = function (it) {\n  return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n  var isFunction = typeof val == 'function';\n  if (isFunction) has(val, 'name') || hide(val, 'name', key);\n  if (O[key] === val) return;\n  if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n  if (O === global) {\n    O[key] = val;\n  } else if (!safe) {\n    delete O[key];\n    hide(O, key, val);\n  } else if (O[key]) {\n    O[key] = val;\n  } else {\n    hide(O, key, val);\n  }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n  return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-species.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-species.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (KEY) {\n  var C = global[KEY];\n  if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {\n    configurable: true,\n    get: function () { return this; }\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-to-string-tag.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-to-string-tag.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar def = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n  if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared-key.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared-key.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('keys');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nmodule.exports = function (key) {\n  return shared[key] || (shared[key] = uid(key));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n  return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n  version: core.version,\n  mode: __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\") ? 'pure' : 'global',\n  copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_species-constructor.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_species-constructor.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\nmodule.exports = function (O, D) {\n  var C = anObject(O).constructor;\n  var S;\n  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_strict-method.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_strict-method.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\n\nmodule.exports = function (method, arg) {\n  return !!method && fails(function () {\n    // eslint-disable-next-line no-useless-call\n    arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-at.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-at.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n// true  -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n  return function (that, pos) {\n    var s = String(defined(that));\n    var i = toInteger(pos);\n    var l = s.length;\n    var a, b;\n    if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n    a = s.charCodeAt(i);\n    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n      ? TO_STRING ? s.charAt(i) : a\n      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_task.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_task.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar html = __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\");\nvar cel = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar process = global.process;\nvar setTask = global.setImmediate;\nvar clearTask = global.clearImmediate;\nvar MessageChannel = global.MessageChannel;\nvar Dispatch = global.Dispatch;\nvar counter = 0;\nvar queue = {};\nvar ONREADYSTATECHANGE = 'onreadystatechange';\nvar defer, channel, port;\nvar run = function () {\n  var id = +this;\n  // eslint-disable-next-line no-prototype-builtins\n  if (queue.hasOwnProperty(id)) {\n    var fn = queue[id];\n    delete queue[id];\n    fn();\n  }\n};\nvar listener = function (event) {\n  run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif (!setTask || !clearTask) {\n  setTask = function setImmediate(fn) {\n    var args = [];\n    var i = 1;\n    while (arguments.length > i) args.push(arguments[i++]);\n    queue[++counter] = function () {\n      // eslint-disable-next-line no-new-func\n      invoke(typeof fn == 'function' ? fn : Function(fn), args);\n    };\n    defer(counter);\n    return counter;\n  };\n  clearTask = function clearImmediate(id) {\n    delete queue[id];\n  };\n  // Node.js 0.8-\n  if (__webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process') {\n    defer = function (id) {\n      process.nextTick(ctx(run, id, 1));\n    };\n  // Sphere (JS game engine) Dispatch API\n  } else if (Dispatch && Dispatch.now) {\n    defer = function (id) {\n      Dispatch.now(ctx(run, id, 1));\n    };\n  // Browsers with MessageChannel, includes WebWorkers\n  } else if (MessageChannel) {\n    channel = new MessageChannel();\n    port = channel.port2;\n    channel.port1.onmessage = listener;\n    defer = ctx(port.postMessage, port, 1);\n  // Browsers with postMessage, skip WebWorkers\n  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n  } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {\n    defer = function (id) {\n      global.postMessage(id + '', '*');\n    };\n    global.addEventListener('message', listener, false);\n  // IE8-\n  } else if (ONREADYSTATECHANGE in cel('script')) {\n    defer = function (id) {\n      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {\n        html.removeChild(this);\n        run.call(id);\n      };\n    };\n  // Rest old browsers\n  } else {\n    defer = function (id) {\n      setTimeout(ctx(run, id, 1), 0);\n    };\n  }\n}\nmodule.exports = {\n  set: setTask,\n  clear: clearTask\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-absolute-index.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-absolute-index.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n  index = toInteger(index);\n  return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-integer.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-integer.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-iobject.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-iobject.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return IObject(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-length.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-length.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.15 ToLength\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar min = Math.min;\nmodule.exports = function (it) {\n  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.13 ToObject(argument)\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return Object(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-primitive.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-primitive.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n  if (!isObject(it)) return it;\n  var fn, val;\n  if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_uid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_uid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_user-agent.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_user-agent.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar store = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('wks');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar Symbol = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n  return store[name] || (store[name] =\n    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/core.get-iterator-method.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/core.get-iterator-method.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nmodule.exports = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").getIteratorMethod = function (it) {\n  if (it != undefined) return it[ITERATOR]\n    || it['@@iterator']\n    || Iterators[classof(it)];\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.find.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.find.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $find = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(5);\nvar KEY = 'find';\nvar forced = true;\n// Shouldn't skip holes\nif (KEY in []) Array(1)[KEY](function () { forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  find: function find(callbackfn /* , that = undefined */) {\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")(KEY);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.is-array.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.is-array.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Array', { isArray: __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.iterator.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.iterator.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar addToUnscopables = __webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\");\nvar step = __webpack_require__(/*! ./_iter-step */ \"./node_modules/core-js/modules/_iter-step.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = __webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(Array, 'Array', function (iterated, kind) {\n  this._t = toIObject(iterated); // target\n  this._i = 0;                   // next index\n  this._k = kind;                // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var kind = this._k;\n  var index = this._i++;\n  if (!O || index >= O.length) {\n    this._t = undefined;\n    return step(1);\n  }\n  if (kind == 'keys') return step(0, index);\n  if (kind == 'values') return step(0, O[index]);\n  return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.some.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.some.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $some = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(3);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].some, true), 'Array', {\n  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])\n  some: function some(callbackfn /* , thisArg */) {\n    return $some(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.bind.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.bind.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Function', { bind: __webpack_require__(/*! ./_bind */ \"./node_modules/core-js/modules/_bind.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.assign.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.assign.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.1 Object.assign(target, source)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S + $export.F, 'Object', { assign: __webpack_require__(/*! ./_object-assign */ \"./node_modules/core-js/modules/_object-assign.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.to-string.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.to-string.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.3.6 Object.prototype.toString()\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar test = {};\ntest[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag')] = 'z';\nif (test + '' != '[object z]') {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(Object.prototype, 'toString', function toString() {\n    return '[object ' + classof(this) + ']';\n  }, true);\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.promise.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.promise.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar task = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar newPromiseCapabilityModule = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\nvar perform = __webpack_require__(/*! ./_perform */ \"./node_modules/core-js/modules/_perform.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\nvar promiseResolve = __webpack_require__(/*! ./_promise-resolve */ \"./node_modules/core-js/modules/_promise-resolve.js\");\nvar PROMISE = 'Promise';\nvar TypeError = global.TypeError;\nvar process = global.process;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8 || '';\nvar $Promise = global[PROMISE];\nvar isNode = classof(process) == 'process';\nvar empty = function () { /* empty */ };\nvar Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;\nvar newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;\n\nvar USE_NATIVE = !!function () {\n  try {\n    // correct subclassing with @@species support\n    var promise = $Promise.resolve(1);\n    var FakePromise = (promise.constructor = {})[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species')] = function (exec) {\n      exec(empty, empty);\n    };\n    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n    return (isNode || typeof PromiseRejectionEvent == 'function')\n      && promise.then(empty) instanceof FakePromise\n      // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables\n      // https://bugs.chromium.org/p/chromium/issues/detail?id=830565\n      // we can't detect it synchronously, so just check versions\n      && v8.indexOf('6.6') !== 0\n      && userAgent.indexOf('Chrome/66') === -1;\n  } catch (e) { /* empty */ }\n}();\n\n// helpers\nvar isThenable = function (it) {\n  var then;\n  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar notify = function (promise, isReject) {\n  if (promise._n) return;\n  promise._n = true;\n  var chain = promise._c;\n  microtask(function () {\n    var value = promise._v;\n    var ok = promise._s == 1;\n    var i = 0;\n    var run = function (reaction) {\n      var handler = ok ? reaction.ok : reaction.fail;\n      var resolve = reaction.resolve;\n      var reject = reaction.reject;\n      var domain = reaction.domain;\n      var result, then, exited;\n      try {\n        if (handler) {\n          if (!ok) {\n            if (promise._h == 2) onHandleUnhandled(promise);\n            promise._h = 1;\n          }\n          if (handler === true) result = value;\n          else {\n            if (domain) domain.enter();\n            result = handler(value); // may throw\n            if (domain) {\n              domain.exit();\n              exited = true;\n            }\n          }\n          if (result === reaction.promise) {\n            reject(TypeError('Promise-chain cycle'));\n          } else if (then = isThenable(result)) {\n            then.call(result, resolve, reject);\n          } else resolve(result);\n        } else reject(value);\n      } catch (e) {\n        if (domain && !exited) domain.exit();\n        reject(e);\n      }\n    };\n    while (chain.length > i) run(chain[i++]); // variable length - can't use forEach\n    promise._c = [];\n    promise._n = false;\n    if (isReject && !promise._h) onUnhandled(promise);\n  });\n};\nvar onUnhandled = function (promise) {\n  task.call(global, function () {\n    var value = promise._v;\n    var unhandled = isUnhandled(promise);\n    var result, handler, console;\n    if (unhandled) {\n      result = perform(function () {\n        if (isNode) {\n          process.emit('unhandledRejection', value, promise);\n        } else if (handler = global.onunhandledrejection) {\n          handler({ promise: promise, reason: value });\n        } else if ((console = global.console) && console.error) {\n          console.error('Unhandled promise rejection', value);\n        }\n      });\n      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n      promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n    } promise._a = undefined;\n    if (unhandled && result.e) throw result.v;\n  });\n};\nvar isUnhandled = function (promise) {\n  return promise._h !== 1 && (promise._a || promise._c).length === 0;\n};\nvar onHandleUnhandled = function (promise) {\n  task.call(global, function () {\n    var handler;\n    if (isNode) {\n      process.emit('rejectionHandled', promise);\n    } else if (handler = global.onrejectionhandled) {\n      handler({ promise: promise, reason: promise._v });\n    }\n  });\n};\nvar $reject = function (value) {\n  var promise = this;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  promise._v = value;\n  promise._s = 2;\n  if (!promise._a) promise._a = promise._c.slice();\n  notify(promise, true);\n};\nvar $resolve = function (value) {\n  var promise = this;\n  var then;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  try {\n    if (promise === value) throw TypeError(\"Promise can't be resolved itself\");\n    if (then = isThenable(value)) {\n      microtask(function () {\n        var wrapper = { _w: promise, _d: false }; // wrap\n        try {\n          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n        } catch (e) {\n          $reject.call(wrapper, e);\n        }\n      });\n    } else {\n      promise._v = value;\n      promise._s = 1;\n      notify(promise, false);\n    }\n  } catch (e) {\n    $reject.call({ _w: promise, _d: false }, e); // wrap\n  }\n};\n\n// constructor polyfill\nif (!USE_NATIVE) {\n  // 25.4.3.1 Promise(executor)\n  $Promise = function Promise(executor) {\n    anInstance(this, $Promise, PROMISE, '_h');\n    aFunction(executor);\n    Internal.call(this);\n    try {\n      executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n    } catch (err) {\n      $reject.call(this, err);\n    }\n  };\n  // eslint-disable-next-line no-unused-vars\n  Internal = function Promise(executor) {\n    this._c = [];             // <- awaiting reactions\n    this._a = undefined;      // <- checked in isUnhandled reactions\n    this._s = 0;              // <- state\n    this._d = false;          // <- done\n    this._v = undefined;      // <- value\n    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n    this._n = false;          // <- notify\n  };\n  Internal.prototype = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\")($Promise.prototype, {\n    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n    then: function then(onFulfilled, onRejected) {\n      var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n      reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n      reaction.fail = typeof onRejected == 'function' && onRejected;\n      reaction.domain = isNode ? process.domain : undefined;\n      this._c.push(reaction);\n      if (this._a) this._a.push(reaction);\n      if (this._s) notify(this, false);\n      return reaction.promise;\n    },\n    // 25.4.5.1 Promise.prototype.catch(onRejected)\n    'catch': function (onRejected) {\n      return this.then(undefined, onRejected);\n    }\n  });\n  OwnPromiseCapability = function () {\n    var promise = new Internal();\n    this.promise = promise;\n    this.resolve = ctx($resolve, promise, 1);\n    this.reject = ctx($reject, promise, 1);\n  };\n  newPromiseCapabilityModule.f = newPromiseCapability = function (C) {\n    return C === $Promise || C === Wrapper\n      ? new OwnPromiseCapability(C)\n      : newGenericPromiseCapability(C);\n  };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });\n__webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\")($Promise, PROMISE);\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")(PROMISE);\nWrapper = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\")[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n  // 25.4.4.5 Promise.reject(r)\n  reject: function reject(r) {\n    var capability = newPromiseCapability(this);\n    var $$reject = capability.reject;\n    $$reject(r);\n    return capability.promise;\n  }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n  // 25.4.4.6 Promise.resolve(x)\n  resolve: function resolve(x) {\n    return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);\n  }\n});\n$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\")(function (iter) {\n  $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n  // 25.4.4.1 Promise.all(iterable)\n  all: function all(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var resolve = capability.resolve;\n    var reject = capability.reject;\n    var result = perform(function () {\n      var values = [];\n      var index = 0;\n      var remaining = 1;\n      forOf(iterable, false, function (promise) {\n        var $index = index++;\n        var alreadyCalled = false;\n        values.push(undefined);\n        remaining++;\n        C.resolve(promise).then(function (value) {\n          if (alreadyCalled) return;\n          alreadyCalled = true;\n          values[$index] = value;\n          --remaining || resolve(values);\n        }, reject);\n      });\n      --remaining || resolve(values);\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  },\n  // 25.4.4.4 Promise.race(iterable)\n  race: function race(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var reject = capability.reject;\n    var result = perform(function () {\n      forOf(iterable, false, function (promise) {\n        C.resolve(promise).then(capability.resolve, reject);\n      });\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.iterator.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.iterator.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\n__webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(String, 'String', function (iterated) {\n  this._t = String(iterated); // target\n  this._i = 0;                // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var index = this._i;\n  var point;\n  if (index >= O.length) return { value: undefined, done: true };\n  point = $at(O, index);\n  this._i += point.length;\n  return { value: point, done: false };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.dom.iterable.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.dom.iterable.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $iterators = __webpack_require__(/*! ./es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar ITERATOR = wks('iterator');\nvar TO_STRING_TAG = wks('toStringTag');\nvar ArrayValues = Iterators.Array;\n\nvar DOMIterables = {\n  CSSRuleList: true, // TODO: Not spec compliant, should be false.\n  CSSStyleDeclaration: false,\n  CSSValueList: false,\n  ClientRectList: false,\n  DOMRectList: false,\n  DOMStringList: false,\n  DOMTokenList: true,\n  DataTransferItemList: false,\n  FileList: false,\n  HTMLAllCollection: false,\n  HTMLCollection: false,\n  HTMLFormElement: false,\n  HTMLSelectElement: false,\n  MediaList: true, // TODO: Not spec compliant, should be false.\n  MimeTypeArray: false,\n  NamedNodeMap: false,\n  NodeList: true,\n  PaintRequestList: false,\n  Plugin: false,\n  PluginArray: false,\n  SVGLengthList: false,\n  SVGNumberList: false,\n  SVGPathSegList: false,\n  SVGPointList: false,\n  SVGStringList: false,\n  SVGTransformList: false,\n  SourceBufferList: false,\n  StyleSheetList: true, // TODO: Not spec compliant, should be false.\n  TextTrackCueList: false,\n  TextTrackList: false,\n  TouchList: false\n};\n\nfor (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {\n  var NAME = collections[i];\n  var explicit = DOMIterables[NAME];\n  var Collection = global[NAME];\n  var proto = Collection && Collection.prototype;\n  var key;\n  if (proto) {\n    if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);\n    if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n    Iterators[NAME] = ArrayValues;\n    if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);\n  }\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/ieee754/index.js\":\n/*!***************************************!*\\\n  !*** ./node_modules/ieee754/index.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = ((value * c) - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/bytesToUuid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/bytesToUuid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n  byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n  var i = offset || 0;\n  var bth = byteToHex;\n  // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n  return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/rng-browser.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/rng-browser.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// Unique ID creation requires a high quality random # generator.  In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API.  We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n                      (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n  // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n  var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n  module.exports = function whatwgRNG() {\n    getRandomValues(rnds8);\n    return rnds8;\n  };\n} else {\n  // Math.random()-based (RNG)\n  //\n  // If all else fails, use Math.random().  It's fast, but is of unspecified\n  // quality.\n  var rnds = new Array(16);\n\n  module.exports = function mathRNG() {\n    for (var i = 0, r; i < 16; i++) {\n      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n      rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n    }\n\n    return rnds;\n  };\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/v4.js\":\n/*!*********************************!*\\\n  !*** ./node_modules/uuid/v4.js ***!\n  \\*********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar rng = __webpack_require__(/*! ./lib/rng */ \"./node_modules/uuid/lib/rng-browser.js\");\nvar bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ \"./node_modules/uuid/lib/bytesToUuid.js\");\n\nfunction v4(options, buf, offset) {\n  var i = buf && offset || 0;\n\n  if (typeof(options) == 'string') {\n    buf = options === 'binary' ? new Array(16) : null;\n    options = null;\n  }\n  options = options || {};\n\n  var rnds = options.random || (options.rng || rng)();\n\n  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n  rnds[6] = (rnds[6] & 0x0f) | 0x40;\n  rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n  // Copy bytes to buffer, if provided\n  if (buf) {\n    for (var ii = 0; ii < 16; ++ii) {\n      buf[i + ii] = rnds[ii];\n    }\n  }\n\n  return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n\n\n/***/ }),\n\n/***/ \"./node_modules/webpack/buildin/global.js\":\n/*!***********************************!*\\\n  !*** (webpack)/buildin/global.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n/***/ }),\n\n/***/ \"./polyfills.js\":\n/*!**********************!*\\\n  !*** ./polyfills.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n__webpack_require__(/*! core-js/es6/promise */ \"./node_modules/core-js/es6/promise.js\");\n\n__webpack_require__(/*! core-js/fn/function/bind */ \"./node_modules/core-js/fn/function/bind.js\");\n\n__webpack_require__(/*! core-js/fn/object/assign */ \"./node_modules/core-js/fn/object/assign.js\");\n\n__webpack_require__(/*! core-js/fn/array/find */ \"./node_modules/core-js/fn/array/find.js\");\n\n__webpack_require__(/*! core-js/fn/array/some */ \"./node_modules/core-js/fn/array/some.js\");\n\n__webpack_require__(/*! core-js/fn/array/is-array */ \"./node_modules/core-js/fn/array/is-array.js\");\n\n__webpack_require__(/*! core-js/fn/array/splice */ \"./node_modules/core-js/fn/array/splice.js\");\n\n/***/ }),\n\n/***/ \"./src/AccessTokenEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/AccessTokenEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AccessTokenEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Timer = __webpack_require__(/*! ./Timer.js */ \"./src/Timer.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60; // seconds\n\nvar AccessTokenEvents = exports.AccessTokenEvents = function () {\n    function AccessTokenEvents() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$accessTokenExpir2 = _ref.accessTokenExpiringTimer,\n            accessTokenExpiringTimer = _ref$accessTokenExpir2 === undefined ? new _Timer.Timer(\"Access token expiring\") : _ref$accessTokenExpir2,\n            _ref$accessTokenExpir3 = _ref.accessTokenExpiredTimer,\n            accessTokenExpiredTimer = _ref$accessTokenExpir3 === undefined ? new _Timer.Timer(\"Access token expired\") : _ref$accessTokenExpir3;\n\n        _classCallCheck(this, AccessTokenEvents);\n\n        this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        this._accessTokenExpiring = accessTokenExpiringTimer;\n        this._accessTokenExpired = accessTokenExpiredTimer;\n    }\n\n    AccessTokenEvents.prototype.load = function load(container) {\n        // only register events if there's an access token and it has an expiration\n        if (container.access_token && container.expires_in !== undefined) {\n            var duration = container.expires_in;\n            _Log.Log.debug(\"AccessTokenEvents.load: access token present, remaining duration:\", duration);\n\n            if (duration > 0) {\n                // only register expiring if we still have time\n                var expiring = duration - this._accessTokenExpiringNotificationTime;\n                if (expiring <= 0) {\n                    expiring = 1;\n                }\n\n                _Log.Log.debug(\"AccessTokenEvents.load: registering expiring timer in:\", expiring);\n                this._accessTokenExpiring.init(expiring);\n            } else {\n                _Log.Log.debug(\"AccessTokenEvents.load: canceling existing expiring timer becase we're past expiration.\");\n                this._accessTokenExpiring.cancel();\n            }\n\n            // if it's negative, it will still fire\n            var expired = duration + 1;\n            _Log.Log.debug(\"AccessTokenEvents.load: registering expired timer in:\", expired);\n            this._accessTokenExpired.init(expired);\n        } else {\n            this._accessTokenExpiring.cancel();\n            this._accessTokenExpired.cancel();\n        }\n    };\n\n    AccessTokenEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"AccessTokenEvents.unload: canceling existing access token timers\");\n        this._accessTokenExpiring.cancel();\n        this._accessTokenExpired.cancel();\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpiring = function addAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpiring = function removeAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.removeHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpired = function addAccessTokenExpired(cb) {\n        this._accessTokenExpired.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpired = function removeAccessTokenExpired(cb) {\n        this._accessTokenExpired.removeHandler(cb);\n    };\n\n    return AccessTokenEvents;\n}();\n\n/***/ }),\n\n/***/ \"./src/CheckSessionIFrame.js\":\n/*!***********************************!*\\\n  !*** ./src/CheckSessionIFrame.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CheckSessionIFrame = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultInterval = 2000;\n\nvar CheckSessionIFrame = exports.CheckSessionIFrame = function () {\n    function CheckSessionIFrame(callback, client_id, url, interval) {\n        var stopOnError = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n\n        _classCallCheck(this, CheckSessionIFrame);\n\n        this._callback = callback;\n        this._client_id = client_id;\n        this._url = url;\n        this._interval = interval || DefaultInterval;\n        this._stopOnError = stopOnError;\n\n        var idx = url.indexOf(\"/\", url.indexOf(\"//\") + 2);\n        this._frame_origin = url.substr(0, idx);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        this._frame.src = url;\n    }\n\n    CheckSessionIFrame.prototype.load = function load() {\n        var _this = this;\n\n        return new Promise(function (resolve) {\n            _this._frame.onload = function () {\n                resolve();\n            };\n\n            window.document.body.appendChild(_this._frame);\n            _this._boundMessageEvent = _this._message.bind(_this);\n            window.addEventListener(\"message\", _this._boundMessageEvent, false);\n        });\n    };\n\n    CheckSessionIFrame.prototype._message = function _message(e) {\n        if (e.origin === this._frame_origin && e.source === this._frame.contentWindow) {\n            if (e.data === \"error\") {\n                _Log.Log.error(\"CheckSessionIFrame: error message from check session op iframe\");\n                if (this._stopOnError) {\n                    this.stop();\n                }\n            } else if (e.data === \"changed\") {\n                _Log.Log.debug(\"CheckSessionIFrame: changed message from check session op iframe\");\n                this.stop();\n                this._callback();\n            } else {\n                _Log.Log.debug(\"CheckSessionIFrame: \" + e.data + \" message from check session op iframe\");\n            }\n        }\n    };\n\n    CheckSessionIFrame.prototype.start = function start(session_state) {\n        var _this2 = this;\n\n        if (this._session_state !== session_state) {\n            _Log.Log.debug(\"CheckSessionIFrame.start\");\n\n            this.stop();\n\n            this._session_state = session_state;\n\n            var send = function send() {\n                _this2._frame.contentWindow.postMessage(_this2._client_id + \" \" + _this2._session_state, _this2._frame_origin);\n            };\n\n            // trigger now\n            send();\n\n            // and setup timer\n            this._timer = window.setInterval(send, this._interval);\n        }\n    };\n\n    CheckSessionIFrame.prototype.stop = function stop() {\n        this._session_state = null;\n\n        if (this._timer) {\n            _Log.Log.debug(\"CheckSessionIFrame.stop\");\n\n            window.clearInterval(this._timer);\n            this._timer = null;\n        }\n    };\n\n    return CheckSessionIFrame;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaIFrameNavigator.js\":\n/*!***************************************!*\\\n  !*** ./src/CordovaIFrameNavigator.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaIFrameNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaIFrameNavigator = exports.CordovaIFrameNavigator = function () {\n    function CordovaIFrameNavigator() {\n        _classCallCheck(this, CordovaIFrameNavigator);\n    }\n\n    CordovaIFrameNavigator.prototype.prepare = function prepare(params) {\n        params.popupWindowFeatures = 'hidden=yes';\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaIFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupNavigator.js\":\n/*!**************************************!*\\\n  !*** ./src/CordovaPopupNavigator.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaPopupNavigator = exports.CordovaPopupNavigator = function () {\n    function CordovaPopupNavigator() {\n        _classCallCheck(this, CordovaPopupNavigator);\n    }\n\n    CordovaPopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaPopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupWindow.js\":\n/*!***********************************!*\\\n  !*** ./src/CordovaPopupWindow.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultPopupFeatures = 'location=no,toolbar=no,zoom=no';\nvar DefaultPopupTarget = \"_blank\";\n\nvar CordovaPopupWindow = exports.CordovaPopupWindow = function () {\n    function CordovaPopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, CordovaPopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this.features = params.popupWindowFeatures || DefaultPopupFeatures;\n        this.target = params.popupWindowTarget || DefaultPopupTarget;\n\n        this.redirect_uri = params.startUrl;\n        _Log.Log.debug(\"CordovaPopupWindow.ctor: redirect_uri: \" + this.redirect_uri);\n    }\n\n    CordovaPopupWindow.prototype._isInAppBrowserInstalled = function _isInAppBrowserInstalled(cordovaMetadata) {\n        return [\"cordova-plugin-inappbrowser\", \"cordova-plugin-inappbrowser.inappbrowser\", \"org.apache.cordova.inappbrowser\"].some(function (name) {\n            return cordovaMetadata.hasOwnProperty(name);\n        });\n    };\n\n    CordovaPopupWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            if (!window.cordova) {\n                return this._error(\"cordova is undefined\");\n            }\n\n            var cordovaMetadata = window.cordova.require(\"cordova/plugin_list\").metadata;\n            if (this._isInAppBrowserInstalled(cordovaMetadata) === false) {\n                return this._error(\"InAppBrowser plugin not found\");\n            }\n            this._popup = cordova.InAppBrowser.open(params.url, this.target, this.features);\n            if (this._popup) {\n                _Log.Log.debug(\"CordovaPopupWindow.navigate: popup successfully created\");\n\n                this._exitCallbackEvent = this._exitCallback.bind(this);\n                this._loadStartCallbackEvent = this._loadStartCallback.bind(this);\n\n                this._popup.addEventListener(\"exit\", this._exitCallbackEvent, false);\n                this._popup.addEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            } else {\n                this._error(\"Error opening popup window\");\n            }\n        }\n        return this.promise;\n    };\n\n    CordovaPopupWindow.prototype._loadStartCallback = function _loadStartCallback(event) {\n        if (event.url.indexOf(this.redirect_uri) === 0) {\n            this._success({ url: event.url });\n        }\n    };\n\n    CordovaPopupWindow.prototype._exitCallback = function _exitCallback(message) {\n        this._error(message);\n    };\n\n    CordovaPopupWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"CordovaPopupWindow: Successful response from cordova popup window\");\n        this._resolve(data);\n    };\n\n    CordovaPopupWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    CordovaPopupWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    CordovaPopupWindow.prototype._cleanup = function _cleanup() {\n        if (this._popup) {\n            _Log.Log.debug(\"CordovaPopupWindow: cleaning up popup\");\n            this._popup.removeEventListener(\"exit\", this._exitCallbackEvent, false);\n            this._popup.removeEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    _createClass(CordovaPopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return CordovaPopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/ErrorResponse.js\":\n/*!******************************!*\\\n  !*** ./src/ErrorResponse.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.ErrorResponse = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ErrorResponse = exports.ErrorResponse = function (_Error) {\n        _inherits(ErrorResponse, _Error);\n\n        function ErrorResponse() {\n                var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n                    error = _ref.error,\n                    error_description = _ref.error_description,\n                    error_uri = _ref.error_uri,\n                    state = _ref.state,\n                    session_state = _ref.session_state;\n\n                _classCallCheck(this, ErrorResponse);\n\n                if (!error) {\n                        _Log.Log.error(\"No error passed to ErrorResponse\");\n                        throw new Error(\"error\");\n                }\n\n                var _this = _possibleConstructorReturn(this, _Error.call(this, error_description || error));\n\n                _this.name = \"ErrorResponse\";\n\n                _this.error = error;\n                _this.error_description = error_description;\n                _this.error_uri = error_uri;\n\n                _this.state = state;\n                _this.session_state = session_state;\n                return _this;\n        }\n\n        return ErrorResponse;\n}(Error);\n\n/***/ }),\n\n/***/ \"./src/Event.js\":\n/*!**********************!*\\\n  !*** ./src/Event.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Event = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar Event = exports.Event = function () {\n    function Event(name) {\n        _classCallCheck(this, Event);\n\n        this._name = name;\n        this._callbacks = [];\n    }\n\n    Event.prototype.addHandler = function addHandler(cb) {\n        this._callbacks.push(cb);\n    };\n\n    Event.prototype.removeHandler = function removeHandler(cb) {\n        var idx = this._callbacks.findIndex(function (item) {\n            return item === cb;\n        });\n        if (idx >= 0) {\n            this._callbacks.splice(idx, 1);\n        }\n    };\n\n    Event.prototype.raise = function raise() {\n        _Log.Log.debug(\"Event: Raising event: \" + this._name);\n        for (var i = 0; i < this._callbacks.length; i++) {\n            var _callbacks;\n\n            (_callbacks = this._callbacks)[i].apply(_callbacks, arguments);\n        }\n    };\n\n    return Event;\n}();\n\n/***/ }),\n\n/***/ \"./src/Global.js\":\n/*!***********************!*\\\n  !*** ./src/Global.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar timer = {\n    setInterval: function (_setInterval) {\n        function setInterval(_x, _x2) {\n            return _setInterval.apply(this, arguments);\n        }\n\n        setInterval.toString = function () {\n            return _setInterval.toString();\n        };\n\n        return setInterval;\n    }(function (cb, duration) {\n        return setInterval(cb, duration);\n    }),\n    clearInterval: function (_clearInterval) {\n        function clearInterval(_x3) {\n            return _clearInterval.apply(this, arguments);\n        }\n\n        clearInterval.toString = function () {\n            return _clearInterval.toString();\n        };\n\n        return clearInterval;\n    }(function (handle) {\n        return clearInterval(handle);\n    })\n};\n\nvar testing = false;\nvar request = null;\n\nvar Global = exports.Global = function () {\n    function Global() {\n        _classCallCheck(this, Global);\n    }\n\n    Global._testing = function _testing() {\n        testing = true;\n    };\n\n    Global.setXMLHttpRequest = function setXMLHttpRequest(newRequest) {\n        request = newRequest;\n    };\n\n    _createClass(Global, null, [{\n        key: 'location',\n        get: function get() {\n            if (!testing) {\n                return location;\n            }\n        }\n    }, {\n        key: 'localStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return localStorage;\n            }\n        }\n    }, {\n        key: 'sessionStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return sessionStorage;\n            }\n        }\n    }, {\n        key: 'XMLHttpRequest',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return request || XMLHttpRequest;\n            }\n        }\n    }, {\n        key: 'timer',\n        get: function get() {\n            if (!testing) {\n                return timer;\n            }\n        }\n    }]);\n\n    return Global;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameNavigator.js\":\n/*!********************************!*\\\n  !*** ./src/IFrameNavigator.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _IFrameWindow = __webpack_require__(/*! ./IFrameWindow.js */ \"./src/IFrameWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar IFrameNavigator = exports.IFrameNavigator = function () {\n    function IFrameNavigator() {\n        _classCallCheck(this, IFrameNavigator);\n    }\n\n    IFrameNavigator.prototype.prepare = function prepare(params) {\n        var frame = new _IFrameWindow.IFrameWindow(params);\n        return Promise.resolve(frame);\n    };\n\n    IFrameNavigator.prototype.callback = function callback(url) {\n        _Log.Log.debug(\"IFrameNavigator.callback\");\n\n        try {\n            _IFrameWindow.IFrameWindow.notifyParent(url);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return IFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameWindow.js\":\n/*!*****************************!*\\\n  !*** ./src/IFrameWindow.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultTimeout = 10000;\n\nvar IFrameWindow = exports.IFrameWindow = function () {\n    function IFrameWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, IFrameWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this._boundMessageEvent = this._message.bind(this);\n        window.addEventListener(\"message\", this._boundMessageEvent, false);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        window.document.body.appendChild(this._frame);\n    }\n\n    IFrameWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            var timeout = params.silentRequestTimeout || DefaultTimeout;\n            _Log.Log.debug(\"IFrameWindow.navigate: Using timeout of:\", timeout);\n            this._timer = window.setTimeout(this._timeout.bind(this), timeout);\n            this._frame.src = params.url;\n        }\n\n        return this.promise;\n    };\n\n    IFrameWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"IFrameWindow: Successful response from frame window\");\n        this._resolve(data);\n    };\n\n    IFrameWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    IFrameWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    IFrameWindow.prototype._cleanup = function _cleanup() {\n        if (this._frame) {\n            _Log.Log.debug(\"IFrameWindow: cleanup\");\n\n            window.removeEventListener(\"message\", this._boundMessageEvent, false);\n            window.clearTimeout(this._timer);\n            window.document.body.removeChild(this._frame);\n\n            this._timer = null;\n            this._frame = null;\n            this._boundMessageEvent = null;\n        }\n    };\n\n    IFrameWindow.prototype._timeout = function _timeout() {\n        _Log.Log.debug(\"IFrameWindow.timeout\");\n        this._error(\"Frame window timed out\");\n    };\n\n    IFrameWindow.prototype._message = function _message(e) {\n        _Log.Log.debug(\"IFrameWindow.message\");\n\n        if (this._timer && e.origin === this._origin && e.source === this._frame.contentWindow) {\n            var url = e.data;\n            if (url) {\n                this._success({ url: url });\n            } else {\n                this._error(\"Invalid response from frame\");\n            }\n        }\n    };\n\n    IFrameWindow.notifyParent = function notifyParent(url) {\n        _Log.Log.debug(\"IFrameWindow.notifyParent\");\n        if (window.frameElement) {\n            url = url || window.location.href;\n            if (url) {\n                _Log.Log.debug(\"IFrameWindow.notifyParent: posting url message to parent\");\n                window.parent.postMessage(url, location.protocol + \"//\" + location.host);\n            }\n        }\n    };\n\n    _createClass(IFrameWindow, [{\n        key: \"promise\",\n        get: function get() {\n            return this._promise;\n        }\n    }, {\n        key: \"_origin\",\n        get: function get() {\n            return location.protocol + \"//\" + location.host;\n        }\n    }]);\n\n    return IFrameWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/InMemoryWebStorage.js\":\n/*!***********************************!*\\\n  !*** ./src/InMemoryWebStorage.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.InMemoryWebStorage = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar InMemoryWebStorage = exports.InMemoryWebStorage = function () {\n    function InMemoryWebStorage() {\n        _classCallCheck(this, InMemoryWebStorage);\n\n        this._data = {};\n    }\n\n    InMemoryWebStorage.prototype.getItem = function getItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.getItem\", key);\n        return this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.setItem = function setItem(key, value) {\n        _Log.Log.debug(\"InMemoryWebStorage.setItem\", key);\n        this._data[key] = value;\n    };\n\n    InMemoryWebStorage.prototype.removeItem = function removeItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.removeItem\", key);\n        delete this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.key = function key(index) {\n        return Object.getOwnPropertyNames(this._data)[index];\n    };\n\n    _createClass(InMemoryWebStorage, [{\n        key: \"length\",\n        get: function get() {\n            return Object.getOwnPropertyNames(this._data).length;\n        }\n    }]);\n\n    return InMemoryWebStorage;\n}();\n\n/***/ }),\n\n/***/ \"./src/JoseUtil.js\":\n/*!*************************!*\\\n  !*** ./src/JoseUtil.js ***!\n  \\*************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.JoseUtil = undefined;\n\nvar _jsrsasign = __webpack_require__(/*! ./crypto/jsrsasign */ \"./src/crypto/jsrsasign.js\");\n\nvar _JoseUtilImpl = __webpack_require__(/*! ./JoseUtilImpl */ \"./src/JoseUtilImpl.js\");\n\nvar _JoseUtilImpl2 = _interopRequireDefault(_JoseUtilImpl);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar JoseUtil = exports.JoseUtil = (0, _JoseUtilImpl2.default)({ jws: _jsrsasign.jws, KeyUtil: _jsrsasign.KeyUtil, X509: _jsrsasign.X509, crypto: _jsrsasign.crypto, hextob64u: _jsrsasign.hextob64u, b64tohex: _jsrsasign.b64tohex, AllowedSigningAlgs: _jsrsasign.AllowedSigningAlgs });\n\n/***/ }),\n\n/***/ \"./src/JoseUtilImpl.js\":\n/*!*****************************!*\\\n  !*** ./src/JoseUtilImpl.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.default = getJoseUtil;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nfunction getJoseUtil(_ref) {\n    var jws = _ref.jws,\n        KeyUtil = _ref.KeyUtil,\n        X509 = _ref.X509,\n        crypto = _ref.crypto,\n        hextob64u = _ref.hextob64u,\n        b64tohex = _ref.b64tohex,\n        AllowedSigningAlgs = _ref.AllowedSigningAlgs;\n\n    return function () {\n        function JoseUtil() {\n            _classCallCheck(this, JoseUtil);\n        }\n\n        JoseUtil.parseJwt = function parseJwt(jwt) {\n            _Log.Log.debug(\"JoseUtil.parseJwt\");\n            try {\n                var token = jws.JWS.parse(jwt);\n                return {\n                    header: token.headerObj,\n                    payload: token.payloadObj\n                };\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.validateJwt = function validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n            _Log.Log.debug(\"JoseUtil.validateJwt\");\n\n            try {\n                if (key.kty === \"RSA\") {\n                    if (key.e && key.n) {\n                        key = KeyUtil.getKey(key);\n                    } else if (key.x5c && key.x5c.length) {\n                        var hex = b64tohex(key.x5c[0]);\n                        key = X509.getPublicKeyFromCertHex(hex);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: RSA key missing key material\", key);\n                        return Promise.reject(new Error(\"RSA key missing key material\"));\n                    }\n                } else if (key.kty === \"EC\") {\n                    if (key.crv && key.x && key.y) {\n                        key = KeyUtil.getKey(key);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: EC key missing key material\", key);\n                        return Promise.reject(new Error(\"EC key missing key material\"));\n                    }\n                } else {\n                    _Log.Log.error(\"JoseUtil.validateJwt: Unsupported key type\", key && key.kty);\n                    return Promise.reject(new Error( true && key.kty));\n                }\n\n                return JoseUtil._validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive);\n            } catch (e) {\n                _Log.Log.error(e && e.message || e);\n                return Promise.reject(\"JWT validation failed\");\n            }\n        };\n\n        JoseUtil.validateJwtAttributes = function validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive) {\n            if (!clockSkew) {\n                clockSkew = 0;\n            }\n\n            if (!now) {\n                now = parseInt(Date.now() / 1000);\n            }\n\n            var payload = JoseUtil.parseJwt(jwt).payload;\n\n            if (!payload.iss) {\n                _Log.Log.error(\"JoseUtil._validateJwt: issuer was not provided\");\n                return Promise.reject(new Error(\"issuer was not provided\"));\n            }\n            if (payload.iss !== issuer) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid issuer in token\", payload.iss);\n                return Promise.reject(new Error(\"Invalid issuer in token: \" + payload.iss));\n            }\n\n            if (!payload.aud) {\n                _Log.Log.error(\"JoseUtil._validateJwt: aud was not provided\");\n                return Promise.reject(new Error(\"aud was not provided\"));\n            }\n            var validAudience = payload.aud === audience || Array.isArray(payload.aud) && payload.aud.indexOf(audience) >= 0;\n            if (!validAudience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid audience in token\", payload.aud);\n                return Promise.reject(new Error(\"Invalid audience in token: \" + payload.aud));\n            }\n            if (payload.azp && payload.azp !== audience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid azp in token\", payload.azp);\n                return Promise.reject(new Error(\"Invalid azp in token: \" + payload.azp));\n            }\n\n            if (!timeInsensitive) {\n                var lowerNow = now + clockSkew;\n                var upperNow = now - clockSkew;\n\n                if (!payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat was not provided\");\n                    return Promise.reject(new Error(\"iat was not provided\"));\n                }\n                if (lowerNow < payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat is in the future\", payload.iat);\n                    return Promise.reject(new Error(\"iat is in the future: \" + payload.iat));\n                }\n\n                if (payload.nbf && lowerNow < payload.nbf) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: nbf is in the future\", payload.nbf);\n                    return Promise.reject(new Error(\"nbf is in the future: \" + payload.nbf));\n                }\n\n                if (!payload.exp) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp was not provided\");\n                    return Promise.reject(new Error(\"exp was not provided\"));\n                }\n                if (payload.exp < upperNow) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp is in the past\", payload.exp);\n                    return Promise.reject(new Error(\"exp is in the past:\" + payload.exp));\n                }\n            }\n\n            return Promise.resolve(payload);\n        };\n\n        JoseUtil._validateJwt = function _validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n\n            return JoseUtil.validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive).then(function (payload) {\n                try {\n                    if (!jws.JWS.verify(jwt, key, AllowedSigningAlgs)) {\n                        _Log.Log.error(\"JoseUtil._validateJwt: signature validation failed\");\n                        return Promise.reject(new Error(\"signature validation failed\"));\n                    }\n\n                    return payload;\n                } catch (e) {\n                    _Log.Log.error(e && e.message || e);\n                    return Promise.reject(new Error(\"signature validation failed\"));\n                }\n            });\n        };\n\n        JoseUtil.hashString = function hashString(value, alg) {\n            try {\n                return crypto.Util.hashString(value, alg);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.hexToBase64Url = function hexToBase64Url(value) {\n            try {\n                return hextob64u(value);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        return JoseUtil;\n    }();\n}\nmodule.exports = exports[\"default\"];\n\n/***/ }),\n\n/***/ \"./src/JsonService.js\":\n/*!****************************!*\\\n  !*** ./src/JsonService.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.JsonService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar JsonService = exports.JsonService = function () {\n    function JsonService() {\n        var additionalContentTypes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var jwtHandler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n\n        _classCallCheck(this, JsonService);\n\n        if (additionalContentTypes && Array.isArray(additionalContentTypes)) {\n            this._contentTypes = additionalContentTypes.slice();\n        } else {\n            this._contentTypes = [];\n        }\n        this._contentTypes.push('application/json');\n        if (jwtHandler) {\n            this._contentTypes.push('application/jwt');\n        }\n\n        this._XMLHttpRequest = XMLHttpRequestCtor;\n        this._jwtHandler = jwtHandler;\n    }\n\n    JsonService.prototype.getJson = function getJson(url, token) {\n        var _this = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.getJson: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.getJson, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this._XMLHttpRequest();\n            req.open('GET', url);\n\n            var allowedContentTypes = _this._contentTypes;\n            var jwtHandler = _this._jwtHandler;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.getJson: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found == \"application/jwt\") {\n                            jwtHandler(req).then(resolve, reject);\n                            return;\n                        }\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.getJson: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                } else {\n                    reject(Error(req.statusText + \" (\" + req.status + \")\"));\n                }\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.getJson: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            if (token) {\n                _Log.Log.debug(\"JsonService.getJson: token passed, setting Authorization header\");\n                req.setRequestHeader(\"Authorization\", \"Bearer \" + token);\n            }\n\n            req.send();\n        });\n    };\n\n    JsonService.prototype.postForm = function postForm(url, payload) {\n        var _this2 = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.postForm: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.postForm, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this2._XMLHttpRequest();\n            req.open('POST', url);\n\n            var allowedContentTypes = _this2._contentTypes;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.postForm: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                    return;\n                }\n\n                if (req.status === 400) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                var payload = JSON.parse(req.responseText);\n                                if (payload && payload.error) {\n                                    _Log.Log.error(\"JsonService.postForm: Error from server: \", payload.error);\n                                    reject(new Error(payload.error));\n                                    return;\n                                }\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n                }\n\n                reject(Error(req.statusText + \" (\" + req.status + \")\"));\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.postForm: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            var body = \"\";\n            for (var key in payload) {\n\n                var value = payload[key];\n\n                if (value) {\n\n                    if (body.length > 0) {\n                        body += \"&\";\n                    }\n\n                    body += encodeURIComponent(key);\n                    body += \"=\";\n                    body += encodeURIComponent(value);\n                }\n            }\n\n            req.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            req.send(body);\n        });\n    };\n\n    return JsonService;\n}();\n\n/***/ }),\n\n/***/ \"./src/Log.js\":\n/*!********************!*\\\n  !*** ./src/Log.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar nopLogger = {\n    debug: function debug() {},\n    info: function info() {},\n    warn: function warn() {},\n    error: function error() {}\n};\n\nvar NONE = 0;\nvar ERROR = 1;\nvar WARN = 2;\nvar INFO = 3;\nvar DEBUG = 4;\n\nvar logger = void 0;\nvar level = void 0;\n\nvar Log = exports.Log = function () {\n    function Log() {\n        _classCallCheck(this, Log);\n    }\n\n    Log.reset = function reset() {\n        level = INFO;\n        logger = nopLogger;\n    };\n\n    Log.debug = function debug() {\n        if (level >= DEBUG) {\n            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n                args[_key] = arguments[_key];\n            }\n\n            logger.debug.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.info = function info() {\n        if (level >= INFO) {\n            for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n                args[_key2] = arguments[_key2];\n            }\n\n            logger.info.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.warn = function warn() {\n        if (level >= WARN) {\n            for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n                args[_key3] = arguments[_key3];\n            }\n\n            logger.warn.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.error = function error() {\n        if (level >= ERROR) {\n            for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n                args[_key4] = arguments[_key4];\n            }\n\n            logger.error.apply(logger, Array.from(args));\n        }\n    };\n\n    _createClass(Log, null, [{\n        key: \"NONE\",\n        get: function get() {\n            return NONE;\n        }\n    }, {\n        key: \"ERROR\",\n        get: function get() {\n            return ERROR;\n        }\n    }, {\n        key: \"WARN\",\n        get: function get() {\n            return WARN;\n        }\n    }, {\n        key: \"INFO\",\n        get: function get() {\n            return INFO;\n        }\n    }, {\n        key: \"DEBUG\",\n        get: function get() {\n            return DEBUG;\n        }\n    }, {\n        key: \"level\",\n        get: function get() {\n            return level;\n        },\n        set: function set(value) {\n            if (NONE <= value && value <= DEBUG) {\n                level = value;\n            } else {\n                throw new Error(\"Invalid log level\");\n            }\n        }\n    }, {\n        key: \"logger\",\n        get: function get() {\n            return logger;\n        },\n        set: function set(value) {\n            if (!value.debug && value.info) {\n                // just to stay backwards compat. can remove in 2.0\n                value.debug = value.info;\n            }\n\n            if (value.debug && value.info && value.warn && value.error) {\n                logger = value;\n            } else {\n                throw new Error(\"Invalid logger\");\n            }\n        }\n    }]);\n\n    return Log;\n}();\n\nLog.reset();\n\n/***/ }),\n\n/***/ \"./src/MetadataService.js\":\n/*!********************************!*\\\n  !*** ./src/MetadataService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.MetadataService = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar MetadataService = exports.MetadataService = function () {\n    function MetadataService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n\n        _classCallCheck(this, MetadataService);\n\n        if (!settings) {\n            _Log.Log.error(\"MetadataService: No settings passed to MetadataService\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(['application/jwk-set+json']);\n    }\n\n    MetadataService.prototype.getMetadata = function getMetadata() {\n        var _this = this;\n\n        if (this._settings.metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: Returning metadata from settings\");\n            return Promise.resolve(this._settings.metadata);\n        }\n\n        if (!this.metadataUrl) {\n            _Log.Log.error(\"MetadataService.getMetadata: No authority or metadataUrl configured on settings\");\n            return Promise.reject(new Error(\"No authority or metadataUrl configured on settings\"));\n        }\n\n        _Log.Log.debug(\"MetadataService.getMetadata: getting metadata from\", this.metadataUrl);\n\n        return this._jsonService.getJson(this.metadataUrl).then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: json received\");\n            _this._settings.metadata = metadata;\n            return metadata;\n        });\n    };\n\n    MetadataService.prototype.getIssuer = function getIssuer() {\n        return this._getMetadataProperty(\"issuer\");\n    };\n\n    MetadataService.prototype.getAuthorizationEndpoint = function getAuthorizationEndpoint() {\n        return this._getMetadataProperty(\"authorization_endpoint\");\n    };\n\n    MetadataService.prototype.getUserInfoEndpoint = function getUserInfoEndpoint() {\n        return this._getMetadataProperty(\"userinfo_endpoint\");\n    };\n\n    MetadataService.prototype.getTokenEndpoint = function getTokenEndpoint() {\n        var optional = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n        return this._getMetadataProperty(\"token_endpoint\", optional);\n    };\n\n    MetadataService.prototype.getCheckSessionIframe = function getCheckSessionIframe() {\n        return this._getMetadataProperty(\"check_session_iframe\", true);\n    };\n\n    MetadataService.prototype.getEndSessionEndpoint = function getEndSessionEndpoint() {\n        return this._getMetadataProperty(\"end_session_endpoint\", true);\n    };\n\n    MetadataService.prototype.getRevocationEndpoint = function getRevocationEndpoint() {\n        return this._getMetadataProperty(\"revocation_endpoint\", true);\n    };\n\n    MetadataService.prototype.getKeysEndpoint = function getKeysEndpoint() {\n        return this._getMetadataProperty(\"jwks_uri\", true);\n    };\n\n    MetadataService.prototype._getMetadataProperty = function _getMetadataProperty(name) {\n        var optional = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n        _Log.Log.debug(\"MetadataService.getMetadataProperty for: \" + name);\n\n        return this.getMetadata().then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadataProperty: metadata recieved\");\n\n            if (metadata[name] === undefined) {\n\n                if (optional === true) {\n                    _Log.Log.warn(\"MetadataService.getMetadataProperty: Metadata does not contain optional property \" + name);\n                    return undefined;\n                } else {\n                    _Log.Log.error(\"MetadataService.getMetadataProperty: Metadata does not contain property \" + name);\n                    throw new Error(\"Metadata does not contain property \" + name);\n                }\n            }\n\n            return metadata[name];\n        });\n    };\n\n    MetadataService.prototype.getSigningKeys = function getSigningKeys() {\n        var _this2 = this;\n\n        if (this._settings.signingKeys) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: Returning signingKeys from settings\");\n            return Promise.resolve(this._settings.signingKeys);\n        }\n\n        return this._getMetadataProperty(\"jwks_uri\").then(function (jwks_uri) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: jwks_uri received\", jwks_uri);\n\n            return _this2._jsonService.getJson(jwks_uri).then(function (keySet) {\n                _Log.Log.debug(\"MetadataService.getSigningKeys: key set received\", keySet);\n\n                if (!keySet.keys) {\n                    _Log.Log.error(\"MetadataService.getSigningKeys: Missing keys on keyset\");\n                    throw new Error(\"Missing keys on keyset\");\n                }\n\n                _this2._settings.signingKeys = keySet.keys;\n                return _this2._settings.signingKeys;\n            });\n        });\n    };\n\n    _createClass(MetadataService, [{\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                if (this._settings.metadataUrl) {\n                    this._metadataUrl = this._settings.metadataUrl;\n                } else {\n                    this._metadataUrl = this._settings.authority;\n\n                    if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                        if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                            this._metadataUrl += '/';\n                        }\n                        this._metadataUrl += OidcMetadataUrlPath;\n                    }\n                }\n            }\n\n            return this._metadataUrl;\n        }\n    }]);\n\n    return MetadataService;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClient.js\":\n/*!***************************!*\\\n  !*** ./src/OidcClient.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClient = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nvar _SigninResponse = __webpack_require__(/*! ./SigninResponse.js */ \"./src/SigninResponse.js\");\n\nvar _SignoutRequest = __webpack_require__(/*! ./SignoutRequest.js */ \"./src/SignoutRequest.js\");\n\nvar _SignoutResponse = __webpack_require__(/*! ./SignoutResponse.js */ \"./src/SignoutResponse.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcClient = exports.OidcClient = function () {\n    function OidcClient() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        _classCallCheck(this, OidcClient);\n\n        if (settings instanceof _OidcClientSettings.OidcClientSettings) {\n            this._settings = settings;\n        } else {\n            this._settings = new _OidcClientSettings.OidcClientSettings(settings);\n        }\n    }\n\n    OidcClient.prototype.createSigninRequest = function createSigninRequest() {\n        var _this = this;\n\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            redirect_uri = _ref.redirect_uri,\n            data = _ref.data,\n            state = _ref.state,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            response_mode = _ref.response_mode,\n            extraQueryParams = _ref.extraQueryParams,\n            extraTokenParams = _ref.extraTokenParams,\n            request_type = _ref.request_type,\n            skipUserInfo = _ref.skipUserInfo;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSigninRequest\");\n\n        var client_id = this._settings.client_id;\n        response_type = response_type || this._settings.response_type;\n        scope = scope || this._settings.scope;\n        redirect_uri = redirect_uri || this._settings.redirect_uri;\n\n        // id_token_hint, login_hint aren't allowed on _settings\n        prompt = prompt || this._settings.prompt;\n        display = display || this._settings.display;\n        max_age = max_age || this._settings.max_age;\n        ui_locales = ui_locales || this._settings.ui_locales;\n        acr_values = acr_values || this._settings.acr_values;\n        resource = resource || this._settings.resource;\n        response_mode = response_mode || this._settings.response_mode;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n        extraTokenParams = extraTokenParams || this._settings.extraTokenParams;\n\n        var authority = this._settings.authority;\n\n        if (_SigninRequest.SigninRequest.isCode(response_type) && response_type !== \"code\") {\n            return Promise.reject(new Error(\"OpenID Connect hybrid flow is not supported\"));\n        }\n\n        return this._metadataService.getAuthorizationEndpoint().then(function (url) {\n            _Log.Log.debug(\"OidcClient.createSigninRequest: Received authorization endpoint\", url);\n\n            var signinRequest = new _SigninRequest.SigninRequest({\n                url: url,\n                client_id: client_id,\n                redirect_uri: redirect_uri,\n                response_type: response_type,\n                scope: scope,\n                data: data || state,\n                authority: authority,\n                prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values,\n                resource: resource, request: request, request_uri: request_uri, extraQueryParams: extraQueryParams, extraTokenParams: extraTokenParams, request_type: request_type, response_mode: response_mode,\n                client_secret: _this._settings.client_secret,\n                skipUserInfo: skipUserInfo\n            });\n\n            var signinState = signinRequest.state;\n            stateStore = stateStore || _this._stateStore;\n\n            return stateStore.set(signinState.id, signinState.toStorageString()).then(function () {\n                return signinRequest;\n            });\n        });\n    };\n\n    OidcClient.prototype.readSigninResponseState = function readSigninResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSigninResponseState\");\n\n        var useQuery = this._settings.response_mode === \"query\" || !this._settings.response_mode && _SigninRequest.SigninRequest.isCode(this._settings.response_type);\n        var delimiter = useQuery ? \"?\" : \"#\";\n\n        var response = new _SigninResponse.SigninResponse(url, delimiter);\n\n        if (!response.state) {\n            _Log.Log.error(\"OidcClient.readSigninResponseState: No state in response\");\n            return Promise.reject(new Error(\"No state in response\"));\n        }\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n\n        return stateApi(response.state).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSigninResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _SigninState.SigninState.fromStorageString(storedStateString);\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSigninResponse = function processSigninResponse(url, stateStore) {\n        var _this2 = this;\n\n        _Log.Log.debug(\"OidcClient.processSigninResponse\");\n\n        return this.readSigninResponseState(url, stateStore, true).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            _Log.Log.debug(\"OidcClient.processSigninResponse: Received state from storage; validating response\");\n            return _this2._validator.validateSigninResponse(state, response);\n        });\n    };\n\n    OidcClient.prototype.createSignoutRequest = function createSignoutRequest() {\n        var _this3 = this;\n\n        var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id_token_hint = _ref3.id_token_hint,\n            data = _ref3.data,\n            state = _ref3.state,\n            post_logout_redirect_uri = _ref3.post_logout_redirect_uri,\n            extraQueryParams = _ref3.extraQueryParams,\n            request_type = _ref3.request_type;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSignoutRequest\");\n\n        post_logout_redirect_uri = post_logout_redirect_uri || this._settings.post_logout_redirect_uri;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n\n        return this._metadataService.getEndSessionEndpoint().then(function (url) {\n            if (!url) {\n                _Log.Log.error(\"OidcClient.createSignoutRequest: No end session endpoint url returned\");\n                throw new Error(\"no end session endpoint\");\n            }\n\n            _Log.Log.debug(\"OidcClient.createSignoutRequest: Received end session endpoint\", url);\n\n            var request = new _SignoutRequest.SignoutRequest({\n                url: url,\n                id_token_hint: id_token_hint,\n                post_logout_redirect_uri: post_logout_redirect_uri,\n                data: data || state,\n                extraQueryParams: extraQueryParams,\n                request_type: request_type\n            });\n\n            var signoutState = request.state;\n            if (signoutState) {\n                _Log.Log.debug(\"OidcClient.createSignoutRequest: Signout request has state to persist\");\n\n                stateStore = stateStore || _this3._stateStore;\n                stateStore.set(signoutState.id, signoutState.toStorageString());\n            }\n\n            return request;\n        });\n    };\n\n    OidcClient.prototype.readSignoutResponseState = function readSignoutResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSignoutResponseState\");\n\n        var response = new _SignoutResponse.SignoutResponse(url);\n        if (!response.state) {\n            _Log.Log.debug(\"OidcClient.readSignoutResponseState: No state in response\");\n\n            if (response.error) {\n                _Log.Log.warn(\"OidcClient.readSignoutResponseState: Response was error: \", response.error);\n                return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n            }\n\n            return Promise.resolve({ undefined: undefined, response: response });\n        }\n\n        var stateKey = response.state;\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n        return stateApi(stateKey).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSignoutResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _State.State.fromStorageString(storedStateString);\n\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSignoutResponse = function processSignoutResponse(url, stateStore) {\n        var _this4 = this;\n\n        _Log.Log.debug(\"OidcClient.processSignoutResponse\");\n\n        return this.readSignoutResponseState(url, stateStore, true).then(function (_ref4) {\n            var state = _ref4.state,\n                response = _ref4.response;\n\n            if (state) {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: Received state from storage; validating response\");\n                return _this4._validator.validateSignoutResponse(state, response);\n            } else {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: No state from storage; skipping validating response\");\n                return response;\n            }\n        });\n    };\n\n    OidcClient.prototype.clearStaleState = function clearStaleState(stateStore) {\n        _Log.Log.debug(\"OidcClient.clearStaleState\");\n\n        stateStore = stateStore || this._stateStore;\n\n        return _State.State.clearStaleState(stateStore, this.settings.staleStateAge);\n    };\n\n    _createClass(OidcClient, [{\n        key: '_stateStore',\n        get: function get() {\n            return this.settings.stateStore;\n        }\n    }, {\n        key: '_validator',\n        get: function get() {\n            return this.settings.validator;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this.settings.metadataService;\n        }\n    }, {\n        key: 'settings',\n        get: function get() {\n            return this._settings;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n    }]);\n\n    return OidcClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClientSettings.js\":\n/*!***********************************!*\\\n  !*** ./src/OidcClientSettings.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClientSettings = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _ResponseValidator = __webpack_require__(/*! ./ResponseValidator.js */ \"./src/ResponseValidator.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar DefaultResponseType = \"id_token\";\nvar DefaultScope = \"openid\";\nvar DefaultStaleStateAge = 60 * 15; // seconds\nvar DefaultClockSkewInSeconds = 60 * 5;\n\nvar OidcClientSettings = exports.OidcClientSettings = function () {\n    function OidcClientSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            authority = _ref.authority,\n            metadataUrl = _ref.metadataUrl,\n            metadata = _ref.metadata,\n            signingKeys = _ref.signingKeys,\n            client_id = _ref.client_id,\n            client_secret = _ref.client_secret,\n            _ref$response_type = _ref.response_type,\n            response_type = _ref$response_type === undefined ? DefaultResponseType : _ref$response_type,\n            _ref$scope = _ref.scope,\n            scope = _ref$scope === undefined ? DefaultScope : _ref$scope,\n            redirect_uri = _ref.redirect_uri,\n            post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            _ref$filterProtocolCl = _ref.filterProtocolClaims,\n            filterProtocolClaims = _ref$filterProtocolCl === undefined ? true : _ref$filterProtocolCl,\n            _ref$loadUserInfo = _ref.loadUserInfo,\n            loadUserInfo = _ref$loadUserInfo === undefined ? true : _ref$loadUserInfo,\n            _ref$staleStateAge = _ref.staleStateAge,\n            staleStateAge = _ref$staleStateAge === undefined ? DefaultStaleStateAge : _ref$staleStateAge,\n            _ref$clockSkew = _ref.clockSkew,\n            clockSkew = _ref$clockSkew === undefined ? DefaultClockSkewInSeconds : _ref$clockSkew,\n            _ref$userInfoJwtIssue = _ref.userInfoJwtIssuer,\n            userInfoJwtIssuer = _ref$userInfoJwtIssue === undefined ? 'OP' : _ref$userInfoJwtIssue,\n            _ref$stateStore = _ref.stateStore,\n            stateStore = _ref$stateStore === undefined ? new _WebStorageStateStore.WebStorageStateStore() : _ref$stateStore,\n            _ref$ResponseValidato = _ref.ResponseValidatorCtor,\n            ResponseValidatorCtor = _ref$ResponseValidato === undefined ? _ResponseValidator.ResponseValidator : _ref$ResponseValidato,\n            _ref$MetadataServiceC = _ref.MetadataServiceCtor,\n            MetadataServiceCtor = _ref$MetadataServiceC === undefined ? _MetadataService.MetadataService : _ref$MetadataServiceC,\n            _ref$extraQueryParams = _ref.extraQueryParams,\n            extraQueryParams = _ref$extraQueryParams === undefined ? {} : _ref$extraQueryParams,\n            _ref$extraTokenParams = _ref.extraTokenParams,\n            extraTokenParams = _ref$extraTokenParams === undefined ? {} : _ref$extraTokenParams;\n\n        _classCallCheck(this, OidcClientSettings);\n\n        this._authority = authority;\n        this._metadataUrl = metadataUrl;\n        this._metadata = metadata;\n        this._signingKeys = signingKeys;\n\n        this._client_id = client_id;\n        this._client_secret = client_secret;\n        this._response_type = response_type;\n        this._scope = scope;\n        this._redirect_uri = redirect_uri;\n        this._post_logout_redirect_uri = post_logout_redirect_uri;\n\n        this._prompt = prompt;\n        this._display = display;\n        this._max_age = max_age;\n        this._ui_locales = ui_locales;\n        this._acr_values = acr_values;\n        this._resource = resource;\n        this._response_mode = response_mode;\n\n        this._filterProtocolClaims = !!filterProtocolClaims;\n        this._loadUserInfo = !!loadUserInfo;\n        this._staleStateAge = staleStateAge;\n        this._clockSkew = clockSkew;\n        this._userInfoJwtIssuer = userInfoJwtIssuer;\n\n        this._stateStore = stateStore;\n        this._validator = new ResponseValidatorCtor(this);\n        this._metadataService = new MetadataServiceCtor(this);\n\n        this._extraQueryParams = (typeof extraQueryParams === 'undefined' ? 'undefined' : _typeof(extraQueryParams)) === 'object' ? extraQueryParams : {};\n        this._extraTokenParams = (typeof extraTokenParams === 'undefined' ? 'undefined' : _typeof(extraTokenParams)) === 'object' ? extraTokenParams : {};\n    }\n\n    // client config\n\n\n    _createClass(OidcClientSettings, [{\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        },\n        set: function set(value) {\n            if (!this._client_id) {\n                // one-time set only\n                this._client_id = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_client_id: client_id has already been assigned.\");\n                throw new Error(\"client_id has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'response_type',\n        get: function get() {\n            return this._response_type;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'post_logout_redirect_uri',\n        get: function get() {\n            return this._post_logout_redirect_uri;\n        }\n\n        // optional protocol params\n\n    }, {\n        key: 'prompt',\n        get: function get() {\n            return this._prompt;\n        }\n    }, {\n        key: 'display',\n        get: function get() {\n            return this._display;\n        }\n    }, {\n        key: 'max_age',\n        get: function get() {\n            return this._max_age;\n        }\n    }, {\n        key: 'ui_locales',\n        get: function get() {\n            return this._ui_locales;\n        }\n    }, {\n        key: 'acr_values',\n        get: function get() {\n            return this._acr_values;\n        }\n    }, {\n        key: 'resource',\n        get: function get() {\n            return this._resource;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n\n        // metadata\n\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        },\n        set: function set(value) {\n            if (!this._authority) {\n                // one-time set only\n                this._authority = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_authority: authority has already been assigned.\");\n                throw new Error(\"authority has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                this._metadataUrl = this.authority;\n\n                if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                    if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                        this._metadataUrl += '/';\n                    }\n                    this._metadataUrl += OidcMetadataUrlPath;\n                }\n            }\n\n            return this._metadataUrl;\n        }\n\n        // settable/cachable metadata values\n\n    }, {\n        key: 'metadata',\n        get: function get() {\n            return this._metadata;\n        },\n        set: function set(value) {\n            this._metadata = value;\n        }\n    }, {\n        key: 'signingKeys',\n        get: function get() {\n            return this._signingKeys;\n        },\n        set: function set(value) {\n            this._signingKeys = value;\n        }\n\n        // behavior flags\n\n    }, {\n        key: 'filterProtocolClaims',\n        get: function get() {\n            return this._filterProtocolClaims;\n        }\n    }, {\n        key: 'loadUserInfo',\n        get: function get() {\n            return this._loadUserInfo;\n        }\n    }, {\n        key: 'staleStateAge',\n        get: function get() {\n            return this._staleStateAge;\n        }\n    }, {\n        key: 'clockSkew',\n        get: function get() {\n            return this._clockSkew;\n        }\n    }, {\n        key: 'userInfoJwtIssuer',\n        get: function get() {\n            return this._userInfoJwtIssuer;\n        }\n    }, {\n        key: 'stateStore',\n        get: function get() {\n            return this._stateStore;\n        }\n    }, {\n        key: 'validator',\n        get: function get() {\n            return this._validator;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n\n        // extra query params\n\n    }, {\n        key: 'extraQueryParams',\n        get: function get() {\n            return this._extraQueryParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraQueryParams = value;\n            } else {\n                this._extraQueryParams = {};\n            }\n        }\n\n        // extra token params\n\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraTokenParams = value;\n            } else {\n                this._extraTokenParams = {};\n            }\n        }\n    }]);\n\n    return OidcClientSettings;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupNavigator.js\":\n/*!*******************************!*\\\n  !*** ./src/PopupNavigator.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _PopupWindow = __webpack_require__(/*! ./PopupWindow.js */ \"./src/PopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar PopupNavigator = exports.PopupNavigator = function () {\n    function PopupNavigator() {\n        _classCallCheck(this, PopupNavigator);\n    }\n\n    PopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _PopupWindow.PopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    PopupNavigator.prototype.callback = function callback(url, keepOpen, delimiter) {\n        _Log.Log.debug(\"PopupNavigator.callback\");\n\n        try {\n            _PopupWindow.PopupWindow.notifyOpener(url, keepOpen, delimiter);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return PopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupWindow.js\":\n/*!****************************!*\\\n  !*** ./src/PopupWindow.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar CheckForPopupClosedInterval = 500;\nvar DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;';\n//const DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;resizable=yes';\n\nvar DefaultPopupTarget = \"_blank\";\n\nvar PopupWindow = exports.PopupWindow = function () {\n    function PopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, PopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        var target = params.popupWindowTarget || DefaultPopupTarget;\n        var features = params.popupWindowFeatures || DefaultPopupFeatures;\n\n        this._popup = window.open('', target, features);\n        if (this._popup) {\n            _Log.Log.debug(\"PopupWindow.ctor: popup successfully created\");\n            this._checkForPopupClosedTimer = window.setInterval(this._checkForPopupClosed.bind(this), CheckForPopupClosedInterval);\n        }\n    }\n\n    PopupWindow.prototype.navigate = function navigate(params) {\n        if (!this._popup) {\n            this._error(\"PopupWindow.navigate: Error opening popup window\");\n        } else if (!params || !params.url) {\n            this._error(\"PopupWindow.navigate: no url provided\");\n            this._error(\"No url provided\");\n        } else {\n            _Log.Log.debug(\"PopupWindow.navigate: Setting URL in popup\");\n\n            this._id = params.id;\n            if (this._id) {\n                window[\"popupCallback_\" + params.id] = this._callback.bind(this);\n            }\n\n            this._popup.focus();\n            this._popup.window.location = params.url;\n        }\n\n        return this.promise;\n    };\n\n    PopupWindow.prototype._success = function _success(data) {\n        _Log.Log.debug(\"PopupWindow.callback: Successful response from popup window\");\n\n        this._cleanup();\n        this._resolve(data);\n    };\n\n    PopupWindow.prototype._error = function _error(message) {\n        _Log.Log.error(\"PopupWindow.error: \", message);\n\n        this._cleanup();\n        this._reject(new Error(message));\n    };\n\n    PopupWindow.prototype.close = function close() {\n        this._cleanup(false);\n    };\n\n    PopupWindow.prototype._cleanup = function _cleanup(keepOpen) {\n        _Log.Log.debug(\"PopupWindow.cleanup\");\n\n        window.clearInterval(this._checkForPopupClosedTimer);\n        this._checkForPopupClosedTimer = null;\n\n        delete window[\"popupCallback_\" + this._id];\n\n        if (this._popup && !keepOpen) {\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    PopupWindow.prototype._checkForPopupClosed = function _checkForPopupClosed() {\n        if (!this._popup || this._popup.closed) {\n            this._error(\"Popup window closed\");\n        }\n    };\n\n    PopupWindow.prototype._callback = function _callback(url, keepOpen) {\n        this._cleanup(keepOpen);\n\n        if (url) {\n            _Log.Log.debug(\"PopupWindow.callback success\");\n            this._success({ url: url });\n        } else {\n            _Log.Log.debug(\"PopupWindow.callback: Invalid response from popup\");\n            this._error(\"Invalid response from popup\");\n        }\n    };\n\n    PopupWindow.notifyOpener = function notifyOpener(url, keepOpen, delimiter) {\n        if (window.opener) {\n            url = url || window.location.href;\n            if (url) {\n                var data = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n                if (data.state) {\n                    var name = \"popupCallback_\" + data.state;\n                    var callback = window.opener[name];\n                    if (callback) {\n                        _Log.Log.debug(\"PopupWindow.notifyOpener: passing url message to opener\");\n                        callback(url, keepOpen);\n                    } else {\n                        _Log.Log.warn(\"PopupWindow.notifyOpener: no matching callback found on opener\");\n                    }\n                } else {\n                    _Log.Log.warn(\"PopupWindow.notifyOpener: no state found in response url\");\n                }\n            }\n        } else {\n            _Log.Log.warn(\"PopupWindow.notifyOpener: no window.opener. Can't complete notification.\");\n        }\n    };\n\n    _createClass(PopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return PopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/RedirectNavigator.js\":\n/*!**********************************!*\\\n  !*** ./src/RedirectNavigator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.RedirectNavigator = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar RedirectNavigator = exports.RedirectNavigator = function () {\n    function RedirectNavigator() {\n        _classCallCheck(this, RedirectNavigator);\n    }\n\n    RedirectNavigator.prototype.prepare = function prepare() {\n        return Promise.resolve(this);\n    };\n\n    RedirectNavigator.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            _Log.Log.error(\"RedirectNavigator.navigate: No url provided\");\n            return Promise.reject(new Error(\"No url provided\"));\n        }\n\n        if (params.useReplaceToNavigate) {\n            window.location.replace(params.url);\n        } else {\n            window.location = params.url;\n        }\n\n        return Promise.resolve();\n    };\n\n    _createClass(RedirectNavigator, [{\n        key: \"url\",\n        get: function get() {\n            return window.location.href;\n        }\n    }]);\n\n    return RedirectNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/ResponseValidator.js\":\n/*!**********************************!*\\\n  !*** ./src/ResponseValidator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.ResponseValidator = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _UserInfoService = __webpack_require__(/*! ./UserInfoService.js */ \"./src/UserInfoService.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ProtocolClaims = [\"nonce\", \"at_hash\", \"iat\", \"nbf\", \"exp\", \"aud\", \"iss\", \"c_hash\"];\n\nvar ResponseValidator = exports.ResponseValidator = function () {\n    function ResponseValidator(settings) {\n        var MetadataServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _MetadataService.MetadataService;\n        var UserInfoServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _UserInfoService.UserInfoService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n\n        _classCallCheck(this, ResponseValidator);\n\n        if (!settings) {\n            _Log.Log.error(\"ResponseValidator.ctor: No settings passed to ResponseValidator\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._userInfoService = new UserInfoServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n        this._tokenClient = new TokenClientCtor(this._settings);\n    }\n\n    ResponseValidator.prototype.validateSigninResponse = function validateSigninResponse(state, response) {\n        var _this = this;\n\n        _Log.Log.debug(\"ResponseValidator.validateSigninResponse\");\n\n        return this._processSigninParams(state, response).then(function (response) {\n            _Log.Log.debug(\"ResponseValidator.validateSigninResponse: state processed\");\n            return _this._validateTokens(state, response).then(function (response) {\n                _Log.Log.debug(\"ResponseValidator.validateSigninResponse: tokens validated\");\n                return _this._processClaims(state, response).then(function (response) {\n                    _Log.Log.debug(\"ResponseValidator.validateSigninResponse: claims processed\");\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype.validateSignoutResponse = function validateSignoutResponse(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator.validateSignoutResponse: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator.validateSignoutResponse: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator.validateSignoutResponse: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processSigninParams = function _processSigninParams(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        if (!state.client_id) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No client_id on state\");\n            return Promise.reject(new Error(\"No client_id on state\"));\n        }\n\n        if (!state.authority) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No authority on state\");\n            return Promise.reject(new Error(\"No authority on state\"));\n        }\n\n        // this allows the authority to be loaded from the signin state\n        if (!this._settings.authority) {\n            this._settings.authority = state.authority;\n        }\n        // ensure we're using the correct authority if the authority is not loaded from signin state\n        else if (this._settings.authority && this._settings.authority !== state.authority) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: authority mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"authority mismatch on settings vs. signin state\"));\n            }\n        // this allows the client_id to be loaded from the signin state\n        if (!this._settings.client_id) {\n            this._settings.client_id = state.client_id;\n        }\n        // ensure we're using the correct client_id if the client_id is not loaded from signin state\n        else if (this._settings.client_id && this._settings.client_id !== state.client_id) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: client_id mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"client_id mismatch on settings vs. signin state\"));\n            }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator._processSigninParams: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator._processSigninParams: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        if (state.nonce && !response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting id_token in response\");\n            return Promise.reject(new Error(\"No id_token in response\"));\n        }\n\n        if (!state.nonce && response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting id_token in response\");\n            return Promise.reject(new Error(\"Unexpected id_token in response\"));\n        }\n\n        if (state.code_verifier && !response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting code in response\");\n            return Promise.reject(new Error(\"No code in response\"));\n        }\n\n        if (!state.code_verifier && response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting code in response\");\n            return Promise.reject(new Error(\"Unexpected code in response\"));\n        }\n\n        if (!response.scope) {\n            // if there's no scope on the response, then assume all scopes granted (per-spec) and copy over scopes from original request\n            response.scope = state.scope;\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processClaims = function _processClaims(state, response) {\n        var _this2 = this;\n\n        if (response.isOpenIdConnect) {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is OIDC, processing claims\");\n\n            response.profile = this._filterProtocolClaims(response.profile);\n\n            if (state.skipUserInfo !== true && this._settings.loadUserInfo && response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._processClaims: loading user info\");\n\n                return this._userInfoService.getClaims(response.access_token).then(function (claims) {\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received from user info endpoint\");\n\n                    if (claims.sub !== response.profile.sub) {\n                        _Log.Log.error(\"ResponseValidator._processClaims: sub from user info endpoint does not match sub in access_token\");\n                        return Promise.reject(new Error(\"sub from user info endpoint does not match sub in access_token\"));\n                    }\n\n                    response.profile = _this2._mergeClaims(response.profile, claims);\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received, updated profile:\", response.profile);\n\n                    return response;\n                });\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processClaims: not loading user info\");\n            }\n        } else {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is not OIDC, not processing claims\");\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._mergeClaims = function _mergeClaims(claims1, claims2) {\n        var result = Object.assign({}, claims1);\n\n        for (var name in claims2) {\n            var values = claims2[name];\n            if (!Array.isArray(values)) {\n                values = [values];\n            }\n\n            for (var i = 0; i < values.length; i++) {\n                var value = values[i];\n                if (!result[name]) {\n                    result[name] = value;\n                } else if (Array.isArray(result[name])) {\n                    if (result[name].indexOf(value) < 0) {\n                        result[name].push(value);\n                    }\n                } else if (result[name] !== value) {\n                    if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                        result[name] = this._mergeClaims(result[name], value);\n                    } else {\n                        result[name] = [result[name], value];\n                    }\n                }\n            }\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._filterProtocolClaims = function _filterProtocolClaims(claims) {\n        _Log.Log.debug(\"ResponseValidator._filterProtocolClaims, incoming claims:\", claims);\n\n        var result = Object.assign({}, claims);\n\n        if (this._settings._filterProtocolClaims) {\n            ProtocolClaims.forEach(function (type) {\n                delete result[type];\n            });\n\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims filtered\", result);\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims not filtered\");\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._validateTokens = function _validateTokens(state, response) {\n        if (response.code) {\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating code\");\n            return this._processCode(state, response);\n        }\n\n        if (response.id_token) {\n            if (response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token and access_token\");\n                return this._validateIdTokenAndAccessToken(state, response);\n            }\n\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token\");\n            return this._validateIdToken(state, response);\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateTokens: No code to process or id_token to validate\");\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processCode = function _processCode(state, response) {\n        var _this3 = this;\n\n        var request = {\n            client_id: state.client_id,\n            client_secret: state.client_secret,\n            code: response.code,\n            redirect_uri: state.redirect_uri,\n            code_verifier: state.code_verifier\n        };\n\n        if (state.extraTokenParams && _typeof(state.extraTokenParams) === 'object') {\n            Object.assign(request, state.extraTokenParams);\n        }\n\n        return this._tokenClient.exchangeCode(request).then(function (tokenResponse) {\n\n            for (var key in tokenResponse) {\n                response[key] = tokenResponse[key];\n            }\n\n            if (response.id_token) {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, processing id_token\");\n                return _this3._validateIdTokenAttributes(state, response);\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, returning response\");\n            }\n\n            return response;\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAttributes = function _validateIdTokenAttributes(state, response) {\n        var _this4 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n\n            var audience = state.client_id;\n            var clockSkewInSeconds = _this4._settings.clockSkew;\n            _Log.Log.debug(\"ResponseValidator._validateIdTokenAttributes: Validaing JWT attributes; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n            return _this4._joseUtil.validateJwtAttributes(response.id_token, issuer, audience, clockSkewInSeconds).then(function (payload) {\n\n                if (state.nonce && state.nonce !== payload.nonce) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: Invalid nonce in id_token\");\n                    return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n                }\n\n                if (!payload.sub) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: No sub present in id_token\");\n                    return Promise.reject(new Error(\"No sub present in id_token\"));\n                }\n\n                response.profile = payload;\n                return response;\n            });\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAndAccessToken = function _validateIdTokenAndAccessToken(state, response) {\n        var _this5 = this;\n\n        return this._validateIdToken(state, response).then(function (response) {\n            return _this5._validateAccessToken(response);\n        });\n    };\n\n    ResponseValidator.prototype._validateIdToken = function _validateIdToken(state, response) {\n        var _this6 = this;\n\n        if (!state.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: No nonce on state\");\n            return Promise.reject(new Error(\"No nonce on state\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header || !jwt.payload) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        if (state.nonce !== jwt.payload.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Invalid nonce in id_token\");\n            return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n        }\n\n        var kid = jwt.header.kid;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            _Log.Log.debug(\"ResponseValidator._validateIdToken: Received issuer\");\n\n            return _this6._metadataService.getSigningKeys().then(function (keys) {\n                if (!keys) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No signing keys from metadata\");\n                    return Promise.reject(new Error(\"No signing keys from metadata\"));\n                }\n\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Received signing keys\");\n                var key = void 0;\n                if (!kid) {\n                    keys = _this6._filterByAlg(keys, jwt.header.alg);\n\n                    if (keys.length > 1) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No kid found in id_token and more than one key found in metadata\");\n                        return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                    } else {\n                        // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                        // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                        key = keys[0];\n                    }\n                } else {\n                    key = keys.filter(function (key) {\n                        return key.kid === kid;\n                    })[0];\n                }\n\n                if (!key) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No key matching kid or alg found in signing keys\");\n                    return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                }\n\n                var audience = state.client_id;\n\n                var clockSkewInSeconds = _this6._settings.clockSkew;\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                return _this6._joseUtil.validateJwt(response.id_token, key, issuer, audience, clockSkewInSeconds).then(function () {\n                    _Log.Log.debug(\"ResponseValidator._validateIdToken: JWT validation successful\");\n\n                    if (!jwt.payload.sub) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No sub present in id_token\");\n                        return Promise.reject(new Error(\"No sub present in id_token\"));\n                    }\n\n                    response.profile = jwt.payload;\n\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    ResponseValidator.prototype._validateAccessToken = function _validateAccessToken(response) {\n        if (!response.profile) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No profile loaded from id_token\");\n            return Promise.reject(new Error(\"No profile loaded from id_token\"));\n        }\n\n        if (!response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No at_hash in id_token\");\n            return Promise.reject(new Error(\"No at_hash in id_token\"));\n        }\n\n        if (!response.id_token) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No id_token\");\n            return Promise.reject(new Error(\"No id_token\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        var hashAlg = jwt.header.alg;\n        if (!hashAlg || hashAlg.length !== 5) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var hashBits = hashAlg.substr(2, 3);\n        if (!hashBits) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        hashBits = parseInt(hashBits);\n        if (hashBits !== 256 && hashBits !== 384 && hashBits !== 512) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var sha = \"sha\" + hashBits;\n        var hash = this._joseUtil.hashString(response.access_token, sha);\n        if (!hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: access_token hash failed:\", sha);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        var left = hash.substr(0, hash.length / 2);\n        var left_b64u = this._joseUtil.hexToBase64Url(left);\n        if (left_b64u !== response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to validate at_hash\", left_b64u, response.profile.at_hash);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateAccessToken: success\");\n\n        return Promise.resolve(response);\n    };\n\n    return ResponseValidator;\n}();\n\n/***/ }),\n\n/***/ \"./src/SessionMonitor.js\":\n/*!*******************************!*\\\n  !*** ./src/SessionMonitor.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SessionMonitor = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar SessionMonitor = exports.SessionMonitor = function () {\n    function SessionMonitor(userManager) {\n        var _this = this;\n\n        var CheckSessionIFrameCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _CheckSessionIFrame.CheckSessionIFrame;\n        var timer = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global.timer;\n\n        _classCallCheck(this, SessionMonitor);\n\n        if (!userManager) {\n            _Log.Log.error(\"SessionMonitor.ctor: No user manager passed to SessionMonitor\");\n            throw new Error(\"userManager\");\n        }\n\n        this._userManager = userManager;\n        this._CheckSessionIFrameCtor = CheckSessionIFrameCtor;\n        this._timer = timer;\n\n        this._userManager.events.addUserLoaded(this._start.bind(this));\n        this._userManager.events.addUserUnloaded(this._stop.bind(this));\n\n        this._userManager.getUser().then(function (user) {\n            // doing this manually here since calling getUser \n            // doesn't trigger load event.\n            if (user) {\n                _this._start(user);\n            } else if (_this._settings.monitorAnonymousSession) {\n                _this._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a ctor\n                    _Log.Log.error(\"SessionMonitor ctor: error from querySessionStatus:\", err.message);\n                });\n            }\n        }).catch(function (err) {\n            // catch to suppress errors since we're in a ctor\n            _Log.Log.error(\"SessionMonitor ctor: error from getUser:\", err.message);\n        });\n    }\n\n    SessionMonitor.prototype._start = function _start(user) {\n        var _this2 = this;\n\n        var session_state = user.session_state;\n\n        if (session_state) {\n            if (user.profile) {\n                this._sub = user.profile.sub;\n                this._sid = user.profile.sid;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", sub:\", this._sub);\n            } else {\n                this._sub = undefined;\n                this._sid = undefined;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", anonymous user\");\n            }\n\n            if (!this._checkSessionIFrame) {\n                this._metadataService.getCheckSessionIframe().then(function (url) {\n                    if (url) {\n                        _Log.Log.debug(\"SessionMonitor._start: Initializing check session iframe\");\n\n                        var client_id = _this2._client_id;\n                        var interval = _this2._checkSessionInterval;\n                        var stopOnError = _this2._stopCheckSessionOnError;\n\n                        _this2._checkSessionIFrame = new _this2._CheckSessionIFrameCtor(_this2._callback.bind(_this2), client_id, url, interval, stopOnError);\n                        _this2._checkSessionIFrame.load().then(function () {\n                            _this2._checkSessionIFrame.start(session_state);\n                        });\n                    } else {\n                        _Log.Log.warn(\"SessionMonitor._start: No check session iframe found in the metadata\");\n                    }\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in non-promise callback\n                    _Log.Log.error(\"SessionMonitor._start: Error from getCheckSessionIframe:\", err.message);\n                });\n            } else {\n                this._checkSessionIFrame.start(session_state);\n            }\n        }\n    };\n\n    SessionMonitor.prototype._stop = function _stop() {\n        var _this3 = this;\n\n        this._sub = undefined;\n        this._sid = undefined;\n\n        if (this._checkSessionIFrame) {\n            _Log.Log.debug(\"SessionMonitor._stop\");\n            this._checkSessionIFrame.stop();\n        }\n\n        if (this._settings.monitorAnonymousSession) {\n            // using a timer to delay re-initialization to avoid race conditions during signout\n            var timerHandle = this._timer.setInterval(function () {\n                _this3._timer.clearInterval(timerHandle);\n\n                _this3._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this3._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a callback\n                    _Log.Log.error(\"SessionMonitor: error from querySessionStatus:\", err.message);\n                });\n            }, 1000);\n        }\n    };\n\n    SessionMonitor.prototype._callback = function _callback() {\n        var _this4 = this;\n\n        this._userManager.querySessionStatus().then(function (session) {\n            var raiseEvent = true;\n\n            if (session) {\n                if (session.sub === _this4._sub) {\n                    raiseEvent = false;\n                    _this4._checkSessionIFrame.start(session.session_state);\n\n                    if (session.sid === _this4._sid) {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:\", session.session_state);\n                    } else {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:\", session.session_state);\n                        _this4._userManager.events._raiseUserSessionChanged();\n                    }\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: Different subject signed into OP:\", session.sub);\n                }\n            } else {\n                _Log.Log.debug(\"SessionMonitor._callback: Subject no longer signed into OP\");\n            }\n\n            if (raiseEvent) {\n                if (_this4._sub) {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed out event\");\n                    _this4._userManager.events._raiseUserSignedOut();\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed in event\");\n                    _this4._userManager.events._raiseUserSignedIn();\n                }\n            }\n        }).catch(function (err) {\n            if (_this4._sub) {\n                _Log.Log.debug(\"SessionMonitor._callback: Error calling queryCurrentSigninSession; raising signed out event\", err.message);\n                _this4._userManager.events._raiseUserSignedOut();\n            }\n        });\n    };\n\n    _createClass(SessionMonitor, [{\n        key: '_settings',\n        get: function get() {\n            return this._userManager.settings;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this._userManager.metadataService;\n        }\n    }, {\n        key: '_client_id',\n        get: function get() {\n            return this._settings.client_id;\n        }\n    }, {\n        key: '_checkSessionInterval',\n        get: function get() {\n            return this._settings.checkSessionInterval;\n        }\n    }, {\n        key: '_stopCheckSessionOnError',\n        get: function get() {\n            return this._settings.stopCheckSessionOnError;\n        }\n    }]);\n\n    return SessionMonitor;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninRequest.js\":\n/*!******************************!*\\\n  !*** ./src/SigninRequest.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninRequest = exports.SigninRequest = function () {\n    function SigninRequest(_ref) {\n        var url = _ref.url,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            authority = _ref.authority,\n            data = _ref.data,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            extraQueryParams = _ref.extraQueryParams,\n            request_type = _ref.request_type,\n            client_secret = _ref.client_secret,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninRequest);\n\n        if (!url) {\n            _Log.Log.error(\"SigninRequest.ctor: No url passed\");\n            throw new Error(\"url\");\n        }\n        if (!client_id) {\n            _Log.Log.error(\"SigninRequest.ctor: No client_id passed\");\n            throw new Error(\"client_id\");\n        }\n        if (!redirect_uri) {\n            _Log.Log.error(\"SigninRequest.ctor: No redirect_uri passed\");\n            throw new Error(\"redirect_uri\");\n        }\n        if (!response_type) {\n            _Log.Log.error(\"SigninRequest.ctor: No response_type passed\");\n            throw new Error(\"response_type\");\n        }\n        if (!scope) {\n            _Log.Log.error(\"SigninRequest.ctor: No scope passed\");\n            throw new Error(\"scope\");\n        }\n        if (!authority) {\n            _Log.Log.error(\"SigninRequest.ctor: No authority passed\");\n            throw new Error(\"authority\");\n        }\n\n        var oidc = SigninRequest.isOidc(response_type);\n        var code = SigninRequest.isCode(response_type);\n\n        if (!response_mode) {\n            response_mode = SigninRequest.isCode(response_type) ? \"query\" : null;\n        }\n\n        this.state = new _SigninState.SigninState({ nonce: oidc,\n            data: data, client_id: client_id, authority: authority, redirect_uri: redirect_uri,\n            code_verifier: code,\n            request_type: request_type, response_mode: response_mode,\n            client_secret: client_secret, scope: scope, extraTokenParams: extraTokenParams, skipUserInfo: skipUserInfo });\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"client_id\", client_id);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"redirect_uri\", redirect_uri);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"response_type\", response_type);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"scope\", scope);\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        if (oidc) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"nonce\", this.state.nonce);\n        }\n        if (code) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge\", this.state.code_challenge);\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge_method\", \"S256\");\n        }\n\n        var optional = { prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values, resource: resource, request: request, request_uri: request_uri, response_mode: response_mode };\n        for (var key in optional) {\n            if (optional[key]) {\n                url = _UrlUtility.UrlUtility.addQueryParam(url, key, optional[key]);\n            }\n        }\n\n        for (var _key in extraQueryParams) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, _key, extraQueryParams[_key]);\n        }\n\n        this.url = url;\n    }\n\n    SigninRequest.isOidc = function isOidc(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"id_token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isOAuth = function isOAuth(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isCode = function isCode(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"code\";\n        });\n        return !!result[0];\n    };\n\n    return SigninRequest;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninResponse.js\":\n/*!*******************************!*\\\n  !*** ./src/SigninResponse.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninResponse = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcScope = \"openid\";\n\nvar SigninResponse = exports.SigninResponse = function () {\n    function SigninResponse(url) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n\n        _classCallCheck(this, SigninResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.code = values.code;\n        this.state = values.state;\n        this.id_token = values.id_token;\n        this.session_state = values.session_state;\n        this.access_token = values.access_token;\n        this.token_type = values.token_type;\n        this.scope = values.scope;\n        this.profile = undefined; // will be set from ResponseValidator\n\n        this.expires_in = values.expires_in;\n    }\n\n    _createClass(SigninResponse, [{\n        key: \"expires_in\",\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: \"expired\",\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: \"scopes\",\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }, {\n        key: \"isOpenIdConnect\",\n        get: function get() {\n            return this.scopes.indexOf(OidcScope) >= 0 || !!this.id_token;\n        }\n    }]);\n\n    return SigninResponse;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninState.js\":\n/*!****************************!*\\\n  !*** ./src/SigninState.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninState = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _State2 = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninState = exports.SigninState = function (_State) {\n    _inherits(SigninState, _State);\n\n    function SigninState() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            nonce = _ref.nonce,\n            authority = _ref.authority,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            code_verifier = _ref.code_verifier,\n            response_mode = _ref.response_mode,\n            client_secret = _ref.client_secret,\n            scope = _ref.scope,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninState);\n\n        var _this = _possibleConstructorReturn(this, _State.call(this, arguments[0]));\n\n        if (nonce === true) {\n            _this._nonce = (0, _random2.default)();\n        } else if (nonce) {\n            _this._nonce = nonce;\n        }\n\n        if (code_verifier === true) {\n            // random() produces 32 length\n            _this._code_verifier = (0, _random2.default)() + (0, _random2.default)() + (0, _random2.default)();\n        } else if (code_verifier) {\n            _this._code_verifier = code_verifier;\n        }\n\n        if (_this.code_verifier) {\n            var hash = _JoseUtil.JoseUtil.hashString(_this.code_verifier, \"SHA256\");\n            _this._code_challenge = _JoseUtil.JoseUtil.hexToBase64Url(hash);\n        }\n\n        _this._redirect_uri = redirect_uri;\n        _this._authority = authority;\n        _this._client_id = client_id;\n        _this._response_mode = response_mode;\n        _this._client_secret = client_secret;\n        _this._scope = scope;\n        _this._extraTokenParams = extraTokenParams;\n        _this._skipUserInfo = skipUserInfo;\n        return _this;\n    }\n\n    SigninState.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"SigninState.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type,\n            nonce: this.nonce,\n            code_verifier: this.code_verifier,\n            redirect_uri: this.redirect_uri,\n            authority: this.authority,\n            client_id: this.client_id,\n            response_mode: this.response_mode,\n            client_secret: this.client_secret,\n            scope: this.scope,\n            extraTokenParams: this.extraTokenParams,\n            skipUserInfo: this.skipUserInfo\n        });\n    };\n\n    SigninState.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"SigninState.fromStorageString\");\n        var data = JSON.parse(storageString);\n        return new SigninState(data);\n    };\n\n    _createClass(SigninState, [{\n        key: 'nonce',\n        get: function get() {\n            return this._nonce;\n        }\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        }\n    }, {\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'code_verifier',\n        get: function get() {\n            return this._code_verifier;\n        }\n    }, {\n        key: 'code_challenge',\n        get: function get() {\n            return this._code_challenge;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        }\n    }, {\n        key: 'skipUserInfo',\n        get: function get() {\n            return this._skipUserInfo;\n        }\n    }]);\n\n    return SigninState;\n}(_State2.State);\n\n/***/ }),\n\n/***/ \"./src/SignoutRequest.js\":\n/*!*******************************!*\\\n  !*** ./src/SignoutRequest.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SignoutRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutRequest = exports.SignoutRequest = function SignoutRequest(_ref) {\n    var url = _ref.url,\n        id_token_hint = _ref.id_token_hint,\n        post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n        data = _ref.data,\n        extraQueryParams = _ref.extraQueryParams,\n        request_type = _ref.request_type;\n\n    _classCallCheck(this, SignoutRequest);\n\n    if (!url) {\n        _Log.Log.error(\"SignoutRequest.ctor: No url passed\");\n        throw new Error(\"url\");\n    }\n\n    if (id_token_hint) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"id_token_hint\", id_token_hint);\n    }\n\n    if (post_logout_redirect_uri) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"post_logout_redirect_uri\", post_logout_redirect_uri);\n\n        if (data) {\n            this.state = new _State.State({ data: data, request_type: request_type });\n\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        }\n    }\n\n    for (var key in extraQueryParams) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, key, extraQueryParams[key]);\n    }\n\n    this.url = url;\n};\n\n/***/ }),\n\n/***/ \"./src/SignoutResponse.js\":\n/*!********************************!*\\\n  !*** ./src/SignoutResponse.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.SignoutResponse = undefined;\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutResponse = exports.SignoutResponse = function SignoutResponse(url) {\n        _classCallCheck(this, SignoutResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, \"?\");\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.state = values.state;\n};\n\n/***/ }),\n\n/***/ \"./src/SilentRenewService.js\":\n/*!***********************************!*\\\n  !*** ./src/SilentRenewService.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SilentRenewService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SilentRenewService = exports.SilentRenewService = function () {\n    function SilentRenewService(userManager) {\n        _classCallCheck(this, SilentRenewService);\n\n        this._userManager = userManager;\n    }\n\n    SilentRenewService.prototype.start = function start() {\n        if (!this._callback) {\n            this._callback = this._tokenExpiring.bind(this);\n            this._userManager.events.addAccessTokenExpiring(this._callback);\n\n            // this will trigger loading of the user so the expiring events can be initialized\n            this._userManager.getUser().then(function (user) {\n                // deliberate nop\n            }).catch(function (err) {\n                // catch to suppress errors since we're in a ctor\n                _Log.Log.error(\"SilentRenewService.start: Error from getUser:\", err.message);\n            });\n        }\n    };\n\n    SilentRenewService.prototype.stop = function stop() {\n        if (this._callback) {\n            this._userManager.events.removeAccessTokenExpiring(this._callback);\n            delete this._callback;\n        }\n    };\n\n    SilentRenewService.prototype._tokenExpiring = function _tokenExpiring() {\n        var _this = this;\n\n        this._userManager.signinSilent().then(function (user) {\n            _Log.Log.debug(\"SilentRenewService._tokenExpiring: Silent token renewal successful\");\n        }, function (err) {\n            _Log.Log.error(\"SilentRenewService._tokenExpiring: Error from signinSilent:\", err.message);\n            _this._userManager.events._raiseSilentRenewError(err);\n        });\n    };\n\n    return SilentRenewService;\n}();\n\n/***/ }),\n\n/***/ \"./src/State.js\":\n/*!**********************!*\\\n  !*** ./src/State.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.State = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar State = exports.State = function () {\n    function State() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id = _ref.id,\n            data = _ref.data,\n            created = _ref.created,\n            request_type = _ref.request_type;\n\n        _classCallCheck(this, State);\n\n        this._id = id || (0, _random2.default)();\n        this._data = data;\n\n        if (typeof created === 'number' && created > 0) {\n            this._created = created;\n        } else {\n            this._created = parseInt(Date.now() / 1000);\n        }\n        this._request_type = request_type;\n    }\n\n    State.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"State.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type\n        });\n    };\n\n    State.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"State.fromStorageString\");\n        return new State(JSON.parse(storageString));\n    };\n\n    State.clearStaleState = function clearStaleState(storage, age) {\n\n        var cutoff = Date.now() / 1000 - age;\n\n        return storage.getAllKeys().then(function (keys) {\n            _Log.Log.debug(\"State.clearStaleState: got keys\", keys);\n\n            var promises = [];\n\n            var _loop = function _loop(i) {\n                var key = keys[i];\n                p = storage.get(key).then(function (item) {\n                    var remove = false;\n\n                    if (item) {\n                        try {\n                            var state = State.fromStorageString(item);\n\n                            _Log.Log.debug(\"State.clearStaleState: got item from key: \", key, state.created);\n\n                            if (state.created <= cutoff) {\n                                remove = true;\n                            }\n                        } catch (e) {\n                            _Log.Log.error(\"State.clearStaleState: Error parsing state for key\", key, e.message);\n                            remove = true;\n                        }\n                    } else {\n                        _Log.Log.debug(\"State.clearStaleState: no item in storage for key: \", key);\n                        remove = true;\n                    }\n\n                    if (remove) {\n                        _Log.Log.debug(\"State.clearStaleState: removed item for key: \", key);\n                        return storage.remove(key);\n                    }\n                });\n\n\n                promises.push(p);\n            };\n\n            for (var i = 0; i < keys.length; i++) {\n                var p;\n\n                _loop(i);\n            }\n\n            _Log.Log.debug(\"State.clearStaleState: waiting on promise count:\", promises.length);\n            return Promise.all(promises);\n        });\n    };\n\n    _createClass(State, [{\n        key: 'id',\n        get: function get() {\n            return this._id;\n        }\n    }, {\n        key: 'data',\n        get: function get() {\n            return this._data;\n        }\n    }, {\n        key: 'created',\n        get: function get() {\n            return this._created;\n        }\n    }, {\n        key: 'request_type',\n        get: function get() {\n            return this._request_type;\n        }\n    }]);\n\n    return State;\n}();\n\n/***/ }),\n\n/***/ \"./src/Timer.js\":\n/*!**********************!*\\\n  !*** ./src/Timer.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Timer = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _Event2 = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TimerDuration = 5; // seconds\n\nvar Timer = exports.Timer = function (_Event) {\n    _inherits(Timer, _Event);\n\n    function Timer(name) {\n        var timer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.timer;\n        var nowFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n\n        _classCallCheck(this, Timer);\n\n        var _this = _possibleConstructorReturn(this, _Event.call(this, name));\n\n        _this._timer = timer;\n\n        if (nowFunc) {\n            _this._nowFunc = nowFunc;\n        } else {\n            _this._nowFunc = function () {\n                return Date.now() / 1000;\n            };\n        }\n        return _this;\n    }\n\n    Timer.prototype.init = function init(duration) {\n        if (duration <= 0) {\n            duration = 1;\n        }\n        duration = parseInt(duration);\n\n        var expiration = this.now + duration;\n        if (this.expiration === expiration && this._timerHandle) {\n            // no need to reinitialize to same expiration, so bail out\n            _Log.Log.debug(\"Timer.init timer \" + this._name + \" skipping initialization since already initialized for expiration:\", this.expiration);\n            return;\n        }\n\n        this.cancel();\n\n        _Log.Log.debug(\"Timer.init timer \" + this._name + \" for duration:\", duration);\n        this._expiration = expiration;\n\n        // we're using a fairly short timer and then checking the expiration in the\n        // callback to handle scenarios where the browser device sleeps, and then\n        // the timers end up getting delayed.\n        var timerDuration = TimerDuration;\n        if (duration < timerDuration) {\n            timerDuration = duration;\n        }\n        this._timerHandle = this._timer.setInterval(this._callback.bind(this), timerDuration * 1000);\n    };\n\n    Timer.prototype.cancel = function cancel() {\n        if (this._timerHandle) {\n            _Log.Log.debug(\"Timer.cancel: \", this._name);\n            this._timer.clearInterval(this._timerHandle);\n            this._timerHandle = null;\n        }\n    };\n\n    Timer.prototype._callback = function _callback() {\n        var diff = this._expiration - this.now;\n        _Log.Log.debug(\"Timer.callback; \" + this._name + \" timer expires in:\", diff);\n\n        if (this._expiration <= this.now) {\n            this.cancel();\n            _Event.prototype.raise.call(this);\n        }\n    };\n\n    _createClass(Timer, [{\n        key: 'now',\n        get: function get() {\n            return parseInt(this._nowFunc());\n        }\n    }, {\n        key: 'expiration',\n        get: function get() {\n            return this._expiration;\n        }\n    }]);\n\n    return Timer;\n}(_Event2.Event);\n\n/***/ }),\n\n/***/ \"./src/TokenClient.js\":\n/*!****************************!*\\\n  !*** ./src/TokenClient.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenClient = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TokenClient = exports.TokenClient = function () {\n    function TokenClient(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenClient.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor();\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenClient.prototype.exchangeCode = function exchangeCode() {\n        var _this = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"authorization_code\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.redirect_uri = args.redirect_uri || this._settings.redirect_uri;\n\n        if (!args.code) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code passed\");\n            return Promise.reject(new Error(\"A code is required\"));\n        }\n        if (!args.redirect_uri) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No redirect_uri passed\");\n            return Promise.reject(new Error(\"A redirect_uri is required\"));\n        }\n        if (!args.code_verifier) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code_verifier passed\");\n            return Promise.reject(new Error(\"A code_verifier is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeCode: Received token endpoint\");\n\n            return _this._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeCode: response received\");\n                return response;\n            });\n        });\n    };\n\n    TokenClient.prototype.exchangeRefreshToken = function exchangeRefreshToken() {\n        var _this2 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"refresh_token\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.client_secret = args.client_secret || this._settings.client_secret;\n\n        if (!args.refresh_token) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No refresh_token passed\");\n            return Promise.reject(new Error(\"A refresh_token is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeRefreshToken: Received token endpoint\");\n\n            return _this2._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeRefreshToken: response received\");\n                return response;\n            });\n        });\n    };\n\n    return TokenClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/TokenRevocationClient.js\":\n/*!**************************************!*\\\n  !*** ./src/TokenRevocationClient.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenRevocationClient = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar AccessTokenTypeHint = \"access_token\";\nvar RefreshTokenTypeHint = \"refresh_token\";\n\nvar TokenRevocationClient = exports.TokenRevocationClient = function () {\n    function TokenRevocationClient(settings) {\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenRevocationClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenRevocationClient.ctor: No settings provided\");\n            throw new Error(\"No settings provided.\");\n        }\n\n        this._settings = settings;\n        this._XMLHttpRequestCtor = XMLHttpRequestCtor;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenRevocationClient.prototype.revoke = function revoke(token, required) {\n        var _this = this;\n\n        var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : \"access_token\";\n\n        if (!token) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: No token provided\");\n            throw new Error(\"No token provided.\");\n        }\n\n        if (type !== AccessTokenTypeHint && type != RefreshTokenTypeHint) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: Invalid token type\");\n            throw new Error(\"Invalid token type.\");\n        }\n\n        return this._metadataService.getRevocationEndpoint().then(function (url) {\n            if (!url) {\n                if (required) {\n                    _Log.Log.error(\"TokenRevocationClient.revoke: Revocation not supported\");\n                    throw new Error(\"Revocation not supported\");\n                }\n\n                // not required, so don't error and just return\n                return;\n            }\n\n            _Log.Log.debug(\"TokenRevocationClient.revoke: Revoking \" + type);\n            var client_id = _this._settings.client_id;\n            var client_secret = _this._settings.client_secret;\n            return _this._revoke(url, client_id, client_secret, token, type);\n        });\n    };\n\n    TokenRevocationClient.prototype._revoke = function _revoke(url, client_id, client_secret, token, type) {\n        var _this2 = this;\n\n        return new Promise(function (resolve, reject) {\n\n            var xhr = new _this2._XMLHttpRequestCtor();\n            xhr.open(\"POST\", url);\n\n            xhr.onload = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: HTTP response received, status\", xhr.status);\n\n                if (xhr.status === 200) {\n                    resolve();\n                } else {\n                    reject(Error(xhr.statusText + \" (\" + xhr.status + \")\"));\n                }\n            };\n            xhr.onerror = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: Network Error.\");\n                reject(\"Network Error\");\n            };\n\n            var body = \"client_id=\" + encodeURIComponent(client_id);\n            if (client_secret) {\n                body += \"&client_secret=\" + encodeURIComponent(client_secret);\n            }\n            body += \"&token_type_hint=\" + encodeURIComponent(type);\n            body += \"&token=\" + encodeURIComponent(token);\n\n            xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            xhr.send(body);\n        });\n    };\n\n    return TokenRevocationClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/UrlUtility.js\":\n/*!***************************!*\\\n  !*** ./src/UrlUtility.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UrlUtility = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UrlUtility = exports.UrlUtility = function () {\n    function UrlUtility() {\n        _classCallCheck(this, UrlUtility);\n    }\n\n    UrlUtility.addQueryParam = function addQueryParam(url, name, value) {\n        if (url.indexOf('?') < 0) {\n            url += \"?\";\n        }\n\n        if (url[url.length - 1] !== \"?\") {\n            url += \"&\";\n        }\n\n        url += encodeURIComponent(name);\n        url += \"=\";\n        url += encodeURIComponent(value);\n\n        return url;\n    };\n\n    UrlUtility.parseUrlFragment = function parseUrlFragment(value) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n        var global = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global;\n\n        if (typeof value !== 'string') {\n            value = global.location.href;\n        }\n\n        var idx = value.lastIndexOf(delimiter);\n        if (idx >= 0) {\n            value = value.substr(idx + 1);\n        }\n\n        if (delimiter === \"?\") {\n            // if we're doing query, then strip off hash fragment before we parse\n            idx = value.indexOf('#');\n            if (idx >= 0) {\n                value = value.substr(0, idx);\n            }\n        }\n\n        var params = {},\n            regex = /([^&=]+)=([^&]*)/g,\n            m;\n\n        var counter = 0;\n        while (m = regex.exec(value)) {\n            params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);\n            if (counter++ > 50) {\n                _Log.Log.error(\"UrlUtility.parseUrlFragment: response exceeded expected number of parameters\", value);\n                return {\n                    error: \"Response exceeded expected number of parameters\"\n                };\n            }\n        }\n\n        for (var prop in params) {\n            return params;\n        }\n\n        return {};\n    };\n\n    return UrlUtility;\n}();\n\n/***/ }),\n\n/***/ \"./src/User.js\":\n/*!*********************!*\\\n  !*** ./src/User.js ***!\n  \\*********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.User = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar User = exports.User = function () {\n    function User(_ref) {\n        var id_token = _ref.id_token,\n            session_state = _ref.session_state,\n            access_token = _ref.access_token,\n            refresh_token = _ref.refresh_token,\n            token_type = _ref.token_type,\n            scope = _ref.scope,\n            profile = _ref.profile,\n            expires_at = _ref.expires_at,\n            state = _ref.state;\n\n        _classCallCheck(this, User);\n\n        this.id_token = id_token;\n        this.session_state = session_state;\n        this.access_token = access_token;\n        this.refresh_token = refresh_token;\n        this.token_type = token_type;\n        this.scope = scope;\n        this.profile = profile;\n        this.expires_at = expires_at;\n        this.state = state;\n    }\n\n    User.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"User.toStorageString\");\n        return JSON.stringify({\n            id_token: this.id_token,\n            session_state: this.session_state,\n            access_token: this.access_token,\n            refresh_token: this.refresh_token,\n            token_type: this.token_type,\n            scope: this.scope,\n            profile: this.profile,\n            expires_at: this.expires_at\n        });\n    };\n\n    User.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"User.fromStorageString\");\n        return new User(JSON.parse(storageString));\n    };\n\n    _createClass(User, [{\n        key: 'expires_in',\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: 'expired',\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: 'scopes',\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }]);\n\n    return User;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserInfoService.js\":\n/*!********************************!*\\\n  !*** ./src/UserInfoService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserInfoService = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserInfoService = exports.UserInfoService = function () {\n    function UserInfoService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserInfoService);\n\n        if (!settings) {\n            _Log.Log.error(\"UserInfoService.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(undefined, undefined, this._getClaimsFromJwt.bind(this));\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n    }\n\n    UserInfoService.prototype.getClaims = function getClaims(token) {\n        var _this = this;\n\n        if (!token) {\n            _Log.Log.error(\"UserInfoService.getClaims: No token passed\");\n            return Promise.reject(new Error(\"A token is required\"));\n        }\n\n        return this._metadataService.getUserInfoEndpoint().then(function (url) {\n            _Log.Log.debug(\"UserInfoService.getClaims: received userinfo url\", url);\n\n            return _this._jsonService.getJson(url, token).then(function (claims) {\n                _Log.Log.debug(\"UserInfoService.getClaims: claims received\", claims);\n                return claims;\n            });\n        });\n    };\n\n    UserInfoService.prototype._getClaimsFromJwt = function _getClaimsFromJwt(req) {\n        var _this2 = this;\n\n        try {\n            var jwt = this._joseUtil.parseJwt(req.responseText);\n            if (!jwt || !jwt.header || !jwt.payload) {\n                _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Failed to parse JWT\", jwt);\n                return Promise.reject(new Error(\"Failed to parse id_token\"));\n            }\n\n            var kid = jwt.header.kid;\n\n            var issuerPromise = void 0;\n            switch (this._settings.userInfoJwtIssuer) {\n                case 'OP':\n                    issuerPromise = this._metadataService.getIssuer();\n                    break;\n                case 'ANY':\n                    issuerPromise = Promise.resolve(jwt.payload.iss);\n                    break;\n                default:\n                    issuerPromise = Promise.resolve(this._settings.userInfoJwtIssuer);\n                    break;\n            }\n\n            return issuerPromise.then(function (issuer) {\n                _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received issuer:\" + issuer);\n\n                return _this2._metadataService.getSigningKeys().then(function (keys) {\n                    if (!keys) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No signing keys from metadata\");\n                        return Promise.reject(new Error(\"No signing keys from metadata\"));\n                    }\n\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received signing keys\");\n                    var key = void 0;\n                    if (!kid) {\n                        keys = _this2._filterByAlg(keys, jwt.header.alg);\n\n                        if (keys.length > 1) {\n                            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No kid found in id_token and more than one key found in metadata\");\n                            return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                        } else {\n                            // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                            // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                            key = keys[0];\n                        }\n                    } else {\n                        key = keys.filter(function (key) {\n                            return key.kid === kid;\n                        })[0];\n                    }\n\n                    if (!key) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No key matching kid or alg found in signing keys\");\n                        return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                    }\n\n                    var audience = _this2._settings.client_id;\n\n                    var clockSkewInSeconds = _this2._settings.clockSkew;\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                    return _this2._joseUtil.validateJwt(req.responseText, key, issuer, audience, clockSkewInSeconds, undefined, true).then(function () {\n                        _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: JWT validation successful\");\n                        return jwt.payload;\n                    });\n                });\n            });\n            return;\n        } catch (e) {\n            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Error parsing JWT response\", e.message);\n            reject(e);\n            return;\n        }\n    };\n\n    UserInfoService.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"UserInfoService._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    return UserInfoService;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserManager.js\":\n/*!****************************!*\\\n  !*** ./src/UserManager.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManager = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClient2 = __webpack_require__(/*! ./OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _UserManagerSettings = __webpack_require__(/*! ./UserManagerSettings.js */ \"./src/UserManagerSettings.js\");\n\nvar _User = __webpack_require__(/*! ./User.js */ \"./src/User.js\");\n\nvar _UserManagerEvents = __webpack_require__(/*! ./UserManagerEvents.js */ \"./src/UserManagerEvents.js\");\n\nvar _SilentRenewService = __webpack_require__(/*! ./SilentRenewService.js */ \"./src/SilentRenewService.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManager = exports.UserManager = function (_OidcClient) {\n    _inherits(UserManager, _OidcClient);\n\n    function UserManager() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n        var SilentRenewServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _SilentRenewService.SilentRenewService;\n        var SessionMonitorCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _SessionMonitor.SessionMonitor;\n        var TokenRevocationClientCtor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _TokenRevocationClient.TokenRevocationClient;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n        var joseUtil = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserManager);\n\n        if (!(settings instanceof _UserManagerSettings.UserManagerSettings)) {\n            settings = new _UserManagerSettings.UserManagerSettings(settings);\n        }\n\n        var _this = _possibleConstructorReturn(this, _OidcClient.call(this, settings));\n\n        _this._events = new _UserManagerEvents.UserManagerEvents(settings);\n        _this._silentRenewService = new SilentRenewServiceCtor(_this);\n\n        // order is important for the following properties; these services depend upon the events.\n        if (_this.settings.automaticSilentRenew) {\n            _Log.Log.debug(\"UserManager.ctor: automaticSilentRenew is configured, setting up silent renew\");\n            _this.startSilentRenew();\n        }\n\n        if (_this.settings.monitorSession) {\n            _Log.Log.debug(\"UserManager.ctor: monitorSession is configured, setting up session monitor\");\n            _this._sessionMonitor = new SessionMonitorCtor(_this);\n        }\n\n        _this._tokenRevocationClient = new TokenRevocationClientCtor(_this._settings);\n        _this._tokenClient = new TokenClientCtor(_this._settings);\n        _this._joseUtil = joseUtil;\n        return _this;\n    }\n\n    UserManager.prototype.getUser = function getUser() {\n        var _this2 = this;\n\n        return this._loadUser().then(function (user) {\n            if (user) {\n                _Log.Log.info(\"UserManager.getUser: user loaded\");\n\n                _this2._events.load(user, false);\n\n                return user;\n            } else {\n                _Log.Log.info(\"UserManager.getUser: user not found in storage\");\n                return null;\n            }\n        });\n    };\n\n    UserManager.prototype.removeUser = function removeUser() {\n        var _this3 = this;\n\n        return this.storeUser(null).then(function () {\n            _Log.Log.info(\"UserManager.removeUser: user removed from storage\");\n            _this3._events.unload();\n        });\n    };\n\n    UserManager.prototype.signinRedirect = function signinRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:r\";\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signinStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signinRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signinRedirectCallback = function signinRedirectCallback(url) {\n        return this._signinEnd(url || this._redirectNavigator.url).then(function (user) {\n            if (user.profile && user.profile.sub) {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: successful, signed in sub: \", user.profile.sub);\n            } else {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: no sub\");\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopup = function signinPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:p\";\n        var url = args.redirect_uri || this.settings.popup_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinPopup: No popup_redirect_uri or redirect_uri configured\");\n            return Promise.reject(new Error(\"No popup_redirect_uri or redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.display = \"popup\";\n\n        return this._signin(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopup: signinPopup successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopup: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopupCallback = function signinPopupCallback(url) {\n        return this._signinCallback(url, this._popupNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: no sub\");\n                }\n            }\n\n            return user;\n        }).catch(function (err) {\n            _Log.Log.error( true && err.message);\n        });\n    };\n\n    UserManager.prototype.signinSilent = function signinSilent() {\n        var _this4 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\";\n        // first determine if we have a refresh token, or need to use iframe\n        return this._loadUser().then(function (user) {\n            if (user && user.refresh_token) {\n                args.refresh_token = user.refresh_token;\n                return _this4._useRefreshToken(args);\n            } else {\n                args.id_token_hint = args.id_token_hint || _this4.settings.includeIdTokenInSilentRenew && user && user.id_token;\n                if (user && _this4._settings.validateSubOnSilentRenew) {\n                    _Log.Log.debug(\"UserManager.signinSilent, subject prior to silent renew: \", user.profile.sub);\n                    args.current_sub = user.profile.sub;\n                }\n                return _this4._signinSilentIframe(args);\n            }\n        });\n    };\n\n    UserManager.prototype._useRefreshToken = function _useRefreshToken() {\n        var _this5 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        return this._tokenClient.exchangeRefreshToken(args).then(function (result) {\n            if (!result) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No response returned from token endpoint\");\n                return Promise.reject(\"No response returned from token endpoint\");\n            }\n            if (!result.access_token) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No access token returned from token endpoint\");\n                return Promise.reject(\"No access token returned from token endpoint\");\n            }\n\n            return _this5._loadUser().then(function (user) {\n                if (user) {\n                    var idTokenValidation = Promise.resolve();\n                    if (result.id_token) {\n                        idTokenValidation = _this5._validateIdTokenFromTokenRefreshToken(user.profile, result.id_token);\n                    }\n\n                    return idTokenValidation.then(function () {\n                        _Log.Log.debug(\"UserManager._useRefreshToken: refresh token response success\");\n                        user.id_token = result.id_token;\n                        user.access_token = result.access_token;\n                        user.refresh_token = result.refresh_token || user.refresh_token;\n                        user.expires_in = result.expires_in;\n\n                        return _this5.storeUser(user).then(function () {\n                            _this5._events.load(user);\n                            return user;\n                        });\n                    });\n                } else {\n                    return null;\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._validateIdTokenFromTokenRefreshToken = function _validateIdTokenFromTokenRefreshToken(profile, id_token) {\n        var _this6 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            return _this6._joseUtil.validateJwtAttributes(id_token, issuer, _this6._settings.client_id, _this6._settings.clockSkew).then(function (payload) {\n                if (!payload) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: Failed to validate id_token\");\n                    return Promise.reject(new Error(\"Failed to validate id_token\"));\n                }\n                if (payload.sub !== profile.sub) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: sub in id_token does not match current sub\");\n                    return Promise.reject(new Error(\"sub in id_token does not match current sub\"));\n                }\n                if (payload.auth_time && payload.auth_time !== profile.auth_time) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: auth_time in id_token does not match original auth_time\");\n                    return Promise.reject(new Error(\"auth_time in id_token does not match original auth_time\"));\n                }\n                if (payload.azp && payload.azp !== profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp in id_token does not match original azp\");\n                    return Promise.reject(new Error(\"azp in id_token does not match original azp\"));\n                }\n                if (!payload.azp && profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp not in id_token, but present in original id_token\");\n                    return Promise.reject(new Error(\"azp not in id_token, but present in original id_token\"));\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._signinSilentIframe = function _signinSilentIframe() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinSilent: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = args.prompt || \"none\";\n\n        return this._signin(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilent: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilent: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinSilentCallback = function signinSilentCallback(url) {\n        return this._signinCallback(url, this._iframeNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinCallback = function signinCallback(url) {\n        var _this7 = this;\n\n        return this.readSigninResponseState(url).then(function (_ref) {\n            var state = _ref.state,\n                response = _ref.response;\n\n            if (state.request_type === \"si:r\") {\n                return _this7.signinRedirectCallback(url);\n            }\n            if (state.request_type === \"si:p\") {\n                return _this7.signinPopupCallback(url);\n            }\n            if (state.request_type === \"si:s\") {\n                return _this7.signinSilentCallback(url);\n            }\n            return Promise.reject(new Error(\"invalid response_type in state\"));\n        });\n    };\n\n    UserManager.prototype.signoutCallback = function signoutCallback(url, keepOpen) {\n        var _this8 = this;\n\n        return this.readSignoutResponseState(url).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            if (state) {\n                if (state.request_type === \"so:r\") {\n                    return _this8.signoutRedirectCallback(url);\n                }\n                if (state.request_type === \"so:p\") {\n                    return _this8.signoutPopupCallback(url, keepOpen);\n                }\n                return Promise.reject(new Error(\"invalid response_type in state\"));\n            }\n            return response;\n        });\n    };\n\n    UserManager.prototype.querySessionStatus = function querySessionStatus() {\n        var _this9 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\"; // this acts like a signin silent\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.querySessionStatus: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = \"none\";\n        args.response_type = args.response_type || this.settings.query_status_response_type;\n        args.scope = args.scope || \"openid\";\n        args.skipUserInfo = true;\n\n        return this._signinStart(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (navResponse) {\n            return _this9.processSigninResponse(navResponse.url).then(function (signinResponse) {\n                _Log.Log.debug(\"UserManager.querySessionStatus: got signin response\");\n\n                if (signinResponse.session_state && signinResponse.profile.sub) {\n                    _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for sub: \", signinResponse.profile.sub);\n                    return {\n                        session_state: signinResponse.session_state,\n                        sub: signinResponse.profile.sub,\n                        sid: signinResponse.profile.sid\n                    };\n                } else {\n                    _Log.Log.info(\"querySessionStatus successful, user not authenticated\");\n                }\n            }).catch(function (err) {\n                if (err.session_state && _this9.settings.monitorAnonymousSession) {\n                    if (err.message == \"login_required\" || err.message == \"consent_required\" || err.message == \"interaction_required\" || err.message == \"account_selection_required\") {\n                        _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for anonymous user\");\n                        return {\n                            session_state: err.session_state\n                        };\n                    }\n                }\n\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signin = function _signin(args, navigator) {\n        var _this10 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signinStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this10._signinEnd(navResponse.url, args);\n        });\n    };\n\n    UserManager.prototype._signinStart = function _signinStart(args, navigator) {\n        var _this11 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signinStart: got navigator window handle\");\n\n            return _this11.createSigninRequest(args).then(function (signinRequest) {\n                _Log.Log.debug(\"UserManager._signinStart: got signin request\");\n\n                navigatorParams.url = signinRequest.url;\n                navigatorParams.id = signinRequest.state.id;\n\n                return handle.navigate(navigatorParams);\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signinStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signinEnd = function _signinEnd(url) {\n        var _this12 = this;\n\n        var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n        return this.processSigninResponse(url).then(function (signinResponse) {\n            _Log.Log.debug(\"UserManager._signinEnd: got signin response\");\n\n            var user = new _User.User(signinResponse);\n\n            if (args.current_sub) {\n                if (args.current_sub !== user.profile.sub) {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user does not match user returned from signin. sub from signin: \", user.profile.sub);\n                    return Promise.reject(new Error(\"login_required\"));\n                } else {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user matches user returned from signin\");\n                }\n            }\n\n            return _this12.storeUser(user).then(function () {\n                _Log.Log.debug(\"UserManager._signinEnd: user stored\");\n\n                _this12._events.load(user);\n\n                return user;\n            });\n        });\n    };\n\n    UserManager.prototype._signinCallback = function _signinCallback(url, navigator) {\n        _Log.Log.debug(\"UserManager._signinCallback\");\n        return navigator.callback(url);\n    };\n\n    UserManager.prototype.signoutRedirect = function signoutRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:r\";\n        var postLogoutRedirectUri = args.post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        if (postLogoutRedirectUri) {\n            args.post_logout_redirect_uri = postLogoutRedirectUri;\n        }\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signoutStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signoutRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutRedirectCallback = function signoutRedirectCallback(url) {\n        return this._signoutEnd(url || this._redirectNavigator.url).then(function (response) {\n            _Log.Log.info(\"UserManager.signoutRedirectCallback: successful\");\n            return response;\n        });\n    };\n\n    UserManager.prototype.signoutPopup = function signoutPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:p\";\n        var url = args.post_logout_redirect_uri || this.settings.popup_post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        args.post_logout_redirect_uri = url;\n        args.display = \"popup\";\n        if (args.post_logout_redirect_uri) {\n            // we're putting a dummy entry in here because we\n            // need a unique id from the state for notification\n            // to the parent window, which is necessary if we\n            // plan to return back to the client after signout\n            // and so we can close the popup after signout\n            args.state = args.state || {};\n        }\n\n        return this._signout(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopup: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutPopupCallback = function signoutPopupCallback(url, keepOpen) {\n        if (typeof keepOpen === 'undefined' && typeof url === 'boolean') {\n            keepOpen = url;\n            url = null;\n        }\n\n        var delimiter = '?';\n        return this._popupNavigator.callback(url, keepOpen, delimiter).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopupCallback: successful\");\n        });\n    };\n\n    UserManager.prototype._signout = function _signout(args, navigator) {\n        var _this13 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signoutStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this13._signoutEnd(navResponse.url);\n        });\n    };\n\n    UserManager.prototype._signoutStart = function _signoutStart() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var _this14 = this;\n\n        var navigator = arguments[1];\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signoutStart: got navigator window handle\");\n\n            return _this14._loadUser().then(function (user) {\n                _Log.Log.debug(\"UserManager._signoutStart: loaded current user from storage\");\n\n                var revokePromise = _this14._settings.revokeAccessTokenOnSignout ? _this14._revokeInternal(user) : Promise.resolve();\n                return revokePromise.then(function () {\n\n                    var id_token = args.id_token_hint || user && user.id_token;\n                    if (id_token) {\n                        _Log.Log.debug(\"UserManager._signoutStart: Setting id_token into signout request\");\n                        args.id_token_hint = id_token;\n                    }\n\n                    return _this14.removeUser().then(function () {\n                        _Log.Log.debug(\"UserManager._signoutStart: user removed, creating signout request\");\n\n                        return _this14.createSignoutRequest(args).then(function (signoutRequest) {\n                            _Log.Log.debug(\"UserManager._signoutStart: got signout request\");\n\n                            navigatorParams.url = signoutRequest.url;\n                            if (signoutRequest.state) {\n                                navigatorParams.id = signoutRequest.state.id;\n                            }\n                            return handle.navigate(navigatorParams);\n                        });\n                    });\n                });\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signoutStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signoutEnd = function _signoutEnd(url) {\n        return this.processSignoutResponse(url).then(function (signoutResponse) {\n            _Log.Log.debug(\"UserManager._signoutEnd: got signout response\");\n\n            return signoutResponse;\n        });\n    };\n\n    UserManager.prototype.revokeAccessToken = function revokeAccessToken() {\n        var _this15 = this;\n\n        return this._loadUser().then(function (user) {\n            return _this15._revokeInternal(user, true).then(function (success) {\n                if (success) {\n                    _Log.Log.debug(\"UserManager.revokeAccessToken: removing token properties from user and re-storing\");\n\n                    user.access_token = null;\n                    user.refresh_token = null;\n                    user.expires_at = null;\n                    user.token_type = null;\n\n                    return _this15.storeUser(user).then(function () {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: user stored\");\n                        _this15._events.load(user);\n                    });\n                }\n            });\n        }).then(function () {\n            _Log.Log.info(\"UserManager.revokeAccessToken: access token revoked successfully\");\n        });\n    };\n\n    UserManager.prototype._revokeInternal = function _revokeInternal(user, required) {\n        var _this16 = this;\n\n        if (user) {\n            var access_token = user.access_token;\n            var refresh_token = user.refresh_token;\n\n            return this._revokeAccessTokenInternal(access_token, required).then(function (atSuccess) {\n                return _this16._revokeRefreshTokenInternal(refresh_token, required).then(function (rtSuccess) {\n                    if (!atSuccess && !rtSuccess) {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: no need to revoke due to no token(s), or JWT format\");\n                    }\n\n                    return atSuccess || rtSuccess;\n                });\n            });\n        }\n\n        return Promise.resolve(false);\n    };\n\n    UserManager.prototype._revokeAccessTokenInternal = function _revokeAccessTokenInternal(access_token, required) {\n        // check for JWT vs. reference token\n        if (!access_token || access_token.indexOf('.') >= 0) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(access_token, required).then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype._revokeRefreshTokenInternal = function _revokeRefreshTokenInternal(refresh_token, required) {\n        if (!refresh_token) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(refresh_token, required, \"refresh_token\").then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype.startSilentRenew = function startSilentRenew() {\n        this._silentRenewService.start();\n    };\n\n    UserManager.prototype.stopSilentRenew = function stopSilentRenew() {\n        this._silentRenewService.stop();\n    };\n\n    UserManager.prototype._loadUser = function _loadUser() {\n        return this._userStore.get(this._userStoreKey).then(function (storageString) {\n            if (storageString) {\n                _Log.Log.debug(\"UserManager._loadUser: user storageString loaded\");\n                return _User.User.fromStorageString(storageString);\n            }\n\n            _Log.Log.debug(\"UserManager._loadUser: no user storageString\");\n            return null;\n        });\n    };\n\n    UserManager.prototype.storeUser = function storeUser(user) {\n        if (user) {\n            _Log.Log.debug(\"UserManager.storeUser: storing user\");\n\n            var storageString = user.toStorageString();\n            return this._userStore.set(this._userStoreKey, storageString);\n        } else {\n            _Log.Log.debug(\"storeUser.storeUser: removing user\");\n            return this._userStore.remove(this._userStoreKey);\n        }\n    };\n\n    _createClass(UserManager, [{\n        key: '_redirectNavigator',\n        get: function get() {\n            return this.settings.redirectNavigator;\n        }\n    }, {\n        key: '_popupNavigator',\n        get: function get() {\n            return this.settings.popupNavigator;\n        }\n    }, {\n        key: '_iframeNavigator',\n        get: function get() {\n            return this.settings.iframeNavigator;\n        }\n    }, {\n        key: '_userStore',\n        get: function get() {\n            return this.settings.userStore;\n        }\n    }, {\n        key: 'events',\n        get: function get() {\n            return this._events;\n        }\n    }, {\n        key: '_userStoreKey',\n        get: function get() {\n            return 'user:' + this.settings.authority + ':' + this.settings.client_id;\n        }\n    }]);\n\n    return UserManager;\n}(_OidcClient2.OidcClient);\n\n/***/ }),\n\n/***/ \"./src/UserManagerEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/UserManagerEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _AccessTokenEvents2 = __webpack_require__(/*! ./AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _Event = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManagerEvents = exports.UserManagerEvents = function (_AccessTokenEvents) {\n    _inherits(UserManagerEvents, _AccessTokenEvents);\n\n    function UserManagerEvents(settings) {\n        _classCallCheck(this, UserManagerEvents);\n\n        var _this = _possibleConstructorReturn(this, _AccessTokenEvents.call(this, settings));\n\n        _this._userLoaded = new _Event.Event(\"User loaded\");\n        _this._userUnloaded = new _Event.Event(\"User unloaded\");\n        _this._silentRenewError = new _Event.Event(\"Silent renew error\");\n        _this._userSignedIn = new _Event.Event(\"User signed in\");\n        _this._userSignedOut = new _Event.Event(\"User signed out\");\n        _this._userSessionChanged = new _Event.Event(\"User session changed\");\n        return _this;\n    }\n\n    UserManagerEvents.prototype.load = function load(user) {\n        var raiseEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n        _Log.Log.debug(\"UserManagerEvents.load\");\n        _AccessTokenEvents.prototype.load.call(this, user);\n        if (raiseEvent) {\n            this._userLoaded.raise(user);\n        }\n    };\n\n    UserManagerEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"UserManagerEvents.unload\");\n        _AccessTokenEvents.prototype.unload.call(this);\n        this._userUnloaded.raise();\n    };\n\n    UserManagerEvents.prototype.addUserLoaded = function addUserLoaded(cb) {\n        this._userLoaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserLoaded = function removeUserLoaded(cb) {\n        this._userLoaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addUserUnloaded = function addUserUnloaded(cb) {\n        this._userUnloaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserUnloaded = function removeUserUnloaded(cb) {\n        this._userUnloaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addSilentRenewError = function addSilentRenewError(cb) {\n        this._silentRenewError.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeSilentRenewError = function removeSilentRenewError(cb) {\n        this._silentRenewError.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseSilentRenewError = function _raiseSilentRenewError(e) {\n        _Log.Log.debug(\"UserManagerEvents._raiseSilentRenewError\", e.message);\n        this._silentRenewError.raise(e);\n    };\n\n    UserManagerEvents.prototype.addUserSignedIn = function addUserSignedIn(cb) {\n        this._userSignedIn.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedIn = function removeUserSignedIn(cb) {\n        this._userSignedIn.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedIn = function _raiseUserSignedIn() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedIn\");\n        this._userSignedIn.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSignedOut = function addUserSignedOut(cb) {\n        this._userSignedOut.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedOut = function removeUserSignedOut(cb) {\n        this._userSignedOut.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedOut = function _raiseUserSignedOut() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedOut\");\n        this._userSignedOut.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSessionChanged = function addUserSessionChanged(cb) {\n        this._userSessionChanged.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSessionChanged = function removeUserSessionChanged(cb) {\n        this._userSessionChanged.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSessionChanged = function _raiseUserSessionChanged() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSessionChanged\");\n        this._userSessionChanged.raise();\n    };\n\n    return UserManagerEvents;\n}(_AccessTokenEvents2.AccessTokenEvents);\n\n/***/ }),\n\n/***/ \"./src/UserManagerSettings.js\":\n/*!************************************!*\\\n  !*** ./src/UserManagerSettings.js ***!\n  \\************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerSettings = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings2 = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _RedirectNavigator = __webpack_require__(/*! ./RedirectNavigator.js */ \"./src/RedirectNavigator.js\");\n\nvar _PopupNavigator = __webpack_require__(/*! ./PopupNavigator.js */ \"./src/PopupNavigator.js\");\n\nvar _IFrameNavigator = __webpack_require__(/*! ./IFrameNavigator.js */ \"./src/IFrameNavigator.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60;\nvar DefaultCheckSessionInterval = 2000;\n\nvar UserManagerSettings = exports.UserManagerSettings = function (_OidcClientSettings) {\n    _inherits(UserManagerSettings, _OidcClientSettings);\n\n    function UserManagerSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            popup_redirect_uri = _ref.popup_redirect_uri,\n            popup_post_logout_redirect_uri = _ref.popup_post_logout_redirect_uri,\n            popupWindowFeatures = _ref.popupWindowFeatures,\n            popupWindowTarget = _ref.popupWindowTarget,\n            silent_redirect_uri = _ref.silent_redirect_uri,\n            silentRequestTimeout = _ref.silentRequestTimeout,\n            _ref$automaticSilentR = _ref.automaticSilentRenew,\n            automaticSilentRenew = _ref$automaticSilentR === undefined ? false : _ref$automaticSilentR,\n            _ref$validateSubOnSil = _ref.validateSubOnSilentRenew,\n            validateSubOnSilentRenew = _ref$validateSubOnSil === undefined ? false : _ref$validateSubOnSil,\n            _ref$includeIdTokenIn = _ref.includeIdTokenInSilentRenew,\n            includeIdTokenInSilentRenew = _ref$includeIdTokenIn === undefined ? true : _ref$includeIdTokenIn,\n            _ref$monitorSession = _ref.monitorSession,\n            monitorSession = _ref$monitorSession === undefined ? true : _ref$monitorSession,\n            _ref$monitorAnonymous = _ref.monitorAnonymousSession,\n            monitorAnonymousSession = _ref$monitorAnonymous === undefined ? false : _ref$monitorAnonymous,\n            _ref$checkSessionInte = _ref.checkSessionInterval,\n            checkSessionInterval = _ref$checkSessionInte === undefined ? DefaultCheckSessionInterval : _ref$checkSessionInte,\n            _ref$stopCheckSession = _ref.stopCheckSessionOnError,\n            stopCheckSessionOnError = _ref$stopCheckSession === undefined ? true : _ref$stopCheckSession,\n            query_status_response_type = _ref.query_status_response_type,\n            _ref$revokeAccessToke = _ref.revokeAccessTokenOnSignout,\n            revokeAccessTokenOnSignout = _ref$revokeAccessToke === undefined ? false : _ref$revokeAccessToke,\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$redirectNavigato = _ref.redirectNavigator,\n            redirectNavigator = _ref$redirectNavigato === undefined ? new _RedirectNavigator.RedirectNavigator() : _ref$redirectNavigato,\n            _ref$popupNavigator = _ref.popupNavigator,\n            popupNavigator = _ref$popupNavigator === undefined ? new _PopupNavigator.PopupNavigator() : _ref$popupNavigator,\n            _ref$iframeNavigator = _ref.iframeNavigator,\n            iframeNavigator = _ref$iframeNavigator === undefined ? new _IFrameNavigator.IFrameNavigator() : _ref$iframeNavigator,\n            _ref$userStore = _ref.userStore,\n            userStore = _ref$userStore === undefined ? new _WebStorageStateStore.WebStorageStateStore({ store: _Global.Global.sessionStorage }) : _ref$userStore;\n\n        _classCallCheck(this, UserManagerSettings);\n\n        var _this = _possibleConstructorReturn(this, _OidcClientSettings.call(this, arguments[0]));\n\n        _this._popup_redirect_uri = popup_redirect_uri;\n        _this._popup_post_logout_redirect_uri = popup_post_logout_redirect_uri;\n        _this._popupWindowFeatures = popupWindowFeatures;\n        _this._popupWindowTarget = popupWindowTarget;\n\n        _this._silent_redirect_uri = silent_redirect_uri;\n        _this._silentRequestTimeout = silentRequestTimeout;\n        _this._automaticSilentRenew = automaticSilentRenew;\n        _this._validateSubOnSilentRenew = validateSubOnSilentRenew;\n        _this._includeIdTokenInSilentRenew = includeIdTokenInSilentRenew;\n        _this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        _this._monitorSession = monitorSession;\n        _this._monitorAnonymousSession = monitorAnonymousSession;\n        _this._checkSessionInterval = checkSessionInterval;\n        _this._stopCheckSessionOnError = stopCheckSessionOnError;\n        if (query_status_response_type) {\n            _this._query_status_response_type = query_status_response_type;\n        } else if (arguments[0] && arguments[0].response_type) {\n            _this._query_status_response_type = _SigninRequest.SigninRequest.isOidc(arguments[0].response_type) ? \"id_token\" : \"code\";\n        } else {\n            _this._query_status_response_type = \"id_token\";\n        }\n        _this._revokeAccessTokenOnSignout = revokeAccessTokenOnSignout;\n\n        _this._redirectNavigator = redirectNavigator;\n        _this._popupNavigator = popupNavigator;\n        _this._iframeNavigator = iframeNavigator;\n\n        _this._userStore = userStore;\n        return _this;\n    }\n\n    _createClass(UserManagerSettings, [{\n        key: 'popup_redirect_uri',\n        get: function get() {\n            return this._popup_redirect_uri;\n        }\n    }, {\n        key: 'popup_post_logout_redirect_uri',\n        get: function get() {\n            return this._popup_post_logout_redirect_uri;\n        }\n    }, {\n        key: 'popupWindowFeatures',\n        get: function get() {\n            return this._popupWindowFeatures;\n        }\n    }, {\n        key: 'popupWindowTarget',\n        get: function get() {\n            return this._popupWindowTarget;\n        }\n    }, {\n        key: 'silent_redirect_uri',\n        get: function get() {\n            return this._silent_redirect_uri;\n        }\n    }, {\n        key: 'silentRequestTimeout',\n        get: function get() {\n            return this._silentRequestTimeout;\n        }\n    }, {\n        key: 'automaticSilentRenew',\n        get: function get() {\n            return this._automaticSilentRenew;\n        }\n    }, {\n        key: 'validateSubOnSilentRenew',\n        get: function get() {\n            return this._validateSubOnSilentRenew;\n        }\n    }, {\n        key: 'includeIdTokenInSilentRenew',\n        get: function get() {\n            return this._includeIdTokenInSilentRenew;\n        }\n    }, {\n        key: 'accessTokenExpiringNotificationTime',\n        get: function get() {\n            return this._accessTokenExpiringNotificationTime;\n        }\n    }, {\n        key: 'monitorSession',\n        get: function get() {\n            return this._monitorSession;\n        }\n    }, {\n        key: 'monitorAnonymousSession',\n        get: function get() {\n            return this._monitorAnonymousSession;\n        }\n    }, {\n        key: 'checkSessionInterval',\n        get: function get() {\n            return this._checkSessionInterval;\n        }\n    }, {\n        key: 'stopCheckSessionOnError',\n        get: function get() {\n            return this._stopCheckSessionOnError;\n        }\n    }, {\n        key: 'query_status_response_type',\n        get: function get() {\n            return this._query_status_response_type;\n        }\n    }, {\n        key: 'revokeAccessTokenOnSignout',\n        get: function get() {\n            return this._revokeAccessTokenOnSignout;\n        }\n    }, {\n        key: 'redirectNavigator',\n        get: function get() {\n            return this._redirectNavigator;\n        }\n    }, {\n        key: 'popupNavigator',\n        get: function get() {\n            return this._popupNavigator;\n        }\n    }, {\n        key: 'iframeNavigator',\n        get: function get() {\n            return this._iframeNavigator;\n        }\n    }, {\n        key: 'userStore',\n        get: function get() {\n            return this._userStore;\n        }\n    }]);\n\n    return UserManagerSettings;\n}(_OidcClientSettings2.OidcClientSettings);\n\n/***/ }),\n\n/***/ \"./src/WebStorageStateStore.js\":\n/*!*************************************!*\\\n  !*** ./src/WebStorageStateStore.js ***!\n  \\*************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.WebStorageStateStore = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar WebStorageStateStore = exports.WebStorageStateStore = function () {\n    function WebStorageStateStore() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$prefix = _ref.prefix,\n            prefix = _ref$prefix === undefined ? \"oidc.\" : _ref$prefix,\n            _ref$store = _ref.store,\n            store = _ref$store === undefined ? _Global.Global.localStorage : _ref$store;\n\n        _classCallCheck(this, WebStorageStateStore);\n\n        this._store = store;\n        this._prefix = prefix;\n    }\n\n    WebStorageStateStore.prototype.set = function set(key, value) {\n        _Log.Log.debug(\"WebStorageStateStore.set\", key);\n\n        key = this._prefix + key;\n\n        this._store.setItem(key, value);\n\n        return Promise.resolve();\n    };\n\n    WebStorageStateStore.prototype.get = function get(key) {\n        _Log.Log.debug(\"WebStorageStateStore.get\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.remove = function remove(key) {\n        _Log.Log.debug(\"WebStorageStateStore.remove\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n        this._store.removeItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.getAllKeys = function getAllKeys() {\n        _Log.Log.debug(\"WebStorageStateStore.getAllKeys\");\n\n        var keys = [];\n\n        for (var index = 0; index < this._store.length; index++) {\n            var key = this._store.key(index);\n\n            if (key.indexOf(this._prefix) === 0) {\n                keys.push(key.substr(this._prefix.length));\n            }\n        }\n\n        return Promise.resolve(keys);\n    };\n\n    return WebStorageStateStore;\n}();\n\n/***/ }),\n\n/***/ \"./src/crypto/jsrsasign.js\":\n/*!*********************************!*\\\n  !*** ./src/crypto/jsrsasign.js ***!\n  \\*********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AllowedSigningAlgs = exports.b64tohex = exports.hextob64u = exports.crypto = exports.X509 = exports.KeyUtil = exports.jws = undefined;\n\nvar _jsrsasign = __webpack_require__(/*! ../../jsrsasign/dist/jsrsasign.js */ \"./jsrsasign/dist/jsrsasign.js\");\n\nvar AllowedSigningAlgs = ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'ES256', 'ES384', 'ES512'];\n\nexports.jws = _jsrsasign.jws;\nexports.KeyUtil = _jsrsasign.KEYUTIL;\nexports.X509 = _jsrsasign.X509;\nexports.crypto = _jsrsasign.crypto;\nexports.hextob64u = _jsrsasign.hextob64u;\nexports.b64tohex = _jsrsasign.b64tohex;\nexports.AllowedSigningAlgs = AllowedSigningAlgs;\n\n/***/ }),\n\n/***/ \"./src/random.js\":\n/*!***********************!*\\\n  !*** ./src/random.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = random;\n\nvar _v = __webpack_require__(/*! uuid/v4 */ \"./node_modules/uuid/v4.js\");\n\nvar _v2 = _interopRequireDefault(_v);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Generates RFC4122 version 4 guid ()\n */\n\nfunction random() {\n  return (0, _v2.default)().replace(/-/g, '');\n}\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./version.js\":\n/*!********************!*\\\n  !*** ./version.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nvar Version = \"1.10.1\";exports.Version = Version;\n\n/***/ }),\n\n/***/ 0:\n/*!***************************************!*\\\n  !*** multi ./polyfills.js ./index.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./polyfills.js */\"./polyfills.js\");\nmodule.exports = __webpack_require__(/*! ./index.js */\"./index.js\");\n\n\n/***/ })\n\n/******/ });\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9PaWRjL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL09pZGMvLi9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vanNyc2FzaWduL2Rpc3QvanNyc2FzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2luZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvYnVmZmVyL25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9lczYvcHJvbWlzZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vYXJyYXkvZmluZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vYXJyYXkvaXMtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL2FycmF5L3NvbWUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL2FycmF5L3NwbGljZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vZnVuY3Rpb24vYmluZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vb2JqZWN0L2Fzc2lnbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYWRkLXRvLXVuc2NvcGFibGVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1pbnN0YW5jZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYW4tb2JqZWN0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1pbmNsdWRlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktc3BlY2llcy1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2JpbmQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NsYXNzb2YuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29yZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1idWcta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mdW5jdGlvbi10by1zdHJpbmcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2dsb2JhbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGFzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19oaWRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19odG1sLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pZTgtZG9tLWRlZmluZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW52b2tlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pb2JqZWN0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS1pdGVyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pcy1hcnJheS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtb2JqZWN0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX25ldy1wcm9taXNlLWNhcGFiaWxpdHkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1hc3NpZ24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGVyZm9ybS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvbWlzZS1yZXNvbHZlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC1rZXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWF0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190YXNrLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1hYnNvbHV0ZS1pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdWlkLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL191c2VyLWFnZW50LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL193a3MuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pcy1hcnJheS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvbWUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmJpbmQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnByb21pc2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL2J5dGVzVG9VdWlkLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvdXVpZC9saWIvcm5nLWJyb3dzZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy91dWlkL3Y0LmpzIiwid2VicGFjazovL09pZGMvKHdlYnBhY2spL2J1aWxkaW4vZ2xvYmFsLmpzIiwid2VicGFjazovL09pZGMvLi9wb2x5ZmlsbHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9BY2Nlc3NUb2tlbkV2ZW50cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0NoZWNrU2Vzc2lvbklGcmFtZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0NvcmRvdmFJRnJhbWVOYXZpZ2F0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Db3Jkb3ZhUG9wdXBOYXZpZ2F0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Db3Jkb3ZhUG9wdXBXaW5kb3cuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9FcnJvclJlc3BvbnNlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvRXZlbnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9HbG9iYWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9JRnJhbWVOYXZpZ2F0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9JRnJhbWVXaW5kb3cuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Jbk1lbW9yeVdlYlN0b3JhZ2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Kb3NlVXRpbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0pvc2VVdGlsSW1wbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0pzb25TZXJ2aWNlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvTG9nLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvTWV0YWRhdGFTZXJ2aWNlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvT2lkY0NsaWVudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL09pZGNDbGllbnRTZXR0aW5ncy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1BvcHVwTmF2aWdhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvUG9wdXBXaW5kb3cuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9SZWRpcmVjdE5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1Jlc3BvbnNlVmFsaWRhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2Vzc2lvbk1vbml0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWduaW5SZXF1ZXN0LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2lnbmluUmVzcG9uc2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWduaW5TdGF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpZ25vdXRSZXF1ZXN0LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2lnbm91dFJlc3BvbnNlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2lsZW50UmVuZXdTZXJ2aWNlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU3RhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9UaW1lci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1Rva2VuQ2xpZW50LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVG9rZW5SZXZvY2F0aW9uQ2xpZW50LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXJsVXRpbGl0eS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VzZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Vc2VySW5mb1NlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Vc2VyTWFuYWdlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VzZXJNYW5hZ2VyRXZlbnRzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXNlck1hbmFnZXJTZXR0aW5ncy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1dlYlN0b3JhZ2VTdGF0ZVN0b3JlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvY3J5cHRvL2pzcnNhc2lnbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL3JhbmRvbS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vdmVyc2lvbi5qcyJdLCJuYW1lcyI6WyJWZXJzaW9uIiwiTG9nIiwiT2lkY0NsaWVudCIsIk9pZGNDbGllbnRTZXR0aW5ncyIsIldlYlN0b3JhZ2VTdGF0ZVN0b3JlIiwiSW5NZW1vcnlXZWJTdG9yYWdlIiwiVXNlck1hbmFnZXIiLCJBY2Nlc3NUb2tlbkV2ZW50cyIsIk1ldGFkYXRhU2VydmljZSIsIkNvcmRvdmFQb3B1cE5hdmlnYXRvciIsIkNvcmRvdmFJRnJhbWVOYXZpZ2F0b3IiLCJDaGVja1Nlc3Npb25JRnJhbWUiLCJUb2tlblJldm9jYXRpb25DbGllbnQiLCJTZXNzaW9uTW9uaXRvciIsIkdsb2JhbCIsIlVzZXIiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJ3aW5kb3ciLCJZQUhPTyIsInVuZGVmaW5lZCIsImxhbmciLCJleHRlbmQiLCJnIiwiaCIsImYiLCJFcnJvciIsImQiLCJwcm90b3R5cGUiLCJjb25zdHJ1Y3RvciIsInN1cGVyY2xhc3MiLCJPYmplY3QiLCJiIiwiZSIsImMiLCJ0ZXN0IiwiaiIsImkiLCJsZW5ndGgiLCJsIiwiayIsImEiLCJDcnlwdG9KUyIsImxpYiIsIkJhc2UiLCJuIiwicCIsIm8iLCJtaXhJbiIsImhhc093blByb3BlcnR5IiwiaW5pdCIsIiRzdXBlciIsImFwcGx5IiwiYXJndW1lbnRzIiwiY3JlYXRlIiwidG9TdHJpbmciLCJjbG9uZSIsIldvcmRBcnJheSIsIndvcmRzIiwic2lnQnl0ZXMiLCJzdHJpbmdpZnkiLCJjb25jYXQiLCJ0IiwicSIsInMiLCJjbGFtcCIsInIiLCJjZWlsIiwiY2FsbCIsInNsaWNlIiwicmFuZG9tIiwicHVzaCIsIm0iLCJlbmMiLCJIZXgiLCJqb2luIiwicGFyc2UiLCJwYXJzZUludCIsInN1YnN0ciIsIkxhdGluMSIsIlN0cmluZyIsImZyb21DaGFyQ29kZSIsImNoYXJDb2RlQXQiLCJVdGY4IiwiZGVjb2RlVVJJQ29tcG9uZW50IiwiZXNjYXBlIiwidW5lc2NhcGUiLCJlbmNvZGVVUklDb21wb25lbnQiLCJCdWZmZXJlZEJsb2NrQWxnb3JpdGhtIiwicmVzZXQiLCJfZGF0YSIsIl9uRGF0YUJ5dGVzIiwiX2FwcGVuZCIsIl9wcm9jZXNzIiwidyIsIngiLCJibG9ja1NpemUiLCJ2IiwidSIsIm1heCIsIl9taW5CdWZmZXJTaXplIiwibWluIiwiX2RvUHJvY2Vzc0Jsb2NrIiwic3BsaWNlIiwiSGFzaGVyIiwiY2ZnIiwiX2RvUmVzZXQiLCJ1cGRhdGUiLCJmaW5hbGl6ZSIsIl9kb0ZpbmFsaXplIiwiX2NyZWF0ZUhlbHBlciIsIl9jcmVhdGVIbWFjSGVscGVyIiwiSE1BQyIsImFsZ28iLCJNYXRoIiwieDY0IiwiV29yZCIsImhpZ2giLCJsb3ciLCJ0b1gzMiIsIkJhc2U2NCIsIl9tYXAiLCJjaGFyQXQiLCJpbmRleE9mIiwic3FydCIsInBvdyIsIlNIQTI1NiIsIl9oYXNoIiwiZmxvb3IiLCJIbWFjU0hBMjU2IiwiVCIsImVhIiwiU0hBNTEyIiwiRiIsIkciLCJIIiwiSSIsIkoiLCJYIiwiSyIsIlkiLCJMIiwiWiIsIk0iLCIkIiwiTiIsImFhIiwiTyIsImJhIiwiUCIsImNhIiwiUSIsInoiLCJBIiwieSIsIlUiLCJCIiwiUiIsIkMiLCJTIiwiRCIsIlYiLCJFIiwiVyIsImZhIiwiZGEiLCJIbWFjU0hBNTEyIiwiU0hBMzg0IiwiSG1hY1NIQTM4NCIsImI2NG1hcCIsImI2NHBhZCIsImhleDJiNjQiLCJzdWJzdHJpbmciLCJiNjR0b2hleCIsImludDJjaGFyIiwiYjY0dG9CQSIsIkFycmF5IiwiZGJpdHMiLCJjYW5hcnkiLCJqX2xtIiwiQmlnSW50ZWdlciIsImZyb21OdW1iZXIiLCJmcm9tU3RyaW5nIiwibmJpIiwiYW0xIiwiYW0yIiwiYW0zIiwiYXBwTmFtZSIsImFtIiwiREIiLCJETSIsIkRWIiwiQklfRlAiLCJGViIsIkYxIiwiRjIiLCJCSV9STSIsIkJJX1JDIiwicnIiLCJ2diIsImludEF0IiwiYm5wQ29weVRvIiwiYm5wRnJvbUludCIsIm5idiIsImZyb21JbnQiLCJibnBGcm9tU3RyaW5nIiwiZnJvbVJhZGl4IiwiWkVSTyIsInN1YlRvIiwiYm5wQ2xhbXAiLCJiblRvU3RyaW5nIiwibmVnYXRlIiwidG9SYWRpeCIsImJuTmVnYXRlIiwiYm5BYnMiLCJibkNvbXBhcmVUbyIsIm5iaXRzIiwiYm5CaXRMZW5ndGgiLCJibnBETFNoaWZ0VG8iLCJibnBEUlNoaWZ0VG8iLCJibnBMU2hpZnRUbyIsImJucFJTaGlmdFRvIiwiYm5wU3ViVG8iLCJibnBNdWx0aXBseVRvIiwiYWJzIiwiYm5wU3F1YXJlVG8iLCJibnBEaXZSZW1UbyIsImNvcHlUbyIsImxTaGlmdFRvIiwiZGxTaGlmdFRvIiwiY29tcGFyZVRvIiwiT05FIiwiZHJTaGlmdFRvIiwiclNoaWZ0VG8iLCJibk1vZCIsImRpdlJlbVRvIiwiQ2xhc3NpYyIsImNDb252ZXJ0IiwibW9kIiwiY1JldmVydCIsImNSZWR1Y2UiLCJjTXVsVG8iLCJtdWx0aXBseVRvIiwicmVkdWNlIiwiY1NxclRvIiwic3F1YXJlVG8iLCJjb252ZXJ0IiwicmV2ZXJ0IiwibXVsVG8iLCJzcXJUbyIsImJucEludkRpZ2l0IiwiTW9udGdvbWVyeSIsIm1wIiwiaW52RGlnaXQiLCJtcGwiLCJtcGgiLCJ1bSIsIm10MiIsIm1vbnRDb252ZXJ0IiwibW9udFJldmVydCIsIm1vbnRSZWR1Y2UiLCJtb250U3FyVG8iLCJtb250TXVsVG8iLCJibnBJc0V2ZW4iLCJibnBFeHAiLCJibk1vZFBvd0ludCIsImlzRXZlbiIsImV4cCIsImJpdExlbmd0aCIsIm1vZFBvd0ludCIsImJuQ2xvbmUiLCJibkludFZhbHVlIiwiYm5CeXRlVmFsdWUiLCJiblNob3J0VmFsdWUiLCJibnBDaHVua1NpemUiLCJMTjIiLCJsb2ciLCJiblNpZ051bSIsImJucFRvUmFkaXgiLCJzaWdudW0iLCJjaHVua1NpemUiLCJpbnRWYWx1ZSIsImJucEZyb21SYWRpeCIsImRNdWx0aXBseSIsImRBZGRPZmZzZXQiLCJibnBGcm9tTnVtYmVyIiwidGVzdEJpdCIsImJpdHdpc2VUbyIsInNoaWZ0TGVmdCIsIm9wX29yIiwiaXNQcm9iYWJsZVByaW1lIiwibmV4dEJ5dGVzIiwiYm5Ub0J5dGVBcnJheSIsImJuRXF1YWxzIiwiYm5NaW4iLCJibk1heCIsImJucEJpdHdpc2VUbyIsIm9wX2FuZCIsImJuQW5kIiwiYm5PciIsIm9wX3hvciIsImJuWG9yIiwib3BfYW5kbm90IiwiYm5BbmROb3QiLCJibk5vdCIsImJuU2hpZnRMZWZ0IiwiYm5TaGlmdFJpZ2h0IiwibGJpdCIsImJuR2V0TG93ZXN0U2V0Qml0IiwiY2JpdCIsImJuQml0Q291bnQiLCJiblRlc3RCaXQiLCJibnBDaGFuZ2VCaXQiLCJiblNldEJpdCIsImNoYW5nZUJpdCIsImJuQ2xlYXJCaXQiLCJibkZsaXBCaXQiLCJibnBBZGRUbyIsImJuQWRkIiwiYWRkVG8iLCJiblN1YnRyYWN0IiwiYm5NdWx0aXBseSIsImJuU3F1YXJlIiwiYm5EaXZpZGUiLCJiblJlbWFpbmRlciIsImJuRGl2aWRlQW5kUmVtYWluZGVyIiwiYm5wRE11bHRpcGx5IiwiYm5wREFkZE9mZnNldCIsIk51bGxFeHAiLCJuTm9wIiwibk11bFRvIiwiblNxclRvIiwiYm5Qb3ciLCJibnBNdWx0aXBseUxvd2VyVG8iLCJibnBNdWx0aXBseVVwcGVyVG8iLCJCYXJyZXR0IiwicjIiLCJxMyIsIm11IiwiZGl2aWRlIiwiYmFycmV0dENvbnZlcnQiLCJiYXJyZXR0UmV2ZXJ0IiwiYmFycmV0dFJlZHVjZSIsIm11bHRpcGx5VXBwZXJUbyIsIm11bHRpcGx5TG93ZXJUbyIsImJhcnJldHRTcXJUbyIsImJhcnJldHRNdWxUbyIsImJuTW9kUG93IiwiYm5HQ0QiLCJnZXRMb3dlc3RTZXRCaXQiLCJibnBNb2RJbnQiLCJibk1vZEludmVyc2UiLCJzdWJ0cmFjdCIsImFkZCIsImxvd3ByaW1lcyIsImxwbGltIiwiYm5Jc1Byb2JhYmxlUHJpbWUiLCJtb2RJbnQiLCJtaWxsZXJSYWJpbiIsImJucE1pbGxlclJhYmluIiwic2hpZnRSaWdodCIsIm1vZFBvdyIsImJ5dGVWYWx1ZSIsInNob3J0VmFsdWUiLCJ0b0J5dGVBcnJheSIsImVxdWFscyIsImFuZCIsIm9yIiwieG9yIiwiYW5kTm90Iiwibm90IiwiYml0Q291bnQiLCJzZXRCaXQiLCJjbGVhckJpdCIsImZsaXBCaXQiLCJtdWx0aXBseSIsInJlbWFpbmRlciIsImRpdmlkZUFuZFJlbWFpbmRlciIsIm1vZEludmVyc2UiLCJnY2QiLCJzcXVhcmUiLCJBcmNmb3VyIiwiQVJDNGluaXQiLCJBUkM0bmV4dCIsIm5leHQiLCJwcm5nX25ld3N0YXRlIiwicm5nX3BzaXplIiwicm5nX3N0YXRlIiwicm5nX3Bvb2wiLCJybmdfcHB0ciIsInJuZ19zZWVkX2ludCIsInJuZ19zZWVkX3RpbWUiLCJEYXRlIiwiZ2V0VGltZSIsImNyeXB0byIsIm1zQ3J5cHRvIiwiZ2V0UmFuZG9tVmFsdWVzIiwidWEiLCJVaW50OEFycmF5IiwiYXBwVmVyc2lvbiIsInJuZ19nZXRfYnl0ZSIsInJuZ19nZXRfYnl0ZXMiLCJTZWN1cmVSYW5kb20iLCJwYXJzZUJpZ0ludCIsImxpbmVicmsiLCJieXRlMkhleCIsInBrY3MxcGFkMiIsIm9hZXBfbWdmMV9hcnIiLCJvYWVwX3BhZCIsIktKVVIiLCJNZXNzYWdlRGlnZXN0IiwiVXRpbCIsImdldENhbm9uaWNhbEFsZ05hbWUiLCJnZXRIYXNoTGVuZ3RoIiwiaGV4dG9yc3RyIiwiaGFzaEhleCIsInJzdHJ0b2hleCIsIlJTQUtleSIsImRtcDEiLCJkbXExIiwiY29lZmYiLCJSU0FTZXRQdWJsaWMiLCJpc1B1YmxpYyIsImlzUHJpdmF0ZSIsIlJTQURvUHVibGljIiwiUlNBRW5jcnlwdCIsImRvUHVibGljIiwiUlNBRW5jcnlwdE9BRVAiLCJzZXRQdWJsaWMiLCJlbmNyeXB0IiwiZW5jcnlwdE9BRVAiLCJ0eXBlIiwiRUNGaWVsZEVsZW1lbnRGcCIsImZlRnBFcXVhbHMiLCJmZUZwVG9CaWdJbnRlZ2VyIiwiZmVGcE5lZ2F0ZSIsImZlRnBBZGQiLCJ0b0JpZ0ludGVnZXIiLCJmZUZwU3VidHJhY3QiLCJmZUZwTXVsdGlwbHkiLCJmZUZwU3F1YXJlIiwiZmVGcERpdmlkZSIsIkVDUG9pbnRGcCIsImN1cnZlIiwiemludiIsInBvaW50RnBHZXRYIiwiZnJvbUJpZ0ludGVnZXIiLCJwb2ludEZwR2V0WSIsInBvaW50RnBFcXVhbHMiLCJpc0luZmluaXR5IiwicG9pbnRGcElzSW5maW5pdHkiLCJwb2ludEZwTmVnYXRlIiwicG9pbnRGcEFkZCIsInR3aWNlIiwiZ2V0SW5maW5pdHkiLCJwb2ludEZwVHdpY2UiLCJwb2ludEZwTXVsdGlwbHkiLCJwb2ludEZwTXVsdGlwbHlUd28iLCJnZXRYIiwiZ2V0WSIsIm11bHRpcGx5VHdvIiwiRUNDdXJ2ZUZwIiwiaW5maW5pdHkiLCJjdXJ2ZUZwR2V0USIsImN1cnZlRnBHZXRBIiwiY3VydmVGcEdldEIiLCJjdXJ2ZUZwRXF1YWxzIiwiY3VydmVGcEdldEluZmluaXR5IiwiY3VydmVGcEZyb21CaWdJbnRlZ2VyIiwiY3VydmVGcERlY29kZVBvaW50SGV4IiwiZ2V0USIsImdldEEiLCJnZXRCIiwiZGVjb2RlUG9pbnRIZXgiLCJnZXRCeXRlTGVuZ3RoIiwiZ2V0RW5jb2RlZCIsInRvQnl0ZUFycmF5VW5zaWduZWQiLCJ1bnNoaWZ0IiwiZGVjb2RlRnJvbSIsImRlY29kZUZyb21IZXgiLCJhZGQyRCIsInR3aWNlMkQiLCJ2YWx1ZU9mIiwibXVsdGlwbHkyRCIsImlzT25DdXJ2ZSIsInZhbGlkYXRlIiwianNvblBhcnNlIiwiUmVnRXhwIiwibWF0Y2giLCJyZXBsYWNlIiwic2hpZnQiLCJhc24xIiwiQVNOMVV0aWwiLCJpbnRlZ2VyVG9CeXRlSGV4IiwiYmlnSW50VG9NaW5Ud29zQ29tcGxlbWVudHNIZXgiLCJnZXRQRU1TdHJpbmdGcm9tSGV4IiwiaGV4dG9wZW0iLCJuZXdPYmplY3QiLCJERVJCb29sZWFuIiwiREVSSW50ZWdlciIsIkRFUkJpdFN0cmluZyIsIkRFUk9jdGV0U3RyaW5nIiwiREVSTnVsbCIsIkRFUk9iamVjdElkZW50aWZpZXIiLCJERVJFbnVtZXJhdGVkIiwiREVSVVRGOFN0cmluZyIsIkRFUk51bWVyaWNTdHJpbmciLCJERVJQcmludGFibGVTdHJpbmciLCJERVJUZWxldGV4U3RyaW5nIiwiREVSSUE1U3RyaW5nIiwiREVSVVRDVGltZSIsIkRFUkdlbmVyYWxpemVkVGltZSIsIkRFUlNlcXVlbmNlIiwiREVSU2V0IiwiREVSVGFnZ2VkT2JqZWN0Iiwia2V5cyIsImFycmF5IiwidGFnIiwiZXhwbGljaXQiLCJvYmoiLCJqc29uVG9BU04xSEVYIiwiZ2V0RW5jb2RlZEhleCIsIm9pZEhleFRvSW50Iiwib2lkSW50VG9IZXgiLCJzcGxpdCIsIkFTTjFPYmplY3QiLCJnZXRMZW5ndGhIZXhGcm9tVmFsdWUiLCJoViIsImhUTFYiLCJpc01vZGlmaWVkIiwiZ2V0RnJlc2hWYWx1ZUhleCIsImhMIiwiaFQiLCJnZXRWYWx1ZUhleCIsIkRFUkFic3RyYWN0U3RyaW5nIiwiZ2V0U3RyaW5nIiwic2V0U3RyaW5nIiwidXRmOHRvaGV4IiwidG9Mb3dlckNhc2UiLCJzZXRTdHJpbmdIZXgiLCJzdHIiLCJoZXgiLCJERVJBYnN0cmFjdFRpbWUiLCJsb2NhbERhdGVUb1VUQyIsInV0YyIsImdldFRpbWV6b25lT2Zmc2V0IiwiZm9ybWF0RGF0ZSIsInplcm9QYWRkaW5nIiwiZ2V0RnVsbFllYXIiLCJnZXRNb250aCIsImdldERhdGUiLCJnZXRIb3VycyIsImdldE1pbnV0ZXMiLCJnZXRTZWNvbmRzIiwiZ2V0TWlsbGlzZWNvbmRzIiwic3RvaGV4Iiwic2V0QnlEYXRlVmFsdWUiLCJVVEMiLCJzZXRCeURhdGUiLCJERVJBYnN0cmFjdFN0cnVjdHVyZWQiLCJzZXRCeUFTTjFPYmplY3RBcnJheSIsImFzbjFBcnJheSIsImFwcGVuZEFTTjFPYmplY3QiLCJzZXRCeUJpZ0ludGVnZXIiLCJzZXRCeUludGVnZXIiLCJzZXRWYWx1ZUhleCIsImJpZ2ludCIsInNldEhleFZhbHVlSW5jbHVkaW5nVW51c2VkQml0cyIsInNldFVudXNlZEJpdHNBbmRIZXhWYWx1ZSIsInNldEJ5QmluYXJ5U3RyaW5nIiwic2V0QnlCb29sZWFuQXJyYXkiLCJuZXdGYWxzZUFycmF5IiwiYmluIiwic2V0VmFsdWVPaWRTdHJpbmciLCJzZXRWYWx1ZU5hbWUiLCJ4NTA5IiwiT0lEIiwibmFtZTJvaWQiLCJvaWQiLCJuYW1lIiwiZGF0ZSIsIndpdGhNaWxsaXMiLCJtaWxsaXMiLCJzb3J0RmxhZyIsInNvcnQiLCJzb3J0ZmxhZyIsImlzRXhwbGljaXQiLCJhc24xT2JqZWN0Iiwic2V0QVNOMU9iamVjdCIsIkFTTjFIRVgiLCJnZXRMYmxlbiIsImdldEwiLCJnZXRWYmxlbiIsImdldFZpZHgiLCJnZXRWIiwiZ2V0VExWIiwiZ2V0TmV4dFNpYmxpbmdJZHgiLCJnZXRDaGlsZElkeCIsImdldE50aENoaWxkSWR4IiwiZ2V0SWR4YnlMaXN0IiwiZ2V0VExWYnlMaXN0IiwiZ2V0VmJ5TGlzdCIsImhleHRvb2lkc3RyIiwiZHVtcCIsIm9tbWl0X2xvbmdfb2N0ZXQiLCJpc0FTTjFIRVgiLCJvaWQybmFtZSIsImhleHRvdXRmOCIsIm9pZG5hbWUiLCJKU09OIiwieDUwOUV4dE5hbWUiLCJpc0hleCIsIkJhc2U2NHgiLCJzdG9CQSIsIkJBdG9zIiwiQkF0b2hleCIsInN0b2I2NCIsInN0b2I2NHUiLCJiNjR0b2I2NHUiLCJiNjR1dG9zIiwiYjY0dXRvYjY0IiwiaGV4dG9iNjR1IiwiYjY0dXRvaGV4IiwidXRmOHRvYjY0dSIsImI2NHV0b3V0ZjgiLCJCdWZmZXIiLCJ1cmljbXB0b2hleCIsImVuY29kZVVSSUNvbXBvbmVudEFsbCIsImhleHRvdXJpY21wIiwidXRmOHRvYjY0IiwiYjY0dG91dGY4IiwiaGV4dG9iNjQiLCJoZXh0b2I2NG5sIiwiYjY0bmx0b2hleCIsInBlbXRvaGV4IiwiaGV4dG9BcnJheUJ1ZmZlciIsIkFycmF5QnVmZmVyIiwiRGF0YVZpZXciLCJzZXRVaW50OCIsIkFycmF5QnVmZmVydG9oZXgiLCJieXRlTGVuZ3RoIiwiZ2V0VWludDgiLCJ6dWx1dG9tc2VjIiwienVsdXRvc2VjIiwienVsdXRvZGF0ZSIsImRhdGV0b3p1bHUiLCJnZXRVVENGdWxsWWVhciIsImdldFVUQ01vbnRoIiwiZ2V0VVRDRGF0ZSIsImdldFVUQ0hvdXJzIiwiZ2V0VVRDTWludXRlcyIsImdldFVUQ1NlY29uZHMiLCJnZXRVVENNaWxsaXNlY29uZHMiLCJpcHY2dG9oZXgiLCJyZXBlYXQiLCJoZXh0b2lwdjYiLCJoZXh0b2lwIiwiaXB0b2hleCIsIm5ld2xpbmVfdG9Vbml4IiwibmV3bGluZV90b0RvcyIsImlzSW50ZWdlciIsImlzQmFzZTY0IiwiaXNCYXNlNjRVUkwiLCJpc0ludGVnZXJBcnJheSIsImhleHRvcG9zaGV4IiwiaW50YXJ5c3RydG9oZXgiLCJtYXAiLCJzdHJkaWZmaWR4IiwiRElHRVNUSU5GT0hFQUQiLCJzaGExIiwic2hhMjI0Iiwic2hhMjU2Iiwic2hhMzg0Iiwic2hhNTEyIiwibWQyIiwibWQ1IiwicmlwZW1kMTYwIiwiREVGQVVMVFBST1ZJREVSIiwiaG1hY21kNSIsImhtYWNzaGExIiwiaG1hY3NoYTIyNCIsImhtYWNzaGEyNTYiLCJobWFjc2hhMzg0IiwiaG1hY3NoYTUxMiIsImhtYWNyaXBlbWQxNjAiLCJNRDV3aXRoUlNBIiwiU0hBMXdpdGhSU0EiLCJTSEEyMjR3aXRoUlNBIiwiU0hBMjU2d2l0aFJTQSIsIlNIQTM4NHdpdGhSU0EiLCJTSEE1MTJ3aXRoUlNBIiwiUklQRU1EMTYwd2l0aFJTQSIsIk1ENXdpdGhFQ0RTQSIsIlNIQTF3aXRoRUNEU0EiLCJTSEEyMjR3aXRoRUNEU0EiLCJTSEEyNTZ3aXRoRUNEU0EiLCJTSEEzODR3aXRoRUNEU0EiLCJTSEE1MTJ3aXRoRUNEU0EiLCJSSVBFTUQxNjB3aXRoRUNEU0EiLCJTSEExd2l0aERTQSIsIlNIQTIyNHdpdGhEU0EiLCJTSEEyNTZ3aXRoRFNBIiwiTUQ1d2l0aFJTQWFuZE1HRjEiLCJTSEExd2l0aFJTQWFuZE1HRjEiLCJTSEEyMjR3aXRoUlNBYW5kTUdGMSIsIlNIQTI1NndpdGhSU0FhbmRNR0YxIiwiU0hBMzg0d2l0aFJTQWFuZE1HRjEiLCJTSEE1MTJ3aXRoUlNBYW5kTUdGMSIsIlJJUEVNRDE2MHdpdGhSU0FhbmRNR0YxIiwiQ1JZUFRPSlNNRVNTQUdFRElHRVNUTkFNRSIsIk1ENSIsIlNIQTEiLCJTSEEyMjQiLCJSSVBFTUQxNjAiLCJnZXREaWdlc3RJbmZvSGV4IiwiZ2V0UGFkZGVkRGlnZXN0SW5mb0hleCIsImhhc2hTdHJpbmciLCJhbGciLCJkaWdlc3RTdHJpbmciLCJkaWdlc3RIZXgiLCJwcm92Iiwic2hhMjU2SGV4Iiwic2hhNTEySGV4IiwiU0VDVVJFUkFORE9NR0VOIiwiZ2V0UmFuZG9tSGV4T2ZOYnl0ZXMiLCJnZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYnl0ZXMiLCJnZXRSYW5kb21IZXhPZk5iaXRzIiwiZ2V0UmFuZG9tQmlnSW50ZWdlck9mTmJpdHMiLCJnZXRSYW5kb21CaWdJbnRlZ2VyWmVyb1RvTWF4IiwiZ2V0UmFuZG9tQmlnSW50ZWdlck1pblRvTWF4Iiwic2V0QWxnQW5kUHJvdmlkZXIiLCJtZCIsInVwZGF0ZVN0cmluZyIsInVwZGF0ZUhleCIsImRpZ2VzdCIsInNqY2wiLCJoYXNoIiwiY29kZWMiLCJ0b0JpdHMiLCJmcm9tQml0cyIsImFsZ05hbWUiLCJwcm92TmFtZSIsIkhBU0hMRU5HVEgiLCJNYWMiLCJhbGdQcm92IiwibWFjIiwicGFzcyIsImRvRmluYWwiLCJkb0ZpbmFsU3RyaW5nIiwiZG9GaW5hbEhleCIsInNldFBhc3N3b3JkIiwidXRmOCIsInJzdHIiLCJiNjQiLCJiNjR1IiwiU2lnbmF0dXJlIiwiX3NldEFsZ05hbWVzIiwibWRBbGdOYW1lIiwicHVia2V5QWxnTmFtZSIsIl96ZXJvUGFkZGluZ09mU2lnbmF0dXJlIiwiS0VZVVRJTCIsImdldEtleSIsInBydktleSIsInN0YXRlIiwicHViS2V5Iiwic2lnbiIsInNIYXNoSGV4IiwiZWNwcnZoZXgiLCJlY2N1cnZlbmFtZSIsIkVDRFNBIiwiaFNpZ24iLCJzaWduSGV4Iiwic2lnbldpdGhNZXNzYWdlSGFzaFBTUyIsInBzc1NhbHRMZW4iLCJzaWduV2l0aE1lc3NhZ2VIYXNoIiwiRFNBIiwic2lnblN0cmluZyIsInZlcmlmeSIsImVjcHViaGV4IiwidmVyaWZ5SGV4IiwidmVyaWZ5V2l0aE1lc3NhZ2VIYXNoUFNTIiwidmVyaWZ5V2l0aE1lc3NhZ2VIYXNoIiwiYWxnUHJvdk5hbWUiLCJpbml0UGFyYW1zIiwicHNzc2FsdGxlbiIsInBydmtleXBlbSIsInBydmtleXBhcyIsIkNpcGhlciIsImdldEFsZ0J5S2V5QW5kTmFtZSIsImRlY3J5cHQiLCJkZWNyeXB0T0FFUCIsIm9pZGhleDJuYW1lIiwiZ2V0QmlnUmFuZG9tIiwic2V0TmFtZWRDdXJ2ZSIsImVjcGFyYW1zIiwiRUNQYXJhbWV0ZXJEQiIsImdldEJ5TmFtZSIsInBydktleUhleCIsInB1YktleUhleCIsImN1cnZlTmFtZSIsInNldFByaXZhdGVLZXlIZXgiLCJzZXRQdWJsaWNLZXlIZXgiLCJnZXRQdWJsaWNLZXlYWUhleCIsImtleWxlbiIsImdldFNob3J0TklTVFBDdXJ2ZU5hbWUiLCJnZW5lcmF0ZUtleVBhaXJIZXgiLCJiaVJTU2lnVG9BU04xU2lnIiwiZnJvbUJ5dGVBcnJheVVuc2lnbmVkIiwic2VyaWFsaXplU2lnIiwicGFyc2VTaWdIZXgiLCJ2ZXJpZnlSYXciLCJCaXRjb2luIiwiaXNBcnJheSIsInBhcnNlU2lnIiwidG9CeXRlQXJyYXlTaWduZWQiLCJwYXJzZVNpZ0NvbXBhY3QiLCJyZWFkUEtDUzVQcnZLZXlIZXgiLCJnZXROYW1lIiwicmVhZFBLQ1M4UHJ2S2V5SGV4IiwicmVhZFBLQ1M4UHViS2V5SGV4IiwicmVhZENlcnRQdWJLZXlIZXgiLCJwcnYiLCJwdWIiLCJwYXJzZVNpZ0hleEluSGV4UlMiLCJhc24xU2lnVG9Db25jYXRTaWciLCJjb25jYXRTaWdUb0FTTjFTaWciLCJoZXhSU1NpZ1RvQVNOMVNpZyIsInJlZ2lzdCIsIkFFUyIsIlRyaXBsZURFUyIsIkRFUyIsImtleSIsIml2IiwiY2lwaGVydGV4dCIsInByb2MiLCJlcHJvYyIsIml2bGVuIiwiY2lwaGVyIiwiaXZzYWx0IiwiZGF0YSIsImtleWhleCIsIml2aGV4IiwidmVyc2lvbiIsInBhcnNlUEtDUzVQRU0iLCJnZXRLZXlBbmRVbnVzZWRJdkJ5UGFzc2NvZGVBbmRJdnNhbHQiLCJkZWNyeXB0S2V5QjY0IiwiZ2V0RGVjcnlwdGVkS2V5SGV4IiwiZ2V0RW5jcnlwdGVkUEtDUzVQRU1Gcm9tUHJ2S2V5SGV4IiwidG9VcHBlckNhc2UiLCJwYXJzZUhleE9mRW5jcnlwdGVkUEtDUzgiLCJlbmNyeXB0aW9uU2NoZW1lQWxnIiwiZW5jcnlwdGlvblNjaGVtZUlWIiwicGJrZGYyU2FsdCIsInBia2RmMkl0ZXIiLCJnZXRQQktERjJLZXlIZXhGcm9tUGFyYW0iLCJQQktERjIiLCJrZXlTaXplIiwiaXRlcmF0aW9ucyIsIl9nZXRQbGFpblBLQ1M4SGV4RnJvbUVuY3J5cHRlZFBLQ1M4UEVNIiwiZ2V0S2V5RnJvbUVuY3J5cHRlZFBLQ1M4UEVNIiwiZ2V0S2V5RnJvbVBsYWluUHJpdmF0ZVBLQ1M4SGV4IiwicGFyc2VQbGFpblByaXZhdGVQS0NTOEhleCIsImFsZ3BhcmFtIiwiYWxnb2lkIiwia2V5aWR4IiwiZ2V0S2V5RnJvbVBsYWluUHJpdmF0ZVBLQ1M4UEVNIiwiX2dldEtleUZyb21QdWJsaWNQS0NTOEhleCIsInBhcnNlUHVibGljUmF3UlNBS2V5SGV4IiwicGFyc2VQdWJsaWNQS0NTOEhleCIsInh5Iiwia3R5IiwiZHAiLCJkcSIsImNvIiwicWkiLCJzZXRQcml2YXRlRXgiLCJzZXRQcml2YXRlIiwiY3J2IiwiWDUwOSIsImdldFB1YmxpY0tleUZyb21DZXJ0SGV4IiwiZ2V0UHVibGljS2V5RnJvbUNlcnRQRU0iLCJnZW5lcmF0ZUtleXBhaXIiLCJnZW5lcmF0ZSIsInBydktleU9iaiIsInB1YktleU9iaiIsImdldFBFTSIsIlN1YmplY3RQdWJsaWNLZXlJbmZvIiwic2VxIiwib2N0c3RyIiwiYml0c3RyIiwiZ2V0S2V5RnJvbUNTUlBFTSIsImdldEtleUZyb21DU1JIZXgiLCJwYXJzZUNTUkhleCIsInA4cHVia2V5aGV4IiwiZ2V0SldLRnJvbUtleSIsImdldFBvc0FycmF5T2ZDaGlsZHJlbkZyb21IZXgiLCJnZXRIZXhWYWx1ZUFycmF5T2ZDaGlsZHJlbkZyb21IZXgiLCJyZWFkUHJpdmF0ZUtleUZyb21QRU1TdHJpbmciLCJyZWFkUEtDUzVQdWJLZXlIZXgiLCJyZWFkQ2VydEhleCIsImdldFB1YmxpY0tleUhleCIsIl9SRV9IRVhERUNPTkxZIiwiY29tcGlsZSIsIl9yc2FzaWduX2dldEhleFBhZGRlZERpZ2VzdEluZm9Gb3JTdHJpbmciLCJkb1ByaXZhdGUiLCJwc3NfbWdmMV9zdHIiLCJzaWduUFNTIiwiX3JzYXNpZ25fZ2V0RGVjcnlwdFNpZ25hdHVyZUJJIiwiX3JzYXNpZ25fZ2V0SGV4RGlnZXN0SW5mb0Zyb21TaWciLCJfcnNhc2lnbl9nZXRBbGdOYW1lQW5kSGFzaEZyb21IZXhEaXNnZXN0SW5mbyIsInZlcmlmeVBTUyIsIlNBTFRfTEVOX0hMRU4iLCJTQUxUX0xFTl9NQVgiLCJTQUxUX0xFTl9SRUNPVkVSIiwiZm9mZnNldCIsImFFeHRJbmZvIiwiZ2V0VmVyc2lvbiIsImdldFNlcmlhbE51bWJlckhleCIsImdldFNpZ25hdHVyZUFsZ29yaXRobUZpZWxkIiwiZ2V0SXNzdWVySGV4IiwiZ2V0SXNzdWVyU3RyaW5nIiwiaGV4MmRuIiwiZ2V0U3ViamVjdEhleCIsImdldFN1YmplY3RTdHJpbmciLCJnZXROb3RCZWZvcmUiLCJnZXROb3RBZnRlciIsImdldFB1YmxpY0tleUlkeCIsImdldFB1YmxpY0tleUNvbnRlbnRJZHgiLCJnZXRQdWJsaWNLZXkiLCJnZXRTaWduYXR1cmVBbGdvcml0aG1OYW1lIiwiZ2V0U2lnbmF0dXJlVmFsdWVIZXgiLCJ2ZXJpZnlTaWduYXR1cmUiLCJwYXJzZUV4dCIsImNyaXRpY2FsIiwidmlkeCIsImdldEV4dEluZm8iLCJnZXRFeHRCYXNpY0NvbnN0cmFpbnRzIiwiY0EiLCJwYXRoTGVuIiwiZ2V0RXh0S2V5VXNhZ2VCaW4iLCJnZXRFeHRLZXlVc2FnZVN0cmluZyIsIktFWVVTQUdFX05BTUUiLCJnZXRFeHRTdWJqZWN0S2V5SWRlbnRpZmllciIsImdldEV4dEF1dGhvcml0eUtleUlkZW50aWZpZXIiLCJraWQiLCJnZXRFeHRFeHRLZXlVc2FnZU5hbWUiLCJnZXRFeHRTdWJqZWN0QWx0TmFtZSIsImdldEV4dFN1YmplY3RBbHROYW1lMiIsImdldEV4dENSTERpc3RyaWJ1dGlvblBvaW50c1VSSSIsImdldEV4dEFJQUluZm8iLCJvY3NwIiwiY2Fpc3N1ZXIiLCJnZXRFeHRDZXJ0aWZpY2F0ZVBvbGljaWVzIiwiaWQiLCJjcHMiLCJ1bm90aWNlIiwicmVhZENlcnRQRU0iLCJnZXRJbmZvIiwiaGV4MnJkbiIsImhleDJhdHRyVHlwZVZhbHVlIiwib2lkMmF0eXBlIiwiZ2V0UHVibGljS2V5SW5mb1Byb3BPZkNlcnRQRU0iLCJqd3MiLCJKV1MiLCJpc1NhZmVKU09OU3RyaW5nIiwicGFyc2VKV1MiLCJwYXJzZWRKV1MiLCJzaWd2YWxIIiwiaGVhZEI2NFUiLCJwYXlsb2FkQjY0VSIsInNpZ3ZhbEI2NFUiLCJzaSIsInNpZ3ZhbEJJIiwiaGVhZFMiLCJwYXlsb2FkUyIsInJlYWRTYWZlSlNPTlN0cmluZyIsImp3c2FsZzJzaWdhbGciLCJoQVNOMVNpZyIsImhlYWRlck9iaiIsInBheWxvYWRPYmoiLCJoZWFkZXJQUCIsInBheWxvYWRQUCIsInNpZ0hleCIsInZlcmlmeUpXVCIsImluQXJyYXkiLCJpbmNsdWRlZEFycmF5IiwiaXNzIiwic3ViIiwiYXVkIiwiSW50RGF0ZSIsImdldE5vdyIsInZlcmlmeUF0IiwiZ3JhY2VQZXJpb2QiLCJuYmYiLCJpYXQiLCJqdGkiLCJIUzI1NiIsIkhTMzg0IiwiSFM1MTIiLCJSUzI1NiIsIlJTMzg0IiwiUlM1MTIiLCJFUzI1NiIsIkVTMzg0IiwiUFMyNTYiLCJQUzM4NCIsIlBTNTEyIiwibm9uZSIsImdldEVuY29kZWRTaWduYXR1cmVWYWx1ZUZyb21KV1MiLCJnZXRKV0t0aHVtYnByaW50IiwiZ2V0IiwiZ2V0WnVsdSIsImludERhdGUyVVRDU3RyaW5nIiwidG9VVENTdHJpbmciLCJpbnREYXRlMlp1bHUiLCJFRFNBIiwiX2NyeXB0byIsIkRlZmF1bHRBY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZSIsImFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lIiwiYWNjZXNzVG9rZW5FeHBpcmluZ1RpbWVyIiwiVGltZXIiLCJhY2Nlc3NUb2tlbkV4cGlyZWRUaW1lciIsIl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZSIsIl9hY2Nlc3NUb2tlbkV4cGlyaW5nIiwiX2FjY2Vzc1Rva2VuRXhwaXJlZCIsImxvYWQiLCJjb250YWluZXIiLCJhY2Nlc3NfdG9rZW4iLCJleHBpcmVzX2luIiwiZHVyYXRpb24iLCJkZWJ1ZyIsImV4cGlyaW5nIiwiY2FuY2VsIiwiZXhwaXJlZCIsInVubG9hZCIsImFkZEFjY2Vzc1Rva2VuRXhwaXJpbmciLCJjYiIsImFkZEhhbmRsZXIiLCJyZW1vdmVBY2Nlc3NUb2tlbkV4cGlyaW5nIiwicmVtb3ZlSGFuZGxlciIsImFkZEFjY2Vzc1Rva2VuRXhwaXJlZCIsInJlbW92ZUFjY2Vzc1Rva2VuRXhwaXJlZCIsIkRlZmF1bHRJbnRlcnZhbCIsImNhbGxiYWNrIiwiY2xpZW50X2lkIiwidXJsIiwiaW50ZXJ2YWwiLCJzdG9wT25FcnJvciIsIl9jYWxsYmFjayIsIl9jbGllbnRfaWQiLCJfdXJsIiwiX2ludGVydmFsIiwiX3N0b3BPbkVycm9yIiwiaWR4IiwiX2ZyYW1lX29yaWdpbiIsIl9mcmFtZSIsImRvY3VtZW50IiwiY3JlYXRlRWxlbWVudCIsInN0eWxlIiwidmlzaWJpbGl0eSIsInBvc2l0aW9uIiwiZGlzcGxheSIsIndpZHRoIiwiaGVpZ2h0Iiwic3JjIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvbmxvYWQiLCJib2R5IiwiYXBwZW5kQ2hpbGQiLCJfYm91bmRNZXNzYWdlRXZlbnQiLCJfbWVzc2FnZSIsImJpbmQiLCJhZGRFdmVudExpc3RlbmVyIiwib3JpZ2luIiwic291cmNlIiwiY29udGVudFdpbmRvdyIsImVycm9yIiwic3RvcCIsInN0YXJ0Iiwic2Vzc2lvbl9zdGF0ZSIsIl9zZXNzaW9uX3N0YXRlIiwic2VuZCIsInBvc3RNZXNzYWdlIiwiX3RpbWVyIiwic2V0SW50ZXJ2YWwiLCJjbGVhckludGVydmFsIiwicHJlcGFyZSIsInBhcmFtcyIsInBvcHVwV2luZG93RmVhdHVyZXMiLCJwb3B1cCIsIkNvcmRvdmFQb3B1cFdpbmRvdyIsIkRlZmF1bHRQb3B1cEZlYXR1cmVzIiwiRGVmYXVsdFBvcHVwVGFyZ2V0IiwiX3Byb21pc2UiLCJyZWplY3QiLCJfcmVzb2x2ZSIsIl9yZWplY3QiLCJmZWF0dXJlcyIsInRhcmdldCIsInBvcHVwV2luZG93VGFyZ2V0IiwicmVkaXJlY3RfdXJpIiwic3RhcnRVcmwiLCJfaXNJbkFwcEJyb3dzZXJJbnN0YWxsZWQiLCJjb3Jkb3ZhTWV0YWRhdGEiLCJzb21lIiwibmF2aWdhdGUiLCJfZXJyb3IiLCJjb3Jkb3ZhIiwicmVxdWlyZSIsIm1ldGFkYXRhIiwiX3BvcHVwIiwiSW5BcHBCcm93c2VyIiwib3BlbiIsIl9leGl0Q2FsbGJhY2tFdmVudCIsIl9leGl0Q2FsbGJhY2siLCJfbG9hZFN0YXJ0Q2FsbGJhY2tFdmVudCIsIl9sb2FkU3RhcnRDYWxsYmFjayIsInByb21pc2UiLCJldmVudCIsIl9zdWNjZXNzIiwibWVzc2FnZSIsIl9jbGVhbnVwIiwiY2xvc2UiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiRXJyb3JSZXNwb25zZSIsImVycm9yX2Rlc2NyaXB0aW9uIiwiZXJyb3JfdXJpIiwiRXZlbnQiLCJfbmFtZSIsIl9jYWxsYmFja3MiLCJmaW5kSW5kZXgiLCJpdGVtIiwicmFpc2UiLCJ0aW1lciIsImhhbmRsZSIsInRlc3RpbmciLCJyZXF1ZXN0IiwiX3Rlc3RpbmciLCJzZXRYTUxIdHRwUmVxdWVzdCIsIm5ld1JlcXVlc3QiLCJsb2NhdGlvbiIsImxvY2FsU3RvcmFnZSIsInNlc3Npb25TdG9yYWdlIiwiWE1MSHR0cFJlcXVlc3QiLCJJRnJhbWVOYXZpZ2F0b3IiLCJmcmFtZSIsIklGcmFtZVdpbmRvdyIsIm5vdGlmeVBhcmVudCIsIkRlZmF1bHRUaW1lb3V0IiwidGltZW91dCIsInNpbGVudFJlcXVlc3RUaW1lb3V0Iiwic2V0VGltZW91dCIsIl90aW1lb3V0IiwiY2xlYXJUaW1lb3V0IiwicmVtb3ZlQ2hpbGQiLCJfb3JpZ2luIiwiZnJhbWVFbGVtZW50IiwiaHJlZiIsInBhcmVudCIsInByb3RvY29sIiwiaG9zdCIsImdldEl0ZW0iLCJzZXRJdGVtIiwidmFsdWUiLCJyZW1vdmVJdGVtIiwiaW5kZXgiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwiSm9zZVV0aWwiLCJLZXlVdGlsIiwiQWxsb3dlZFNpZ25pbmdBbGdzIiwiZ2V0Sm9zZVV0aWwiLCJwYXJzZUp3dCIsImp3dCIsInRva2VuIiwiaGVhZGVyIiwicGF5bG9hZCIsInZhbGlkYXRlSnd0IiwiaXNzdWVyIiwiYXVkaWVuY2UiLCJjbG9ja1NrZXciLCJub3ciLCJ0aW1lSW5zZW5zaXRpdmUiLCJ4NWMiLCJfdmFsaWRhdGVKd3QiLCJ2YWxpZGF0ZUp3dEF0dHJpYnV0ZXMiLCJ2YWxpZEF1ZGllbmNlIiwiYXpwIiwibG93ZXJOb3ciLCJ1cHBlck5vdyIsInRoZW4iLCJoZXhUb0Jhc2U2NFVybCIsIkpzb25TZXJ2aWNlIiwiYWRkaXRpb25hbENvbnRlbnRUeXBlcyIsIlhNTEh0dHBSZXF1ZXN0Q3RvciIsImp3dEhhbmRsZXIiLCJfY29udGVudFR5cGVzIiwiX1hNTEh0dHBSZXF1ZXN0IiwiX2p3dEhhbmRsZXIiLCJnZXRKc29uIiwicmVxIiwiYWxsb3dlZENvbnRlbnRUeXBlcyIsInN0YXR1cyIsImNvbnRlbnRUeXBlIiwiZ2V0UmVzcG9uc2VIZWFkZXIiLCJmb3VuZCIsImZpbmQiLCJzdGFydHNXaXRoIiwicmVzcG9uc2VUZXh0Iiwic3RhdHVzVGV4dCIsIm9uZXJyb3IiLCJzZXRSZXF1ZXN0SGVhZGVyIiwicG9zdEZvcm0iLCJub3BMb2dnZXIiLCJpbmZvIiwid2FybiIsIk5PTkUiLCJFUlJPUiIsIldBUk4iLCJJTkZPIiwiREVCVUciLCJsb2dnZXIiLCJsZXZlbCIsImFyZ3MiLCJmcm9tIiwiT2lkY01ldGFkYXRhVXJsUGF0aCIsInNldHRpbmdzIiwiSnNvblNlcnZpY2VDdG9yIiwiX3NldHRpbmdzIiwiX2pzb25TZXJ2aWNlIiwiZ2V0TWV0YWRhdGEiLCJtZXRhZGF0YVVybCIsImdldElzc3VlciIsIl9nZXRNZXRhZGF0YVByb3BlcnR5IiwiZ2V0QXV0aG9yaXphdGlvbkVuZHBvaW50IiwiZ2V0VXNlckluZm9FbmRwb2ludCIsImdldFRva2VuRW5kcG9pbnQiLCJvcHRpb25hbCIsImdldENoZWNrU2Vzc2lvbklmcmFtZSIsImdldEVuZFNlc3Npb25FbmRwb2ludCIsImdldFJldm9jYXRpb25FbmRwb2ludCIsImdldEtleXNFbmRwb2ludCIsImdldFNpZ25pbmdLZXlzIiwic2lnbmluZ0tleXMiLCJqd2tzX3VyaSIsImtleVNldCIsIl9tZXRhZGF0YVVybCIsImF1dGhvcml0eSIsImNyZWF0ZVNpZ25pblJlcXVlc3QiLCJyZXNwb25zZV90eXBlIiwic2NvcGUiLCJwcm9tcHQiLCJtYXhfYWdlIiwidWlfbG9jYWxlcyIsImlkX3Rva2VuX2hpbnQiLCJsb2dpbl9oaW50IiwiYWNyX3ZhbHVlcyIsInJlc291cmNlIiwicmVxdWVzdF91cmkiLCJyZXNwb25zZV9tb2RlIiwiZXh0cmFRdWVyeVBhcmFtcyIsImV4dHJhVG9rZW5QYXJhbXMiLCJyZXF1ZXN0X3R5cGUiLCJza2lwVXNlckluZm8iLCJzdGF0ZVN0b3JlIiwiU2lnbmluUmVxdWVzdCIsImlzQ29kZSIsIl9tZXRhZGF0YVNlcnZpY2UiLCJzaWduaW5SZXF1ZXN0IiwiY2xpZW50X3NlY3JldCIsInNpZ25pblN0YXRlIiwiX3N0YXRlU3RvcmUiLCJzZXQiLCJ0b1N0b3JhZ2VTdHJpbmciLCJyZWFkU2lnbmluUmVzcG9uc2VTdGF0ZSIsInJlbW92ZVN0YXRlIiwidXNlUXVlcnkiLCJkZWxpbWl0ZXIiLCJyZXNwb25zZSIsIlNpZ25pblJlc3BvbnNlIiwic3RhdGVBcGkiLCJyZW1vdmUiLCJzdG9yZWRTdGF0ZVN0cmluZyIsIlNpZ25pblN0YXRlIiwiZnJvbVN0b3JhZ2VTdHJpbmciLCJwcm9jZXNzU2lnbmluUmVzcG9uc2UiLCJfdmFsaWRhdG9yIiwidmFsaWRhdGVTaWduaW5SZXNwb25zZSIsImNyZWF0ZVNpZ25vdXRSZXF1ZXN0IiwicG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIiwiU2lnbm91dFJlcXVlc3QiLCJzaWdub3V0U3RhdGUiLCJyZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUiLCJTaWdub3V0UmVzcG9uc2UiLCJzdGF0ZUtleSIsIlN0YXRlIiwicHJvY2Vzc1NpZ25vdXRSZXNwb25zZSIsInZhbGlkYXRlU2lnbm91dFJlc3BvbnNlIiwiY2xlYXJTdGFsZVN0YXRlIiwic3RhbGVTdGF0ZUFnZSIsInZhbGlkYXRvciIsIm1ldGFkYXRhU2VydmljZSIsIkRlZmF1bHRSZXNwb25zZVR5cGUiLCJEZWZhdWx0U2NvcGUiLCJEZWZhdWx0U3RhbGVTdGF0ZUFnZSIsIkRlZmF1bHRDbG9ja1NrZXdJblNlY29uZHMiLCJmaWx0ZXJQcm90b2NvbENsYWltcyIsImxvYWRVc2VySW5mbyIsInVzZXJJbmZvSnd0SXNzdWVyIiwiUmVzcG9uc2VWYWxpZGF0b3JDdG9yIiwiUmVzcG9uc2VWYWxpZGF0b3IiLCJNZXRhZGF0YVNlcnZpY2VDdG9yIiwiX2F1dGhvcml0eSIsIl9tZXRhZGF0YSIsIl9zaWduaW5nS2V5cyIsIl9jbGllbnRfc2VjcmV0IiwiX3Jlc3BvbnNlX3R5cGUiLCJfc2NvcGUiLCJfcmVkaXJlY3RfdXJpIiwiX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIl9wcm9tcHQiLCJfZGlzcGxheSIsIl9tYXhfYWdlIiwiX3VpX2xvY2FsZXMiLCJfYWNyX3ZhbHVlcyIsIl9yZXNvdXJjZSIsIl9yZXNwb25zZV9tb2RlIiwiX2ZpbHRlclByb3RvY29sQ2xhaW1zIiwiX2xvYWRVc2VySW5mbyIsIl9zdGFsZVN0YXRlQWdlIiwiX2Nsb2NrU2tldyIsIl91c2VySW5mb0p3dElzc3VlciIsIl9leHRyYVF1ZXJ5UGFyYW1zIiwiX2V4dHJhVG9rZW5QYXJhbXMiLCJQb3B1cE5hdmlnYXRvciIsIlBvcHVwV2luZG93Iiwia2VlcE9wZW4iLCJub3RpZnlPcGVuZXIiLCJDaGVja0ZvclBvcHVwQ2xvc2VkSW50ZXJ2YWwiLCJfY2hlY2tGb3JQb3B1cENsb3NlZFRpbWVyIiwiX2NoZWNrRm9yUG9wdXBDbG9zZWQiLCJfaWQiLCJmb2N1cyIsImNsb3NlZCIsIm9wZW5lciIsIlVybFV0aWxpdHkiLCJwYXJzZVVybEZyYWdtZW50IiwiUmVkaXJlY3ROYXZpZ2F0b3IiLCJ1c2VSZXBsYWNlVG9OYXZpZ2F0ZSIsIlByb3RvY29sQ2xhaW1zIiwiVXNlckluZm9TZXJ2aWNlQ3RvciIsIlVzZXJJbmZvU2VydmljZSIsImpvc2VVdGlsIiwiVG9rZW5DbGllbnRDdG9yIiwiVG9rZW5DbGllbnQiLCJfdXNlckluZm9TZXJ2aWNlIiwiX2pvc2VVdGlsIiwiX3Rva2VuQ2xpZW50IiwiX3Byb2Nlc3NTaWduaW5QYXJhbXMiLCJfdmFsaWRhdGVUb2tlbnMiLCJfcHJvY2Vzc0NsYWltcyIsIm5vbmNlIiwiaWRfdG9rZW4iLCJjb2RlX3ZlcmlmaWVyIiwiY29kZSIsImlzT3BlbklkQ29ubmVjdCIsInByb2ZpbGUiLCJnZXRDbGFpbXMiLCJjbGFpbXMiLCJfbWVyZ2VDbGFpbXMiLCJjbGFpbXMxIiwiY2xhaW1zMiIsInJlc3VsdCIsImFzc2lnbiIsInZhbHVlcyIsImZvckVhY2giLCJfcHJvY2Vzc0NvZGUiLCJfdmFsaWRhdGVJZFRva2VuQW5kQWNjZXNzVG9rZW4iLCJfdmFsaWRhdGVJZFRva2VuIiwiZXhjaGFuZ2VDb2RlIiwidG9rZW5SZXNwb25zZSIsIl92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzIiwiY2xvY2tTa2V3SW5TZWNvbmRzIiwiX3ZhbGlkYXRlQWNjZXNzVG9rZW4iLCJfZmlsdGVyQnlBbGciLCJmaWx0ZXIiLCJhdF9oYXNoIiwiaGFzaEFsZyIsImhhc2hCaXRzIiwic2hhIiwibGVmdCIsImxlZnRfYjY0dSIsInVzZXJNYW5hZ2VyIiwiQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvciIsIl91c2VyTWFuYWdlciIsIl9DaGVja1Nlc3Npb25JRnJhbWVDdG9yIiwiZXZlbnRzIiwiYWRkVXNlckxvYWRlZCIsIl9zdGFydCIsImFkZFVzZXJVbmxvYWRlZCIsIl9zdG9wIiwiZ2V0VXNlciIsInVzZXIiLCJtb25pdG9yQW5vbnltb3VzU2Vzc2lvbiIsInF1ZXJ5U2Vzc2lvblN0YXR1cyIsInRtcFVzZXIiLCJzZXNzaW9uIiwic2lkIiwiY2F0Y2giLCJlcnIiLCJfc3ViIiwiX3NpZCIsIl9jaGVja1Nlc3Npb25JRnJhbWUiLCJfY2hlY2tTZXNzaW9uSW50ZXJ2YWwiLCJfc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IiLCJ0aW1lckhhbmRsZSIsInJhaXNlRXZlbnQiLCJfcmFpc2VVc2VyU2Vzc2lvbkNoYW5nZWQiLCJfcmFpc2VVc2VyU2lnbmVkT3V0IiwiX3JhaXNlVXNlclNpZ25lZEluIiwiY2hlY2tTZXNzaW9uSW50ZXJ2YWwiLCJzdG9wQ2hlY2tTZXNzaW9uT25FcnJvciIsIm9pZGMiLCJpc09pZGMiLCJhZGRRdWVyeVBhcmFtIiwiY29kZV9jaGFsbGVuZ2UiLCJpc09BdXRoIiwiT2lkY1Njb3BlIiwidG9rZW5fdHlwZSIsImV4cGlyZXNfYXQiLCJzY29wZXMiLCJfbm9uY2UiLCJfY29kZV92ZXJpZmllciIsIl9jb2RlX2NoYWxsZW5nZSIsIl9za2lwVXNlckluZm8iLCJjcmVhdGVkIiwic3RvcmFnZVN0cmluZyIsIlNpbGVudFJlbmV3U2VydmljZSIsIl90b2tlbkV4cGlyaW5nIiwic2lnbmluU2lsZW50IiwiX3JhaXNlU2lsZW50UmVuZXdFcnJvciIsIl9jcmVhdGVkIiwiX3JlcXVlc3RfdHlwZSIsInN0b3JhZ2UiLCJhZ2UiLCJjdXRvZmYiLCJnZXRBbGxLZXlzIiwicHJvbWlzZXMiLCJhbGwiLCJUaW1lckR1cmF0aW9uIiwibm93RnVuYyIsIl9ub3dGdW5jIiwiZXhwaXJhdGlvbiIsIl90aW1lckhhbmRsZSIsIl9leHBpcmF0aW9uIiwidGltZXJEdXJhdGlvbiIsImRpZmYiLCJncmFudF90eXBlIiwiZXhjaGFuZ2VSZWZyZXNoVG9rZW4iLCJyZWZyZXNoX3Rva2VuIiwiQWNjZXNzVG9rZW5UeXBlSGludCIsIlJlZnJlc2hUb2tlblR5cGVIaW50IiwiX1hNTEh0dHBSZXF1ZXN0Q3RvciIsInJldm9rZSIsInJlcXVpcmVkIiwiX3Jldm9rZSIsInhociIsImdsb2JhbCIsImxhc3RJbmRleE9mIiwicmVnZXgiLCJjb3VudGVyIiwiZXhlYyIsInByb3AiLCJfZ2V0Q2xhaW1zRnJvbUp3dCIsImlzc3VlclByb21pc2UiLCJTaWxlbnRSZW5ld1NlcnZpY2VDdG9yIiwiU2Vzc2lvbk1vbml0b3JDdG9yIiwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50Q3RvciIsIlVzZXJNYW5hZ2VyU2V0dGluZ3MiLCJfZXZlbnRzIiwiVXNlck1hbmFnZXJFdmVudHMiLCJfc2lsZW50UmVuZXdTZXJ2aWNlIiwiYXV0b21hdGljU2lsZW50UmVuZXciLCJzdGFydFNpbGVudFJlbmV3IiwibW9uaXRvclNlc3Npb24iLCJfc2Vzc2lvbk1vbml0b3IiLCJfdG9rZW5SZXZvY2F0aW9uQ2xpZW50IiwiX2xvYWRVc2VyIiwicmVtb3ZlVXNlciIsInN0b3JlVXNlciIsInNpZ25pblJlZGlyZWN0IiwibmF2UGFyYW1zIiwiX3NpZ25pblN0YXJ0IiwiX3JlZGlyZWN0TmF2aWdhdG9yIiwic2lnbmluUmVkaXJlY3RDYWxsYmFjayIsIl9zaWduaW5FbmQiLCJzaWduaW5Qb3B1cCIsInBvcHVwX3JlZGlyZWN0X3VyaSIsIl9zaWduaW4iLCJfcG9wdXBOYXZpZ2F0b3IiLCJzaWduaW5Qb3B1cENhbGxiYWNrIiwiX3NpZ25pbkNhbGxiYWNrIiwiX3VzZVJlZnJlc2hUb2tlbiIsImluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyIsInZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldyIsImN1cnJlbnRfc3ViIiwiX3NpZ25pblNpbGVudElmcmFtZSIsImlkVG9rZW5WYWxpZGF0aW9uIiwiX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbiIsImF1dGhfdGltZSIsInNpbGVudF9yZWRpcmVjdF91cmkiLCJfaWZyYW1lTmF2aWdhdG9yIiwic2lnbmluU2lsZW50Q2FsbGJhY2siLCJzaWduaW5DYWxsYmFjayIsInNpZ25vdXRDYWxsYmFjayIsInNpZ25vdXRSZWRpcmVjdENhbGxiYWNrIiwic2lnbm91dFBvcHVwQ2FsbGJhY2siLCJxdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZSIsIm5hdlJlc3BvbnNlIiwic2lnbmluUmVzcG9uc2UiLCJuYXZpZ2F0b3JQYXJhbXMiLCJzaWdub3V0UmVkaXJlY3QiLCJwb3N0TG9nb3V0UmVkaXJlY3RVcmkiLCJfc2lnbm91dFN0YXJ0IiwiX3NpZ25vdXRFbmQiLCJzaWdub3V0UG9wdXAiLCJwb3B1cF9wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkiLCJfc2lnbm91dCIsInJldm9rZVByb21pc2UiLCJyZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCIsIl9yZXZva2VJbnRlcm5hbCIsInNpZ25vdXRSZXF1ZXN0Iiwic2lnbm91dFJlc3BvbnNlIiwicmV2b2tlQWNjZXNzVG9rZW4iLCJzdWNjZXNzIiwiX3Jldm9rZUFjY2Vzc1Rva2VuSW50ZXJuYWwiLCJfcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwiLCJhdFN1Y2Nlc3MiLCJydFN1Y2Nlc3MiLCJzdG9wU2lsZW50UmVuZXciLCJfdXNlclN0b3JlIiwiX3VzZXJTdG9yZUtleSIsInJlZGlyZWN0TmF2aWdhdG9yIiwicG9wdXBOYXZpZ2F0b3IiLCJpZnJhbWVOYXZpZ2F0b3IiLCJ1c2VyU3RvcmUiLCJfdXNlckxvYWRlZCIsIl91c2VyVW5sb2FkZWQiLCJfc2lsZW50UmVuZXdFcnJvciIsIl91c2VyU2lnbmVkSW4iLCJfdXNlclNpZ25lZE91dCIsIl91c2VyU2Vzc2lvbkNoYW5nZWQiLCJyZW1vdmVVc2VyTG9hZGVkIiwicmVtb3ZlVXNlclVubG9hZGVkIiwiYWRkU2lsZW50UmVuZXdFcnJvciIsInJlbW92ZVNpbGVudFJlbmV3RXJyb3IiLCJhZGRVc2VyU2lnbmVkSW4iLCJyZW1vdmVVc2VyU2lnbmVkSW4iLCJhZGRVc2VyU2lnbmVkT3V0IiwicmVtb3ZlVXNlclNpZ25lZE91dCIsImFkZFVzZXJTZXNzaW9uQ2hhbmdlZCIsInJlbW92ZVVzZXJTZXNzaW9uQ2hhbmdlZCIsIkRlZmF1bHRDaGVja1Nlc3Npb25JbnRlcnZhbCIsInN0b3JlIiwiX3BvcHVwX3JlZGlyZWN0X3VyaSIsIl9wb3B1cF9wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkiLCJfcG9wdXBXaW5kb3dGZWF0dXJlcyIsIl9wb3B1cFdpbmRvd1RhcmdldCIsIl9zaWxlbnRfcmVkaXJlY3RfdXJpIiwiX3NpbGVudFJlcXVlc3RUaW1lb3V0IiwiX2F1dG9tYXRpY1NpbGVudFJlbmV3IiwiX3ZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldyIsIl9pbmNsdWRlSWRUb2tlbkluU2lsZW50UmVuZXciLCJfbW9uaXRvclNlc3Npb24iLCJfbW9uaXRvckFub255bW91c1Nlc3Npb24iLCJfcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUiLCJfcmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQiLCJwcmVmaXgiLCJfc3RvcmUiLCJfcHJlZml4Il0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0RBQTBDLGdDQUFnQztBQUMxRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGdFQUF3RCxrQkFBa0I7QUFDMUU7QUFDQSx5REFBaUQsY0FBYztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQXlDLGlDQUFpQztBQUMxRSx3SEFBZ0gsbUJBQW1CLEVBQUU7QUFDckk7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7O0FBR0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQy9FQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFFQTs7QUFuQkE7QUFDQTs7a0JBb0JlO0FBQ1hBLDZCQURXO0FBRVhDLGlCQUZXO0FBR1hDLHNDQUhXO0FBSVhDLDhEQUpXO0FBS1hDLG9FQUxXO0FBTVhDLDhEQU5XO0FBT1hDLHlDQVBXO0FBUVhDLDJEQVJXO0FBU1hDLHFEQVRXO0FBVVhDLHVFQVZXO0FBV1hDLDBFQVhXO0FBWVhDLDhEQVpXO0FBYVhDLHVFQWJXO0FBY1hDLGtEQWRXO0FBZVhDLDBCQWZXO0FBZ0JYQztBQWhCVyxDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNyQmY7Ozs7QUFJQSxJQUFJQyxZQUFZLEVBQWhCO0FBQ0FBLFVBQVVDLFNBQVYsR0FBc0IsS0FBdEI7O0FBRUEsSUFBSUMsU0FBUyxFQUFiOztBQUVBOzs7Ozs7QUFNQSxJQUFHQyxVQUFRQyxTQUFYLEVBQXFCO0FBQUMsTUFBSUQsUUFBTSxFQUFWO0FBQWEsT0FBTUUsSUFBTixHQUFXLEVBQUNDLFFBQU8sZ0JBQVNDLENBQVQsRUFBV0MsQ0FBWCxFQUFhQyxDQUFiLEVBQWU7QUFBQyxRQUFHLENBQUNELENBQUQsSUFBSSxDQUFDRCxDQUFSLEVBQVU7QUFBQyxZQUFNLElBQUlHLEtBQUosQ0FBVSw0RUFBVixDQUFOO0FBQThGLFNBQUlDLElBQUUsU0FBRkEsQ0FBRSxHQUFVLENBQUUsQ0FBbEIsQ0FBbUJBLEVBQUVDLFNBQUYsR0FBWUosRUFBRUksU0FBZCxDQUF3QkwsRUFBRUssU0FBRixHQUFZLElBQUlELENBQUosRUFBWixDQUFvQkosRUFBRUssU0FBRixDQUFZQyxXQUFaLEdBQXdCTixDQUF4QixDQUEwQkEsRUFBRU8sVUFBRixHQUFhTixFQUFFSSxTQUFmLENBQXlCLElBQUdKLEVBQUVJLFNBQUYsQ0FBWUMsV0FBWixJQUF5QkUsT0FBT0gsU0FBUCxDQUFpQkMsV0FBN0MsRUFBeUQ7QUFBQ0wsUUFBRUksU0FBRixDQUFZQyxXQUFaLEdBQXdCTCxDQUF4QjtBQUEwQixTQUFHQyxDQUFILEVBQUs7QUFBQyxVQUFJTyxDQUFKLENBQU0sS0FBSUEsQ0FBSixJQUFTUCxDQUFULEVBQVc7QUFBQ0YsVUFBRUssU0FBRixDQUFZSSxDQUFaLElBQWVQLEVBQUVPLENBQUYsQ0FBZjtBQUFvQixXQUFJQyxJQUFFLGFBQVUsQ0FBRSxDQUFsQjtBQUFBLFVBQW1CQyxJQUFFLENBQUMsVUFBRCxFQUFZLFNBQVosQ0FBckIsQ0FBNEMsSUFBRztBQUFDLFlBQUcsT0FBT0MsSUFBUCxDQUFZbkIsVUFBVUMsU0FBdEIsQ0FBSCxFQUFvQztBQUFDZ0IsY0FBRSxXQUFTRyxDQUFULEVBQVdDLENBQVgsRUFBYTtBQUFDLGlCQUFJTCxJQUFFLENBQU4sRUFBUUEsSUFBRUUsRUFBRUksTUFBWixFQUFtQk4sSUFBRUEsSUFBRSxDQUF2QixFQUF5QjtBQUFDLGtCQUFJTyxJQUFFTCxFQUFFRixDQUFGLENBQU47QUFBQSxrQkFBV1EsSUFBRUgsRUFBRUUsQ0FBRixDQUFiLENBQWtCLElBQUcsT0FBT0MsQ0FBUCxLQUFXLFVBQVgsSUFBdUJBLEtBQUdULE9BQU9ILFNBQVAsQ0FBaUJXLENBQWpCLENBQTdCLEVBQWlEO0FBQUNILGtCQUFFRyxDQUFGLElBQUtDLENBQUw7QUFBTztBQUFDO0FBQUMsV0FBdkg7QUFBd0g7QUFBQyxPQUFsSyxDQUFrSyxPQUFNQyxDQUFOLEVBQVEsQ0FBRSxHQUFFbEIsRUFBRUssU0FBSixFQUFjSCxDQUFkO0FBQWlCO0FBQUMsR0FBN2xCLEVBQVg7QUFDbkM7Ozs7Ozs7O0FBUUEsSUFBSWlCLFdBQVNBLFlBQVcsVUFBU1QsQ0FBVCxFQUFXVixDQUFYLEVBQWE7QUFBQyxNQUFJa0IsSUFBRSxFQUFOLENBQVMsSUFBSVQsSUFBRVMsRUFBRUUsR0FBRixHQUFNLEVBQVosQ0FBZSxJQUFJUCxJQUFFSixFQUFFWSxJQUFGLEdBQVEsWUFBVTtBQUFDLGFBQVNDLENBQVQsR0FBWSxDQUFFLFFBQU0sRUFBQ3ZCLFFBQU8sZ0JBQVN3QixDQUFULEVBQVc7QUFBQ0QsVUFBRWpCLFNBQUYsR0FBWSxJQUFaLENBQWlCLElBQUltQixJQUFFLElBQUlGLENBQUosRUFBTixDQUFjLElBQUdDLENBQUgsRUFBSztBQUFDQyxZQUFFQyxLQUFGLENBQVFGLENBQVI7QUFBVyxhQUFHLENBQUNDLEVBQUVFLGNBQUYsQ0FBaUIsTUFBakIsQ0FBSixFQUE2QjtBQUFDRixZQUFFRyxJQUFGLEdBQU8sWUFBVTtBQUFDSCxjQUFFSSxNQUFGLENBQVNELElBQVQsQ0FBY0UsS0FBZCxDQUFvQixJQUFwQixFQUF5QkMsU0FBekI7QUFBb0MsV0FBdEQ7QUFBdUQsV0FBRUgsSUFBRixDQUFPdEIsU0FBUCxHQUFpQm1CLENBQWpCLENBQW1CQSxFQUFFSSxNQUFGLEdBQVMsSUFBVCxDQUFjLE9BQU9KLENBQVA7QUFBUyxPQUFuTSxFQUFvTU8sUUFBTyxrQkFBVTtBQUFDLFlBQUlQLElBQUUsS0FBS3pCLE1BQUwsRUFBTixDQUFvQnlCLEVBQUVHLElBQUYsQ0FBT0UsS0FBUCxDQUFhTCxDQUFiLEVBQWVNLFNBQWYsRUFBMEIsT0FBT04sQ0FBUDtBQUFTLE9BQTdRLEVBQThRRyxNQUFLLGdCQUFVLENBQUUsQ0FBL1IsRUFBZ1NGLE9BQU0sZUFBU0YsQ0FBVCxFQUFXO0FBQUMsYUFBSSxJQUFJQyxDQUFSLElBQWFELENBQWIsRUFBZTtBQUFDLGNBQUdBLEVBQUVHLGNBQUYsQ0FBaUJGLENBQWpCLENBQUgsRUFBdUI7QUFBQyxpQkFBS0EsQ0FBTCxJQUFRRCxFQUFFQyxDQUFGLENBQVI7QUFBYTtBQUFDLGFBQUdELEVBQUVHLGNBQUYsQ0FBaUIsVUFBakIsQ0FBSCxFQUFnQztBQUFDLGVBQUtNLFFBQUwsR0FBY1QsRUFBRVMsUUFBaEI7QUFBeUI7QUFBQyxPQUFuYSxFQUFvYUMsT0FBTSxpQkFBVTtBQUFDLGVBQU8sS0FBS04sSUFBTCxDQUFVdEIsU0FBVixDQUFvQk4sTUFBcEIsQ0FBMkIsSUFBM0IsQ0FBUDtBQUF3QyxPQUE3ZCxFQUFOO0FBQXFlLEdBQTlmLEVBQWQsQ0FBZ2hCLElBQUlpQixJQUFFUCxFQUFFeUIsU0FBRixHQUFZckIsRUFBRWQsTUFBRixDQUFTLEVBQUM0QixNQUFLLGNBQVNILENBQVQsRUFBV0YsQ0FBWCxFQUFhO0FBQUNFLFVBQUUsS0FBS1csS0FBTCxHQUFXWCxLQUFHLEVBQWhCLENBQW1CLElBQUdGLEtBQUd0QixDQUFOLEVBQVE7QUFBQyxhQUFLb0MsUUFBTCxHQUFjZCxDQUFkO0FBQWdCLE9BQXpCLE1BQTZCO0FBQUMsYUFBS2MsUUFBTCxHQUFjWixFQUFFVCxNQUFGLEdBQVMsQ0FBdkI7QUFBeUI7QUFBQyxLQUEvRixFQUFnR2lCLFVBQVMsa0JBQVNWLENBQVQsRUFBVztBQUFDLGFBQU0sQ0FBQ0EsS0FBR3JCLENBQUosRUFBT29DLFNBQVAsQ0FBaUIsSUFBakIsQ0FBTjtBQUE2QixLQUFsSixFQUFtSkMsUUFBTyxnQkFBU0MsQ0FBVCxFQUFXO0FBQUMsVUFBSUMsSUFBRSxLQUFLTCxLQUFYLENBQWlCLElBQUlaLElBQUVnQixFQUFFSixLQUFSLENBQWMsSUFBSWIsSUFBRSxLQUFLYyxRQUFYLENBQW9CLElBQUlLLElBQUVGLEVBQUVILFFBQVIsQ0FBaUIsS0FBS00sS0FBTCxHQUFhLElBQUdwQixJQUFFLENBQUwsRUFBTztBQUFDLGFBQUksSUFBSXFCLElBQUUsQ0FBVixFQUFZQSxJQUFFRixDQUFkLEVBQWdCRSxHQUFoQixFQUFvQjtBQUFDLGNBQUluQixJQUFHRCxFQUFFb0IsTUFBSSxDQUFOLE1BQVksS0FBSUEsSUFBRSxDQUFILEdBQU0sQ0FBdEIsR0FBMEIsR0FBaEMsQ0FBb0NILEVBQUdsQixJQUFFcUIsQ0FBSCxLQUFRLENBQVYsS0FBY25CLEtBQUksS0FBSSxDQUFDRixJQUFFcUIsQ0FBSCxJQUFNLENBQVAsR0FBVSxDQUEvQjtBQUFrQztBQUFDLE9BQXBHLE1BQXdHO0FBQUMsYUFBSSxJQUFJQSxJQUFFLENBQVYsRUFBWUEsSUFBRUYsQ0FBZCxFQUFnQkUsS0FBRyxDQUFuQixFQUFxQjtBQUFDSCxZQUFHbEIsSUFBRXFCLENBQUgsS0FBUSxDQUFWLElBQWFwQixFQUFFb0IsTUFBSSxDQUFOLENBQWI7QUFBc0I7QUFBQyxZQUFLUCxRQUFMLElBQWVLLENBQWYsQ0FBaUIsT0FBTyxJQUFQO0FBQVksS0FBMWEsRUFBMmFDLE9BQU0saUJBQVU7QUFBQyxVQUFJbEIsSUFBRSxLQUFLVyxLQUFYLENBQWlCLElBQUliLElBQUUsS0FBS2MsUUFBWCxDQUFvQlosRUFBRUYsTUFBSSxDQUFOLEtBQVUsY0FBYSxLQUFJQSxJQUFFLENBQUgsR0FBTSxDQUFoQyxDQUFtQ0UsRUFBRVQsTUFBRixHQUFTTCxFQUFFa0MsSUFBRixDQUFPdEIsSUFBRSxDQUFULENBQVQ7QUFBcUIsS0FBemhCLEVBQTBoQlcsT0FBTSxpQkFBVTtBQUFDLFVBQUlYLElBQUVULEVBQUVvQixLQUFGLENBQVFZLElBQVIsQ0FBYSxJQUFiLENBQU4sQ0FBeUJ2QixFQUFFYSxLQUFGLEdBQVEsS0FBS0EsS0FBTCxDQUFXVyxLQUFYLENBQWlCLENBQWpCLENBQVIsQ0FBNEIsT0FBT3hCLENBQVA7QUFBUyxLQUF6bUIsRUFBMG1CeUIsUUFBTyxnQkFBU3hCLENBQVQsRUFBVztBQUFDLFVBQUlDLElBQUUsRUFBTixDQUFTLEtBQUksSUFBSUYsSUFBRSxDQUFWLEVBQVlBLElBQUVDLENBQWQsRUFBZ0JELEtBQUcsQ0FBbkIsRUFBcUI7QUFBQ0UsVUFBRXdCLElBQUYsQ0FBUXRDLEVBQUVxQyxNQUFGLEtBQVcsVUFBWixHQUF3QixDQUEvQjtBQUFrQyxjQUFPLElBQUkvQixFQUFFVyxJQUFOLENBQVdILENBQVgsRUFBYUQsQ0FBYixDQUFQO0FBQXVCLEtBQXJ0QixFQUFULENBQWxCLENBQW12QixJQUFJMEIsSUFBRS9CLEVBQUVnQyxHQUFGLEdBQU0sRUFBWixDQUFlLElBQUlqRCxJQUFFZ0QsRUFBRUUsR0FBRixHQUFNLEVBQUNkLFdBQVUsbUJBQVNkLENBQVQsRUFBVztBQUFDLFVBQUlvQixJQUFFcEIsRUFBRVksS0FBUixDQUFjLElBQUlYLElBQUVELEVBQUVhLFFBQVIsQ0FBaUIsSUFBSUksSUFBRSxFQUFOLENBQVMsS0FBSSxJQUFJbEIsSUFBRSxDQUFWLEVBQVlBLElBQUVFLENBQWQsRUFBZ0JGLEdBQWhCLEVBQW9CO0FBQUMsWUFBSW1CLElBQUdFLEVBQUVyQixNQUFJLENBQU4sTUFBWSxLQUFJQSxJQUFFLENBQUgsR0FBTSxDQUF0QixHQUEwQixHQUFoQyxDQUFvQ2tCLEVBQUVRLElBQUYsQ0FBTyxDQUFDUCxNQUFJLENBQUwsRUFBUVQsUUFBUixDQUFpQixFQUFqQixDQUFQLEVBQTZCUSxFQUFFUSxJQUFGLENBQU8sQ0FBQ1AsSUFBRSxFQUFILEVBQU9ULFFBQVAsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUE0QixjQUFPUSxFQUFFWSxJQUFGLENBQU8sRUFBUCxDQUFQO0FBQWtCLEtBQW5NLEVBQW9NQyxPQUFNLGVBQVM5QixDQUFULEVBQVc7QUFBQyxVQUFJRCxJQUFFQyxFQUFFUixNQUFSLENBQWUsSUFBSXlCLElBQUUsRUFBTixDQUFTLEtBQUksSUFBSWhCLElBQUUsQ0FBVixFQUFZQSxJQUFFRixDQUFkLEVBQWdCRSxLQUFHLENBQW5CLEVBQXFCO0FBQUNnQixVQUFFaEIsTUFBSSxDQUFOLEtBQVU4QixTQUFTL0IsRUFBRWdDLE1BQUYsQ0FBUy9CLENBQVQsRUFBVyxDQUFYLENBQVQsRUFBdUIsRUFBdkIsS0FBNkIsS0FBSUEsSUFBRSxDQUFILEdBQU0sQ0FBaEQ7QUFBbUQsY0FBTyxJQUFJUixFQUFFVyxJQUFOLENBQVdhLENBQVgsRUFBYWxCLElBQUUsQ0FBZixDQUFQO0FBQXlCLEtBQWhWLEVBQVosQ0FBOFYsSUFBSWxCLElBQUU2QyxFQUFFTyxNQUFGLEdBQVMsRUFBQ25CLFdBQVUsbUJBQVNHLENBQVQsRUFBVztBQUFDLFVBQUlHLElBQUVILEVBQUVMLEtBQVIsQ0FBYyxJQUFJWixJQUFFaUIsRUFBRUosUUFBUixDQUFpQixJQUFJZCxJQUFFLEVBQU4sQ0FBUyxLQUFJLElBQUlFLElBQUUsQ0FBVixFQUFZQSxJQUFFRCxDQUFkLEVBQWdCQyxHQUFoQixFQUFvQjtBQUFDLFlBQUlpQixJQUFHRSxFQUFFbkIsTUFBSSxDQUFOLE1BQVksS0FBSUEsSUFBRSxDQUFILEdBQU0sQ0FBdEIsR0FBMEIsR0FBaEMsQ0FBb0NGLEVBQUUwQixJQUFGLENBQU9TLE9BQU9DLFlBQVAsQ0FBb0JqQixDQUFwQixDQUFQO0FBQStCLGNBQU9uQixFQUFFOEIsSUFBRixDQUFPLEVBQVAsQ0FBUDtBQUFrQixLQUF6SyxFQUEwS0MsT0FBTSxlQUFTOUIsQ0FBVCxFQUFXO0FBQUMsVUFBSUQsSUFBRUMsRUFBRVIsTUFBUixDQUFlLElBQUl5QixJQUFFLEVBQU4sQ0FBUyxLQUFJLElBQUloQixJQUFFLENBQVYsRUFBWUEsSUFBRUYsQ0FBZCxFQUFnQkUsR0FBaEIsRUFBb0I7QUFBQ2dCLFVBQUVoQixNQUFJLENBQU4sS0FBVSxDQUFDRCxFQUFFb0MsVUFBRixDQUFhbkMsQ0FBYixJQUFnQixHQUFqQixLQUF3QixLQUFJQSxJQUFFLENBQUgsR0FBTSxDQUEzQztBQUE4QyxjQUFPLElBQUlSLEVBQUVXLElBQU4sQ0FBV2EsQ0FBWCxFQUFhbEIsQ0FBYixDQUFQO0FBQXVCLEtBQTlTLEVBQWYsQ0FBK1QsSUFBSVgsSUFBRXNDLEVBQUVXLElBQUYsR0FBTyxFQUFDdkIsV0FBVSxtQkFBU2YsQ0FBVCxFQUFXO0FBQUMsVUFBRztBQUFDLGVBQU91QyxtQkFBbUJDLE9BQU8xRCxFQUFFaUMsU0FBRixDQUFZZixDQUFaLENBQVAsQ0FBbkIsQ0FBUDtBQUFrRCxPQUF0RCxDQUFzRCxPQUFNRSxDQUFOLEVBQVE7QUFBQyxjQUFNLElBQUlyQixLQUFKLENBQVUsc0JBQVYsQ0FBTjtBQUF3QztBQUFDLEtBQS9ILEVBQWdJa0QsT0FBTSxlQUFTL0IsQ0FBVCxFQUFXO0FBQUMsYUFBT2xCLEVBQUVpRCxLQUFGLENBQVFVLFNBQVNDLG1CQUFtQjFDLENBQW5CLENBQVQsQ0FBUixDQUFQO0FBQWdELEtBQWxNLEVBQWIsQ0FBaU4sSUFBSVIsSUFBRUwsRUFBRXdELHNCQUFGLEdBQXlCcEQsRUFBRWQsTUFBRixDQUFTLEVBQUNtRSxPQUFNLGlCQUFVO0FBQUMsV0FBS0MsS0FBTCxHQUFXLElBQUluRCxFQUFFVyxJQUFOLEVBQVgsQ0FBd0IsS0FBS3lDLFdBQUwsR0FBaUIsQ0FBakI7QUFBbUIsS0FBN0QsRUFBOERDLFNBQVEsaUJBQVMvQyxDQUFULEVBQVc7QUFBQyxVQUFHLE9BQU9BLENBQVAsSUFBVSxRQUFiLEVBQXNCO0FBQUNBLFlBQUVYLEVBQUUwQyxLQUFGLENBQVEvQixDQUFSLENBQUY7QUFBYSxZQUFLNkMsS0FBTCxDQUFXN0IsTUFBWCxDQUFrQmhCLENBQWxCLEVBQXFCLEtBQUs4QyxXQUFMLElBQWtCOUMsRUFBRWMsUUFBcEI7QUFBNkIsS0FBeEssRUFBeUtrQyxVQUFTLGtCQUFTQyxDQUFULEVBQVc7QUFBQyxVQUFJL0IsSUFBRSxLQUFLMkIsS0FBWCxDQUFpQixJQUFJSyxJQUFFaEMsRUFBRUwsS0FBUixDQUFjLElBQUliLElBQUVrQixFQUFFSixRQUFSLENBQWlCLElBQUlHLElBQUUsS0FBS2tDLFNBQVgsQ0FBcUIsSUFBSUMsSUFBRW5DLElBQUUsQ0FBUixDQUFVLElBQUlvQyxJQUFFckQsSUFBRW9ELENBQVIsQ0FBVSxJQUFHSCxDQUFILEVBQUs7QUFBQ0ksWUFBRWpFLEVBQUVrQyxJQUFGLENBQU8rQixDQUFQLENBQUY7QUFBWSxPQUFsQixNQUFzQjtBQUFDQSxZQUFFakUsRUFBRWtFLEdBQUYsQ0FBTSxDQUFDRCxJQUFFLENBQUgsSUFBTSxLQUFLRSxjQUFqQixFQUFnQyxDQUFoQyxDQUFGO0FBQXFDLFdBQUlwQyxJQUFFa0MsSUFBRXBDLENBQVIsQ0FBVSxJQUFJSSxJQUFFakMsRUFBRW9FLEdBQUYsQ0FBTXJDLElBQUUsQ0FBUixFQUFVbkIsQ0FBVixDQUFOLENBQW1CLElBQUdtQixDQUFILEVBQUs7QUFBQyxhQUFJLElBQUlsQixJQUFFLENBQVYsRUFBWUEsSUFBRWtCLENBQWQsRUFBZ0JsQixLQUFHZ0IsQ0FBbkIsRUFBcUI7QUFBQyxlQUFLd0MsZUFBTCxDQUFxQlAsQ0FBckIsRUFBdUJqRCxDQUF2QjtBQUEwQixhQUFJQyxJQUFFZ0QsRUFBRVEsTUFBRixDQUFTLENBQVQsRUFBV3ZDLENBQVgsQ0FBTixDQUFvQkQsRUFBRUosUUFBRixJQUFZTyxDQUFaO0FBQWMsY0FBTyxJQUFJM0IsRUFBRVcsSUFBTixDQUFXSCxDQUFYLEVBQWFtQixDQUFiLENBQVA7QUFBdUIsS0FBL2QsRUFBZ2VWLE9BQU0saUJBQVU7QUFBQyxVQUFJWCxJQUFFVCxFQUFFb0IsS0FBRixDQUFRWSxJQUFSLENBQWEsSUFBYixDQUFOLENBQXlCdkIsRUFBRTZDLEtBQUYsR0FBUSxLQUFLQSxLQUFMLENBQVdsQyxLQUFYLEVBQVIsQ0FBMkIsT0FBT1gsQ0FBUDtBQUFTLEtBQTlpQixFQUEraUJ1RCxnQkFBZSxDQUE5akIsRUFBVCxDQUEvQixDQUEwbUIsSUFBSTNFLElBQUVPLEVBQUV3RSxNQUFGLEdBQVNuRSxFQUFFZixNQUFGLENBQVMsRUFBQ21GLEtBQUlyRSxFQUFFZCxNQUFGLEVBQUwsRUFBZ0I0QixNQUFLLGNBQVNMLENBQVQsRUFBVztBQUFDLFdBQUs0RCxHQUFMLEdBQVMsS0FBS0EsR0FBTCxDQUFTbkYsTUFBVCxDQUFnQnVCLENBQWhCLENBQVQsQ0FBNEIsS0FBSzRDLEtBQUw7QUFBYSxLQUExRSxFQUEyRUEsT0FBTSxpQkFBVTtBQUFDcEQsUUFBRW9ELEtBQUYsQ0FBUXJCLElBQVIsQ0FBYSxJQUFiLEVBQW1CLEtBQUtzQyxRQUFMO0FBQWdCLEtBQS9ILEVBQWdJQyxRQUFPLGdCQUFTOUQsQ0FBVCxFQUFXO0FBQUMsV0FBSytDLE9BQUwsQ0FBYS9DLENBQWIsRUFBZ0IsS0FBS2dELFFBQUwsR0FBZ0IsT0FBTyxJQUFQO0FBQVksS0FBL0wsRUFBZ01lLFVBQVMsa0JBQVMvRCxDQUFULEVBQVc7QUFBQyxVQUFHQSxDQUFILEVBQUs7QUFBQyxhQUFLK0MsT0FBTCxDQUFhL0MsQ0FBYjtBQUFnQixXQUFJRSxJQUFFLEtBQUs4RCxXQUFMLEVBQU4sQ0FBeUIsT0FBTzlELENBQVA7QUFBUyxLQUE3USxFQUE4UWlELFdBQVUsTUFBSSxFQUE1UixFQUErUmMsZUFBYyx1QkFBU2pFLENBQVQsRUFBVztBQUFDLGFBQU8sVUFBU0MsQ0FBVCxFQUFXQyxDQUFYLEVBQWE7QUFBQyxlQUFPLElBQUlGLEVBQUVLLElBQU4sQ0FBV0gsQ0FBWCxFQUFjNkQsUUFBZCxDQUF1QjlELENBQXZCLENBQVA7QUFBaUMsT0FBdEQ7QUFBdUQsS0FBaFgsRUFBaVhpRSxtQkFBa0IsMkJBQVNsRSxDQUFULEVBQVc7QUFBQyxhQUFPLFVBQVNDLENBQVQsRUFBV0MsQ0FBWCxFQUFhO0FBQUMsZUFBTyxJQUFJUCxFQUFFd0UsSUFBRixDQUFPOUQsSUFBWCxDQUFnQkwsQ0FBaEIsRUFBa0JFLENBQWxCLEVBQXFCNkQsUUFBckIsQ0FBOEI5RCxDQUE5QixDQUFQO0FBQXdDLE9BQTdEO0FBQThELEtBQTdjLEVBQVQsQ0FBZixDQUF3ZSxJQUFJTixJQUFFQyxFQUFFd0UsSUFBRixHQUFPLEVBQWIsQ0FBZ0IsT0FBT3hFLENBQVA7QUFBUyxDQUFqeEcsQ0FBa3hHeUUsSUFBbHhHLENBQXhCO0FBQ0E7Ozs7OztBQU1BLENBQUMsVUFBUzNGLENBQVQsRUFBVztBQUFDLE1BQUlrQixJQUFFQyxRQUFOO0FBQUEsTUFBZWpCLElBQUVnQixFQUFFRSxHQUFuQjtBQUFBLE1BQXVCVixJQUFFUixFQUFFbUIsSUFBM0I7QUFBQSxNQUFnQ3BCLElBQUVDLEVBQUVnQyxTQUFwQztBQUFBLE1BQThDaEIsSUFBRUEsRUFBRTBFLEdBQUYsR0FBTSxFQUF0RCxDQUF5RDFFLEVBQUUyRSxJQUFGLEdBQU9uRixFQUFFWCxNQUFGLENBQVMsRUFBQzRCLE1BQUssY0FBU2xCLENBQVQsRUFBV0UsQ0FBWCxFQUFhO0FBQUMsV0FBS21GLElBQUwsR0FBVXJGLENBQVYsQ0FBWSxLQUFLc0YsR0FBTCxHQUFTcEYsQ0FBVDtBQUFXLEtBQTNDLEVBQVQsQ0FBUCxDQUE4RE8sRUFBRWdCLFNBQUYsR0FBWXhCLEVBQUVYLE1BQUYsQ0FBUyxFQUFDNEIsTUFBSyxjQUFTbEIsQ0FBVCxFQUFXRSxDQUFYLEVBQWE7QUFBQ0YsVUFBRSxLQUFLMEIsS0FBTCxHQUFXMUIsS0FBRyxFQUFoQixDQUFtQixLQUFLMkIsUUFBTCxHQUFjekIsS0FBR1gsQ0FBSCxHQUFLVyxDQUFMLEdBQU8sSUFBRUYsRUFBRU0sTUFBekI7QUFBZ0MsS0FBdkUsRUFBd0VpRixPQUFNLGlCQUFVO0FBQUMsV0FBSSxJQUFJdkYsSUFBRSxLQUFLMEIsS0FBWCxFQUFpQnhCLElBQUVGLEVBQUVNLE1BQXJCLEVBQTRCRyxJQUFFLEVBQTlCLEVBQWlDZCxJQUFFLENBQXZDLEVBQXlDQSxJQUFFTyxDQUEzQyxFQUE2Q1AsR0FBN0MsRUFBaUQ7QUFBQyxZQUFJTSxJQUFFRCxFQUFFTCxDQUFGLENBQU4sQ0FBV2MsRUFBRThCLElBQUYsQ0FBT3RDLEVBQUVvRixJQUFULEVBQWU1RSxFQUFFOEIsSUFBRixDQUFPdEMsRUFBRXFGLEdBQVQ7QUFBYyxjQUFPOUYsRUFBRThCLE1BQUYsQ0FBU2IsQ0FBVCxFQUFXLEtBQUtrQixRQUFoQixDQUFQO0FBQWlDLEtBQXBOLEVBQXFOSCxPQUFNLGlCQUFVO0FBQUMsV0FBSSxJQUFJeEIsSUFBRUMsRUFBRXVCLEtBQUYsQ0FBUVksSUFBUixDQUFhLElBQWIsQ0FBTixFQUF5QmxDLElBQUVGLEVBQUUwQixLQUFGLEdBQVEsS0FBS0EsS0FBTCxDQUFXVyxLQUFYLENBQWlCLENBQWpCLENBQW5DLEVBQXVENUIsSUFBRVAsRUFBRUksTUFBM0QsRUFBa0VYLElBQUUsQ0FBeEUsRUFBMEVBLElBQUVjLENBQTVFLEVBQThFZCxHQUE5RTtBQUFrRk8sVUFBRVAsQ0FBRixJQUFLTyxFQUFFUCxDQUFGLEVBQUs2QixLQUFMLEVBQUw7QUFBbEYsT0FBb0csT0FBT3hCLENBQVA7QUFBUyxLQUFuVixFQUFULENBQVo7QUFBMlcsQ0FBL2U7O0FBRUE7Ozs7OztBQU1BLENBQUMsWUFBVTtBQUFDLE1BQUlSLElBQUVrQixRQUFOO0FBQUEsTUFBZU4sSUFBRVosRUFBRW1CLEdBQUYsQ0FBTWMsU0FBdkIsQ0FBaUNqQyxFQUFFaUQsR0FBRixDQUFNK0MsTUFBTixHQUFhLEVBQUM1RCxXQUFVLG1CQUFTNUIsQ0FBVCxFQUFXO0FBQUMsVUFBSUMsSUFBRUQsRUFBRTBCLEtBQVI7QUFBQSxVQUFjakMsSUFBRU8sRUFBRTJCLFFBQWxCO0FBQUEsVUFBMkJ6QixJQUFFLEtBQUt1RixJQUFsQyxDQUF1Q3pGLEVBQUVpQyxLQUFGLEdBQVVqQyxJQUFFLEVBQUYsQ0FBSyxLQUFJLElBQUlTLElBQUUsQ0FBVixFQUFZQSxJQUFFaEIsQ0FBZCxFQUFnQmdCLEtBQUcsQ0FBbkI7QUFBcUIsYUFBSSxJQUFJZCxJQUFFLENBQUNNLEVBQUVRLE1BQUksQ0FBTixNQUFXLEtBQUcsS0FBR0EsSUFBRSxDQUFMLENBQWQsR0FBc0IsR0FBdkIsS0FBNkIsRUFBN0IsR0FBZ0MsQ0FBQ1IsRUFBRVEsSUFBRSxDQUFGLEtBQU0sQ0FBUixNQUFhLEtBQUcsS0FBRyxDQUFDQSxJQUFFLENBQUgsSUFBTSxDQUFULENBQWhCLEdBQTRCLEdBQTdCLEtBQW1DLENBQW5FLEdBQXFFUixFQUFFUSxJQUFFLENBQUYsS0FBTSxDQUFSLE1BQWEsS0FBRyxLQUFHLENBQUNBLElBQUUsQ0FBSCxJQUFNLENBQVQsQ0FBaEIsR0FBNEIsR0FBdkcsRUFBMkdsQixJQUFFLENBQWpILEVBQW1ILElBQUVBLENBQUYsSUFBS2tCLElBQUUsT0FBS2xCLENBQVAsR0FBU0UsQ0FBakksRUFBbUlGLEdBQW5JO0FBQXVJUyxZQUFFdUMsSUFBRixDQUFPckMsRUFBRXdGLE1BQUYsQ0FBUy9GLE1BQUksS0FBRyxJQUFFSixDQUFMLENBQUosR0FBWSxFQUFyQixDQUFQO0FBQXZJO0FBQXJCLE9BQTZMLElBQUdVLElBQUVDLEVBQUV3RixNQUFGLENBQVMsRUFBVCxDQUFMLEVBQWtCLE9BQUsxRixFQUFFTSxNQUFGLEdBQVMsQ0FBZDtBQUFpQk4sVUFBRXVDLElBQUYsQ0FBT3RDLENBQVA7QUFBakIsT0FBMkIsT0FBT0QsRUFBRTJDLElBQUYsQ0FBTyxFQUFQLENBQVA7QUFBa0IsS0FBelUsRUFBMFVDLE9BQU0sZUFBUzVDLENBQVQsRUFBVztBQUFDLFVBQUlDLElBQUVELEVBQUVNLE1BQVI7QUFBQSxVQUFlYixJQUFFLEtBQUtnRyxJQUF0QjtBQUFBLFVBQTJCdkYsSUFBRVQsRUFBRWlHLE1BQUYsQ0FBUyxFQUFULENBQTdCLENBQTBDeEYsTUFBSUEsSUFBRUYsRUFBRTJGLE9BQUYsQ0FBVXpGLENBQVYsQ0FBRixFQUFlLENBQUMsQ0FBRCxJQUFJQSxDQUFKLEtBQVFELElBQUVDLENBQVYsQ0FBbkIsRUFBaUMsS0FBSSxJQUFJQSxJQUFFLEVBQU4sRUFBU08sSUFBRSxDQUFYLEVBQWFkLElBQUUsQ0FBbkIsRUFBcUJBLElBQ3RmTSxDQURpZSxFQUMvZE4sR0FEK2Q7QUFDM2QsWUFBR0EsSUFBRSxDQUFMLEVBQU87QUFBQyxjQUFJSixJQUFFRSxFQUFFa0csT0FBRixDQUFVM0YsRUFBRTBGLE1BQUYsQ0FBUy9GLElBQUUsQ0FBWCxDQUFWLEtBQTBCLEtBQUdBLElBQUUsQ0FBTCxDQUFoQztBQUFBLGNBQXdDSCxJQUFFQyxFQUFFa0csT0FBRixDQUFVM0YsRUFBRTBGLE1BQUYsQ0FBUy9GLENBQVQsQ0FBVixNQUF5QixJQUFFLEtBQUdBLElBQUUsQ0FBTCxDQUFyRSxDQUE2RU8sRUFBRU8sTUFBSSxDQUFOLEtBQVUsQ0FBQ2xCLElBQUVDLENBQUgsS0FBTyxLQUFHLEtBQUdpQixJQUFFLENBQUwsQ0FBcEIsQ0FBNEJBO0FBQUk7QUFEc1csT0FDdFcsT0FBT0wsRUFBRWtCLE1BQUYsQ0FBU3BCLENBQVQsRUFBV08sQ0FBWCxDQUFQO0FBQXFCLEtBRHRGLEVBQ3VGZ0YsTUFBSyxtRUFENUYsRUFBYjtBQUM4SyxDQUQzTjs7QUFHQTs7Ozs7O0FBTUEsQ0FBQyxVQUFTakYsQ0FBVCxFQUFXO0FBQUMsT0FBSSxJQUFJakIsSUFBRW1CLFFBQU4sRUFBZWxCLElBQUVELEVBQUVvQixHQUFuQixFQUF1QnNELElBQUV6RSxFQUFFaUMsU0FBM0IsRUFBcUNyQixJQUFFWixFQUFFZ0YsTUFBekMsRUFBZ0RoRixJQUFFRCxFQUFFMEYsSUFBcEQsRUFBeURqRCxJQUFFLEVBQTNELEVBQThERixJQUFFLEVBQWhFLEVBQW1Fb0MsSUFBRSxTQUFGQSxDQUFFLENBQVNuQyxDQUFULEVBQVc7QUFBQyxXQUFPLGNBQVlBLEtBQUdBLElBQUUsQ0FBTCxDQUFaLElBQXFCLENBQTVCO0FBQThCLEdBQS9HLEVBQWdIeEIsSUFBRSxDQUFsSCxFQUFvSFAsSUFBRSxDQUExSCxFQUE0SCxLQUFHQSxDQUEvSCxHQUFrSTtBQUFDLFFBQUlMLENBQUosQ0FBTWMsR0FBRTtBQUFDZCxVQUFFWSxDQUFGLENBQUksS0FBSSxJQUFJdUQsSUFBRXRELEVBQUVvRixJQUFGLENBQU9qRyxDQUFQLENBQU4sRUFBZ0J1QyxJQUFFLENBQXRCLEVBQXdCQSxLQUFHNEIsQ0FBM0IsRUFBNkI1QixHQUE3QjtBQUFpQyxZQUFHLEVBQUV2QyxJQUFFdUMsQ0FBSixDQUFILEVBQVU7QUFBQ3ZDLGNBQUUsQ0FBQyxDQUFILENBQUssTUFBTWMsQ0FBTjtBQUFRO0FBQXpELE9BQXlEZCxJQUFFLENBQUMsQ0FBSDtBQUFLLFdBQUksSUFBRUssQ0FBRixLQUFNZ0MsRUFBRWhDLENBQUYsSUFBS2tFLEVBQUUxRCxFQUFFcUYsR0FBRixDQUFNdEYsQ0FBTixFQUFRLEdBQVIsQ0FBRixDQUFYLEdBQTRCdUIsRUFBRTlCLENBQUYsSUFBS2tFLEVBQUUxRCxFQUFFcUYsR0FBRixDQUFNdEYsQ0FBTixFQUFRLElBQUUsQ0FBVixDQUFGLENBQWpDLEVBQWlEUCxHQUFyRCxFQUEwRE87QUFBSSxPQUFJTSxJQUFFLEVBQU47QUFBQSxNQUFTckIsSUFBRUEsRUFBRXNHLE1BQUYsR0FBUzFGLEVBQUVkLE1BQUYsQ0FBUyxFQUFDb0YsVUFBUyxvQkFBVTtBQUFDLFdBQUtxQixLQUFMLEdBQVcsSUFBSTlCLEVBQUUvQyxJQUFOLENBQVdjLEVBQUVLLEtBQUYsQ0FBUSxDQUFSLENBQVgsQ0FBWDtBQUFrQyxLQUF2RCxFQUF3RGlDLGlCQUFnQix5QkFBU3ZDLENBQVQsRUFBV3ZDLENBQVgsRUFBYTtBQUFDLFdBQUksSUFBSWlCLElBQUUsS0FBS3NGLEtBQUwsQ0FBV3JFLEtBQWpCLEVBQXVCeEIsSUFBRU8sRUFBRSxDQUFGLENBQXpCLEVBQThCZCxJQUFFYyxFQUFFLENBQUYsQ0FBaEMsRUFBcUNULElBQUVTLEVBQUUsQ0FBRixDQUF2QyxFQUE0Q0QsSUFBRUMsRUFBRSxDQUFGLENBQTlDLEVBQW1EaEIsSUFBRWdCLEVBQUUsQ0FBRixDQUFyRCxFQUEwRGxCLElBQUVrQixFQUFFLENBQUYsQ0FBNUQsRUFBaUVMLElBQUVLLEVBQUUsQ0FBRixDQUFuRSxFQUF3RUYsSUFBRUUsRUFBRSxDQUFGLENBQTFFLEVBQStFUixJQUFFLENBQXJGLEVBQXVGLEtBQUdBLENBQTFGLEVBQTRGQSxHQUE1RixFQUFnRztBQUFDLFlBQUcsS0FBR0EsQ0FBTixFQUFRWSxFQUFFWixDQUFGLElBQ3JmOEIsRUFBRXZDLElBQUVTLENBQUosSUFBTyxDQUQ4ZSxDQUFSLEtBQ2hlO0FBQUMsY0FBSXVDLElBQUUzQixFQUFFWixJQUFFLEVBQUosQ0FBTjtBQUFBLGNBQWNhLElBQUVELEVBQUVaLElBQUUsQ0FBSixDQUFoQixDQUF1QlksRUFBRVosQ0FBRixJQUFLLENBQUMsQ0FBQ3VDLEtBQUcsRUFBSCxHQUFNQSxNQUFJLENBQVgsS0FBZUEsS0FBRyxFQUFILEdBQU1BLE1BQUksRUFBekIsSUFBNkJBLE1BQUksQ0FBbEMsSUFBcUMzQixFQUFFWixJQUFFLENBQUosQ0FBckMsSUFBNkMsQ0FBQ2EsS0FBRyxFQUFILEdBQU1BLE1BQUksRUFBWCxLQUFnQkEsS0FBRyxFQUFILEdBQU1BLE1BQUksRUFBMUIsSUFBOEJBLE1BQUksRUFBL0UsSUFBbUZELEVBQUVaLElBQUUsRUFBSixDQUF4RjtBQUFnRyxhQUFFTSxLQUFHLENBQUNkLEtBQUcsRUFBSCxHQUFNQSxNQUFJLENBQVgsS0FBZUEsS0FBRyxFQUFILEdBQU1BLE1BQUksRUFBekIsS0FBOEJBLEtBQUcsQ0FBSCxHQUFLQSxNQUFJLEVBQXZDLENBQUgsS0FBZ0RBLElBQUVGLENBQUYsR0FBSSxDQUFDRSxDQUFELEdBQUdXLENBQXZELElBQTBEMEIsRUFBRTdCLENBQUYsQ0FBMUQsR0FBK0RZLEVBQUVaLENBQUYsQ0FBakUsQ0FBc0VhLElBQUUsQ0FBQyxDQUFDWixLQUFHLEVBQUgsR0FBTUEsTUFBSSxDQUFYLEtBQWVBLEtBQUcsRUFBSCxHQUFNQSxNQUFJLEVBQXpCLEtBQThCQSxLQUFHLEVBQUgsR0FBTUEsTUFBSSxFQUF4QyxDQUFELEtBQStDQSxJQUFFUCxDQUFGLEdBQUlPLElBQUVGLENBQU4sR0FBUUwsSUFBRUssQ0FBekQsQ0FBRixDQUE4RE8sSUFBRUgsQ0FBRixDQUFJQSxJQUFFYixDQUFGLENBQUlBLElBQUVFLENBQUYsQ0FBSUEsSUFBRWUsSUFBRWdDLENBQUYsR0FBSSxDQUFOLENBQVFoQyxJQUFFUixDQUFGLENBQUlBLElBQUVMLENBQUYsQ0FBSUEsSUFBRU8sQ0FBRixDQUFJQSxJQUFFc0MsSUFBRTFCLENBQUYsR0FBSSxDQUFOO0FBQVEsU0FBRSxDQUFGLElBQUtMLEVBQUUsQ0FBRixJQUFLUCxDQUFMLEdBQU8sQ0FBWixDQUFjTyxFQUFFLENBQUYsSUFBS0EsRUFBRSxDQUFGLElBQUtkLENBQUwsR0FBTyxDQUFaLENBQWNjLEVBQUUsQ0FBRixJQUFLQSxFQUFFLENBQUYsSUFBS1QsQ0FBTCxHQUFPLENBQVosQ0FBY1MsRUFBRSxDQUFGLElBQUtBLEVBQUUsQ0FBRixJQUFLRCxDQUFMLEdBQU8sQ0FBWixDQUFjQyxFQUFFLENBQUYsSUFBS0EsRUFBRSxDQUFGLElBQUtoQixDQUFMLEdBQU8sQ0FBWixDQUFjZ0IsRUFBRSxDQUFGLElBQUtBLEVBQUUsQ0FBRixJQUFLbEIsQ0FBTCxHQUFPLENBQVosQ0FBY2tCLEVBQUUsQ0FBRixJQUFLQSxFQUFFLENBQUYsSUFBS0wsQ0FBTCxHQUFPLENBQVosQ0FBY0ssRUFBRSxDQUFGLElBQUtBLEVBQUUsQ0FBRixJQUFLRixDQUFMLEdBQU8sQ0FBWjtBQUFjLEtBRDNHLEVBQzRHc0UsYUFBWSx1QkFBVTtBQUFDLFVBQUlsRixJQUFFLEtBQUsrRCxLQUFYO0FBQUEsVUFBaUIxRCxJQUFFTCxFQUFFK0IsS0FBckI7QUFBQSxVQUEyQmpCLElBQUUsSUFBRSxLQUFLa0QsV0FBcEM7QUFBQSxVQUFnRHpELElBQUUsSUFBRVAsRUFBRWdDLFFBQXREO0FBQ3piM0IsUUFBRUUsTUFBSSxDQUFOLEtBQVUsT0FBSyxLQUFHQSxJQUFFLEVBQXBCLENBQXVCRixFQUFFLENBQUNFLElBQUUsRUFBRixLQUFPLENBQVAsSUFBVSxDQUFYLElBQWMsRUFBaEIsSUFBb0JNLEVBQUV3RixLQUFGLENBQVF2RixJQUFFLFVBQVYsQ0FBcEIsQ0FBMENULEVBQUUsQ0FBQ0UsSUFBRSxFQUFGLEtBQU8sQ0FBUCxJQUFVLENBQVgsSUFBYyxFQUFoQixJQUFvQk8sQ0FBcEIsQ0FBc0JkLEVBQUVnQyxRQUFGLEdBQVcsSUFBRTNCLEVBQUVNLE1BQWYsQ0FBc0IsS0FBS3VELFFBQUwsR0FBZ0IsT0FBTyxLQUFLa0MsS0FBWjtBQUFrQixLQUZ1SyxFQUV0S3ZFLE9BQU0saUJBQVU7QUFBQyxVQUFJeEIsSUFBRUksRUFBRW9CLEtBQUYsQ0FBUVksSUFBUixDQUFhLElBQWIsQ0FBTixDQUF5QnBDLEVBQUUrRixLQUFGLEdBQVEsS0FBS0EsS0FBTCxDQUFXdkUsS0FBWCxFQUFSLENBQTJCLE9BQU94QixDQUFQO0FBQVMsS0FGd0YsRUFBVCxDQUFwQixDQUV4RFQsRUFBRXVHLE1BQUYsR0FBUzFGLEVBQUUwRSxhQUFGLENBQWdCdEYsQ0FBaEIsQ0FBVCxDQUE0QkQsRUFBRTBHLFVBQUYsR0FBYTdGLEVBQUUyRSxpQkFBRixDQUFvQnZGLENBQXBCLENBQWI7QUFBb0MsQ0FGalMsRUFFbVMwRixJQUZuUzs7QUFJQTs7Ozs7O0FBTUEsQ0FBQyxZQUFVO0FBQUMsV0FBU3pFLENBQVQsR0FBWTtBQUFDLFdBQU9kLEVBQUUyQixNQUFGLENBQVNGLEtBQVQsQ0FBZXpCLENBQWYsRUFBaUIwQixTQUFqQixDQUFQO0FBQW1DLFFBQUksSUFBSVIsSUFBRUgsUUFBTixFQUFld0IsSUFBRXJCLEVBQUVGLEdBQUYsQ0FBTTZELE1BQXZCLEVBQThCdkUsSUFBRVksRUFBRXNFLEdBQWxDLEVBQXNDeEYsSUFBRU0sRUFBRW1GLElBQTFDLEVBQStDYyxJQUFFakcsRUFBRXdCLFNBQW5ELEVBQTZEeEIsSUFBRVksRUFBRW9FLElBQWpFLEVBQXNFa0IsS0FBRyxDQUFDMUYsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUFELEVBQTBCQSxFQUFFLFVBQUYsRUFBYSxTQUFiLENBQTFCLEVBQWtEQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQWxELEVBQTJFQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQTNFLEVBQW9HQSxFQUFFLFNBQUYsRUFBWSxVQUFaLENBQXBHLEVBQTRIQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQTVILEVBQXFKQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQXJKLEVBQThLQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQTlLLEVBQXVNQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQXZNLEVBQWdPQSxFQUFFLFNBQUYsRUFBWSxVQUFaLENBQWhPLEVBQXdQQSxFQUFFLFNBQUYsRUFBWSxVQUFaLENBQXhQLEVBQWdSQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQWhSLEVBQXlTQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBQXpTLEVBQWtVQSxFQUFFLFVBQUYsRUFBYSxTQUFiLENBQWxVLEVBQTBWQSxFQUFFLFVBQUYsRUFBYSxTQUFiLENBQTFWLEVBQ3pJQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBRHlJLEVBQ2hIQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBRGdILEVBQ3ZGQSxFQUFFLFVBQUYsRUFBYSxTQUFiLENBRHVGLEVBQy9EQSxFQUFFLFNBQUYsRUFBWSxVQUFaLENBRCtELEVBQ3ZDQSxFQUFFLFNBQUYsRUFBWSxVQUFaLENBRHVDLEVBQ2ZBLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FEZSxFQUNTQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBRFQsRUFDa0NBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEbEMsRUFDMkRBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEM0QsRUFDb0ZBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEcEYsRUFDNkdBLEVBQUUsVUFBRixFQUFhLFNBQWIsQ0FEN0csRUFDcUlBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEckksRUFDOEpBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEOUosRUFDdUxBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEdkwsRUFDZ05BLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEaE4sRUFDeU9BLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FEek8sRUFDaVFBLEVBQUUsU0FBRixFQUFZLFNBQVosQ0FEalEsRUFDd1JBLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FEeFIsRUFDZ1RBLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FEaFQsRUFDd1VBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FEeFUsRUFDaVdBLEVBQUUsVUFBRixFQUMxZSxVQUQwZSxDQURqVyxFQUU3SEEsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUY2SCxFQUVwR0EsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUZvRyxFQUUzRUEsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUYyRSxFQUVsREEsRUFBRSxVQUFGLEVBQWEsU0FBYixDQUZrRCxFQUUxQkEsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUYwQixFQUVEQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBRkMsRUFFd0JBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FGeEIsRUFFaURBLEVBQUUsVUFBRixFQUFhLFNBQWIsQ0FGakQsRUFFeUVBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FGekUsRUFFa0dBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FGbEcsRUFFMkhBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FGM0gsRUFFb0pBLEVBQUUsU0FBRixFQUFZLFNBQVosQ0FGcEosRUFFMktBLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FGM0ssRUFFbU1BLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FGbk0sRUFFMk5BLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FGM04sRUFFbVBBLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FGblAsRUFFMlFBLEVBQUUsU0FBRixFQUFZLFVBQVosQ0FGM1EsRUFFbVNBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FGblMsRUFFNFRBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FGNVQsRUFFcVZBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FGclYsRUFHeklBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FIeUksRUFHaEhBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FIZ0gsRUFHdkZBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FIdUYsRUFHOURBLEVBQUUsVUFBRixFQUFhLFNBQWIsQ0FIOEQsRUFHdENBLEVBQUUsVUFBRixFQUFhLFNBQWIsQ0FIc0MsRUFHZEEsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUhjLEVBR1dBLEVBQUUsVUFBRixFQUFhLFVBQWIsQ0FIWCxFQUdvQ0EsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUhwQyxFQUc2REEsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUg3RCxFQUdzRkEsRUFBRSxVQUFGLEVBQWEsU0FBYixDQUh0RixFQUc4R0EsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUg5RyxFQUd1SUEsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUh2SSxFQUdnS0EsRUFBRSxTQUFGLEVBQVksVUFBWixDQUhoSyxFQUd3TEEsRUFBRSxTQUFGLEVBQVksVUFBWixDQUh4TCxFQUdnTkEsRUFBRSxTQUFGLEVBQVksVUFBWixDQUhoTixFQUd3T0EsRUFBRSxTQUFGLEVBQVksU0FBWixDQUh4TyxFQUcrUEEsRUFBRSxTQUFGLEVBQVksU0FBWixDQUgvUCxFQUdzUkEsRUFBRSxTQUFGLEVBQVksVUFBWixDQUh0UixFQUc4U0EsRUFBRSxVQUFGLEVBQWEsU0FBYixDQUg5UyxFQUdzVUEsRUFBRSxVQUFGLEVBQWEsVUFBYixDQUh0VSxFQUcrVkEsRUFBRSxVQUFGLEVBQ3hlLFVBRHdlLENBSC9WLEVBSTdIQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBSjZILEVBSXBHQSxFQUFFLFVBQUYsRUFBYSxTQUFiLENBSm9HLEVBSTVFQSxFQUFFLFVBQUYsRUFBYSxVQUFiLENBSjRFLENBQXpFLEVBSXVCd0QsSUFBRSxFQUp6QixFQUk0QkgsSUFBRSxDQUpsQyxFQUlvQyxLQUFHQSxDQUp2QyxFQUl5Q0EsR0FKekM7QUFJNkNHLE1BQUVILENBQUYsSUFBS3JELEdBQUw7QUFKN0MsR0FJc0RSLElBQUVBLEVBQUVtRyxNQUFGLEdBQVNsRSxFQUFFNUMsTUFBRixDQUFTLEVBQUNvRixVQUFTLG9CQUFVO0FBQUMsV0FBS3FCLEtBQUwsR0FBVyxJQUFJRyxFQUFFaEYsSUFBTixDQUFXLENBQUMsSUFBSXZCLEVBQUV1QixJQUFOLENBQVcsVUFBWCxFQUFzQixVQUF0QixDQUFELEVBQW1DLElBQUl2QixFQUFFdUIsSUFBTixDQUFXLFVBQVgsRUFBc0IsVUFBdEIsQ0FBbkMsRUFBcUUsSUFBSXZCLEVBQUV1QixJQUFOLENBQVcsVUFBWCxFQUFzQixVQUF0QixDQUFyRSxFQUF1RyxJQUFJdkIsRUFBRXVCLElBQU4sQ0FBVyxVQUFYLEVBQXNCLFVBQXRCLENBQXZHLEVBQXlJLElBQUl2QixFQUFFdUIsSUFBTixDQUFXLFVBQVgsRUFBc0IsVUFBdEIsQ0FBekksRUFBMkssSUFBSXZCLEVBQUV1QixJQUFOLENBQVcsVUFBWCxFQUFzQixTQUF0QixDQUEzSyxFQUE0TSxJQUFJdkIsRUFBRXVCLElBQU4sQ0FBVyxTQUFYLEVBQXFCLFVBQXJCLENBQTVNLEVBQTZPLElBQUl2QixFQUFFdUIsSUFBTixDQUFXLFVBQVgsRUFBc0IsU0FBdEIsQ0FBN08sQ0FBWCxDQUFYO0FBQXNTLEtBQTNULEVBQTRUb0QsaUJBQWdCLHlCQUFTN0QsQ0FBVCxFQUFXZCxDQUFYLEVBQWE7QUFBQyxXQUFJLElBQUlGLElBQUUsS0FBS3NHLEtBQUwsQ0FBV3JFLEtBQWpCLEVBQ3BlMkUsSUFBRTVHLEVBQUUsQ0FBRixDQURrZSxFQUM3ZFEsSUFBRVIsRUFBRSxDQUFGLENBRDJkLEVBQ3Rkb0IsSUFBRXBCLEVBQUUsQ0FBRixDQURvZCxFQUMvY3lDLElBQUV6QyxFQUFFLENBQUYsQ0FENmMsRUFDeGM2RyxJQUFFN0csRUFBRSxDQUFGLENBRHNjLEVBQ2pjOEcsSUFBRTlHLEVBQUUsQ0FBRixDQUQrYixFQUMxYitHLElBQUUvRyxFQUFFLENBQUYsQ0FEd2IsRUFDbmJBLElBQUVBLEVBQUUsQ0FBRixDQURpYixFQUM1YXFFLElBQUV1QyxFQUFFaEIsSUFEd2EsRUFDbmFvQixJQUFFSixFQUFFZixHQUQrWixFQUMzWm9CLElBQUV6RyxFQUFFb0YsSUFEdVosRUFDbFpzQixJQUFFMUcsRUFBRXFGLEdBRDhZLEVBQzFZc0IsSUFBRS9GLEVBQUV3RSxJQURzWSxFQUNqWXdCLElBQUVoRyxFQUFFeUUsR0FENlgsRUFDelh3QixJQUFFNUUsRUFBRW1ELElBRHFYLEVBQ2hYMEIsSUFBRTdFLEVBQUVvRCxHQUQ0VyxFQUN4VzBCLElBQUVWLEVBQUVqQixJQURvVyxFQUMvVjRCLElBQUVYLEVBQUVoQixHQUQyVixFQUN2VjRCLEtBQUdYLEVBQUVsQixJQURrVixFQUM3VThCLElBQUVaLEVBQUVqQixHQUR5VSxFQUNyVThCLEtBQUdaLEVBQUVuQixJQURnVSxFQUMzVGdDLElBQUViLEVBQUVsQixHQUR1VCxFQUNuVGdDLEtBQUc3SCxFQUFFNEYsSUFEOFMsRUFDelNrQyxJQUFFOUgsRUFBRTZGLEdBRHFTLEVBQ2pTOUUsSUFBRXNELENBRCtSLEVBQzdSdkUsSUFBRWtILENBRDJSLEVBQ3pSZSxJQUFFZCxDQUR1UixFQUNyUjNDLElBQUU0QyxDQURtUixFQUNqUmMsSUFBRWIsQ0FEK1EsRUFDN1FjLElBQUViLENBRDJRLEVBQ3pRYyxJQUFFYixDQUR1USxFQUNyUWMsSUFBRWIsQ0FEbVEsRUFDalF4RyxJQUFFeUcsQ0FEK1AsRUFDN1B4SCxJQUFFeUgsQ0FEMlAsRUFDelBZLElBQUVYLEVBRHVQLEVBQ3BQWSxJQUFFWCxDQURrUCxFQUNoUFksSUFBRVgsRUFEOE8sRUFDM09ZLElBQUVYLENBRHlPLEVBQ3ZPWSxJQUFFWCxFQURxTyxFQUNsT1ksSUFBRVgsQ0FEZ08sRUFDOU4vRSxJQUFFLENBRHdOLEVBQ3ROLEtBQUdBLENBRG1OLEVBQ2pOQSxHQURpTixFQUM3TTtBQUFDLFlBQUlSLElBQUVpQyxFQUFFekIsQ0FBRixDQUFOLENBQVcsSUFBRyxLQUFHQSxDQUFOLEVBQVEsSUFBSXBDLElBQUU0QixFQUFFcUQsSUFBRixHQUFPNUUsRUFBRWQsSUFBRSxJQUFFNkMsQ0FBTixJQUFTLENBQXRCO0FBQUEsWUFBd0J4QyxJQUFFZ0MsRUFBRXNELEdBQUYsR0FBTTdFLEVBQUVkLElBQUUsSUFBRTZDLENBQUosR0FBTSxDQUFSLElBQVcsQ0FBM0MsQ0FBUixLQUF5RDtBQUFDLGNBQUlwQyxJQUFFNkQsRUFBRXpCLElBQUUsRUFBSixDQUFOO0FBQUEsY0FBY3hDLElBQUVJLEVBQUVpRixJQUFsQjtBQUFBLGNBQXVCdkUsSUFBRVYsRUFBRWtGLEdBQTNCO0FBQUEsY0FBK0JsRixJQUFFLENBQUNKLE1BQUksQ0FBSixHQUFNYyxLQUFHLEVBQVYsS0FBZWQsTUFBSSxDQUFKLEdBQU1jLEtBQUcsRUFBeEIsSUFBNEJkLE1BQUksQ0FBakU7QUFBQSxjQUFtRWMsSUFBRSxDQUFDQSxNQUFJLENBQUosR0FBTWQsS0FBRyxFQUFWLEtBQWVjLE1BQUksQ0FBSixHQUFNZCxLQUFHLEVBQXhCLEtBQTZCYyxNQUFJLENBQUosR0FBTWQsS0FBRyxFQUF0QyxDQUFyRTtBQUFBLGNBQStHa0UsSUFBRUQsRUFBRXpCLElBQUUsQ0FBSixDQUFqSDtBQUFBLGNBQXdIeEMsSUFBRWtFLEVBQUVtQixJQUE1SDtBQUFBLGNBQWlJbkYsSUFBRWdFLEVBQUVvQixHQUFySTtBQUFBLGNBQXlJcEIsSUFBRSxDQUFDbEUsTUFBSSxFQUFKLEdBQU9FLEtBQUcsRUFBWCxLQUFnQkYsS0FDcGYsQ0FEb2YsR0FDbGZFLE1BQUksRUFEOGQsSUFDMWRGLE1BQUksQ0FEMlU7QUFBQSxjQUN6VUUsSUFBRSxDQUFDQSxNQUFJLEVBQUosR0FBT0YsS0FBRyxFQUFYLEtBQWdCRSxLQUFHLENBQUgsR0FBS0YsTUFBSSxFQUF6QixLQUE4QkUsTUFBSSxDQUFKLEdBQU1GLEtBQUcsRUFBdkMsQ0FEdVU7QUFBQSxjQUM1UkEsSUFBRWlFLEVBQUV6QixJQUFFLENBQUosQ0FEMFI7QUFBQSxjQUNuUjJGLElBQUVuSSxFQUFFcUYsSUFEK1E7QUFBQSxjQUMxUXZELElBQUVtQyxFQUFFekIsSUFBRSxFQUFKLENBRHdRO0FBQUEsY0FDaFFULElBQUVELEVBQUV1RCxJQUQ0UDtBQUFBLGNBQ3ZQdkQsSUFBRUEsRUFBRXdELEdBRG1QO0FBQUEsY0FDL090RixJQUFFYyxJQUFFZCxFQUFFc0YsR0FEeU87QUFBQSxjQUNyT2xGLElBQUVBLElBQUUrSCxDQUFGLElBQUtuSSxNQUFJLENBQUosR0FBTWMsTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQW5CLENBRG1PO0FBQUEsY0FDN01kLElBQUVBLElBQUVFLENBRHlNO0FBQUEsY0FDdk1FLElBQUVBLElBQUU4RCxDQUFGLElBQUtsRSxNQUFJLENBQUosR0FBTUUsTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQW5CLENBRHFNO0FBQUEsY0FDL0tGLElBQUVBLElBQUU4QixDQUQySztBQUFBLGNBQ3pLMUIsSUFBRUEsSUFBRTJCLENBQUYsSUFBSy9CLE1BQUksQ0FBSixHQUFNOEIsTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQW5CLENBRHVLLENBQ2pKRSxFQUFFcUQsSUFBRixHQUFPakYsQ0FBUCxDQUFTNEIsRUFBRXNELEdBQUYsR0FBTXRGLENBQU47QUFBUSxhQUFJbUksSUFBRTVILElBQUVzSCxDQUFGLEdBQUksQ0FBQ3RILENBQUQsR0FBR3dILENBQWI7QUFBQSxZQUFlakcsSUFBRXRDLElBQUVzSSxDQUFGLEdBQUksQ0FBQ3RJLENBQUQsR0FBR3dJLENBQXhCO0FBQUEsWUFBMEJoRyxJQUFFeEIsSUFBRWdILENBQUYsR0FBSWhILElBQUVpSCxDQUFOLEdBQVFELElBQUVDLENBQXRDO0FBQUEsWUFBd0N2QixJQUFFM0csSUFBRXdFLENBQUYsR0FBSXhFLElBQUVtSSxDQUFOLEdBQVEzRCxJQUFFMkQsQ0FBcEQ7QUFBQSxZQUFzRDVHLElBQUUsQ0FBQ04sTUFBSSxFQUFKLEdBQU9qQixLQUFHLENBQVgsS0FBZWlCLEtBQUcsRUFBSCxHQUFNakIsTUFBSSxDQUF6QixLQUE2QmlCLEtBQUcsRUFBSCxHQUFNakIsTUFBSSxDQUF2QyxDQUF4RDtBQUFBLFlBQWtHMkUsSUFBRSxDQUFDM0UsTUFBSSxFQUFKLEdBQU9pQixLQUFHLENBQVgsS0FBZWpCLEtBQUcsRUFBSCxHQUFNaUIsTUFBSSxDQUF6QixLQUE2QmpCLEtBQUcsRUFBSCxHQUFNaUIsTUFBSSxDQUF2QyxDQUFwRztBQUFBLFlBQThJTixJQUFFaUcsR0FBRzNELENBQUgsQ0FBaEo7QUFBQSxZQUFzSjRGLEtBQUdsSSxFQUFFbUYsSUFBM0o7QUFBQSxZQUFnS2dELEtBQUduSSxFQUFFb0YsR0FBcks7QUFBQSxZQUF5S3BGLElBQUVnSSxLQUFHLENBQUMxSSxNQUFJLEVBQUosR0FBT2UsS0FBRyxFQUFYLEtBQWdCZixNQUFJLEVBQUosR0FBT2UsS0FBRyxFQUExQixLQUErQmYsS0FBRyxFQUFILEdBQU1lLE1BQUksQ0FBekMsQ0FBSCxDQUEzSztBQUFBLFlBQTJOd0IsSUFBRWtHLEtBQUcsQ0FBQzFILE1BQUksRUFBSixHQUFPZixLQUFHLEVBQVgsS0FBZ0JlLE1BQUksRUFBSixHQUFPZixLQUFHLEVBQTFCLEtBQStCZSxLQUFHLEVBQUgsR0FBTWYsTUFBSSxDQUF6QyxDQUFILEtBQWlEVSxNQUFJLENBQUosR0FBTWdJLE1BQUksQ0FBVixHQUFZLENBQVosR0FDdmUsQ0FEc2IsQ0FBN047QUFBQSxZQUN0TmhJLElBQUVBLElBQUU0QixDQURrTjtBQUFBLFlBQ2hOQyxJQUFFQSxJQUFFb0csQ0FBRixJQUFLakksTUFBSSxDQUFKLEdBQU00QixNQUFJLENBQVYsR0FBWSxDQUFaLEdBQWMsQ0FBbkIsQ0FEOE07QUFBQSxZQUN4TDVCLElBQUVBLElBQUVtSSxFQURvTDtBQUFBLFlBQ2pMdEcsSUFBRUEsSUFBRXFHLEVBQUYsSUFBTWxJLE1BQUksQ0FBSixHQUFNbUksT0FBSyxDQUFYLEdBQWEsQ0FBYixHQUFlLENBQXJCLENBRCtLO0FBQUEsWUFDdkpuSSxJQUFFQSxJQUFFRixDQURtSjtBQUFBLFlBQ2pKK0IsSUFBRUEsSUFBRTNCLENBQUYsSUFBS0YsTUFBSSxDQUFKLEdBQU1GLE1BQUksQ0FBVixHQUFZLENBQVosR0FBYyxDQUFuQixDQUQrSTtBQUFBLFlBQ3pIQSxJQUFFa0UsSUFBRWdDLENBRHFIO0FBQUEsWUFDbkhsRSxJQUFFbEIsSUFBRWtCLENBQUYsSUFBS2hDLE1BQUksQ0FBSixHQUFNa0UsTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQW5CLENBRGlIO0FBQUEsWUFDM0YrRCxJQUFFRixDQUR5RjtBQUFBLFlBQ3ZGRyxJQUFFRixDQURxRjtBQUFBLFlBQ25GRCxJQUFFRixDQURpRjtBQUFBLFlBQy9FRyxJQUFFRixDQUQ2RTtBQUFBLFlBQzNFRCxJQUFFdEgsQ0FEeUU7QUFBQSxZQUN2RXVILElBQUV0SSxDQURxRTtBQUFBLFlBQ25FQSxJQUFFb0ksSUFBRTFILENBQUYsR0FBSSxDQUQ2RDtBQUFBLFlBQzNESyxJQUFFb0gsSUFBRTVGLENBQUYsSUFBS3ZDLE1BQUksQ0FBSixHQUFNb0ksTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQW5CLElBQXNCLENBRG1DO0FBQUEsWUFDakNELElBQUVGLENBRCtCO0FBQUEsWUFDN0JHLElBQUVGLENBRDJCO0FBQUEsWUFDekJELElBQUVELENBRHVCO0FBQUEsWUFDckJFLElBQUUzRCxDQURtQjtBQUFBLFlBQ2pCeUQsSUFBRWhILENBRGU7QUFBQSxZQUNidUQsSUFBRXhFLENBRFc7QUFBQSxZQUNUQSxJQUFFVyxJQUFFRixDQUFGLEdBQUksQ0FERztBQUFBLFlBQ0RRLElBQUV1QixJQUFFQyxDQUFGLElBQUt6QyxNQUFJLENBQUosR0FBTVcsTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQW5CLElBQXNCLENBRHZCO0FBQ3lCLFdBQUVtRyxFQUFFZixHQUFGLEdBQU1tQixJQUFFbEgsQ0FBVixDQUFZOEcsRUFBRWhCLElBQUYsR0FBT3ZCLElBQUV0RCxDQUFGLElBQUtpRyxNQUFJLENBQUosR0FBTWxILE1BQUksQ0FBVixHQUFZLENBQVosR0FBYyxDQUFuQixDQUFQLENBQTZCb0gsSUFBRTFHLEVBQUVxRixHQUFGLEdBQU1xQixJQUFFNUMsQ0FBVixDQUFZOUQsRUFBRW9GLElBQUYsR0FBT3FCLElBQUVjLENBQUYsSUFBS2IsTUFBSSxDQUFKLEdBQU01QyxNQUFJLENBQVYsR0FBWSxDQUFaLEdBQWMsQ0FBbkIsQ0FBUCxDQUE2QjhDLElBQUVoRyxFQUFFeUUsR0FBRixHQUFNdUIsSUFBRWEsQ0FBVixDQUFZN0csRUFBRXdFLElBQUYsR0FBT3VCLElBQUVhLENBQUYsSUFBS1osTUFBSSxDQUFKLEdBQU1hLE1BQUksQ0FBVixHQUFZLENBQVosR0FBYyxDQUFuQixDQUFQLENBQTZCWCxJQUFFN0UsRUFBRW9ELEdBQUYsR0FBTXlCLElBQUVhLENBQVYsQ0FBWTFGLEVBQUVtRCxJQUFGLEdBQU95QixJQUFFYSxDQUFGLElBQUtaLE1BQUksQ0FBSixHQUFNYSxNQUFJLENBQVYsR0FBWSxDQUFaLEdBQWMsQ0FBbkIsQ0FBUCxDQUE2QlgsSUFBRVgsRUFBRWhCLEdBQUYsR0FBTTJCLElBQUV6SCxDQUFWLENBQVk4RyxFQUFFakIsSUFBRixHQUFPMkIsSUFBRXpHLENBQUYsSUFBSzBHLE1BQUksQ0FBSixHQUFNekgsTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQW5CLENBQVAsQ0FBNkIySCxJQUFFWixFQUFFakIsR0FBRixHQUFNNkIsSUFBRVcsQ0FBVixDQUFZdkIsRUFBRWxCLElBQUYsR0FBTzZCLEtBQUdXLENBQUgsSUFBTVYsTUFBSSxDQUFKLEdBQU1XLE1BQUksQ0FBVixHQUFZLENBQVosR0FBYyxDQUFwQixDQUFQLENBQThCVCxJQUFFYixFQUFFbEIsR0FBRixHQUFNK0IsSUFBRVcsQ0FBVjtBQUN6ZXhCLFFBQUVuQixJQUFGLEdBQU8rQixLQUFHVyxDQUFILElBQU1WLE1BQUksQ0FBSixHQUFNVyxNQUFJLENBQVYsR0FBWSxDQUFaLEdBQWMsQ0FBcEIsQ0FBUCxDQUE4QlQsSUFBRTlILEVBQUU2RixHQUFGLEdBQU1pQyxJQUFFVyxDQUFWLENBQVl6SSxFQUFFNEYsSUFBRixHQUFPaUMsS0FBR1csQ0FBSCxJQUFNVixNQUFJLENBQUosR0FBTVcsTUFBSSxDQUFWLEdBQVksQ0FBWixHQUFjLENBQXBCLENBQVA7QUFBOEIsS0FKOEQsRUFJN0RyRCxhQUFZLHVCQUFVO0FBQUMsVUFBSXBFLElBQUUsS0FBS2lELEtBQVg7QUFBQSxVQUFpQi9ELElBQUVjLEVBQUVpQixLQUFyQjtBQUFBLFVBQTJCakMsSUFBRSxJQUFFLEtBQUtrRSxXQUFwQztBQUFBLFVBQWdEMUQsSUFBRSxJQUFFUSxFQUFFa0IsUUFBdEQsQ0FBK0RoQyxFQUFFTSxNQUFJLENBQU4sS0FBVSxPQUFLLEtBQUdBLElBQUUsRUFBcEIsQ0FBdUJOLEVBQUUsQ0FBQ00sSUFBRSxHQUFGLEtBQVEsRUFBUixJQUFZLENBQWIsSUFBZ0IsRUFBbEIsSUFBc0JpRixLQUFLYyxLQUFMLENBQVd2RyxJQUFFLFVBQWIsQ0FBdEIsQ0FBK0NFLEVBQUUsQ0FBQ00sSUFBRSxHQUFGLEtBQVEsRUFBUixJQUFZLENBQWIsSUFBZ0IsRUFBbEIsSUFBc0JSLENBQXRCLENBQXdCZ0IsRUFBRWtCLFFBQUYsR0FBVyxJQUFFaEMsRUFBRVcsTUFBZixDQUFzQixLQUFLdUQsUUFBTCxHQUFnQixPQUFPLEtBQUtrQyxLQUFMLENBQVdSLEtBQVgsRUFBUDtBQUEwQixLQUp2TCxFQUl3TC9ELE9BQU0saUJBQVU7QUFBQyxVQUFJZixJQUFFeUIsRUFBRVYsS0FBRixDQUFRWSxJQUFSLENBQWEsSUFBYixDQUFOLENBQXlCM0IsRUFBRXNGLEtBQUYsR0FBUSxLQUFLQSxLQUFMLENBQVd2RSxLQUFYLEVBQVIsQ0FBMkIsT0FBT2YsQ0FBUDtBQUFTLEtBSnRRLEVBSXVRdUQsV0FBVSxFQUpqUixFQUFULENBQVgsQ0FJMFNuRCxFQUFFdUYsTUFBRixHQUFTbEUsRUFBRTRDLGFBQUYsQ0FBZ0I3RSxDQUFoQixDQUFULENBQTRCWSxFQUFFeUgsVUFBRixHQUFhcEcsRUFBRTZDLGlCQUFGLENBQW9COUUsQ0FBcEIsQ0FBYjtBQUFvQyxDQVI1ZDs7QUFVQTs7Ozs7O0FBTUEsQ0FBQyxZQUFVO0FBQUMsTUFBSUMsSUFBRVEsUUFBTjtBQUFBLE1BQWVELElBQUVQLEVBQUVpRixHQUFuQjtBQUFBLE1BQXVCbkYsSUFBRVMsRUFBRTJFLElBQTNCO0FBQUEsTUFBZ0NuRixJQUFFUSxFQUFFZ0IsU0FBcEM7QUFBQSxNQUE4Q2hCLElBQUVQLEVBQUUrRSxJQUFsRDtBQUFBLE1BQXVEdEYsSUFBRWMsRUFBRTJGLE1BQTNEO0FBQUEsTUFBa0UzRixJQUFFQSxFQUFFOEgsTUFBRixHQUFTNUksRUFBRUwsTUFBRixDQUFTLEVBQUNvRixVQUFTLG9CQUFVO0FBQUMsV0FBS3FCLEtBQUwsR0FBVyxJQUFJOUYsRUFBRWlCLElBQU4sQ0FBVyxDQUFDLElBQUlsQixFQUFFa0IsSUFBTixDQUFXLFVBQVgsRUFBc0IsVUFBdEIsQ0FBRCxFQUFtQyxJQUFJbEIsRUFBRWtCLElBQU4sQ0FBVyxVQUFYLEVBQXNCLFNBQXRCLENBQW5DLEVBQW9FLElBQUlsQixFQUFFa0IsSUFBTixDQUFXLFVBQVgsRUFBc0IsU0FBdEIsQ0FBcEUsRUFBcUcsSUFBSWxCLEVBQUVrQixJQUFOLENBQVcsU0FBWCxFQUFxQixVQUFyQixDQUFyRyxFQUFzSSxJQUFJbEIsRUFBRWtCLElBQU4sQ0FBVyxVQUFYLEVBQXNCLFVBQXRCLENBQXRJLEVBQXdLLElBQUlsQixFQUFFa0IsSUFBTixDQUFXLFVBQVgsRUFBc0IsVUFBdEIsQ0FBeEssRUFBME0sSUFBSWxCLEVBQUVrQixJQUFOLENBQVcsVUFBWCxFQUFzQixVQUF0QixDQUExTSxFQUE0TyxJQUFJbEIsRUFBRWtCLElBQU4sQ0FBVyxVQUFYLEVBQXNCLFVBQXRCLENBQTVPLENBQVgsQ0FBWDtBQUFzUyxLQUEzVCxFQUE0VDJELGFBQVksdUJBQVU7QUFBQyxVQUFJcEUsSUFBRWQsRUFBRWtGLFdBQUYsQ0FBY3pDLElBQWQsQ0FBbUIsSUFBbkIsQ0FBTixDQUErQjNCLEVBQUVrQixRQUFGLElBQVksRUFBWixDQUFlLE9BQU9sQixDQUFQO0FBQVMsS0FBMVksRUFBVCxDQUE3RSxDQUFtZVAsRUFBRXFJLE1BQUYsR0FDL2U1SSxFQUFFbUYsYUFBRixDQUFnQnJFLENBQWhCLENBRCtlLENBQzVkUCxFQUFFc0ksVUFBRixHQUFhN0ksRUFBRW9GLGlCQUFGLENBQW9CdEUsQ0FBcEIsQ0FBYjtBQUFvQyxDQUR2RDs7QUFHQTs7QUFFQSxJQUFJZ0ksU0FBTyxrRUFBWCxDQUE4RSxJQUFJQyxTQUFPLEdBQVgsQ0FBZSxTQUFTQyxPQUFULENBQWlCaEosQ0FBakIsRUFBbUI7QUFBQyxNQUFJSyxDQUFKLENBQU0sSUFBSUMsQ0FBSixDQUFNLElBQUlRLElBQUUsRUFBTixDQUFTLEtBQUlULElBQUUsQ0FBTixFQUFRQSxJQUFFLENBQUYsSUFBS0wsRUFBRVcsTUFBZixFQUFzQk4sS0FBRyxDQUF6QixFQUEyQjtBQUFDQyxRQUFFNEMsU0FBU2xELEVBQUVpSixTQUFGLENBQVk1SSxDQUFaLEVBQWNBLElBQUUsQ0FBaEIsQ0FBVCxFQUE0QixFQUE1QixDQUFGLENBQWtDUyxLQUFHZ0ksT0FBTy9DLE1BQVAsQ0FBY3pGLEtBQUcsQ0FBakIsSUFBb0J3SSxPQUFPL0MsTUFBUCxDQUFjekYsSUFBRSxFQUFoQixDQUF2QjtBQUEyQyxPQUFHRCxJQUFFLENBQUYsSUFBS0wsRUFBRVcsTUFBVixFQUFpQjtBQUFDTCxRQUFFNEMsU0FBU2xELEVBQUVpSixTQUFGLENBQVk1SSxDQUFaLEVBQWNBLElBQUUsQ0FBaEIsQ0FBVCxFQUE0QixFQUE1QixDQUFGLENBQWtDUyxLQUFHZ0ksT0FBTy9DLE1BQVAsQ0FBY3pGLEtBQUcsQ0FBakIsQ0FBSDtBQUF1QixHQUEzRSxNQUErRTtBQUFDLFFBQUdELElBQUUsQ0FBRixJQUFLTCxFQUFFVyxNQUFWLEVBQWlCO0FBQUNMLFVBQUU0QyxTQUFTbEQsRUFBRWlKLFNBQUYsQ0FBWTVJLENBQVosRUFBY0EsSUFBRSxDQUFoQixDQUFULEVBQTRCLEVBQTVCLENBQUYsQ0FBa0NTLEtBQUdnSSxPQUFPL0MsTUFBUCxDQUFjekYsS0FBRyxDQUFqQixJQUFvQndJLE9BQU8vQyxNQUFQLENBQWMsQ0FBQ3pGLElBQUUsQ0FBSCxLQUFPLENBQXJCLENBQXZCO0FBQStDO0FBQUMsT0FBR3lJLE1BQUgsRUFBVTtBQUFDLFdBQU0sQ0FBQ2pJLEVBQUVILE1BQUYsR0FBUyxDQUFWLElBQWEsQ0FBbkIsRUFBcUI7QUFBQ0csV0FBR2lJLE1BQUg7QUFBVTtBQUFDLFVBQU9qSSxDQUFQO0FBQVMsVUFBU29JLFFBQVQsQ0FBa0JwSixDQUFsQixFQUFvQjtBQUFDLE1BQUlFLElBQUUsRUFBTixDQUFTLElBQUlNLENBQUosQ0FBTSxJQUFJRCxJQUFFLENBQU4sQ0FBUSxJQUFJRSxDQUFKLENBQU0sSUFBSU8sQ0FBSixDQUFNLEtBQUlSLElBQUUsQ0FBTixFQUFRQSxJQUFFUixFQUFFYSxNQUFaLEVBQW1CLEVBQUVMLENBQXJCLEVBQXVCO0FBQUMsUUFBR1IsRUFBRWlHLE1BQUYsQ0FBU3pGLENBQVQsS0FBYXlJLE1BQWhCLEVBQXVCO0FBQUM7QUFBTSxTQUFFRCxPQUFPOUMsT0FBUCxDQUFlbEcsRUFBRWlHLE1BQUYsQ0FBU3pGLENBQVQsQ0FBZixDQUFGLENBQThCLElBQUdRLElBQUUsQ0FBTCxFQUFPO0FBQUM7QUFBUyxTQUFHVCxLQUFHLENBQU4sRUFBUTtBQUFDTCxXQUFHbUosU0FBU3JJLEtBQUcsQ0FBWixDQUFILENBQWtCUCxJQUFFTyxJQUFFLENBQUosQ0FBTVQsSUFBRSxDQUFGO0FBQUksS0FBckMsTUFBeUM7QUFBQyxVQUFHQSxLQUFHLENBQU4sRUFBUTtBQUFDTCxhQUFHbUosU0FBVTVJLEtBQUcsQ0FBSixHQUFRTyxLQUFHLENBQXBCLENBQUgsQ0FBMkJQLElBQUVPLElBQUUsRUFBSixDQUFPVCxJQUFFLENBQUY7QUFBSSxPQUEvQyxNQUFtRDtBQUFDLFlBQUdBLEtBQUcsQ0FBTixFQUFRO0FBQUNMLGVBQUdtSixTQUFTNUksQ0FBVCxDQUFILENBQWVQLEtBQUdtSixTQUFTckksS0FBRyxDQUFaLENBQUgsQ0FBa0JQLElBQUVPLElBQUUsQ0FBSixDQUFNVCxJQUFFLENBQUY7QUFBSSxTQUFwRCxNQUF3RDtBQUFDTCxlQUFHbUosU0FBVTVJLEtBQUcsQ0FBSixHQUFRTyxLQUFHLENBQXBCLENBQUgsQ0FBMkJkLEtBQUdtSixTQUFTckksSUFBRSxFQUFYLENBQUgsQ0FBa0JULElBQUUsQ0FBRjtBQUFJO0FBQUM7QUFBQztBQUFDLE9BQUdBLEtBQUcsQ0FBTixFQUFRO0FBQUNMLFNBQUdtSixTQUFTNUksS0FBRyxDQUFaLENBQUg7QUFBa0IsVUFBT1AsQ0FBUDtBQUFTLFVBQVNvSixPQUFULENBQWlCOUksQ0FBakIsRUFBbUI7QUFBQyxNQUFJTixJQUFFa0osU0FBUzVJLENBQVQsQ0FBTixDQUFrQixJQUFJQyxDQUFKLENBQU0sSUFBSUYsSUFBRSxJQUFJZ0osS0FBSixFQUFOLENBQWtCLEtBQUk5SSxJQUFFLENBQU4sRUFBUSxJQUFFQSxDQUFGLEdBQUlQLEVBQUVXLE1BQWQsRUFBcUIsRUFBRUosQ0FBdkIsRUFBeUI7QUFBQ0YsTUFBRUUsQ0FBRixJQUFLMkMsU0FBU2xELEVBQUVpSixTQUFGLENBQVksSUFBRTFJLENBQWQsRUFBZ0IsSUFBRUEsQ0FBRixHQUFJLENBQXBCLENBQVQsRUFBZ0MsRUFBaEMsQ0FBTDtBQUF5QyxVQUFPRixDQUFQO0FBQVM7QUFDOStCOztBQUVBLElBQUlpSixLQUFKLENBQVUsSUFBSUMsU0FBTyxlQUFYLENBQTJCLElBQUlDLE9BQU0sQ0FBQ0QsU0FBTyxRQUFSLEtBQW1CLFFBQTdCLENBQXVDLFNBQVNFLFVBQVQsQ0FBb0JuSixDQUFwQixFQUFzQk4sQ0FBdEIsRUFBd0JGLENBQXhCLEVBQTBCO0FBQUMsTUFBR1EsS0FBRyxJQUFOLEVBQVc7QUFBQyxRQUFHLFlBQVUsT0FBT0EsQ0FBcEIsRUFBc0I7QUFBQyxXQUFLb0osVUFBTCxDQUFnQnBKLENBQWhCLEVBQWtCTixDQUFsQixFQUFvQkYsQ0FBcEI7QUFBdUIsS0FBOUMsTUFBa0Q7QUFBQyxVQUFHRSxLQUFHLElBQUgsSUFBUyxZQUFVLE9BQU9NLENBQTdCLEVBQStCO0FBQUMsYUFBS3FKLFVBQUwsQ0FBZ0JySixDQUFoQixFQUFrQixHQUFsQjtBQUF1QixPQUF2RCxNQUEyRDtBQUFDLGFBQUtxSixVQUFMLENBQWdCckosQ0FBaEIsRUFBa0JOLENBQWxCO0FBQXFCO0FBQUM7QUFBQztBQUFDLFVBQVM0SixHQUFULEdBQWM7QUFBQyxTQUFPLElBQUlILFVBQUosQ0FBZSxJQUFmLENBQVA7QUFBNEIsVUFBU0ksR0FBVCxDQUFhL0osQ0FBYixFQUFlZ0IsQ0FBZixFQUFpQlQsQ0FBakIsRUFBbUJDLENBQW5CLEVBQXFCVCxDQUFyQixFQUF1QkQsQ0FBdkIsRUFBeUI7QUFBQyxTQUFNLEVBQUVBLENBQUYsSUFBSyxDQUFYLEVBQWE7QUFBQyxRQUFJSSxJQUFFYyxJQUFFLEtBQUtoQixHQUFMLENBQUYsR0FBWU8sRUFBRUMsQ0FBRixDQUFaLEdBQWlCVCxDQUF2QixDQUF5QkEsSUFBRTBGLEtBQUtjLEtBQUwsQ0FBV3JHLElBQUUsUUFBYixDQUFGLENBQXlCSyxFQUFFQyxHQUFGLElBQU9OLElBQUUsUUFBVDtBQUFrQixVQUFPSCxDQUFQO0FBQVMsVUFBU2lLLEdBQVQsQ0FBYWhLLENBQWIsRUFBZXNDLENBQWYsRUFBaUJHLENBQWpCLEVBQW1CakMsQ0FBbkIsRUFBcUJjLENBQXJCLEVBQXVCTixDQUF2QixFQUF5QjtBQUFDLE1BQUlELElBQUV1QixJQUFFLEtBQVI7QUFBQSxNQUFjakIsSUFBRWlCLEtBQUcsRUFBbkIsQ0FBc0IsT0FBTSxFQUFFdEIsQ0FBRixJQUFLLENBQVgsRUFBYTtBQUFDLFFBQUlkLElBQUUsS0FBS0YsQ0FBTCxJQUFRLEtBQWQsQ0FBb0IsSUFBSUYsSUFBRSxLQUFLRSxHQUFMLEtBQVcsRUFBakIsQ0FBb0IsSUFBSU8sSUFBRWMsSUFBRW5CLENBQUYsR0FBSUosSUFBRWlCLENBQVosQ0FBY2IsSUFBRWEsSUFBRWIsQ0FBRixJQUFLLENBQUNLLElBQUUsS0FBSCxLQUFXLEVBQWhCLElBQW9Ca0MsRUFBRWpDLENBQUYsQ0FBcEIsSUFBMEJjLElBQUUsVUFBNUIsQ0FBRixDQUEwQ0EsSUFBRSxDQUFDcEIsTUFBSSxFQUFMLEtBQVVLLE1BQUksRUFBZCxJQUFrQmMsSUFBRXZCLENBQXBCLElBQXVCd0IsTUFBSSxFQUEzQixDQUFGLENBQWlDbUIsRUFBRWpDLEdBQUYsSUFBT04sSUFBRSxVQUFUO0FBQW9CLFVBQU9vQixDQUFQO0FBQVMsVUFBUzJJLEdBQVQsQ0FBYWpLLENBQWIsRUFBZXNDLENBQWYsRUFBaUJHLENBQWpCLEVBQW1CakMsQ0FBbkIsRUFBcUJjLENBQXJCLEVBQXVCTixDQUF2QixFQUF5QjtBQUFDLE1BQUlELElBQUV1QixJQUFFLEtBQVI7QUFBQSxNQUFjakIsSUFBRWlCLEtBQUcsRUFBbkIsQ0FBc0IsT0FBTSxFQUFFdEIsQ0FBRixJQUFLLENBQVgsRUFBYTtBQUFDLFFBQUlkLElBQUUsS0FBS0YsQ0FBTCxJQUFRLEtBQWQsQ0FBb0IsSUFBSUYsSUFBRSxLQUFLRSxHQUFMLEtBQVcsRUFBakIsQ0FBb0IsSUFBSU8sSUFBRWMsSUFBRW5CLENBQUYsR0FBSUosSUFBRWlCLENBQVosQ0FBY2IsSUFBRWEsSUFBRWIsQ0FBRixJQUFLLENBQUNLLElBQUUsS0FBSCxLQUFXLEVBQWhCLElBQW9Ca0MsRUFBRWpDLENBQUYsQ0FBcEIsR0FBeUJjLENBQTNCLENBQTZCQSxJQUFFLENBQUNwQixLQUFHLEVBQUosS0FBU0ssS0FBRyxFQUFaLElBQWdCYyxJQUFFdkIsQ0FBcEIsQ0FBc0IyQyxFQUFFakMsR0FBRixJQUFPTixJQUFFLFNBQVQ7QUFBbUIsVUFBT29CLENBQVA7QUFBUyxLQUFHb0ksUUFBT25LLFVBQVUySyxPQUFWLElBQW1CLDZCQUE3QixFQUE0RDtBQUFDUCxhQUFXeEosU0FBWCxDQUFxQmdLLEVBQXJCLEdBQXdCSCxHQUF4QixDQUE0QlIsUUFBTSxFQUFOO0FBQVMsQ0FBbEcsTUFBc0c7QUFBQyxNQUFHRSxRQUFPbkssVUFBVTJLLE9BQVYsSUFBbUIsVUFBN0IsRUFBeUM7QUFBQ1AsZUFBV3hKLFNBQVgsQ0FBcUJnSyxFQUFyQixHQUF3QkosR0FBeEIsQ0FBNEJQLFFBQU0sRUFBTjtBQUFTLEdBQS9FLE1BQW1GO0FBQUNHLGVBQVd4SixTQUFYLENBQXFCZ0ssRUFBckIsR0FBd0JGLEdBQXhCLENBQTRCVCxRQUFNLEVBQU47QUFBUztBQUFDLFlBQVdySixTQUFYLENBQXFCaUssRUFBckIsR0FBd0JaLEtBQXhCLENBQThCRyxXQUFXeEosU0FBWCxDQUFxQmtLLEVBQXJCLEdBQXlCLENBQUMsS0FBR2IsS0FBSixJQUFXLENBQXBDLENBQXVDRyxXQUFXeEosU0FBWCxDQUFxQm1LLEVBQXJCLEdBQXlCLEtBQUdkLEtBQTVCLENBQW1DLElBQUllLFFBQU0sRUFBVixDQUFhWixXQUFXeEosU0FBWCxDQUFxQnFLLEVBQXJCLEdBQXdCL0UsS0FBS1csR0FBTCxDQUFTLENBQVQsRUFBV21FLEtBQVgsQ0FBeEIsQ0FBMENaLFdBQVd4SixTQUFYLENBQXFCc0ssRUFBckIsR0FBd0JGLFFBQU1mLEtBQTlCLENBQW9DRyxXQUFXeEosU0FBWCxDQUFxQnVLLEVBQXJCLEdBQXdCLElBQUVsQixLQUFGLEdBQVFlLEtBQWhDLENBQXNDLElBQUlJLFFBQU0sc0NBQVYsQ0FBaUQsSUFBSUMsUUFBTSxJQUFJckIsS0FBSixFQUFWLENBQXNCLElBQUlzQixFQUFKLEVBQU9DLEVBQVAsQ0FBVUQsS0FBRyxJQUFJcEgsVUFBSixDQUFlLENBQWYsQ0FBSCxDQUFxQixLQUFJcUgsS0FBRyxDQUFQLEVBQVNBLE1BQUksQ0FBYixFQUFlLEVBQUVBLEVBQWpCLEVBQW9CO0FBQUNGLFFBQU1DLElBQU4sSUFBWUMsRUFBWjtBQUFlLE1BQUcsSUFBSXJILFVBQUosQ0FBZSxDQUFmLENBQUgsQ0FBcUIsS0FBSXFILEtBQUcsRUFBUCxFQUFVQSxLQUFHLEVBQWIsRUFBZ0IsRUFBRUEsRUFBbEIsRUFBcUI7QUFBQ0YsUUFBTUMsSUFBTixJQUFZQyxFQUFaO0FBQWUsTUFBRyxJQUFJckgsVUFBSixDQUFlLENBQWYsQ0FBSCxDQUFxQixLQUFJcUgsS0FBRyxFQUFQLEVBQVVBLEtBQUcsRUFBYixFQUFnQixFQUFFQSxFQUFsQixFQUFxQjtBQUFDRixRQUFNQyxJQUFOLElBQVlDLEVBQVo7QUFBZSxVQUFTekIsUUFBVCxDQUFrQnJJLENBQWxCLEVBQW9CO0FBQUMsU0FBTzJKLE1BQU0xRSxNQUFOLENBQWFqRixDQUFiLENBQVA7QUFBdUIsVUFBUytKLEtBQVQsQ0FBZXhLLENBQWYsRUFBaUJTLENBQWpCLEVBQW1CO0FBQUMsTUFBSWQsSUFBRTBLLE1BQU1ySyxFQUFFa0QsVUFBRixDQUFhekMsQ0FBYixDQUFOLENBQU4sQ0FBNkIsT0FBT2QsS0FBRyxJQUFKLEdBQVUsQ0FBQyxDQUFYLEdBQWFBLENBQW5CO0FBQXFCLFVBQVM4SyxTQUFULENBQW1CekssQ0FBbkIsRUFBcUI7QUFBQyxPQUFJLElBQUlTLElBQUUsS0FBS3FCLENBQUwsR0FBTyxDQUFqQixFQUFtQnJCLEtBQUcsQ0FBdEIsRUFBd0IsRUFBRUEsQ0FBMUIsRUFBNEI7QUFBQ1QsTUFBRVMsQ0FBRixJQUFLLEtBQUtBLENBQUwsQ0FBTDtBQUFhLEtBQUVxQixDQUFGLEdBQUksS0FBS0EsQ0FBVCxDQUFXOUIsRUFBRWdDLENBQUYsR0FBSSxLQUFLQSxDQUFUO0FBQVcsVUFBUzBJLFVBQVQsQ0FBb0JqSyxDQUFwQixFQUFzQjtBQUFDLE9BQUtxQixDQUFMLEdBQU8sQ0FBUCxDQUFTLEtBQUtFLENBQUwsR0FBUXZCLElBQUUsQ0FBSCxHQUFNLENBQUMsQ0FBUCxHQUFTLENBQWhCLENBQWtCLElBQUdBLElBQUUsQ0FBTCxFQUFPO0FBQUMsU0FBSyxDQUFMLElBQVFBLENBQVI7QUFBVSxHQUFsQixNQUFzQjtBQUFDLFFBQUdBLElBQUUsQ0FBQyxDQUFOLEVBQVE7QUFBQyxXQUFLLENBQUwsSUFBUUEsSUFBRSxLQUFLc0osRUFBZjtBQUFrQixLQUEzQixNQUErQjtBQUFDLFdBQUtqSSxDQUFMLEdBQU8sQ0FBUDtBQUFTO0FBQUM7QUFBQyxVQUFTNkksR0FBVCxDQUFhbEssQ0FBYixFQUFlO0FBQUMsTUFBSVQsSUFBRXVKLEtBQU4sQ0FBWXZKLEVBQUU0SyxPQUFGLENBQVVuSyxDQUFWLEVBQWEsT0FBT1QsQ0FBUDtBQUFTLFVBQVM2SyxhQUFULENBQXVCckwsQ0FBdkIsRUFBeUJVLENBQXpCLEVBQTJCO0FBQUMsTUFBSUQsQ0FBSixDQUFNLElBQUdDLEtBQUcsRUFBTixFQUFTO0FBQUNELFFBQUUsQ0FBRjtBQUFJLEdBQWQsTUFBa0I7QUFBQyxRQUFHQyxLQUFHLENBQU4sRUFBUTtBQUFDRCxVQUFFLENBQUY7QUFBSSxLQUFiLE1BQWlCO0FBQUMsVUFBR0MsS0FBRyxHQUFOLEVBQVU7QUFBQ0QsWUFBRSxDQUFGO0FBQUksT0FBZixNQUFtQjtBQUFDLFlBQUdDLEtBQUcsQ0FBTixFQUFRO0FBQUNELGNBQUUsQ0FBRjtBQUFJLFNBQWIsTUFBaUI7QUFBQyxjQUFHQyxLQUFHLEVBQU4sRUFBUztBQUFDRCxnQkFBRSxDQUFGO0FBQUksV0FBZCxNQUFrQjtBQUFDLGdCQUFHQyxLQUFHLENBQU4sRUFBUTtBQUFDRCxrQkFBRSxDQUFGO0FBQUksYUFBYixNQUFpQjtBQUFDLG1CQUFLNkssU0FBTCxDQUFldEwsQ0FBZixFQUFpQlUsQ0FBakIsRUFBb0I7QUFBTztBQUFDO0FBQUM7QUFBQztBQUFDO0FBQUMsUUFBSzRCLENBQUwsR0FBTyxDQUFQLENBQVMsS0FBS0UsQ0FBTCxHQUFPLENBQVAsQ0FBUyxJQUFJekMsSUFBRUMsRUFBRWMsTUFBUjtBQUFBLE1BQWVYLElBQUUsS0FBakI7QUFBQSxNQUF1QkYsSUFBRSxDQUF6QixDQUEyQixPQUFNLEVBQUVGLENBQUYsSUFBSyxDQUFYLEVBQWE7QUFBQyxRQUFJa0IsSUFBR1IsS0FBRyxDQUFKLEdBQU9ULEVBQUVELENBQUYsSUFBSyxHQUFaLEdBQWdCaUwsTUFBTWhMLENBQU4sRUFBUUQsQ0FBUixDQUF0QixDQUFpQyxJQUFHa0IsSUFBRSxDQUFMLEVBQU87QUFBQyxVQUFHakIsRUFBRWtHLE1BQUYsQ0FBU25HLENBQVQsS0FBYSxHQUFoQixFQUFvQjtBQUFDSSxZQUFFLElBQUY7QUFBTztBQUFTLFNBQUUsS0FBRixDQUFRLElBQUdGLEtBQUcsQ0FBTixFQUFRO0FBQUMsV0FBSyxLQUFLcUMsQ0FBTCxFQUFMLElBQWVyQixDQUFmO0FBQWlCLEtBQTFCLE1BQThCO0FBQUMsVUFBR2hCLElBQUVRLENBQUYsR0FBSSxLQUFLNEosRUFBWixFQUFlO0FBQUMsYUFBSyxLQUFLL0gsQ0FBTCxHQUFPLENBQVosS0FBZ0IsQ0FBQ3JCLElBQUcsQ0FBQyxLQUFJLEtBQUtvSixFQUFMLEdBQVFwSyxDQUFiLElBQWlCLENBQXJCLEtBQTBCQSxDQUExQyxDQUE0QyxLQUFLLEtBQUtxQyxDQUFMLEVBQUwsSUFBZ0JyQixLQUFJLEtBQUtvSixFQUFMLEdBQVFwSyxDQUE1QjtBQUFnQyxPQUE1RixNQUFnRztBQUFDLGFBQUssS0FBS3FDLENBQUwsR0FBTyxDQUFaLEtBQWdCckIsS0FBR2hCLENBQW5CO0FBQXFCO0FBQUMsVUFBR1EsQ0FBSCxDQUFLLElBQUdSLEtBQUcsS0FBS29LLEVBQVgsRUFBYztBQUFDcEssV0FBRyxLQUFLb0ssRUFBUjtBQUFXO0FBQUMsT0FBRzVKLEtBQUcsQ0FBSCxJQUFNLENBQUNULEVBQUUsQ0FBRixJQUFLLEdBQU4sS0FBWSxDQUFyQixFQUF1QjtBQUFDLFNBQUt3QyxDQUFMLEdBQU8sQ0FBQyxDQUFSLENBQVUsSUFBR3ZDLElBQUUsQ0FBTCxFQUFPO0FBQUMsV0FBSyxLQUFLcUMsQ0FBTCxHQUFPLENBQVosS0FBaUIsQ0FBQyxLQUFJLEtBQUsrSCxFQUFMLEdBQVFwSyxDQUFiLElBQWlCLENBQWxCLElBQXNCQSxDQUF0QztBQUF3QztBQUFDLFFBQUt3QyxLQUFMLEdBQWEsSUFBR3RDLENBQUgsRUFBSztBQUFDeUosZUFBVzJCLElBQVgsQ0FBZ0JDLEtBQWhCLENBQXNCLElBQXRCLEVBQTJCLElBQTNCO0FBQWlDO0FBQUMsVUFBU0MsUUFBVCxHQUFtQjtBQUFDLE1BQUl4SyxJQUFFLEtBQUt1QixDQUFMLEdBQU8sS0FBSzhILEVBQWxCLENBQXFCLE9BQU0sS0FBS2hJLENBQUwsR0FBTyxDQUFQLElBQVUsS0FBSyxLQUFLQSxDQUFMLEdBQU8sQ0FBWixLQUFnQnJCLENBQWhDLEVBQWtDO0FBQUMsTUFBRSxLQUFLcUIsQ0FBUDtBQUFTO0FBQUMsVUFBU29KLFVBQVQsQ0FBb0JoTCxDQUFwQixFQUFzQjtBQUFDLE1BQUcsS0FBSzhCLENBQUwsR0FBTyxDQUFWLEVBQVk7QUFBQyxXQUFNLE1BQUksS0FBS21KLE1BQUwsR0FBYzVKLFFBQWQsQ0FBdUJyQixDQUF2QixDQUFWO0FBQW9DLE9BQUlELENBQUosQ0FBTSxJQUFHQyxLQUFHLEVBQU4sRUFBUztBQUFDRCxRQUFFLENBQUY7QUFBSSxHQUFkLE1BQWtCO0FBQUMsUUFBR0MsS0FBRyxDQUFOLEVBQVE7QUFBQ0QsVUFBRSxDQUFGO0FBQUksS0FBYixNQUFpQjtBQUFDLFVBQUdDLEtBQUcsQ0FBTixFQUFRO0FBQUNELFlBQUUsQ0FBRjtBQUFJLE9BQWIsTUFBaUI7QUFBQyxZQUFHQyxLQUFHLEVBQU4sRUFBUztBQUFDRCxjQUFFLENBQUY7QUFBSSxTQUFkLE1BQWtCO0FBQUMsY0FBR0MsS0FBRyxDQUFOLEVBQVE7QUFBQ0QsZ0JBQUUsQ0FBRjtBQUFJLFdBQWIsTUFBaUI7QUFBQyxtQkFBTyxLQUFLbUwsT0FBTCxDQUFhbEwsQ0FBYixDQUFQO0FBQXVCO0FBQUM7QUFBQztBQUFDO0FBQUMsT0FBSVgsSUFBRSxDQUFDLEtBQUdVLENBQUosSUFBTyxDQUFiO0FBQUEsTUFBZU0sQ0FBZjtBQUFBLE1BQWlCRSxJQUFFLEtBQW5CO0FBQUEsTUFBeUJqQixJQUFFLEVBQTNCO0FBQUEsTUFBOEJDLElBQUUsS0FBS3FDLENBQXJDLENBQXVDLElBQUkxQixJQUFFLEtBQUt5SixFQUFMLEdBQVNwSyxJQUFFLEtBQUtvSyxFQUFSLEdBQVk1SixDQUExQixDQUE0QixJQUFHUixNQUFJLENBQVAsRUFBUztBQUFDLFFBQUdXLElBQUUsS0FBS3lKLEVBQVAsSUFBVyxDQUFDdEosSUFBRSxLQUFLZCxDQUFMLEtBQVNXLENBQVosSUFBZSxDQUE3QixFQUErQjtBQUFDSyxVQUFFLElBQUYsQ0FBT2pCLElBQUVzSixTQUFTdkksQ0FBVCxDQUFGO0FBQWMsWUFBTWQsS0FBRyxDQUFULEVBQVc7QUFBQyxVQUFHVyxJQUFFSCxDQUFMLEVBQU87QUFBQ00sWUFBRSxDQUFDLEtBQUtkLENBQUwsSUFBUyxDQUFDLEtBQUdXLENBQUosSUFBTyxDQUFqQixLQUF1QkgsSUFBRUcsQ0FBM0IsQ0FBOEJHLEtBQUcsS0FBSyxFQUFFZCxDQUFQLE1BQVlXLEtBQUcsS0FBS3lKLEVBQUwsR0FBUTVKLENBQXZCLENBQUg7QUFBNkIsT0FBbkUsTUFBdUU7QUFBQ00sWUFBRyxLQUFLZCxDQUFMLE1BQVVXLEtBQUdILENBQWIsQ0FBRCxHQUFrQlYsQ0FBcEIsQ0FBc0IsSUFBR2EsS0FBRyxDQUFOLEVBQVE7QUFBQ0EsZUFBRyxLQUFLeUosRUFBUixDQUFXLEVBQUVwSyxDQUFGO0FBQUk7QUFBQyxXQUFHYyxJQUFFLENBQUwsRUFBTztBQUFDRSxZQUFFLElBQUY7QUFBTyxXQUFHQSxDQUFILEVBQUs7QUFBQ2pCLGFBQUdzSixTQUFTdkksQ0FBVCxDQUFIO0FBQWU7QUFBQztBQUFDLFVBQU9FLElBQUVqQixDQUFGLEdBQUksR0FBWDtBQUFlLFVBQVM2TCxRQUFULEdBQW1CO0FBQUMsTUFBSTVLLElBQUU4SSxLQUFOLENBQVlILFdBQVcyQixJQUFYLENBQWdCQyxLQUFoQixDQUFzQixJQUF0QixFQUEyQnZLLENBQTNCLEVBQThCLE9BQU9BLENBQVA7QUFBUyxVQUFTNkssS0FBVCxHQUFnQjtBQUFDLFNBQU8sS0FBS3RKLENBQUwsR0FBTyxDQUFSLEdBQVcsS0FBS21KLE1BQUwsRUFBWCxHQUF5QixJQUEvQjtBQUFvQyxVQUFTSSxXQUFULENBQXFCdkwsQ0FBckIsRUFBdUI7QUFBQyxNQUFJTCxJQUFFLEtBQUtxQyxDQUFMLEdBQU9oQyxFQUFFZ0MsQ0FBZixDQUFpQixJQUFHckMsS0FBRyxDQUFOLEVBQVE7QUFBQyxXQUFPQSxDQUFQO0FBQVMsT0FBSU8sSUFBRSxLQUFLNEIsQ0FBWCxDQUFhbkMsSUFBRU8sSUFBRUYsRUFBRThCLENBQU4sQ0FBUSxJQUFHbkMsS0FBRyxDQUFOLEVBQVE7QUFBQyxXQUFPLEtBQUtxQyxDQUFMLEdBQU8sQ0FBUixHQUFXLENBQUNyQyxDQUFaLEdBQWNBLENBQXBCO0FBQXNCLFVBQU0sRUFBRU8sQ0FBRixJQUFLLENBQVgsRUFBYTtBQUFDLFFBQUcsQ0FBQ1AsSUFBRSxLQUFLTyxDQUFMLElBQVFGLEVBQUVFLENBQUYsQ0FBWCxLQUFrQixDQUFyQixFQUF1QjtBQUFDLGFBQU9QLENBQVA7QUFBUztBQUFDLFVBQU8sQ0FBUDtBQUFTLFVBQVM2TCxLQUFULENBQWUvSyxDQUFmLEVBQWlCO0FBQUMsTUFBSVAsSUFBRSxDQUFOO0FBQUEsTUFBUUYsQ0FBUixDQUFVLElBQUcsQ0FBQ0EsSUFBRVMsTUFBSSxFQUFQLEtBQVksQ0FBZixFQUFpQjtBQUFDQSxRQUFFVCxDQUFGLENBQUlFLEtBQUcsRUFBSDtBQUFNLE9BQUcsQ0FBQ0YsSUFBRVMsS0FBRyxDQUFOLEtBQVUsQ0FBYixFQUFlO0FBQUNBLFFBQUVULENBQUYsQ0FBSUUsS0FBRyxDQUFIO0FBQUssT0FBRyxDQUFDRixJQUFFUyxLQUFHLENBQU4sS0FBVSxDQUFiLEVBQWU7QUFBQ0EsUUFBRVQsQ0FBRixDQUFJRSxLQUFHLENBQUg7QUFBSyxPQUFHLENBQUNGLElBQUVTLEtBQUcsQ0FBTixLQUFVLENBQWIsRUFBZTtBQUFDQSxRQUFFVCxDQUFGLENBQUlFLEtBQUcsQ0FBSDtBQUFLLE9BQUcsQ0FBQ0YsSUFBRVMsS0FBRyxDQUFOLEtBQVUsQ0FBYixFQUFlO0FBQUNBLFFBQUVULENBQUYsQ0FBSUUsS0FBRyxDQUFIO0FBQUssVUFBT0EsQ0FBUDtBQUFTLFVBQVN1TCxXQUFULEdBQXNCO0FBQUMsTUFBRyxLQUFLM0osQ0FBTCxJQUFRLENBQVgsRUFBYTtBQUFDLFdBQU8sQ0FBUDtBQUFTLFVBQU8sS0FBSytILEVBQUwsSUFBUyxLQUFLL0gsQ0FBTCxHQUFPLENBQWhCLElBQW1CMEosTUFBTSxLQUFLLEtBQUsxSixDQUFMLEdBQU8sQ0FBWixJQUFnQixLQUFLRSxDQUFMLEdBQU8sS0FBSzhILEVBQWxDLENBQTFCO0FBQWlFLFVBQVM0QixZQUFULENBQXNCeEwsQ0FBdEIsRUFBd0JGLENBQXhCLEVBQTBCO0FBQUMsTUFBSVMsQ0FBSixDQUFNLEtBQUlBLElBQUUsS0FBS3FCLENBQUwsR0FBTyxDQUFiLEVBQWVyQixLQUFHLENBQWxCLEVBQW9CLEVBQUVBLENBQXRCLEVBQXdCO0FBQUNULE1BQUVTLElBQUVQLENBQUosSUFBTyxLQUFLTyxDQUFMLENBQVA7QUFBZSxRQUFJQSxJQUFFUCxJQUFFLENBQVIsRUFBVU8sS0FBRyxDQUFiLEVBQWUsRUFBRUEsQ0FBakIsRUFBbUI7QUFBQ1QsTUFBRVMsQ0FBRixJQUFLLENBQUw7QUFBTyxLQUFFcUIsQ0FBRixHQUFJLEtBQUtBLENBQUwsR0FBTzVCLENBQVgsQ0FBYUYsRUFBRWdDLENBQUYsR0FBSSxLQUFLQSxDQUFUO0FBQVcsVUFBUzJKLFlBQVQsQ0FBc0J6TCxDQUF0QixFQUF3QkYsQ0FBeEIsRUFBMEI7QUFBQyxPQUFJLElBQUlTLElBQUVQLENBQVYsRUFBWU8sSUFBRSxLQUFLcUIsQ0FBbkIsRUFBcUIsRUFBRXJCLENBQXZCLEVBQXlCO0FBQUNULE1BQUVTLElBQUVQLENBQUosSUFBTyxLQUFLTyxDQUFMLENBQVA7QUFBZSxLQUFFcUIsQ0FBRixHQUFJb0QsS0FBS2YsR0FBTCxDQUFTLEtBQUtyQyxDQUFMLEdBQU81QixDQUFoQixFQUFrQixDQUFsQixDQUFKLENBQXlCRixFQUFFZ0MsQ0FBRixHQUFJLEtBQUtBLENBQVQ7QUFBVyxVQUFTNEosV0FBVCxDQUFxQnhMLENBQXJCLEVBQXVCSCxDQUF2QixFQUF5QjtBQUFDLE1BQUlELElBQUVJLElBQUUsS0FBS3lKLEVBQWIsQ0FBZ0IsSUFBSXBKLElBQUUsS0FBS29KLEVBQUwsR0FBUTdKLENBQWQsQ0FBZ0IsSUFBSVQsSUFBRSxDQUFDLEtBQUdrQixDQUFKLElBQU8sQ0FBYixDQUFlLElBQUloQixJQUFFeUYsS0FBS2MsS0FBTCxDQUFXNUYsSUFBRSxLQUFLeUosRUFBbEIsQ0FBTjtBQUFBLE1BQTRCckssSUFBRyxLQUFLd0MsQ0FBTCxJQUFRaEMsQ0FBVCxHQUFZLEtBQUs4SixFQUEvQztBQUFBLE1BQWtEbkssQ0FBbEQsQ0FBb0QsS0FBSUEsSUFBRSxLQUFLbUMsQ0FBTCxHQUFPLENBQWIsRUFBZW5DLEtBQUcsQ0FBbEIsRUFBb0IsRUFBRUEsQ0FBdEIsRUFBd0I7QUFBQ00sTUFBRU4sSUFBRUYsQ0FBRixHQUFJLENBQU4sSUFBVSxLQUFLRSxDQUFMLEtBQVNjLENBQVYsR0FBYWpCLENBQXRCLENBQXdCQSxJQUFFLENBQUMsS0FBS0csQ0FBTCxJQUFRSixDQUFULEtBQWFTLENBQWY7QUFBaUIsUUFBSUwsSUFBRUYsSUFBRSxDQUFSLEVBQVVFLEtBQUcsQ0FBYixFQUFlLEVBQUVBLENBQWpCLEVBQW1CO0FBQUNNLE1BQUVOLENBQUYsSUFBSyxDQUFMO0FBQU8sS0FBRUYsQ0FBRixJQUFLRCxDQUFMLENBQU9TLEVBQUU2QixDQUFGLEdBQUksS0FBS0EsQ0FBTCxHQUFPckMsQ0FBUCxHQUFTLENBQWIsQ0FBZVEsRUFBRStCLENBQUYsR0FBSSxLQUFLQSxDQUFULENBQVcvQixFQUFFZ0MsS0FBRjtBQUFVLFVBQVM0SixXQUFULENBQXFCdE0sQ0FBckIsRUFBdUJJLENBQXZCLEVBQXlCO0FBQUNBLElBQUVxQyxDQUFGLEdBQUksS0FBS0EsQ0FBVCxDQUFXLElBQUkvQixJQUFFaUYsS0FBS2MsS0FBTCxDQUFXekcsSUFBRSxLQUFLc0ssRUFBbEIsQ0FBTixDQUE0QixJQUFHNUosS0FBRyxLQUFLNkIsQ0FBWCxFQUFhO0FBQUNuQyxNQUFFbUMsQ0FBRixHQUFJLENBQUosQ0FBTTtBQUFPLE9BQUk5QixJQUFFVCxJQUFFLEtBQUtzSyxFQUFiLENBQWdCLElBQUlwSixJQUFFLEtBQUtvSixFQUFMLEdBQVE3SixDQUFkLENBQWdCLElBQUlQLElBQUUsQ0FBQyxLQUFHTyxDQUFKLElBQU8sQ0FBYixDQUFlTCxFQUFFLENBQUYsSUFBSyxLQUFLTSxDQUFMLEtBQVNELENBQWQsQ0FBZ0IsS0FBSSxJQUFJRSxJQUFFRCxJQUFFLENBQVosRUFBY0MsSUFBRSxLQUFLNEIsQ0FBckIsRUFBdUIsRUFBRTVCLENBQXpCLEVBQTJCO0FBQUNQLE1BQUVPLElBQUVELENBQUYsR0FBSSxDQUFOLEtBQVUsQ0FBQyxLQUFLQyxDQUFMLElBQVFULENBQVQsS0FBYWdCLENBQXZCLENBQXlCZCxFQUFFTyxJQUFFRCxDQUFKLElBQU8sS0FBS0MsQ0FBTCxLQUFTRixDQUFoQjtBQUFrQixPQUFHQSxJQUFFLENBQUwsRUFBTztBQUFDTCxNQUFFLEtBQUttQyxDQUFMLEdBQU83QixDQUFQLEdBQVMsQ0FBWCxLQUFlLENBQUMsS0FBSytCLENBQUwsR0FBT3ZDLENBQVIsS0FBWWdCLENBQTNCO0FBQTZCLEtBQUVxQixDQUFGLEdBQUksS0FBS0EsQ0FBTCxHQUFPN0IsQ0FBWCxDQUFhTixFQUFFc0MsS0FBRjtBQUFVLFVBQVM2SixRQUFULENBQWtCbk0sQ0FBbEIsRUFBb0JGLENBQXBCLEVBQXNCO0FBQUMsTUFBSVEsSUFBRSxDQUFOO0FBQUEsTUFBUVYsSUFBRSxDQUFWO0FBQUEsTUFBWVMsSUFBRWtGLEtBQUtiLEdBQUwsQ0FBUzFFLEVBQUVtQyxDQUFYLEVBQWEsS0FBS0EsQ0FBbEIsQ0FBZCxDQUFtQyxPQUFNN0IsSUFBRUQsQ0FBUixFQUFVO0FBQUNULFNBQUcsS0FBS1UsQ0FBTCxJQUFRTixFQUFFTSxDQUFGLENBQVgsQ0FBZ0JSLEVBQUVRLEdBQUYsSUFBT1YsSUFBRSxLQUFLdUssRUFBZCxDQUFpQnZLLE1BQUksS0FBS3NLLEVBQVQ7QUFBWSxPQUFHbEssRUFBRW1DLENBQUYsR0FBSSxLQUFLQSxDQUFaLEVBQWM7QUFBQ3ZDLFNBQUdJLEVBQUVxQyxDQUFMLENBQU8sT0FBTS9CLElBQUUsS0FBSzZCLENBQWIsRUFBZTtBQUFDdkMsV0FBRyxLQUFLVSxDQUFMLENBQUgsQ0FBV1IsRUFBRVEsR0FBRixJQUFPVixJQUFFLEtBQUt1SyxFQUFkLENBQWlCdkssTUFBSSxLQUFLc0ssRUFBVDtBQUFZLFVBQUcsS0FBSzdILENBQVI7QUFBVSxHQUF4RixNQUE0RjtBQUFDekMsU0FBRyxLQUFLeUMsQ0FBUixDQUFVLE9BQU0vQixJQUFFTixFQUFFbUMsQ0FBVixFQUFZO0FBQUN2QyxXQUFHSSxFQUFFTSxDQUFGLENBQUgsQ0FBUVIsRUFBRVEsR0FBRixJQUFPVixJQUFFLEtBQUt1SyxFQUFkLENBQWlCdkssTUFBSSxLQUFLc0ssRUFBVDtBQUFZLFVBQUdsSyxFQUFFcUMsQ0FBTDtBQUFPLEtBQUVBLENBQUYsR0FBS3pDLElBQUUsQ0FBSCxHQUFNLENBQUMsQ0FBUCxHQUFTLENBQWIsQ0FBZSxJQUFHQSxJQUFFLENBQUMsQ0FBTixFQUFRO0FBQUNFLE1BQUVRLEdBQUYsSUFBTyxLQUFLOEosRUFBTCxHQUFReEssQ0FBZjtBQUFpQixHQUExQixNQUE4QjtBQUFDLFFBQUdBLElBQUUsQ0FBTCxFQUFPO0FBQUNFLFFBQUVRLEdBQUYsSUFBT1YsQ0FBUDtBQUFTO0FBQUMsS0FBRXVDLENBQUYsR0FBSTdCLENBQUosQ0FBTVIsRUFBRXdDLEtBQUY7QUFBVSxVQUFTOEosYUFBVCxDQUF1QjdMLENBQXZCLEVBQXlCRCxDQUF6QixFQUEyQjtBQUFDLE1BQUlELElBQUUsS0FBS2dNLEdBQUwsRUFBTjtBQUFBLE1BQWlCdk0sSUFBRVMsRUFBRThMLEdBQUYsRUFBbkIsQ0FBMkIsSUFBSXJNLElBQUVLLEVBQUU4QixDQUFSLENBQVU3QixFQUFFNkIsQ0FBRixHQUFJbkMsSUFBRUYsRUFBRXFDLENBQVIsQ0FBVSxPQUFNLEVBQUVuQyxDQUFGLElBQUssQ0FBWCxFQUFhO0FBQUNNLE1BQUVOLENBQUYsSUFBSyxDQUFMO0FBQU8sUUFBSUEsSUFBRSxDQUFOLEVBQVFBLElBQUVGLEVBQUVxQyxDQUFaLEVBQWMsRUFBRW5DLENBQWhCLEVBQWtCO0FBQUNNLE1BQUVOLElBQUVLLEVBQUU4QixDQUFOLElBQVM5QixFQUFFNEosRUFBRixDQUFLLENBQUwsRUFBT25LLEVBQUVFLENBQUYsQ0FBUCxFQUFZTSxDQUFaLEVBQWNOLENBQWQsRUFBZ0IsQ0FBaEIsRUFBa0JLLEVBQUU4QixDQUFwQixDQUFUO0FBQWdDLEtBQUVFLENBQUYsR0FBSSxDQUFKLENBQU0vQixFQUFFZ0MsS0FBRixHQUFVLElBQUcsS0FBS0QsQ0FBTCxJQUFROUIsRUFBRThCLENBQWIsRUFBZTtBQUFDb0gsZUFBVzJCLElBQVgsQ0FBZ0JDLEtBQWhCLENBQXNCL0ssQ0FBdEIsRUFBd0JBLENBQXhCO0FBQTJCO0FBQUMsVUFBU2dNLFdBQVQsQ0FBcUJ0TSxDQUFyQixFQUF1QjtBQUFDLE1BQUljLElBQUUsS0FBS3VMLEdBQUwsRUFBTixDQUFpQixJQUFJaE0sSUFBRUwsRUFBRW1DLENBQUYsR0FBSSxJQUFFckIsRUFBRXFCLENBQWQsQ0FBZ0IsT0FBTSxFQUFFOUIsQ0FBRixJQUFLLENBQVgsRUFBYTtBQUFDTCxNQUFFSyxDQUFGLElBQUssQ0FBTDtBQUFPLFFBQUlBLElBQUUsQ0FBTixFQUFRQSxJQUFFUyxFQUFFcUIsQ0FBRixHQUFJLENBQWQsRUFBZ0IsRUFBRTlCLENBQWxCLEVBQW9CO0FBQUMsUUFBSUMsSUFBRVEsRUFBRW1KLEVBQUYsQ0FBSzVKLENBQUwsRUFBT1MsRUFBRVQsQ0FBRixDQUFQLEVBQVlMLENBQVosRUFBYyxJQUFFSyxDQUFoQixFQUFrQixDQUFsQixFQUFvQixDQUFwQixDQUFOLENBQTZCLElBQUcsQ0FBQ0wsRUFBRUssSUFBRVMsRUFBRXFCLENBQU4sS0FBVXJCLEVBQUVtSixFQUFGLENBQUs1SixJQUFFLENBQVAsRUFBUyxJQUFFUyxFQUFFVCxDQUFGLENBQVgsRUFBZ0JMLENBQWhCLEVBQWtCLElBQUVLLENBQUYsR0FBSSxDQUF0QixFQUF3QkMsQ0FBeEIsRUFBMEJRLEVBQUVxQixDQUFGLEdBQUk5QixDQUFKLEdBQU0sQ0FBaEMsQ0FBWCxLQUFnRFMsRUFBRXNKLEVBQXJELEVBQXdEO0FBQUNwSyxRQUFFSyxJQUFFUyxFQUFFcUIsQ0FBTixLQUFVckIsRUFBRXNKLEVBQVosQ0FBZXBLLEVBQUVLLElBQUVTLEVBQUVxQixDQUFKLEdBQU0sQ0FBUixJQUFXLENBQVg7QUFBYTtBQUFDLE9BQUduQyxFQUFFbUMsQ0FBRixHQUFJLENBQVAsRUFBUztBQUFDbkMsTUFBRUEsRUFBRW1DLENBQUYsR0FBSSxDQUFOLEtBQVVyQixFQUFFbUosRUFBRixDQUFLNUosQ0FBTCxFQUFPUyxFQUFFVCxDQUFGLENBQVAsRUFBWUwsQ0FBWixFQUFjLElBQUVLLENBQWhCLEVBQWtCLENBQWxCLEVBQW9CLENBQXBCLENBQVY7QUFBaUMsS0FBRWdDLENBQUYsR0FBSSxDQUFKLENBQU1yQyxFQUFFc0MsS0FBRjtBQUFVLFVBQVNpSyxXQUFULENBQXFCckwsQ0FBckIsRUFBdUJyQixDQUF2QixFQUF5QkQsQ0FBekIsRUFBMkI7QUFBQyxNQUFJdUUsSUFBRWpELEVBQUVtTCxHQUFGLEVBQU4sQ0FBYyxJQUFHbEksRUFBRWhDLENBQUYsSUFBSyxDQUFSLEVBQVU7QUFBQztBQUFPLE9BQUl0QixJQUFFLEtBQUt3TCxHQUFMLEVBQU4sQ0FBaUIsSUFBR3hMLEVBQUVzQixDQUFGLEdBQUlnQyxFQUFFaEMsQ0FBVCxFQUFXO0FBQUMsUUFBR3RDLEtBQUcsSUFBTixFQUFXO0FBQUNBLFFBQUVvTCxPQUFGLENBQVUsQ0FBVjtBQUFhLFNBQUdyTCxLQUFHLElBQU4sRUFBVztBQUFDLFdBQUs0TSxNQUFMLENBQVk1TSxDQUFaO0FBQWU7QUFBTyxPQUFHQSxLQUFHLElBQU4sRUFBVztBQUFDQSxRQUFFZ0ssS0FBRjtBQUFRLE9BQUk1SixJQUFFNEosS0FBTjtBQUFBLE1BQVk5SSxJQUFFLEtBQUt1QixDQUFuQjtBQUFBLE1BQXFCekIsSUFBRU0sRUFBRW1CLENBQXpCLENBQTJCLElBQUlpQyxJQUFFLEtBQUs0RixFQUFMLEdBQVEyQixNQUFNMUgsRUFBRUEsRUFBRWhDLENBQUYsR0FBSSxDQUFOLENBQU4sQ0FBZCxDQUE4QixJQUFHbUMsSUFBRSxDQUFMLEVBQU87QUFBQ0gsTUFBRXNJLFFBQUYsQ0FBV25JLENBQVgsRUFBYXRFLENBQWIsRUFBZ0JhLEVBQUU0TCxRQUFGLENBQVduSSxDQUFYLEVBQWExRSxDQUFiO0FBQWdCLEdBQXhDLE1BQTRDO0FBQUN1RSxNQUFFcUksTUFBRixDQUFTeE0sQ0FBVCxFQUFZYSxFQUFFMkwsTUFBRixDQUFTNU0sQ0FBVDtBQUFZLE9BQUl1QixJQUFFbkIsRUFBRW1DLENBQVIsQ0FBVSxJQUFJOUIsSUFBRUwsRUFBRW1CLElBQUUsQ0FBSixDQUFOLENBQWEsSUFBR2QsS0FBRyxDQUFOLEVBQVE7QUFBQztBQUFPLE9BQUllLElBQUVmLEtBQUcsS0FBRyxLQUFLa0ssRUFBWCxLQUFpQnBKLElBQUUsQ0FBSCxHQUFNbkIsRUFBRW1CLElBQUUsQ0FBSixLQUFRLEtBQUtxSixFQUFuQixHQUFzQixDQUF0QyxDQUFOLENBQStDLElBQUkxQyxJQUFFLEtBQUt3QyxFQUFMLEdBQVFsSixDQUFkO0FBQUEsTUFBZ0J5RyxJQUFFLENBQUMsS0FBRyxLQUFLMEMsRUFBVCxJQUFhbkosQ0FBL0I7QUFBQSxNQUFpQ2dELElBQUUsS0FBRyxLQUFLb0csRUFBM0MsQ0FBOEMsSUFBSWpHLElBQUUzRSxFQUFFdUMsQ0FBUjtBQUFBLE1BQVVFLElBQUVrQyxJQUFFcEQsQ0FBZDtBQUFBLE1BQWdCckIsSUFBR0QsS0FBRyxJQUFKLEdBQVUrSixLQUFWLEdBQWdCL0osQ0FBbEMsQ0FBb0NHLEVBQUUwTSxTQUFGLENBQVlySyxDQUFaLEVBQWN2QyxDQUFkLEVBQWlCLElBQUdGLEVBQUUrTSxTQUFGLENBQVk3TSxDQUFaLEtBQWdCLENBQW5CLEVBQXFCO0FBQUNGLE1BQUVBLEVBQUV1QyxDQUFGLEVBQUYsSUFBUyxDQUFULENBQVd2QyxFQUFFeUwsS0FBRixDQUFRdkwsQ0FBUixFQUFVRixDQUFWO0FBQWEsY0FBV2dOLEdBQVgsQ0FBZUYsU0FBZixDQUF5QnZMLENBQXpCLEVBQTJCckIsQ0FBM0IsRUFBOEJBLEVBQUV1TCxLQUFGLENBQVFyTCxDQUFSLEVBQVVBLENBQVYsRUFBYSxPQUFNQSxFQUFFbUMsQ0FBRixHQUFJaEIsQ0FBVixFQUFZO0FBQUNuQixNQUFFQSxFQUFFbUMsQ0FBRixFQUFGLElBQVMsQ0FBVDtBQUFXLFVBQU0sRUFBRUUsQ0FBRixJQUFLLENBQVgsRUFBYTtBQUFDLFFBQUk5QixJQUFHWCxFQUFFLEVBQUUyRSxDQUFKLEtBQVFsRSxDQUFULEdBQVksS0FBSzhKLEVBQWpCLEdBQW9CNUUsS0FBS2MsS0FBTCxDQUFXekcsRUFBRTJFLENBQUYsSUFBS3VELENBQUwsR0FBTyxDQUFDbEksRUFBRTJFLElBQUUsQ0FBSixJQUFPSCxDQUFSLElBQVd5RCxDQUE3QixDQUExQixDQUEwRCxJQUFHLENBQUNqSSxFQUFFMkUsQ0FBRixLQUFNdkUsRUFBRWlLLEVBQUYsQ0FBSyxDQUFMLEVBQU8xSixDQUFQLEVBQVNYLENBQVQsRUFBV3lDLENBQVgsRUFBYSxDQUFiLEVBQWVsQixDQUFmLENBQVAsSUFBMEJaLENBQTdCLEVBQStCO0FBQUNQLFFBQUUwTSxTQUFGLENBQVlySyxDQUFaLEVBQWN2QyxDQUFkLEVBQWlCRixFQUFFeUwsS0FBRixDQUFRdkwsQ0FBUixFQUFVRixDQUFWLEVBQWEsT0FBTUEsRUFBRTJFLENBQUYsSUFBSyxFQUFFaEUsQ0FBYixFQUFlO0FBQUNYLFVBQUV5TCxLQUFGLENBQVF2TCxDQUFSLEVBQVVGLENBQVY7QUFBYTtBQUFDO0FBQUMsT0FBR0MsS0FBRyxJQUFOLEVBQVc7QUFBQ0QsTUFBRWlOLFNBQUYsQ0FBWTFMLENBQVosRUFBY3RCLENBQWQsRUFBaUIsSUFBR2lCLEtBQUdGLENBQU4sRUFBUTtBQUFDNkksaUJBQVcyQixJQUFYLENBQWdCQyxLQUFoQixDQUFzQnhMLENBQXRCLEVBQXdCQSxDQUF4QjtBQUEyQjtBQUFDLEtBQUVzQyxDQUFGLEdBQUloQixDQUFKLENBQU12QixFQUFFMEMsS0FBRixHQUFVLElBQUdnQyxJQUFFLENBQUwsRUFBTztBQUFDMUUsTUFBRWtOLFFBQUYsQ0FBV3hJLENBQVgsRUFBYTFFLENBQWI7QUFBZ0IsT0FBR2tCLElBQUUsQ0FBTCxFQUFPO0FBQUMySSxlQUFXMkIsSUFBWCxDQUFnQkMsS0FBaEIsQ0FBc0J6TCxDQUF0QixFQUF3QkEsQ0FBeEI7QUFBMkI7QUFBQyxVQUFTbU4sS0FBVCxDQUFlMU0sQ0FBZixFQUFpQjtBQUFDLE1BQUlFLElBQUVxSixLQUFOLENBQVksS0FBS3lDLEdBQUwsR0FBV1csUUFBWCxDQUFvQjNNLENBQXBCLEVBQXNCLElBQXRCLEVBQTJCRSxDQUEzQixFQUE4QixJQUFHLEtBQUs4QixDQUFMLEdBQU8sQ0FBUCxJQUFVOUIsRUFBRW9NLFNBQUYsQ0FBWWxELFdBQVcyQixJQUF2QixJQUE2QixDQUExQyxFQUE0QztBQUFDL0ssTUFBRWdMLEtBQUYsQ0FBUTlLLENBQVIsRUFBVUEsQ0FBVjtBQUFhLFVBQU9BLENBQVA7QUFBUyxVQUFTME0sT0FBVCxDQUFpQm5NLENBQWpCLEVBQW1CO0FBQUMsT0FBSytCLENBQUwsR0FBTy9CLENBQVA7QUFBUyxVQUFTb00sUUFBVCxDQUFrQnBNLENBQWxCLEVBQW9CO0FBQUMsTUFBR0EsRUFBRXVCLENBQUYsR0FBSSxDQUFKLElBQU92QixFQUFFNkwsU0FBRixDQUFZLEtBQUs5SixDQUFqQixLQUFxQixDQUEvQixFQUFpQztBQUFDLFdBQU8vQixFQUFFcU0sR0FBRixDQUFNLEtBQUt0SyxDQUFYLENBQVA7QUFBcUIsR0FBdkQsTUFBMkQ7QUFBQyxXQUFPL0IsQ0FBUDtBQUFTO0FBQUMsVUFBU3NNLE9BQVQsQ0FBaUJ0TSxDQUFqQixFQUFtQjtBQUFDLFNBQU9BLENBQVA7QUFBUyxVQUFTdU0sT0FBVCxDQUFpQnZNLENBQWpCLEVBQW1CO0FBQUNBLElBQUVrTSxRQUFGLENBQVcsS0FBS25LLENBQWhCLEVBQWtCLElBQWxCLEVBQXVCL0IsQ0FBdkI7QUFBMEIsVUFBU3dNLE1BQVQsQ0FBZ0J4TSxDQUFoQixFQUFrQlAsQ0FBbEIsRUFBb0JGLENBQXBCLEVBQXNCO0FBQUNTLElBQUV5TSxVQUFGLENBQWFoTixDQUFiLEVBQWVGLENBQWYsRUFBa0IsS0FBS21OLE1BQUwsQ0FBWW5OLENBQVo7QUFBZSxVQUFTb04sTUFBVCxDQUFnQjNNLENBQWhCLEVBQWtCVCxDQUFsQixFQUFvQjtBQUFDUyxJQUFFNE0sUUFBRixDQUFXck4sQ0FBWCxFQUFjLEtBQUttTixNQUFMLENBQVluTixDQUFaO0FBQWUsU0FBUUosU0FBUixDQUFrQjBOLE9BQWxCLEdBQTBCVCxRQUExQixDQUFtQ0QsUUFBUWhOLFNBQVIsQ0FBa0IyTixNQUFsQixHQUF5QlIsT0FBekIsQ0FBaUNILFFBQVFoTixTQUFSLENBQWtCdU4sTUFBbEIsR0FBeUJILE9BQXpCLENBQWlDSixRQUFRaE4sU0FBUixDQUFrQjROLEtBQWxCLEdBQXdCUCxNQUF4QixDQUErQkwsUUFBUWhOLFNBQVIsQ0FBa0I2TixLQUFsQixHQUF3QkwsTUFBeEIsQ0FBK0IsU0FBU00sV0FBVCxHQUFzQjtBQUFDLE1BQUcsS0FBSzVMLENBQUwsR0FBTyxDQUFWLEVBQVk7QUFBQyxXQUFPLENBQVA7QUFBUyxPQUFJckIsSUFBRSxLQUFLLENBQUwsQ0FBTixDQUFjLElBQUcsQ0FBQ0EsSUFBRSxDQUFILEtBQU8sQ0FBVixFQUFZO0FBQUMsV0FBTyxDQUFQO0FBQVMsT0FBSVQsSUFBRVMsSUFBRSxDQUFSLENBQVVULElBQUdBLEtBQUcsSUFBRSxDQUFDUyxJQUFFLEVBQUgsSUFBT1QsQ0FBWixDQUFELEdBQWlCLEVBQW5CLENBQXNCQSxJQUFHQSxLQUFHLElBQUUsQ0FBQ1MsSUFBRSxHQUFILElBQVFULENBQWIsQ0FBRCxHQUFrQixHQUFwQixDQUF3QkEsSUFBR0EsS0FBRyxLQUFJLENBQUNTLElBQUUsS0FBSCxJQUFVVCxDQUFYLEdBQWMsS0FBakIsQ0FBSCxDQUFELEdBQThCLEtBQWhDLENBQXNDQSxJQUFHQSxLQUFHLElBQUVTLElBQUVULENBQUYsR0FBSSxLQUFLK0osRUFBZCxDQUFELEdBQW9CLEtBQUtBLEVBQTNCLENBQThCLE9BQU8vSixJQUFFLENBQUgsR0FBTSxLQUFLK0osRUFBTCxHQUFRL0osQ0FBZCxHQUFnQixDQUFDQSxDQUF2QjtBQUF5QixVQUFTMk4sVUFBVCxDQUFvQmxOLENBQXBCLEVBQXNCO0FBQUMsT0FBSytCLENBQUwsR0FBTy9CLENBQVAsQ0FBUyxLQUFLbU4sRUFBTCxHQUFRbk4sRUFBRW9OLFFBQUYsRUFBUixDQUFxQixLQUFLQyxHQUFMLEdBQVMsS0FBS0YsRUFBTCxHQUFRLEtBQWpCLENBQXVCLEtBQUtHLEdBQUwsR0FBUyxLQUFLSCxFQUFMLElBQVMsRUFBbEIsQ0FBcUIsS0FBS0ksRUFBTCxHQUFRLENBQUMsS0FBSXZOLEVBQUVvSixFQUFGLEdBQUssRUFBVixJQUFlLENBQXZCLENBQXlCLEtBQUtvRSxHQUFMLEdBQVMsSUFBRXhOLEVBQUVxQixDQUFiO0FBQWUsVUFBU29NLFdBQVQsQ0FBcUJ6TixDQUFyQixFQUF1QjtBQUFDLE1BQUlULElBQUV1SixLQUFOLENBQVk5SSxFQUFFdUwsR0FBRixHQUFRSyxTQUFSLENBQWtCLEtBQUs3SixDQUFMLENBQU9WLENBQXpCLEVBQTJCOUIsQ0FBM0IsRUFBOEJBLEVBQUUyTSxRQUFGLENBQVcsS0FBS25LLENBQWhCLEVBQWtCLElBQWxCLEVBQXVCeEMsQ0FBdkIsRUFBMEIsSUFBR1MsRUFBRXVCLENBQUYsR0FBSSxDQUFKLElBQU9oQyxFQUFFc00sU0FBRixDQUFZbEQsV0FBVzJCLElBQXZCLElBQTZCLENBQXZDLEVBQXlDO0FBQUMsU0FBS3ZJLENBQUwsQ0FBT3dJLEtBQVAsQ0FBYWhMLENBQWIsRUFBZUEsQ0FBZjtBQUFrQixVQUFPQSxDQUFQO0FBQVMsVUFBU21PLFVBQVQsQ0FBb0IxTixDQUFwQixFQUFzQjtBQUFDLE1BQUlULElBQUV1SixLQUFOLENBQVk5SSxFQUFFMEwsTUFBRixDQUFTbk0sQ0FBVCxFQUFZLEtBQUttTixNQUFMLENBQVluTixDQUFaLEVBQWUsT0FBT0EsQ0FBUDtBQUFTLFVBQVNvTyxVQUFULENBQW9CM04sQ0FBcEIsRUFBc0I7QUFBQyxTQUFNQSxFQUFFcUIsQ0FBRixJQUFLLEtBQUttTSxHQUFoQixFQUFvQjtBQUFDeE4sTUFBRUEsRUFBRXFCLENBQUYsRUFBRixJQUFTLENBQVQ7QUFBVyxRQUFJLElBQUk1QixJQUFFLENBQVYsRUFBWUEsSUFBRSxLQUFLc0MsQ0FBTCxDQUFPVixDQUFyQixFQUF1QixFQUFFNUIsQ0FBekIsRUFBMkI7QUFBQyxRQUFJRixJQUFFUyxFQUFFUCxDQUFGLElBQUssS0FBWCxDQUFpQixJQUFJUCxJQUFHSyxJQUFFLEtBQUs4TixHQUFQLElBQVksQ0FBRTlOLElBQUUsS0FBSytOLEdBQVAsR0FBVyxDQUFDdE4sRUFBRVAsQ0FBRixLQUFNLEVBQVAsSUFBVyxLQUFLNE4sR0FBNUIsR0FBaUMsS0FBS0UsRUFBdkMsS0FBNEMsRUFBeEQsQ0FBRCxHQUE4RHZOLEVBQUVxSixFQUF0RSxDQUF5RTlKLElBQUVFLElBQUUsS0FBS3NDLENBQUwsQ0FBT1YsQ0FBWCxDQUFhckIsRUFBRVQsQ0FBRixLQUFNLEtBQUt3QyxDQUFMLENBQU9vSCxFQUFQLENBQVUsQ0FBVixFQUFZakssQ0FBWixFQUFjYyxDQUFkLEVBQWdCUCxDQUFoQixFQUFrQixDQUFsQixFQUFvQixLQUFLc0MsQ0FBTCxDQUFPVixDQUEzQixDQUFOLENBQW9DLE9BQU1yQixFQUFFVCxDQUFGLEtBQU1TLEVBQUVzSixFQUFkLEVBQWlCO0FBQUN0SixRQUFFVCxDQUFGLEtBQU1TLEVBQUVzSixFQUFSLENBQVd0SixFQUFFLEVBQUVULENBQUo7QUFBUztBQUFDLEtBQUVpQyxLQUFGLEdBQVV4QixFQUFFK0wsU0FBRixDQUFZLEtBQUtoSyxDQUFMLENBQU9WLENBQW5CLEVBQXFCckIsQ0FBckIsRUFBd0IsSUFBR0EsRUFBRTZMLFNBQUYsQ0FBWSxLQUFLOUosQ0FBakIsS0FBcUIsQ0FBeEIsRUFBMEI7QUFBQy9CLE1BQUV1SyxLQUFGLENBQVEsS0FBS3hJLENBQWIsRUFBZS9CLENBQWY7QUFBa0I7QUFBQyxVQUFTNE4sU0FBVCxDQUFtQjVOLENBQW5CLEVBQXFCVCxDQUFyQixFQUF1QjtBQUFDUyxJQUFFNE0sUUFBRixDQUFXck4sQ0FBWCxFQUFjLEtBQUttTixNQUFMLENBQVluTixDQUFaO0FBQWUsVUFBU3NPLFNBQVQsQ0FBbUI3TixDQUFuQixFQUFxQlAsQ0FBckIsRUFBdUJGLENBQXZCLEVBQXlCO0FBQUNTLElBQUV5TSxVQUFGLENBQWFoTixDQUFiLEVBQWVGLENBQWYsRUFBa0IsS0FBS21OLE1BQUwsQ0FBWW5OLENBQVo7QUFBZSxZQUFXSixTQUFYLENBQXFCME4sT0FBckIsR0FBNkJZLFdBQTdCLENBQXlDUCxXQUFXL04sU0FBWCxDQUFxQjJOLE1BQXJCLEdBQTRCWSxVQUE1QixDQUF1Q1IsV0FBVy9OLFNBQVgsQ0FBcUJ1TixNQUFyQixHQUE0QmlCLFVBQTVCLENBQXVDVCxXQUFXL04sU0FBWCxDQUFxQjROLEtBQXJCLEdBQTJCYyxTQUEzQixDQUFxQ1gsV0FBVy9OLFNBQVgsQ0FBcUI2TixLQUFyQixHQUEyQlksU0FBM0IsQ0FBcUMsU0FBU0UsU0FBVCxHQUFvQjtBQUFDLFNBQU0sQ0FBRSxLQUFLek0sQ0FBTCxHQUFPLENBQVIsR0FBWSxLQUFLLENBQUwsSUFBUSxDQUFwQixHQUF1QixLQUFLRSxDQUE3QixLQUFpQyxDQUF2QztBQUF5QyxVQUFTd00sTUFBVCxDQUFnQmhQLENBQWhCLEVBQWtCWSxDQUFsQixFQUFvQjtBQUFDLE1BQUdaLElBQUUsVUFBRixJQUFjQSxJQUFFLENBQW5CLEVBQXFCO0FBQUMsV0FBTzRKLFdBQVdtRCxHQUFsQjtBQUFzQixPQUFJOU0sSUFBRThKLEtBQU47QUFBQSxNQUFZOUksSUFBRThJLEtBQWQ7QUFBQSxNQUFvQjVKLElBQUVTLEVBQUVrTixPQUFGLENBQVUsSUFBVixDQUF0QjtBQUFBLE1BQXNDcE4sSUFBRXNMLE1BQU1oTSxDQUFOLElBQVMsQ0FBakQsQ0FBbURHLEVBQUV3TSxNQUFGLENBQVMxTSxDQUFULEVBQVksT0FBTSxFQUFFUyxDQUFGLElBQUssQ0FBWCxFQUFhO0FBQUNFLE1BQUVxTixLQUFGLENBQVFoTyxDQUFSLEVBQVVnQixDQUFWLEVBQWEsSUFBRyxDQUFDakIsSUFBRyxLQUFHVSxDQUFQLElBQVcsQ0FBZCxFQUFnQjtBQUFDRSxRQUFFb04sS0FBRixDQUFRL00sQ0FBUixFQUFVZCxDQUFWLEVBQVlGLENBQVo7QUFBZSxLQUFoQyxNQUFvQztBQUFDLFVBQUlPLElBQUVQLENBQU4sQ0FBUUEsSUFBRWdCLENBQUYsQ0FBSUEsSUFBRVQsQ0FBRjtBQUFJO0FBQUMsVUFBT0ksRUFBRW1OLE1BQUYsQ0FBUzlOLENBQVQsQ0FBUDtBQUFtQixVQUFTZ1AsV0FBVCxDQUFxQnpPLENBQXJCLEVBQXVCUyxDQUF2QixFQUF5QjtBQUFDLE1BQUlQLENBQUosQ0FBTSxJQUFHRixJQUFFLEdBQUYsSUFBT1MsRUFBRWlPLE1BQUYsRUFBVixFQUFxQjtBQUFDeE8sUUFBRSxJQUFJME0sT0FBSixDQUFZbk0sQ0FBWixDQUFGO0FBQWlCLEdBQXZDLE1BQTJDO0FBQUNQLFFBQUUsSUFBSXlOLFVBQUosQ0FBZWxOLENBQWYsQ0FBRjtBQUFvQixVQUFPLEtBQUtrTyxHQUFMLENBQVMzTyxDQUFULEVBQVdFLENBQVgsQ0FBUDtBQUFxQixZQUFXTixTQUFYLENBQXFCdU0sTUFBckIsR0FBNEIxQixTQUE1QixDQUFzQ3JCLFdBQVd4SixTQUFYLENBQXFCZ0wsT0FBckIsR0FBNkJGLFVBQTdCLENBQXdDdEIsV0FBV3hKLFNBQVgsQ0FBcUIwSixVQUFyQixHQUFnQ3VCLGFBQWhDLENBQThDekIsV0FBV3hKLFNBQVgsQ0FBcUJxQyxLQUFyQixHQUEyQmdKLFFBQTNCLENBQW9DN0IsV0FBV3hKLFNBQVgsQ0FBcUJ5TSxTQUFyQixHQUErQlgsWUFBL0IsQ0FBNEN0QyxXQUFXeEosU0FBWCxDQUFxQjRNLFNBQXJCLEdBQStCYixZQUEvQixDQUE0Q3ZDLFdBQVd4SixTQUFYLENBQXFCd00sUUFBckIsR0FBOEJSLFdBQTlCLENBQTBDeEMsV0FBV3hKLFNBQVgsQ0FBcUI2TSxRQUFyQixHQUE4QlosV0FBOUIsQ0FBMEN6QyxXQUFXeEosU0FBWCxDQUFxQm9MLEtBQXJCLEdBQTJCYyxRQUEzQixDQUFvQzFDLFdBQVd4SixTQUFYLENBQXFCc04sVUFBckIsR0FBZ0NuQixhQUFoQyxDQUE4QzNDLFdBQVd4SixTQUFYLENBQXFCeU4sUUFBckIsR0FBOEJwQixXQUE5QixDQUEwQzdDLFdBQVd4SixTQUFYLENBQXFCK00sUUFBckIsR0FBOEJULFdBQTlCLENBQTBDOUMsV0FBV3hKLFNBQVgsQ0FBcUJpTyxRQUFyQixHQUE4QkgsV0FBOUIsQ0FBMEN0RSxXQUFXeEosU0FBWCxDQUFxQjhPLE1BQXJCLEdBQTRCSCxTQUE1QixDQUFzQ25GLFdBQVd4SixTQUFYLENBQXFCK08sR0FBckIsR0FBeUJILE1BQXpCLENBQWdDcEYsV0FBV3hKLFNBQVgsQ0FBcUIyQixRQUFyQixHQUE4QjJKLFVBQTlCLENBQXlDOUIsV0FBV3hKLFNBQVgsQ0FBcUJ1TCxNQUFyQixHQUE0QkUsUUFBNUIsQ0FBcUNqQyxXQUFXeEosU0FBWCxDQUFxQm9NLEdBQXJCLEdBQXlCVixLQUF6QixDQUErQmxDLFdBQVd4SixTQUFYLENBQXFCME0sU0FBckIsR0FBK0JmLFdBQS9CLENBQTJDbkMsV0FBV3hKLFNBQVgsQ0FBcUJnUCxTQUFyQixHQUErQm5ELFdBQS9CLENBQTJDckMsV0FBV3hKLFNBQVgsQ0FBcUJrTixHQUFyQixHQUF5QkosS0FBekIsQ0FBK0J0RCxXQUFXeEosU0FBWCxDQUFxQmlQLFNBQXJCLEdBQStCSixXQUEvQixDQUEyQ3JGLFdBQVcyQixJQUFYLEdBQWdCSixJQUFJLENBQUosQ0FBaEIsQ0FBdUJ2QixXQUFXbUQsR0FBWCxHQUFlNUIsSUFBSSxDQUFKLENBQWY7QUFDbHBTOztBQUVBLFNBQVNtRSxPQUFULEdBQWtCO0FBQUMsTUFBSXJPLElBQUU4SSxLQUFOLENBQVksS0FBSzRDLE1BQUwsQ0FBWTFMLENBQVosRUFBZSxPQUFPQSxDQUFQO0FBQVMsVUFBU3NPLFVBQVQsR0FBcUI7QUFBQyxNQUFHLEtBQUsvTSxDQUFMLEdBQU8sQ0FBVixFQUFZO0FBQUMsUUFBRyxLQUFLRixDQUFMLElBQVEsQ0FBWCxFQUFhO0FBQUMsYUFBTyxLQUFLLENBQUwsSUFBUSxLQUFLaUksRUFBcEI7QUFBdUIsS0FBckMsTUFBeUM7QUFBQyxVQUFHLEtBQUtqSSxDQUFMLElBQVEsQ0FBWCxFQUFhO0FBQUMsZUFBTyxDQUFDLENBQVI7QUFBVTtBQUFDO0FBQUMsR0FBakYsTUFBcUY7QUFBQyxRQUFHLEtBQUtBLENBQUwsSUFBUSxDQUFYLEVBQWE7QUFBQyxhQUFPLEtBQUssQ0FBTCxDQUFQO0FBQWUsS0FBN0IsTUFBaUM7QUFBQyxVQUFHLEtBQUtBLENBQUwsSUFBUSxDQUFYLEVBQWE7QUFBQyxlQUFPLENBQVA7QUFBUztBQUFDO0FBQUMsVUFBTyxDQUFDLEtBQUssQ0FBTCxJQUFTLENBQUMsS0FBSSxLQUFHLEtBQUsrSCxFQUFiLElBQWtCLENBQTVCLEtBQWlDLEtBQUtBLEVBQXZDLEdBQTJDLEtBQUssQ0FBTCxDQUFqRDtBQUF5RCxVQUFTbUYsV0FBVCxHQUFzQjtBQUFDLFNBQU8sS0FBS2xOLENBQUwsSUFBUSxDQUFULEdBQVksS0FBS0UsQ0FBakIsR0FBb0IsS0FBSyxDQUFMLEtBQVMsRUFBVixJQUFlLEVBQXhDO0FBQTJDLFVBQVNpTixZQUFULEdBQXVCO0FBQUMsU0FBTyxLQUFLbk4sQ0FBTCxJQUFRLENBQVQsR0FBWSxLQUFLRSxDQUFqQixHQUFvQixLQUFLLENBQUwsS0FBUyxFQUFWLElBQWUsRUFBeEM7QUFBMkMsVUFBU2tOLFlBQVQsQ0FBc0J6TyxDQUF0QixFQUF3QjtBQUFDLFNBQU95RSxLQUFLYyxLQUFMLENBQVdkLEtBQUtpSyxHQUFMLEdBQVMsS0FBS3RGLEVBQWQsR0FBaUIzRSxLQUFLa0ssR0FBTCxDQUFTM08sQ0FBVCxDQUE1QixDQUFQO0FBQWdELFVBQVM0TyxRQUFULEdBQW1CO0FBQUMsTUFBRyxLQUFLck4sQ0FBTCxHQUFPLENBQVYsRUFBWTtBQUFDLFdBQU8sQ0FBQyxDQUFSO0FBQVUsR0FBdkIsTUFBMkI7QUFBQyxRQUFHLEtBQUtGLENBQUwsSUFBUSxDQUFSLElBQVksS0FBS0EsQ0FBTCxJQUFRLENBQVIsSUFBVyxLQUFLLENBQUwsS0FBUyxDQUFuQyxFQUFzQztBQUFDLGFBQU8sQ0FBUDtBQUFTLEtBQWhELE1BQW9EO0FBQUMsYUFBTyxDQUFQO0FBQVM7QUFBQztBQUFDLFVBQVN3TixVQUFULENBQW9CcFAsQ0FBcEIsRUFBc0I7QUFBQyxNQUFHQSxLQUFHLElBQU4sRUFBVztBQUFDQSxRQUFFLEVBQUY7QUFBSyxPQUFHLEtBQUtxUCxNQUFMLE1BQWUsQ0FBZixJQUFrQnJQLElBQUUsQ0FBcEIsSUFBdUJBLElBQUUsRUFBNUIsRUFBK0I7QUFBQyxXQUFNLEdBQU47QUFBVSxPQUFJVCxJQUFFLEtBQUsrUCxTQUFMLENBQWV0UCxDQUFmLENBQU4sQ0FBd0IsSUFBSUQsSUFBRWlGLEtBQUtXLEdBQUwsQ0FBUzNGLENBQVQsRUFBV1QsQ0FBWCxDQUFOLENBQW9CLElBQUlZLElBQUVzSyxJQUFJMUssQ0FBSixDQUFOO0FBQUEsTUFBYUcsSUFBRW1KLEtBQWY7QUFBQSxNQUFxQi9KLElBQUUrSixLQUF2QjtBQUFBLE1BQTZCaEssSUFBRSxFQUEvQixDQUFrQyxLQUFLb04sUUFBTCxDQUFjdE0sQ0FBZCxFQUFnQkQsQ0FBaEIsRUFBa0JaLENBQWxCLEVBQXFCLE9BQU1ZLEVBQUVtUCxNQUFGLEtBQVcsQ0FBakIsRUFBbUI7QUFBQ2hRLFFBQUUsQ0FBQ1UsSUFBRVQsRUFBRWlRLFFBQUYsRUFBSCxFQUFpQmxPLFFBQWpCLENBQTBCckIsQ0FBMUIsRUFBNkI0QyxNQUE3QixDQUFvQyxDQUFwQyxJQUF1Q3ZELENBQXpDLENBQTJDYSxFQUFFdU0sUUFBRixDQUFXdE0sQ0FBWCxFQUFhRCxDQUFiLEVBQWVaLENBQWY7QUFBa0IsVUFBT0EsRUFBRWlRLFFBQUYsR0FBYWxPLFFBQWIsQ0FBc0JyQixDQUF0QixJQUF5QlgsQ0FBaEM7QUFBa0MsVUFBU21RLFlBQVQsQ0FBc0JsTixDQUF0QixFQUF3QmhELENBQXhCLEVBQTBCO0FBQUMsT0FBS29MLE9BQUwsQ0FBYSxDQUFiLEVBQWdCLElBQUdwTCxLQUFHLElBQU4sRUFBVztBQUFDQSxRQUFFLEVBQUY7QUFBSyxPQUFJQyxJQUFFLEtBQUsrUCxTQUFMLENBQWVoUSxDQUFmLENBQU4sQ0FBd0IsSUFBSUQsSUFBRTJGLEtBQUtXLEdBQUwsQ0FBU3JHLENBQVQsRUFBV0MsQ0FBWCxDQUFOO0FBQUEsTUFBb0JRLElBQUUsS0FBdEI7QUFBQSxNQUE0QlEsSUFBRSxDQUE5QjtBQUFBLE1BQWdDRixJQUFFLENBQWxDLENBQW9DLEtBQUksSUFBSUwsSUFBRSxDQUFWLEVBQVlBLElBQUVzQyxFQUFFbEMsTUFBaEIsRUFBdUIsRUFBRUosQ0FBekIsRUFBMkI7QUFBQyxRQUFJTSxJQUFFZ0ssTUFBTWhJLENBQU4sRUFBUXRDLENBQVIsQ0FBTixDQUFpQixJQUFHTSxJQUFFLENBQUwsRUFBTztBQUFDLFVBQUdnQyxFQUFFa0QsTUFBRixDQUFTeEYsQ0FBVCxLQUFhLEdBQWIsSUFBa0IsS0FBS3FQLE1BQUwsTUFBZSxDQUFwQyxFQUFzQztBQUFDdFAsWUFBRSxJQUFGO0FBQU87QUFBUyxTQUFFVCxJQUFFZSxDQUFGLEdBQUlDLENBQU4sQ0FBUSxJQUFHLEVBQUVDLENBQUYsSUFBS2hCLENBQVIsRUFBVTtBQUFDLFdBQUtrUSxTQUFMLENBQWVwUSxDQUFmLEVBQWtCLEtBQUtxUSxVQUFMLENBQWdCclAsQ0FBaEIsRUFBa0IsQ0FBbEIsRUFBcUJFLElBQUUsQ0FBRixDQUFJRixJQUFFLENBQUY7QUFBSTtBQUFDLE9BQUdFLElBQUUsQ0FBTCxFQUFPO0FBQUMsU0FBS2tQLFNBQUwsQ0FBZXpLLEtBQUtXLEdBQUwsQ0FBU3JHLENBQVQsRUFBV2lCLENBQVgsQ0FBZixFQUE4QixLQUFLbVAsVUFBTCxDQUFnQnJQLENBQWhCLEVBQWtCLENBQWxCO0FBQXFCLE9BQUdOLENBQUgsRUFBSztBQUFDbUosZUFBVzJCLElBQVgsQ0FBZ0JDLEtBQWhCLENBQXNCLElBQXRCLEVBQTJCLElBQTNCO0FBQWlDO0FBQUMsVUFBUzZFLGFBQVQsQ0FBdUJwUSxDQUF2QixFQUF5QlEsQ0FBekIsRUFBMkJULENBQTNCLEVBQTZCO0FBQUMsTUFBRyxZQUFVLE9BQU9TLENBQXBCLEVBQXNCO0FBQUMsUUFBR1IsSUFBRSxDQUFMLEVBQU87QUFBQyxXQUFLbUwsT0FBTCxDQUFhLENBQWI7QUFBZ0IsS0FBeEIsTUFBNEI7QUFBQyxXQUFLdkIsVUFBTCxDQUFnQjVKLENBQWhCLEVBQWtCRCxDQUFsQixFQUFxQixJQUFHLENBQUMsS0FBS3NRLE9BQUwsQ0FBYXJRLElBQUUsQ0FBZixDQUFKLEVBQXNCO0FBQUMsYUFBS3NRLFNBQUwsQ0FBZTNHLFdBQVdtRCxHQUFYLENBQWV5RCxTQUFmLENBQXlCdlEsSUFBRSxDQUEzQixDQUFmLEVBQTZDd1EsS0FBN0MsRUFBbUQsSUFBbkQ7QUFBeUQsV0FBRyxLQUFLdkIsTUFBTCxFQUFILEVBQWlCO0FBQUMsYUFBS2tCLFVBQUwsQ0FBZ0IsQ0FBaEIsRUFBa0IsQ0FBbEI7QUFBcUIsY0FBTSxDQUFDLEtBQUtNLGVBQUwsQ0FBcUJqUSxDQUFyQixDQUFQLEVBQStCO0FBQUMsYUFBSzJQLFVBQUwsQ0FBZ0IsQ0FBaEIsRUFBa0IsQ0FBbEIsRUFBcUIsSUFBRyxLQUFLaEIsU0FBTCxLQUFpQm5QLENBQXBCLEVBQXNCO0FBQUMsZUFBS3VMLEtBQUwsQ0FBVzVCLFdBQVdtRCxHQUFYLENBQWV5RCxTQUFmLENBQXlCdlEsSUFBRSxDQUEzQixDQUFYLEVBQXlDLElBQXpDO0FBQStDO0FBQUM7QUFBQztBQUFDLEdBQTlULE1BQWtVO0FBQUMsUUFBSUUsSUFBRSxJQUFJcUosS0FBSixFQUFOO0FBQUEsUUFBa0J6SixJQUFFRSxJQUFFLENBQXRCLENBQXdCRSxFQUFFVyxNQUFGLEdBQVMsQ0FBQ2IsS0FBRyxDQUFKLElBQU8sQ0FBaEIsQ0FBa0JRLEVBQUVrUSxTQUFGLENBQVl4USxDQUFaLEVBQWUsSUFBR0osSUFBRSxDQUFMLEVBQU87QUFBQ0ksUUFBRSxDQUFGLEtBQU8sQ0FBQyxLQUFHSixDQUFKLElBQU8sQ0FBZDtBQUFpQixLQUF6QixNQUE2QjtBQUFDSSxRQUFFLENBQUYsSUFBSyxDQUFMO0FBQU8sVUFBSzJKLFVBQUwsQ0FBZ0IzSixDQUFoQixFQUFrQixHQUFsQjtBQUF1QjtBQUFDLFVBQVN5USxhQUFULEdBQXdCO0FBQUMsTUFBSXBRLElBQUUsS0FBSzhCLENBQVg7QUFBQSxNQUFhNUIsSUFBRSxJQUFJOEksS0FBSixFQUFmLENBQTJCOUksRUFBRSxDQUFGLElBQUssS0FBSzhCLENBQVYsQ0FBWSxJQUFJL0IsSUFBRSxLQUFLNEosRUFBTCxHQUFTN0osSUFBRSxLQUFLNkosRUFBUixHQUFZLENBQTFCO0FBQUEsTUFBNEJwSyxDQUE1QjtBQUFBLE1BQThCZ0IsSUFBRSxDQUFoQyxDQUFrQyxJQUFHVCxNQUFJLENBQVAsRUFBUztBQUFDLFFBQUdDLElBQUUsS0FBSzRKLEVBQVAsSUFBVyxDQUFDcEssSUFBRSxLQUFLTyxDQUFMLEtBQVNDLENBQVosS0FBZ0IsQ0FBQyxLQUFLK0IsQ0FBTCxHQUFPLEtBQUs4SCxFQUFiLEtBQWtCN0osQ0FBaEQsRUFBa0Q7QUFBQ0MsUUFBRU8sR0FBRixJQUFPaEIsSUFBRyxLQUFLdUMsQ0FBTCxJQUFTLEtBQUs2SCxFQUFMLEdBQVE1SixDQUEzQjtBQUErQixZQUFNRCxLQUFHLENBQVQsRUFBVztBQUFDLFVBQUdDLElBQUUsQ0FBTCxFQUFPO0FBQUNSLFlBQUUsQ0FBQyxLQUFLTyxDQUFMLElBQVMsQ0FBQyxLQUFHQyxDQUFKLElBQU8sQ0FBakIsS0FBdUIsSUFBRUEsQ0FBM0IsQ0FBOEJSLEtBQUcsS0FBSyxFQUFFTyxDQUFQLE1BQVlDLEtBQUcsS0FBSzRKLEVBQUwsR0FBUSxDQUF2QixDQUFIO0FBQTZCLE9BQW5FLE1BQXVFO0FBQUNwSyxZQUFHLEtBQUtPLENBQUwsTUFBVUMsS0FBRyxDQUFiLENBQUQsR0FBa0IsR0FBcEIsQ0FBd0IsSUFBR0EsS0FBRyxDQUFOLEVBQVE7QUFBQ0EsZUFBRyxLQUFLNEosRUFBUixDQUFXLEVBQUU3SixDQUFGO0FBQUk7QUFBQyxXQUFHLENBQUNQLElBQUUsR0FBSCxLQUFTLENBQVosRUFBYztBQUFDQSxhQUFHLENBQUMsR0FBSjtBQUFRLFdBQUdnQixLQUFHLENBQUgsSUFBTSxDQUFDLEtBQUt1QixDQUFMLEdBQU8sR0FBUixNQUFldkMsSUFBRSxHQUFqQixDQUFULEVBQStCO0FBQUMsVUFBRWdCLENBQUY7QUFBSSxXQUFHQSxJQUFFLENBQUYsSUFBS2hCLEtBQUcsS0FBS3VDLENBQWhCLEVBQWtCO0FBQUM5QixVQUFFTyxHQUFGLElBQU9oQixDQUFQO0FBQVM7QUFBQztBQUFDLFVBQU9TLENBQVA7QUFBUyxVQUFTbVEsUUFBVCxDQUFrQnJRLENBQWxCLEVBQW9CO0FBQUMsU0FBTyxLQUFLc00sU0FBTCxDQUFldE0sQ0FBZixLQUFtQixDQUExQjtBQUE2QixVQUFTc1EsS0FBVCxDQUFldFEsQ0FBZixFQUFpQjtBQUFDLFNBQU8sS0FBS3NNLFNBQUwsQ0FBZXRNLENBQWYsSUFBa0IsQ0FBbkIsR0FBc0IsSUFBdEIsR0FBMkJBLENBQWpDO0FBQW1DLFVBQVN1USxLQUFULENBQWV2USxDQUFmLEVBQWlCO0FBQUMsU0FBTyxLQUFLc00sU0FBTCxDQUFldE0sQ0FBZixJQUFrQixDQUFuQixHQUFzQixJQUF0QixHQUEyQkEsQ0FBakM7QUFBbUMsVUFBU3dRLFlBQVQsQ0FBc0J0USxDQUF0QixFQUF3QlYsQ0FBeEIsRUFBMEJTLENBQTFCLEVBQTRCO0FBQUMsTUFBSU4sQ0FBSjtBQUFBLE1BQU1KLENBQU47QUFBQSxNQUFRUyxJQUFFa0YsS0FBS2IsR0FBTCxDQUFTbkUsRUFBRTRCLENBQVgsRUFBYSxLQUFLQSxDQUFsQixDQUFWLENBQStCLEtBQUluQyxJQUFFLENBQU4sRUFBUUEsSUFBRUssQ0FBVixFQUFZLEVBQUVMLENBQWQsRUFBZ0I7QUFBQ00sTUFBRU4sQ0FBRixJQUFLSCxFQUFFLEtBQUtHLENBQUwsQ0FBRixFQUFVTyxFQUFFUCxDQUFGLENBQVYsQ0FBTDtBQUFxQixPQUFHTyxFQUFFNEIsQ0FBRixHQUFJLEtBQUtBLENBQVosRUFBYztBQUFDdkMsUUFBRVcsRUFBRThCLENBQUYsR0FBSSxLQUFLOEgsRUFBWCxDQUFjLEtBQUluSyxJQUFFSyxDQUFOLEVBQVFMLElBQUUsS0FBS21DLENBQWYsRUFBaUIsRUFBRW5DLENBQW5CLEVBQXFCO0FBQUNNLFFBQUVOLENBQUYsSUFBS0gsRUFBRSxLQUFLRyxDQUFMLENBQUYsRUFBVUosQ0FBVixDQUFMO0FBQWtCLE9BQUV1QyxDQUFGLEdBQUksS0FBS0EsQ0FBVDtBQUFXLEdBQWhGLE1BQW9GO0FBQUN2QyxRQUFFLEtBQUt5QyxDQUFMLEdBQU8sS0FBSzhILEVBQWQsQ0FBaUIsS0FBSW5LLElBQUVLLENBQU4sRUFBUUwsSUFBRU8sRUFBRTRCLENBQVosRUFBYyxFQUFFbkMsQ0FBaEIsRUFBa0I7QUFBQ00sUUFBRU4sQ0FBRixJQUFLSCxFQUFFRCxDQUFGLEVBQUlXLEVBQUVQLENBQUYsQ0FBSixDQUFMO0FBQWUsT0FBRW1DLENBQUYsR0FBSTVCLEVBQUU0QixDQUFOO0FBQVEsS0FBRUUsQ0FBRixHQUFJeEMsRUFBRSxLQUFLd0MsQ0FBUCxFQUFTOUIsRUFBRThCLENBQVgsQ0FBSixDQUFrQi9CLEVBQUVnQyxLQUFGO0FBQVUsVUFBU3dPLE1BQVQsQ0FBZ0JoUSxDQUFoQixFQUFrQlQsQ0FBbEIsRUFBb0I7QUFBQyxTQUFPUyxJQUFFVCxDQUFUO0FBQVcsVUFBUzBRLEtBQVQsQ0FBZTFRLENBQWYsRUFBaUI7QUFBQyxNQUFJRSxJQUFFcUosS0FBTixDQUFZLEtBQUt3RyxTQUFMLENBQWUvUCxDQUFmLEVBQWlCeVEsTUFBakIsRUFBd0J2USxDQUF4QixFQUEyQixPQUFPQSxDQUFQO0FBQVMsVUFBUytQLEtBQVQsQ0FBZXhQLENBQWYsRUFBaUJULENBQWpCLEVBQW1CO0FBQUMsU0FBT1MsSUFBRVQsQ0FBVDtBQUFXLFVBQVMyUSxJQUFULENBQWMzUSxDQUFkLEVBQWdCO0FBQUMsTUFBSUUsSUFBRXFKLEtBQU4sQ0FBWSxLQUFLd0csU0FBTCxDQUFlL1AsQ0FBZixFQUFpQmlRLEtBQWpCLEVBQXVCL1AsQ0FBdkIsRUFBMEIsT0FBT0EsQ0FBUDtBQUFTLFVBQVMwUSxNQUFULENBQWdCblEsQ0FBaEIsRUFBa0JULENBQWxCLEVBQW9CO0FBQUMsU0FBT1MsSUFBRVQsQ0FBVDtBQUFXLFVBQVM2USxLQUFULENBQWU3USxDQUFmLEVBQWlCO0FBQUMsTUFBSUUsSUFBRXFKLEtBQU4sQ0FBWSxLQUFLd0csU0FBTCxDQUFlL1AsQ0FBZixFQUFpQjRRLE1BQWpCLEVBQXdCMVEsQ0FBeEIsRUFBMkIsT0FBT0EsQ0FBUDtBQUFTLFVBQVM0USxTQUFULENBQW1CclEsQ0FBbkIsRUFBcUJULENBQXJCLEVBQXVCO0FBQUMsU0FBT1MsSUFBRSxDQUFDVCxDQUFWO0FBQVksVUFBUytRLFFBQVQsQ0FBa0IvUSxDQUFsQixFQUFvQjtBQUFDLE1BQUlFLElBQUVxSixLQUFOLENBQVksS0FBS3dHLFNBQUwsQ0FBZS9QLENBQWYsRUFBaUI4USxTQUFqQixFQUEyQjVRLENBQTNCLEVBQThCLE9BQU9BLENBQVA7QUFBUyxVQUFTOFEsS0FBVCxHQUFnQjtBQUFDLE1BQUloUixJQUFFdUosS0FBTixDQUFZLEtBQUksSUFBSTlJLElBQUUsQ0FBVixFQUFZQSxJQUFFLEtBQUtxQixDQUFuQixFQUFxQixFQUFFckIsQ0FBdkIsRUFBeUI7QUFBQ1QsTUFBRVMsQ0FBRixJQUFLLEtBQUtxSixFQUFMLEdBQVEsQ0FBQyxLQUFLckosQ0FBTCxDQUFkO0FBQXNCLEtBQUVxQixDQUFGLEdBQUksS0FBS0EsQ0FBVCxDQUFXOUIsRUFBRWdDLENBQUYsR0FBSSxDQUFDLEtBQUtBLENBQVYsQ0FBWSxPQUFPaEMsQ0FBUDtBQUFTLFVBQVNpUixXQUFULENBQXFCalIsQ0FBckIsRUFBdUI7QUFBQyxNQUFJUyxJQUFFOEksS0FBTixDQUFZLElBQUd2SixJQUFFLENBQUwsRUFBTztBQUFDLFNBQUt5TSxRQUFMLENBQWMsQ0FBQ3pNLENBQWYsRUFBaUJTLENBQWpCO0FBQW9CLEdBQTVCLE1BQWdDO0FBQUMsU0FBSzJMLFFBQUwsQ0FBY3BNLENBQWQsRUFBZ0JTLENBQWhCO0FBQW1CLFVBQU9BLENBQVA7QUFBUyxVQUFTeVEsWUFBVCxDQUFzQmxSLENBQXRCLEVBQXdCO0FBQUMsTUFBSVMsSUFBRThJLEtBQU4sQ0FBWSxJQUFHdkosSUFBRSxDQUFMLEVBQU87QUFBQyxTQUFLb00sUUFBTCxDQUFjLENBQUNwTSxDQUFmLEVBQWlCUyxDQUFqQjtBQUFvQixHQUE1QixNQUFnQztBQUFDLFNBQUtnTSxRQUFMLENBQWN6TSxDQUFkLEVBQWdCUyxDQUFoQjtBQUFtQixVQUFPQSxDQUFQO0FBQVMsVUFBUzBRLElBQVQsQ0FBYzFRLENBQWQsRUFBZ0I7QUFBQyxNQUFHQSxLQUFHLENBQU4sRUFBUTtBQUFDLFdBQU8sQ0FBQyxDQUFSO0FBQVUsT0FBSVQsSUFBRSxDQUFOLENBQVEsSUFBRyxDQUFDUyxJQUFFLEtBQUgsS0FBVyxDQUFkLEVBQWdCO0FBQUNBLFVBQUksRUFBSixDQUFPVCxLQUFHLEVBQUg7QUFBTSxPQUFHLENBQUNTLElBQUUsR0FBSCxLQUFTLENBQVosRUFBYztBQUFDQSxVQUFJLENBQUosQ0FBTVQsS0FBRyxDQUFIO0FBQUssT0FBRyxDQUFDUyxJQUFFLEVBQUgsS0FBUSxDQUFYLEVBQWE7QUFBQ0EsVUFBSSxDQUFKLENBQU1ULEtBQUcsQ0FBSDtBQUFLLE9BQUcsQ0FBQ1MsSUFBRSxDQUFILEtBQU8sQ0FBVixFQUFZO0FBQUNBLFVBQUksQ0FBSixDQUFNVCxLQUFHLENBQUg7QUFBSyxPQUFHLENBQUNTLElBQUUsQ0FBSCxLQUFPLENBQVYsRUFBWTtBQUFDLE1BQUVULENBQUY7QUFBSSxVQUFPQSxDQUFQO0FBQVMsVUFBU29SLGlCQUFULEdBQTRCO0FBQUMsT0FBSSxJQUFJM1EsSUFBRSxDQUFWLEVBQVlBLElBQUUsS0FBS3FCLENBQW5CLEVBQXFCLEVBQUVyQixDQUF2QixFQUF5QjtBQUFDLFFBQUcsS0FBS0EsQ0FBTCxLQUFTLENBQVosRUFBYztBQUFDLGFBQU9BLElBQUUsS0FBS29KLEVBQVAsR0FBVXNILEtBQUssS0FBSzFRLENBQUwsQ0FBTCxDQUFqQjtBQUErQjtBQUFDLE9BQUcsS0FBS3VCLENBQUwsR0FBTyxDQUFWLEVBQVk7QUFBQyxXQUFPLEtBQUtGLENBQUwsR0FBTyxLQUFLK0gsRUFBbkI7QUFBc0IsVUFBTyxDQUFDLENBQVI7QUFBVSxVQUFTd0gsSUFBVCxDQUFjNVEsQ0FBZCxFQUFnQjtBQUFDLE1BQUlULElBQUUsQ0FBTixDQUFRLE9BQU1TLEtBQUcsQ0FBVCxFQUFXO0FBQUNBLFNBQUdBLElBQUUsQ0FBTCxDQUFPLEVBQUVULENBQUY7QUFBSSxVQUFPQSxDQUFQO0FBQVMsVUFBU3NSLFVBQVQsR0FBcUI7QUFBQyxNQUFJcFIsSUFBRSxDQUFOO0FBQUEsTUFBUU8sSUFBRSxLQUFLdUIsQ0FBTCxHQUFPLEtBQUs4SCxFQUF0QixDQUF5QixLQUFJLElBQUk5SixJQUFFLENBQVYsRUFBWUEsSUFBRSxLQUFLOEIsQ0FBbkIsRUFBcUIsRUFBRTlCLENBQXZCLEVBQXlCO0FBQUNFLFNBQUdtUixLQUFLLEtBQUtyUixDQUFMLElBQVFTLENBQWIsQ0FBSDtBQUFtQixVQUFPUCxDQUFQO0FBQVMsVUFBU3FSLFNBQVQsQ0FBbUJ2UixDQUFuQixFQUFxQjtBQUFDLE1BQUlTLElBQUV5RSxLQUFLYyxLQUFMLENBQVdoRyxJQUFFLEtBQUs2SixFQUFsQixDQUFOLENBQTRCLElBQUdwSixLQUFHLEtBQUtxQixDQUFYLEVBQWE7QUFBQyxXQUFPLEtBQUtFLENBQUwsSUFBUSxDQUFmO0FBQWtCLFVBQU8sQ0FBQyxLQUFLdkIsQ0FBTCxJQUFTLEtBQUlULElBQUUsS0FBSzZKLEVBQXJCLEtBQTRCLENBQW5DO0FBQXNDLFVBQVMySCxZQUFULENBQXNCdFIsQ0FBdEIsRUFBd0JGLENBQXhCLEVBQTBCO0FBQUMsTUFBSVMsSUFBRTJJLFdBQVdtRCxHQUFYLENBQWV5RCxTQUFmLENBQXlCOVAsQ0FBekIsQ0FBTixDQUFrQyxLQUFLNlAsU0FBTCxDQUFldFAsQ0FBZixFQUFpQlQsQ0FBakIsRUFBbUJTLENBQW5CLEVBQXNCLE9BQU9BLENBQVA7QUFBUyxVQUFTZ1IsUUFBVCxDQUFrQmhSLENBQWxCLEVBQW9CO0FBQUMsU0FBTyxLQUFLaVIsU0FBTCxDQUFlalIsQ0FBZixFQUFpQndQLEtBQWpCLENBQVA7QUFBK0IsVUFBUzBCLFVBQVQsQ0FBb0JsUixDQUFwQixFQUFzQjtBQUFDLFNBQU8sS0FBS2lSLFNBQUwsQ0FBZWpSLENBQWYsRUFBaUJxUSxTQUFqQixDQUFQO0FBQW1DLFVBQVNjLFNBQVQsQ0FBbUJuUixDQUFuQixFQUFxQjtBQUFDLFNBQU8sS0FBS2lSLFNBQUwsQ0FBZWpSLENBQWYsRUFBaUJtUSxNQUFqQixDQUFQO0FBQWdDLFVBQVNpQixRQUFULENBQWtCbFMsQ0FBbEIsRUFBb0JGLENBQXBCLEVBQXNCO0FBQUMsTUFBSVEsSUFBRSxDQUFOO0FBQUEsTUFBUVYsSUFBRSxDQUFWO0FBQUEsTUFBWVMsSUFBRWtGLEtBQUtiLEdBQUwsQ0FBUzFFLEVBQUVtQyxDQUFYLEVBQWEsS0FBS0EsQ0FBbEIsQ0FBZCxDQUFtQyxPQUFNN0IsSUFBRUQsQ0FBUixFQUFVO0FBQUNULFNBQUcsS0FBS1UsQ0FBTCxJQUFRTixFQUFFTSxDQUFGLENBQVgsQ0FBZ0JSLEVBQUVRLEdBQUYsSUFBT1YsSUFBRSxLQUFLdUssRUFBZCxDQUFpQnZLLE1BQUksS0FBS3NLLEVBQVQ7QUFBWSxPQUFHbEssRUFBRW1DLENBQUYsR0FBSSxLQUFLQSxDQUFaLEVBQWM7QUFBQ3ZDLFNBQUdJLEVBQUVxQyxDQUFMLENBQU8sT0FBTS9CLElBQUUsS0FBSzZCLENBQWIsRUFBZTtBQUFDdkMsV0FBRyxLQUFLVSxDQUFMLENBQUgsQ0FBV1IsRUFBRVEsR0FBRixJQUFPVixJQUFFLEtBQUt1SyxFQUFkLENBQWlCdkssTUFBSSxLQUFLc0ssRUFBVDtBQUFZLFVBQUcsS0FBSzdILENBQVI7QUFBVSxHQUF4RixNQUE0RjtBQUFDekMsU0FBRyxLQUFLeUMsQ0FBUixDQUFVLE9BQU0vQixJQUFFTixFQUFFbUMsQ0FBVixFQUFZO0FBQUN2QyxXQUFHSSxFQUFFTSxDQUFGLENBQUgsQ0FBUVIsRUFBRVEsR0FBRixJQUFPVixJQUFFLEtBQUt1SyxFQUFkLENBQWlCdkssTUFBSSxLQUFLc0ssRUFBVDtBQUFZLFVBQUdsSyxFQUFFcUMsQ0FBTDtBQUFPLEtBQUVBLENBQUYsR0FBS3pDLElBQUUsQ0FBSCxHQUFNLENBQUMsQ0FBUCxHQUFTLENBQWIsQ0FBZSxJQUFHQSxJQUFFLENBQUwsRUFBTztBQUFDRSxNQUFFUSxHQUFGLElBQU9WLENBQVA7QUFBUyxHQUFqQixNQUFxQjtBQUFDLFFBQUdBLElBQUUsQ0FBQyxDQUFOLEVBQVE7QUFBQ0UsUUFBRVEsR0FBRixJQUFPLEtBQUs4SixFQUFMLEdBQVF4SyxDQUFmO0FBQWlCO0FBQUMsS0FBRXVDLENBQUYsR0FBSTdCLENBQUosQ0FBTVIsRUFBRXdDLEtBQUY7QUFBVSxVQUFTNlAsS0FBVCxDQUFlOVIsQ0FBZixFQUFpQjtBQUFDLE1BQUlFLElBQUVxSixLQUFOLENBQVksS0FBS3dJLEtBQUwsQ0FBVy9SLENBQVgsRUFBYUUsQ0FBYixFQUFnQixPQUFPQSxDQUFQO0FBQVMsVUFBUzhSLFVBQVQsQ0FBb0JoUyxDQUFwQixFQUFzQjtBQUFDLE1BQUlFLElBQUVxSixLQUFOLENBQVksS0FBS3lCLEtBQUwsQ0FBV2hMLENBQVgsRUFBYUUsQ0FBYixFQUFnQixPQUFPQSxDQUFQO0FBQVMsVUFBUytSLFVBQVQsQ0FBb0JqUyxDQUFwQixFQUFzQjtBQUFDLE1BQUlFLElBQUVxSixLQUFOLENBQVksS0FBSzJELFVBQUwsQ0FBZ0JsTixDQUFoQixFQUFrQkUsQ0FBbEIsRUFBcUIsT0FBT0EsQ0FBUDtBQUFTLFVBQVNnUyxRQUFULEdBQW1CO0FBQUMsTUFBSXpSLElBQUU4SSxLQUFOLENBQVksS0FBSzhELFFBQUwsQ0FBYzVNLENBQWQsRUFBaUIsT0FBT0EsQ0FBUDtBQUFTLFVBQVMwUixRQUFULENBQWtCblMsQ0FBbEIsRUFBb0I7QUFBQyxNQUFJRSxJQUFFcUosS0FBTixDQUFZLEtBQUtvRCxRQUFMLENBQWMzTSxDQUFkLEVBQWdCRSxDQUFoQixFQUFrQixJQUFsQixFQUF3QixPQUFPQSxDQUFQO0FBQVMsVUFBU2tTLFdBQVQsQ0FBcUJwUyxDQUFyQixFQUF1QjtBQUFDLE1BQUlFLElBQUVxSixLQUFOLENBQVksS0FBS29ELFFBQUwsQ0FBYzNNLENBQWQsRUFBZ0IsSUFBaEIsRUFBcUJFLENBQXJCLEVBQXdCLE9BQU9BLENBQVA7QUFBUyxVQUFTbVMsb0JBQVQsQ0FBOEJyUyxDQUE5QixFQUFnQztBQUFDLE1BQUlMLElBQUU0SixLQUFOO0FBQUEsTUFBWXJKLElBQUVxSixLQUFkLENBQW9CLEtBQUtvRCxRQUFMLENBQWMzTSxDQUFkLEVBQWdCTCxDQUFoQixFQUFrQk8sQ0FBbEIsRUFBcUIsT0FBTyxJQUFJOEksS0FBSixDQUFVckosQ0FBVixFQUFZTyxDQUFaLENBQVA7QUFBc0IsVUFBU29TLFlBQVQsQ0FBc0I3UixDQUF0QixFQUF3QjtBQUFDLE9BQUssS0FBS3FCLENBQVYsSUFBYSxLQUFLOEgsRUFBTCxDQUFRLENBQVIsRUFBVW5KLElBQUUsQ0FBWixFQUFjLElBQWQsRUFBbUIsQ0FBbkIsRUFBcUIsQ0FBckIsRUFBdUIsS0FBS3FCLENBQTVCLENBQWIsQ0FBNEMsRUFBRSxLQUFLQSxDQUFQLENBQVMsS0FBS0csS0FBTDtBQUFhLFVBQVNzUSxhQUFULENBQXVCdlMsQ0FBdkIsRUFBeUJTLENBQXpCLEVBQTJCO0FBQUMsTUFBR1QsS0FBRyxDQUFOLEVBQVE7QUFBQztBQUFPLFVBQU0sS0FBSzhCLENBQUwsSUFBUXJCLENBQWQsRUFBZ0I7QUFBQyxTQUFLLEtBQUtxQixDQUFMLEVBQUwsSUFBZSxDQUFmO0FBQWlCLFFBQUtyQixDQUFMLEtBQVNULENBQVQsQ0FBVyxPQUFNLEtBQUtTLENBQUwsS0FBUyxLQUFLc0osRUFBcEIsRUFBdUI7QUFBQyxTQUFLdEosQ0FBTCxLQUFTLEtBQUtzSixFQUFkLENBQWlCLElBQUcsRUFBRXRKLENBQUYsSUFBSyxLQUFLcUIsQ0FBYixFQUFlO0FBQUMsV0FBSyxLQUFLQSxDQUFMLEVBQUwsSUFBZSxDQUFmO0FBQWlCLE9BQUUsS0FBS3JCLENBQUwsQ0FBRjtBQUFVO0FBQUMsVUFBUytSLE9BQVQsR0FBa0IsQ0FBRSxVQUFTQyxJQUFULENBQWNoUyxDQUFkLEVBQWdCO0FBQUMsU0FBT0EsQ0FBUDtBQUFTLFVBQVNpUyxNQUFULENBQWdCalMsQ0FBaEIsRUFBa0JQLENBQWxCLEVBQW9CRixDQUFwQixFQUFzQjtBQUFDUyxJQUFFeU0sVUFBRixDQUFhaE4sQ0FBYixFQUFlRixDQUFmO0FBQWtCLFVBQVMyUyxNQUFULENBQWdCbFMsQ0FBaEIsRUFBa0JULENBQWxCLEVBQW9CO0FBQUNTLElBQUU0TSxRQUFGLENBQVdyTixDQUFYO0FBQWMsU0FBUUosU0FBUixDQUFrQjBOLE9BQWxCLEdBQTBCbUYsSUFBMUIsQ0FBK0JELFFBQVE1UyxTQUFSLENBQWtCMk4sTUFBbEIsR0FBeUJrRixJQUF6QixDQUE4QkQsUUFBUTVTLFNBQVIsQ0FBa0I0TixLQUFsQixHQUF3QmtGLE1BQXhCLENBQStCRixRQUFRNVMsU0FBUixDQUFrQjZOLEtBQWxCLEdBQXdCa0YsTUFBeEIsQ0FBK0IsU0FBU0MsS0FBVCxDQUFlblMsQ0FBZixFQUFpQjtBQUFDLFNBQU8sS0FBS2tPLEdBQUwsQ0FBU2xPLENBQVQsRUFBVyxJQUFJK1IsT0FBSixFQUFYLENBQVA7QUFBaUMsVUFBU0ssa0JBQVQsQ0FBNEI3UyxDQUE1QixFQUE4QlAsQ0FBOUIsRUFBZ0NRLENBQWhDLEVBQWtDO0FBQUMsTUFBSU4sSUFBRXVGLEtBQUtiLEdBQUwsQ0FBUyxLQUFLdkMsQ0FBTCxHQUFPOUIsRUFBRThCLENBQWxCLEVBQW9CckMsQ0FBcEIsQ0FBTixDQUE2QlEsRUFBRStCLENBQUYsR0FBSSxDQUFKLENBQU0vQixFQUFFNkIsQ0FBRixHQUFJbkMsQ0FBSixDQUFNLE9BQU1BLElBQUUsQ0FBUixFQUFVO0FBQUNNLE1BQUUsRUFBRU4sQ0FBSixJQUFPLENBQVA7QUFBUyxPQUFJTyxDQUFKLENBQU0sS0FBSUEsSUFBRUQsRUFBRTZCLENBQUYsR0FBSSxLQUFLQSxDQUFmLEVBQWlCbkMsSUFBRU8sQ0FBbkIsRUFBcUIsRUFBRVAsQ0FBdkIsRUFBeUI7QUFBQ00sTUFBRU4sSUFBRSxLQUFLbUMsQ0FBVCxJQUFZLEtBQUs4SCxFQUFMLENBQVEsQ0FBUixFQUFVNUosRUFBRUwsQ0FBRixDQUFWLEVBQWVNLENBQWYsRUFBaUJOLENBQWpCLEVBQW1CLENBQW5CLEVBQXFCLEtBQUttQyxDQUExQixDQUFaO0FBQXlDLFFBQUk1QixJQUFFZ0YsS0FBS2IsR0FBTCxDQUFTckUsRUFBRThCLENBQVgsRUFBYXJDLENBQWIsQ0FBTixFQUFzQkUsSUFBRU8sQ0FBeEIsRUFBMEIsRUFBRVAsQ0FBNUIsRUFBOEI7QUFBQyxTQUFLaUssRUFBTCxDQUFRLENBQVIsRUFBVTVKLEVBQUVMLENBQUYsQ0FBVixFQUFlTSxDQUFmLEVBQWlCTixDQUFqQixFQUFtQixDQUFuQixFQUFxQkYsSUFBRUUsQ0FBdkI7QUFBMEIsS0FBRXNDLEtBQUY7QUFBVSxVQUFTNlEsa0JBQVQsQ0FBNEI5UyxDQUE1QixFQUE4QkMsQ0FBOUIsRUFBZ0NOLENBQWhDLEVBQWtDO0FBQUMsSUFBRU0sQ0FBRixDQUFJLElBQUlDLElBQUVQLEVBQUVtQyxDQUFGLEdBQUksS0FBS0EsQ0FBTCxHQUFPOUIsRUFBRThCLENBQVQsR0FBVzdCLENBQXJCLENBQXVCTixFQUFFcUMsQ0FBRixHQUFJLENBQUosQ0FBTSxPQUFNLEVBQUU5QixDQUFGLElBQUssQ0FBWCxFQUFhO0FBQUNQLE1BQUVPLENBQUYsSUFBSyxDQUFMO0FBQU8sUUFBSUEsSUFBRWdGLEtBQUtmLEdBQUwsQ0FBU2xFLElBQUUsS0FBSzZCLENBQWhCLEVBQWtCLENBQWxCLENBQU4sRUFBMkI1QixJQUFFRixFQUFFOEIsQ0FBL0IsRUFBaUMsRUFBRTVCLENBQW5DLEVBQXFDO0FBQUNQLE1BQUUsS0FBS21DLENBQUwsR0FBTzVCLENBQVAsR0FBU0QsQ0FBWCxJQUFjLEtBQUsySixFQUFMLENBQVEzSixJQUFFQyxDQUFWLEVBQVlGLEVBQUVFLENBQUYsQ0FBWixFQUFpQlAsQ0FBakIsRUFBbUIsQ0FBbkIsRUFBcUIsQ0FBckIsRUFBdUIsS0FBS21DLENBQUwsR0FBTzVCLENBQVAsR0FBU0QsQ0FBaEMsQ0FBZDtBQUFpRCxLQUFFZ0MsS0FBRixHQUFVdEMsRUFBRTZNLFNBQUYsQ0FBWSxDQUFaLEVBQWM3TSxDQUFkO0FBQWlCLFVBQVNvVCxPQUFULENBQWlCdFMsQ0FBakIsRUFBbUI7QUFBQyxPQUFLdVMsRUFBTCxHQUFRekosS0FBUixDQUFjLEtBQUswSixFQUFMLEdBQVExSixLQUFSLENBQWNILFdBQVdtRCxHQUFYLENBQWVGLFNBQWYsQ0FBeUIsSUFBRTVMLEVBQUVxQixDQUE3QixFQUErQixLQUFLa1IsRUFBcEMsRUFBd0MsS0FBS0UsRUFBTCxHQUFRLEtBQUtGLEVBQUwsQ0FBUUcsTUFBUixDQUFlMVMsQ0FBZixDQUFSLENBQTBCLEtBQUsrQixDQUFMLEdBQU8vQixDQUFQO0FBQVMsVUFBUzJTLGNBQVQsQ0FBd0IzUyxDQUF4QixFQUEwQjtBQUFDLE1BQUdBLEVBQUV1QixDQUFGLEdBQUksQ0FBSixJQUFPdkIsRUFBRXFCLENBQUYsR0FBSSxJQUFFLEtBQUtVLENBQUwsQ0FBT1YsQ0FBdkIsRUFBeUI7QUFBQyxXQUFPckIsRUFBRXFNLEdBQUYsQ0FBTSxLQUFLdEssQ0FBWCxDQUFQO0FBQXFCLEdBQS9DLE1BQW1EO0FBQUMsUUFBRy9CLEVBQUU2TCxTQUFGLENBQVksS0FBSzlKLENBQWpCLElBQW9CLENBQXZCLEVBQXlCO0FBQUMsYUFBTy9CLENBQVA7QUFBUyxLQUFuQyxNQUF1QztBQUFDLFVBQUlULElBQUV1SixLQUFOLENBQVk5SSxFQUFFMEwsTUFBRixDQUFTbk0sQ0FBVCxFQUFZLEtBQUttTixNQUFMLENBQVluTixDQUFaLEVBQWUsT0FBT0EsQ0FBUDtBQUFTO0FBQUM7QUFBQyxVQUFTcVQsYUFBVCxDQUF1QjVTLENBQXZCLEVBQXlCO0FBQUMsU0FBT0EsQ0FBUDtBQUFTLFVBQVM2UyxhQUFULENBQXVCN1MsQ0FBdkIsRUFBeUI7QUFBQ0EsSUFBRStMLFNBQUYsQ0FBWSxLQUFLaEssQ0FBTCxDQUFPVixDQUFQLEdBQVMsQ0FBckIsRUFBdUIsS0FBS2tSLEVBQTVCLEVBQWdDLElBQUd2UyxFQUFFcUIsQ0FBRixHQUFJLEtBQUtVLENBQUwsQ0FBT1YsQ0FBUCxHQUFTLENBQWhCLEVBQWtCO0FBQUNyQixNQUFFcUIsQ0FBRixHQUFJLEtBQUtVLENBQUwsQ0FBT1YsQ0FBUCxHQUFTLENBQWIsQ0FBZXJCLEVBQUV3QixLQUFGO0FBQVUsUUFBS2lSLEVBQUwsQ0FBUUssZUFBUixDQUF3QixLQUFLUCxFQUE3QixFQUFnQyxLQUFLeFEsQ0FBTCxDQUFPVixDQUFQLEdBQVMsQ0FBekMsRUFBMkMsS0FBS21SLEVBQWhELEVBQW9ELEtBQUt6USxDQUFMLENBQU9nUixlQUFQLENBQXVCLEtBQUtQLEVBQTVCLEVBQStCLEtBQUt6USxDQUFMLENBQU9WLENBQVAsR0FBUyxDQUF4QyxFQUEwQyxLQUFLa1IsRUFBL0MsRUFBbUQsT0FBTXZTLEVBQUU2TCxTQUFGLENBQVksS0FBSzBHLEVBQWpCLElBQXFCLENBQTNCLEVBQTZCO0FBQUN2UyxNQUFFbVAsVUFBRixDQUFhLENBQWIsRUFBZSxLQUFLcE4sQ0FBTCxDQUFPVixDQUFQLEdBQVMsQ0FBeEI7QUFBMkIsS0FBRWtKLEtBQUYsQ0FBUSxLQUFLZ0ksRUFBYixFQUFnQnZTLENBQWhCLEVBQW1CLE9BQU1BLEVBQUU2TCxTQUFGLENBQVksS0FBSzlKLENBQWpCLEtBQXFCLENBQTNCLEVBQTZCO0FBQUMvQixNQUFFdUssS0FBRixDQUFRLEtBQUt4SSxDQUFiLEVBQWUvQixDQUFmO0FBQWtCO0FBQUMsVUFBU2dULFlBQVQsQ0FBc0JoVCxDQUF0QixFQUF3QlQsQ0FBeEIsRUFBMEI7QUFBQ1MsSUFBRTRNLFFBQUYsQ0FBV3JOLENBQVgsRUFBYyxLQUFLbU4sTUFBTCxDQUFZbk4sQ0FBWjtBQUFlLFVBQVMwVCxZQUFULENBQXNCalQsQ0FBdEIsRUFBd0JQLENBQXhCLEVBQTBCRixDQUExQixFQUE0QjtBQUFDUyxJQUFFeU0sVUFBRixDQUFhaE4sQ0FBYixFQUFlRixDQUFmLEVBQWtCLEtBQUttTixNQUFMLENBQVluTixDQUFaO0FBQWUsU0FBUUosU0FBUixDQUFrQjBOLE9BQWxCLEdBQTBCOEYsY0FBMUIsQ0FBeUNMLFFBQVFuVCxTQUFSLENBQWtCMk4sTUFBbEIsR0FBeUI4RixhQUF6QixDQUF1Q04sUUFBUW5ULFNBQVIsQ0FBa0J1TixNQUFsQixHQUF5Qm1HLGFBQXpCLENBQXVDUCxRQUFRblQsU0FBUixDQUFrQjROLEtBQWxCLEdBQXdCa0csWUFBeEIsQ0FBcUNYLFFBQVFuVCxTQUFSLENBQWtCNk4sS0FBbEIsR0FBd0JnRyxZQUF4QixDQUFxQyxTQUFTRSxRQUFULENBQWtCNVIsQ0FBbEIsRUFBb0J0QyxDQUFwQixFQUFzQjtBQUFDLE1BQUlzQixJQUFFZ0IsRUFBRTZNLFNBQUYsRUFBTjtBQUFBLE1BQW9CcFAsQ0FBcEI7QUFBQSxNQUFzQlEsSUFBRTJLLElBQUksQ0FBSixDQUF4QjtBQUFBLE1BQStCMUcsQ0FBL0IsQ0FBaUMsSUFBR2xELEtBQUcsQ0FBTixFQUFRO0FBQUMsV0FBT2YsQ0FBUDtBQUFTLEdBQWxCLE1BQXNCO0FBQUMsUUFBR2UsSUFBRSxFQUFMLEVBQVE7QUFBQ3ZCLFVBQUUsQ0FBRjtBQUFJLEtBQWIsTUFBaUI7QUFBQyxVQUFHdUIsSUFBRSxFQUFMLEVBQVE7QUFBQ3ZCLFlBQUUsQ0FBRjtBQUFJLE9BQWIsTUFBaUI7QUFBQyxZQUFHdUIsSUFBRSxHQUFMLEVBQVM7QUFBQ3ZCLGNBQUUsQ0FBRjtBQUFJLFNBQWQsTUFBa0I7QUFBQyxjQUFHdUIsSUFBRSxHQUFMLEVBQVM7QUFBQ3ZCLGdCQUFFLENBQUY7QUFBSSxXQUFkLE1BQWtCO0FBQUNBLGdCQUFFLENBQUY7QUFBSTtBQUFDO0FBQUM7QUFBQztBQUFDLE9BQUd1QixJQUFFLENBQUwsRUFBTztBQUFDa0QsUUFBRSxJQUFJMkksT0FBSixDQUFZbk4sQ0FBWixDQUFGO0FBQWlCLEdBQXpCLE1BQTZCO0FBQUMsUUFBR0EsRUFBRWlQLE1BQUYsRUFBSCxFQUFjO0FBQUN6SyxVQUFFLElBQUk4TyxPQUFKLENBQVl0VCxDQUFaLENBQUY7QUFBaUIsS0FBaEMsTUFBb0M7QUFBQ3dFLFVBQUUsSUFBSTBKLFVBQUosQ0FBZWxPLENBQWYsQ0FBRjtBQUFvQjtBQUFDLE9BQUlxQixJQUFFLElBQUlrSSxLQUFKLEVBQU47QUFBQSxNQUFrQnJKLElBQUUsQ0FBcEI7QUFBQSxNQUFzQnFDLElBQUV4QyxJQUFFLENBQTFCO0FBQUEsTUFBNEJpQixJQUFFLENBQUMsS0FBR2pCLENBQUosSUFBTyxDQUFyQyxDQUF1Q3NCLEVBQUUsQ0FBRixJQUFLbUQsRUFBRXFKLE9BQUYsQ0FBVSxJQUFWLENBQUwsQ0FBcUIsSUFBRzlOLElBQUUsQ0FBTCxFQUFPO0FBQUMsUUFBSWlJLElBQUU4QixLQUFOLENBQVl0RixFQUFFd0osS0FBRixDQUFRM00sRUFBRSxDQUFGLENBQVIsRUFBYTJHLENBQWIsRUFBZ0IsT0FBTTlILEtBQUdjLENBQVQsRUFBVztBQUFDSyxRQUFFbkIsQ0FBRixJQUFLNEosS0FBTCxDQUFXdEYsRUFBRXVKLEtBQUYsQ0FBUS9GLENBQVIsRUFBVTNHLEVBQUVuQixJQUFFLENBQUosQ0FBVixFQUFpQm1CLEVBQUVuQixDQUFGLENBQWpCLEVBQXVCQSxLQUFHLENBQUg7QUFBSztBQUFDLE9BQUlZLElBQUV3QixFQUFFRCxDQUFGLEdBQUksQ0FBVjtBQUFBLE1BQVlpQyxDQUFaO0FBQUEsTUFBY0csSUFBRSxJQUFoQjtBQUFBLE1BQXFCaEUsSUFBRXFKLEtBQXZCO0FBQUEsTUFBNkI3QixDQUE3QixDQUErQjNHLElBQUV5SyxNQUFNekosRUFBRXhCLENBQUYsQ0FBTixJQUFZLENBQWQsQ0FBZ0IsT0FBTUEsS0FBRyxDQUFULEVBQVc7QUFBQyxRQUFHUSxLQUFHaUIsQ0FBTixFQUFRO0FBQUMrQixVQUFHaEMsRUFBRXhCLENBQUYsS0FBT1EsSUFBRWlCLENBQVYsR0FBY3ZCLENBQWhCO0FBQWtCLEtBQTNCLE1BQStCO0FBQUNzRCxVQUFFLENBQUNoQyxFQUFFeEIsQ0FBRixJQUFNLENBQUMsS0FBSVEsSUFBRSxDQUFQLElBQVcsQ0FBbEIsS0FBd0JpQixJQUFFakIsQ0FBNUIsQ0FBK0IsSUFBR1IsSUFBRSxDQUFMLEVBQU87QUFBQ3dELGFBQUdoQyxFQUFFeEIsSUFBRSxDQUFKLEtBQVMsS0FBS3NKLEVBQUwsR0FBUTlJLENBQVIsR0FBVWlCLENBQXRCO0FBQXlCO0FBQUMsU0FBRXhDLENBQUYsQ0FBSSxPQUFNLENBQUN1RSxJQUFFLENBQUgsS0FBTyxDQUFiLEVBQWU7QUFBQ0EsWUFBSSxDQUFKLENBQU0sRUFBRXBFLENBQUY7QUFBSSxTQUFHLENBQUNvQixLQUFHcEIsQ0FBSixJQUFPLENBQVYsRUFBWTtBQUFDb0IsV0FBRyxLQUFLOEksRUFBUixDQUFXLEVBQUV0SixDQUFGO0FBQUksU0FBRzJELENBQUgsRUFBSztBQUFDcEQsUUFBRWlELENBQUYsRUFBS29JLE1BQUwsQ0FBWW5NLENBQVosRUFBZWtFLElBQUUsS0FBRjtBQUFRLEtBQTdCLE1BQWlDO0FBQUMsYUFBTXZFLElBQUUsQ0FBUixFQUFVO0FBQUNzRSxVQUFFd0osS0FBRixDQUFRek4sQ0FBUixFQUFVRSxDQUFWLEVBQWErRCxFQUFFd0osS0FBRixDQUFRdk4sQ0FBUixFQUFVRixDQUFWLEVBQWFMLEtBQUcsQ0FBSDtBQUFLLFdBQUdBLElBQUUsQ0FBTCxFQUFPO0FBQUNzRSxVQUFFd0osS0FBRixDQUFRek4sQ0FBUixFQUFVRSxDQUFWO0FBQWEsT0FBckIsTUFBeUI7QUFBQ3dILFlBQUUxSCxDQUFGLENBQUlBLElBQUVFLENBQUYsQ0FBSUEsSUFBRXdILENBQUY7QUFBSSxTQUFFOEYsS0FBRixDQUFRdE4sQ0FBUixFQUFVWSxFQUFFaUQsQ0FBRixDQUFWLEVBQWUvRCxDQUFmO0FBQWtCLFlBQU1PLEtBQUcsQ0FBSCxJQUFNLENBQUN3QixFQUFFeEIsQ0FBRixJQUFNLEtBQUdRLENBQVYsS0FBZSxDQUEzQixFQUE2QjtBQUFDa0QsUUFBRXdKLEtBQUYsQ0FBUXpOLENBQVIsRUFBVUUsQ0FBVixFQUFhd0gsSUFBRTFILENBQUYsQ0FBSUEsSUFBRUUsQ0FBRixDQUFJQSxJQUFFd0gsQ0FBRixDQUFJLElBQUcsRUFBRTNHLENBQUYsR0FBSSxDQUFQLEVBQVM7QUFBQ0EsWUFBRSxLQUFLOEksRUFBTCxHQUFRLENBQVYsQ0FBWSxFQUFFdEosQ0FBRjtBQUFJO0FBQUM7QUFBQyxVQUFPMEQsRUFBRXNKLE1BQUYsQ0FBU3ZOLENBQVQsQ0FBUDtBQUFtQixVQUFTNFQsS0FBVCxDQUFlMVQsQ0FBZixFQUFpQjtBQUFDLE1BQUlGLElBQUcsS0FBS2dDLENBQUwsR0FBTyxDQUFSLEdBQVcsS0FBS21KLE1BQUwsRUFBWCxHQUF5QixLQUFLM0osS0FBTCxFQUEvQixDQUE0QyxJQUFJaEMsSUFBR1UsRUFBRThCLENBQUYsR0FBSSxDQUFMLEdBQVE5QixFQUFFaUwsTUFBRixFQUFSLEdBQW1CakwsRUFBRXNCLEtBQUYsRUFBekIsQ0FBbUMsSUFBR3hCLEVBQUVzTSxTQUFGLENBQVk5TSxDQUFaLElBQWUsQ0FBbEIsRUFBb0I7QUFBQyxRQUFJUyxJQUFFRCxDQUFOLENBQVFBLElBQUVSLENBQUYsQ0FBSUEsSUFBRVMsQ0FBRjtBQUFJLE9BQUlOLElBQUVLLEVBQUU2VCxlQUFGLEVBQU47QUFBQSxNQUEwQnBVLElBQUVELEVBQUVxVSxlQUFGLEVBQTVCLENBQWdELElBQUdwVSxJQUFFLENBQUwsRUFBTztBQUFDLFdBQU9PLENBQVA7QUFBUyxPQUFHTCxJQUFFRixDQUFMLEVBQU87QUFBQ0EsUUFBRUUsQ0FBRjtBQUFJLE9BQUdGLElBQUUsQ0FBTCxFQUFPO0FBQUNPLE1BQUV5TSxRQUFGLENBQVdoTixDQUFYLEVBQWFPLENBQWIsRUFBZ0JSLEVBQUVpTixRQUFGLENBQVdoTixDQUFYLEVBQWFELENBQWI7QUFBZ0IsVUFBTVEsRUFBRXVQLE1BQUYsS0FBVyxDQUFqQixFQUFtQjtBQUFDLFFBQUcsQ0FBQzVQLElBQUVLLEVBQUU2VCxlQUFGLEVBQUgsSUFBd0IsQ0FBM0IsRUFBNkI7QUFBQzdULFFBQUV5TSxRQUFGLENBQVc5TSxDQUFYLEVBQWFLLENBQWI7QUFBZ0IsU0FBRyxDQUFDTCxJQUFFSCxFQUFFcVUsZUFBRixFQUFILElBQXdCLENBQTNCLEVBQTZCO0FBQUNyVSxRQUFFaU4sUUFBRixDQUFXOU0sQ0FBWCxFQUFhSCxDQUFiO0FBQWdCLFNBQUdRLEVBQUVzTSxTQUFGLENBQVk5TSxDQUFaLEtBQWdCLENBQW5CLEVBQXFCO0FBQUNRLFFBQUVnTCxLQUFGLENBQVF4TCxDQUFSLEVBQVVRLENBQVYsRUFBYUEsRUFBRXlNLFFBQUYsQ0FBVyxDQUFYLEVBQWF6TSxDQUFiO0FBQWdCLEtBQW5ELE1BQXVEO0FBQUNSLFFBQUV3TCxLQUFGLENBQVFoTCxDQUFSLEVBQVVSLENBQVYsRUFBYUEsRUFBRWlOLFFBQUYsQ0FBVyxDQUFYLEVBQWFqTixDQUFiO0FBQWdCO0FBQUMsT0FBR0MsSUFBRSxDQUFMLEVBQU87QUFBQ0QsTUFBRTRNLFFBQUYsQ0FBVzNNLENBQVgsRUFBYUQsQ0FBYjtBQUFnQixVQUFPQSxDQUFQO0FBQVMsVUFBU3NVLFNBQVQsQ0FBbUI3VCxDQUFuQixFQUFxQjtBQUFDLE1BQUdBLEtBQUcsQ0FBTixFQUFRO0FBQUMsV0FBTyxDQUFQO0FBQVMsT0FBSUMsSUFBRSxLQUFLNkosRUFBTCxHQUFROUosQ0FBZDtBQUFBLE1BQWdCRCxJQUFHLEtBQUtnQyxDQUFMLEdBQU8sQ0FBUixHQUFXL0IsSUFBRSxDQUFiLEdBQWUsQ0FBakMsQ0FBbUMsSUFBRyxLQUFLNkIsQ0FBTCxHQUFPLENBQVYsRUFBWTtBQUFDLFFBQUc1QixLQUFHLENBQU4sRUFBUTtBQUFDRixVQUFFLEtBQUssQ0FBTCxJQUFRQyxDQUFWO0FBQVksS0FBckIsTUFBeUI7QUFBQyxXQUFJLElBQUlRLElBQUUsS0FBS3FCLENBQUwsR0FBTyxDQUFqQixFQUFtQnJCLEtBQUcsQ0FBdEIsRUFBd0IsRUFBRUEsQ0FBMUIsRUFBNEI7QUFBQ1QsWUFBRSxDQUFDRSxJQUFFRixDQUFGLEdBQUksS0FBS1MsQ0FBTCxDQUFMLElBQWNSLENBQWhCO0FBQWtCO0FBQUM7QUFBQyxVQUFPRCxDQUFQO0FBQVMsVUFBUytULFlBQVQsQ0FBc0J0VSxDQUF0QixFQUF3QjtBQUFDLE1BQUlXLElBQUVYLEVBQUVpUCxNQUFGLEVBQU4sQ0FBaUIsSUFBSSxLQUFLQSxNQUFMLE1BQWV0TyxDQUFoQixJQUFvQlgsRUFBRThQLE1BQUYsTUFBWSxDQUFuQyxFQUFxQztBQUFDLFdBQU9uRyxXQUFXMkIsSUFBbEI7QUFBdUIsT0FBSTFLLElBQUVaLEVBQUUrQixLQUFGLEVBQU47QUFBQSxNQUFnQmhDLElBQUUsS0FBS2dDLEtBQUwsRUFBbEIsQ0FBK0IsSUFBSWpDLElBQUVvTCxJQUFJLENBQUosQ0FBTjtBQUFBLE1BQWExSyxJQUFFMEssSUFBSSxDQUFKLENBQWY7QUFBQSxNQUFzQnBLLElBQUVvSyxJQUFJLENBQUosQ0FBeEI7QUFBQSxNQUErQm5LLElBQUVtSyxJQUFJLENBQUosQ0FBakMsQ0FBd0MsT0FBTXRLLEVBQUVrUCxNQUFGLE1BQVksQ0FBbEIsRUFBb0I7QUFBQyxXQUFNbFAsRUFBRXFPLE1BQUYsRUFBTixFQUFpQjtBQUFDck8sUUFBRW9NLFFBQUYsQ0FBVyxDQUFYLEVBQWFwTSxDQUFiLEVBQWdCLElBQUdELENBQUgsRUFBSztBQUFDLFlBQUcsQ0FBQ2IsRUFBRW1QLE1BQUYsRUFBRCxJQUFhLENBQUN6TyxFQUFFeU8sTUFBRixFQUFqQixFQUE0QjtBQUFDblAsWUFBRXdTLEtBQUYsQ0FBUSxJQUFSLEVBQWF4UyxDQUFiLEVBQWdCVSxFQUFFK0ssS0FBRixDQUFRdkwsQ0FBUixFQUFVUSxDQUFWO0FBQWEsV0FBRXdNLFFBQUYsQ0FBVyxDQUFYLEVBQWFsTixDQUFiO0FBQWdCLE9BQWhGLE1BQW9GO0FBQUMsWUFBRyxDQUFDVSxFQUFFeU8sTUFBRixFQUFKLEVBQWU7QUFBQ3pPLFlBQUUrSyxLQUFGLENBQVF2TCxDQUFSLEVBQVVRLENBQVY7QUFBYTtBQUFDLFNBQUV3TSxRQUFGLENBQVcsQ0FBWCxFQUFheE0sQ0FBYjtBQUFnQixZQUFNVCxFQUFFa1AsTUFBRixFQUFOLEVBQWlCO0FBQUNsUCxRQUFFaU4sUUFBRixDQUFXLENBQVgsRUFBYWpOLENBQWIsRUFBZ0IsSUFBR1ksQ0FBSCxFQUFLO0FBQUMsWUFBRyxDQUFDRyxFQUFFbU8sTUFBRixFQUFELElBQWEsQ0FBQ2xPLEVBQUVrTyxNQUFGLEVBQWpCLEVBQTRCO0FBQUNuTyxZQUFFd1IsS0FBRixDQUFRLElBQVIsRUFBYXhSLENBQWIsRUFBZ0JDLEVBQUV3SyxLQUFGLENBQVF2TCxDQUFSLEVBQVVlLENBQVY7QUFBYSxXQUFFaU0sUUFBRixDQUFXLENBQVgsRUFBYWxNLENBQWI7QUFBZ0IsT0FBaEYsTUFBb0Y7QUFBQyxZQUFHLENBQUNDLEVBQUVrTyxNQUFGLEVBQUosRUFBZTtBQUFDbE8sWUFBRXdLLEtBQUYsQ0FBUXZMLENBQVIsRUFBVWUsQ0FBVjtBQUFhO0FBQUMsU0FBRWlNLFFBQUYsQ0FBVyxDQUFYLEVBQWFqTSxDQUFiO0FBQWdCLFNBQUdILEVBQUVpTSxTQUFGLENBQVk5TSxDQUFaLEtBQWdCLENBQW5CLEVBQXFCO0FBQUNhLFFBQUUySyxLQUFGLENBQVF4TCxDQUFSLEVBQVVhLENBQVYsRUFBYSxJQUFHRCxDQUFILEVBQUs7QUFBQ2IsVUFBRXlMLEtBQUYsQ0FBUXpLLENBQVIsRUFBVWhCLENBQVY7QUFBYSxTQUFFeUwsS0FBRixDQUFReEssQ0FBUixFQUFVUCxDQUFWO0FBQWEsS0FBbkUsTUFBdUU7QUFBQ1QsUUFBRXdMLEtBQUYsQ0FBUTNLLENBQVIsRUFBVWIsQ0FBVixFQUFhLElBQUdZLENBQUgsRUFBSztBQUFDRyxVQUFFeUssS0FBRixDQUFRekwsQ0FBUixFQUFVZ0IsQ0FBVjtBQUFhLFNBQUV5SyxLQUFGLENBQVEvSyxDQUFSLEVBQVVPLENBQVY7QUFBYTtBQUFDLE9BQUdoQixFQUFFOE0sU0FBRixDQUFZbEQsV0FBV21ELEdBQXZCLEtBQTZCLENBQWhDLEVBQWtDO0FBQUMsV0FBT25ELFdBQVcyQixJQUFsQjtBQUF1QixPQUFHdkssRUFBRThMLFNBQUYsQ0FBWTdNLENBQVosS0FBZ0IsQ0FBbkIsRUFBcUI7QUFBQyxXQUFPZSxFQUFFd1QsUUFBRixDQUFXdlUsQ0FBWCxDQUFQO0FBQXFCLE9BQUdlLEVBQUUrTyxNQUFGLEtBQVcsQ0FBZCxFQUFnQjtBQUFDL08sTUFBRXVSLEtBQUYsQ0FBUXRTLENBQVIsRUFBVWUsQ0FBVjtBQUFhLEdBQTlCLE1BQWtDO0FBQUMsV0FBT0EsQ0FBUDtBQUFTLE9BQUdBLEVBQUUrTyxNQUFGLEtBQVcsQ0FBZCxFQUFnQjtBQUFDLFdBQU8vTyxFQUFFeVQsR0FBRixDQUFNeFUsQ0FBTixDQUFQO0FBQWdCLEdBQWpDLE1BQXFDO0FBQUMsV0FBT2UsQ0FBUDtBQUFTO0FBQUMsS0FBSTBULFlBQVUsQ0FBQyxDQUFELEVBQUcsQ0FBSCxFQUFLLENBQUwsRUFBTyxDQUFQLEVBQVMsRUFBVCxFQUFZLEVBQVosRUFBZSxFQUFmLEVBQWtCLEVBQWxCLEVBQXFCLEVBQXJCLEVBQXdCLEVBQXhCLEVBQTJCLEVBQTNCLEVBQThCLEVBQTlCLEVBQWlDLEVBQWpDLEVBQW9DLEVBQXBDLEVBQXVDLEVBQXZDLEVBQTBDLEVBQTFDLEVBQTZDLEVBQTdDLEVBQWdELEVBQWhELEVBQW1ELEVBQW5ELEVBQXNELEVBQXRELEVBQXlELEVBQXpELEVBQTRELEVBQTVELEVBQStELEVBQS9ELEVBQWtFLEVBQWxFLEVBQXFFLEVBQXJFLEVBQXdFLEdBQXhFLEVBQTRFLEdBQTVFLEVBQWdGLEdBQWhGLEVBQW9GLEdBQXBGLEVBQXdGLEdBQXhGLEVBQTRGLEdBQTVGLEVBQWdHLEdBQWhHLEVBQW9HLEdBQXBHLEVBQXdHLEdBQXhHLEVBQTRHLEdBQTVHLEVBQWdILEdBQWhILEVBQW9ILEdBQXBILEVBQXdILEdBQXhILEVBQTRILEdBQTVILEVBQWdJLEdBQWhJLEVBQW9JLEdBQXBJLEVBQXdJLEdBQXhJLEVBQTRJLEdBQTVJLEVBQWdKLEdBQWhKLEVBQW9KLEdBQXBKLEVBQXdKLEdBQXhKLEVBQTRKLEdBQTVKLEVBQWdLLEdBQWhLLEVBQW9LLEdBQXBLLEVBQXdLLEdBQXhLLEVBQTRLLEdBQTVLLEVBQWdMLEdBQWhMLEVBQW9MLEdBQXBMLEVBQXdMLEdBQXhMLEVBQTRMLEdBQTVMLEVBQWdNLEdBQWhNLEVBQW9NLEdBQXBNLEVBQXdNLEdBQXhNLEVBQTRNLEdBQTVNLEVBQWdOLEdBQWhOLEVBQW9OLEdBQXBOLEVBQXdOLEdBQXhOLEVBQTROLEdBQTVOLEVBQWdPLEdBQWhPLEVBQW9PLEdBQXBPLEVBQXdPLEdBQXhPLEVBQTRPLEdBQTVPLEVBQWdQLEdBQWhQLEVBQW9QLEdBQXBQLEVBQXdQLEdBQXhQLEVBQTRQLEdBQTVQLEVBQWdRLEdBQWhRLEVBQW9RLEdBQXBRLEVBQXdRLEdBQXhRLEVBQTRRLEdBQTVRLEVBQWdSLEdBQWhSLEVBQW9SLEdBQXBSLEVBQXdSLEdBQXhSLEVBQTRSLEdBQTVSLEVBQWdTLEdBQWhTLEVBQW9TLEdBQXBTLEVBQXdTLEdBQXhTLEVBQTRTLEdBQTVTLEVBQWdULEdBQWhULEVBQW9ULEdBQXBULEVBQXdULEdBQXhULEVBQTRULEdBQTVULEVBQWdVLEdBQWhVLEVBQW9VLEdBQXBVLEVBQXdVLEdBQXhVLEVBQTRVLEdBQTVVLEVBQWdWLEdBQWhWLEVBQW9WLEdBQXBWLEVBQXdWLEdBQXhWLEVBQTRWLEdBQTVWLEVBQWdXLEdBQWhXLEVBQW9XLEdBQXBXLEVBQXdXLEdBQXhXLEVBQTRXLEdBQTVXLEVBQWdYLEdBQWhYLEVBQW9YLEdBQXBYLEVBQXdYLEdBQXhYLEVBQTRYLEdBQTVYLEVBQWdZLEdBQWhZLEVBQW9ZLEdBQXBZLEVBQXdZLEdBQXhZLEVBQTRZLEdBQTVZLEVBQWdaLEdBQWhaLEVBQW9aLEdBQXBaLEVBQXdaLEdBQXhaLEVBQTRaLEdBQTVaLEVBQWdhLEdBQWhhLEVBQW9hLEdBQXBhLEVBQXdhLEdBQXhhLEVBQTRhLEdBQTVhLEVBQWdiLEdBQWhiLEVBQW9iLEdBQXBiLEVBQXdiLEdBQXhiLEVBQTRiLEdBQTViLEVBQWdjLEdBQWhjLEVBQW9jLEdBQXBjLEVBQXdjLEdBQXhjLEVBQTRjLEdBQTVj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Q0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFVBQVU7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFlBQVk7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQSx1Q0FBdUMsU0FBUztBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFpQjtBQUNoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsaUJBQWlCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxFQUFFO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixlQUFlO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLHdCQUF3QixRQUFRO0FBQ2hDO0FBQ0EscUJBQXFCLGVBQWU7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFlBQVk7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFCQUFxQixTQUFTO0FBQzlCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQWtCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxtQkFBbUIsY0FBYztBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdURBQXVELE9BQU87QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVEQUF1RCxPQUFPO0FBQzlEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUFxQixRQUFRO0FBQzdCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztB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a0NBLE8sR0FBQUEsTyIsImZpbGUiOiJvaWRjLWNsaWVudC5zbGltLmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuIFx0XHR9XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3RcbiBcdC8vIG1vZGUgJiAxOiB2YWx1ZSBpcyBhIG1vZHVsZSBpZCwgcmVxdWlyZSBpdFxuIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3RcbiBcdC8vIG1vZGUgJiA4fDE6IGJlaGF2ZSBsaWtlIHJlcXVpcmVcbiBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xuIFx0XHRpZihtb2RlICYgOCkgcmV0dXJuIHZhbHVlO1xuIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIobnMpO1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcbiBcdFx0cmV0dXJuIG5zO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDApO1xuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9zcmMvTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudCB9IGZyb20gJy4vc3JjL09pZGNDbGllbnQuanMnO1xyXG5pbXBvcnQgeyBPaWRjQ2xpZW50U2V0dGluZ3MgfSBmcm9tICcuL3NyYy9PaWRjQ2xpZW50U2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB9IGZyb20gJy4vc3JjL1dlYlN0b3JhZ2VTdGF0ZVN0b3JlLmpzJztcclxuaW1wb3J0IHsgSW5NZW1vcnlXZWJTdG9yYWdlIH0gZnJvbSAnLi9zcmMvSW5NZW1vcnlXZWJTdG9yYWdlLmpzJztcclxuaW1wb3J0IHsgVXNlck1hbmFnZXIgfSBmcm9tICcuL3NyYy9Vc2VyTWFuYWdlci5qcyc7XHJcbmltcG9ydCB7IEFjY2Vzc1Rva2VuRXZlbnRzIH0gZnJvbSAnLi9zcmMvQWNjZXNzVG9rZW5FdmVudHMuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL3NyYy9NZXRhZGF0YVNlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBDb3Jkb3ZhUG9wdXBOYXZpZ2F0b3IgfSBmcm9tICcuL3NyYy9Db3Jkb3ZhUG9wdXBOYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yIH0gZnJvbSAnLi9zcmMvQ29yZG92YUlGcmFtZU5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IENoZWNrU2Vzc2lvbklGcmFtZSB9IGZyb20gJy4vc3JjL0NoZWNrU2Vzc2lvbklGcmFtZS5qcyc7XHJcbmltcG9ydCB7IFRva2VuUmV2b2NhdGlvbkNsaWVudCB9IGZyb20gJy4vc3JjL1Rva2VuUmV2b2NhdGlvbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IFNlc3Npb25Nb25pdG9yIH0gZnJvbSAnLi9zcmMvU2Vzc2lvbk1vbml0b3IuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL3NyYy9HbG9iYWwuanMnO1xyXG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi9zcmMvVXNlci5qcyc7XHJcblxyXG5pbXBvcnQgeyBWZXJzaW9uIH0gZnJvbSAnLi92ZXJzaW9uLmpzJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICAgIFZlcnNpb24sXHJcbiAgICBMb2csXHJcbiAgICBPaWRjQ2xpZW50LFxyXG4gICAgT2lkY0NsaWVudFNldHRpbmdzLFxyXG4gICAgV2ViU3RvcmFnZVN0YXRlU3RvcmUsXHJcbiAgICBJbk1lbW9yeVdlYlN0b3JhZ2UsXHJcbiAgICBVc2VyTWFuYWdlcixcclxuICAgIEFjY2Vzc1Rva2VuRXZlbnRzLFxyXG4gICAgTWV0YWRhdGFTZXJ2aWNlLFxyXG4gICAgQ29yZG92YVBvcHVwTmF2aWdhdG9yLFxyXG4gICAgQ29yZG92YUlGcmFtZU5hdmlnYXRvcixcclxuICAgIENoZWNrU2Vzc2lvbklGcmFtZSxcclxuICAgIFRva2VuUmV2b2NhdGlvbkNsaWVudCxcclxuICAgIFNlc3Npb25Nb25pdG9yLFxyXG4gICAgR2xvYmFsLFxyXG4gICAgVXNlclxyXG59O1xyXG4iLCIvKlxyXG4gKiBqc3JzYXNpZ24oYWxsKSA4LjAuMTIgKDIwMTgtMDQtMjIpIChjKSAyMDEwLTIwMTggS2VuamkgVXJ1c2hpbWEgfCBranVyLmdpdGh1Yi5jb20vanNyc2FzaWduL2xpY2Vuc2VcclxuICovXHJcblxyXG52YXIgbmF2aWdhdG9yID0ge307XHJcbm5hdmlnYXRvci51c2VyQWdlbnQgPSBmYWxzZTtcclxuXHJcbnZhciB3aW5kb3cgPSB7fTtcclxuXG4vKiFcclxuQ29weXJpZ2h0IChjKSAyMDExLCBZYWhvbyEgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5Db2RlIGxpY2Vuc2VkIHVuZGVyIHRoZSBCU0QgTGljZW5zZTpcclxuaHR0cDovL2RldmVsb3Blci55YWhvby5jb20veXVpL2xpY2Vuc2UuaHRtbFxyXG52ZXJzaW9uOiAyLjkuMFxyXG4qL1xyXG5pZihZQUhPTz09PXVuZGVmaW5lZCl7dmFyIFlBSE9PPXt9fVlBSE9PLmxhbmc9e2V4dGVuZDpmdW5jdGlvbihnLGgsZil7aWYoIWh8fCFnKXt0aHJvdyBuZXcgRXJyb3IoXCJZQUhPTy5sYW5nLmV4dGVuZCBmYWlsZWQsIHBsZWFzZSBjaGVjayB0aGF0IGFsbCBkZXBlbmRlbmNpZXMgYXJlIGluY2x1ZGVkLlwiKX12YXIgZD1mdW5jdGlvbigpe307ZC5wcm90b3R5cGU9aC5wcm90b3R5cGU7Zy5wcm90b3R5cGU9bmV3IGQoKTtnLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1nO2cuc3VwZXJjbGFzcz1oLnByb3RvdHlwZTtpZihoLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj09T2JqZWN0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvcil7aC5wcm90b3R5cGUuY29uc3RydWN0b3I9aH1pZihmKXt2YXIgYjtmb3IoYiBpbiBmKXtnLnByb3RvdHlwZVtiXT1mW2JdfXZhciBlPWZ1bmN0aW9uKCl7fSxjPVtcInRvU3RyaW5nXCIsXCJ2YWx1ZU9mXCJdO3RyeXtpZigvTVNJRS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSl7ZT1mdW5jdGlvbihqLGkpe2ZvcihiPTA7YjxjLmxlbmd0aDtiPWIrMSl7dmFyIGw9Y1tiXSxrPWlbbF07aWYodHlwZW9mIGs9PT1cImZ1bmN0aW9uXCImJmshPU9iamVjdC5wcm90b3R5cGVbbF0pe2pbbF09a319fX19Y2F0Y2goYSl7fWUoZy5wcm90b3R5cGUsZil9fX07XG4vKiEgQ3J5cHRvSlMgdjMuMS4yIGNvcmUtZml4LmpzXHJcbiAqIGNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xyXG4gKiAoYykgMjAwOS0yMDEzIGJ5IEplZmYgTW90dC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuICogY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL3dpa2kvTGljZW5zZVxyXG4gKiBUSElTIElTIEZJWCBvZiAnY29yZS5qcycgdG8gZml4IEhtYWMgaXNzdWUuXHJcbiAqIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL2lzc3Vlcy9kZXRhaWw/aWQ9ODRcclxuICogaHR0cHM6Ly9jcnlwdG8tanMuZ29vZ2xlY29kZS5jb20vc3ZuLWhpc3RvcnkvcjY2Ny9icmFuY2hlcy8zLngvc3JjL2NvcmUuanNcclxuICovXHJcbnZhciBDcnlwdG9KUz1DcnlwdG9KU3x8KGZ1bmN0aW9uKGUsZyl7dmFyIGE9e307dmFyIGI9YS5saWI9e307dmFyIGo9Yi5CYXNlPShmdW5jdGlvbigpe2Z1bmN0aW9uIG4oKXt9cmV0dXJue2V4dGVuZDpmdW5jdGlvbihwKXtuLnByb3RvdHlwZT10aGlzO3ZhciBvPW5ldyBuKCk7aWYocCl7by5taXhJbihwKX1pZighby5oYXNPd25Qcm9wZXJ0eShcImluaXRcIikpe28uaW5pdD1mdW5jdGlvbigpe28uJHN1cGVyLmluaXQuYXBwbHkodGhpcyxhcmd1bWVudHMpfX1vLmluaXQucHJvdG90eXBlPW87by4kc3VwZXI9dGhpcztyZXR1cm4gb30sY3JlYXRlOmZ1bmN0aW9uKCl7dmFyIG89dGhpcy5leHRlbmQoKTtvLmluaXQuYXBwbHkobyxhcmd1bWVudHMpO3JldHVybiBvfSxpbml0OmZ1bmN0aW9uKCl7fSxtaXhJbjpmdW5jdGlvbihwKXtmb3IodmFyIG8gaW4gcCl7aWYocC5oYXNPd25Qcm9wZXJ0eShvKSl7dGhpc1tvXT1wW29dfX1pZihwLmhhc093blByb3BlcnR5KFwidG9TdHJpbmdcIikpe3RoaXMudG9TdHJpbmc9cC50b1N0cmluZ319LGNsb25lOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpfX19KCkpO3ZhciBsPWIuV29yZEFycmF5PWouZXh0ZW5kKHtpbml0OmZ1bmN0aW9uKG8sbil7bz10aGlzLndvcmRzPW98fFtdO2lmKG4hPWcpe3RoaXMuc2lnQnl0ZXM9bn1lbHNle3RoaXMuc2lnQnl0ZXM9by5sZW5ndGgqNH19LHRvU3RyaW5nOmZ1bmN0aW9uKG4pe3JldHVybihufHxoKS5zdHJpbmdpZnkodGhpcyl9LGNvbmNhdDpmdW5jdGlvbih0KXt2YXIgcT10aGlzLndvcmRzO3ZhciBwPXQud29yZHM7dmFyIG49dGhpcy5zaWdCeXRlczt2YXIgcz10LnNpZ0J5dGVzO3RoaXMuY2xhbXAoKTtpZihuJTQpe2Zvcih2YXIgcj0wO3I8cztyKyspe3ZhciBvPShwW3I+Pj4yXT4+PigyNC0ociU0KSo4KSkmMjU1O3FbKG4rcik+Pj4yXXw9bzw8KDI0LSgobityKSU0KSo4KX19ZWxzZXtmb3IodmFyIHI9MDtyPHM7cis9NCl7cVsobityKT4+PjJdPXBbcj4+PjJdfX10aGlzLnNpZ0J5dGVzKz1zO3JldHVybiB0aGlzfSxjbGFtcDpmdW5jdGlvbigpe3ZhciBvPXRoaXMud29yZHM7dmFyIG49dGhpcy5zaWdCeXRlcztvW24+Pj4yXSY9NDI5NDk2NzI5NTw8KDMyLShuJTQpKjgpO28ubGVuZ3RoPWUuY2VpbChuLzQpfSxjbG9uZTpmdW5jdGlvbigpe3ZhciBuPWouY2xvbmUuY2FsbCh0aGlzKTtuLndvcmRzPXRoaXMud29yZHMuc2xpY2UoMCk7cmV0dXJuIG59LHJhbmRvbTpmdW5jdGlvbihwKXt2YXIgbz1bXTtmb3IodmFyIG49MDtuPHA7bis9NCl7by5wdXNoKChlLnJhbmRvbSgpKjQyOTQ5NjcyOTYpfDApfXJldHVybiBuZXcgbC5pbml0KG8scCl9fSk7dmFyIG09YS5lbmM9e307dmFyIGg9bS5IZXg9e3N0cmluZ2lmeTpmdW5jdGlvbihwKXt2YXIgcj1wLndvcmRzO3ZhciBvPXAuc2lnQnl0ZXM7dmFyIHE9W107Zm9yKHZhciBuPTA7bjxvO24rKyl7dmFyIHM9KHJbbj4+PjJdPj4+KDI0LShuJTQpKjgpKSYyNTU7cS5wdXNoKChzPj4+NCkudG9TdHJpbmcoMTYpKTtxLnB1c2goKHMmMTUpLnRvU3RyaW5nKDE2KSl9cmV0dXJuIHEuam9pbihcIlwiKX0scGFyc2U6ZnVuY3Rpb24ocCl7dmFyIG49cC5sZW5ndGg7dmFyIHE9W107Zm9yKHZhciBvPTA7bzxuO28rPTIpe3Fbbz4+PjNdfD1wYXJzZUludChwLnN1YnN0cihvLDIpLDE2KTw8KDI0LShvJTgpKjQpfXJldHVybiBuZXcgbC5pbml0KHEsbi8yKX19O3ZhciBkPW0uTGF0aW4xPXtzdHJpbmdpZnk6ZnVuY3Rpb24ocSl7dmFyIHI9cS53b3Jkczt2YXIgcD1xLnNpZ0J5dGVzO3ZhciBuPVtdO2Zvcih2YXIgbz0wO288cDtvKyspe3ZhciBzPShyW28+Pj4yXT4+PigyNC0obyU0KSo4KSkmMjU1O24ucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKHMpKX1yZXR1cm4gbi5qb2luKFwiXCIpfSxwYXJzZTpmdW5jdGlvbihwKXt2YXIgbj1wLmxlbmd0aDt2YXIgcT1bXTtmb3IodmFyIG89MDtvPG47bysrKXtxW28+Pj4yXXw9KHAuY2hhckNvZGVBdChvKSYyNTUpPDwoMjQtKG8lNCkqOCl9cmV0dXJuIG5ldyBsLmluaXQocSxuKX19O3ZhciBjPW0uVXRmOD17c3RyaW5naWZ5OmZ1bmN0aW9uKG4pe3RyeXtyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShkLnN0cmluZ2lmeShuKSkpfWNhdGNoKG8pe3Rocm93IG5ldyBFcnJvcihcIk1hbGZvcm1lZCBVVEYtOCBkYXRhXCIpfX0scGFyc2U6ZnVuY3Rpb24obil7cmV0dXJuIGQucGFyc2UodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KG4pKSl9fTt2YXIgaT1iLkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG09ai5leHRlbmQoe3Jlc2V0OmZ1bmN0aW9uKCl7dGhpcy5fZGF0YT1uZXcgbC5pbml0KCk7dGhpcy5fbkRhdGFCeXRlcz0wfSxfYXBwZW5kOmZ1bmN0aW9uKG4pe2lmKHR5cGVvZiBuPT1cInN0cmluZ1wiKXtuPWMucGFyc2Uobil9dGhpcy5fZGF0YS5jb25jYXQobik7dGhpcy5fbkRhdGFCeXRlcys9bi5zaWdCeXRlc30sX3Byb2Nlc3M6ZnVuY3Rpb24odyl7dmFyIHE9dGhpcy5fZGF0YTt2YXIgeD1xLndvcmRzO3ZhciBuPXEuc2lnQnl0ZXM7dmFyIHQ9dGhpcy5ibG9ja1NpemU7dmFyIHY9dCo0O3ZhciB1PW4vdjtpZih3KXt1PWUuY2VpbCh1KX1lbHNle3U9ZS5tYXgoKHV8MCktdGhpcy5fbWluQnVmZmVyU2l6ZSwwKX12YXIgcz11KnQ7dmFyIHI9ZS5taW4ocyo0LG4pO2lmKHMpe2Zvcih2YXIgcD0wO3A8cztwKz10KXt0aGlzLl9kb1Byb2Nlc3NCbG9jayh4LHApfXZhciBvPXguc3BsaWNlKDAscyk7cS5zaWdCeXRlcy09cn1yZXR1cm4gbmV3IGwuaW5pdChvLHIpfSxjbG9uZTpmdW5jdGlvbigpe3ZhciBuPWouY2xvbmUuY2FsbCh0aGlzKTtuLl9kYXRhPXRoaXMuX2RhdGEuY2xvbmUoKTtyZXR1cm4gbn0sX21pbkJ1ZmZlclNpemU6MH0pO3ZhciBmPWIuSGFzaGVyPWkuZXh0ZW5kKHtjZmc6ai5leHRlbmQoKSxpbml0OmZ1bmN0aW9uKG4pe3RoaXMuY2ZnPXRoaXMuY2ZnLmV4dGVuZChuKTt0aGlzLnJlc2V0KCl9LHJlc2V0OmZ1bmN0aW9uKCl7aS5yZXNldC5jYWxsKHRoaXMpO3RoaXMuX2RvUmVzZXQoKX0sdXBkYXRlOmZ1bmN0aW9uKG4pe3RoaXMuX2FwcGVuZChuKTt0aGlzLl9wcm9jZXNzKCk7cmV0dXJuIHRoaXN9LGZpbmFsaXplOmZ1bmN0aW9uKG4pe2lmKG4pe3RoaXMuX2FwcGVuZChuKX12YXIgbz10aGlzLl9kb0ZpbmFsaXplKCk7cmV0dXJuIG99LGJsb2NrU2l6ZTo1MTIvMzIsX2NyZWF0ZUhlbHBlcjpmdW5jdGlvbihuKXtyZXR1cm4gZnVuY3Rpb24ocCxvKXtyZXR1cm4gbmV3IG4uaW5pdChvKS5maW5hbGl6ZShwKX19LF9jcmVhdGVIbWFjSGVscGVyOmZ1bmN0aW9uKG4pe3JldHVybiBmdW5jdGlvbihwLG8pe3JldHVybiBuZXcgay5ITUFDLmluaXQobixvKS5maW5hbGl6ZShwKX19fSk7dmFyIGs9YS5hbGdvPXt9O3JldHVybiBhfShNYXRoKSk7XG4vKlxyXG5DcnlwdG9KUyB2My4xLjIgeDY0LWNvcmUtbWluLmpzXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xyXG4oYykgMjAwOS0yMDEzIGJ5IEplZmYgTW90dC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL3dpa2kvTGljZW5zZVxyXG4qL1xyXG4oZnVuY3Rpb24oZyl7dmFyIGE9Q3J5cHRvSlMsZj1hLmxpYixlPWYuQmFzZSxoPWYuV29yZEFycmF5LGE9YS54NjQ9e307YS5Xb3JkPWUuZXh0ZW5kKHtpbml0OmZ1bmN0aW9uKGIsYyl7dGhpcy5oaWdoPWI7dGhpcy5sb3c9Y319KTthLldvcmRBcnJheT1lLmV4dGVuZCh7aW5pdDpmdW5jdGlvbihiLGMpe2I9dGhpcy53b3Jkcz1ifHxbXTt0aGlzLnNpZ0J5dGVzPWMhPWc/Yzo4KmIubGVuZ3RofSx0b1gzMjpmdW5jdGlvbigpe2Zvcih2YXIgYj10aGlzLndvcmRzLGM9Yi5sZW5ndGgsYT1bXSxkPTA7ZDxjO2QrKyl7dmFyIGU9YltkXTthLnB1c2goZS5oaWdoKTthLnB1c2goZS5sb3cpfXJldHVybiBoLmNyZWF0ZShhLHRoaXMuc2lnQnl0ZXMpfSxjbG9uZTpmdW5jdGlvbigpe2Zvcih2YXIgYj1lLmNsb25lLmNhbGwodGhpcyksYz1iLndvcmRzPXRoaXMud29yZHMuc2xpY2UoMCksYT1jLmxlbmd0aCxkPTA7ZDxhO2QrKyljW2RdPWNbZF0uY2xvbmUoKTtyZXR1cm4gYn19KX0pKCk7XHJcblxuLypcclxuQ3J5cHRvSlMgdjMuMS4yIGVuYy1iYXNlNjQuanNcclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbihjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiovXHJcbihmdW5jdGlvbigpe3ZhciBoPUNyeXB0b0pTLGo9aC5saWIuV29yZEFycmF5O2guZW5jLkJhc2U2ND17c3RyaW5naWZ5OmZ1bmN0aW9uKGIpe3ZhciBlPWIud29yZHMsZj1iLnNpZ0J5dGVzLGM9dGhpcy5fbWFwO2IuY2xhbXAoKTtiPVtdO2Zvcih2YXIgYT0wO2E8ZjthKz0zKWZvcih2YXIgZD0oZVthPj4+Ml0+Pj4yNC04KihhJTQpJjI1NSk8PDE2fChlW2ErMT4+PjJdPj4+MjQtOCooKGErMSklNCkmMjU1KTw8OHxlW2ErMj4+PjJdPj4+MjQtOCooKGErMiklNCkmMjU1LGc9MDs0PmcmJmErMC43NSpnPGY7ZysrKWIucHVzaChjLmNoYXJBdChkPj4+NiooMy1nKSY2MykpO2lmKGU9Yy5jaGFyQXQoNjQpKWZvcig7Yi5sZW5ndGglNDspYi5wdXNoKGUpO3JldHVybiBiLmpvaW4oXCJcIil9LHBhcnNlOmZ1bmN0aW9uKGIpe3ZhciBlPWIubGVuZ3RoLGY9dGhpcy5fbWFwLGM9Zi5jaGFyQXQoNjQpO2MmJihjPWIuaW5kZXhPZihjKSwtMSE9YyYmKGU9YykpO2Zvcih2YXIgYz1bXSxhPTAsZD0wO2Q8XHJcbmU7ZCsrKWlmKGQlNCl7dmFyIGc9Zi5pbmRleE9mKGIuY2hhckF0KGQtMSkpPDwyKihkJTQpLGg9Zi5pbmRleE9mKGIuY2hhckF0KGQpKT4+PjYtMiooZCU0KTtjW2E+Pj4yXXw9KGd8aCk8PDI0LTgqKGElNCk7YSsrfXJldHVybiBqLmNyZWF0ZShjLGEpfSxfbWFwOlwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz1cIn19KSgpO1xyXG5cbi8qXHJcbkNyeXB0b0pTIHYzLjEuMiBzaGEyNTYtbWluLmpzXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xyXG4oYykgMjAwOS0yMDEzIGJ5IEplZmYgTW90dC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL3dpa2kvTGljZW5zZVxyXG4qL1xyXG4oZnVuY3Rpb24oayl7Zm9yKHZhciBnPUNyeXB0b0pTLGg9Zy5saWIsdj1oLldvcmRBcnJheSxqPWguSGFzaGVyLGg9Zy5hbGdvLHM9W10sdD1bXSx1PWZ1bmN0aW9uKHEpe3JldHVybiA0Mjk0OTY3Mjk2KihxLShxfDApKXwwfSxsPTIsYj0wOzY0PmI7KXt2YXIgZDthOntkPWw7Zm9yKHZhciB3PWsuc3FydChkKSxyPTI7cjw9dztyKyspaWYoIShkJXIpKXtkPSExO2JyZWFrIGF9ZD0hMH1kJiYoOD5iJiYoc1tiXT11KGsucG93KGwsMC41KSkpLHRbYl09dShrLnBvdyhsLDEvMykpLGIrKyk7bCsrfXZhciBuPVtdLGg9aC5TSEEyNTY9ai5leHRlbmQoe19kb1Jlc2V0OmZ1bmN0aW9uKCl7dGhpcy5faGFzaD1uZXcgdi5pbml0KHMuc2xpY2UoMCkpfSxfZG9Qcm9jZXNzQmxvY2s6ZnVuY3Rpb24ocSxoKXtmb3IodmFyIGE9dGhpcy5faGFzaC53b3JkcyxjPWFbMF0sZD1hWzFdLGI9YVsyXSxrPWFbM10sZj1hWzRdLGc9YVs1XSxqPWFbNl0sbD1hWzddLGU9MDs2ND5lO2UrKyl7aWYoMTY+ZSluW2VdPVxyXG5xW2grZV18MDtlbHNle3ZhciBtPW5bZS0xNV0scD1uW2UtMl07bltlXT0oKG08PDI1fG0+Pj43KV4obTw8MTR8bT4+PjE4KV5tPj4+MykrbltlLTddKygocDw8MTV8cD4+PjE3KV4ocDw8MTN8cD4+PjE5KV5wPj4+MTApK25bZS0xNl19bT1sKygoZjw8MjZ8Zj4+PjYpXihmPDwyMXxmPj4+MTEpXihmPDw3fGY+Pj4yNSkpKyhmJmdefmYmaikrdFtlXStuW2VdO3A9KChjPDwzMHxjPj4+MileKGM8PDE5fGM+Pj4xMyleKGM8PDEwfGM+Pj4yMikpKyhjJmReYyZiXmQmYik7bD1qO2o9ZztnPWY7Zj1rK218MDtrPWI7Yj1kO2Q9YztjPW0rcHwwfWFbMF09YVswXStjfDA7YVsxXT1hWzFdK2R8MDthWzJdPWFbMl0rYnwwO2FbM109YVszXStrfDA7YVs0XT1hWzRdK2Z8MDthWzVdPWFbNV0rZ3wwO2FbNl09YVs2XStqfDA7YVs3XT1hWzddK2x8MH0sX2RvRmluYWxpemU6ZnVuY3Rpb24oKXt2YXIgZD10aGlzLl9kYXRhLGI9ZC53b3JkcyxhPTgqdGhpcy5fbkRhdGFCeXRlcyxjPTgqZC5zaWdCeXRlcztcclxuYltjPj4+NV18PTEyODw8MjQtYyUzMjtiWyhjKzY0Pj4+OTw8NCkrMTRdPWsuZmxvb3IoYS80Mjk0OTY3Mjk2KTtiWyhjKzY0Pj4+OTw8NCkrMTVdPWE7ZC5zaWdCeXRlcz00KmIubGVuZ3RoO3RoaXMuX3Byb2Nlc3MoKTtyZXR1cm4gdGhpcy5faGFzaH0sY2xvbmU6ZnVuY3Rpb24oKXt2YXIgYj1qLmNsb25lLmNhbGwodGhpcyk7Yi5faGFzaD10aGlzLl9oYXNoLmNsb25lKCk7cmV0dXJuIGJ9fSk7Zy5TSEEyNTY9ai5fY3JlYXRlSGVscGVyKGgpO2cuSG1hY1NIQTI1Nj1qLl9jcmVhdGVIbWFjSGVscGVyKGgpfSkoTWF0aCk7XHJcblxuLypcclxuQ3J5cHRvSlMgdjMuMS4yIHNoYTUxMi1taW4uanNcclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbihjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiovXHJcbihmdW5jdGlvbigpe2Z1bmN0aW9uIGEoKXtyZXR1cm4gZC5jcmVhdGUuYXBwbHkoZCxhcmd1bWVudHMpfWZvcih2YXIgbj1DcnlwdG9KUyxyPW4ubGliLkhhc2hlcixlPW4ueDY0LGQ9ZS5Xb3JkLFQ9ZS5Xb3JkQXJyYXksZT1uLmFsZ28sZWE9W2EoMTExNjM1MjQwOCwzNjA5NzY3NDU4KSxhKDE4OTk0NDc0NDEsNjAyODkxNzI1KSxhKDMwNDkzMjM0NzEsMzk2NDQ4NDM5OSksYSgzOTIxMDA5NTczLDIxNzMyOTU1NDgpLGEoOTYxOTg3MTYzLDQwODE2Mjg0NzIpLGEoMTUwODk3MDk5MywzMDUzODM0MjY1KSxhKDI0NTM2MzU3NDgsMjkzNzY3MTU3OSksYSgyODcwNzYzMjIxLDM2NjQ2MDk1NjApLGEoMzYyNDM4MTA4MCwyNzM0ODgzMzk0KSxhKDMxMDU5ODQwMSwxMTY0OTk2NTQyKSxhKDYwNzIyNTI3OCwxMzIzNjEwNzY0KSxhKDE0MjY4ODE5ODcsMzU5MDMwNDk5NCksYSgxOTI1MDc4Mzg4LDQwNjgxODIzODMpLGEoMjE2MjA3ODIwNiw5OTEzMzYxMTMpLGEoMjYxNDg4ODEwMyw2MzM4MDMzMTcpLFxyXG5hKDMyNDgyMjI1ODAsMzQ3OTc3NDg2OCksYSgzODM1MzkwNDAxLDI2NjY2MTM0NTgpLGEoNDAyMjIyNDc3NCw5NDQ3MTExMzkpLGEoMjY0MzQ3MDc4LDIzNDEyNjI3NzMpLGEoNjA0ODA3NjI4LDIwMDc4MDA5MzMpLGEoNzcwMjU1OTgzLDE0OTU5OTA5MDEpLGEoMTI0OTE1MDEyMiwxODU2NDMxMjM1KSxhKDE1NTUwODE2OTIsMzE3NTIxODEzMiksYSgxOTk2MDY0OTg2LDIxOTg5NTA4MzcpLGEoMjU1NDIyMDg4MiwzOTk5NzE5MzM5KSxhKDI4MjE4MzQzNDksNzY2Nzg0MDE2KSxhKDI5NTI5OTY4MDgsMjU2NjU5NDg3OSksYSgzMjEwMzEzNjcxLDMyMDMzMzc5NTYpLGEoMzMzNjU3MTg5MSwxMDM0NDU3MDI2KSxhKDM1ODQ1Mjg3MTEsMjQ2Njk0ODkwMSksYSgxMTM5MjY5OTMsMzc1ODMyNjM4MyksYSgzMzgyNDE4OTUsMTY4NzE3OTM2KSxhKDY2NjMwNzIwNSwxMTg4MTc5OTY0KSxhKDc3MzUyOTkxMiwxNTQ2MDQ1NzM0KSxhKDEyOTQ3NTczNzIsMTUyMjgwNTQ4NSksYSgxMzk2MTgyMjkxLFxyXG4yNjQzODMzODIzKSxhKDE2OTUxODM3MDAsMjM0MzUyNzM5MCksYSgxOTg2NjYxMDUxLDEwMTQ0Nzc0ODApLGEoMjE3NzAyNjM1MCwxMjA2NzU5MTQyKSxhKDI0NTY5NTYwMzcsMzQ0MDc3NjI3KSxhKDI3MzA0ODU5MjEsMTI5MDg2MzQ2MCksYSgyODIwMzAyNDExLDMxNTg0NTQyNzMpLGEoMzI1OTczMDgwMCwzNTA1OTUyNjU3KSxhKDMzNDU3NjQ3NzEsMTA2MjE3MDA4KSxhKDM1MTYwNjU4MTcsMzYwNjAwODM0NCksYSgzNjAwMzUyODA0LDE0MzI3MjU3NzYpLGEoNDA5NDU3MTkwOSwxNDY3MDMxNTk0KSxhKDI3NTQyMzM0NCw4NTExNjk3MjApLGEoNDMwMjI3NzM0LDMxMDA4MjM3NTIpLGEoNTA2OTQ4NjE2LDEzNjMyNTgxOTUpLGEoNjU5MDYwNTU2LDM3NTA2ODU1OTMpLGEoODgzOTk3ODc3LDM3ODUwNTAyODApLGEoOTU4MTM5NTcxLDMzMTgzMDc0MjcpLGEoMTMyMjgyMjIxOCwzODEyNzIzNDAzKSxhKDE1MzcwMDIwNjMsMjAwMzAzNDk5NSksYSgxNzQ3ODczNzc5LDM2MDIwMzY4OTkpLFxyXG5hKDE5NTU1NjIyMjIsMTU3NTk5MDAxMiksYSgyMDI0MTA0ODE1LDExMjU1OTI5MjgpLGEoMjIyNzczMDQ1MiwyNzE2OTA0MzA2KSxhKDIzNjE4NTI0MjQsNDQyNzc2MDQ0KSxhKDI0Mjg0MzY0NzQsNTkzNjk4MzQ0KSxhKDI3NTY3MzQxODcsMzczMzExMDI0OSksYSgzMjA0MDMxNDc5LDI5OTkzNTE1NzMpLGEoMzMyOTMyNTI5OCwzODE1OTIwNDI3KSxhKDMzOTE1Njk2MTQsMzkyODM4MzkwMCksYSgzNTE1MjY3MjcxLDU2NjI4MDcxMSksYSgzOTQwMTg3NjA2LDM0NTQwNjk1MzQpLGEoNDExODYzMDI3MSw0MDAwMjM5OTkyKSxhKDExNjQxODQ3NCwxOTE0MTM4NTU0KSxhKDE3NDI5MjQyMSwyNzMxMDU1MjcwKSxhKDI4OTM4MDM1NiwzMjAzOTkzMDA2KSxhKDQ2MDM5MzI2OSwzMjA2MjAzMTUpLGEoNjg1NDcxNzMzLDU4NzQ5NjgzNiksYSg4NTIxNDI5NzEsMTA4Njc5Mjg1MSksYSgxMDE3MDM2Mjk4LDM2NTU0MzEwMCksYSgxMTI2MDAwNTgwLDI2MTgyOTc2NzYpLGEoMTI4ODAzMzQ3MCxcclxuMzQwOTg1NTE1OCksYSgxNTAxNTA1OTQ4LDQyMzQ1MDk4NjYpLGEoMTYwNzE2NzkxNSw5ODcxNjc0NjgpLGEoMTgxNjQwMjMxNiwxMjQ2MTg5NTkxKV0sdj1bXSx3PTA7ODA+dzt3Kyspdlt3XT1hKCk7ZT1lLlNIQTUxMj1yLmV4dGVuZCh7X2RvUmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLl9oYXNoPW5ldyBULmluaXQoW25ldyBkLmluaXQoMTc3OTAzMzcwMyw0MDg5MjM1NzIwKSxuZXcgZC5pbml0KDMxNDQxMzQyNzcsMjIyNzg3MzU5NSksbmV3IGQuaW5pdCgxMDEzOTA0MjQyLDQyNzExNzU3MjMpLG5ldyBkLmluaXQoMjc3MzQ4MDc2MiwxNTk1NzUwMTI5KSxuZXcgZC5pbml0KDEzNTk4OTMxMTksMjkxNzU2NTEzNyksbmV3IGQuaW5pdCgyNjAwODIyOTI0LDcyNTUxMTE5OSksbmV3IGQuaW5pdCg1Mjg3MzQ2MzUsNDIxNTM4OTU0NyksbmV3IGQuaW5pdCgxNTQxNDU5MjI1LDMyNzAzMzIwOSldKX0sX2RvUHJvY2Vzc0Jsb2NrOmZ1bmN0aW9uKGEsZCl7Zm9yKHZhciBmPXRoaXMuX2hhc2gud29yZHMsXHJcbkY9ZlswXSxlPWZbMV0sbj1mWzJdLHI9ZlszXSxHPWZbNF0sSD1mWzVdLEk9Zls2XSxmPWZbN10sdz1GLmhpZ2gsSj1GLmxvdyxYPWUuaGlnaCxLPWUubG93LFk9bi5oaWdoLEw9bi5sb3csWj1yLmhpZ2gsTT1yLmxvdywkPUcuaGlnaCxOPUcubG93LGFhPUguaGlnaCxPPUgubG93LGJhPUkuaGlnaCxQPUkubG93LGNhPWYuaGlnaCxRPWYubG93LGs9dyxnPUosej1YLHg9SyxBPVkseT1MLFU9WixCPU0sbD0kLGg9TixSPWFhLEM9TyxTPWJhLEQ9UCxWPWNhLEU9USxtPTA7ODA+bTttKyspe3ZhciBzPXZbbV07aWYoMTY+bSl2YXIgaj1zLmhpZ2g9YVtkKzIqbV18MCxiPXMubG93PWFbZCsyKm0rMV18MDtlbHNle3ZhciBqPXZbbS0xNV0sYj1qLmhpZ2gscD1qLmxvdyxqPShiPj4+MXxwPDwzMSleKGI+Pj44fHA8PDI0KV5iPj4+NyxwPShwPj4+MXxiPDwzMSleKHA+Pj44fGI8PDI0KV4ocD4+Pjd8Yjw8MjUpLHU9dlttLTJdLGI9dS5oaWdoLGM9dS5sb3csdT0oYj4+PjE5fGM8PDEzKV4oYjw8XHJcbjN8Yz4+PjI5KV5iPj4+NixjPShjPj4+MTl8Yjw8MTMpXihjPDwzfGI+Pj4yOSleKGM+Pj42fGI8PDI2KSxiPXZbbS03XSxXPWIuaGlnaCx0PXZbbS0xNl0scT10LmhpZ2gsdD10LmxvdyxiPXArYi5sb3csaj1qK1crKGI+Pj4wPHA+Pj4wPzE6MCksYj1iK2Msaj1qK3UrKGI+Pj4wPGM+Pj4wPzE6MCksYj1iK3Qsaj1qK3ErKGI+Pj4wPHQ+Pj4wPzE6MCk7cy5oaWdoPWo7cy5sb3c9Yn12YXIgVz1sJlJefmwmUyx0PWgmQ15+aCZELHM9ayZ6XmsmQV56JkEsVD1nJnheZyZ5XngmeSxwPShrPj4+Mjh8Zzw8NCleKGs8PDMwfGc+Pj4yKV4oazw8MjV8Zz4+PjcpLHU9KGc+Pj4yOHxrPDw0KV4oZzw8MzB8az4+PjIpXihnPDwyNXxrPj4+NyksYz1lYVttXSxmYT1jLmhpZ2gsZGE9Yy5sb3csYz1FKygoaD4+PjE0fGw8PDE4KV4oaD4+PjE4fGw8PDE0KV4oaDw8MjN8bD4+PjkpKSxxPVYrKChsPj4+MTR8aDw8MTgpXihsPj4+MTh8aDw8MTQpXihsPDwyM3xoPj4+OSkpKyhjPj4+MDxFPj4+MD8xOlxyXG4wKSxjPWMrdCxxPXErVysoYz4+PjA8dD4+PjA/MTowKSxjPWMrZGEscT1xK2ZhKyhjPj4+MDxkYT4+PjA/MTowKSxjPWMrYixxPXEraisoYz4+PjA8Yj4+PjA/MTowKSxiPXUrVCxzPXArcysoYj4+PjA8dT4+PjA/MTowKSxWPVMsRT1ELFM9UixEPUMsUj1sLEM9aCxoPUIrY3wwLGw9VStxKyhoPj4+MDxCPj4+MD8xOjApfDAsVT1BLEI9eSxBPXoseT14LHo9ayx4PWcsZz1jK2J8MCxrPXErcysoZz4+PjA8Yz4+PjA/MTowKXwwfUo9Ri5sb3c9SitnO0YuaGlnaD13K2srKEo+Pj4wPGc+Pj4wPzE6MCk7Sz1lLmxvdz1LK3g7ZS5oaWdoPVgreisoSz4+PjA8eD4+PjA/MTowKTtMPW4ubG93PUwreTtuLmhpZ2g9WStBKyhMPj4+MDx5Pj4+MD8xOjApO009ci5sb3c9TStCO3IuaGlnaD1aK1UrKE0+Pj4wPEI+Pj4wPzE6MCk7Tj1HLmxvdz1OK2g7Ry5oaWdoPSQrbCsoTj4+PjA8aD4+PjA/MTowKTtPPUgubG93PU8rQztILmhpZ2g9YWErUisoTz4+PjA8Qz4+PjA/MTowKTtQPUkubG93PVArRDtcclxuSS5oaWdoPWJhK1MrKFA+Pj4wPEQ+Pj4wPzE6MCk7UT1mLmxvdz1RK0U7Zi5oaWdoPWNhK1YrKFE+Pj4wPEU+Pj4wPzE6MCl9LF9kb0ZpbmFsaXplOmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5fZGF0YSxkPWEud29yZHMsZj04KnRoaXMuX25EYXRhQnl0ZXMsZT04KmEuc2lnQnl0ZXM7ZFtlPj4+NV18PTEyODw8MjQtZSUzMjtkWyhlKzEyOD4+PjEwPDw1KSszMF09TWF0aC5mbG9vcihmLzQyOTQ5NjcyOTYpO2RbKGUrMTI4Pj4+MTA8PDUpKzMxXT1mO2Euc2lnQnl0ZXM9NCpkLmxlbmd0aDt0aGlzLl9wcm9jZXNzKCk7cmV0dXJuIHRoaXMuX2hhc2gudG9YMzIoKX0sY2xvbmU6ZnVuY3Rpb24oKXt2YXIgYT1yLmNsb25lLmNhbGwodGhpcyk7YS5faGFzaD10aGlzLl9oYXNoLmNsb25lKCk7cmV0dXJuIGF9LGJsb2NrU2l6ZTozMn0pO24uU0hBNTEyPXIuX2NyZWF0ZUhlbHBlcihlKTtuLkhtYWNTSEE1MTI9ci5fY3JlYXRlSG1hY0hlbHBlcihlKX0pKCk7XHJcblxuLypcclxuQ3J5cHRvSlMgdjMuMS4yIHNoYTM4NC1taW4uanNcclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbihjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiovXHJcbihmdW5jdGlvbigpe3ZhciBjPUNyeXB0b0pTLGE9Yy54NjQsYj1hLldvcmQsZT1hLldvcmRBcnJheSxhPWMuYWxnbyxkPWEuU0hBNTEyLGE9YS5TSEEzODQ9ZC5leHRlbmQoe19kb1Jlc2V0OmZ1bmN0aW9uKCl7dGhpcy5faGFzaD1uZXcgZS5pbml0KFtuZXcgYi5pbml0KDM0MTgwNzAzNjUsMzIzODM3MTAzMiksbmV3IGIuaW5pdCgxNjU0MjcwMjUwLDkxNDE1MDY2MyksbmV3IGIuaW5pdCgyNDM4NTI5MzcwLDgxMjcwMjk5OSksbmV3IGIuaW5pdCgzNTU0NjIzNjAsNDE0NDkxMjY5NyksbmV3IGIuaW5pdCgxNzMxNDA1NDE1LDQyOTA3NzU4NTcpLG5ldyBiLmluaXQoMjM5NDE4MDIzMSwxNzUwNjAzMDI1KSxuZXcgYi5pbml0KDM2NzUwMDg1MjUsMTY5NDA3NjgzOSksbmV3IGIuaW5pdCgxMjAzMDYyODEzLDMyMDQwNzU0MjgpXSl9LF9kb0ZpbmFsaXplOmZ1bmN0aW9uKCl7dmFyIGE9ZC5fZG9GaW5hbGl6ZS5jYWxsKHRoaXMpO2Euc2lnQnl0ZXMtPTE2O3JldHVybiBhfX0pO2MuU0hBMzg0PVxyXG5kLl9jcmVhdGVIZWxwZXIoYSk7Yy5IbWFjU0hBMzg0PWQuX2NyZWF0ZUhtYWNIZWxwZXIoYSl9KSgpO1xyXG5cbi8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xyXG4gKi9cclxudmFyIGI2NG1hcD1cIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky9cIjt2YXIgYjY0cGFkPVwiPVwiO2Z1bmN0aW9uIGhleDJiNjQoZCl7dmFyIGI7dmFyIGU7dmFyIGE9XCJcIjtmb3IoYj0wO2IrMzw9ZC5sZW5ndGg7Yis9Myl7ZT1wYXJzZUludChkLnN1YnN0cmluZyhiLGIrMyksMTYpO2ErPWI2NG1hcC5jaGFyQXQoZT4+NikrYjY0bWFwLmNoYXJBdChlJjYzKX1pZihiKzE9PWQubGVuZ3RoKXtlPXBhcnNlSW50KGQuc3Vic3RyaW5nKGIsYisxKSwxNik7YSs9YjY0bWFwLmNoYXJBdChlPDwyKX1lbHNle2lmKGIrMj09ZC5sZW5ndGgpe2U9cGFyc2VJbnQoZC5zdWJzdHJpbmcoYixiKzIpLDE2KTthKz1iNjRtYXAuY2hhckF0KGU+PjIpK2I2NG1hcC5jaGFyQXQoKGUmMyk8PDQpfX1pZihiNjRwYWQpe3doaWxlKChhLmxlbmd0aCYzKT4wKXthKz1iNjRwYWR9fXJldHVybiBhfWZ1bmN0aW9uIGI2NHRvaGV4KGYpe3ZhciBkPVwiXCI7dmFyIGU7dmFyIGI9MDt2YXIgYzt2YXIgYTtmb3IoZT0wO2U8Zi5sZW5ndGg7KytlKXtpZihmLmNoYXJBdChlKT09YjY0cGFkKXticmVha31hPWI2NG1hcC5pbmRleE9mKGYuY2hhckF0KGUpKTtpZihhPDApe2NvbnRpbnVlfWlmKGI9PTApe2QrPWludDJjaGFyKGE+PjIpO2M9YSYzO2I9MX1lbHNle2lmKGI9PTEpe2QrPWludDJjaGFyKChjPDwyKXwoYT4+NCkpO2M9YSYxNTtiPTJ9ZWxzZXtpZihiPT0yKXtkKz1pbnQyY2hhcihjKTtkKz1pbnQyY2hhcihhPj4yKTtjPWEmMztiPTN9ZWxzZXtkKz1pbnQyY2hhcigoYzw8Mil8KGE+PjQpKTtkKz1pbnQyY2hhcihhJjE1KTtiPTB9fX19aWYoYj09MSl7ZCs9aW50MmNoYXIoYzw8Mil9cmV0dXJuIGR9ZnVuY3Rpb24gYjY0dG9CQShlKXt2YXIgZD1iNjR0b2hleChlKTt2YXIgYzt2YXIgYj1uZXcgQXJyYXkoKTtmb3IoYz0wOzIqYzxkLmxlbmd0aDsrK2Mpe2JbY109cGFyc2VJbnQoZC5zdWJzdHJpbmcoMipjLDIqYysyKSwxNil9cmV0dXJuIGJ9O1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG52YXIgZGJpdHM7dmFyIGNhbmFyeT0yNDQ4Mzc4MTQwOTQ1OTA7dmFyIGpfbG09KChjYW5hcnkmMTY3NzcyMTUpPT0xNTcxNTA3MCk7ZnVuY3Rpb24gQmlnSW50ZWdlcihlLGQsZil7aWYoZSE9bnVsbCl7aWYoXCJudW1iZXJcIj09dHlwZW9mIGUpe3RoaXMuZnJvbU51bWJlcihlLGQsZil9ZWxzZXtpZihkPT1udWxsJiZcInN0cmluZ1wiIT10eXBlb2YgZSl7dGhpcy5mcm9tU3RyaW5nKGUsMjU2KX1lbHNle3RoaXMuZnJvbVN0cmluZyhlLGQpfX19fWZ1bmN0aW9uIG5iaSgpe3JldHVybiBuZXcgQmlnSW50ZWdlcihudWxsKX1mdW5jdGlvbiBhbTEoZixhLGIsZSxoLGcpe3doaWxlKC0tZz49MCl7dmFyIGQ9YSp0aGlzW2YrK10rYltlXStoO2g9TWF0aC5mbG9vcihkLzY3MTA4ODY0KTtiW2UrK109ZCY2NzEwODg2M31yZXR1cm4gaH1mdW5jdGlvbiBhbTIoZixxLHIsZSxvLGEpe3ZhciBrPXEmMzI3NjcscD1xPj4xNTt3aGlsZSgtLWE+PTApe3ZhciBkPXRoaXNbZl0mMzI3Njc7dmFyIGc9dGhpc1tmKytdPj4xNTt2YXIgYj1wKmQrZyprO2Q9aypkKygoYiYzMjc2Nyk8PDE1KStyW2VdKyhvJjEwNzM3NDE4MjMpO289KGQ+Pj4zMCkrKGI+Pj4xNSkrcCpnKyhvPj4+MzApO3JbZSsrXT1kJjEwNzM3NDE4MjN9cmV0dXJuIG99ZnVuY3Rpb24gYW0zKGYscSxyLGUsbyxhKXt2YXIgaz1xJjE2MzgzLHA9cT4+MTQ7d2hpbGUoLS1hPj0wKXt2YXIgZD10aGlzW2ZdJjE2MzgzO3ZhciBnPXRoaXNbZisrXT4+MTQ7dmFyIGI9cCpkK2cqaztkPWsqZCsoKGImMTYzODMpPDwxNCkrcltlXStvO289KGQ+PjI4KSsoYj4+MTQpK3AqZztyW2UrK109ZCYyNjg0MzU0NTV9cmV0dXJuIG99aWYoal9sbSYmKG5hdmlnYXRvci5hcHBOYW1lPT1cIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiKSl7QmlnSW50ZWdlci5wcm90b3R5cGUuYW09YW0yO2RiaXRzPTMwfWVsc2V7aWYoal9sbSYmKG5hdmlnYXRvci5hcHBOYW1lIT1cIk5ldHNjYXBlXCIpKXtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbT1hbTE7ZGJpdHM9MjZ9ZWxzZXtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbT1hbTM7ZGJpdHM9Mjh9fUJpZ0ludGVnZXIucHJvdG90eXBlLkRCPWRiaXRzO0JpZ0ludGVnZXIucHJvdG90eXBlLkRNPSgoMTw8ZGJpdHMpLTEpO0JpZ0ludGVnZXIucHJvdG90eXBlLkRWPSgxPDxkYml0cyk7dmFyIEJJX0ZQPTUyO0JpZ0ludGVnZXIucHJvdG90eXBlLkZWPU1hdGgucG93KDIsQklfRlApO0JpZ0ludGVnZXIucHJvdG90eXBlLkYxPUJJX0ZQLWRiaXRzO0JpZ0ludGVnZXIucHJvdG90eXBlLkYyPTIqZGJpdHMtQklfRlA7dmFyIEJJX1JNPVwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCI7dmFyIEJJX1JDPW5ldyBBcnJheSgpO3ZhciBycix2djtycj1cIjBcIi5jaGFyQ29kZUF0KDApO2Zvcih2dj0wO3Z2PD05OysrdnYpe0JJX1JDW3JyKytdPXZ2fXJyPVwiYVwiLmNoYXJDb2RlQXQoMCk7Zm9yKHZ2PTEwO3Z2PDM2OysrdnYpe0JJX1JDW3JyKytdPXZ2fXJyPVwiQVwiLmNoYXJDb2RlQXQoMCk7Zm9yKHZ2PTEwO3Z2PDM2OysrdnYpe0JJX1JDW3JyKytdPXZ2fWZ1bmN0aW9uIGludDJjaGFyKGEpe3JldHVybiBCSV9STS5jaGFyQXQoYSl9ZnVuY3Rpb24gaW50QXQoYixhKXt2YXIgZD1CSV9SQ1tiLmNoYXJDb2RlQXQoYSldO3JldHVybihkPT1udWxsKT8tMTpkfWZ1bmN0aW9uIGJucENvcHlUbyhiKXtmb3IodmFyIGE9dGhpcy50LTE7YT49MDstLWEpe2JbYV09dGhpc1thXX1iLnQ9dGhpcy50O2Iucz10aGlzLnN9ZnVuY3Rpb24gYm5wRnJvbUludChhKXt0aGlzLnQ9MTt0aGlzLnM9KGE8MCk/LTE6MDtpZihhPjApe3RoaXNbMF09YX1lbHNle2lmKGE8LTEpe3RoaXNbMF09YSt0aGlzLkRWfWVsc2V7dGhpcy50PTB9fX1mdW5jdGlvbiBuYnYoYSl7dmFyIGI9bmJpKCk7Yi5mcm9tSW50KGEpO3JldHVybiBifWZ1bmN0aW9uIGJucEZyb21TdHJpbmcoaCxjKXt2YXIgZTtpZihjPT0xNil7ZT00fWVsc2V7aWYoYz09OCl7ZT0zfWVsc2V7aWYoYz09MjU2KXtlPTh9ZWxzZXtpZihjPT0yKXtlPTF9ZWxzZXtpZihjPT0zMil7ZT01fWVsc2V7aWYoYz09NCl7ZT0yfWVsc2V7dGhpcy5mcm9tUmFkaXgoaCxjKTtyZXR1cm59fX19fX10aGlzLnQ9MDt0aGlzLnM9MDt2YXIgZz1oLmxlbmd0aCxkPWZhbHNlLGY9MDt3aGlsZSgtLWc+PTApe3ZhciBhPShlPT04KT9oW2ddJjI1NTppbnRBdChoLGcpO2lmKGE8MCl7aWYoaC5jaGFyQXQoZyk9PVwiLVwiKXtkPXRydWV9Y29udGludWV9ZD1mYWxzZTtpZihmPT0wKXt0aGlzW3RoaXMudCsrXT1hfWVsc2V7aWYoZitlPnRoaXMuREIpe3RoaXNbdGhpcy50LTFdfD0oYSYoKDE8PCh0aGlzLkRCLWYpKS0xKSk8PGY7dGhpc1t0aGlzLnQrK109KGE+Pih0aGlzLkRCLWYpKX1lbHNle3RoaXNbdGhpcy50LTFdfD1hPDxmfX1mKz1lO2lmKGY+PXRoaXMuREIpe2YtPXRoaXMuREJ9fWlmKGU9PTgmJihoWzBdJjEyOCkhPTApe3RoaXMucz0tMTtpZihmPjApe3RoaXNbdGhpcy50LTFdfD0oKDE8PCh0aGlzLkRCLWYpKS0xKTw8Zn19dGhpcy5jbGFtcCgpO2lmKGQpe0JpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpfX1mdW5jdGlvbiBibnBDbGFtcCgpe3ZhciBhPXRoaXMucyZ0aGlzLkRNO3doaWxlKHRoaXMudD4wJiZ0aGlzW3RoaXMudC0xXT09YSl7LS10aGlzLnR9fWZ1bmN0aW9uIGJuVG9TdHJpbmcoYyl7aWYodGhpcy5zPDApe3JldHVyblwiLVwiK3RoaXMubmVnYXRlKCkudG9TdHJpbmcoYyl9dmFyIGU7aWYoYz09MTYpe2U9NH1lbHNle2lmKGM9PTgpe2U9M31lbHNle2lmKGM9PTIpe2U9MX1lbHNle2lmKGM9PTMyKXtlPTV9ZWxzZXtpZihjPT00KXtlPTJ9ZWxzZXtyZXR1cm4gdGhpcy50b1JhZGl4KGMpfX19fX12YXIgZz0oMTw8ZSktMSxsLGE9ZmFsc2UsaD1cIlwiLGY9dGhpcy50O3ZhciBqPXRoaXMuREItKGYqdGhpcy5EQiklZTtpZihmLS0+MCl7aWYoajx0aGlzLkRCJiYobD10aGlzW2ZdPj5qKT4wKXthPXRydWU7aD1pbnQyY2hhcihsKX13aGlsZShmPj0wKXtpZihqPGUpe2w9KHRoaXNbZl0mKCgxPDxqKS0xKSk8PChlLWopO2x8PXRoaXNbLS1mXT4+KGorPXRoaXMuREItZSl9ZWxzZXtsPSh0aGlzW2ZdPj4oai09ZSkpJmc7aWYoajw9MCl7ais9dGhpcy5EQjstLWZ9fWlmKGw+MCl7YT10cnVlfWlmKGEpe2grPWludDJjaGFyKGwpfX19cmV0dXJuIGE/aDpcIjBcIn1mdW5jdGlvbiBibk5lZ2F0ZSgpe3ZhciBhPW5iaSgpO0JpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLGEpO3JldHVybiBhfWZ1bmN0aW9uIGJuQWJzKCl7cmV0dXJuKHRoaXMuczwwKT90aGlzLm5lZ2F0ZSgpOnRoaXN9ZnVuY3Rpb24gYm5Db21wYXJlVG8oYil7dmFyIGQ9dGhpcy5zLWIucztpZihkIT0wKXtyZXR1cm4gZH12YXIgYz10aGlzLnQ7ZD1jLWIudDtpZihkIT0wKXtyZXR1cm4odGhpcy5zPDApPy1kOmR9d2hpbGUoLS1jPj0wKXtpZigoZD10aGlzW2NdLWJbY10pIT0wKXtyZXR1cm4gZH19cmV0dXJuIDB9ZnVuY3Rpb24gbmJpdHMoYSl7dmFyIGM9MSxiO2lmKChiPWE+Pj4xNikhPTApe2E9YjtjKz0xNn1pZigoYj1hPj44KSE9MCl7YT1iO2MrPTh9aWYoKGI9YT4+NCkhPTApe2E9YjtjKz00fWlmKChiPWE+PjIpIT0wKXthPWI7Yys9Mn1pZigoYj1hPj4xKSE9MCl7YT1iO2MrPTF9cmV0dXJuIGN9ZnVuY3Rpb24gYm5CaXRMZW5ndGgoKXtpZih0aGlzLnQ8PTApe3JldHVybiAwfXJldHVybiB0aGlzLkRCKih0aGlzLnQtMSkrbmJpdHModGhpc1t0aGlzLnQtMV1eKHRoaXMucyZ0aGlzLkRNKSl9ZnVuY3Rpb24gYm5wRExTaGlmdFRvKGMsYil7dmFyIGE7Zm9yKGE9dGhpcy50LTE7YT49MDstLWEpe2JbYStjXT10aGlzW2FdfWZvcihhPWMtMTthPj0wOy0tYSl7YlthXT0wfWIudD10aGlzLnQrYztiLnM9dGhpcy5zfWZ1bmN0aW9uIGJucERSU2hpZnRUbyhjLGIpe2Zvcih2YXIgYT1jO2E8dGhpcy50OysrYSl7YlthLWNdPXRoaXNbYV19Yi50PU1hdGgubWF4KHRoaXMudC1jLDApO2Iucz10aGlzLnN9ZnVuY3Rpb24gYm5wTFNoaWZ0VG8oaixlKXt2YXIgYj1qJXRoaXMuREI7dmFyIGE9dGhpcy5EQi1iO3ZhciBnPSgxPDxhKS0xO3ZhciBmPU1hdGguZmxvb3Ioai90aGlzLkRCKSxoPSh0aGlzLnM8PGIpJnRoaXMuRE0sZDtmb3IoZD10aGlzLnQtMTtkPj0wOy0tZCl7ZVtkK2YrMV09KHRoaXNbZF0+PmEpfGg7aD0odGhpc1tkXSZnKTw8Yn1mb3IoZD1mLTE7ZD49MDstLWQpe2VbZF09MH1lW2ZdPWg7ZS50PXRoaXMudCtmKzE7ZS5zPXRoaXMucztlLmNsYW1wKCl9ZnVuY3Rpb24gYm5wUlNoaWZ0VG8oZyxkKXtkLnM9dGhpcy5zO3ZhciBlPU1hdGguZmxvb3IoZy90aGlzLkRCKTtpZihlPj10aGlzLnQpe2QudD0wO3JldHVybn12YXIgYj1nJXRoaXMuREI7dmFyIGE9dGhpcy5EQi1iO3ZhciBmPSgxPDxiKS0xO2RbMF09dGhpc1tlXT4+Yjtmb3IodmFyIGM9ZSsxO2M8dGhpcy50OysrYyl7ZFtjLWUtMV18PSh0aGlzW2NdJmYpPDxhO2RbYy1lXT10aGlzW2NdPj5ifWlmKGI+MCl7ZFt0aGlzLnQtZS0xXXw9KHRoaXMucyZmKTw8YX1kLnQ9dGhpcy50LWU7ZC5jbGFtcCgpfWZ1bmN0aW9uIGJucFN1YlRvKGQsZil7dmFyIGU9MCxnPTAsYj1NYXRoLm1pbihkLnQsdGhpcy50KTt3aGlsZShlPGIpe2crPXRoaXNbZV0tZFtlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWlmKGQudDx0aGlzLnQpe2ctPWQuczt3aGlsZShlPHRoaXMudCl7Zys9dGhpc1tlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWcrPXRoaXMuc31lbHNle2crPXRoaXMuczt3aGlsZShlPGQudCl7Zy09ZFtlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWctPWQuc31mLnM9KGc8MCk/LTE6MDtpZihnPC0xKXtmW2UrK109dGhpcy5EVitnfWVsc2V7aWYoZz4wKXtmW2UrK109Z319Zi50PWU7Zi5jbGFtcCgpfWZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYyxlKXt2YXIgYj10aGlzLmFicygpLGY9Yy5hYnMoKTt2YXIgZD1iLnQ7ZS50PWQrZi50O3doaWxlKC0tZD49MCl7ZVtkXT0wfWZvcihkPTA7ZDxmLnQ7KytkKXtlW2QrYi50XT1iLmFtKDAsZltkXSxlLGQsMCxiLnQpfWUucz0wO2UuY2xhbXAoKTtpZih0aGlzLnMhPWMucyl7QmlnSW50ZWdlci5aRVJPLnN1YlRvKGUsZSl9fWZ1bmN0aW9uIGJucFNxdWFyZVRvKGQpe3ZhciBhPXRoaXMuYWJzKCk7dmFyIGI9ZC50PTIqYS50O3doaWxlKC0tYj49MCl7ZFtiXT0wfWZvcihiPTA7YjxhLnQtMTsrK2Ipe3ZhciBlPWEuYW0oYixhW2JdLGQsMipiLDAsMSk7aWYoKGRbYithLnRdKz1hLmFtKGIrMSwyKmFbYl0sZCwyKmIrMSxlLGEudC1iLTEpKT49YS5EVil7ZFtiK2EudF0tPWEuRFY7ZFtiK2EudCsxXT0xfX1pZihkLnQ+MCl7ZFtkLnQtMV0rPWEuYW0oYixhW2JdLGQsMipiLDAsMSl9ZC5zPTA7ZC5jbGFtcCgpfWZ1bmN0aW9uIGJucERpdlJlbVRvKG4saCxnKXt2YXIgdz1uLmFicygpO2lmKHcudDw9MCl7cmV0dXJufXZhciBrPXRoaXMuYWJzKCk7aWYoay50PHcudCl7aWYoaCE9bnVsbCl7aC5mcm9tSW50KDApfWlmKGchPW51bGwpe3RoaXMuY29weVRvKGcpfXJldHVybn1pZihnPT1udWxsKXtnPW5iaSgpfXZhciBkPW5iaSgpLGE9dGhpcy5zLGw9bi5zO3ZhciB2PXRoaXMuREItbmJpdHMod1t3LnQtMV0pO2lmKHY+MCl7dy5sU2hpZnRUbyh2LGQpO2subFNoaWZ0VG8odixnKX1lbHNle3cuY29weVRvKGQpO2suY29weVRvKGcpfXZhciBwPWQudDt2YXIgYj1kW3AtMV07aWYoYj09MCl7cmV0dXJufXZhciBvPWIqKDE8PHRoaXMuRjEpKygocD4xKT9kW3AtMl0+PnRoaXMuRjI6MCk7dmFyIEE9dGhpcy5GVi9vLHo9KDE8PHRoaXMuRjEpL28seD0xPDx0aGlzLkYyO3ZhciB1PWcudCxzPXUtcCxmPShoPT1udWxsKT9uYmkoKTpoO2QuZGxTaGlmdFRvKHMsZik7aWYoZy5jb21wYXJlVG8oZik+PTApe2dbZy50KytdPTE7Zy5zdWJUbyhmLGcpfUJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyhwLGYpO2Yuc3ViVG8oZCxkKTt3aGlsZShkLnQ8cCl7ZFtkLnQrK109MH13aGlsZSgtLXM+PTApe3ZhciBjPShnWy0tdV09PWIpP3RoaXMuRE06TWF0aC5mbG9vcihnW3VdKkErKGdbdS0xXSt4KSp6KTtpZigoZ1t1XSs9ZC5hbSgwLGMsZyxzLDAscCkpPGMpe2QuZGxTaGlmdFRvKHMsZik7Zy5zdWJUbyhmLGcpO3doaWxlKGdbdV08LS1jKXtnLnN1YlRvKGYsZyl9fX1pZihoIT1udWxsKXtnLmRyU2hpZnRUbyhwLGgpO2lmKGEhPWwpe0JpZ0ludGVnZXIuWkVSTy5zdWJUbyhoLGgpfX1nLnQ9cDtnLmNsYW1wKCk7aWYodj4wKXtnLnJTaGlmdFRvKHYsZyl9aWYoYTwwKXtCaWdJbnRlZ2VyLlpFUk8uc3ViVG8oZyxnKX19ZnVuY3Rpb24gYm5Nb2QoYil7dmFyIGM9bmJpKCk7dGhpcy5hYnMoKS5kaXZSZW1UbyhiLG51bGwsYyk7aWYodGhpcy5zPDAmJmMuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTyk+MCl7Yi5zdWJUbyhjLGMpfXJldHVybiBjfWZ1bmN0aW9uIENsYXNzaWMoYSl7dGhpcy5tPWF9ZnVuY3Rpb24gY0NvbnZlcnQoYSl7aWYoYS5zPDB8fGEuY29tcGFyZVRvKHRoaXMubSk+PTApe3JldHVybiBhLm1vZCh0aGlzLm0pfWVsc2V7cmV0dXJuIGF9fWZ1bmN0aW9uIGNSZXZlcnQoYSl7cmV0dXJuIGF9ZnVuY3Rpb24gY1JlZHVjZShhKXthLmRpdlJlbVRvKHRoaXMubSxudWxsLGEpfWZ1bmN0aW9uIGNNdWxUbyhhLGMsYil7YS5tdWx0aXBseVRvKGMsYik7dGhpcy5yZWR1Y2UoYil9ZnVuY3Rpb24gY1NxclRvKGEsYil7YS5zcXVhcmVUbyhiKTt0aGlzLnJlZHVjZShiKX1DbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0PWNDb252ZXJ0O0NsYXNzaWMucHJvdG90eXBlLnJldmVydD1jUmV2ZXJ0O0NsYXNzaWMucHJvdG90eXBlLnJlZHVjZT1jUmVkdWNlO0NsYXNzaWMucHJvdG90eXBlLm11bFRvPWNNdWxUbztDbGFzc2ljLnByb3RvdHlwZS5zcXJUbz1jU3FyVG87ZnVuY3Rpb24gYm5wSW52RGlnaXQoKXtpZih0aGlzLnQ8MSl7cmV0dXJuIDB9dmFyIGE9dGhpc1swXTtpZigoYSYxKT09MCl7cmV0dXJuIDB9dmFyIGI9YSYzO2I9KGIqKDItKGEmMTUpKmIpKSYxNTtiPShiKigyLShhJjI1NSkqYikpJjI1NTtiPShiKigyLSgoKGEmNjU1MzUpKmIpJjY1NTM1KSkpJjY1NTM1O2I9KGIqKDItYSpiJXRoaXMuRFYpKSV0aGlzLkRWO3JldHVybihiPjApP3RoaXMuRFYtYjotYn1mdW5jdGlvbiBNb250Z29tZXJ5KGEpe3RoaXMubT1hO3RoaXMubXA9YS5pbnZEaWdpdCgpO3RoaXMubXBsPXRoaXMubXAmMzI3Njc7dGhpcy5tcGg9dGhpcy5tcD4+MTU7dGhpcy51bT0oMTw8KGEuREItMTUpKS0xO3RoaXMubXQyPTIqYS50fWZ1bmN0aW9uIG1vbnRDb252ZXJ0KGEpe3ZhciBiPW5iaSgpO2EuYWJzKCkuZGxTaGlmdFRvKHRoaXMubS50LGIpO2IuZGl2UmVtVG8odGhpcy5tLG51bGwsYik7aWYoYS5zPDAmJmIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTyk+MCl7dGhpcy5tLnN1YlRvKGIsYil9cmV0dXJuIGJ9ZnVuY3Rpb24gbW9udFJldmVydChhKXt2YXIgYj1uYmkoKTthLmNvcHlUbyhiKTt0aGlzLnJlZHVjZShiKTtyZXR1cm4gYn1mdW5jdGlvbiBtb250UmVkdWNlKGEpe3doaWxlKGEudDw9dGhpcy5tdDIpe2FbYS50KytdPTB9Zm9yKHZhciBjPTA7Yzx0aGlzLm0udDsrK2Mpe3ZhciBiPWFbY10mMzI3Njc7dmFyIGQ9KGIqdGhpcy5tcGwrKCgoYip0aGlzLm1waCsoYVtjXT4+MTUpKnRoaXMubXBsKSZ0aGlzLnVtKTw8MTUpKSZhLkRNO2I9Yyt0aGlzLm0udDthW2JdKz10aGlzLm0uYW0oMCxkLGEsYywwLHRoaXMubS50KTt3aGlsZShhW2JdPj1hLkRWKXthW2JdLT1hLkRWO2FbKytiXSsrfX1hLmNsYW1wKCk7YS5kclNoaWZ0VG8odGhpcy5tLnQsYSk7aWYoYS5jb21wYXJlVG8odGhpcy5tKT49MCl7YS5zdWJUbyh0aGlzLm0sYSl9fWZ1bmN0aW9uIG1vbnRTcXJUbyhhLGIpe2Euc3F1YXJlVG8oYik7dGhpcy5yZWR1Y2UoYil9ZnVuY3Rpb24gbW9udE11bFRvKGEsYyxiKXthLm11bHRpcGx5VG8oYyxiKTt0aGlzLnJlZHVjZShiKX1Nb250Z29tZXJ5LnByb3RvdHlwZS5jb252ZXJ0PW1vbnRDb252ZXJ0O01vbnRnb21lcnkucHJvdG90eXBlLnJldmVydD1tb250UmV2ZXJ0O01vbnRnb21lcnkucHJvdG90eXBlLnJlZHVjZT1tb250UmVkdWNlO01vbnRnb21lcnkucHJvdG90eXBlLm11bFRvPW1vbnRNdWxUbztNb250Z29tZXJ5LnByb3RvdHlwZS5zcXJUbz1tb250U3FyVG87ZnVuY3Rpb24gYm5wSXNFdmVuKCl7cmV0dXJuKCh0aGlzLnQ+MCk/KHRoaXNbMF0mMSk6dGhpcy5zKT09MH1mdW5jdGlvbiBibnBFeHAoaCxqKXtpZihoPjQyOTQ5NjcyOTV8fGg8MSl7cmV0dXJuIEJpZ0ludGVnZXIuT05FfXZhciBmPW5iaSgpLGE9bmJpKCksZD1qLmNvbnZlcnQodGhpcyksYz1uYml0cyhoKS0xO2QuY29weVRvKGYpO3doaWxlKC0tYz49MCl7ai5zcXJUbyhmLGEpO2lmKChoJigxPDxjKSk+MCl7ai5tdWxUbyhhLGQsZil9ZWxzZXt2YXIgYj1mO2Y9YTthPWJ9fXJldHVybiBqLnJldmVydChmKX1mdW5jdGlvbiBibk1vZFBvd0ludChiLGEpe3ZhciBjO2lmKGI8MjU2fHxhLmlzRXZlbigpKXtjPW5ldyBDbGFzc2ljKGEpfWVsc2V7Yz1uZXcgTW9udGdvbWVyeShhKX1yZXR1cm4gdGhpcy5leHAoYixjKX1CaWdJbnRlZ2VyLnByb3RvdHlwZS5jb3B5VG89Ym5wQ29weVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQ9Ym5wRnJvbUludDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tU3RyaW5nPWJucEZyb21TdHJpbmc7QmlnSW50ZWdlci5wcm90b3R5cGUuY2xhbXA9Ym5wQ2xhbXA7QmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvPWJucERMU2hpZnRUbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5kclNoaWZ0VG89Ym5wRFJTaGlmdFRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmxTaGlmdFRvPWJucExTaGlmdFRvO0JpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvPWJucFJTaGlmdFRvO0JpZ0ludGVnZXIucHJvdG90eXBlLnN1YlRvPWJucFN1YlRvO0JpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VG89Ym5wTXVsdGlwbHlUbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbz1ibnBTcXVhcmVUbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZSZW1Ubz1ibnBEaXZSZW1UbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnZEaWdpdD1ibnBJbnZEaWdpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW49Ym5wSXNFdmVuO0JpZ0ludGVnZXIucHJvdG90eXBlLmV4cD1ibnBFeHA7QmlnSW50ZWdlci5wcm90b3R5cGUudG9TdHJpbmc9Ym5Ub1N0cmluZztCaWdJbnRlZ2VyLnByb3RvdHlwZS5uZWdhdGU9Ym5OZWdhdGU7QmlnSW50ZWdlci5wcm90b3R5cGUuYWJzPWJuQWJzO0JpZ0ludGVnZXIucHJvdG90eXBlLmNvbXBhcmVUbz1ibkNvbXBhcmVUbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRMZW5ndGg9Ym5CaXRMZW5ndGg7QmlnSW50ZWdlci5wcm90b3R5cGUubW9kPWJuTW9kO0JpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvd0ludD1ibk1vZFBvd0ludDtCaWdJbnRlZ2VyLlpFUk89bmJ2KDApO0JpZ0ludGVnZXIuT05FPW5idigxKTtcbi8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xyXG4gKi9cclxuZnVuY3Rpb24gYm5DbG9uZSgpe3ZhciBhPW5iaSgpO3RoaXMuY29weVRvKGEpO3JldHVybiBhfWZ1bmN0aW9uIGJuSW50VmFsdWUoKXtpZih0aGlzLnM8MCl7aWYodGhpcy50PT0xKXtyZXR1cm4gdGhpc1swXS10aGlzLkRWfWVsc2V7aWYodGhpcy50PT0wKXtyZXR1cm4gLTF9fX1lbHNle2lmKHRoaXMudD09MSl7cmV0dXJuIHRoaXNbMF19ZWxzZXtpZih0aGlzLnQ9PTApe3JldHVybiAwfX19cmV0dXJuKCh0aGlzWzFdJigoMTw8KDMyLXRoaXMuREIpKS0xKSk8PHRoaXMuREIpfHRoaXNbMF19ZnVuY3Rpb24gYm5CeXRlVmFsdWUoKXtyZXR1cm4odGhpcy50PT0wKT90aGlzLnM6KHRoaXNbMF08PDI0KT4+MjR9ZnVuY3Rpb24gYm5TaG9ydFZhbHVlKCl7cmV0dXJuKHRoaXMudD09MCk/dGhpcy5zOih0aGlzWzBdPDwxNik+PjE2fWZ1bmN0aW9uIGJucENodW5rU2l6ZShhKXtyZXR1cm4gTWF0aC5mbG9vcihNYXRoLkxOMip0aGlzLkRCL01hdGgubG9nKGEpKX1mdW5jdGlvbiBiblNpZ051bSgpe2lmKHRoaXMuczwwKXtyZXR1cm4gLTF9ZWxzZXtpZih0aGlzLnQ8PTB8fCh0aGlzLnQ9PTEmJnRoaXNbMF08PTApKXtyZXR1cm4gMH1lbHNle3JldHVybiAxfX19ZnVuY3Rpb24gYm5wVG9SYWRpeChjKXtpZihjPT1udWxsKXtjPTEwfWlmKHRoaXMuc2lnbnVtKCk9PTB8fGM8Mnx8Yz4zNil7cmV0dXJuXCIwXCJ9dmFyIGY9dGhpcy5jaHVua1NpemUoYyk7dmFyIGU9TWF0aC5wb3coYyxmKTt2YXIgaT1uYnYoZSksaj1uYmkoKSxoPW5iaSgpLGc9XCJcIjt0aGlzLmRpdlJlbVRvKGksaixoKTt3aGlsZShqLnNpZ251bSgpPjApe2c9KGUraC5pbnRWYWx1ZSgpKS50b1N0cmluZyhjKS5zdWJzdHIoMSkrZztqLmRpdlJlbVRvKGksaixoKX1yZXR1cm4gaC5pbnRWYWx1ZSgpLnRvU3RyaW5nKGMpK2d9ZnVuY3Rpb24gYm5wRnJvbVJhZGl4KG0saCl7dGhpcy5mcm9tSW50KDApO2lmKGg9PW51bGwpe2g9MTB9dmFyIGY9dGhpcy5jaHVua1NpemUoaCk7dmFyIGc9TWF0aC5wb3coaCxmKSxlPWZhbHNlLGE9MCxsPTA7Zm9yKHZhciBjPTA7YzxtLmxlbmd0aDsrK2Mpe3ZhciBrPWludEF0KG0sYyk7aWYoazwwKXtpZihtLmNoYXJBdChjKT09XCItXCImJnRoaXMuc2lnbnVtKCk9PTApe2U9dHJ1ZX1jb250aW51ZX1sPWgqbCtrO2lmKCsrYT49Zil7dGhpcy5kTXVsdGlwbHkoZyk7dGhpcy5kQWRkT2Zmc2V0KGwsMCk7YT0wO2w9MH19aWYoYT4wKXt0aGlzLmRNdWx0aXBseShNYXRoLnBvdyhoLGEpKTt0aGlzLmRBZGRPZmZzZXQobCwwKX1pZihlKXtCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcyx0aGlzKX19ZnVuY3Rpb24gYm5wRnJvbU51bWJlcihmLGUsaCl7aWYoXCJudW1iZXJcIj09dHlwZW9mIGUpe2lmKGY8Mil7dGhpcy5mcm9tSW50KDEpfWVsc2V7dGhpcy5mcm9tTnVtYmVyKGYsaCk7aWYoIXRoaXMudGVzdEJpdChmLTEpKXt0aGlzLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoZi0xKSxvcF9vcix0aGlzKX1pZih0aGlzLmlzRXZlbigpKXt0aGlzLmRBZGRPZmZzZXQoMSwwKX13aGlsZSghdGhpcy5pc1Byb2JhYmxlUHJpbWUoZSkpe3RoaXMuZEFkZE9mZnNldCgyLDApO2lmKHRoaXMuYml0TGVuZ3RoKCk+Zil7dGhpcy5zdWJUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoZi0xKSx0aGlzKX19fX1lbHNle3ZhciBkPW5ldyBBcnJheSgpLGc9ZiY3O2QubGVuZ3RoPShmPj4zKSsxO2UubmV4dEJ5dGVzKGQpO2lmKGc+MCl7ZFswXSY9KCgxPDxnKS0xKX1lbHNle2RbMF09MH10aGlzLmZyb21TdHJpbmcoZCwyNTYpfX1mdW5jdGlvbiBiblRvQnl0ZUFycmF5KCl7dmFyIGI9dGhpcy50LGM9bmV3IEFycmF5KCk7Y1swXT10aGlzLnM7dmFyIGU9dGhpcy5EQi0oYip0aGlzLkRCKSU4LGYsYT0wO2lmKGItLT4wKXtpZihlPHRoaXMuREImJihmPXRoaXNbYl0+PmUpIT0odGhpcy5zJnRoaXMuRE0pPj5lKXtjW2ErK109ZnwodGhpcy5zPDwodGhpcy5EQi1lKSl9d2hpbGUoYj49MCl7aWYoZTw4KXtmPSh0aGlzW2JdJigoMTw8ZSktMSkpPDwoOC1lKTtmfD10aGlzWy0tYl0+PihlKz10aGlzLkRCLTgpfWVsc2V7Zj0odGhpc1tiXT4+KGUtPTgpKSYyNTU7aWYoZTw9MCl7ZSs9dGhpcy5EQjstLWJ9fWlmKChmJjEyOCkhPTApe2Z8PS0yNTZ9aWYoYT09MCYmKHRoaXMucyYxMjgpIT0oZiYxMjgpKXsrK2F9aWYoYT4wfHxmIT10aGlzLnMpe2NbYSsrXT1mfX19cmV0dXJuIGN9ZnVuY3Rpb24gYm5FcXVhbHMoYil7cmV0dXJuKHRoaXMuY29tcGFyZVRvKGIpPT0wKX1mdW5jdGlvbiBibk1pbihiKXtyZXR1cm4odGhpcy5jb21wYXJlVG8oYik8MCk/dGhpczpifWZ1bmN0aW9uIGJuTWF4KGIpe3JldHVybih0aGlzLmNvbXBhcmVUbyhiKT4wKT90aGlzOmJ9ZnVuY3Rpb24gYm5wQml0d2lzZVRvKGMsaCxlKXt2YXIgZCxnLGI9TWF0aC5taW4oYy50LHRoaXMudCk7Zm9yKGQ9MDtkPGI7KytkKXtlW2RdPWgodGhpc1tkXSxjW2RdKX1pZihjLnQ8dGhpcy50KXtnPWMucyZ0aGlzLkRNO2ZvcihkPWI7ZDx0aGlzLnQ7KytkKXtlW2RdPWgodGhpc1tkXSxnKX1lLnQ9dGhpcy50fWVsc2V7Zz10aGlzLnMmdGhpcy5ETTtmb3IoZD1iO2Q8Yy50OysrZCl7ZVtkXT1oKGcsY1tkXSl9ZS50PWMudH1lLnM9aCh0aGlzLnMsYy5zKTtlLmNsYW1wKCl9ZnVuY3Rpb24gb3BfYW5kKGEsYil7cmV0dXJuIGEmYn1mdW5jdGlvbiBibkFuZChiKXt2YXIgYz1uYmkoKTt0aGlzLmJpdHdpc2VUbyhiLG9wX2FuZCxjKTtyZXR1cm4gY31mdW5jdGlvbiBvcF9vcihhLGIpe3JldHVybiBhfGJ9ZnVuY3Rpb24gYm5PcihiKXt2YXIgYz1uYmkoKTt0aGlzLmJpdHdpc2VUbyhiLG9wX29yLGMpO3JldHVybiBjfWZ1bmN0aW9uIG9wX3hvcihhLGIpe3JldHVybiBhXmJ9ZnVuY3Rpb24gYm5Yb3IoYil7dmFyIGM9bmJpKCk7dGhpcy5iaXR3aXNlVG8oYixvcF94b3IsYyk7cmV0dXJuIGN9ZnVuY3Rpb24gb3BfYW5kbm90KGEsYil7cmV0dXJuIGEmfmJ9ZnVuY3Rpb24gYm5BbmROb3QoYil7dmFyIGM9bmJpKCk7dGhpcy5iaXR3aXNlVG8oYixvcF9hbmRub3QsYyk7cmV0dXJuIGN9ZnVuY3Rpb24gYm5Ob3QoKXt2YXIgYj1uYmkoKTtmb3IodmFyIGE9MDthPHRoaXMudDsrK2Epe2JbYV09dGhpcy5ETSZ+dGhpc1thXX1iLnQ9dGhpcy50O2Iucz1+dGhpcy5zO3JldHVybiBifWZ1bmN0aW9uIGJuU2hpZnRMZWZ0KGIpe3ZhciBhPW5iaSgpO2lmKGI8MCl7dGhpcy5yU2hpZnRUbygtYixhKX1lbHNle3RoaXMubFNoaWZ0VG8oYixhKX1yZXR1cm4gYX1mdW5jdGlvbiBiblNoaWZ0UmlnaHQoYil7dmFyIGE9bmJpKCk7aWYoYjwwKXt0aGlzLmxTaGlmdFRvKC1iLGEpfWVsc2V7dGhpcy5yU2hpZnRUbyhiLGEpfXJldHVybiBhfWZ1bmN0aW9uIGxiaXQoYSl7aWYoYT09MCl7cmV0dXJuIC0xfXZhciBiPTA7aWYoKGEmNjU1MzUpPT0wKXthPj49MTY7Yis9MTZ9aWYoKGEmMjU1KT09MCl7YT4+PTg7Yis9OH1pZigoYSYxNSk9PTApe2E+Pj00O2IrPTR9aWYoKGEmMyk9PTApe2E+Pj0yO2IrPTJ9aWYoKGEmMSk9PTApeysrYn1yZXR1cm4gYn1mdW5jdGlvbiBibkdldExvd2VzdFNldEJpdCgpe2Zvcih2YXIgYT0wO2E8dGhpcy50OysrYSl7aWYodGhpc1thXSE9MCl7cmV0dXJuIGEqdGhpcy5EQitsYml0KHRoaXNbYV0pfX1pZih0aGlzLnM8MCl7cmV0dXJuIHRoaXMudCp0aGlzLkRCfXJldHVybiAtMX1mdW5jdGlvbiBjYml0KGEpe3ZhciBiPTA7d2hpbGUoYSE9MCl7YSY9YS0xOysrYn1yZXR1cm4gYn1mdW5jdGlvbiBibkJpdENvdW50KCl7dmFyIGM9MCxhPXRoaXMucyZ0aGlzLkRNO2Zvcih2YXIgYj0wO2I8dGhpcy50OysrYil7Yys9Y2JpdCh0aGlzW2JdXmEpfXJldHVybiBjfWZ1bmN0aW9uIGJuVGVzdEJpdChiKXt2YXIgYT1NYXRoLmZsb29yKGIvdGhpcy5EQik7aWYoYT49dGhpcy50KXtyZXR1cm4odGhpcy5zIT0wKX1yZXR1cm4oKHRoaXNbYV0mKDE8PChiJXRoaXMuREIpKSkhPTApfWZ1bmN0aW9uIGJucENoYW5nZUJpdChjLGIpe3ZhciBhPUJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChjKTt0aGlzLmJpdHdpc2VUbyhhLGIsYSk7cmV0dXJuIGF9ZnVuY3Rpb24gYm5TZXRCaXQoYSl7cmV0dXJuIHRoaXMuY2hhbmdlQml0KGEsb3Bfb3IpfWZ1bmN0aW9uIGJuQ2xlYXJCaXQoYSl7cmV0dXJuIHRoaXMuY2hhbmdlQml0KGEsb3BfYW5kbm90KX1mdW5jdGlvbiBibkZsaXBCaXQoYSl7cmV0dXJuIHRoaXMuY2hhbmdlQml0KGEsb3BfeG9yKX1mdW5jdGlvbiBibnBBZGRUbyhkLGYpe3ZhciBlPTAsZz0wLGI9TWF0aC5taW4oZC50LHRoaXMudCk7d2hpbGUoZTxiKXtnKz10aGlzW2VdK2RbZV07ZltlKytdPWcmdGhpcy5ETTtnPj49dGhpcy5EQn1pZihkLnQ8dGhpcy50KXtnKz1kLnM7d2hpbGUoZTx0aGlzLnQpe2crPXRoaXNbZV07ZltlKytdPWcmdGhpcy5ETTtnPj49dGhpcy5EQn1nKz10aGlzLnN9ZWxzZXtnKz10aGlzLnM7d2hpbGUoZTxkLnQpe2crPWRbZV07ZltlKytdPWcmdGhpcy5ETTtnPj49dGhpcy5EQn1nKz1kLnN9Zi5zPShnPDApPy0xOjA7aWYoZz4wKXtmW2UrK109Z31lbHNle2lmKGc8LTEpe2ZbZSsrXT10aGlzLkRWK2d9fWYudD1lO2YuY2xhbXAoKX1mdW5jdGlvbiBibkFkZChiKXt2YXIgYz1uYmkoKTt0aGlzLmFkZFRvKGIsYyk7cmV0dXJuIGN9ZnVuY3Rpb24gYm5TdWJ0cmFjdChiKXt2YXIgYz1uYmkoKTt0aGlzLnN1YlRvKGIsYyk7cmV0dXJuIGN9ZnVuY3Rpb24gYm5NdWx0aXBseShiKXt2YXIgYz1uYmkoKTt0aGlzLm11bHRpcGx5VG8oYixjKTtyZXR1cm4gY31mdW5jdGlvbiBiblNxdWFyZSgpe3ZhciBhPW5iaSgpO3RoaXMuc3F1YXJlVG8oYSk7cmV0dXJuIGF9ZnVuY3Rpb24gYm5EaXZpZGUoYil7dmFyIGM9bmJpKCk7dGhpcy5kaXZSZW1UbyhiLGMsbnVsbCk7cmV0dXJuIGN9ZnVuY3Rpb24gYm5SZW1haW5kZXIoYil7dmFyIGM9bmJpKCk7dGhpcy5kaXZSZW1UbyhiLG51bGwsYyk7cmV0dXJuIGN9ZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYil7dmFyIGQ9bmJpKCksYz1uYmkoKTt0aGlzLmRpdlJlbVRvKGIsZCxjKTtyZXR1cm4gbmV3IEFycmF5KGQsYyl9ZnVuY3Rpb24gYm5wRE11bHRpcGx5KGEpe3RoaXNbdGhpcy50XT10aGlzLmFtKDAsYS0xLHRoaXMsMCwwLHRoaXMudCk7Kyt0aGlzLnQ7dGhpcy5jbGFtcCgpfWZ1bmN0aW9uIGJucERBZGRPZmZzZXQoYixhKXtpZihiPT0wKXtyZXR1cm59d2hpbGUodGhpcy50PD1hKXt0aGlzW3RoaXMudCsrXT0wfXRoaXNbYV0rPWI7d2hpbGUodGhpc1thXT49dGhpcy5EVil7dGhpc1thXS09dGhpcy5EVjtpZigrK2E+PXRoaXMudCl7dGhpc1t0aGlzLnQrK109MH0rK3RoaXNbYV19fWZ1bmN0aW9uIE51bGxFeHAoKXt9ZnVuY3Rpb24gbk5vcChhKXtyZXR1cm4gYX1mdW5jdGlvbiBuTXVsVG8oYSxjLGIpe2EubXVsdGlwbHlUbyhjLGIpfWZ1bmN0aW9uIG5TcXJUbyhhLGIpe2Euc3F1YXJlVG8oYil9TnVsbEV4cC5wcm90b3R5cGUuY29udmVydD1uTm9wO051bGxFeHAucHJvdG90eXBlLnJldmVydD1uTm9wO051bGxFeHAucHJvdG90eXBlLm11bFRvPW5NdWxUbztOdWxsRXhwLnByb3RvdHlwZS5zcXJUbz1uU3FyVG87ZnVuY3Rpb24gYm5Qb3coYSl7cmV0dXJuIHRoaXMuZXhwKGEsbmV3IE51bGxFeHAoKSl9ZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGIsZixlKXt2YXIgZD1NYXRoLm1pbih0aGlzLnQrYi50LGYpO2Uucz0wO2UudD1kO3doaWxlKGQ+MCl7ZVstLWRdPTB9dmFyIGM7Zm9yKGM9ZS50LXRoaXMudDtkPGM7KytkKXtlW2QrdGhpcy50XT10aGlzLmFtKDAsYltkXSxlLGQsMCx0aGlzLnQpfWZvcihjPU1hdGgubWluKGIudCxmKTtkPGM7KytkKXt0aGlzLmFtKDAsYltkXSxlLGQsMCxmLWQpfWUuY2xhbXAoKX1mdW5jdGlvbiBibnBNdWx0aXBseVVwcGVyVG8oYixlLGQpey0tZTt2YXIgYz1kLnQ9dGhpcy50K2IudC1lO2Qucz0wO3doaWxlKC0tYz49MCl7ZFtjXT0wfWZvcihjPU1hdGgubWF4KGUtdGhpcy50LDApO2M8Yi50OysrYyl7ZFt0aGlzLnQrYy1lXT10aGlzLmFtKGUtYyxiW2NdLGQsMCwwLHRoaXMudCtjLWUpfWQuY2xhbXAoKTtkLmRyU2hpZnRUbygxLGQpfWZ1bmN0aW9uIEJhcnJldHQoYSl7dGhpcy5yMj1uYmkoKTt0aGlzLnEzPW5iaSgpO0JpZ0ludGVnZXIuT05FLmRsU2hpZnRUbygyKmEudCx0aGlzLnIyKTt0aGlzLm11PXRoaXMucjIuZGl2aWRlKGEpO3RoaXMubT1hfWZ1bmN0aW9uIGJhcnJldHRDb252ZXJ0KGEpe2lmKGEuczwwfHxhLnQ+Mip0aGlzLm0udCl7cmV0dXJuIGEubW9kKHRoaXMubSl9ZWxzZXtpZihhLmNvbXBhcmVUbyh0aGlzLm0pPDApe3JldHVybiBhfWVsc2V7dmFyIGI9bmJpKCk7YS5jb3B5VG8oYik7dGhpcy5yZWR1Y2UoYik7cmV0dXJuIGJ9fX1mdW5jdGlvbiBiYXJyZXR0UmV2ZXJ0KGEpe3JldHVybiBhfWZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoYSl7YS5kclNoaWZ0VG8odGhpcy5tLnQtMSx0aGlzLnIyKTtpZihhLnQ+dGhpcy5tLnQrMSl7YS50PXRoaXMubS50KzE7YS5jbGFtcCgpfXRoaXMubXUubXVsdGlwbHlVcHBlclRvKHRoaXMucjIsdGhpcy5tLnQrMSx0aGlzLnEzKTt0aGlzLm0ubXVsdGlwbHlMb3dlclRvKHRoaXMucTMsdGhpcy5tLnQrMSx0aGlzLnIyKTt3aGlsZShhLmNvbXBhcmVUbyh0aGlzLnIyKTwwKXthLmRBZGRPZmZzZXQoMSx0aGlzLm0udCsxKX1hLnN1YlRvKHRoaXMucjIsYSk7d2hpbGUoYS5jb21wYXJlVG8odGhpcy5tKT49MCl7YS5zdWJUbyh0aGlzLm0sYSl9fWZ1bmN0aW9uIGJhcnJldHRTcXJUbyhhLGIpe2Euc3F1YXJlVG8oYik7dGhpcy5yZWR1Y2UoYil9ZnVuY3Rpb24gYmFycmV0dE11bFRvKGEsYyxiKXthLm11bHRpcGx5VG8oYyxiKTt0aGlzLnJlZHVjZShiKX1CYXJyZXR0LnByb3RvdHlwZS5jb252ZXJ0PWJhcnJldHRDb252ZXJ0O0JhcnJldHQucHJvdG90eXBlLnJldmVydD1iYXJyZXR0UmV2ZXJ0O0JhcnJldHQucHJvdG90eXBlLnJlZHVjZT1iYXJyZXR0UmVkdWNlO0JhcnJldHQucHJvdG90eXBlLm11bFRvPWJhcnJldHRNdWxUbztCYXJyZXR0LnByb3RvdHlwZS5zcXJUbz1iYXJyZXR0U3FyVG87ZnVuY3Rpb24gYm5Nb2RQb3cocSxmKXt2YXIgbz1xLmJpdExlbmd0aCgpLGgsYj1uYnYoMSksdjtpZihvPD0wKXtyZXR1cm4gYn1lbHNle2lmKG88MTgpe2g9MX1lbHNle2lmKG88NDgpe2g9M31lbHNle2lmKG88MTQ0KXtoPTR9ZWxzZXtpZihvPDc2OCl7aD01fWVsc2V7aD02fX19fX1pZihvPDgpe3Y9bmV3IENsYXNzaWMoZil9ZWxzZXtpZihmLmlzRXZlbigpKXt2PW5ldyBCYXJyZXR0KGYpfWVsc2V7dj1uZXcgTW9udGdvbWVyeShmKX19dmFyIHA9bmV3IEFycmF5KCksZD0zLHM9aC0xLGE9KDE8PGgpLTE7cFsxXT12LmNvbnZlcnQodGhpcyk7aWYoaD4xKXt2YXIgQT1uYmkoKTt2LnNxclRvKHBbMV0sQSk7d2hpbGUoZDw9YSl7cFtkXT1uYmkoKTt2Lm11bFRvKEEscFtkLTJdLHBbZF0pO2QrPTJ9fXZhciBsPXEudC0xLHgsdT10cnVlLGM9bmJpKCkseTtvPW5iaXRzKHFbbF0pLTE7d2hpbGUobD49MCl7aWYobz49cyl7eD0ocVtsXT4+KG8tcykpJmF9ZWxzZXt4PShxW2xdJigoMTw8KG8rMSkpLTEpKTw8KHMtbyk7aWYobD4wKXt4fD1xW2wtMV0+Pih0aGlzLkRCK28tcyl9fWQ9aDt3aGlsZSgoeCYxKT09MCl7eD4+PTE7LS1kfWlmKChvLT1kKTwwKXtvKz10aGlzLkRCOy0tbH1pZih1KXtwW3hdLmNvcHlUbyhiKTt1PWZhbHNlfWVsc2V7d2hpbGUoZD4xKXt2LnNxclRvKGIsYyk7di5zcXJUbyhjLGIpO2QtPTJ9aWYoZD4wKXt2LnNxclRvKGIsYyl9ZWxzZXt5PWI7Yj1jO2M9eX12Lm11bFRvKGMscFt4XSxiKX13aGlsZShsPj0wJiYocVtsXSYoMTw8bykpPT0wKXt2LnNxclRvKGIsYyk7eT1iO2I9YztjPXk7aWYoLS1vPDApe289dGhpcy5EQi0xOy0tbH19fXJldHVybiB2LnJldmVydChiKX1mdW5jdGlvbiBibkdDRChjKXt2YXIgYj0odGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpcy5jbG9uZSgpO3ZhciBoPShjLnM8MCk/Yy5uZWdhdGUoKTpjLmNsb25lKCk7aWYoYi5jb21wYXJlVG8oaCk8MCl7dmFyIGU9YjtiPWg7aD1lfXZhciBkPWIuZ2V0TG93ZXN0U2V0Qml0KCksZj1oLmdldExvd2VzdFNldEJpdCgpO2lmKGY8MCl7cmV0dXJuIGJ9aWYoZDxmKXtmPWR9aWYoZj4wKXtiLnJTaGlmdFRvKGYsYik7aC5yU2hpZnRUbyhmLGgpfXdoaWxlKGIuc2lnbnVtKCk+MCl7aWYoKGQ9Yi5nZXRMb3dlc3RTZXRCaXQoKSk+MCl7Yi5yU2hpZnRUbyhkLGIpfWlmKChkPWguZ2V0TG93ZXN0U2V0Qml0KCkpPjApe2guclNoaWZ0VG8oZCxoKX1pZihiLmNvbXBhcmVUbyhoKT49MCl7Yi5zdWJUbyhoLGIpO2IuclNoaWZ0VG8oMSxiKX1lbHNle2guc3ViVG8oYixoKTtoLnJTaGlmdFRvKDEsaCl9fWlmKGY+MCl7aC5sU2hpZnRUbyhmLGgpfXJldHVybiBofWZ1bmN0aW9uIGJucE1vZEludChlKXtpZihlPD0wKXtyZXR1cm4gMH12YXIgYz10aGlzLkRWJWUsYj0odGhpcy5zPDApP2UtMTowO2lmKHRoaXMudD4wKXtpZihjPT0wKXtiPXRoaXNbMF0lZX1lbHNle2Zvcih2YXIgYT10aGlzLnQtMTthPj0wOy0tYSl7Yj0oYypiK3RoaXNbYV0pJWV9fX1yZXR1cm4gYn1mdW5jdGlvbiBibk1vZEludmVyc2UoZil7dmFyIGo9Zi5pc0V2ZW4oKTtpZigodGhpcy5pc0V2ZW4oKSYmail8fGYuc2lnbnVtKCk9PTApe3JldHVybiBCaWdJbnRlZ2VyLlpFUk99dmFyIGk9Zi5jbG9uZSgpLGg9dGhpcy5jbG9uZSgpO3ZhciBnPW5idigxKSxlPW5idigwKSxsPW5idigwKSxrPW5idigxKTt3aGlsZShpLnNpZ251bSgpIT0wKXt3aGlsZShpLmlzRXZlbigpKXtpLnJTaGlmdFRvKDEsaSk7aWYoail7aWYoIWcuaXNFdmVuKCl8fCFlLmlzRXZlbigpKXtnLmFkZFRvKHRoaXMsZyk7ZS5zdWJUbyhmLGUpfWcuclNoaWZ0VG8oMSxnKX1lbHNle2lmKCFlLmlzRXZlbigpKXtlLnN1YlRvKGYsZSl9fWUuclNoaWZ0VG8oMSxlKX13aGlsZShoLmlzRXZlbigpKXtoLnJTaGlmdFRvKDEsaCk7aWYoail7aWYoIWwuaXNFdmVuKCl8fCFrLmlzRXZlbigpKXtsLmFkZFRvKHRoaXMsbCk7ay5zdWJUbyhmLGspfWwuclNoaWZ0VG8oMSxsKX1lbHNle2lmKCFrLmlzRXZlbigpKXtrLnN1YlRvKGYsayl9fWsuclNoaWZ0VG8oMSxrKX1pZihpLmNvbXBhcmVUbyhoKT49MCl7aS5zdWJUbyhoLGkpO2lmKGope2cuc3ViVG8obCxnKX1lLnN1YlRvKGssZSl9ZWxzZXtoLnN1YlRvKGksaCk7aWYoail7bC5zdWJUbyhnLGwpfWsuc3ViVG8oZSxrKX19aWYoaC5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpIT0wKXtyZXR1cm4gQmlnSW50ZWdlci5aRVJPfWlmKGsuY29tcGFyZVRvKGYpPj0wKXtyZXR1cm4gay5zdWJ0cmFjdChmKX1pZihrLnNpZ251bSgpPDApe2suYWRkVG8oZixrKX1lbHNle3JldHVybiBrfWlmKGsuc2lnbnVtKCk8MCl7cmV0dXJuIGsuYWRkKGYpfWVsc2V7cmV0dXJuIGt9fXZhciBsb3dwcmltZXM9WzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDksNTIxLDUyMyw1NDEsNTQ3LDU1Nyw1NjMsNTY5LDU3MSw1NzcsNTg3LDU5Myw1OTksNjAxLDYwNyw2MTMsNjE3LDYxOSw2MzEsNjQxLDY0Myw2NDcsNjUzLDY1OSw2NjEsNjczLDY3Nyw2ODMsNjkxLDcwMSw3MDksNzE5LDcyNyw3MzMsNzM5LDc0Myw3NTEsNzU3LDc2MSw3NjksNzczLDc4Nyw3OTcsODA5LDgxMSw4MjEsODIzLDgyNyw4MjksODM5LDg1Myw4NTcsODU5LDg2Myw4NzcsODgxLDg4Myw4ODcsOTA3LDkxMSw5MTksOTI5LDkzNyw5NDEsOTQ3LDk1Myw5NjcsOTcxLDk3Nyw5ODMsOTkxLDk5N107dmFyIGxwbGltPSgxPDwyNikvbG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGgtMV07ZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUoZSl7dmFyIGQsYj10aGlzLmFicygpO2lmKGIudD09MSYmYlswXTw9bG93cHJpbWVzW2xvd3ByaW1lcy5sZW5ndGgtMV0pe2ZvcihkPTA7ZDxsb3dwcmltZXMubGVuZ3RoOysrZCl7aWYoYlswXT09bG93cHJpbWVzW2RdKXtyZXR1cm4gdHJ1ZX19cmV0dXJuIGZhbHNlfWlmKGIuaXNFdmVuKCkpe3JldHVybiBmYWxzZX1kPTE7d2hpbGUoZDxsb3dwcmltZXMubGVuZ3RoKXt2YXIgYT1sb3dwcmltZXNbZF0sYz1kKzE7d2hpbGUoYzxsb3dwcmltZXMubGVuZ3RoJiZhPGxwbGltKXthKj1sb3dwcmltZXNbYysrXX1hPWIubW9kSW50KGEpO3doaWxlKGQ8Yyl7aWYoYSVsb3dwcmltZXNbZCsrXT09MCl7cmV0dXJuIGZhbHNlfX19cmV0dXJuIGIubWlsbGVyUmFiaW4oZSl9ZnVuY3Rpb24gYm5wTWlsbGVyUmFiaW4oZil7dmFyIGc9dGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7dmFyIGM9Zy5nZXRMb3dlc3RTZXRCaXQoKTtpZihjPD0wKXtyZXR1cm4gZmFsc2V9dmFyIGg9Zy5zaGlmdFJpZ2h0KGMpO2Y9KGYrMSk+PjE7aWYoZj5sb3dwcmltZXMubGVuZ3RoKXtmPWxvd3ByaW1lcy5sZW5ndGh9dmFyIGI9bmJpKCk7Zm9yKHZhciBlPTA7ZTxmOysrZSl7Yi5mcm9tSW50KGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqbG93cHJpbWVzLmxlbmd0aCldKTt2YXIgbD1iLm1vZFBvdyhoLHRoaXMpO2lmKGwuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSE9MCYmbC5jb21wYXJlVG8oZykhPTApe3ZhciBkPTE7d2hpbGUoZCsrPGMmJmwuY29tcGFyZVRvKGcpIT0wKXtsPWwubW9kUG93SW50KDIsdGhpcyk7aWYobC5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpPT0wKXtyZXR1cm4gZmFsc2V9fWlmKGwuY29tcGFyZVRvKGcpIT0wKXtyZXR1cm4gZmFsc2V9fX1yZXR1cm4gdHJ1ZX1CaWdJbnRlZ2VyLnByb3RvdHlwZS5jaHVua1NpemU9Ym5wQ2h1bmtTaXplO0JpZ0ludGVnZXIucHJvdG90eXBlLnRvUmFkaXg9Ym5wVG9SYWRpeDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXg9Ym5wRnJvbVJhZGl4O0JpZ0ludGVnZXIucHJvdG90eXBlLmZyb21OdW1iZXI9Ym5wRnJvbU51bWJlcjtCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXR3aXNlVG89Ym5wQml0d2lzZVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdD1ibnBDaGFuZ2VCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuYWRkVG89Ym5wQWRkVG87QmlnSW50ZWdlci5wcm90b3R5cGUuZE11bHRpcGx5PWJucERNdWx0aXBseTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0PWJucERBZGRPZmZzZXQ7QmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlMb3dlclRvPWJucE11bHRpcGx5TG93ZXJUbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVVwcGVyVG89Ym5wTXVsdGlwbHlVcHBlclRvO0JpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludD1ibnBNb2RJbnQ7QmlnSW50ZWdlci5wcm90b3R5cGUubWlsbGVyUmFiaW49Ym5wTWlsbGVyUmFiaW47QmlnSW50ZWdlci5wcm90b3R5cGUuY2xvbmU9Ym5DbG9uZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnRWYWx1ZT1ibkludFZhbHVlO0JpZ0ludGVnZXIucHJvdG90eXBlLmJ5dGVWYWx1ZT1ibkJ5dGVWYWx1ZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaG9ydFZhbHVlPWJuU2hvcnRWYWx1ZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaWdudW09Ym5TaWdOdW07QmlnSW50ZWdlci5wcm90b3R5cGUudG9CeXRlQXJyYXk9Ym5Ub0J5dGVBcnJheTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5lcXVhbHM9Ym5FcXVhbHM7QmlnSW50ZWdlci5wcm90b3R5cGUubWluPWJuTWluO0JpZ0ludGVnZXIucHJvdG90eXBlLm1heD1ibk1heDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmQ9Ym5BbmQ7QmlnSW50ZWdlci5wcm90b3R5cGUub3I9Ym5PcjtCaWdJbnRlZ2VyLnByb3RvdHlwZS54b3I9Ym5Yb3I7QmlnSW50ZWdlci5wcm90b3R5cGUuYW5kTm90PWJuQW5kTm90O0JpZ0ludGVnZXIucHJvdG90eXBlLm5vdD1ibk5vdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaGlmdExlZnQ9Ym5TaGlmdExlZnQ7QmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRSaWdodD1iblNoaWZ0UmlnaHQ7QmlnSW50ZWdlci5wcm90b3R5cGUuZ2V0TG93ZXN0U2V0Qml0PWJuR2V0TG93ZXN0U2V0Qml0O0JpZ0ludGVnZXIucHJvdG90eXBlLmJpdENvdW50PWJuQml0Q291bnQ7QmlnSW50ZWdlci5wcm90b3R5cGUudGVzdEJpdD1iblRlc3RCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuc2V0Qml0PWJuU2V0Qml0O0JpZ0ludGVnZXIucHJvdG90eXBlLmNsZWFyQml0PWJuQ2xlYXJCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuZmxpcEJpdD1ibkZsaXBCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuYWRkPWJuQWRkO0JpZ0ludGVnZXIucHJvdG90eXBlLnN1YnRyYWN0PWJuU3VidHJhY3Q7QmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHk9Ym5NdWx0aXBseTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGU9Ym5EaXZpZGU7QmlnSW50ZWdlci5wcm90b3R5cGUucmVtYWluZGVyPWJuUmVtYWluZGVyO0JpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZUFuZFJlbWFpbmRlcj1ibkRpdmlkZUFuZFJlbWFpbmRlcjtCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RQb3c9Ym5Nb2RQb3c7QmlnSW50ZWdlci5wcm90b3R5cGUubW9kSW52ZXJzZT1ibk1vZEludmVyc2U7QmlnSW50ZWdlci5wcm90b3R5cGUucG93PWJuUG93O0JpZ0ludGVnZXIucHJvdG90eXBlLmdjZD1ibkdDRDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5pc1Byb2JhYmxlUHJpbWU9Ym5Jc1Byb2JhYmxlUHJpbWU7QmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlPWJuU3F1YXJlO1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG5mdW5jdGlvbiBBcmNmb3VyKCl7dGhpcy5pPTA7dGhpcy5qPTA7dGhpcy5TPW5ldyBBcnJheSgpfWZ1bmN0aW9uIEFSQzRpbml0KGQpe3ZhciBjLGEsYjtmb3IoYz0wO2M8MjU2OysrYyl7dGhpcy5TW2NdPWN9YT0wO2ZvcihjPTA7YzwyNTY7KytjKXthPShhK3RoaXMuU1tjXStkW2MlZC5sZW5ndGhdKSYyNTU7Yj10aGlzLlNbY107dGhpcy5TW2NdPXRoaXMuU1thXTt0aGlzLlNbYV09Yn10aGlzLmk9MDt0aGlzLmo9MH1mdW5jdGlvbiBBUkM0bmV4dCgpe3ZhciBhO3RoaXMuaT0odGhpcy5pKzEpJjI1NTt0aGlzLmo9KHRoaXMuait0aGlzLlNbdGhpcy5pXSkmMjU1O2E9dGhpcy5TW3RoaXMuaV07dGhpcy5TW3RoaXMuaV09dGhpcy5TW3RoaXMual07dGhpcy5TW3RoaXMual09YTtyZXR1cm4gdGhpcy5TWyhhK3RoaXMuU1t0aGlzLmldKSYyNTVdfUFyY2ZvdXIucHJvdG90eXBlLmluaXQ9QVJDNGluaXQ7QXJjZm91ci5wcm90b3R5cGUubmV4dD1BUkM0bmV4dDtmdW5jdGlvbiBwcm5nX25ld3N0YXRlKCl7cmV0dXJuIG5ldyBBcmNmb3VyKCl9dmFyIHJuZ19wc2l6ZT0yNTY7XG4vKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi9cclxuICovXHJcbnZhciBybmdfc3RhdGU7dmFyIHJuZ19wb29sO3ZhciBybmdfcHB0cjtmdW5jdGlvbiBybmdfc2VlZF9pbnQoYSl7cm5nX3Bvb2xbcm5nX3BwdHIrK11ePWEmMjU1O3JuZ19wb29sW3JuZ19wcHRyKytdXj0oYT4+OCkmMjU1O3JuZ19wb29sW3JuZ19wcHRyKytdXj0oYT4+MTYpJjI1NTtybmdfcG9vbFtybmdfcHB0cisrXV49KGE+PjI0KSYyNTU7aWYocm5nX3BwdHI+PXJuZ19wc2l6ZSl7cm5nX3BwdHItPXJuZ19wc2l6ZX19ZnVuY3Rpb24gcm5nX3NlZWRfdGltZSgpe3JuZ19zZWVkX2ludChuZXcgRGF0ZSgpLmdldFRpbWUoKSl9aWYocm5nX3Bvb2w9PW51bGwpe3JuZ19wb29sPW5ldyBBcnJheSgpO3JuZ19wcHRyPTA7dmFyIHQ7aWYod2luZG93IT09dW5kZWZpbmVkJiYod2luZG93LmNyeXB0byE9PXVuZGVmaW5lZHx8d2luZG93Lm1zQ3J5cHRvIT09dW5kZWZpbmVkKSl7dmFyIGNyeXB0bz13aW5kb3cuY3J5cHRvfHx3aW5kb3cubXNDcnlwdG87aWYoY3J5cHRvLmdldFJhbmRvbVZhbHVlcyl7dmFyIHVhPW5ldyBVaW50OEFycmF5KDMyKTtjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKHVhKTtmb3IodD0wO3Q8MzI7Kyt0KXtybmdfcG9vbFtybmdfcHB0cisrXT11YVt0XX19ZWxzZXtpZihuYXZpZ2F0b3IuYXBwTmFtZT09XCJOZXRzY2FwZVwiJiZuYXZpZ2F0b3IuYXBwVmVyc2lvbjxcIjVcIil7dmFyIHo9d2luZG93LmNyeXB0by5yYW5kb20oMzIpO2Zvcih0PTA7dDx6Lmxlbmd0aDsrK3Qpe3JuZ19wb29sW3JuZ19wcHRyKytdPXouY2hhckNvZGVBdCh0KSYyNTV9fX19d2hpbGUocm5nX3BwdHI8cm5nX3BzaXplKXt0PU1hdGguZmxvb3IoNjU1MzYqTWF0aC5yYW5kb20oKSk7cm5nX3Bvb2xbcm5nX3BwdHIrK109dD4+Pjg7cm5nX3Bvb2xbcm5nX3BwdHIrK109dCYyNTV9cm5nX3BwdHI9MDtybmdfc2VlZF90aW1lKCl9ZnVuY3Rpb24gcm5nX2dldF9ieXRlKCl7aWYocm5nX3N0YXRlPT1udWxsKXtybmdfc2VlZF90aW1lKCk7cm5nX3N0YXRlPXBybmdfbmV3c3RhdGUoKTtybmdfc3RhdGUuaW5pdChybmdfcG9vbCk7Zm9yKHJuZ19wcHRyPTA7cm5nX3BwdHI8cm5nX3Bvb2wubGVuZ3RoOysrcm5nX3BwdHIpe3JuZ19wb29sW3JuZ19wcHRyXT0wfXJuZ19wcHRyPTB9cmV0dXJuIHJuZ19zdGF0ZS5uZXh0KCl9ZnVuY3Rpb24gcm5nX2dldF9ieXRlcyhiKXt2YXIgYTtmb3IoYT0wO2E8Yi5sZW5ndGg7KythKXtiW2FdPXJuZ19nZXRfYnl0ZSgpfX1mdW5jdGlvbiBTZWN1cmVSYW5kb20oKXt9U2VjdXJlUmFuZG9tLnByb3RvdHlwZS5uZXh0Qnl0ZXM9cm5nX2dldF9ieXRlcztcbi8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xyXG4gKi9cclxuZnVuY3Rpb24gcGFyc2VCaWdJbnQoYixhKXtyZXR1cm4gbmV3IEJpZ0ludGVnZXIoYixhKX1mdW5jdGlvbiBsaW5lYnJrKGMsZCl7dmFyIGE9XCJcIjt2YXIgYj0wO3doaWxlKGIrZDxjLmxlbmd0aCl7YSs9Yy5zdWJzdHJpbmcoYixiK2QpK1wiXFxuXCI7Yis9ZH1yZXR1cm4gYStjLnN1YnN0cmluZyhiLGMubGVuZ3RoKX1mdW5jdGlvbiBieXRlMkhleChhKXtpZihhPDE2KXtyZXR1cm5cIjBcIithLnRvU3RyaW5nKDE2KX1lbHNle3JldHVybiBhLnRvU3RyaW5nKDE2KX19ZnVuY3Rpb24gcGtjczFwYWQyKGUsaCl7aWYoaDxlLmxlbmd0aCsxMSl7dGhyb3dcIk1lc3NhZ2UgdG9vIGxvbmcgZm9yIFJTQVwiO3JldHVybiBudWxsfXZhciBnPW5ldyBBcnJheSgpO3ZhciBkPWUubGVuZ3RoLTE7d2hpbGUoZD49MCYmaD4wKXt2YXIgZj1lLmNoYXJDb2RlQXQoZC0tKTtpZihmPDEyOCl7Z1stLWhdPWZ9ZWxzZXtpZigoZj4xMjcpJiYoZjwyMDQ4KSl7Z1stLWhdPShmJjYzKXwxMjg7Z1stLWhdPShmPj42KXwxOTJ9ZWxzZXtnWy0taF09KGYmNjMpfDEyODtnWy0taF09KChmPj42KSY2Myl8MTI4O2dbLS1oXT0oZj4+MTIpfDIyNH19fWdbLS1oXT0wO3ZhciBiPW5ldyBTZWN1cmVSYW5kb20oKTt2YXIgYT1uZXcgQXJyYXkoKTt3aGlsZShoPjIpe2FbMF09MDt3aGlsZShhWzBdPT0wKXtiLm5leHRCeXRlcyhhKX1nWy0taF09YVswXX1nWy0taF09MjtnWy0taF09MDtyZXR1cm4gbmV3IEJpZ0ludGVnZXIoZyl9ZnVuY3Rpb24gb2FlcF9tZ2YxX2FycihjLGEsZSl7dmFyIGI9XCJcIixkPTA7d2hpbGUoYi5sZW5ndGg8YSl7Yis9ZShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxjLmNvbmNhdChbKGQmNDI3ODE5MDA4MCk+PjI0LChkJjE2NzExNjgwKT4+MTYsKGQmNjUyODApPj44LGQmMjU1XSkpKTtkKz0xfXJldHVybiBifWZ1bmN0aW9uIG9hZXBfcGFkKHEsYSxmLGwpe3ZhciBjPUtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Q7dmFyIG89S0pVUi5jcnlwdG8uVXRpbDt2YXIgYj1udWxsO2lmKCFmKXtmPVwic2hhMVwifWlmKHR5cGVvZiBmPT09XCJzdHJpbmdcIil7Yj1jLmdldENhbm9uaWNhbEFsZ05hbWUoZik7bD1jLmdldEhhc2hMZW5ndGgoYik7Zj1mdW5jdGlvbihpKXtyZXR1cm4gaGV4dG9yc3RyKG8uaGFzaEhleChyc3RydG9oZXgoaSksYikpfX1pZihxLmxlbmd0aCsyKmwrMj5hKXt0aHJvd1wiTWVzc2FnZSB0b28gbG9uZyBmb3IgUlNBXCJ9dmFyIGs9XCJcIixlO2ZvcihlPTA7ZTxhLXEubGVuZ3RoLTIqbC0yO2UrPTEpe2srPVwiXFx4MDBcIn12YXIgaD1mKFwiXCIpK2srXCJcXHgwMVwiK3E7dmFyIGc9bmV3IEFycmF5KGwpO25ldyBTZWN1cmVSYW5kb20oKS5uZXh0Qnl0ZXMoZyk7dmFyIGo9b2FlcF9tZ2YxX2FycihnLGgubGVuZ3RoLGYpO3ZhciBwPVtdO2ZvcihlPTA7ZTxoLmxlbmd0aDtlKz0xKXtwW2VdPWguY2hhckNvZGVBdChlKV5qLmNoYXJDb2RlQXQoZSl9dmFyIG09b2FlcF9tZ2YxX2FycihwLGcubGVuZ3RoLGYpO3ZhciBkPVswXTtmb3IoZT0wO2U8Zy5sZW5ndGg7ZSs9MSl7ZFtlKzFdPWdbZV1ebS5jaGFyQ29kZUF0KGUpfXJldHVybiBuZXcgQmlnSW50ZWdlcihkLmNvbmNhdChwKSl9ZnVuY3Rpb24gUlNBS2V5KCl7dGhpcy5uPW51bGw7dGhpcy5lPTA7dGhpcy5kPW51bGw7dGhpcy5wPW51bGw7dGhpcy5xPW51bGw7dGhpcy5kbXAxPW51bGw7dGhpcy5kbXExPW51bGw7dGhpcy5jb2VmZj1udWxsfWZ1bmN0aW9uIFJTQVNldFB1YmxpYyhiLGEpe3RoaXMuaXNQdWJsaWM9dHJ1ZTt0aGlzLmlzUHJpdmF0ZT1mYWxzZTtpZih0eXBlb2YgYiE9PVwic3RyaW5nXCIpe3RoaXMubj1iO3RoaXMuZT1hfWVsc2V7aWYoYiE9bnVsbCYmYSE9bnVsbCYmYi5sZW5ndGg+MCYmYS5sZW5ndGg+MCl7dGhpcy5uPXBhcnNlQmlnSW50KGIsMTYpO3RoaXMuZT1wYXJzZUludChhLDE2KX1lbHNle3Rocm93XCJJbnZhbGlkIFJTQSBwdWJsaWMga2V5XCJ9fX1mdW5jdGlvbiBSU0FEb1B1YmxpYyhhKXtyZXR1cm4gYS5tb2RQb3dJbnQodGhpcy5lLHRoaXMubil9ZnVuY3Rpb24gUlNBRW5jcnlwdChkKXt2YXIgYT1wa2NzMXBhZDIoZCwodGhpcy5uLmJpdExlbmd0aCgpKzcpPj4zKTtpZihhPT1udWxsKXtyZXR1cm4gbnVsbH12YXIgZT10aGlzLmRvUHVibGljKGEpO2lmKGU9PW51bGwpe3JldHVybiBudWxsfXZhciBiPWUudG9TdHJpbmcoMTYpO2lmKChiLmxlbmd0aCYxKT09MCl7cmV0dXJuIGJ9ZWxzZXtyZXR1cm5cIjBcIitifX1mdW5jdGlvbiBSU0FFbmNyeXB0T0FFUChmLGUsYil7dmFyIGE9b2FlcF9wYWQoZiwodGhpcy5uLmJpdExlbmd0aCgpKzcpPj4zLGUsYik7aWYoYT09bnVsbCl7cmV0dXJuIG51bGx9dmFyIGc9dGhpcy5kb1B1YmxpYyhhKTtpZihnPT1udWxsKXtyZXR1cm4gbnVsbH12YXIgZD1nLnRvU3RyaW5nKDE2KTtpZigoZC5sZW5ndGgmMSk9PTApe3JldHVybiBkfWVsc2V7cmV0dXJuXCIwXCIrZH19UlNBS2V5LnByb3RvdHlwZS5kb1B1YmxpYz1SU0FEb1B1YmxpYztSU0FLZXkucHJvdG90eXBlLnNldFB1YmxpYz1SU0FTZXRQdWJsaWM7UlNBS2V5LnByb3RvdHlwZS5lbmNyeXB0PVJTQUVuY3J5cHQ7UlNBS2V5LnByb3RvdHlwZS5lbmNyeXB0T0FFUD1SU0FFbmNyeXB0T0FFUDtSU0FLZXkucHJvdG90eXBlLnR5cGU9XCJSU0FcIjtcbi8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xyXG4gKi9cclxuZnVuY3Rpb24gRUNGaWVsZEVsZW1lbnRGcChiLGEpe3RoaXMueD1hO3RoaXMucT1ifWZ1bmN0aW9uIGZlRnBFcXVhbHMoYSl7aWYoYT09dGhpcyl7cmV0dXJuIHRydWV9cmV0dXJuKHRoaXMucS5lcXVhbHMoYS5xKSYmdGhpcy54LmVxdWFscyhhLngpKX1mdW5jdGlvbiBmZUZwVG9CaWdJbnRlZ2VyKCl7cmV0dXJuIHRoaXMueH1mdW5jdGlvbiBmZUZwTmVnYXRlKCl7cmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLngubmVnYXRlKCkubW9kKHRoaXMucSkpfWZ1bmN0aW9uIGZlRnBBZGQoYSl7cmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLnguYWRkKGEudG9CaWdJbnRlZ2VyKCkpLm1vZCh0aGlzLnEpKX1mdW5jdGlvbiBmZUZwU3VidHJhY3QoYSl7cmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLnguc3VidHJhY3QoYS50b0JpZ0ludGVnZXIoKSkubW9kKHRoaXMucSkpfWZ1bmN0aW9uIGZlRnBNdWx0aXBseShhKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5tdWx0aXBseShhLnRvQmlnSW50ZWdlcigpKS5tb2QodGhpcy5xKSl9ZnVuY3Rpb24gZmVGcFNxdWFyZSgpe3JldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsdGhpcy54LnNxdWFyZSgpLm1vZCh0aGlzLnEpKX1mdW5jdGlvbiBmZUZwRGl2aWRlKGEpe3JldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsdGhpcy54Lm11bHRpcGx5KGEudG9CaWdJbnRlZ2VyKCkubW9kSW52ZXJzZSh0aGlzLnEpKS5tb2QodGhpcy5xKSl9RUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuZXF1YWxzPWZlRnBFcXVhbHM7RUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUudG9CaWdJbnRlZ2VyPWZlRnBUb0JpZ0ludGVnZXI7RUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUubmVnYXRlPWZlRnBOZWdhdGU7RUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuYWRkPWZlRnBBZGQ7RUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuc3VidHJhY3Q9ZmVGcFN1YnRyYWN0O0VDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLm11bHRpcGx5PWZlRnBNdWx0aXBseTtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5zcXVhcmU9ZmVGcFNxdWFyZTtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5kaXZpZGU9ZmVGcERpdmlkZTtmdW5jdGlvbiBFQ1BvaW50RnAoYyxhLGQsYil7dGhpcy5jdXJ2ZT1jO3RoaXMueD1hO3RoaXMueT1kO2lmKGI9PW51bGwpe3RoaXMuej1CaWdJbnRlZ2VyLk9ORX1lbHNle3RoaXMuej1ifXRoaXMuemludj1udWxsfWZ1bmN0aW9uIHBvaW50RnBHZXRYKCl7aWYodGhpcy56aW52PT1udWxsKXt0aGlzLnppbnY9dGhpcy56Lm1vZEludmVyc2UodGhpcy5jdXJ2ZS5xKX1yZXR1cm4gdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcih0aGlzLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56aW52KS5tb2QodGhpcy5jdXJ2ZS5xKSl9ZnVuY3Rpb24gcG9pbnRGcEdldFkoKXtpZih0aGlzLnppbnY9PW51bGwpe3RoaXMuemludj10aGlzLnoubW9kSW52ZXJzZSh0aGlzLmN1cnZlLnEpfXJldHVybiB0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKHRoaXMueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnppbnYpLm1vZCh0aGlzLmN1cnZlLnEpKX1mdW5jdGlvbiBwb2ludEZwRXF1YWxzKGEpe2lmKGE9PXRoaXMpe3JldHVybiB0cnVlfWlmKHRoaXMuaXNJbmZpbml0eSgpKXtyZXR1cm4gYS5pc0luZmluaXR5KCl9aWYoYS5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzLmlzSW5maW5pdHkoKX12YXIgYyxiO2M9YS55LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy55LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KGEueikpLm1vZCh0aGlzLmN1cnZlLnEpO2lmKCFjLmVxdWFscyhCaWdJbnRlZ2VyLlpFUk8pKXtyZXR1cm4gZmFsc2V9Yj1hLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkoYS56KSkubW9kKHRoaXMuY3VydmUucSk7cmV0dXJuIGIuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTyl9ZnVuY3Rpb24gcG9pbnRGcElzSW5maW5pdHkoKXtpZigodGhpcy54PT1udWxsKSYmKHRoaXMueT09bnVsbCkpe3JldHVybiB0cnVlfXJldHVybiB0aGlzLnouZXF1YWxzKEJpZ0ludGVnZXIuWkVSTykmJiF0aGlzLnkudG9CaWdJbnRlZ2VyKCkuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTyl9ZnVuY3Rpb24gcG9pbnRGcE5lZ2F0ZSgpe3JldHVybiBuZXcgRUNQb2ludEZwKHRoaXMuY3VydmUsdGhpcy54LHRoaXMueS5uZWdhdGUoKSx0aGlzLnopfWZ1bmN0aW9uIHBvaW50RnBBZGQobCl7aWYodGhpcy5pc0luZmluaXR5KCkpe3JldHVybiBsfWlmKGwuaXNJbmZpbml0eSgpKXtyZXR1cm4gdGhpc312YXIgcD1sLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkobC56KSkubW9kKHRoaXMuY3VydmUucSk7dmFyIG89bC54LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KHRoaXMueikuc3VidHJhY3QodGhpcy54LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KGwueikpLm1vZCh0aGlzLmN1cnZlLnEpO2lmKEJpZ0ludGVnZXIuWkVSTy5lcXVhbHMobykpe2lmKEJpZ0ludGVnZXIuWkVSTy5lcXVhbHMocCkpe3JldHVybiB0aGlzLnR3aWNlKCl9cmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKX12YXIgaj1uZXcgQmlnSW50ZWdlcihcIjNcIik7dmFyIGU9dGhpcy54LnRvQmlnSW50ZWdlcigpO3ZhciBuPXRoaXMueS50b0JpZ0ludGVnZXIoKTt2YXIgYz1sLngudG9CaWdJbnRlZ2VyKCk7dmFyIGs9bC55LnRvQmlnSW50ZWdlcigpO3ZhciBtPW8uc3F1YXJlKCk7dmFyIGk9bS5tdWx0aXBseShvKTt2YXIgZD1lLm11bHRpcGx5KG0pO3ZhciBnPXAuc3F1YXJlKCkubXVsdGlwbHkodGhpcy56KTt2YXIgYT1nLnN1YnRyYWN0KGQuc2hpZnRMZWZ0KDEpKS5tdWx0aXBseShsLnopLnN1YnRyYWN0KGkpLm11bHRpcGx5KG8pLm1vZCh0aGlzLmN1cnZlLnEpO3ZhciBoPWQubXVsdGlwbHkoaikubXVsdGlwbHkocCkuc3VidHJhY3Qobi5tdWx0aXBseShpKSkuc3VidHJhY3QoZy5tdWx0aXBseShwKSkubXVsdGlwbHkobC56KS5hZGQocC5tdWx0aXBseShpKSkubW9kKHRoaXMuY3VydmUucSk7dmFyIGY9aS5tdWx0aXBseSh0aGlzLnopLm11bHRpcGx5KGwueikubW9kKHRoaXMuY3VydmUucSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSx0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKGEpLHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoaCksZil9ZnVuY3Rpb24gcG9pbnRGcFR3aWNlKCl7aWYodGhpcy5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzfWlmKHRoaXMueS50b0JpZ0ludGVnZXIoKS5zaWdudW0oKT09MCl7cmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKX12YXIgZz1uZXcgQmlnSW50ZWdlcihcIjNcIik7dmFyIGM9dGhpcy54LnRvQmlnSW50ZWdlcigpO3ZhciBoPXRoaXMueS50b0JpZ0ludGVnZXIoKTt2YXIgZT1oLm11bHRpcGx5KHRoaXMueik7dmFyIGo9ZS5tdWx0aXBseShoKS5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgaT10aGlzLmN1cnZlLmEudG9CaWdJbnRlZ2VyKCk7dmFyIGs9Yy5zcXVhcmUoKS5tdWx0aXBseShnKTtpZighQmlnSW50ZWdlci5aRVJPLmVxdWFscyhpKSl7az1rLmFkZCh0aGlzLnouc3F1YXJlKCkubXVsdGlwbHkoaSkpfWs9ay5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgYj1rLnNxdWFyZSgpLnN1YnRyYWN0KGMuc2hpZnRMZWZ0KDMpLm11bHRpcGx5KGopKS5zaGlmdExlZnQoMSkubXVsdGlwbHkoZSkubW9kKHRoaXMuY3VydmUucSk7dmFyIGY9ay5tdWx0aXBseShnKS5tdWx0aXBseShjKS5zdWJ0cmFjdChqLnNoaWZ0TGVmdCgxKSkuc2hpZnRMZWZ0KDIpLm11bHRpcGx5KGopLnN1YnRyYWN0KGsuc3F1YXJlKCkubXVsdGlwbHkoaykpLm1vZCh0aGlzLmN1cnZlLnEpO3ZhciBkPWUuc3F1YXJlKCkubXVsdGlwbHkoZSkuc2hpZnRMZWZ0KDMpLm1vZCh0aGlzLmN1cnZlLnEpO3JldHVybiBuZXcgRUNQb2ludEZwKHRoaXMuY3VydmUsdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcihiKSx0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKGYpLGQpfWZ1bmN0aW9uIHBvaW50RnBNdWx0aXBseShiKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXN9aWYoYi5zaWdudW0oKT09MCl7cmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKX12YXIgZz1iO3ZhciBmPWcubXVsdGlwbHkobmV3IEJpZ0ludGVnZXIoXCIzXCIpKTt2YXIgbD10aGlzLm5lZ2F0ZSgpO3ZhciBkPXRoaXM7dmFyIGM7Zm9yKGM9Zi5iaXRMZW5ndGgoKS0yO2M+MDstLWMpe2Q9ZC50d2ljZSgpO3ZhciBhPWYudGVzdEJpdChjKTt2YXIgaj1nLnRlc3RCaXQoYyk7aWYoYSE9ail7ZD1kLmFkZChhP3RoaXM6bCl9fXJldHVybiBkfWZ1bmN0aW9uIHBvaW50RnBNdWx0aXBseVR3byhjLGEsYil7dmFyIGQ7aWYoYy5iaXRMZW5ndGgoKT5iLmJpdExlbmd0aCgpKXtkPWMuYml0TGVuZ3RoKCktMX1lbHNle2Q9Yi5iaXRMZW5ndGgoKS0xfXZhciBmPXRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKTt2YXIgZT10aGlzLmFkZChhKTt3aGlsZShkPj0wKXtmPWYudHdpY2UoKTtpZihjLnRlc3RCaXQoZCkpe2lmKGIudGVzdEJpdChkKSl7Zj1mLmFkZChlKX1lbHNle2Y9Zi5hZGQodGhpcyl9fWVsc2V7aWYoYi50ZXN0Qml0KGQpKXtmPWYuYWRkKGEpfX0tLWR9cmV0dXJuIGZ9RUNQb2ludEZwLnByb3RvdHlwZS5nZXRYPXBvaW50RnBHZXRYO0VDUG9pbnRGcC5wcm90b3R5cGUuZ2V0WT1wb2ludEZwR2V0WTtFQ1BvaW50RnAucHJvdG90eXBlLmVxdWFscz1wb2ludEZwRXF1YWxzO0VDUG9pbnRGcC5wcm90b3R5cGUuaXNJbmZpbml0eT1wb2ludEZwSXNJbmZpbml0eTtFQ1BvaW50RnAucHJvdG90eXBlLm5lZ2F0ZT1wb2ludEZwTmVnYXRlO0VDUG9pbnRGcC5wcm90b3R5cGUuYWRkPXBvaW50RnBBZGQ7RUNQb2ludEZwLnByb3RvdHlwZS50d2ljZT1wb2ludEZwVHdpY2U7RUNQb2ludEZwLnByb3RvdHlwZS5tdWx0aXBseT1wb2ludEZwTXVsdGlwbHk7RUNQb2ludEZwLnByb3RvdHlwZS5tdWx0aXBseVR3bz1wb2ludEZwTXVsdGlwbHlUd287ZnVuY3Rpb24gRUNDdXJ2ZUZwKGUsZCxjKXt0aGlzLnE9ZTt0aGlzLmE9dGhpcy5mcm9tQmlnSW50ZWdlcihkKTt0aGlzLmI9dGhpcy5mcm9tQmlnSW50ZWdlcihjKTt0aGlzLmluZmluaXR5PW5ldyBFQ1BvaW50RnAodGhpcyxudWxsLG51bGwpfWZ1bmN0aW9uIGN1cnZlRnBHZXRRKCl7cmV0dXJuIHRoaXMucX1mdW5jdGlvbiBjdXJ2ZUZwR2V0QSgpe3JldHVybiB0aGlzLmF9ZnVuY3Rpb24gY3VydmVGcEdldEIoKXtyZXR1cm4gdGhpcy5ifWZ1bmN0aW9uIGN1cnZlRnBFcXVhbHMoYSl7aWYoYT09dGhpcyl7cmV0dXJuIHRydWV9cmV0dXJuKHRoaXMucS5lcXVhbHMoYS5xKSYmdGhpcy5hLmVxdWFscyhhLmEpJiZ0aGlzLmIuZXF1YWxzKGEuYikpfWZ1bmN0aW9uIGN1cnZlRnBHZXRJbmZpbml0eSgpe3JldHVybiB0aGlzLmluZmluaXR5fWZ1bmN0aW9uIGN1cnZlRnBGcm9tQmlnSW50ZWdlcihhKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLGEpfWZ1bmN0aW9uIGN1cnZlRnBEZWNvZGVQb2ludEhleChkKXtzd2l0Y2gocGFyc2VJbnQoZC5zdWJzdHIoMCwyKSwxNikpe2Nhc2UgMDpyZXR1cm4gdGhpcy5pbmZpbml0eTtjYXNlIDI6Y2FzZSAzOnJldHVybiBudWxsO2Nhc2UgNDpjYXNlIDY6Y2FzZSA3OnZhciBhPShkLmxlbmd0aC0yKS8yO3ZhciBjPWQuc3Vic3RyKDIsYSk7dmFyIGI9ZC5zdWJzdHIoYSsyLGEpO3JldHVybiBuZXcgRUNQb2ludEZwKHRoaXMsdGhpcy5mcm9tQmlnSW50ZWdlcihuZXcgQmlnSW50ZWdlcihjLDE2KSksdGhpcy5mcm9tQmlnSW50ZWdlcihuZXcgQmlnSW50ZWdlcihiLDE2KSkpO2RlZmF1bHQ6cmV0dXJuIG51bGx9fUVDQ3VydmVGcC5wcm90b3R5cGUuZ2V0UT1jdXJ2ZUZwR2V0UTtFQ0N1cnZlRnAucHJvdG90eXBlLmdldEE9Y3VydmVGcEdldEE7RUNDdXJ2ZUZwLnByb3RvdHlwZS5nZXRCPWN1cnZlRnBHZXRCO0VDQ3VydmVGcC5wcm90b3R5cGUuZXF1YWxzPWN1cnZlRnBFcXVhbHM7RUNDdXJ2ZUZwLnByb3RvdHlwZS5nZXRJbmZpbml0eT1jdXJ2ZUZwR2V0SW5maW5pdHk7RUNDdXJ2ZUZwLnByb3RvdHlwZS5mcm9tQmlnSW50ZWdlcj1jdXJ2ZUZwRnJvbUJpZ0ludGVnZXI7RUNDdXJ2ZUZwLnByb3RvdHlwZS5kZWNvZGVQb2ludEhleD1jdXJ2ZUZwRGVjb2RlUG9pbnRIZXg7XG4vKiEgKGMpIFN0ZWZhbiBUaG9tYXMgfCBodHRwczovL2dpdGh1Yi5jb20vYml0Y29pbmpzL2JpdGNvaW5qcy1saWJcclxuICovXHJcbkVDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLmdldEJ5dGVMZW5ndGg9ZnVuY3Rpb24oKXtyZXR1cm4gTWF0aC5mbG9vcigodGhpcy50b0JpZ0ludGVnZXIoKS5iaXRMZW5ndGgoKSs3KS84KX07RUNQb2ludEZwLnByb3RvdHlwZS5nZXRFbmNvZGVkPWZ1bmN0aW9uKGMpe3ZhciBkPWZ1bmN0aW9uKGgsZil7dmFyIGc9aC50b0J5dGVBcnJheVVuc2lnbmVkKCk7aWYoZjxnLmxlbmd0aCl7Zz1nLnNsaWNlKGcubGVuZ3RoLWYpfWVsc2V7d2hpbGUoZj5nLmxlbmd0aCl7Zy51bnNoaWZ0KDApfX1yZXR1cm4gZ307dmFyIGE9dGhpcy5nZXRYKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGU9dGhpcy5nZXRZKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGI9ZChhLDMyKTtpZihjKXtpZihlLmlzRXZlbigpKXtiLnVuc2hpZnQoMil9ZWxzZXtiLnVuc2hpZnQoMyl9fWVsc2V7Yi51bnNoaWZ0KDQpO2I9Yi5jb25jYXQoZChlLDMyKSl9cmV0dXJuIGJ9O0VDUG9pbnRGcC5kZWNvZGVGcm9tPWZ1bmN0aW9uKGcsYyl7dmFyIGY9Y1swXTt2YXIgZT1jLmxlbmd0aC0xO3ZhciBkPWMuc2xpY2UoMSwxK2UvMik7dmFyIGI9Yy5zbGljZSgxK2UvMiwxK2UpO2QudW5zaGlmdCgwKTtiLnVuc2hpZnQoMCk7dmFyIGE9bmV3IEJpZ0ludGVnZXIoZCk7dmFyIGg9bmV3IEJpZ0ludGVnZXIoYik7cmV0dXJuIG5ldyBFQ1BvaW50RnAoZyxnLmZyb21CaWdJbnRlZ2VyKGEpLGcuZnJvbUJpZ0ludGVnZXIoaCkpfTtFQ1BvaW50RnAuZGVjb2RlRnJvbUhleD1mdW5jdGlvbihnLGMpe3ZhciBmPWMuc3Vic3RyKDAsMik7dmFyIGU9Yy5sZW5ndGgtMjt2YXIgZD1jLnN1YnN0cigyLGUvMik7dmFyIGI9Yy5zdWJzdHIoMitlLzIsZS8yKTt2YXIgYT1uZXcgQmlnSW50ZWdlcihkLDE2KTt2YXIgaD1uZXcgQmlnSW50ZWdlcihiLDE2KTtyZXR1cm4gbmV3IEVDUG9pbnRGcChnLGcuZnJvbUJpZ0ludGVnZXIoYSksZy5mcm9tQmlnSW50ZWdlcihoKSl9O0VDUG9pbnRGcC5wcm90b3R5cGUuYWRkMkQ9ZnVuY3Rpb24oYyl7aWYodGhpcy5pc0luZmluaXR5KCkpe3JldHVybiBjfWlmKGMuaXNJbmZpbml0eSgpKXtyZXR1cm4gdGhpc31pZih0aGlzLnguZXF1YWxzKGMueCkpe2lmKHRoaXMueS5lcXVhbHMoYy55KSl7cmV0dXJuIHRoaXMudHdpY2UoKX1yZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBnPWMueC5zdWJ0cmFjdCh0aGlzLngpO3ZhciBlPWMueS5zdWJ0cmFjdCh0aGlzLnkpO3ZhciBhPWUuZGl2aWRlKGcpO3ZhciBkPWEuc3F1YXJlKCkuc3VidHJhY3QodGhpcy54KS5zdWJ0cmFjdChjLngpO3ZhciBmPWEubXVsdGlwbHkodGhpcy54LnN1YnRyYWN0KGQpKS5zdWJ0cmFjdCh0aGlzLnkpO3JldHVybiBuZXcgRUNQb2ludEZwKHRoaXMuY3VydmUsZCxmKX07RUNQb2ludEZwLnByb3RvdHlwZS50d2ljZTJEPWZ1bmN0aW9uKCl7aWYodGhpcy5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzfWlmKHRoaXMueS50b0JpZ0ludGVnZXIoKS5zaWdudW0oKT09MCl7cmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKX12YXIgYj10aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKEJpZ0ludGVnZXIudmFsdWVPZigyKSk7dmFyIGU9dGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcihCaWdJbnRlZ2VyLnZhbHVlT2YoMykpO3ZhciBhPXRoaXMueC5zcXVhcmUoKS5tdWx0aXBseShlKS5hZGQodGhpcy5jdXJ2ZS5hKS5kaXZpZGUodGhpcy55Lm11bHRpcGx5KGIpKTt2YXIgYz1hLnNxdWFyZSgpLnN1YnRyYWN0KHRoaXMueC5tdWx0aXBseShiKSk7dmFyIGQ9YS5tdWx0aXBseSh0aGlzLnguc3VidHJhY3QoYykpLnN1YnRyYWN0KHRoaXMueSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSxjLGQpfTtFQ1BvaW50RnAucHJvdG90eXBlLm11bHRpcGx5MkQ9ZnVuY3Rpb24oYil7aWYodGhpcy5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzfWlmKGIuc2lnbnVtKCk9PTApe3JldHVybiB0aGlzLmN1cnZlLmdldEluZmluaXR5KCl9dmFyIGc9Yjt2YXIgZj1nLm11bHRpcGx5KG5ldyBCaWdJbnRlZ2VyKFwiM1wiKSk7dmFyIGw9dGhpcy5uZWdhdGUoKTt2YXIgZD10aGlzO3ZhciBjO2ZvcihjPWYuYml0TGVuZ3RoKCktMjtjPjA7LS1jKXtkPWQudHdpY2UoKTt2YXIgYT1mLnRlc3RCaXQoYyk7dmFyIGo9Zy50ZXN0Qml0KGMpO2lmKGEhPWope2Q9ZC5hZGQyRChhP3RoaXM6bCl9fXJldHVybiBkfTtFQ1BvaW50RnAucHJvdG90eXBlLmlzT25DdXJ2ZT1mdW5jdGlvbigpe3ZhciBkPXRoaXMuZ2V0WCgpLnRvQmlnSW50ZWdlcigpO3ZhciBpPXRoaXMuZ2V0WSgpLnRvQmlnSW50ZWdlcigpO3ZhciBmPXRoaXMuY3VydmUuZ2V0QSgpLnRvQmlnSW50ZWdlcigpO3ZhciBjPXRoaXMuY3VydmUuZ2V0QigpLnRvQmlnSW50ZWdlcigpO3ZhciBoPXRoaXMuY3VydmUuZ2V0USgpO3ZhciBlPWkubXVsdGlwbHkoaSkubW9kKGgpO3ZhciBnPWQubXVsdGlwbHkoZCkubXVsdGlwbHkoZCkuYWRkKGYubXVsdGlwbHkoZCkpLmFkZChjKS5tb2QoaCk7cmV0dXJuIGUuZXF1YWxzKGcpfTtFQ1BvaW50RnAucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuXCIoXCIrdGhpcy5nZXRYKCkudG9CaWdJbnRlZ2VyKCkudG9TdHJpbmcoKStcIixcIit0aGlzLmdldFkoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygpK1wiKVwifTtFQ1BvaW50RnAucHJvdG90eXBlLnZhbGlkYXRlPWZ1bmN0aW9uKCl7dmFyIGM9dGhpcy5jdXJ2ZS5nZXRRKCk7aWYodGhpcy5pc0luZmluaXR5KCkpe3Rocm93IG5ldyBFcnJvcihcIlBvaW50IGlzIGF0IGluZmluaXR5LlwiKX12YXIgYT10aGlzLmdldFgoKS50b0JpZ0ludGVnZXIoKTt2YXIgYj10aGlzLmdldFkoKS50b0JpZ0ludGVnZXIoKTtpZihhLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSk8MHx8YS5jb21wYXJlVG8oYy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpPjApe3Rocm93IG5ldyBFcnJvcihcInggY29vcmRpbmF0ZSBvdXQgb2YgYm91bmRzXCIpfWlmKGIuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKTwwfHxiLmNvbXBhcmVUbyhjLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSk+MCl7dGhyb3cgbmV3IEVycm9yKFwieSBjb29yZGluYXRlIG91dCBvZiBib3VuZHNcIil9aWYoIXRoaXMuaXNPbkN1cnZlKCkpe3Rocm93IG5ldyBFcnJvcihcIlBvaW50IGlzIG5vdCBvbiB0aGUgY3VydmUuXCIpfWlmKHRoaXMubXVsdGlwbHkoYykuaXNJbmZpbml0eSgpKXt0aHJvdyBuZXcgRXJyb3IoXCJQb2ludCBpcyBub3QgYSBzY2FsYXIgbXVsdGlwbGUgb2YgRy5cIil9cmV0dXJuIHRydWV9O1xuLyohIE1pa2UgU2FtdWVsIChjKSAyMDA5IHwgY29kZS5nb29nbGUuY29tL3AvanNvbi1zYW5zLWV2YWxcclxuICovXHJcbnZhciBqc29uUGFyc2U9KGZ1bmN0aW9uKCl7dmFyIGU9XCIoPzotP1xcXFxiKD86MHxbMS05XVswLTldKikoPzpcXFxcLlswLTldKyk/KD86W2VFXVsrLV0/WzAtOV0rKT9cXFxcYilcIjt2YXIgaj0nKD86W15cXFxcMC1cXFxceDA4XFxcXHgwYS1cXFxceDFmXCJcXFxcXFxcXF18XFxcXFxcXFwoPzpbXCIvXFxcXFxcXFxiZm5ydF18dVswLTlBLUZhLWZdezR9KSknO3ZhciBpPScoPzpcIicraisnKlwiKSc7dmFyIGQ9bmV3IFJlZ0V4cChcIig/OmZhbHNlfHRydWV8bnVsbHxbXFxcXHtcXFxcfVxcXFxbXFxcXF1dfFwiK2UrXCJ8XCIraStcIilcIixcImdcIik7dmFyIGs9bmV3IFJlZ0V4cChcIlxcXFxcXFxcKD86KFtedV0pfHUoLns0fSkpXCIsXCJnXCIpO3ZhciBnPXsnXCInOidcIicsXCIvXCI6XCIvXCIsXCJcXFxcXCI6XCJcXFxcXCIsYjpcIlxcYlwiLGY6XCJcXGZcIixuOlwiXFxuXCIscjpcIlxcclwiLHQ6XCJcXHRcIn07ZnVuY3Rpb24gaChsLG0sbil7cmV0dXJuIG0/Z1ttXTpTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KG4sMTYpKX12YXIgYz1uZXcgU3RyaW5nKFwiXCIpO3ZhciBhPVwiXFxcXFwiO3ZhciBmPXtcIntcIjpPYmplY3QsXCJbXCI6QXJyYXl9O3ZhciBiPU9iamVjdC5oYXNPd25Qcm9wZXJ0eTtyZXR1cm4gZnVuY3Rpb24odSxxKXt2YXIgcD11Lm1hdGNoKGQpO3ZhciB4O3ZhciB2PXBbMF07dmFyIGw9ZmFsc2U7aWYoXCJ7XCI9PT12KXt4PXt9fWVsc2V7aWYoXCJbXCI9PT12KXt4PVtdfWVsc2V7eD1bXTtsPXRydWV9fXZhciB0O3ZhciByPVt4XTtmb3IodmFyIG89MS1sLG09cC5sZW5ndGg7bzxtOysrbyl7dj1wW29dO3ZhciB3O3N3aXRjaCh2LmNoYXJDb2RlQXQoMCkpe2RlZmF1bHQ6dz1yWzBdO3dbdHx8dy5sZW5ndGhdPSsodik7dD12b2lkIDA7YnJlYWs7Y2FzZSAzNDp2PXYuc3Vic3RyaW5nKDEsdi5sZW5ndGgtMSk7aWYodi5pbmRleE9mKGEpIT09LTEpe3Y9di5yZXBsYWNlKGssaCl9dz1yWzBdO2lmKCF0KXtpZih3IGluc3RhbmNlb2YgQXJyYXkpe3Q9dy5sZW5ndGh9ZWxzZXt0PXZ8fGM7YnJlYWt9fXdbdF09djt0PXZvaWQgMDticmVhaztjYXNlIDkxOnc9clswXTtyLnVuc2hpZnQod1t0fHx3Lmxlbmd0aF09W10pO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgOTM6ci5zaGlmdCgpO2JyZWFrO2Nhc2UgMTAyOnc9clswXTt3W3R8fHcubGVuZ3RoXT1mYWxzZTt0PXZvaWQgMDticmVhaztjYXNlIDExMDp3PXJbMF07d1t0fHx3Lmxlbmd0aF09bnVsbDt0PXZvaWQgMDticmVhaztjYXNlIDExNjp3PXJbMF07d1t0fHx3Lmxlbmd0aF09dHJ1ZTt0PXZvaWQgMDticmVhaztjYXNlIDEyMzp3PXJbMF07ci51bnNoaWZ0KHdbdHx8dy5sZW5ndGhdPXt9KTt0PXZvaWQgMDticmVhaztjYXNlIDEyNTpyLnNoaWZ0KCk7YnJlYWt9fWlmKGwpe2lmKHIubGVuZ3RoIT09MSl7dGhyb3cgbmV3IEVycm9yKCl9eD14WzBdfWVsc2V7aWYoci5sZW5ndGgpe3Rocm93IG5ldyBFcnJvcigpfX1pZihxKXt2YXIgcz1mdW5jdGlvbihDLEIpe3ZhciBEPUNbQl07aWYoRCYmdHlwZW9mIEQ9PT1cIm9iamVjdFwiKXt2YXIgbj1udWxsO2Zvcih2YXIgeiBpbiBEKXtpZihiLmNhbGwoRCx6KSYmRCE9PUMpe3ZhciB5PXMoRCx6KTtpZih5IT09dm9pZCAwKXtEW3pdPXl9ZWxzZXtpZighbil7bj1bXX1uLnB1c2goeil9fX1pZihuKXtmb3IodmFyIEE9bi5sZW5ndGg7LS1BPj0wOyl7ZGVsZXRlIERbbltBXV19fX1yZXR1cm4gcS5jYWxsKEMsQixEKX07eD1zKHtcIlwiOnh9LFwiXCIpfXJldHVybiB4fX0pKCk7XG5pZih0eXBlb2YgS0pVUj09XCJ1bmRlZmluZWRcInx8IUtKVVIpe0tKVVI9e319aWYodHlwZW9mIEtKVVIuYXNuMT09XCJ1bmRlZmluZWRcInx8IUtKVVIuYXNuMSl7S0pVUi5hc24xPXt9fUtKVVIuYXNuMS5BU04xVXRpbD1uZXcgZnVuY3Rpb24oKXt0aGlzLmludGVnZXJUb0J5dGVIZXg9ZnVuY3Rpb24oYSl7dmFyIGI9YS50b1N0cmluZygxNik7aWYoKGIubGVuZ3RoJTIpPT0xKXtiPVwiMFwiK2J9cmV0dXJuIGJ9O3RoaXMuYmlnSW50VG9NaW5Ud29zQ29tcGxlbWVudHNIZXg9ZnVuY3Rpb24oail7dmFyIGY9ai50b1N0cmluZygxNik7aWYoZi5zdWJzdHIoMCwxKSE9XCItXCIpe2lmKGYubGVuZ3RoJTI9PTEpe2Y9XCIwXCIrZn1lbHNle2lmKCFmLm1hdGNoKC9eWzAtN10vKSl7Zj1cIjAwXCIrZn19fWVsc2V7dmFyIGE9Zi5zdWJzdHIoMSk7dmFyIGU9YS5sZW5ndGg7aWYoZSUyPT0xKXtlKz0xfWVsc2V7aWYoIWYubWF0Y2goL15bMC03XS8pKXtlKz0yfX12YXIgZz1cIlwiO2Zvcih2YXIgZD0wO2Q8ZTtkKyspe2crPVwiZlwifXZhciBjPW5ldyBCaWdJbnRlZ2VyKGcsMTYpO3ZhciBiPWMueG9yKGopLmFkZChCaWdJbnRlZ2VyLk9ORSk7Zj1iLnRvU3RyaW5nKDE2KS5yZXBsYWNlKC9eLS8sXCJcIil9cmV0dXJuIGZ9O3RoaXMuZ2V0UEVNU3RyaW5nRnJvbUhleD1mdW5jdGlvbihhLGIpe3JldHVybiBoZXh0b3BlbShhLGIpfTt0aGlzLm5ld09iamVjdD1mdW5jdGlvbihrKXt2YXIgRD1LSlVSLG49RC5hc24xLHo9bi5ERVJCb29sZWFuLGU9bi5ERVJJbnRlZ2VyLHM9bi5ERVJCaXRTdHJpbmcsaD1uLkRFUk9jdGV0U3RyaW5nLHY9bi5ERVJOdWxsLHc9bi5ERVJPYmplY3RJZGVudGlmaWVyLGw9bi5ERVJFbnVtZXJhdGVkLGc9bi5ERVJVVEY4U3RyaW5nLGY9bi5ERVJOdW1lcmljU3RyaW5nLHk9bi5ERVJQcmludGFibGVTdHJpbmcsdT1uLkRFUlRlbGV0ZXhTdHJpbmcscD1uLkRFUklBNVN0cmluZyxDPW4uREVSVVRDVGltZSxqPW4uREVSR2VuZXJhbGl6ZWRUaW1lLG09bi5ERVJTZXF1ZW5jZSxjPW4uREVSU2V0LHI9bi5ERVJUYWdnZWRPYmplY3Qsbz1uLkFTTjFVdGlsLm5ld09iamVjdDt2YXIgdD1PYmplY3Qua2V5cyhrKTtpZih0Lmxlbmd0aCE9MSl7dGhyb3dcImtleSBvZiBwYXJhbSBzaGFsbCBiZSBvbmx5IG9uZS5cIn12YXIgRj10WzBdO2lmKFwiOmJvb2w6aW50OmJpdHN0cjpvY3RzdHI6bnVsbDpvaWQ6ZW51bTp1dGY4c3RyOm51bXN0cjpwcm5zdHI6dGVsc3RyOmlhNXN0cjp1dGN0aW1lOmdlbnRpbWU6c2VxOnNldDp0YWc6XCIuaW5kZXhPZihcIjpcIitGK1wiOlwiKT09LTEpe3Rocm93XCJ1bmRlZmluZWQga2V5OiBcIitGfWlmKEY9PVwiYm9vbFwiKXtyZXR1cm4gbmV3IHooa1tGXSl9aWYoRj09XCJpbnRcIil7cmV0dXJuIG5ldyBlKGtbRl0pfWlmKEY9PVwiYml0c3RyXCIpe3JldHVybiBuZXcgcyhrW0ZdKX1pZihGPT1cIm9jdHN0clwiKXtyZXR1cm4gbmV3IGgoa1tGXSl9aWYoRj09XCJudWxsXCIpe3JldHVybiBuZXcgdihrW0ZdKX1pZihGPT1cIm9pZFwiKXtyZXR1cm4gbmV3IHcoa1tGXSl9aWYoRj09XCJlbnVtXCIpe3JldHVybiBuZXcgbChrW0ZdKX1pZihGPT1cInV0ZjhzdHJcIil7cmV0dXJuIG5ldyBnKGtbRl0pfWlmKEY9PVwibnVtc3RyXCIpe3JldHVybiBuZXcgZihrW0ZdKX1pZihGPT1cInBybnN0clwiKXtyZXR1cm4gbmV3IHkoa1tGXSl9aWYoRj09XCJ0ZWxzdHJcIil7cmV0dXJuIG5ldyB1KGtbRl0pfWlmKEY9PVwiaWE1c3RyXCIpe3JldHVybiBuZXcgcChrW0ZdKX1pZihGPT1cInV0Y3RpbWVcIil7cmV0dXJuIG5ldyBDKGtbRl0pfWlmKEY9PVwiZ2VudGltZVwiKXtyZXR1cm4gbmV3IGooa1tGXSl9aWYoRj09XCJzZXFcIil7dmFyIGQ9a1tGXTt2YXIgRT1bXTtmb3IodmFyIHg9MDt4PGQubGVuZ3RoO3grKyl7dmFyIEI9byhkW3hdKTtFLnB1c2goQil9cmV0dXJuIG5ldyBtKHthcnJheTpFfSl9aWYoRj09XCJzZXRcIil7dmFyIGQ9a1tGXTt2YXIgRT1bXTtmb3IodmFyIHg9MDt4PGQubGVuZ3RoO3grKyl7dmFyIEI9byhkW3hdKTtFLnB1c2goQil9cmV0dXJuIG5ldyBjKHthcnJheTpFfSl9aWYoRj09XCJ0YWdcIil7dmFyIEE9a1tGXTtpZihPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoQSk9PT1cIltvYmplY3QgQXJyYXldXCImJkEubGVuZ3RoPT0zKXt2YXIgcT1vKEFbMl0pO3JldHVybiBuZXcgcih7dGFnOkFbMF0sZXhwbGljaXQ6QVsxXSxvYmo6cX0pfWVsc2V7dmFyIGI9e307aWYoQS5leHBsaWNpdCE9PXVuZGVmaW5lZCl7Yi5leHBsaWNpdD1BLmV4cGxpY2l0fWlmKEEudGFnIT09dW5kZWZpbmVkKXtiLnRhZz1BLnRhZ31pZihBLm9iaj09PXVuZGVmaW5lZCl7dGhyb3dcIm9iaiBzaGFsbCBiZSBzcGVjaWZpZWQgZm9yICd0YWcnLlwifWIub2JqPW8oQS5vYmopO3JldHVybiBuZXcgcihiKX19fTt0aGlzLmpzb25Ub0FTTjFIRVg9ZnVuY3Rpb24oYil7dmFyIGE9dGhpcy5uZXdPYmplY3QoYik7cmV0dXJuIGEuZ2V0RW5jb2RlZEhleCgpfX07S0pVUi5hc24xLkFTTjFVdGlsLm9pZEhleFRvSW50PWZ1bmN0aW9uKGEpe3ZhciBqPVwiXCI7dmFyIGs9cGFyc2VJbnQoYS5zdWJzdHIoMCwyKSwxNik7dmFyIGQ9TWF0aC5mbG9vcihrLzQwKTt2YXIgYz1rJTQwO3ZhciBqPWQrXCIuXCIrYzt2YXIgZT1cIlwiO2Zvcih2YXIgZj0yO2Y8YS5sZW5ndGg7Zis9Mil7dmFyIGc9cGFyc2VJbnQoYS5zdWJzdHIoZiwyKSwxNik7dmFyIGg9KFwiMDAwMDAwMDBcIitnLnRvU3RyaW5nKDIpKS5zbGljZSgtOCk7ZT1lK2guc3Vic3RyKDEsNyk7aWYoaC5zdWJzdHIoMCwxKT09XCIwXCIpe3ZhciBiPW5ldyBCaWdJbnRlZ2VyKGUsMik7aj1qK1wiLlwiK2IudG9TdHJpbmcoMTApO2U9XCJcIn19cmV0dXJuIGp9O0tKVVIuYXNuMS5BU04xVXRpbC5vaWRJbnRUb0hleD1mdW5jdGlvbihmKXt2YXIgZT1mdW5jdGlvbihhKXt2YXIgaz1hLnRvU3RyaW5nKDE2KTtpZihrLmxlbmd0aD09MSl7az1cIjBcIitrfXJldHVybiBrfTt2YXIgZD1mdW5jdGlvbihvKXt2YXIgbj1cIlwiO3ZhciBrPW5ldyBCaWdJbnRlZ2VyKG8sMTApO3ZhciBhPWsudG9TdHJpbmcoMik7dmFyIGw9Ny1hLmxlbmd0aCU3O2lmKGw9PTcpe2w9MH12YXIgcT1cIlwiO2Zvcih2YXIgbT0wO208bDttKyspe3ErPVwiMFwifWE9cSthO2Zvcih2YXIgbT0wO208YS5sZW5ndGgtMTttKz03KXt2YXIgcD1hLnN1YnN0cihtLDcpO2lmKG0hPWEubGVuZ3RoLTcpe3A9XCIxXCIrcH1uKz1lKHBhcnNlSW50KHAsMikpfXJldHVybiBufTtpZighZi5tYXRjaCgvXlswLTkuXSskLykpe3Rocm93XCJtYWxmb3JtZWQgb2lkIHN0cmluZzogXCIrZn12YXIgZz1cIlwiO3ZhciBiPWYuc3BsaXQoXCIuXCIpO3ZhciBqPXBhcnNlSW50KGJbMF0pKjQwK3BhcnNlSW50KGJbMV0pO2crPWUoaik7Yi5zcGxpY2UoMCwyKTtmb3IodmFyIGM9MDtjPGIubGVuZ3RoO2MrKyl7Zys9ZChiW2NdKX1yZXR1cm4gZ307S0pVUi5hc24xLkFTTjFPYmplY3Q9ZnVuY3Rpb24oKXt2YXIgYz10cnVlO3ZhciBiPW51bGw7dmFyIGQ9XCIwMFwiO3ZhciBlPVwiMDBcIjt2YXIgYT1cIlwiO3RoaXMuZ2V0TGVuZ3RoSGV4RnJvbVZhbHVlPWZ1bmN0aW9uKCl7aWYodHlwZW9mIHRoaXMuaFY9PVwidW5kZWZpbmVkXCJ8fHRoaXMuaFY9PW51bGwpe3Rocm93XCJ0aGlzLmhWIGlzIG51bGwgb3IgdW5kZWZpbmVkLlwifWlmKHRoaXMuaFYubGVuZ3RoJTI9PTEpe3Rocm93XCJ2YWx1ZSBoZXggbXVzdCBiZSBldmVuIGxlbmd0aDogbj1cIithLmxlbmd0aCtcIix2PVwiK3RoaXMuaFZ9dmFyIGk9dGhpcy5oVi5sZW5ndGgvMjt2YXIgaD1pLnRvU3RyaW5nKDE2KTtpZihoLmxlbmd0aCUyPT0xKXtoPVwiMFwiK2h9aWYoaTwxMjgpe3JldHVybiBofWVsc2V7dmFyIGc9aC5sZW5ndGgvMjtpZihnPjE1KXt0aHJvd1wiQVNOLjEgbGVuZ3RoIHRvbyBsb25nIHRvIHJlcHJlc2VudCBieSA4eDogbiA9IFwiK2kudG9TdHJpbmcoMTYpfXZhciBmPTEyOCtnO3JldHVybiBmLnRvU3RyaW5nKDE2KStofX07dGhpcy5nZXRFbmNvZGVkSGV4PWZ1bmN0aW9uKCl7aWYodGhpcy5oVExWPT1udWxsfHx0aGlzLmlzTW9kaWZpZWQpe3RoaXMuaFY9dGhpcy5nZXRGcmVzaFZhbHVlSGV4KCk7dGhpcy5oTD10aGlzLmdldExlbmd0aEhleEZyb21WYWx1ZSgpO3RoaXMuaFRMVj10aGlzLmhUK3RoaXMuaEwrdGhpcy5oVjt0aGlzLmlzTW9kaWZpZWQ9ZmFsc2V9cmV0dXJuIHRoaXMuaFRMVn07dGhpcy5nZXRWYWx1ZUhleD1mdW5jdGlvbigpe3RoaXMuZ2V0RW5jb2RlZEhleCgpO3JldHVybiB0aGlzLmhWfTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm5cIlwifX07S0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nPWZ1bmN0aW9uKGMpe0tKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZy5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dmFyIGI9bnVsbDt2YXIgYT1udWxsO3RoaXMuZ2V0U3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuc307dGhpcy5zZXRTdHJpbmc9ZnVuY3Rpb24oZCl7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5zPWQ7dGhpcy5oVj11dGY4dG9oZXgodGhpcy5zKS50b0xvd2VyQ2FzZSgpfTt0aGlzLnNldFN0cmluZ0hleD1mdW5jdGlvbihkKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLnM9bnVsbDt0aGlzLmhWPWR9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYyE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGM9PVwic3RyaW5nXCIpe3RoaXMuc2V0U3RyaW5nKGMpfWVsc2V7aWYodHlwZW9mIGMuc3RyIT1cInVuZGVmaW5lZFwiKXt0aGlzLnNldFN0cmluZyhjLnN0cil9ZWxzZXtpZih0eXBlb2YgYy5oZXghPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0U3RyaW5nSGV4KGMuaGV4KX19fX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyxLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUkFic3RyYWN0VGltZT1mdW5jdGlvbihjKXtLSlVSLmFzbjEuREVSQWJzdHJhY3RUaW1lLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt2YXIgYj1udWxsO3ZhciBhPW51bGw7dGhpcy5sb2NhbERhdGVUb1VUQz1mdW5jdGlvbihmKXt1dGM9Zi5nZXRUaW1lKCkrKGYuZ2V0VGltZXpvbmVPZmZzZXQoKSo2MDAwMCk7dmFyIGU9bmV3IERhdGUodXRjKTtyZXR1cm4gZX07dGhpcy5mb3JtYXREYXRlPWZ1bmN0aW9uKG0sbyxlKXt2YXIgZz10aGlzLnplcm9QYWRkaW5nO3ZhciBuPXRoaXMubG9jYWxEYXRlVG9VVEMobSk7dmFyIHA9U3RyaW5nKG4uZ2V0RnVsbFllYXIoKSk7aWYobz09XCJ1dGNcIil7cD1wLnN1YnN0cigyLDIpfXZhciBsPWcoU3RyaW5nKG4uZ2V0TW9udGgoKSsxKSwyKTt2YXIgcT1nKFN0cmluZyhuLmdldERhdGUoKSksMik7dmFyIGg9ZyhTdHJpbmcobi5nZXRIb3VycygpKSwyKTt2YXIgaT1nKFN0cmluZyhuLmdldE1pbnV0ZXMoKSksMik7dmFyIGo9ZyhTdHJpbmcobi5nZXRTZWNvbmRzKCkpLDIpO3ZhciByPXArbCtxK2graStqO2lmKGU9PT10cnVlKXt2YXIgZj1uLmdldE1pbGxpc2Vjb25kcygpO2lmKGYhPTApe3ZhciBrPWcoU3RyaW5nKGYpLDMpO2s9ay5yZXBsYWNlKC9bMF0rJC8sXCJcIik7cj1yK1wiLlwiK2t9fXJldHVybiByK1wiWlwifTt0aGlzLnplcm9QYWRkaW5nPWZ1bmN0aW9uKGUsZCl7aWYoZS5sZW5ndGg+PWQpe3JldHVybiBlfXJldHVybiBuZXcgQXJyYXkoZC1lLmxlbmd0aCsxKS5qb2luKFwiMFwiKStlfTt0aGlzLmdldFN0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnN9O3RoaXMuc2V0U3RyaW5nPWZ1bmN0aW9uKGQpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMucz1kO3RoaXMuaFY9c3RvaGV4KGQpfTt0aGlzLnNldEJ5RGF0ZVZhbHVlPWZ1bmN0aW9uKGgsaixlLGQsZixnKXt2YXIgaT1uZXcgRGF0ZShEYXRlLlVUQyhoLGotMSxlLGQsZixnLDApKTt0aGlzLnNldEJ5RGF0ZShpKX07dGhpcy5nZXRGcmVzaFZhbHVlSGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaFZ9fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSQWJzdHJhY3RUaW1lLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJ1Y3R1cmVkPWZ1bmN0aW9uKGIpe0tKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZy5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dmFyIGE9bnVsbDt0aGlzLnNldEJ5QVNOMU9iamVjdEFycmF5PWZ1bmN0aW9uKGMpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMuYXNuMUFycmF5PWN9O3RoaXMuYXBwZW5kQVNOMU9iamVjdD1mdW5jdGlvbihjKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmFzbjFBcnJheS5wdXNoKGMpfTt0aGlzLmFzbjFBcnJheT1uZXcgQXJyYXkoKTtpZih0eXBlb2YgYiE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGIuYXJyYXkhPVwidW5kZWZpbmVkXCIpe3RoaXMuYXNuMUFycmF5PWIuYXJyYXl9fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkFic3RyYWN0U3RydWN0dXJlZCxLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUkJvb2xlYW49ZnVuY3Rpb24oKXtLSlVSLmFzbjEuREVSQm9vbGVhbi5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjAxXCI7dGhpcy5oVExWPVwiMDEwMWZmXCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJCb29sZWFuLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSSW50ZWdlcj1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSSW50ZWdlci5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjAyXCI7dGhpcy5zZXRCeUJpZ0ludGVnZXI9ZnVuY3Rpb24oYil7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5oVj1LSlVSLmFzbjEuQVNOMVV0aWwuYmlnSW50VG9NaW5Ud29zQ29tcGxlbWVudHNIZXgoYil9O3RoaXMuc2V0QnlJbnRlZ2VyPWZ1bmN0aW9uKGMpe3ZhciBiPW5ldyBCaWdJbnRlZ2VyKFN0cmluZyhjKSwxMCk7dGhpcy5zZXRCeUJpZ0ludGVnZXIoYil9O3RoaXMuc2V0VmFsdWVIZXg9ZnVuY3Rpb24oYil7dGhpcy5oVj1ifTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn07aWYodHlwZW9mIGEhPVwidW5kZWZpbmVkXCIpe2lmKHR5cGVvZiBhLmJpZ2ludCE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUJpZ0ludGVnZXIoYS5iaWdpbnQpfWVsc2V7aWYodHlwZW9mIGFbXCJpbnRcIl0hPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0QnlJbnRlZ2VyKGFbXCJpbnRcIl0pfWVsc2V7aWYodHlwZW9mIGE9PVwibnVtYmVyXCIpe3RoaXMuc2V0QnlJbnRlZ2VyKGEpfWVsc2V7aWYodHlwZW9mIGEuaGV4IT1cInVuZGVmaW5lZFwiKXt0aGlzLnNldFZhbHVlSGV4KGEuaGV4KX19fX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSSW50ZWdlcixLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUkJpdFN0cmluZz1mdW5jdGlvbihiKXtpZihiIT09dW5kZWZpbmVkJiZ0eXBlb2YgYi5vYmohPT1cInVuZGVmaW5lZFwiKXt2YXIgYT1LSlVSLmFzbjEuQVNOMVV0aWwubmV3T2JqZWN0KGIub2JqKTtiLmhleD1cIjAwXCIrYS5nZXRFbmNvZGVkSGV4KCl9S0pVUi5hc24xLkRFUkJpdFN0cmluZy5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjAzXCI7dGhpcy5zZXRIZXhWYWx1ZUluY2x1ZGluZ1VudXNlZEJpdHM9ZnVuY3Rpb24oYyl7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5oVj1jfTt0aGlzLnNldFVudXNlZEJpdHNBbmRIZXhWYWx1ZT1mdW5jdGlvbihjLGUpe2lmKGM8MHx8NzxjKXt0aHJvd1widW51c2VkIGJpdHMgc2hhbGwgYmUgZnJvbSAwIHRvIDc6IHUgPSBcIitjfXZhciBkPVwiMFwiK2M7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5oVj1kK2V9O3RoaXMuc2V0QnlCaW5hcnlTdHJpbmc9ZnVuY3Rpb24oZSl7ZT1lLnJlcGxhY2UoLzArJC8sXCJcIik7dmFyIGY9OC1lLmxlbmd0aCU4O2lmKGY9PTgpe2Y9MH1mb3IodmFyIGc9MDtnPD1mO2crKyl7ZSs9XCIwXCJ9dmFyIGo9XCJcIjtmb3IodmFyIGc9MDtnPGUubGVuZ3RoLTE7Zys9OCl7dmFyIGQ9ZS5zdWJzdHIoZyw4KTt2YXIgYz1wYXJzZUludChkLDIpLnRvU3RyaW5nKDE2KTtpZihjLmxlbmd0aD09MSl7Yz1cIjBcIitjfWorPWN9dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5oVj1cIjBcIitmK2p9O3RoaXMuc2V0QnlCb29sZWFuQXJyYXk9ZnVuY3Rpb24oZSl7dmFyIGQ9XCJcIjtmb3IodmFyIGM9MDtjPGUubGVuZ3RoO2MrKyl7aWYoZVtjXT09dHJ1ZSl7ZCs9XCIxXCJ9ZWxzZXtkKz1cIjBcIn19dGhpcy5zZXRCeUJpbmFyeVN0cmluZyhkKX07dGhpcy5uZXdGYWxzZUFycmF5PWZ1bmN0aW9uKGUpe3ZhciBjPW5ldyBBcnJheShlKTtmb3IodmFyIGQ9MDtkPGU7ZCsrKXtjW2RdPWZhbHNlfXJldHVybiBjfTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn07aWYodHlwZW9mIGIhPVwidW5kZWZpbmVkXCIpe2lmKHR5cGVvZiBiPT1cInN0cmluZ1wiJiZiLnRvTG93ZXJDYXNlKCkubWF0Y2goL15bMC05YS1mXSskLykpe3RoaXMuc2V0SGV4VmFsdWVJbmNsdWRpbmdVbnVzZWRCaXRzKGIpfWVsc2V7aWYodHlwZW9mIGIuaGV4IT1cInVuZGVmaW5lZFwiKXt0aGlzLnNldEhleFZhbHVlSW5jbHVkaW5nVW51c2VkQml0cyhiLmhleCl9ZWxzZXtpZih0eXBlb2YgYi5iaW4hPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0QnlCaW5hcnlTdHJpbmcoYi5iaW4pfWVsc2V7aWYodHlwZW9mIGIuYXJyYXkhPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0QnlCb29sZWFuQXJyYXkoYi5hcnJheSl9fX19fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkJpdFN0cmluZyxLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUk9jdGV0U3RyaW5nPWZ1bmN0aW9uKGIpe2lmKGIhPT11bmRlZmluZWQmJnR5cGVvZiBiLm9iaiE9PVwidW5kZWZpbmVkXCIpe3ZhciBhPUtKVVIuYXNuMS5BU04xVXRpbC5uZXdPYmplY3QoYi5vYmopO2IuaGV4PWEuZ2V0RW5jb2RlZEhleCgpfUtKVVIuYXNuMS5ERVJPY3RldFN0cmluZy5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyxiKTt0aGlzLmhUPVwiMDRcIn07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUk9jdGV0U3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUk51bGw9ZnVuY3Rpb24oKXtLSlVSLmFzbjEuREVSTnVsbC5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjA1XCI7dGhpcy5oVExWPVwiMDUwMFwifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSTnVsbCxLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUk9iamVjdElkZW50aWZpZXI9ZnVuY3Rpb24oYyl7dmFyIGI9ZnVuY3Rpb24oZCl7dmFyIGU9ZC50b1N0cmluZygxNik7aWYoZS5sZW5ndGg9PTEpe2U9XCIwXCIrZX1yZXR1cm4gZX07dmFyIGE9ZnVuY3Rpb24oayl7dmFyIGo9XCJcIjt2YXIgZT1uZXcgQmlnSW50ZWdlcihrLDEwKTt2YXIgZD1lLnRvU3RyaW5nKDIpO3ZhciBmPTctZC5sZW5ndGglNztpZihmPT03KXtmPTB9dmFyIG09XCJcIjtmb3IodmFyIGc9MDtnPGY7ZysrKXttKz1cIjBcIn1kPW0rZDtmb3IodmFyIGc9MDtnPGQubGVuZ3RoLTE7Zys9Nyl7dmFyIGw9ZC5zdWJzdHIoZyw3KTtpZihnIT1kLmxlbmd0aC03KXtsPVwiMVwiK2x9ais9YihwYXJzZUludChsLDIpKX1yZXR1cm4gan07S0pVUi5hc24xLkRFUk9iamVjdElkZW50aWZpZXIuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3RoaXMuaFQ9XCIwNlwiO3RoaXMuc2V0VmFsdWVIZXg9ZnVuY3Rpb24oZCl7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5zPW51bGw7dGhpcy5oVj1kfTt0aGlzLnNldFZhbHVlT2lkU3RyaW5nPWZ1bmN0aW9uKGYpe2lmKCFmLm1hdGNoKC9eWzAtOS5dKyQvKSl7dGhyb3dcIm1hbGZvcm1lZCBvaWQgc3RyaW5nOiBcIitmfXZhciBnPVwiXCI7dmFyIGQ9Zi5zcGxpdChcIi5cIik7dmFyIGo9cGFyc2VJbnQoZFswXSkqNDArcGFyc2VJbnQoZFsxXSk7Zys9YihqKTtkLnNwbGljZSgwLDIpO2Zvcih2YXIgZT0wO2U8ZC5sZW5ndGg7ZSsrKXtnKz1hKGRbZV0pfXRoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMucz1udWxsO3RoaXMuaFY9Z307dGhpcy5zZXRWYWx1ZU5hbWU9ZnVuY3Rpb24oZSl7dmFyIGQ9S0pVUi5hc24xLng1MDkuT0lELm5hbWUyb2lkKGUpO2lmKGQhPT1cIlwiKXt0aGlzLnNldFZhbHVlT2lkU3RyaW5nKGQpfWVsc2V7dGhyb3dcIkRFUk9iamVjdElkZW50aWZpZXIgb2lkTmFtZSB1bmRlZmluZWQ6IFwiK2V9fTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn07aWYoYyE9PXVuZGVmaW5lZCl7aWYodHlwZW9mIGM9PT1cInN0cmluZ1wiKXtpZihjLm1hdGNoKC9eWzAtMl0uWzAtOS5dKyQvKSl7dGhpcy5zZXRWYWx1ZU9pZFN0cmluZyhjKX1lbHNle3RoaXMuc2V0VmFsdWVOYW1lKGMpfX1lbHNle2lmKGMub2lkIT09dW5kZWZpbmVkKXt0aGlzLnNldFZhbHVlT2lkU3RyaW5nKGMub2lkKX1lbHNle2lmKGMuaGV4IT09dW5kZWZpbmVkKXt0aGlzLnNldFZhbHVlSGV4KGMuaGV4KX1lbHNle2lmKGMubmFtZSE9PXVuZGVmaW5lZCl7dGhpcy5zZXRWYWx1ZU5hbWUoYy5uYW1lKX19fX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVST2JqZWN0SWRlbnRpZmllcixLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUkVudW1lcmF0ZWQ9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUkVudW1lcmF0ZWQuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3RoaXMuaFQ9XCIwYVwiO3RoaXMuc2V0QnlCaWdJbnRlZ2VyPWZ1bmN0aW9uKGIpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMuaFY9S0pVUi5hc24xLkFTTjFVdGlsLmJpZ0ludFRvTWluVHdvc0NvbXBsZW1lbnRzSGV4KGIpfTt0aGlzLnNldEJ5SW50ZWdlcj1mdW5jdGlvbihjKXt2YXIgYj1uZXcgQmlnSW50ZWdlcihTdHJpbmcoYyksMTApO3RoaXMuc2V0QnlCaWdJbnRlZ2VyKGIpfTt0aGlzLnNldFZhbHVlSGV4PWZ1bmN0aW9uKGIpe3RoaXMuaFY9Yn07dGhpcy5nZXRGcmVzaFZhbHVlSGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaFZ9O2lmKHR5cGVvZiBhIT1cInVuZGVmaW5lZFwiKXtpZih0eXBlb2YgYVtcImludFwiXSE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUludGVnZXIoYVtcImludFwiXSl9ZWxzZXtpZih0eXBlb2YgYT09XCJudW1iZXJcIil7dGhpcy5zZXRCeUludGVnZXIoYSl9ZWxzZXtpZih0eXBlb2YgYS5oZXghPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0VmFsdWVIZXgoYS5oZXgpfX19fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkVudW1lcmF0ZWQsS0pVUi5hc24xLkFTTjFPYmplY3QpO0tKVVIuYXNuMS5ERVJVVEY4U3RyaW5nPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJVVEY4U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIwY1wifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSVVRGOFN0cmluZyxLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJpbmcpO0tKVVIuYXNuMS5ERVJOdW1lcmljU3RyaW5nPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJOdW1lcmljU3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIxMlwifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSTnVtZXJpY1N0cmluZyxLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJpbmcpO0tKVVIuYXNuMS5ERVJQcmludGFibGVTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlByaW50YWJsZVN0cmluZy5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyxhKTt0aGlzLmhUPVwiMTNcIn07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUlByaW50YWJsZVN0cmluZyxLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJpbmcpO0tKVVIuYXNuMS5ERVJUZWxldGV4U3RyaW5nPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJUZWxldGV4U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIxNFwifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSVGVsZXRleFN0cmluZyxLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJpbmcpO0tKVVIuYXNuMS5ERVJJQTVTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUklBNVN0cmluZy5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyxhKTt0aGlzLmhUPVwiMTZcIn07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUklBNVN0cmluZyxLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJpbmcpO0tKVVIuYXNuMS5ERVJVVENUaW1lPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJVVENUaW1lLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIxN1wiO3RoaXMuc2V0QnlEYXRlPWZ1bmN0aW9uKGIpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMuZGF0ZT1iO3RoaXMucz10aGlzLmZvcm1hdERhdGUodGhpcy5kYXRlLFwidXRjXCIpO3RoaXMuaFY9c3RvaGV4KHRoaXMucyl9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe2lmKHR5cGVvZiB0aGlzLmRhdGU9PVwidW5kZWZpbmVkXCImJnR5cGVvZiB0aGlzLnM9PVwidW5kZWZpbmVkXCIpe3RoaXMuZGF0ZT1uZXcgRGF0ZSgpO3RoaXMucz10aGlzLmZvcm1hdERhdGUodGhpcy5kYXRlLFwidXRjXCIpO3RoaXMuaFY9c3RvaGV4KHRoaXMucyl9cmV0dXJuIHRoaXMuaFZ9O2lmKGEhPT11bmRlZmluZWQpe2lmKGEuc3RyIT09dW5kZWZpbmVkKXt0aGlzLnNldFN0cmluZyhhLnN0cil9ZWxzZXtpZih0eXBlb2YgYT09XCJzdHJpbmdcIiYmYS5tYXRjaCgvXlswLTldezEyfVokLykpe3RoaXMuc2V0U3RyaW5nKGEpfWVsc2V7aWYoYS5oZXghPT11bmRlZmluZWQpe3RoaXMuc2V0U3RyaW5nSGV4KGEuaGV4KX1lbHNle2lmKGEuZGF0ZSE9PXVuZGVmaW5lZCl7dGhpcy5zZXRCeURhdGUoYS5kYXRlKX19fX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSVVRDVGltZSxLSlVSLmFzbjEuREVSQWJzdHJhY3RUaW1lKTtLSlVSLmFzbjEuREVSR2VuZXJhbGl6ZWRUaW1lPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJHZW5lcmFsaXplZFRpbWUuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjE4XCI7dGhpcy53aXRoTWlsbGlzPWZhbHNlO3RoaXMuc2V0QnlEYXRlPWZ1bmN0aW9uKGIpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMuZGF0ZT1iO3RoaXMucz10aGlzLmZvcm1hdERhdGUodGhpcy5kYXRlLFwiZ2VuXCIsdGhpcy53aXRoTWlsbGlzKTt0aGlzLmhWPXN0b2hleCh0aGlzLnMpfTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtpZih0aGlzLmRhdGU9PT11bmRlZmluZWQmJnRoaXMucz09PXVuZGVmaW5lZCl7dGhpcy5kYXRlPW5ldyBEYXRlKCk7dGhpcy5zPXRoaXMuZm9ybWF0RGF0ZSh0aGlzLmRhdGUsXCJnZW5cIix0aGlzLndpdGhNaWxsaXMpO3RoaXMuaFY9c3RvaGV4KHRoaXMucyl9cmV0dXJuIHRoaXMuaFZ9O2lmKGEhPT11bmRlZmluZWQpe2lmKGEuc3RyIT09dW5kZWZpbmVkKXt0aGlzLnNldFN0cmluZyhhLnN0cil9ZWxzZXtpZih0eXBlb2YgYT09XCJzdHJpbmdcIiYmYS5tYXRjaCgvXlswLTldezE0fVokLykpe3RoaXMuc2V0U3RyaW5nKGEpfWVsc2V7aWYoYS5oZXghPT11bmRlZmluZWQpe3RoaXMuc2V0U3RyaW5nSGV4KGEuaGV4KX1lbHNle2lmKGEuZGF0ZSE9PXVuZGVmaW5lZCl7dGhpcy5zZXRCeURhdGUoYS5kYXRlKX19fX1pZihhLm1pbGxpcz09PXRydWUpe3RoaXMud2l0aE1pbGxpcz10cnVlfX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJHZW5lcmFsaXplZFRpbWUsS0pVUi5hc24xLkRFUkFic3RyYWN0VGltZSk7S0pVUi5hc24xLkRFUlNlcXVlbmNlPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJTZXF1ZW5jZS5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyxhKTt0aGlzLmhUPVwiMzBcIjt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXt2YXIgYz1cIlwiO2Zvcih2YXIgYj0wO2I8dGhpcy5hc24xQXJyYXkubGVuZ3RoO2IrKyl7dmFyIGQ9dGhpcy5hc24xQXJyYXlbYl07Yys9ZC5nZXRFbmNvZGVkSGV4KCl9dGhpcy5oVj1jO3JldHVybiB0aGlzLmhWfX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUlNlcXVlbmNlLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cnVjdHVyZWQpO0tKVVIuYXNuMS5ERVJTZXQ9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlNldC5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyxhKTt0aGlzLmhUPVwiMzFcIjt0aGlzLnNvcnRGbGFnPXRydWU7dGhpcy5nZXRGcmVzaFZhbHVlSGV4PWZ1bmN0aW9uKCl7dmFyIGI9bmV3IEFycmF5KCk7Zm9yKHZhciBjPTA7Yzx0aGlzLmFzbjFBcnJheS5sZW5ndGg7YysrKXt2YXIgZD10aGlzLmFzbjFBcnJheVtjXTtiLnB1c2goZC5nZXRFbmNvZGVkSGV4KCkpfWlmKHRoaXMuc29ydEZsYWc9PXRydWUpe2Iuc29ydCgpfXRoaXMuaFY9Yi5qb2luKFwiXCIpO3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYSE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGEuc29ydGZsYWchPVwidW5kZWZpbmVkXCImJmEuc29ydGZsYWc9PWZhbHNlKXt0aGlzLnNvcnRGbGFnPWZhbHNlfX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJTZXQsS0pVUi5hc24xLkRFUkFic3RyYWN0U3RydWN0dXJlZCk7S0pVUi5hc24xLkRFUlRhZ2dlZE9iamVjdD1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSVGFnZ2VkT2JqZWN0LnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiYTBcIjt0aGlzLmhWPVwiXCI7dGhpcy5pc0V4cGxpY2l0PXRydWU7dGhpcy5hc24xT2JqZWN0PW51bGw7dGhpcy5zZXRBU04xT2JqZWN0PWZ1bmN0aW9uKGIsYyxkKXt0aGlzLmhUPWM7dGhpcy5pc0V4cGxpY2l0PWI7dGhpcy5hc24xT2JqZWN0PWQ7aWYodGhpcy5pc0V4cGxpY2l0KXt0aGlzLmhWPXRoaXMuYXNuMU9iamVjdC5nZXRFbmNvZGVkSGV4KCk7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWV9ZWxzZXt0aGlzLmhWPW51bGw7dGhpcy5oVExWPWQuZ2V0RW5jb2RlZEhleCgpO3RoaXMuaFRMVj10aGlzLmhUTFYucmVwbGFjZSgvXi4uLyxjKTt0aGlzLmlzTW9kaWZpZWQ9ZmFsc2V9fTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn07aWYodHlwZW9mIGEhPVwidW5kZWZpbmVkXCIpe2lmKHR5cGVvZiBhLnRhZyE9XCJ1bmRlZmluZWRcIil7dGhpcy5oVD1hLnRhZ31pZih0eXBlb2YgYS5leHBsaWNpdCE9XCJ1bmRlZmluZWRcIil7dGhpcy5pc0V4cGxpY2l0PWEuZXhwbGljaXR9aWYodHlwZW9mIGEub2JqIT1cInVuZGVmaW5lZFwiKXt0aGlzLmFzbjFPYmplY3Q9YS5vYmo7dGhpcy5zZXRBU04xT2JqZWN0KHRoaXMuaXNFeHBsaWNpdCx0aGlzLmhULHRoaXMuYXNuMU9iamVjdCl9fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUlRhZ2dlZE9iamVjdCxLSlVSLmFzbjEuQVNOMU9iamVjdCk7XG52YXIgQVNOMUhFWD1uZXcgZnVuY3Rpb24oKXt9O0FTTjFIRVguZ2V0TGJsZW49ZnVuY3Rpb24oYyxhKXtpZihjLnN1YnN0cihhKzIsMSkhPVwiOFwiKXtyZXR1cm4gMX12YXIgYj1wYXJzZUludChjLnN1YnN0cihhKzMsMSkpO2lmKGI9PTApe3JldHVybiAtMX1pZigwPGImJmI8MTApe3JldHVybiBiKzF9cmV0dXJuIC0yfTtBU04xSEVYLmdldEw9ZnVuY3Rpb24oYyxiKXt2YXIgYT1BU04xSEVYLmdldExibGVuKGMsYik7aWYoYTwxKXtyZXR1cm5cIlwifXJldHVybiBjLnN1YnN0cihiKzIsYSoyKX07QVNOMUhFWC5nZXRWYmxlbj1mdW5jdGlvbihkLGEpe3ZhciBjLGI7Yz1BU04xSEVYLmdldEwoZCxhKTtpZihjPT1cIlwiKXtyZXR1cm4gLTF9aWYoYy5zdWJzdHIoMCwxKT09PVwiOFwiKXtiPW5ldyBCaWdJbnRlZ2VyKGMuc3Vic3RyKDIpLDE2KX1lbHNle2I9bmV3IEJpZ0ludGVnZXIoYywxNil9cmV0dXJuIGIuaW50VmFsdWUoKX07QVNOMUhFWC5nZXRWaWR4PWZ1bmN0aW9uKGMsYil7dmFyIGE9QVNOMUhFWC5nZXRMYmxlbihjLGIpO2lmKGE8MCl7cmV0dXJuIGF9cmV0dXJuIGIrKGErMSkqMn07QVNOMUhFWC5nZXRWPWZ1bmN0aW9uKGQsYSl7dmFyIGM9QVNOMUhFWC5nZXRWaWR4KGQsYSk7dmFyIGI9QVNOMUhFWC5nZXRWYmxlbihkLGEpO3JldHVybiBkLnN1YnN0cihjLGIqMil9O0FTTjFIRVguZ2V0VExWPWZ1bmN0aW9uKGIsYSl7cmV0dXJuIGIuc3Vic3RyKGEsMikrQVNOMUhFWC5nZXRMKGIsYSkrQVNOMUhFWC5nZXRWKGIsYSl9O0FTTjFIRVguZ2V0TmV4dFNpYmxpbmdJZHg9ZnVuY3Rpb24oZCxhKXt2YXIgYz1BU04xSEVYLmdldFZpZHgoZCxhKTt2YXIgYj1BU04xSEVYLmdldFZibGVuKGQsYSk7cmV0dXJuIGMrYioyfTtBU04xSEVYLmdldENoaWxkSWR4PWZ1bmN0aW9uKGUsZil7dmFyIGo9QVNOMUhFWDt2YXIgZz1uZXcgQXJyYXkoKTt2YXIgaT1qLmdldFZpZHgoZSxmKTtpZihlLnN1YnN0cihmLDIpPT1cIjAzXCIpe2cucHVzaChpKzIpfWVsc2V7Zy5wdXNoKGkpfXZhciBsPWouZ2V0VmJsZW4oZSxmKTt2YXIgYz1pO3ZhciBkPTA7d2hpbGUoMSl7dmFyIGI9ai5nZXROZXh0U2libGluZ0lkeChlLGMpO2lmKGI9PW51bGx8fChiLWk+PShsKjIpKSl7YnJlYWt9aWYoZD49MjAwKXticmVha31nLnB1c2goYik7Yz1iO2QrK31yZXR1cm4gZ307QVNOMUhFWC5nZXROdGhDaGlsZElkeD1mdW5jdGlvbihkLGIsZSl7dmFyIGM9QVNOMUhFWC5nZXRDaGlsZElkeChkLGIpO3JldHVybiBjW2VdfTtBU04xSEVYLmdldElkeGJ5TGlzdD1mdW5jdGlvbihlLGQsYyxpKXt2YXIgZz1BU04xSEVYO3ZhciBmLGI7aWYoYy5sZW5ndGg9PTApe2lmKGkhPT11bmRlZmluZWQpe2lmKGUuc3Vic3RyKGQsMikhPT1pKXt0aHJvd1wiY2hlY2tpbmcgdGFnIGRvZXNuJ3QgbWF0Y2g6IFwiK2Uuc3Vic3RyKGQsMikrXCIhPVwiK2l9fXJldHVybiBkfWY9Yy5zaGlmdCgpO2I9Zy5nZXRDaGlsZElkeChlLGQpO3JldHVybiBnLmdldElkeGJ5TGlzdChlLGJbZl0sYyxpKX07QVNOMUhFWC5nZXRUTFZieUxpc3Q9ZnVuY3Rpb24oZCxjLGIsZil7dmFyIGU9QVNOMUhFWDt2YXIgYT1lLmdldElkeGJ5TGlzdChkLGMsYik7aWYoYT09PXVuZGVmaW5lZCl7dGhyb3dcImNhbid0IGZpbmQgbnRoTGlzdCBvYmplY3RcIn1pZihmIT09dW5kZWZpbmVkKXtpZihkLnN1YnN0cihhLDIpIT1mKXt0aHJvd1wiY2hlY2tpbmcgdGFnIGRvZXNuJ3QgbWF0Y2g6IFwiK2Quc3Vic3RyKGEsMikrXCIhPVwiK2Z9fXJldHVybiBlLmdldFRMVihkLGEpfTtBU04xSEVYLmdldFZieUxpc3Q9ZnVuY3Rpb24oZSxjLGIsZyxpKXt2YXIgZj1BU04xSEVYO3ZhciBhLGQ7YT1mLmdldElkeGJ5TGlzdChlLGMsYixnKTtpZihhPT09dW5kZWZpbmVkKXt0aHJvd1wiY2FuJ3QgZmluZCBudGhMaXN0IG9iamVjdFwifWQ9Zi5nZXRWKGUsYSk7aWYoaT09PXRydWUpe2Q9ZC5zdWJzdHIoMil9cmV0dXJuIGR9O0FTTjFIRVguaGV4dG9vaWRzdHI9ZnVuY3Rpb24oZSl7dmFyIGg9ZnVuY3Rpb24oYixhKXtpZihiLmxlbmd0aD49YSl7cmV0dXJuIGJ9cmV0dXJuIG5ldyBBcnJheShhLWIubGVuZ3RoKzEpLmpvaW4oXCIwXCIpK2J9O3ZhciBsPVtdO3ZhciBvPWUuc3Vic3RyKDAsMik7dmFyIGY9cGFyc2VJbnQobywxNik7bFswXT1uZXcgU3RyaW5nKE1hdGguZmxvb3IoZi80MCkpO2xbMV09bmV3IFN0cmluZyhmJTQwKTt2YXIgbT1lLnN1YnN0cigyKTt2YXIgaz1bXTtmb3IodmFyIGc9MDtnPG0ubGVuZ3RoLzI7ZysrKXtrLnB1c2gocGFyc2VJbnQobS5zdWJzdHIoZyoyLDIpLDE2KSl9dmFyIGo9W107dmFyIGQ9XCJcIjtmb3IodmFyIGc9MDtnPGsubGVuZ3RoO2crKyl7aWYoa1tnXSYxMjgpe2Q9ZCtoKChrW2ddJjEyNykudG9TdHJpbmcoMiksNyl9ZWxzZXtkPWQraCgoa1tnXSYxMjcpLnRvU3RyaW5nKDIpLDcpO2oucHVzaChuZXcgU3RyaW5nKHBhcnNlSW50KGQsMikpKTtkPVwiXCJ9fXZhciBuPWwuam9pbihcIi5cIik7aWYoai5sZW5ndGg+MCl7bj1uK1wiLlwiK2ouam9pbihcIi5cIil9cmV0dXJuIG59O0FTTjFIRVguZHVtcD1mdW5jdGlvbih0LGMsbCxnKXt2YXIgcD1BU04xSEVYO3ZhciBqPXAuZ2V0Vjt2YXIgeT1wLmR1bXA7dmFyIHc9cC5nZXRDaGlsZElkeDt2YXIgZT10O2lmKHQgaW5zdGFuY2VvZiBLSlVSLmFzbjEuQVNOMU9iamVjdCl7ZT10LmdldEVuY29kZWRIZXgoKX12YXIgcT1mdW5jdGlvbihBLGkpe2lmKEEubGVuZ3RoPD1pKjIpe3JldHVybiBBfWVsc2V7dmFyIHY9QS5zdWJzdHIoMCxpKStcIi4uKHRvdGFsIFwiK0EubGVuZ3RoLzIrXCJieXRlcykuLlwiK0Euc3Vic3RyKEEubGVuZ3RoLWksaSk7cmV0dXJuIHZ9fTtpZihjPT09dW5kZWZpbmVkKXtjPXtvbW1pdF9sb25nX29jdGV0OjMyfX1pZihsPT09dW5kZWZpbmVkKXtsPTB9aWYoZz09PXVuZGVmaW5lZCl7Zz1cIlwifXZhciB4PWMub21taXRfbG9uZ19vY3RldDtpZihlLnN1YnN0cihsLDIpPT1cIjAxXCIpe3ZhciBoPWooZSxsKTtpZihoPT1cIjAwXCIpe3JldHVybiBnK1wiQk9PTEVBTiBGQUxTRVxcblwifWVsc2V7cmV0dXJuIGcrXCJCT09MRUFOIFRSVUVcXG5cIn19aWYoZS5zdWJzdHIobCwyKT09XCIwMlwiKXt2YXIgaD1qKGUsbCk7cmV0dXJuIGcrXCJJTlRFR0VSIFwiK3EoaCx4KStcIlxcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMDNcIil7dmFyIGg9aihlLGwpO3JldHVybiBnK1wiQklUU1RSSU5HIFwiK3EoaCx4KStcIlxcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMDRcIil7dmFyIGg9aihlLGwpO2lmKHAuaXNBU04xSEVYKGgpKXt2YXIgaz1nK1wiT0NURVRTVFJJTkcsIGVuY2Fwc3VsYXRlc1xcblwiO2s9ayt5KGgsYywwLGcrXCIgIFwiKTtyZXR1cm4ga31lbHNle3JldHVybiBnK1wiT0NURVRTVFJJTkcgXCIrcShoLHgpK1wiXFxuXCJ9fWlmKGUuc3Vic3RyKGwsMik9PVwiMDVcIil7cmV0dXJuIGcrXCJOVUxMXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIwNlwiKXt2YXIgbT1qKGUsbCk7dmFyIGE9S0pVUi5hc24xLkFTTjFVdGlsLm9pZEhleFRvSW50KG0pO3ZhciBvPUtKVVIuYXNuMS54NTA5Lk9JRC5vaWQybmFtZShhKTt2YXIgYj1hLnJlcGxhY2UoL1xcLi9nLFwiIFwiKTtpZihvIT1cIlwiKXtyZXR1cm4gZytcIk9iamVjdElkZW50aWZpZXIgXCIrbytcIiAoXCIrYitcIilcXG5cIn1lbHNle3JldHVybiBnK1wiT2JqZWN0SWRlbnRpZmllciAoXCIrYitcIilcXG5cIn19aWYoZS5zdWJzdHIobCwyKT09XCIwY1wiKXtyZXR1cm4gZytcIlVURjhTdHJpbmcgJ1wiK2hleHRvdXRmOChqKGUsbCkpK1wiJ1xcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMTNcIil7cmV0dXJuIGcrXCJQcmludGFibGVTdHJpbmcgJ1wiK2hleHRvdXRmOChqKGUsbCkpK1wiJ1xcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMTRcIil7cmV0dXJuIGcrXCJUZWxldGV4U3RyaW5nICdcIitoZXh0b3V0ZjgoaihlLGwpKStcIidcXG5cIn1pZihlLnN1YnN0cihsLDIpPT1cIjE2XCIpe3JldHVybiBnK1wiSUE1U3RyaW5nICdcIitoZXh0b3V0ZjgoaihlLGwpKStcIidcXG5cIn1pZihlLnN1YnN0cihsLDIpPT1cIjE3XCIpe3JldHVybiBnK1wiVVRDVGltZSBcIitoZXh0b3V0ZjgoaihlLGwpKStcIlxcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMThcIil7cmV0dXJuIGcrXCJHZW5lcmFsaXplZFRpbWUgXCIraGV4dG91dGY4KGooZSxsKSkrXCJcXG5cIn1pZihlLnN1YnN0cihsLDIpPT1cIjMwXCIpe2lmKGUuc3Vic3RyKGwsNCk9PVwiMzAwMFwiKXtyZXR1cm4gZytcIlNFUVVFTkNFIHt9XFxuXCJ9dmFyIGs9ZytcIlNFUVVFTkNFXFxuXCI7dmFyIGQ9dyhlLGwpO3ZhciBmPWM7aWYoKGQubGVuZ3RoPT0yfHxkLmxlbmd0aD09MykmJmUuc3Vic3RyKGRbMF0sMik9PVwiMDZcIiYmZS5zdWJzdHIoZFtkLmxlbmd0aC0xXSwyKT09XCIwNFwiKXt2YXIgbz1wLm9pZG5hbWUoaihlLGRbMF0pKTt2YXIgcj1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGMpKTtyLng1MDlFeHROYW1lPW87Zj1yfWZvcih2YXIgdT0wO3U8ZC5sZW5ndGg7dSsrKXtrPWsreShlLGYsZFt1XSxnK1wiICBcIil9cmV0dXJuIGt9aWYoZS5zdWJzdHIobCwyKT09XCIzMVwiKXt2YXIgaz1nK1wiU0VUXFxuXCI7dmFyIGQ9dyhlLGwpO2Zvcih2YXIgdT0wO3U8ZC5sZW5ndGg7dSsrKXtrPWsreShlLGMsZFt1XSxnK1wiICBcIil9cmV0dXJuIGt9dmFyIHo9cGFyc2VJbnQoZS5zdWJzdHIobCwyKSwxNik7aWYoKHomMTI4KSE9MCl7dmFyIG49eiYzMTtpZigoeiYzMikhPTApe3ZhciBrPWcrXCJbXCIrbitcIl1cXG5cIjt2YXIgZD13KGUsbCk7Zm9yKHZhciB1PTA7dTxkLmxlbmd0aDt1Kyspe2s9ayt5KGUsYyxkW3VdLGcrXCIgIFwiKX1yZXR1cm4ga31lbHNle3ZhciBoPWooZSxsKTtpZihoLnN1YnN0cigwLDgpPT1cIjY4NzQ3NDcwXCIpe2g9aGV4dG91dGY4KGgpfWlmKGMueDUwOUV4dE5hbWU9PT1cInN1YmplY3RBbHROYW1lXCImJm49PTIpe2g9aGV4dG91dGY4KGgpfXZhciBrPWcrXCJbXCIrbitcIl0gXCIraCtcIlxcblwiO3JldHVybiBrfX1yZXR1cm4gZytcIlVOS05PV04oXCIrZS5zdWJzdHIobCwyKStcIikgXCIraihlLGwpK1wiXFxuXCJ9O0FTTjFIRVguaXNBU04xSEVYPWZ1bmN0aW9uKGUpe3ZhciBkPUFTTjFIRVg7aWYoZS5sZW5ndGglMj09MSl7cmV0dXJuIGZhbHNlfXZhciBjPWQuZ2V0VmJsZW4oZSwwKTt2YXIgYj1lLnN1YnN0cigwLDIpO3ZhciBmPWQuZ2V0TChlLDApO3ZhciBhPWUubGVuZ3RoLWIubGVuZ3RoLWYubGVuZ3RoO2lmKGE9PWMqMil7cmV0dXJuIHRydWV9cmV0dXJuIGZhbHNlfTtBU04xSEVYLm9pZG5hbWU9ZnVuY3Rpb24oYSl7dmFyIGM9S0pVUi5hc24xO2lmKEtKVVIubGFuZy5TdHJpbmcuaXNIZXgoYSkpe2E9Yy5BU04xVXRpbC5vaWRIZXhUb0ludChhKX12YXIgYj1jLng1MDkuT0lELm9pZDJuYW1lKGEpO2lmKGI9PT1cIlwiKXtiPWF9cmV0dXJuIGJ9O1xudmFyIEtKVVI7aWYodHlwZW9mIEtKVVI9PVwidW5kZWZpbmVkXCJ8fCFLSlVSKXtLSlVSPXt9fWlmKHR5cGVvZiBLSlVSLmxhbmc9PVwidW5kZWZpbmVkXCJ8fCFLSlVSLmxhbmcpe0tKVVIubGFuZz17fX1LSlVSLmxhbmcuU3RyaW5nPWZ1bmN0aW9uKCl7fTtmdW5jdGlvbiBCYXNlNjR4KCl7fWZ1bmN0aW9uIHN0b0JBKGQpe3ZhciBiPW5ldyBBcnJheSgpO2Zvcih2YXIgYz0wO2M8ZC5sZW5ndGg7YysrKXtiW2NdPWQuY2hhckNvZGVBdChjKX1yZXR1cm4gYn1mdW5jdGlvbiBCQXRvcyhiKXt2YXIgZD1cIlwiO2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGg7YysrKXtkPWQrU3RyaW5nLmZyb21DaGFyQ29kZShiW2NdKX1yZXR1cm4gZH1mdW5jdGlvbiBCQXRvaGV4KGIpe3ZhciBlPVwiXCI7Zm9yKHZhciBkPTA7ZDxiLmxlbmd0aDtkKyspe3ZhciBjPWJbZF0udG9TdHJpbmcoMTYpO2lmKGMubGVuZ3RoPT0xKXtjPVwiMFwiK2N9ZT1lK2N9cmV0dXJuIGV9ZnVuY3Rpb24gc3RvaGV4KGEpe3JldHVybiBCQXRvaGV4KHN0b0JBKGEpKX1mdW5jdGlvbiBzdG9iNjQoYSl7cmV0dXJuIGhleDJiNjQoc3RvaGV4KGEpKX1mdW5jdGlvbiBzdG9iNjR1KGEpe3JldHVybiBiNjR0b2I2NHUoaGV4MmI2NChzdG9oZXgoYSkpKX1mdW5jdGlvbiBiNjR1dG9zKGEpe3JldHVybiBCQXRvcyhiNjR0b0JBKGI2NHV0b2I2NChhKSkpfWZ1bmN0aW9uIGI2NHRvYjY0dShhKXthPWEucmVwbGFjZSgvXFw9L2csXCJcIik7YT1hLnJlcGxhY2UoL1xcKy9nLFwiLVwiKTthPWEucmVwbGFjZSgvXFwvL2csXCJfXCIpO3JldHVybiBhfWZ1bmN0aW9uIGI2NHV0b2I2NChhKXtpZihhLmxlbmd0aCU0PT0yKXthPWErXCI9PVwifWVsc2V7aWYoYS5sZW5ndGglND09Myl7YT1hK1wiPVwifX1hPWEucmVwbGFjZSgvLS9nLFwiK1wiKTthPWEucmVwbGFjZSgvXy9nLFwiL1wiKTtyZXR1cm4gYX1mdW5jdGlvbiBoZXh0b2I2NHUoYSl7aWYoYS5sZW5ndGglMj09MSl7YT1cIjBcIithfXJldHVybiBiNjR0b2I2NHUoaGV4MmI2NChhKSl9ZnVuY3Rpb24gYjY0dXRvaGV4KGEpe3JldHVybiBiNjR0b2hleChiNjR1dG9iNjQoYSkpfXZhciB1dGY4dG9iNjR1LGI2NHV0b3V0Zjg7aWYodHlwZW9mIEJ1ZmZlcj09PVwiZnVuY3Rpb25cIil7dXRmOHRvYjY0dT1mdW5jdGlvbihhKXtyZXR1cm4gYjY0dG9iNjR1KG5ldyBCdWZmZXIoYSxcInV0ZjhcIikudG9TdHJpbmcoXCJiYXNlNjRcIikpfTtiNjR1dG91dGY4PWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgQnVmZmVyKGI2NHV0b2I2NChhKSxcImJhc2U2NFwiKS50b1N0cmluZyhcInV0ZjhcIil9fWVsc2V7dXRmOHRvYjY0dT1mdW5jdGlvbihhKXtyZXR1cm4gaGV4dG9iNjR1KHVyaWNtcHRvaGV4KGVuY29kZVVSSUNvbXBvbmVudEFsbChhKSkpfTtiNjR1dG91dGY4PWZ1bmN0aW9uKGEpe3JldHVybiBkZWNvZGVVUklDb21wb25lbnQoaGV4dG91cmljbXAoYjY0dXRvaGV4KGEpKSl9fWZ1bmN0aW9uIHV0Zjh0b2I2NChhKXtyZXR1cm4gaGV4MmI2NCh1cmljbXB0b2hleChlbmNvZGVVUklDb21wb25lbnRBbGwoYSkpKX1mdW5jdGlvbiBiNjR0b3V0ZjgoYSl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChoZXh0b3VyaWNtcChiNjR0b2hleChhKSkpfWZ1bmN0aW9uIHV0Zjh0b2hleChhKXtyZXR1cm4gdXJpY21wdG9oZXgoZW5jb2RlVVJJQ29tcG9uZW50QWxsKGEpKX1mdW5jdGlvbiBoZXh0b3V0ZjgoYSl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChoZXh0b3VyaWNtcChhKSl9ZnVuY3Rpb24gaGV4dG9yc3RyKGMpe3ZhciBiPVwiXCI7Zm9yKHZhciBhPTA7YTxjLmxlbmd0aC0xO2ErPTIpe2IrPVN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQoYy5zdWJzdHIoYSwyKSwxNikpfXJldHVybiBifWZ1bmN0aW9uIHJzdHJ0b2hleChjKXt2YXIgYT1cIlwiO2Zvcih2YXIgYj0wO2I8Yy5sZW5ndGg7YisrKXthKz0oXCIwXCIrYy5jaGFyQ29kZUF0KGIpLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpfXJldHVybiBhfWZ1bmN0aW9uIGhleHRvYjY0KGEpe3JldHVybiBoZXgyYjY0KGEpfWZ1bmN0aW9uIGhleHRvYjY0bmwoYil7dmFyIGE9aGV4dG9iNjQoYik7dmFyIGM9YS5yZXBsYWNlKC8oLns2NH0pL2csXCIkMVxcclxcblwiKTtjPWMucmVwbGFjZSgvXFxyXFxuJC8sXCJcIik7cmV0dXJuIGN9ZnVuY3Rpb24gYjY0bmx0b2hleChiKXt2YXIgYT1iLnJlcGxhY2UoL1teMC05QS1aYS16XFwvKz1dKi9nLFwiXCIpO3ZhciBjPWI2NHRvaGV4KGEpO3JldHVybiBjfWZ1bmN0aW9uIGhleHRvcGVtKGEsYil7dmFyIGM9aGV4dG9iNjRubChhKTtyZXR1cm5cIi0tLS0tQkVHSU4gXCIrYitcIi0tLS0tXFxyXFxuXCIrYytcIlxcclxcbi0tLS0tRU5EIFwiK2IrXCItLS0tLVxcclxcblwifWZ1bmN0aW9uIHBlbXRvaGV4KGEsYil7aWYoYS5pbmRleE9mKFwiLS0tLS1CRUdJTiBcIik9PS0xKXt0aHJvd1wiY2FuJ3QgZmluZCBQRU0gaGVhZGVyOiBcIitifWlmKGIhPT11bmRlZmluZWQpe2E9YS5yZXBsYWNlKFwiLS0tLS1CRUdJTiBcIitiK1wiLS0tLS1cIixcIlwiKTthPWEucmVwbGFjZShcIi0tLS0tRU5EIFwiK2IrXCItLS0tLVwiLFwiXCIpfWVsc2V7YT1hLnJlcGxhY2UoLy0tLS0tQkVHSU4gW14tXSstLS0tLS8sXCJcIik7YT1hLnJlcGxhY2UoLy0tLS0tRU5EIFteLV0rLS0tLS0vLFwiXCIpfXJldHVybiBiNjRubHRvaGV4KGEpfWZ1bmN0aW9uIGhleHRvQXJyYXlCdWZmZXIoZCl7aWYoZC5sZW5ndGglMiE9MCl7dGhyb3dcImlucHV0IGlzIG5vdCBldmVuIGxlbmd0aFwifWlmKGQubWF0Y2goL15bMC05QS1GYS1mXSskLyk9PW51bGwpe3Rocm93XCJpbnB1dCBpcyBub3QgaGV4YWRlY2ltYWxcIn12YXIgYj1uZXcgQXJyYXlCdWZmZXIoZC5sZW5ndGgvMik7dmFyIGE9bmV3IERhdGFWaWV3KGIpO2Zvcih2YXIgYz0wO2M8ZC5sZW5ndGgvMjtjKyspe2Euc2V0VWludDgoYyxwYXJzZUludChkLnN1YnN0cihjKjIsMiksMTYpKX1yZXR1cm4gYn1mdW5jdGlvbiBBcnJheUJ1ZmZlcnRvaGV4KGIpe3ZhciBkPVwiXCI7dmFyIGE9bmV3IERhdGFWaWV3KGIpO2Zvcih2YXIgYz0wO2M8Yi5ieXRlTGVuZ3RoO2MrKyl7ZCs9KFwiMDBcIithLmdldFVpbnQ4KGMpLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpfXJldHVybiBkfWZ1bmN0aW9uIHp1bHV0b21zZWMobil7dmFyIGwsaixtLGUsZixpLGIsazt2YXIgYSxoLGcsYztjPW4ubWF0Y2goL14oXFxkezJ9fFxcZHs0fSkoXFxkXFxkKShcXGRcXGQpKFxcZFxcZCkoXFxkXFxkKShcXGRcXGQpKHxcXC5cXGQrKVokLyk7aWYoYyl7YT1jWzFdO2w9cGFyc2VJbnQoYSk7aWYoYS5sZW5ndGg9PT0yKXtpZig1MDw9bCYmbDwxMDApe2w9MTkwMCtsfWVsc2V7aWYoMDw9bCYmbDw1MCl7bD0yMDAwK2x9fX1qPXBhcnNlSW50KGNbMl0pLTE7bT1wYXJzZUludChjWzNdKTtlPXBhcnNlSW50KGNbNF0pO2Y9cGFyc2VJbnQoY1s1XSk7aT1wYXJzZUludChjWzZdKTtiPTA7aD1jWzddO2lmKGghPT1cIlwiKXtnPShoLnN1YnN0cigxKStcIjAwXCIpLnN1YnN0cigwLDMpO2I9cGFyc2VJbnQoZyl9cmV0dXJuIERhdGUuVVRDKGwsaixtLGUsZixpLGIpfXRocm93XCJ1bnN1cHBvcnRlZCB6dWx1IGZvcm1hdDogXCIrbn1mdW5jdGlvbiB6dWx1dG9zZWMoYSl7dmFyIGI9enVsdXRvbXNlYyhhKTtyZXR1cm4gfn4oYi8xMDAwKX1mdW5jdGlvbiB6dWx1dG9kYXRlKGEpe3JldHVybiBuZXcgRGF0ZSh6dWx1dG9tc2VjKGEpKX1mdW5jdGlvbiBkYXRldG96dWx1KGcsZSxmKXt2YXIgYjt2YXIgYT1nLmdldFVUQ0Z1bGxZZWFyKCk7aWYoZSl7aWYoYTwxOTUwfHwyMDQ5PGEpe3Rocm93XCJub3QgcHJvcGVyIHllYXIgZm9yIFVUQ1RpbWU6IFwiK2F9Yj0oXCJcIithKS5zbGljZSgtMil9ZWxzZXtiPShcIjAwMFwiK2EpLnNsaWNlKC00KX1iKz0oXCIwXCIrKGcuZ2V0VVRDTW9udGgoKSsxKSkuc2xpY2UoLTIpO2IrPShcIjBcIitnLmdldFVUQ0RhdGUoKSkuc2xpY2UoLTIpO2IrPShcIjBcIitnLmdldFVUQ0hvdXJzKCkpLnNsaWNlKC0yKTtiKz0oXCIwXCIrZy5nZXRVVENNaW51dGVzKCkpLnNsaWNlKC0yKTtiKz0oXCIwXCIrZy5nZXRVVENTZWNvbmRzKCkpLnNsaWNlKC0yKTtpZihmKXt2YXIgYz1nLmdldFVUQ01pbGxpc2Vjb25kcygpO2lmKGMhPT0wKXtjPShcIjAwXCIrYykuc2xpY2UoLTMpO2M9Yy5yZXBsYWNlKC8wKyQvZyxcIlwiKTtiKz1cIi5cIitjfX1iKz1cIlpcIjtyZXR1cm4gYn1mdW5jdGlvbiB1cmljbXB0b2hleChhKXtyZXR1cm4gYS5yZXBsYWNlKC8lL2csXCJcIil9ZnVuY3Rpb24gaGV4dG91cmljbXAoYSl7cmV0dXJuIGEucmVwbGFjZSgvKC4uKS9nLFwiJSQxXCIpfWZ1bmN0aW9uIGlwdjZ0b2hleChnKXt2YXIgYj1cIm1hbGZvcm1lZCBJUHY2IGFkZHJlc3NcIjtpZighZy5tYXRjaCgvXlswLTlBLUZhLWY6XSskLykpe3Rocm93IGJ9Zz1nLnRvTG93ZXJDYXNlKCk7dmFyIGQ9Zy5zcGxpdChcIjpcIikubGVuZ3RoLTE7aWYoZDwyKXt0aHJvdyBifXZhciBlPVwiOlwiLnJlcGVhdCg3LWQrMik7Zz1nLnJlcGxhY2UoXCI6OlwiLGUpO3ZhciBjPWcuc3BsaXQoXCI6XCIpO2lmKGMubGVuZ3RoIT04KXt0aHJvdyBifWZvcih2YXIgZj0wO2Y8ODtmKyspe2NbZl09KFwiMDAwMFwiK2NbZl0pLnNsaWNlKC00KX1yZXR1cm4gYy5qb2luKFwiXCIpfWZ1bmN0aW9uIGhleHRvaXB2NihlKXtpZighZS5tYXRjaCgvXlswLTlBLUZhLWZdezMyfSQvKSl7dGhyb3dcIm1hbGZvcm1lZCBJUHY2IGFkZHJlc3Mgb2N0ZXRcIn1lPWUudG9Mb3dlckNhc2UoKTt2YXIgYj1lLm1hdGNoKC8uezEsNH0vZyk7Zm9yKHZhciBkPTA7ZDw4O2QrKyl7YltkXT1iW2RdLnJlcGxhY2UoL14wKy8sXCJcIik7aWYoYltkXT09XCJcIil7YltkXT1cIjBcIn19ZT1cIjpcIitiLmpvaW4oXCI6XCIpK1wiOlwiO3ZhciBjPWUubWF0Y2goLzooMDopezIsfS9nKTtpZihjPT09bnVsbCl7cmV0dXJuIGUuc2xpY2UoMSwtMSl9dmFyIGY9XCJcIjtmb3IodmFyIGQ9MDtkPGMubGVuZ3RoO2QrKyl7aWYoY1tkXS5sZW5ndGg+Zi5sZW5ndGgpe2Y9Y1tkXX19ZT1lLnJlcGxhY2UoZixcIjo6XCIpO3JldHVybiBlLnNsaWNlKDEsLTEpfWZ1bmN0aW9uIGhleHRvaXAoYil7dmFyIGQ9XCJtYWxmb3JtZWQgaGV4IHZhbHVlXCI7aWYoIWIubWF0Y2goL14oWzAtOUEtRmEtZl1bMC05QS1GYS1mXSl7MSx9JC8pKXt0aHJvdyBkfWlmKGIubGVuZ3RoPT04KXt2YXIgYzt0cnl7Yz1wYXJzZUludChiLnN1YnN0cigwLDIpLDE2KStcIi5cIitwYXJzZUludChiLnN1YnN0cigyLDIpLDE2KStcIi5cIitwYXJzZUludChiLnN1YnN0cig0LDIpLDE2KStcIi5cIitwYXJzZUludChiLnN1YnN0cig2LDIpLDE2KTtyZXR1cm4gY31jYXRjaChhKXt0aHJvdyBkfX1lbHNle2lmKGIubGVuZ3RoPT0zMil7cmV0dXJuIGhleHRvaXB2NihiKX1lbHNle3JldHVybiBifX19ZnVuY3Rpb24gaXB0b2hleChmKXt2YXIgaj1cIm1hbGZvcm1lZCBJUCBhZGRyZXNzXCI7Zj1mLnRvTG93ZXJDYXNlKGYpO2lmKGYubWF0Y2goL15bMC05Ll0rJC8pKXt2YXIgYj1mLnNwbGl0KFwiLlwiKTtpZihiLmxlbmd0aCE9PTQpe3Rocm93IGp9dmFyIGc9XCJcIjt0cnl7Zm9yKHZhciBlPTA7ZTw0O2UrKyl7dmFyIGg9cGFyc2VJbnQoYltlXSk7Zys9KFwiMFwiK2gudG9TdHJpbmcoMTYpKS5zbGljZSgtMil9cmV0dXJuIGd9Y2F0Y2goYyl7dGhyb3cgan19ZWxzZXtpZihmLm1hdGNoKC9eWzAtOWEtZjpdKyQvKSYmZi5pbmRleE9mKFwiOlwiKSE9PS0xKXtyZXR1cm4gaXB2NnRvaGV4KGYpfWVsc2V7dGhyb3cgan19fWZ1bmN0aW9uIGVuY29kZVVSSUNvbXBvbmVudEFsbChhKXt2YXIgZD1lbmNvZGVVUklDb21wb25lbnQoYSk7dmFyIGI9XCJcIjtmb3IodmFyIGM9MDtjPGQubGVuZ3RoO2MrKyl7aWYoZFtjXT09XCIlXCIpe2I9YitkLnN1YnN0cihjLDMpO2M9YysyfWVsc2V7Yj1iK1wiJVwiK3N0b2hleChkW2NdKX19cmV0dXJuIGJ9ZnVuY3Rpb24gbmV3bGluZV90b1VuaXgoYSl7YT1hLnJlcGxhY2UoL1xcclxcbi9tZyxcIlxcblwiKTtyZXR1cm4gYX1mdW5jdGlvbiBuZXdsaW5lX3RvRG9zKGEpe2E9YS5yZXBsYWNlKC9cXHJcXG4vbWcsXCJcXG5cIik7YT1hLnJlcGxhY2UoL1xcbi9tZyxcIlxcclxcblwiKTtyZXR1cm4gYX1LSlVSLmxhbmcuU3RyaW5nLmlzSW50ZWdlcj1mdW5jdGlvbihhKXtpZihhLm1hdGNoKC9eWzAtOV0rJC8pKXtyZXR1cm4gdHJ1ZX1lbHNle2lmKGEubWF0Y2goL14tWzAtOV0rJC8pKXtyZXR1cm4gdHJ1ZX1lbHNle3JldHVybiBmYWxzZX19fTtLSlVSLmxhbmcuU3RyaW5nLmlzSGV4PWZ1bmN0aW9uKGEpe2lmKGEubGVuZ3RoJTI9PTAmJihhLm1hdGNoKC9eWzAtOWEtZl0rJC8pfHxhLm1hdGNoKC9eWzAtOUEtRl0rJC8pKSl7cmV0dXJuIHRydWV9ZWxzZXtyZXR1cm4gZmFsc2V9fTtLSlVSLmxhbmcuU3RyaW5nLmlzQmFzZTY0PWZ1bmN0aW9uKGEpe2E9YS5yZXBsYWNlKC9cXHMrL2csXCJcIik7aWYoYS5tYXRjaCgvXlswLTlBLVphLXorXFwvXSs9ezAsM30kLykmJmEubGVuZ3RoJTQ9PTApe3JldHVybiB0cnVlfWVsc2V7cmV0dXJuIGZhbHNlfX07S0pVUi5sYW5nLlN0cmluZy5pc0Jhc2U2NFVSTD1mdW5jdGlvbihhKXtpZihhLm1hdGNoKC9bKy89XS8pKXtyZXR1cm4gZmFsc2V9YT1iNjR1dG9iNjQoYSk7cmV0dXJuIEtKVVIubGFuZy5TdHJpbmcuaXNCYXNlNjQoYSl9O0tKVVIubGFuZy5TdHJpbmcuaXNJbnRlZ2VyQXJyYXk9ZnVuY3Rpb24oYSl7YT1hLnJlcGxhY2UoL1xccysvZyxcIlwiKTtpZihhLm1hdGNoKC9eXFxbWzAtOSxdK1xcXSQvKSl7cmV0dXJuIHRydWV9ZWxzZXtyZXR1cm4gZmFsc2V9fTtmdW5jdGlvbiBoZXh0b3Bvc2hleChhKXtpZihhLmxlbmd0aCUyPT0xKXtyZXR1cm5cIjBcIithfWlmKGEuc3Vic3RyKDAsMSk+XCI3XCIpe3JldHVyblwiMDBcIithfXJldHVybiBhfWZ1bmN0aW9uIGludGFyeXN0cnRvaGV4KGIpe2I9Yi5yZXBsYWNlKC9eXFxzKlxcW1xccyovLFwiXCIpO2I9Yi5yZXBsYWNlKC9cXHMqXFxdXFxzKiQvLFwiXCIpO2I9Yi5yZXBsYWNlKC9cXHMqL2csXCJcIik7dHJ5e3ZhciBjPWIuc3BsaXQoLywvKS5tYXAoZnVuY3Rpb24oZyxlLGgpe3ZhciBmPXBhcnNlSW50KGcpO2lmKGY8MHx8MjU1PGYpe3Rocm93XCJpbnRlZ2VyIG5vdCBpbiByYW5nZSAwLTI1NVwifXZhciBkPShcIjAwXCIrZi50b1N0cmluZygxNikpLnNsaWNlKC0yKTtyZXR1cm4gZH0pLmpvaW4oXCJcIik7cmV0dXJuIGN9Y2F0Y2goYSl7dGhyb3dcIm1hbGZvcm1lZCBpbnRlZ2VyIGFycmF5IHN0cmluZzogXCIrYX19dmFyIHN0cmRpZmZpZHg9ZnVuY3Rpb24oYyxhKXt2YXIgZD1jLmxlbmd0aDtpZihjLmxlbmd0aD5hLmxlbmd0aCl7ZD1hLmxlbmd0aH1mb3IodmFyIGI9MDtiPGQ7YisrKXtpZihjLmNoYXJDb2RlQXQoYikhPWEuY2hhckNvZGVBdChiKSl7cmV0dXJuIGJ9fWlmKGMubGVuZ3RoIT1hLmxlbmd0aCl7cmV0dXJuIGR9cmV0dXJuIC0xfTtcbmlmKHR5cGVvZiBLSlVSPT1cInVuZGVmaW5lZFwifHwhS0pVUil7S0pVUj17fX1pZih0eXBlb2YgS0pVUi5jcnlwdG89PVwidW5kZWZpbmVkXCJ8fCFLSlVSLmNyeXB0byl7S0pVUi5jcnlwdG89e319S0pVUi5jcnlwdG8uVXRpbD1uZXcgZnVuY3Rpb24oKXt0aGlzLkRJR0VTVElORk9IRUFEPXtzaGExOlwiMzAyMTMwMDkwNjA1MmIwZTAzMDIxYTA1MDAwNDE0XCIsc2hhMjI0OlwiMzAyZDMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjA0MDUwMDA0MWNcIixzaGEyNTY6XCIzMDMxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDEwNTAwMDQyMFwiLHNoYTM4NDpcIjMwNDEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMjA1MDAwNDMwXCIsc2hhNTEyOlwiMzA1MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAzMDUwMDA0NDBcIixtZDI6XCIzMDIwMzAwYzA2MDgyYTg2NDg4NmY3MGQwMjAyMDUwMDA0MTBcIixtZDU6XCIzMDIwMzAwYzA2MDgyYTg2NDg4NmY3MGQwMjA1MDUwMDA0MTBcIixyaXBlbWQxNjA6XCIzMDIxMzAwOTA2MDUyYjI0MDMwMjAxMDUwMDA0MTRcIix9O3RoaXMuREVGQVVMVFBST1ZJREVSPXttZDU6XCJjcnlwdG9qc1wiLHNoYTE6XCJjcnlwdG9qc1wiLHNoYTIyNDpcImNyeXB0b2pzXCIsc2hhMjU2OlwiY3J5cHRvanNcIixzaGEzODQ6XCJjcnlwdG9qc1wiLHNoYTUxMjpcImNyeXB0b2pzXCIscmlwZW1kMTYwOlwiY3J5cHRvanNcIixobWFjbWQ1OlwiY3J5cHRvanNcIixobWFjc2hhMTpcImNyeXB0b2pzXCIsaG1hY3NoYTIyNDpcImNyeXB0b2pzXCIsaG1hY3NoYTI1NjpcImNyeXB0b2pzXCIsaG1hY3NoYTM4NDpcImNyeXB0b2pzXCIsaG1hY3NoYTUxMjpcImNyeXB0b2pzXCIsaG1hY3JpcGVtZDE2MDpcImNyeXB0b2pzXCIsTUQ1d2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMXdpdGhSU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTIyNHdpdGhSU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTI1NndpdGhSU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTM4NHdpdGhSU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTUxMndpdGhSU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFJJUEVNRDE2MHdpdGhSU0E6XCJjcnlwdG9qcy9qc3JzYVwiLE1ENXdpdGhFQ0RTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMXdpdGhFQ0RTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMjI0d2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEEyNTZ3aXRoRUNEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTM4NHdpdGhFQ0RTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBNTEyd2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixSSVBFTUQxNjB3aXRoRUNEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTF3aXRoRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEEyMjR3aXRoRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEEyNTZ3aXRoRFNBOlwiY3J5cHRvanMvanNyc2FcIixNRDV3aXRoUlNBYW5kTUdGMTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMXdpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixTSEEyMjR3aXRoUlNBYW5kTUdGMTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMjU2d2l0aFJTQWFuZE1HRjE6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTM4NHdpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixTSEE1MTJ3aXRoUlNBYW5kTUdGMTpcImNyeXB0b2pzL2pzcnNhXCIsUklQRU1EMTYwd2l0aFJTQWFuZE1HRjE6XCJjcnlwdG9qcy9qc3JzYVwiLH07dGhpcy5DUllQVE9KU01FU1NBR0VESUdFU1ROQU1FPXttZDU6Q3J5cHRvSlMuYWxnby5NRDUsc2hhMTpDcnlwdG9KUy5hbGdvLlNIQTEsc2hhMjI0OkNyeXB0b0pTLmFsZ28uU0hBMjI0LHNoYTI1NjpDcnlwdG9KUy5hbGdvLlNIQTI1NixzaGEzODQ6Q3J5cHRvSlMuYWxnby5TSEEzODQsc2hhNTEyOkNyeXB0b0pTLmFsZ28uU0hBNTEyLHJpcGVtZDE2MDpDcnlwdG9KUy5hbGdvLlJJUEVNRDE2MH07dGhpcy5nZXREaWdlc3RJbmZvSGV4PWZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIHRoaXMuRElHRVNUSU5GT0hFQURbYl09PVwidW5kZWZpbmVkXCIpe3Rocm93XCJhbGcgbm90IHN1cHBvcnRlZCBpbiBVdGlsLkRJR0VTVElORk9IRUFEOiBcIitifXJldHVybiB0aGlzLkRJR0VTVElORk9IRUFEW2JdK2F9O3RoaXMuZ2V0UGFkZGVkRGlnZXN0SW5mb0hleD1mdW5jdGlvbihoLGEsail7dmFyIGM9dGhpcy5nZXREaWdlc3RJbmZvSGV4KGgsYSk7dmFyIGQ9ai80O2lmKGMubGVuZ3RoKzIyPmQpe3Rocm93XCJrZXkgaXMgdG9vIHNob3J0IGZvciBTaWdBbGc6IGtleWxlbj1cIitqK1wiLFwiK2F9dmFyIGI9XCIwMDAxXCI7dmFyIGs9XCIwMFwiK2M7dmFyIGc9XCJcIjt2YXIgbD1kLWIubGVuZ3RoLWsubGVuZ3RoO2Zvcih2YXIgZj0wO2Y8bDtmKz0yKXtnKz1cImZmXCJ9dmFyIGU9YitnK2s7cmV0dXJuIGV9O3RoaXMuaGFzaFN0cmluZz1mdW5jdGlvbihhLGMpe3ZhciBiPW5ldyBLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0KHthbGc6Y30pO3JldHVybiBiLmRpZ2VzdFN0cmluZyhhKX07dGhpcy5oYXNoSGV4PWZ1bmN0aW9uKGIsYyl7dmFyIGE9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpjfSk7cmV0dXJuIGEuZGlnZXN0SGV4KGIpfTt0aGlzLnNoYTE9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpcInNoYTFcIixwcm92OlwiY3J5cHRvanNcIn0pO3JldHVybiBiLmRpZ2VzdFN0cmluZyhhKX07dGhpcy5zaGEyNTY9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpcInNoYTI1NlwiLHByb3Y6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTt0aGlzLnNoYTI1NkhleD1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwic2hhMjU2XCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RIZXgoYSl9O3RoaXMuc2hhNTEyPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0KHthbGc6XCJzaGE1MTJcIixwcm92OlwiY3J5cHRvanNcIn0pO3JldHVybiBiLmRpZ2VzdFN0cmluZyhhKX07dGhpcy5zaGE1MTJIZXg9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpcInNoYTUxMlwiLHByb3Y6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGIuZGlnZXN0SGV4KGEpfX07S0pVUi5jcnlwdG8uVXRpbC5tZDU9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpcIm1kNVwiLHByb3Y6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTtLSlVSLmNyeXB0by5VdGlsLnJpcGVtZDE2MD1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwicmlwZW1kMTYwXCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RTdHJpbmcoYSl9O0tKVVIuY3J5cHRvLlV0aWwuU0VDVVJFUkFORE9NR0VOPW5ldyBTZWN1cmVSYW5kb20oKTtLSlVSLmNyeXB0by5VdGlsLmdldFJhbmRvbUhleE9mTmJ5dGVzPWZ1bmN0aW9uKGIpe3ZhciBhPW5ldyBBcnJheShiKTtLSlVSLmNyeXB0by5VdGlsLlNFQ1VSRVJBTkRPTUdFTi5uZXh0Qnl0ZXMoYSk7cmV0dXJuIEJBdG9oZXgoYSl9O0tKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tQmlnSW50ZWdlck9mTmJ5dGVzPWZ1bmN0aW9uKGEpe3JldHVybiBuZXcgQmlnSW50ZWdlcihLSlVSLmNyeXB0by5VdGlsLmdldFJhbmRvbUhleE9mTmJ5dGVzKGEpLDE2KX07S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21IZXhPZk5iaXRzPWZ1bmN0aW9uKGQpe3ZhciBjPWQlODt2YXIgYT0oZC1jKS84O3ZhciBiPW5ldyBBcnJheShhKzEpO0tKVVIuY3J5cHRvLlV0aWwuU0VDVVJFUkFORE9NR0VOLm5leHRCeXRlcyhiKTtiWzBdPSgoKDI1NTw8YykmMjU1KV4yNTUpJmJbMF07cmV0dXJuIEJBdG9oZXgoYil9O0tKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tQmlnSW50ZWdlck9mTmJpdHM9ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKEtKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tSGV4T2ZOYml0cyhhKSwxNil9O0tKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tQmlnSW50ZWdlclplcm9Ub01heD1mdW5jdGlvbihiKXt2YXIgYT1iLmJpdExlbmd0aCgpO3doaWxlKDEpe3ZhciBjPUtKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tQmlnSW50ZWdlck9mTmJpdHMoYSk7aWYoYi5jb21wYXJlVG8oYykhPS0xKXtyZXR1cm4gY319fTtLSlVSLmNyeXB0by5VdGlsLmdldFJhbmRvbUJpZ0ludGVnZXJNaW5Ub01heD1mdW5jdGlvbihlLGIpe3ZhciBjPWUuY29tcGFyZVRvKGIpO2lmKGM9PTEpe3Rocm93XCJiaU1pbiBpcyBncmVhdGVyIHRoYW4gYmlNYXhcIn1pZihjPT0wKXtyZXR1cm4gZX12YXIgYT1iLnN1YnRyYWN0KGUpO3ZhciBkPUtKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tQmlnSW50ZWdlclplcm9Ub01heChhKTtyZXR1cm4gZC5hZGQoZSl9O0tKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Q9ZnVuY3Rpb24oYyl7dmFyIGI9bnVsbDt2YXIgYT1udWxsO3ZhciBkPW51bGw7dGhpcy5zZXRBbGdBbmRQcm92aWRlcj1mdW5jdGlvbihnLGYpe2c9S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdC5nZXRDYW5vbmljYWxBbGdOYW1lKGcpO2lmKGchPT1udWxsJiZmPT09dW5kZWZpbmVkKXtmPUtKVVIuY3J5cHRvLlV0aWwuREVGQVVMVFBST1ZJREVSW2ddfWlmKFwiOm1kNTpzaGExOnNoYTIyNDpzaGEyNTY6c2hhMzg0OnNoYTUxMjpyaXBlbWQxNjA6XCIuaW5kZXhPZihnKSE9LTEmJmY9PVwiY3J5cHRvanNcIil7dHJ5e3RoaXMubWQ9S0pVUi5jcnlwdG8uVXRpbC5DUllQVE9KU01FU1NBR0VESUdFU1ROQU1FW2ddLmNyZWF0ZSgpfWNhdGNoKGUpe3Rocm93XCJzZXRBbGdBbmRQcm92aWRlciBoYXNoIGFsZyBzZXQgZmFpbCBhbGc9XCIrZytcIi9cIitlfXRoaXMudXBkYXRlU3RyaW5nPWZ1bmN0aW9uKGgpe3RoaXMubWQudXBkYXRlKGgpfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihoKXt2YXIgaT1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGgpO3RoaXMubWQudXBkYXRlKGkpfTt0aGlzLmRpZ2VzdD1mdW5jdGlvbigpe3ZhciBoPXRoaXMubWQuZmluYWxpemUoKTtyZXR1cm4gaC50b1N0cmluZyhDcnlwdG9KUy5lbmMuSGV4KX07dGhpcy5kaWdlc3RTdHJpbmc9ZnVuY3Rpb24oaCl7dGhpcy51cGRhdGVTdHJpbmcoaCk7cmV0dXJuIHRoaXMuZGlnZXN0KCl9O3RoaXMuZGlnZXN0SGV4PWZ1bmN0aW9uKGgpe3RoaXMudXBkYXRlSGV4KGgpO3JldHVybiB0aGlzLmRpZ2VzdCgpfX1pZihcIjpzaGEyNTY6XCIuaW5kZXhPZihnKSE9LTEmJmY9PVwic2pjbFwiKXt0cnl7dGhpcy5tZD1uZXcgc2pjbC5oYXNoLnNoYTI1NigpfWNhdGNoKGUpe3Rocm93XCJzZXRBbGdBbmRQcm92aWRlciBoYXNoIGFsZyBzZXQgZmFpbCBhbGc9XCIrZytcIi9cIitlfXRoaXMudXBkYXRlU3RyaW5nPWZ1bmN0aW9uKGgpe3RoaXMubWQudXBkYXRlKGgpfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihpKXt2YXIgaD1zamNsLmNvZGVjLmhleC50b0JpdHMoaSk7dGhpcy5tZC51cGRhdGUoaCl9O3RoaXMuZGlnZXN0PWZ1bmN0aW9uKCl7dmFyIGg9dGhpcy5tZC5maW5hbGl6ZSgpO3JldHVybiBzamNsLmNvZGVjLmhleC5mcm9tQml0cyhoKX07dGhpcy5kaWdlc3RTdHJpbmc9ZnVuY3Rpb24oaCl7dGhpcy51cGRhdGVTdHJpbmcoaCk7cmV0dXJuIHRoaXMuZGlnZXN0KCl9O3RoaXMuZGlnZXN0SGV4PWZ1bmN0aW9uKGgpe3RoaXMudXBkYXRlSGV4KGgpO3JldHVybiB0aGlzLmRpZ2VzdCgpfX19O3RoaXMudXBkYXRlU3RyaW5nPWZ1bmN0aW9uKGUpe3Rocm93XCJ1cGRhdGVTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmFsZ05hbWUrXCIvXCIrdGhpcy5wcm92TmFtZX07dGhpcy51cGRhdGVIZXg9ZnVuY3Rpb24oZSl7dGhyb3dcInVwZGF0ZUhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnTmFtZStcIi9cIit0aGlzLnByb3ZOYW1lfTt0aGlzLmRpZ2VzdD1mdW5jdGlvbigpe3Rocm93XCJkaWdlc3QoKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmFsZ05hbWUrXCIvXCIrdGhpcy5wcm92TmFtZX07dGhpcy5kaWdlc3RTdHJpbmc9ZnVuY3Rpb24oZSl7dGhyb3dcImRpZ2VzdFN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnTmFtZStcIi9cIit0aGlzLnByb3ZOYW1lfTt0aGlzLmRpZ2VzdEhleD1mdW5jdGlvbihlKXt0aHJvd1wiZGlnZXN0SGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdOYW1lK1wiL1wiK3RoaXMucHJvdk5hbWV9O2lmKGMhPT11bmRlZmluZWQpe2lmKGMuYWxnIT09dW5kZWZpbmVkKXt0aGlzLmFsZ05hbWU9Yy5hbGc7aWYoYy5wcm92PT09dW5kZWZpbmVkKXt0aGlzLnByb3ZOYW1lPUtKVVIuY3J5cHRvLlV0aWwuREVGQVVMVFBST1ZJREVSW3RoaXMuYWxnTmFtZV19dGhpcy5zZXRBbGdBbmRQcm92aWRlcih0aGlzLmFsZ05hbWUsdGhpcy5wcm92TmFtZSl9fX07S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdC5nZXRDYW5vbmljYWxBbGdOYW1lPWZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT09XCJzdHJpbmdcIil7YT1hLnRvTG93ZXJDYXNlKCk7YT1hLnJlcGxhY2UoLy0vLFwiXCIpfXJldHVybiBhfTtLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0LmdldEhhc2hMZW5ndGg9ZnVuY3Rpb24oYyl7dmFyIGI9S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdDt2YXIgYT1iLmdldENhbm9uaWNhbEFsZ05hbWUoYyk7aWYoYi5IQVNITEVOR1RIW2FdPT09dW5kZWZpbmVkKXt0aHJvd1wibm90IHN1cHBvcnRlZCBhbGdvcml0aG06IFwiK2N9cmV0dXJuIGIuSEFTSExFTkdUSFthXX07S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdC5IQVNITEVOR1RIPXttZDU6MTYsc2hhMToyMCxzaGEyMjQ6Mjgsc2hhMjU2OjMyLHNoYTM4NDo0OCxzaGE1MTI6NjQscmlwZW1kMTYwOjIwfTtLSlVSLmNyeXB0by5NYWM9ZnVuY3Rpb24oZCl7dmFyIGY9bnVsbDt2YXIgYz1udWxsO3ZhciBhPW51bGw7dmFyIGU9bnVsbDt2YXIgYj1udWxsO3RoaXMuc2V0QWxnQW5kUHJvdmlkZXI9ZnVuY3Rpb24oayxpKXtrPWsudG9Mb3dlckNhc2UoKTtpZihrPT1udWxsKXtrPVwiaG1hY3NoYTFcIn1rPWsudG9Mb3dlckNhc2UoKTtpZihrLnN1YnN0cigwLDQpIT1cImhtYWNcIil7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIHVuc3VwcG9ydGVkIEhNQUMgYWxnOiBcIitrfWlmKGk9PT11bmRlZmluZWQpe2k9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJba119dGhpcy5hbGdQcm92PWsrXCIvXCIraTt2YXIgZz1rLnN1YnN0cig0KTtpZihcIjptZDU6c2hhMTpzaGEyMjQ6c2hhMjU2OnNoYTM4NDpzaGE1MTI6cmlwZW1kMTYwOlwiLmluZGV4T2YoZykhPS0xJiZpPT1cImNyeXB0b2pzXCIpe3RyeXt2YXIgaj1LSlVSLmNyeXB0by5VdGlsLkNSWVBUT0pTTUVTU0FHRURJR0VTVE5BTUVbZ107dGhpcy5tYWM9Q3J5cHRvSlMuYWxnby5ITUFDLmNyZWF0ZShqLHRoaXMucGFzcyl9Y2F0Y2goaCl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGhhc2hBbGc9XCIrZytcIi9cIitofXRoaXMudXBkYXRlU3RyaW5nPWZ1bmN0aW9uKGwpe3RoaXMubWFjLnVwZGF0ZShsKX07dGhpcy51cGRhdGVIZXg9ZnVuY3Rpb24obCl7dmFyIG09Q3J5cHRvSlMuZW5jLkhleC5wYXJzZShsKTt0aGlzLm1hYy51cGRhdGUobSl9O3RoaXMuZG9GaW5hbD1mdW5jdGlvbigpe3ZhciBsPXRoaXMubWFjLmZpbmFsaXplKCk7cmV0dXJuIGwudG9TdHJpbmcoQ3J5cHRvSlMuZW5jLkhleCl9O3RoaXMuZG9GaW5hbFN0cmluZz1mdW5jdGlvbihsKXt0aGlzLnVwZGF0ZVN0cmluZyhsKTtyZXR1cm4gdGhpcy5kb0ZpbmFsKCl9O3RoaXMuZG9GaW5hbEhleD1mdW5jdGlvbihsKXt0aGlzLnVwZGF0ZUhleChsKTtyZXR1cm4gdGhpcy5kb0ZpbmFsKCl9fX07dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24oZyl7dGhyb3dcInVwZGF0ZVN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnUHJvdn07dGhpcy51cGRhdGVIZXg9ZnVuY3Rpb24oZyl7dGhyb3dcInVwZGF0ZUhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnUHJvdn07dGhpcy5kb0ZpbmFsPWZ1bmN0aW9uKCl7dGhyb3dcImRpZ2VzdCgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnUHJvdn07dGhpcy5kb0ZpbmFsU3RyaW5nPWZ1bmN0aW9uKGcpe3Rocm93XCJkaWdlc3RTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmFsZ1Byb3Z9O3RoaXMuZG9GaW5hbEhleD1mdW5jdGlvbihnKXt0aHJvd1wiZGlnZXN0SGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdQcm92fTt0aGlzLnNldFBhc3N3b3JkPWZ1bmN0aW9uKGgpe2lmKHR5cGVvZiBoPT1cInN0cmluZ1wiKXt2YXIgZz1oO2lmKGgubGVuZ3RoJTI9PTF8fCFoLm1hdGNoKC9eWzAtOUEtRmEtZl0rJC8pKXtnPXJzdHJ0b2hleChoKX10aGlzLnBhc3M9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZShnKTtyZXR1cm59aWYodHlwZW9mIGghPVwib2JqZWN0XCIpe3Rocm93XCJLSlVSLmNyeXB0by5NYWMgdW5zdXBwb3J0ZWQgcGFzc3dvcmQgdHlwZTogXCIraH12YXIgZz1udWxsO2lmKGguaGV4IT09dW5kZWZpbmVkKXtpZihoLmhleC5sZW5ndGglMiE9MHx8IWguaGV4Lm1hdGNoKC9eWzAtOUEtRmEtZl0rJC8pKXt0aHJvd1wiTWFjOiB3cm9uZyBoZXggcGFzc3dvcmQ6IFwiK2guaGV4fWc9aC5oZXh9aWYoaC51dGY4IT09dW5kZWZpbmVkKXtnPXV0Zjh0b2hleChoLnV0ZjgpfWlmKGgucnN0ciE9PXVuZGVmaW5lZCl7Zz1yc3RydG9oZXgoaC5yc3RyKX1pZihoLmI2NCE9PXVuZGVmaW5lZCl7Zz1iNjR0b2hleChoLmI2NCl9aWYoaC5iNjR1IT09dW5kZWZpbmVkKXtnPWI2NHV0b2hleChoLmI2NHUpfWlmKGc9PW51bGwpe3Rocm93XCJLSlVSLmNyeXB0by5NYWMgdW5zdXBwb3J0ZWQgcGFzc3dvcmQgdHlwZTogXCIraH10aGlzLnBhc3M9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZShnKX07aWYoZCE9PXVuZGVmaW5lZCl7aWYoZC5wYXNzIT09dW5kZWZpbmVkKXt0aGlzLnNldFBhc3N3b3JkKGQucGFzcyl9aWYoZC5hbGchPT11bmRlZmluZWQpe3RoaXMuYWxnTmFtZT1kLmFsZztpZihkLnByb3Y9PT11bmRlZmluZWQpe3RoaXMucHJvdk5hbWU9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJbdGhpcy5hbGdOYW1lXX10aGlzLnNldEFsZ0FuZFByb3ZpZGVyKHRoaXMuYWxnTmFtZSx0aGlzLnByb3ZOYW1lKX19fTtLSlVSLmNyeXB0by5TaWduYXR1cmU9ZnVuY3Rpb24obyl7dmFyIHE9bnVsbDt2YXIgbj1udWxsO3ZhciByPW51bGw7dmFyIGM9bnVsbDt2YXIgbD1udWxsO3ZhciBkPW51bGw7dmFyIGs9bnVsbDt2YXIgaD1udWxsO3ZhciBwPW51bGw7dmFyIGU9bnVsbDt2YXIgYj0tMTt2YXIgZz1udWxsO3ZhciBqPW51bGw7dmFyIGE9bnVsbDt2YXIgaT1udWxsO3ZhciBmPW51bGw7dGhpcy5fc2V0QWxnTmFtZXM9ZnVuY3Rpb24oKXt2YXIgcz10aGlzLmFsZ05hbWUubWF0Y2goL14oLispd2l0aCguKykkLyk7aWYocyl7dGhpcy5tZEFsZ05hbWU9c1sxXS50b0xvd2VyQ2FzZSgpO3RoaXMucHVia2V5QWxnTmFtZT1zWzJdLnRvTG93ZXJDYXNlKCl9fTt0aGlzLl96ZXJvUGFkZGluZ09mU2lnbmF0dXJlPWZ1bmN0aW9uKHgsdyl7dmFyIHY9XCJcIjt2YXIgdD13LzQteC5sZW5ndGg7Zm9yKHZhciB1PTA7dTx0O3UrKyl7dj12K1wiMFwifXJldHVybiB2K3h9O3RoaXMuc2V0QWxnQW5kUHJvdmlkZXI9ZnVuY3Rpb24odSx0KXt0aGlzLl9zZXRBbGdOYW1lcygpO2lmKHQhPVwiY3J5cHRvanMvanNyc2FcIil7dGhyb3dcInByb3ZpZGVyIG5vdCBzdXBwb3J0ZWQ6IFwiK3R9aWYoXCI6bWQ1OnNoYTE6c2hhMjI0OnNoYTI1NjpzaGEzODQ6c2hhNTEyOnJpcGVtZDE2MDpcIi5pbmRleE9mKHRoaXMubWRBbGdOYW1lKSE9LTEpe3RyeXt0aGlzLm1kPW5ldyBLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0KHthbGc6dGhpcy5tZEFsZ05hbWV9KX1jYXRjaChzKXt0aHJvd1wic2V0QWxnQW5kUHJvdmlkZXIgaGFzaCBhbGcgc2V0IGZhaWwgYWxnPVwiK3RoaXMubWRBbGdOYW1lK1wiL1wiK3N9dGhpcy5pbml0PWZ1bmN0aW9uKHcseCl7dmFyIHk9bnVsbDt0cnl7aWYoeD09PXVuZGVmaW5lZCl7eT1LRVlVVElMLmdldEtleSh3KX1lbHNle3k9S0VZVVRJTC5nZXRLZXkodyx4KX19Y2F0Y2godil7dGhyb3dcImluaXQgZmFpbGVkOlwiK3Z9aWYoeS5pc1ByaXZhdGU9PT10cnVlKXt0aGlzLnBydktleT15O3RoaXMuc3RhdGU9XCJTSUdOXCJ9ZWxzZXtpZih5LmlzUHVibGljPT09dHJ1ZSl7dGhpcy5wdWJLZXk9eTt0aGlzLnN0YXRlPVwiVkVSSUZZXCJ9ZWxzZXt0aHJvd1wiaW5pdCBmYWlsZWQuOlwiK3l9fX07dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24odil7dGhpcy5tZC51cGRhdGVTdHJpbmcodil9O3RoaXMudXBkYXRlSGV4PWZ1bmN0aW9uKHYpe3RoaXMubWQudXBkYXRlSGV4KHYpfTt0aGlzLnNpZ249ZnVuY3Rpb24oKXt0aGlzLnNIYXNoSGV4PXRoaXMubWQuZGlnZXN0KCk7aWYodHlwZW9mIHRoaXMuZWNwcnZoZXghPVwidW5kZWZpbmVkXCImJnR5cGVvZiB0aGlzLmVjY3VydmVuYW1lIT1cInVuZGVmaW5lZFwiKXt2YXIgdj1uZXcgS0pVUi5jcnlwdG8uRUNEU0Eoe2N1cnZlOnRoaXMuZWNjdXJ2ZW5hbWV9KTt0aGlzLmhTaWduPXYuc2lnbkhleCh0aGlzLnNIYXNoSGV4LHRoaXMuZWNwcnZoZXgpfWVsc2V7aWYodGhpcy5wcnZLZXkgaW5zdGFuY2VvZiBSU0FLZXkmJnRoaXMucHVia2V5QWxnTmFtZT09PVwicnNhYW5kbWdmMVwiKXt0aGlzLmhTaWduPXRoaXMucHJ2S2V5LnNpZ25XaXRoTWVzc2FnZUhhc2hQU1ModGhpcy5zSGFzaEhleCx0aGlzLm1kQWxnTmFtZSx0aGlzLnBzc1NhbHRMZW4pfWVsc2V7aWYodGhpcy5wcnZLZXkgaW5zdGFuY2VvZiBSU0FLZXkmJnRoaXMucHVia2V5QWxnTmFtZT09PVwicnNhXCIpe3RoaXMuaFNpZ249dGhpcy5wcnZLZXkuc2lnbldpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4LHRoaXMubWRBbGdOYW1lKX1lbHNle2lmKHRoaXMucHJ2S2V5IGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRUNEU0Epe3RoaXMuaFNpZ249dGhpcy5wcnZLZXkuc2lnbldpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4KX1lbHNle2lmKHRoaXMucHJ2S2V5IGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRFNBKXt0aGlzLmhTaWduPXRoaXMucHJ2S2V5LnNpZ25XaXRoTWVzc2FnZUhhc2godGhpcy5zSGFzaEhleCl9ZWxzZXt0aHJvd1wiU2lnbmF0dXJlOiB1bnN1cHBvcnRlZCBwcml2YXRlIGtleSBhbGc6IFwiK3RoaXMucHVia2V5QWxnTmFtZX19fX19cmV0dXJuIHRoaXMuaFNpZ259O3RoaXMuc2lnblN0cmluZz1mdW5jdGlvbih2KXt0aGlzLnVwZGF0ZVN0cmluZyh2KTtyZXR1cm4gdGhpcy5zaWduKCl9O3RoaXMuc2lnbkhleD1mdW5jdGlvbih2KXt0aGlzLnVwZGF0ZUhleCh2KTtyZXR1cm4gdGhpcy5zaWduKCl9O3RoaXMudmVyaWZ5PWZ1bmN0aW9uKHYpe3RoaXMuc0hhc2hIZXg9dGhpcy5tZC5kaWdlc3QoKTtpZih0eXBlb2YgdGhpcy5lY3B1YmhleCE9XCJ1bmRlZmluZWRcIiYmdHlwZW9mIHRoaXMuZWNjdXJ2ZW5hbWUhPVwidW5kZWZpbmVkXCIpe3ZhciB3PW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6dGhpcy5lY2N1cnZlbmFtZX0pO3JldHVybiB3LnZlcmlmeUhleCh0aGlzLnNIYXNoSGV4LHYsdGhpcy5lY3B1YmhleCl9ZWxzZXtpZih0aGlzLnB1YktleSBpbnN0YW5jZW9mIFJTQUtleSYmdGhpcy5wdWJrZXlBbGdOYW1lPT09XCJyc2FhbmRtZ2YxXCIpe3JldHVybiB0aGlzLnB1YktleS52ZXJpZnlXaXRoTWVzc2FnZUhhc2hQU1ModGhpcy5zSGFzaEhleCx2LHRoaXMubWRBbGdOYW1lLHRoaXMucHNzU2FsdExlbil9ZWxzZXtpZih0aGlzLnB1YktleSBpbnN0YW5jZW9mIFJTQUtleSYmdGhpcy5wdWJrZXlBbGdOYW1lPT09XCJyc2FcIil7cmV0dXJuIHRoaXMucHViS2V5LnZlcmlmeVdpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4LHYpfWVsc2V7aWYoS0pVUi5jcnlwdG8uRUNEU0EhPT11bmRlZmluZWQmJnRoaXMucHViS2V5IGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRUNEU0Epe3JldHVybiB0aGlzLnB1YktleS52ZXJpZnlXaXRoTWVzc2FnZUhhc2godGhpcy5zSGFzaEhleCx2KX1lbHNle2lmKEtKVVIuY3J5cHRvLkRTQSE9PXVuZGVmaW5lZCYmdGhpcy5wdWJLZXkgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5EU0Epe3JldHVybiB0aGlzLnB1YktleS52ZXJpZnlXaXRoTWVzc2FnZUhhc2godGhpcy5zSGFzaEhleCx2KX1lbHNle3Rocm93XCJTaWduYXR1cmU6IHVuc3VwcG9ydGVkIHB1YmxpYyBrZXkgYWxnOiBcIit0aGlzLnB1YmtleUFsZ05hbWV9fX19fX19fTt0aGlzLmluaXQ9ZnVuY3Rpb24ocyx0KXt0aHJvd1wiaW5pdChrZXksIHBhc3MpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24ocyl7dGhyb3dcInVwZGF0ZVN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy51cGRhdGVIZXg9ZnVuY3Rpb24ocyl7dGhyb3dcInVwZGF0ZUhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy5zaWduPWZ1bmN0aW9uKCl7dGhyb3dcInNpZ24oKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMuYWxnUHJvdk5hbWV9O3RoaXMuc2lnblN0cmluZz1mdW5jdGlvbihzKXt0aHJvd1wiZGlnZXN0U3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnNpZ25IZXg9ZnVuY3Rpb24ocyl7dGhyb3dcImRpZ2VzdEhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy52ZXJpZnk9ZnVuY3Rpb24ocyl7dGhyb3dcInZlcmlmeShoU2lnVmFsKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMuYWxnUHJvdk5hbWV9O3RoaXMuaW5pdFBhcmFtcz1vO2lmKG8hPT11bmRlZmluZWQpe2lmKG8uYWxnIT09dW5kZWZpbmVkKXt0aGlzLmFsZ05hbWU9by5hbGc7aWYoby5wcm92PT09dW5kZWZpbmVkKXt0aGlzLnByb3ZOYW1lPUtKVVIuY3J5cHRvLlV0aWwuREVGQVVMVFBST1ZJREVSW3RoaXMuYWxnTmFtZV19ZWxzZXt0aGlzLnByb3ZOYW1lPW8ucHJvdn10aGlzLmFsZ1Byb3ZOYW1lPXRoaXMuYWxnTmFtZStcIjpcIit0aGlzLnByb3ZOYW1lO3RoaXMuc2V0QWxnQW5kUHJvdmlkZXIodGhpcy5hbGdOYW1lLHRoaXMucHJvdk5hbWUpO3RoaXMuX3NldEFsZ05hbWVzKCl9aWYoby5wc3NzYWx0bGVuIT09dW5kZWZpbmVkKXt0aGlzLnBzc1NhbHRMZW49by5wc3NzYWx0bGVufWlmKG8ucHJ2a2V5cGVtIT09dW5kZWZpbmVkKXtpZihvLnBydmtleXBhcyE9PXVuZGVmaW5lZCl7dGhyb3dcImJvdGggcHJ2a2V5cGVtIGFuZCBwcnZrZXlwYXMgcGFyYW1ldGVycyBub3Qgc3VwcG9ydGVkXCJ9ZWxzZXt0cnl7dmFyIHE9S0VZVVRJTC5nZXRLZXkoby5wcnZrZXlwZW0pO3RoaXMuaW5pdChxKX1jYXRjaChtKXt0aHJvd1wiZmF0YWwgZXJyb3IgdG8gbG9hZCBwZW0gcHJpdmF0ZSBrZXk6IFwiK219fX19fTtLSlVSLmNyeXB0by5DaXBoZXI9ZnVuY3Rpb24oYSl7fTtLSlVSLmNyeXB0by5DaXBoZXIuZW5jcnlwdD1mdW5jdGlvbihlLGYsZCl7aWYoZiBpbnN0YW5jZW9mIFJTQUtleSYmZi5pc1B1YmxpYyl7dmFyIGM9S0pVUi5jcnlwdG8uQ2lwaGVyLmdldEFsZ0J5S2V5QW5kTmFtZShmLGQpO2lmKGM9PT1cIlJTQVwiKXtyZXR1cm4gZi5lbmNyeXB0KGUpfWlmKGM9PT1cIlJTQU9BRVBcIil7cmV0dXJuIGYuZW5jcnlwdE9BRVAoZSxcInNoYTFcIil9dmFyIGI9Yy5tYXRjaCgvXlJTQU9BRVAoXFxkKykkLyk7aWYoYiE9PW51bGwpe3JldHVybiBmLmVuY3J5cHRPQUVQKGUsXCJzaGFcIitiWzFdKX10aHJvd1wiQ2lwaGVyLmVuY3J5cHQ6IHVuc3VwcG9ydGVkIGFsZ29yaXRobSBmb3IgUlNBS2V5OiBcIitkfWVsc2V7dGhyb3dcIkNpcGhlci5lbmNyeXB0OiB1bnN1cHBvcnRlZCBrZXkgb3IgYWxnb3JpdGhtXCJ9fTtLSlVSLmNyeXB0by5DaXBoZXIuZGVjcnlwdD1mdW5jdGlvbihlLGYsZCl7aWYoZiBpbnN0YW5jZW9mIFJTQUtleSYmZi5pc1ByaXZhdGUpe3ZhciBjPUtKVVIuY3J5cHRvLkNpcGhlci5nZXRBbGdCeUtleUFuZE5hbWUoZixkKTtpZihjPT09XCJSU0FcIil7cmV0dXJuIGYuZGVjcnlwdChlKX1pZihjPT09XCJSU0FPQUVQXCIpe3JldHVybiBmLmRlY3J5cHRPQUVQKGUsXCJzaGExXCIpfXZhciBiPWMubWF0Y2goL15SU0FPQUVQKFxcZCspJC8pO2lmKGIhPT1udWxsKXtyZXR1cm4gZi5kZWNyeXB0T0FFUChlLFwic2hhXCIrYlsxXSl9dGhyb3dcIkNpcGhlci5kZWNyeXB0OiB1bnN1cHBvcnRlZCBhbGdvcml0aG0gZm9yIFJTQUtleTogXCIrZH1lbHNle3Rocm93XCJDaXBoZXIuZGVjcnlwdDogdW5zdXBwb3J0ZWQga2V5IG9yIGFsZ29yaXRobVwifX07S0pVUi5jcnlwdG8uQ2lwaGVyLmdldEFsZ0J5S2V5QW5kTmFtZT1mdW5jdGlvbihiLGEpe2lmKGIgaW5zdGFuY2VvZiBSU0FLZXkpe2lmKFwiOlJTQTpSU0FPQUVQOlJTQU9BRVAyMjQ6UlNBT0FFUDI1NjpSU0FPQUVQMzg0OlJTQU9BRVA1MTI6XCIuaW5kZXhPZihhKSE9LTEpe3JldHVybiBhfWlmKGE9PT1udWxsfHxhPT09dW5kZWZpbmVkKXtyZXR1cm5cIlJTQVwifXRocm93XCJnZXRBbGdCeUtleUFuZE5hbWU6IG5vdCBzdXBwb3J0ZWQgYWxnb3JpdGhtIG5hbWUgZm9yIFJTQUtleTogXCIrYX10aHJvd1wiZ2V0QWxnQnlLZXlBbmROYW1lOiBub3Qgc3VwcG9ydGVkIGFsZ29yaXRobSBuYW1lOiBcIithfTtLSlVSLmNyeXB0by5PSUQ9bmV3IGZ1bmN0aW9uKCl7dGhpcy5vaWRoZXgybmFtZT17XCIyYTg2NDg4NmY3MGQwMTAxMDFcIjpcInJzYUVuY3J5cHRpb25cIixcIjJhODY0OGNlM2QwMjAxXCI6XCJlY1B1YmxpY0tleVwiLFwiMmE4NjQ4Y2UzODA0MDFcIjpcImRzYVwiLFwiMmE4NjQ4Y2UzZDAzMDEwN1wiOlwic2VjcDI1NnIxXCIsXCIyYjgxMDQwMDFmXCI6XCJzZWNwMTkyazFcIixcIjJiODEwNDAwMjFcIjpcInNlY3AyMjRyMVwiLFwiMmI4MTA0MDAwYVwiOlwic2VjcDI1NmsxXCIsXCIyYjgxMDQwMDIzXCI6XCJzZWNwNTIxcjFcIixcIjJiODEwNDAwMjJcIjpcInNlY3AzODRyMVwiLFwiMmE4NjQ4Y2UzODA0MDNcIjpcIlNIQTF3aXRoRFNBXCIsXCI2MDg2NDgwMTY1MDMwNDAzMDFcIjpcIlNIQTIyNHdpdGhEU0FcIixcIjYwODY0ODAxNjUwMzA0MDMwMlwiOlwiU0hBMjU2d2l0aERTQVwiLH19O1xuaWYodHlwZW9mIEtKVVI9PVwidW5kZWZpbmVkXCJ8fCFLSlVSKXtLSlVSPXt9fWlmKHR5cGVvZiBLSlVSLmNyeXB0bz09XCJ1bmRlZmluZWRcInx8IUtKVVIuY3J5cHRvKXtLSlVSLmNyeXB0bz17fX1LSlVSLmNyeXB0by5FQ0RTQT1mdW5jdGlvbihoKXt2YXIgZT1cInNlY3AyNTZyMVwiO3ZhciBnPW51bGw7dmFyIGI9bnVsbDt2YXIgZj1udWxsO3ZhciBhPW5ldyBTZWN1cmVSYW5kb20oKTt2YXIgZD1udWxsO3RoaXMudHlwZT1cIkVDXCI7dGhpcy5pc1ByaXZhdGU9ZmFsc2U7dGhpcy5pc1B1YmxpYz1mYWxzZTtmdW5jdGlvbiBjKHMsbyxyLG4pe3ZhciBqPU1hdGgubWF4KG8uYml0TGVuZ3RoKCksbi5iaXRMZW5ndGgoKSk7dmFyIHQ9cy5hZGQyRChyKTt2YXIgcT1zLmN1cnZlLmdldEluZmluaXR5KCk7Zm9yKHZhciBwPWotMTtwPj0wOy0tcCl7cT1xLnR3aWNlMkQoKTtxLno9QmlnSW50ZWdlci5PTkU7aWYoby50ZXN0Qml0KHApKXtpZihuLnRlc3RCaXQocCkpe3E9cS5hZGQyRCh0KX1lbHNle3E9cS5hZGQyRChzKX19ZWxzZXtpZihuLnRlc3RCaXQocCkpe3E9cS5hZGQyRChyKX19fXJldHVybiBxfXRoaXMuZ2V0QmlnUmFuZG9tPWZ1bmN0aW9uKGkpe3JldHVybiBuZXcgQmlnSW50ZWdlcihpLmJpdExlbmd0aCgpLGEpLm1vZChpLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSkuYWRkKEJpZ0ludGVnZXIuT05FKX07dGhpcy5zZXROYW1lZEN1cnZlPWZ1bmN0aW9uKGkpe3RoaXMuZWNwYXJhbXM9S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5nZXRCeU5hbWUoaSk7dGhpcy5wcnZLZXlIZXg9bnVsbDt0aGlzLnB1YktleUhleD1udWxsO3RoaXMuY3VydmVOYW1lPWl9O3RoaXMuc2V0UHJpdmF0ZUtleUhleD1mdW5jdGlvbihpKXt0aGlzLmlzUHJpdmF0ZT10cnVlO3RoaXMucHJ2S2V5SGV4PWl9O3RoaXMuc2V0UHVibGljS2V5SGV4PWZ1bmN0aW9uKGkpe3RoaXMuaXNQdWJsaWM9dHJ1ZTt0aGlzLnB1YktleUhleD1pfTt0aGlzLmdldFB1YmxpY0tleVhZSGV4PWZ1bmN0aW9uKCl7dmFyIGs9dGhpcy5wdWJLZXlIZXg7aWYoay5zdWJzdHIoMCwyKSE9PVwiMDRcIil7dGhyb3dcInRoaXMgbWV0aG9kIHN1cHBvcnRzIHVuY29tcHJlc3NlZCBmb3JtYXQoMDQpIG9ubHlcIn12YXIgaj10aGlzLmVjcGFyYW1zLmtleWxlbi80O2lmKGsubGVuZ3RoIT09MitqKjIpe3Rocm93XCJtYWxmb3JtZWQgcHVibGljIGtleSBoZXggbGVuZ3RoXCJ9dmFyIGk9e307aS54PWsuc3Vic3RyKDIsaik7aS55PWsuc3Vic3RyKDIraik7cmV0dXJuIGl9O3RoaXMuZ2V0U2hvcnROSVNUUEN1cnZlTmFtZT1mdW5jdGlvbigpe3ZhciBpPXRoaXMuY3VydmVOYW1lO2lmKGk9PT1cInNlY3AyNTZyMVwifHxpPT09XCJOSVNUIFAtMjU2XCJ8fGk9PT1cIlAtMjU2XCJ8fGk9PT1cInByaW1lMjU2djFcIil7cmV0dXJuXCJQLTI1NlwifWlmKGk9PT1cInNlY3AzODRyMVwifHxpPT09XCJOSVNUIFAtMzg0XCJ8fGk9PT1cIlAtMzg0XCIpe3JldHVyblwiUC0zODRcIn1yZXR1cm4gbnVsbH07dGhpcy5nZW5lcmF0ZUtleVBhaXJIZXg9ZnVuY3Rpb24oKXt2YXIgaz10aGlzLmVjcGFyYW1zLm47dmFyIG49dGhpcy5nZXRCaWdSYW5kb20oayk7dmFyIGw9dGhpcy5lY3BhcmFtcy5HLm11bHRpcGx5KG4pO3ZhciBxPWwuZ2V0WCgpLnRvQmlnSW50ZWdlcigpO3ZhciBvPWwuZ2V0WSgpLnRvQmlnSW50ZWdlcigpO3ZhciBpPXRoaXMuZWNwYXJhbXMua2V5bGVuLzQ7dmFyIG09KFwiMDAwMDAwMDAwMFwiK24udG9TdHJpbmcoMTYpKS5zbGljZSgtaSk7dmFyIHI9KFwiMDAwMDAwMDAwMFwiK3EudG9TdHJpbmcoMTYpKS5zbGljZSgtaSk7dmFyIHA9KFwiMDAwMDAwMDAwMFwiK28udG9TdHJpbmcoMTYpKS5zbGljZSgtaSk7dmFyIGo9XCIwNFwiK3IrcDt0aGlzLnNldFByaXZhdGVLZXlIZXgobSk7dGhpcy5zZXRQdWJsaWNLZXlIZXgoaik7cmV0dXJue2VjcHJ2aGV4Om0sZWNwdWJoZXg6an19O3RoaXMuc2lnbldpdGhNZXNzYWdlSGFzaD1mdW5jdGlvbihpKXtyZXR1cm4gdGhpcy5zaWduSGV4KGksdGhpcy5wcnZLZXlIZXgpfTt0aGlzLnNpZ25IZXg9ZnVuY3Rpb24obyxqKXt2YXIgdD1uZXcgQmlnSW50ZWdlcihqLDE2KTt2YXIgbD10aGlzLmVjcGFyYW1zLm47dmFyIHE9bmV3IEJpZ0ludGVnZXIobywxNik7ZG97dmFyIG09dGhpcy5nZXRCaWdSYW5kb20obCk7dmFyIHU9dGhpcy5lY3BhcmFtcy5HO3ZhciBwPXUubXVsdGlwbHkobSk7dmFyIGk9cC5nZXRYKCkudG9CaWdJbnRlZ2VyKCkubW9kKGwpfXdoaWxlKGkuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTyk8PTApO3ZhciB2PW0ubW9kSW52ZXJzZShsKS5tdWx0aXBseShxLmFkZCh0Lm11bHRpcGx5KGkpKSkubW9kKGwpO3JldHVybiBLSlVSLmNyeXB0by5FQ0RTQS5iaVJTU2lnVG9BU04xU2lnKGksdil9O3RoaXMuc2lnbj1mdW5jdGlvbihtLHUpe3ZhciBxPXU7dmFyIGo9dGhpcy5lY3BhcmFtcy5uO3ZhciBwPUJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkKG0pO2Rve3ZhciBsPXRoaXMuZ2V0QmlnUmFuZG9tKGopO3ZhciB0PXRoaXMuZWNwYXJhbXMuRzt2YXIgbz10Lm11bHRpcGx5KGwpO3ZhciBpPW8uZ2V0WCgpLnRvQmlnSW50ZWdlcigpLm1vZChqKX13aGlsZShpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pPD0wKTt2YXIgdj1sLm1vZEludmVyc2UoaikubXVsdGlwbHkocC5hZGQocS5tdWx0aXBseShpKSkpLm1vZChqKTtyZXR1cm4gdGhpcy5zZXJpYWxpemVTaWcoaSx2KX07dGhpcy52ZXJpZnlXaXRoTWVzc2FnZUhhc2g9ZnVuY3Rpb24oaixpKXtyZXR1cm4gdGhpcy52ZXJpZnlIZXgoaixpLHRoaXMucHViS2V5SGV4KX07dGhpcy52ZXJpZnlIZXg9ZnVuY3Rpb24obSxpLHApe3ZhciBsLGo7dmFyIG89S0pVUi5jcnlwdG8uRUNEU0EucGFyc2VTaWdIZXgoaSk7bD1vLnI7aj1vLnM7dmFyIGs7az1FQ1BvaW50RnAuZGVjb2RlRnJvbUhleCh0aGlzLmVjcGFyYW1zLmN1cnZlLHApO3ZhciBuPW5ldyBCaWdJbnRlZ2VyKG0sMTYpO3JldHVybiB0aGlzLnZlcmlmeVJhdyhuLGwsaixrKX07dGhpcy52ZXJpZnk9ZnVuY3Rpb24obyxwLGope3ZhciBsLGk7aWYoQml0Y29pbi5VdGlsLmlzQXJyYXkocCkpe3ZhciBuPXRoaXMucGFyc2VTaWcocCk7bD1uLnI7aT1uLnN9ZWxzZXtpZihcIm9iamVjdFwiPT09dHlwZW9mIHAmJnAuciYmcC5zKXtsPXAucjtpPXAuc31lbHNle3Rocm93XCJJbnZhbGlkIHZhbHVlIGZvciBzaWduYXR1cmVcIn19dmFyIGs7aWYoaiBpbnN0YW5jZW9mIEVDUG9pbnRGcCl7az1qfWVsc2V7aWYoQml0Y29pbi5VdGlsLmlzQXJyYXkoaikpe2s9RUNQb2ludEZwLmRlY29kZUZyb20odGhpcy5lY3BhcmFtcy5jdXJ2ZSxqKX1lbHNle3Rocm93XCJJbnZhbGlkIGZvcm1hdCBmb3IgcHVia2V5IHZhbHVlLCBtdXN0IGJlIGJ5dGUgYXJyYXkgb3IgRUNQb2ludEZwXCJ9fXZhciBtPUJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkKG8pO3JldHVybiB0aGlzLnZlcmlmeVJhdyhtLGwsaSxrKX07dGhpcy52ZXJpZnlSYXc9ZnVuY3Rpb24obyxpLHcsbSl7dmFyIGw9dGhpcy5lY3BhcmFtcy5uO3ZhciB1PXRoaXMuZWNwYXJhbXMuRztpZihpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSk8MHx8aS5jb21wYXJlVG8obCk+PTApe3JldHVybiBmYWxzZX1pZih3LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSk8MHx8dy5jb21wYXJlVG8obCk+PTApe3JldHVybiBmYWxzZX12YXIgcD13Lm1vZEludmVyc2UobCk7dmFyIGs9by5tdWx0aXBseShwKS5tb2QobCk7dmFyIGo9aS5tdWx0aXBseShwKS5tb2QobCk7dmFyIHE9dS5tdWx0aXBseShrKS5hZGQobS5tdWx0aXBseShqKSk7dmFyIHQ9cS5nZXRYKCkudG9CaWdJbnRlZ2VyKCkubW9kKGwpO3JldHVybiB0LmVxdWFscyhpKX07dGhpcy5zZXJpYWxpemVTaWc9ZnVuY3Rpb24oayxqKXt2YXIgbD1rLnRvQnl0ZUFycmF5U2lnbmVkKCk7dmFyIGk9ai50b0J5dGVBcnJheVNpZ25lZCgpO3ZhciBtPVtdO20ucHVzaCgyKTttLnB1c2gobC5sZW5ndGgpO209bS5jb25jYXQobCk7bS5wdXNoKDIpO20ucHVzaChpLmxlbmd0aCk7bT1tLmNvbmNhdChpKTttLnVuc2hpZnQobS5sZW5ndGgpO20udW5zaGlmdCg0OCk7cmV0dXJuIG19O3RoaXMucGFyc2VTaWc9ZnVuY3Rpb24obil7dmFyIG07aWYoblswXSE9NDgpe3Rocm93IG5ldyBFcnJvcihcIlNpZ25hdHVyZSBub3QgYSB2YWxpZCBERVJTZXF1ZW5jZVwiKX1tPTI7aWYoblttXSE9Mil7dGhyb3cgbmV3IEVycm9yKFwiRmlyc3QgZWxlbWVudCBpbiBzaWduYXR1cmUgbXVzdCBiZSBhIERFUkludGVnZXJcIil9dmFyIGw9bi5zbGljZShtKzIsbSsyK25bbSsxXSk7bSs9MituW20rMV07aWYoblttXSE9Mil7dGhyb3cgbmV3IEVycm9yKFwiU2Vjb25kIGVsZW1lbnQgaW4gc2lnbmF0dXJlIG11c3QgYmUgYSBERVJJbnRlZ2VyXCIpfXZhciBpPW4uc2xpY2UobSsyLG0rMituW20rMV0pO20rPTIrblttKzFdO3ZhciBrPUJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkKGwpO3ZhciBqPUJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkKGkpO3JldHVybntyOmssczpqfX07dGhpcy5wYXJzZVNpZ0NvbXBhY3Q9ZnVuY3Rpb24obSl7aWYobS5sZW5ndGghPT02NSl7dGhyb3dcIlNpZ25hdHVyZSBoYXMgdGhlIHdyb25nIGxlbmd0aFwifXZhciBqPW1bMF0tMjc7aWYoajwwfHxqPjcpe3Rocm93XCJJbnZhbGlkIHNpZ25hdHVyZSB0eXBlXCJ9dmFyIG89dGhpcy5lY3BhcmFtcy5uO3ZhciBsPUJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkKG0uc2xpY2UoMSwzMykpLm1vZChvKTt2YXIgaz1CaWdJbnRlZ2VyLmZyb21CeXRlQXJyYXlVbnNpZ25lZChtLnNsaWNlKDMzLDY1KSkubW9kKG8pO3JldHVybntyOmwsczprLGk6an19O3RoaXMucmVhZFBLQ1M1UHJ2S2V5SGV4PWZ1bmN0aW9uKGwpe3ZhciBuPUFTTjFIRVg7dmFyIG09S0pVUi5jcnlwdG8uRUNEU0EuZ2V0TmFtZTt2YXIgcD1uLmdldFZieUxpc3Q7aWYobi5pc0FTTjFIRVgobCk9PT1mYWxzZSl7dGhyb3dcIm5vdCBBU04uMSBoZXggc3RyaW5nXCJ9dmFyIGksayxvO3RyeXtpPXAobCwwLFsyLDBdLFwiMDZcIik7az1wKGwsMCxbMV0sXCIwNFwiKTt0cnl7bz1wKGwsMCxbMywwXSxcIjAzXCIpLnN1YnN0cigyKX1jYXRjaChqKXt9fWNhdGNoKGope3Rocm93XCJtYWxmb3JtZWQgUEtDUyMxLzUgcGxhaW4gRUNDIHByaXZhdGUga2V5XCJ9dGhpcy5jdXJ2ZU5hbWU9bShpKTtpZih0aGlzLmN1cnZlTmFtZT09PXVuZGVmaW5lZCl7dGhyb3dcInVuc3VwcG9ydGVkIGN1cnZlIG5hbWVcIn10aGlzLnNldE5hbWVkQ3VydmUodGhpcy5jdXJ2ZU5hbWUpO3RoaXMuc2V0UHVibGljS2V5SGV4KG8pO3RoaXMuc2V0UHJpdmF0ZUtleUhleChrKTt0aGlzLmlzUHVibGljPWZhbHNlfTt0aGlzLnJlYWRQS0NTOFBydktleUhleD1mdW5jdGlvbihsKXt2YXIgcT1BU04xSEVYO3ZhciBpPUtKVVIuY3J5cHRvLkVDRFNBLmdldE5hbWU7dmFyIG49cS5nZXRWYnlMaXN0O2lmKHEuaXNBU04xSEVYKGwpPT09ZmFsc2Upe3Rocm93XCJub3QgQVNOLjEgaGV4IHN0cmluZ1wifXZhciBqLHAsbSxrO3RyeXtqPW4obCwwLFsxLDBdLFwiMDZcIik7cD1uKGwsMCxbMSwxXSxcIjA2XCIpO209bihsLDAsWzIsMCwxXSxcIjA0XCIpO3RyeXtrPW4obCwwLFsyLDAsMiwwXSxcIjAzXCIpLnN1YnN0cigyKX1jYXRjaChvKXt9fWNhdGNoKG8pe3Rocm93XCJtYWxmb3JtZWQgUEtDUyM4IHBsYWluIEVDQyBwcml2YXRlIGtleVwifXRoaXMuY3VydmVOYW1lPWkocCk7aWYodGhpcy5jdXJ2ZU5hbWU9PT11bmRlZmluZWQpe3Rocm93XCJ1bnN1cHBvcnRlZCBjdXJ2ZSBuYW1lXCJ9dGhpcy5zZXROYW1lZEN1cnZlKHRoaXMuY3VydmVOYW1lKTt0aGlzLnNldFB1YmxpY0tleUhleChrKTt0aGlzLnNldFByaXZhdGVLZXlIZXgobSk7dGhpcy5pc1B1YmxpYz1mYWxzZX07dGhpcy5yZWFkUEtDUzhQdWJLZXlIZXg9ZnVuY3Rpb24obCl7dmFyIG49QVNOMUhFWDt2YXIgbT1LSlVSLmNyeXB0by5FQ0RTQS5nZXROYW1lO3ZhciBwPW4uZ2V0VmJ5TGlzdDtpZihuLmlzQVNOMUhFWChsKT09PWZhbHNlKXt0aHJvd1wibm90IEFTTi4xIGhleCBzdHJpbmdcIn12YXIgayxpLG87dHJ5e2s9cChsLDAsWzAsMF0sXCIwNlwiKTtpPXAobCwwLFswLDFdLFwiMDZcIik7bz1wKGwsMCxbMV0sXCIwM1wiKS5zdWJzdHIoMil9Y2F0Y2goail7dGhyb3dcIm1hbGZvcm1lZCBQS0NTIzggRUNDIHB1YmxpYyBrZXlcIn10aGlzLmN1cnZlTmFtZT1tKGkpO2lmKHRoaXMuY3VydmVOYW1lPT09bnVsbCl7dGhyb3dcInVuc3VwcG9ydGVkIGN1cnZlIG5hbWVcIn10aGlzLnNldE5hbWVkQ3VydmUodGhpcy5jdXJ2ZU5hbWUpO3RoaXMuc2V0UHVibGljS2V5SGV4KG8pfTt0aGlzLnJlYWRDZXJ0UHViS2V5SGV4PWZ1bmN0aW9uKGsscCl7aWYocCE9PTUpe3A9Nn12YXIgbT1BU04xSEVYO3ZhciBsPUtKVVIuY3J5cHRvLkVDRFNBLmdldE5hbWU7dmFyIG89bS5nZXRWYnlMaXN0O2lmKG0uaXNBU04xSEVYKGspPT09ZmFsc2Upe3Rocm93XCJub3QgQVNOLjEgaGV4IHN0cmluZ1wifXZhciBpLG47dHJ5e2k9byhrLDAsWzAscCwwLDFdLFwiMDZcIik7bj1vKGssMCxbMCxwLDFdLFwiMDNcIikuc3Vic3RyKDIpfWNhdGNoKGope3Rocm93XCJtYWxmb3JtZWQgWC41MDkgY2VydGlmaWNhdGUgRUNDIHB1YmxpYyBrZXlcIn10aGlzLmN1cnZlTmFtZT1sKGkpO2lmKHRoaXMuY3VydmVOYW1lPT09bnVsbCl7dGhyb3dcInVuc3VwcG9ydGVkIGN1cnZlIG5hbWVcIn10aGlzLnNldE5hbWVkQ3VydmUodGhpcy5jdXJ2ZU5hbWUpO3RoaXMuc2V0UHVibGljS2V5SGV4KG4pfTtpZihoIT09dW5kZWZpbmVkKXtpZihoLmN1cnZlIT09dW5kZWZpbmVkKXt0aGlzLmN1cnZlTmFtZT1oLmN1cnZlfX1pZih0aGlzLmN1cnZlTmFtZT09PXVuZGVmaW5lZCl7dGhpcy5jdXJ2ZU5hbWU9ZX10aGlzLnNldE5hbWVkQ3VydmUodGhpcy5jdXJ2ZU5hbWUpO2lmKGghPT11bmRlZmluZWQpe2lmKGgucHJ2IT09dW5kZWZpbmVkKXt0aGlzLnNldFByaXZhdGVLZXlIZXgoaC5wcnYpfWlmKGgucHViIT09dW5kZWZpbmVkKXt0aGlzLnNldFB1YmxpY0tleUhleChoLnB1Yil9fX07S0pVUi5jcnlwdG8uRUNEU0EucGFyc2VTaWdIZXg9ZnVuY3Rpb24oYSl7dmFyIGI9S0pVUi5jcnlwdG8uRUNEU0EucGFyc2VTaWdIZXhJbkhleFJTKGEpO3ZhciBkPW5ldyBCaWdJbnRlZ2VyKGIuciwxNik7dmFyIGM9bmV3IEJpZ0ludGVnZXIoYi5zLDE2KTtyZXR1cm57cjpkLHM6Y319O0tKVVIuY3J5cHRvLkVDRFNBLnBhcnNlU2lnSGV4SW5IZXhSUz1mdW5jdGlvbihmKXt2YXIgaj1BU04xSEVYO3ZhciBpPWouZ2V0Q2hpbGRJZHg7dmFyIGc9ai5nZXRWO2lmKGYuc3Vic3RyKDAsMikhPVwiMzBcIil7dGhyb3dcInNpZ25hdHVyZSBpcyBub3QgYSBBU04uMSBzZXF1ZW5jZVwifXZhciBoPWkoZiwwKTtpZihoLmxlbmd0aCE9Mil7dGhyb3dcIm51bWJlciBvZiBzaWduYXR1cmUgQVNOLjEgc2VxdWVuY2UgZWxlbWVudHMgc2VlbSB3cm9uZ1wifXZhciBlPWhbMF07dmFyIGQ9aFsxXTtpZihmLnN1YnN0cihlLDIpIT1cIjAyXCIpe3Rocm93XCIxc3QgaXRlbSBvZiBzZXF1ZW5lIG9mIHNpZ25hdHVyZSBpcyBub3QgQVNOLjEgaW50ZWdlclwifWlmKGYuc3Vic3RyKGQsMikhPVwiMDJcIil7dGhyb3dcIjJuZCBpdGVtIG9mIHNlcXVlbmUgb2Ygc2lnbmF0dXJlIGlzIG5vdCBBU04uMSBpbnRlZ2VyXCJ9dmFyIGM9ZyhmLGUpO3ZhciBiPWcoZixkKTtyZXR1cm57cjpjLHM6Yn19O0tKVVIuY3J5cHRvLkVDRFNBLmFzbjFTaWdUb0NvbmNhdFNpZz1mdW5jdGlvbihjKXt2YXIgZD1LSlVSLmNyeXB0by5FQ0RTQS5wYXJzZVNpZ0hleEluSGV4UlMoYyk7dmFyIGI9ZC5yO3ZhciBhPWQucztpZihiLnN1YnN0cigwLDIpPT1cIjAwXCImJihiLmxlbmd0aCUzMik9PTIpe2I9Yi5zdWJzdHIoMil9aWYoYS5zdWJzdHIoMCwyKT09XCIwMFwiJiYoYS5sZW5ndGglMzIpPT0yKXthPWEuc3Vic3RyKDIpfWlmKChiLmxlbmd0aCUzMik9PTMwKXtiPVwiMDBcIitifWlmKChhLmxlbmd0aCUzMik9PTMwKXthPVwiMDBcIithfWlmKGIubGVuZ3RoJTMyIT0wKXt0aHJvd1widW5rbm93biBFQ0RTQSBzaWcgciBsZW5ndGggZXJyb3JcIn1pZihhLmxlbmd0aCUzMiE9MCl7dGhyb3dcInVua25vd24gRUNEU0Egc2lnIHMgbGVuZ3RoIGVycm9yXCJ9cmV0dXJuIGIrYX07S0pVUi5jcnlwdG8uRUNEU0EuY29uY2F0U2lnVG9BU04xU2lnPWZ1bmN0aW9uKGEpe2lmKCgoKGEubGVuZ3RoLzIpKjgpJSgxNio4KSkhPTApe3Rocm93XCJ1bmtub3duIEVDRFNBIGNvbmNhdGluYXRlZCByLXMgc2lnICBsZW5ndGggZXJyb3JcIn12YXIgYz1hLnN1YnN0cigwLGEubGVuZ3RoLzIpO3ZhciBiPWEuc3Vic3RyKGEubGVuZ3RoLzIpO3JldHVybiBLSlVSLmNyeXB0by5FQ0RTQS5oZXhSU1NpZ1RvQVNOMVNpZyhjLGIpfTtLSlVSLmNyeXB0by5FQ0RTQS5oZXhSU1NpZ1RvQVNOMVNpZz1mdW5jdGlvbihiLGEpe3ZhciBkPW5ldyBCaWdJbnRlZ2VyKGIsMTYpO3ZhciBjPW5ldyBCaWdJbnRlZ2VyKGEsMTYpO3JldHVybiBLSlVSLmNyeXB0by5FQ0RTQS5iaVJTU2lnVG9BU04xU2lnKGQsYyl9O0tKVVIuY3J5cHRvLkVDRFNBLmJpUlNTaWdUb0FTTjFTaWc9ZnVuY3Rpb24oZixkKXt2YXIgYz1LSlVSLmFzbjE7dmFyIGI9bmV3IGMuREVSSW50ZWdlcih7YmlnaW50OmZ9KTt2YXIgYT1uZXcgYy5ERVJJbnRlZ2VyKHtiaWdpbnQ6ZH0pO3ZhciBlPW5ldyBjLkRFUlNlcXVlbmNlKHthcnJheTpbYixhXX0pO3JldHVybiBlLmdldEVuY29kZWRIZXgoKX07S0pVUi5jcnlwdG8uRUNEU0EuZ2V0TmFtZT1mdW5jdGlvbihhKXtpZihhPT09XCIyYTg2NDhjZTNkMDMwMTA3XCIpe3JldHVyblwic2VjcDI1NnIxXCJ9aWYoYT09PVwiMmI4MTA0MDAwYVwiKXtyZXR1cm5cInNlY3AyNTZrMVwifWlmKGE9PT1cIjJiODEwNDAwMjJcIil7cmV0dXJuXCJzZWNwMzg0cjFcIn1pZihcInxzZWNwMjU2cjF8TklTVCBQLTI1NnxQLTI1NnxwcmltZTI1NnYxfFwiLmluZGV4T2YoYSkhPT0tMSl7cmV0dXJuXCJzZWNwMjU2cjFcIn1pZihcInxzZWNwMjU2azF8XCIuaW5kZXhPZihhKSE9PS0xKXtyZXR1cm5cInNlY3AyNTZrMVwifWlmKFwifHNlY3AzODRyMXxOSVNUIFAtMzg0fFAtMzg0fFwiLmluZGV4T2YoYSkhPT0tMSl7cmV0dXJuXCJzZWNwMzg0cjFcIn1yZXR1cm4gbnVsbH07XG5pZih0eXBlb2YgS0pVUj09XCJ1bmRlZmluZWRcInx8IUtKVVIpe0tKVVI9e319aWYodHlwZW9mIEtKVVIuY3J5cHRvPT1cInVuZGVmaW5lZFwifHwhS0pVUi5jcnlwdG8pe0tKVVIuY3J5cHRvPXt9fUtKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREI9bmV3IGZ1bmN0aW9uKCl7dmFyIGI9e307dmFyIGM9e307ZnVuY3Rpb24gYShkKXtyZXR1cm4gbmV3IEJpZ0ludGVnZXIoZCwxNil9dGhpcy5nZXRCeU5hbWU9ZnVuY3Rpb24oZSl7dmFyIGQ9ZTtpZih0eXBlb2YgY1tkXSE9XCJ1bmRlZmluZWRcIil7ZD1jW2VdfWlmKHR5cGVvZiBiW2RdIT1cInVuZGVmaW5lZFwiKXtyZXR1cm4gYltkXX10aHJvd1widW5yZWdpc3RlcmVkIEVDIGN1cnZlIG5hbWU6IFwiK2R9O3RoaXMucmVnaXN0PWZ1bmN0aW9uKEEsbCxvLGcsbSxlLGosZixrLHUsZCx4KXtiW0FdPXt9O3ZhciBzPWEobyk7dmFyIHo9YShnKTt2YXIgeT1hKG0pO3ZhciB0PWEoZSk7dmFyIHc9YShqKTt2YXIgcj1uZXcgRUNDdXJ2ZUZwKHMseix5KTt2YXIgcT1yLmRlY29kZVBvaW50SGV4KFwiMDRcIitmK2spO2JbQV1bXCJuYW1lXCJdPUE7YltBXVtcImtleWxlblwiXT1sO2JbQV1bXCJjdXJ2ZVwiXT1yO2JbQV1bXCJHXCJdPXE7YltBXVtcIm5cIl09dDtiW0FdW1wiaFwiXT13O2JbQV1bXCJvaWRcIl09ZDtiW0FdW1wiaW5mb1wiXT14O2Zvcih2YXIgdj0wO3Y8dS5sZW5ndGg7disrKXtjW3Vbdl1dPUF9fX07S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMTI4cjFcIiwxMjgsXCJGRkZGRkZGREZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRlwiLFwiRkZGRkZGRkRGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkNcIixcIkU4NzU3OUMxMTA3OUY0M0REODI0OTkzQzJDRUU1RUQzXCIsXCJGRkZGRkZGRTAwMDAwMDAwNzVBMzBEMUI5MDM4QTExNVwiLFwiMVwiLFwiMTYxRkY3NTI4Qjg5OUIyRDBDMjg2MDdDQTUyQzVCODZcIixcIkNGNUFDODM5NUJBRkVCMTNDMDJEQTI5MkRERUQ3QTgzXCIsW10sXCJcIixcInNlY3AxMjhyMSA6IFNFQ0cgY3VydmUgb3ZlciBhIDEyOCBiaXQgcHJpbWUgZmllbGRcIik7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMTYwazFcIiwxNjAsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZBQzczXCIsXCIwXCIsXCI3XCIsXCIwMTAwMDAwMDAwMDAwMDAwMDAwMDAxQjhGQTE2REZBQjlBQ0ExNkI2QjNcIixcIjFcIixcIjNCNEMzODJDRTM3QUExOTJBNDAxOUU3NjMwMzZGNEY1REQ0RDdFQkJcIixcIjkzOENGOTM1MzE4RkRDRUQ2QkMyODI4NjUzMTczM0MzRjAzQzRGRUVcIixbXSxcIlwiLFwic2VjcDE2MGsxIDogU0VDRyBjdXJ2ZSBvdmVyIGEgMTYwIGJpdCBwcmltZSBmaWVsZFwiKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AxNjByMVwiLDE2MCxcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGN0ZGRkZGRkZcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGN0ZGRkZGRkNcIixcIjFDOTdCRUZDNTRCRDdBOEI2NUFDRjg5RjgxRDRENEFEQzU2NUZBNDVcIixcIjAxMDAwMDAwMDAwMDAwMDAwMDAwMDFGNEM4RjkyN0FFRDNDQTc1MjI1N1wiLFwiMVwiLFwiNEE5NkI1Njg4RUY1NzMyODQ2NjQ2OTg5NjhDMzhCQjkxM0NCRkM4MlwiLFwiMjNBNjI4NTUzMTY4OTQ3RDU5RENDOTEyMDQyMzUxMzc3QUM1RkIzMlwiLFtdLFwiXCIsXCJzZWNwMTYwcjEgOiBTRUNHIGN1cnZlIG92ZXIgYSAxNjAgYml0IHByaW1lIGZpZWxkXCIpO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDE5MmsxXCIsMTkyLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZFRTM3XCIsXCIwXCIsXCIzXCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkUyNkYyRkMxNzBGNjk0NjZBNzRERUZEOERcIixcIjFcIixcIkRCNEZGMTBFQzA1N0U5QUUyNkIwN0QwMjgwQjdGNDM0MURBNUQxQjFFQUUwNkM3RFwiLFwiOUIyRjJGNkQ5QzU2MjhBNzg0NDE2M0QwMTVCRTg2MzQ0MDgyQUE4OEQ5NUUyRjlEXCIsW10pO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDE5MnIxXCIsMTkyLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkVGRkZGRkZGRkZGRkZGRkZGXCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGRkZGRkZGRkNcIixcIjY0MjEwNTE5RTU5QzgwRTcwRkE3RTlBQjcyMjQzMDQ5RkVCOERFRUNDMTQ2QjlCMVwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGOTlERUY4MzYxNDZCQzlCMUI0RDIyODMxXCIsXCIxXCIsXCIxODhEQTgwRUIwMzA5MEY2N0NCRjIwRUI0M0ExODgwMEY0RkYwQUZEODJGRjEwMTJcIixcIjA3MTkyQjk1RkZDOERBNzg2MzEwMTFFRDZCMjRDREQ1NzNGOTc3QTExRTc5NDgxMVwiLFtdKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AyMjRyMVwiLDIyNCxcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxXCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRVwiLFwiQjQwNTBBODUwQzA0QjNBQkY1NDEzMjU2NTA0NEIwQjdEN0JGRDhCQTI3MEIzOTQzMjM1NUZGQjRcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkYxNkEyRTBCOEYwM0UxM0REMjk0NTVDNUMyQTNEXCIsXCIxXCIsXCJCNzBFMENCRDZCQjRCRjdGMzIxMzkwQjk0QTAzQzFEMzU2QzIxMTIyMzQzMjgwRDYxMTVDMUQyMVwiLFwiQkQzNzYzODhCNUY3MjNGQjRDMjJERkU2Q0Q0Mzc1QTA1QTA3NDc2NDQ0RDU4MTk5ODUwMDdFMzRcIixbXSk7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMjU2azFcIiwyNTYsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGQzJGXCIsXCIwXCIsXCI3XCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUJBQUVEQ0U2QUY0OEEwM0JCRkQyNUU4Q0QwMzY0MTQxXCIsXCIxXCIsXCI3OUJFNjY3RUY5RENCQkFDNTVBMDYyOTVDRTg3MEIwNzAyOUJGQ0RCMkRDRTI4RDk1OUYyODE1QjE2RjgxNzk4XCIsXCI0ODNBREE3NzI2QTNDNDY1NURBNEZCRkMwRTExMDhBOEZEMTdCNDQ4QTY4NTU0MTk5QzQ3RDA4RkZCMTBENEI4XCIsW10pO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDI1NnIxXCIsMjU2LFwiRkZGRkZGRkYwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRlwiLFwiRkZGRkZGRkYwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQ1wiLFwiNUFDNjM1RDhBQTNBOTNFN0IzRUJCRDU1NzY5ODg2QkM2NTFEMDZCMENDNTNCMEY2M0JDRTNDM0UyN0QyNjA0QlwiLFwiRkZGRkZGRkYwMDAwMDAwMEZGRkZGRkZGRkZGRkZGRkZCQ0U2RkFBREE3MTc5RTg0RjNCOUNBQzJGQzYzMjU1MVwiLFwiMVwiLFwiNkIxN0QxRjJFMTJDNDI0N0Y4QkNFNkU1NjNBNDQwRjI3NzAzN0Q4MTJERUIzM0EwRjRBMTM5NDVEODk4QzI5NlwiLFwiNEZFMzQyRTJGRTFBN0Y5QjhFRTdFQjRBN0MwRjlFMTYyQkNFMzM1NzZCMzE1RUNFQ0JCNjQwNjgzN0JGNTFGNVwiLFtcIk5JU1QgUC0yNTZcIixcIlAtMjU2XCIsXCJwcmltZTI1NnYxXCJdKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AzODRyMVwiLDM4NCxcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkVGRkZGRkZGRjAwMDAwMDAwMDAwMDAwMDBGRkZGRkZGRlwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGMDAwMDAwMDAwMDAwMDAwMEZGRkZGRkZDXCIsXCJCMzMxMkZBN0UyM0VFN0U0OTg4RTA1NkJFM0Y4MkQxOTE4MUQ5QzZFRkU4MTQxMTIwMzE0MDg4RjUwMTM4NzVBQzY1NjM5OEQ4QTJFRDE5RDJBODVDOEVERDNFQzJBRUZcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkM3NjM0RDgxRjQzNzJEREY1ODFBMERCMjQ4QjBBNzdBRUNFQzE5NkFDQ0M1Mjk3M1wiLFwiMVwiLFwiQUE4N0NBMjJCRThCMDUzNzhFQjFDNzFFRjMyMEFENzQ2RTFEM0I2MjhCQTc5Qjk4NTlGNzQxRTA4MjU0MkEzODU1MDJGMjVEQkY1NTI5NkMzQTU0NUUzODcyNzYwQUI3XCIsXCIzNjE3ZGU0YTk2MjYyYzZmNWQ5ZTk4YmY5MjkyZGMyOWY4ZjQxZGJkMjg5YTE0N2NlOWRhMzExM2I1ZjBiOGMwMGE2MGIxY2UxZDdlODE5ZDdhNDMxZDdjOTBlYTBlNWZcIixbXCJOSVNUIFAtMzg0XCIsXCJQLTM4NFwiXSk7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwNTIxcjFcIiw1MjEsXCIxRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRlwiLFwiMUZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkNcIixcIjA1MTk1M0VCOTYxOEUxQzlBMUY5MjlBMjFBMEI2ODU0MEVFQTJEQTcyNUI5OUIzMTVGM0I4QjQ4OTkxOEVGMTA5RTE1NjE5Mzk1MUVDN0U5MzdCMTY1MkMwQkQzQkIxQkYwNzM1NzNERjg4M0QyQzM0RjFFRjQ1MUZENDZCNTAzRjAwXCIsXCIxRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZBNTE4Njg3ODNCRjJGOTY2QjdGQ0MwMTQ4RjcwOUE1RDAzQkI1QzlCODg5OUM0N0FFQkI2RkI3MUU5MTM4NjQwOVwiLFwiMVwiLFwiQzY4NThFMDZCNzA0MDRFOUNEOUUzRUNCNjYyMzk1QjQ0MjlDNjQ4MTM5MDUzRkI1MjFGODI4QUY2MDZCNEQzREJBQTE0QjVFNzdFRkU3NTkyOEZFMURDMTI3QTJGRkE4REUzMzQ4QjNDMTg1NkE0MjlCRjk3RTdFMzFDMkU1QkQ2NlwiLFwiMDExODM5Mjk2YTc4OWEzYmMwMDQ1YzhhNWZiNDJjN2QxYmQ5OThmNTQ0NDk1NzliNDQ2ODE3YWZiZDE3MjczZTY2MmM5N2VlNzI5OTVlZjQyNjQwYzU1MGI5MDEzZmFkMDc2MTM1M2M3MDg2YTI3MmMyNDA4OGJlOTQ3NjlmZDE2NjUwXCIsW1wiTklTVCBQLTUyMVwiLFwiUC01MjFcIl0pO1xudmFyIEtFWVVUSUw9ZnVuY3Rpb24oKXt2YXIgZD1mdW5jdGlvbihwLHIscSl7cmV0dXJuIGsoQ3J5cHRvSlMuQUVTLHAscixxKX07dmFyIGU9ZnVuY3Rpb24ocCxyLHEpe3JldHVybiBrKENyeXB0b0pTLlRyaXBsZURFUyxwLHIscSl9O3ZhciBhPWZ1bmN0aW9uKHAscixxKXtyZXR1cm4gayhDcnlwdG9KUy5ERVMscCxyLHEpfTt2YXIgaz1mdW5jdGlvbihzLHgsdSxxKXt2YXIgcj1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHgpO3ZhciB3PUNyeXB0b0pTLmVuYy5IZXgucGFyc2UodSk7dmFyIHA9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZShxKTt2YXIgdD17fTt0LmtleT13O3QuaXY9cDt0LmNpcGhlcnRleHQ9cjt2YXIgdj1zLmRlY3J5cHQodCx3LHtpdjpwfSk7cmV0dXJuIENyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHYpfTt2YXIgbD1mdW5jdGlvbihwLHIscSl7cmV0dXJuIGcoQ3J5cHRvSlMuQUVTLHAscixxKX07dmFyIG89ZnVuY3Rpb24ocCxyLHEpe3JldHVybiBnKENyeXB0b0pTLlRyaXBsZURFUyxwLHIscSl9O3ZhciBmPWZ1bmN0aW9uKHAscixxKXtyZXR1cm4gZyhDcnlwdG9KUy5ERVMscCxyLHEpfTt2YXIgZz1mdW5jdGlvbih0LHksdixxKXt2YXIgcz1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHkpO3ZhciB4PUNyeXB0b0pTLmVuYy5IZXgucGFyc2Uodik7dmFyIHA9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZShxKTt2YXIgdz10LmVuY3J5cHQocyx4LHtpdjpwfSk7dmFyIHI9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh3LnRvU3RyaW5nKCkpO3ZhciB1PUNyeXB0b0pTLmVuYy5CYXNlNjQuc3RyaW5naWZ5KHIpO3JldHVybiB1fTt2YXIgaT17XCJBRVMtMjU2LUNCQ1wiOntwcm9jOmQsZXByb2M6bCxrZXlsZW46MzIsaXZsZW46MTZ9LFwiQUVTLTE5Mi1DQkNcIjp7cHJvYzpkLGVwcm9jOmwsa2V5bGVuOjI0LGl2bGVuOjE2fSxcIkFFUy0xMjgtQ0JDXCI6e3Byb2M6ZCxlcHJvYzpsLGtleWxlbjoxNixpdmxlbjoxNn0sXCJERVMtRURFMy1DQkNcIjp7cHJvYzplLGVwcm9jOm8sa2V5bGVuOjI0LGl2bGVuOjh9LFwiREVTLUNCQ1wiOntwcm9jOmEsZXByb2M6ZixrZXlsZW46OCxpdmxlbjo4fX07dmFyIGM9ZnVuY3Rpb24ocCl7cmV0dXJuIGlbcF1bXCJwcm9jXCJdfTt2YXIgbT1mdW5jdGlvbihwKXt2YXIgcj1DcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbShwKTt2YXIgcT1DcnlwdG9KUy5lbmMuSGV4LnN0cmluZ2lmeShyKTtyZXR1cm4gcX07dmFyIG49ZnVuY3Rpb24odil7dmFyIHc9e307dmFyIHE9di5tYXRjaChuZXcgUmVnRXhwKFwiREVLLUluZm86IChbXixdKyksKFswLTlBLUZhLWZdKylcIixcIm1cIikpO2lmKHEpe3cuY2lwaGVyPXFbMV07dy5pdnNhbHQ9cVsyXX12YXIgcD12Lm1hdGNoKG5ldyBSZWdFeHAoXCItLS0tLUJFR0lOIChbQS1aXSspIFBSSVZBVEUgS0VZLS0tLS1cIikpO2lmKHApe3cudHlwZT1wWzFdfXZhciB1PS0xO3ZhciB4PTA7aWYodi5pbmRleE9mKFwiXFxyXFxuXFxyXFxuXCIpIT0tMSl7dT12LmluZGV4T2YoXCJcXHJcXG5cXHJcXG5cIik7eD0yfWlmKHYuaW5kZXhPZihcIlxcblxcblwiKSE9LTEpe3U9di5pbmRleE9mKFwiXFxuXFxuXCIpO3g9MX12YXIgdD12LmluZGV4T2YoXCItLS0tLUVORFwiKTtpZih1IT0tMSYmdCE9LTEpe3ZhciByPXYuc3Vic3RyaW5nKHUreCoyLHQteCk7cj1yLnJlcGxhY2UoL1xccysvZyxcIlwiKTt3LmRhdGE9cn1yZXR1cm4gd307dmFyIGo9ZnVuY3Rpb24ocSx5LHApe3ZhciB2PXAuc3Vic3RyaW5nKDAsMTYpO3ZhciB0PUNyeXB0b0pTLmVuYy5IZXgucGFyc2Uodik7dmFyIHI9Q3J5cHRvSlMuZW5jLlV0ZjgucGFyc2UoeSk7dmFyIHU9aVtxXVtcImtleWxlblwiXStpW3FdW1wiaXZsZW5cIl07dmFyIHg9XCJcIjt2YXIgdz1udWxsO2Zvcig7Oyl7dmFyIHM9Q3J5cHRvSlMuYWxnby5NRDUuY3JlYXRlKCk7aWYodyE9bnVsbCl7cy51cGRhdGUodyl9cy51cGRhdGUocik7cy51cGRhdGUodCk7dz1zLmZpbmFsaXplKCk7eD14K0NyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHcpO2lmKHgubGVuZ3RoPj11KjIpe2JyZWFrfX12YXIgej17fTt6LmtleWhleD14LnN1YnN0cigwLGlbcV1bXCJrZXlsZW5cIl0qMik7ei5pdmhleD14LnN1YnN0cihpW3FdW1wia2V5bGVuXCJdKjIsaVtxXVtcIml2bGVuXCJdKjIpO3JldHVybiB6fTt2YXIgYj1mdW5jdGlvbihwLHYscix3KXt2YXIgcz1DcnlwdG9KUy5lbmMuQmFzZTY0LnBhcnNlKHApO3ZhciBxPUNyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHMpO3ZhciB1PWlbdl1bXCJwcm9jXCJdO3ZhciB0PXUocSxyLHcpO3JldHVybiB0fTt2YXIgaD1mdW5jdGlvbihwLHMscSx1KXt2YXIgcj1pW3NdW1wiZXByb2NcIl07dmFyIHQ9cihwLHEsdSk7cmV0dXJuIHR9O3JldHVybnt2ZXJzaW9uOlwiMS4wLjBcIixwYXJzZVBLQ1M1UEVNOmZ1bmN0aW9uKHApe3JldHVybiBuKHApfSxnZXRLZXlBbmRVbnVzZWRJdkJ5UGFzc2NvZGVBbmRJdnNhbHQ6ZnVuY3Rpb24ocSxwLHIpe3JldHVybiBqKHEscCxyKX0sZGVjcnlwdEtleUI2NDpmdW5jdGlvbihwLHIscSxzKXtyZXR1cm4gYihwLHIscSxzKX0sZ2V0RGVjcnlwdGVkS2V5SGV4OmZ1bmN0aW9uKHkseCl7dmFyIHE9bih5KTt2YXIgdD1xLnR5cGU7dmFyIHI9cS5jaXBoZXI7dmFyIHA9cS5pdnNhbHQ7dmFyIHM9cS5kYXRhO3ZhciB3PWoocix4LHApO3ZhciB2PXcua2V5aGV4O3ZhciB1PWIocyxyLHYscCk7cmV0dXJuIHV9LGdldEVuY3J5cHRlZFBLQ1M1UEVNRnJvbVBydktleUhleDpmdW5jdGlvbih4LHMsQSx0LHIpe3ZhciBwPVwiXCI7aWYodHlwZW9mIHQ9PVwidW5kZWZpbmVkXCJ8fHQ9PW51bGwpe3Q9XCJBRVMtMjU2LUNCQ1wifWlmKHR5cGVvZiBpW3RdPT1cInVuZGVmaW5lZFwiKXt0aHJvd1wiS0VZVVRJTCB1bnN1cHBvcnRlZCBhbGdvcml0aG06IFwiK3R9aWYodHlwZW9mIHI9PVwidW5kZWZpbmVkXCJ8fHI9PW51bGwpe3ZhciB2PWlbdF1bXCJpdmxlblwiXTt2YXIgdT1tKHYpO3I9dS50b1VwcGVyQ2FzZSgpfXZhciB6PWoodCxBLHIpO3ZhciB5PXoua2V5aGV4O3ZhciB3PWgocyx0LHkscik7dmFyIHE9dy5yZXBsYWNlKC8oLns2NH0pL2csXCIkMVxcclxcblwiKTt2YXIgcD1cIi0tLS0tQkVHSU4gXCIreCtcIiBQUklWQVRFIEtFWS0tLS0tXFxyXFxuXCI7cCs9XCJQcm9jLVR5cGU6IDQsRU5DUllQVEVEXFxyXFxuXCI7cCs9XCJERUstSW5mbzogXCIrdCtcIixcIityK1wiXFxyXFxuXCI7cCs9XCJcXHJcXG5cIjtwKz1xO3ArPVwiXFxyXFxuLS0tLS1FTkQgXCIreCtcIiBQUklWQVRFIEtFWS0tLS0tXFxyXFxuXCI7cmV0dXJuIHB9LHBhcnNlSGV4T2ZFbmNyeXB0ZWRQS0NTODpmdW5jdGlvbih5KXt2YXIgQj1BU04xSEVYO3ZhciB6PUIuZ2V0Q2hpbGRJZHg7dmFyIHc9Qi5nZXRWO3ZhciB0PXt9O3ZhciByPXooeSwwKTtpZihyLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQ6IFNFUVVFTkNFKDApLml0ZW1zICE9IDI6IFwiK3IubGVuZ3RofXQuY2lwaGVydGV4dD13KHksclsxXSk7dmFyIEE9eih5LHJbMF0pO2lmKEEubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIGZvcm1hdDogU0VRVUVOQ0UoMC4wKS5pdGVtcyAhPSAyOiBcIitBLmxlbmd0aH1pZih3KHksQVswXSkhPVwiMmE4NjQ4ODZmNzBkMDEwNTBkXCIpe3Rocm93XCJ0aGlzIG9ubHkgc3VwcG9ydHMgcGtjczVQQkVTMlwifXZhciBwPXooeSxBWzFdKTtpZihBLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQ6IFNFUVVFTkNFKDAuMC4xKS5pdGVtcyAhPSAyOiBcIitwLmxlbmd0aH12YXIgcT16KHkscFsxXSk7aWYocS5sZW5ndGghPTIpe3Rocm93XCJtYWxmb3JtZWQgZm9ybWF0OiBTRVFVRU5DRSgwLjAuMS4xKS5pdGVtcyAhPSAyOiBcIitxLmxlbmd0aH1pZih3KHkscVswXSkhPVwiMmE4NjQ4ODZmNzBkMDMwN1wiKXt0aHJvd1widGhpcyBvbmx5IHN1cHBvcnRzIFRyaXBsZURFU1wifXQuZW5jcnlwdGlvblNjaGVtZUFsZz1cIlRyaXBsZURFU1wiO3QuZW5jcnlwdGlvblNjaGVtZUlWPXcoeSxxWzFdKTt2YXIgcz16KHkscFswXSk7aWYocy5sZW5ndGghPTIpe3Rocm93XCJtYWxmb3JtZWQgZm9ybWF0OiBTRVFVRU5DRSgwLjAuMS4wKS5pdGVtcyAhPSAyOiBcIitzLmxlbmd0aH1pZih3KHksc1swXSkhPVwiMmE4NjQ4ODZmNzBkMDEwNTBjXCIpe3Rocm93XCJ0aGlzIG9ubHkgc3VwcG9ydHMgcGtjczVQQktERjJcIn12YXIgeD16KHksc1sxXSk7aWYoeC5sZW5ndGg8Mil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQ6IFNFUVVFTkNFKDAuMC4xLjAuMSkuaXRlbXMgPCAyOiBcIit4Lmxlbmd0aH10LnBia2RmMlNhbHQ9dyh5LHhbMF0pO3ZhciB1PXcoeSx4WzFdKTt0cnl7dC5wYmtkZjJJdGVyPXBhcnNlSW50KHUsMTYpfWNhdGNoKHYpe3Rocm93XCJtYWxmb3JtZWQgZm9ybWF0IHBia2RmMkl0ZXI6IFwiK3V9cmV0dXJuIHR9LGdldFBCS0RGMktleUhleEZyb21QYXJhbTpmdW5jdGlvbih1LHApe3ZhciB0PUNyeXB0b0pTLmVuYy5IZXgucGFyc2UodS5wYmtkZjJTYWx0KTt2YXIgcT11LnBia2RmMkl0ZXI7dmFyIHM9Q3J5cHRvSlMuUEJLREYyKHAsdCx7a2V5U2l6ZToxOTIvMzIsaXRlcmF0aW9uczpxfSk7dmFyIHI9Q3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkocyk7cmV0dXJuIHJ9LF9nZXRQbGFpblBLQ1M4SGV4RnJvbUVuY3J5cHRlZFBLQ1M4UEVNOmZ1bmN0aW9uKHgseSl7dmFyIHI9cGVtdG9oZXgoeCxcIkVOQ1JZUFRFRCBQUklWQVRFIEtFWVwiKTt2YXIgcD10aGlzLnBhcnNlSGV4T2ZFbmNyeXB0ZWRQS0NTOChyKTt2YXIgdT1LRVlVVElMLmdldFBCS0RGMktleUhleEZyb21QYXJhbShwLHkpO3ZhciB2PXt9O3YuY2lwaGVydGV4dD1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHAuY2lwaGVydGV4dCk7dmFyIHQ9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh1KTt2YXIgcz1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHAuZW5jcnlwdGlvblNjaGVtZUlWKTt2YXIgdz1DcnlwdG9KUy5UcmlwbGVERVMuZGVjcnlwdCh2LHQse2l2OnN9KTt2YXIgcT1DcnlwdG9KUy5lbmMuSGV4LnN0cmluZ2lmeSh3KTtyZXR1cm4gcX0sZ2V0S2V5RnJvbUVuY3J5cHRlZFBLQ1M4UEVNOmZ1bmN0aW9uKHMscSl7dmFyIHA9dGhpcy5fZ2V0UGxhaW5QS0NTOEhleEZyb21FbmNyeXB0ZWRQS0NTOFBFTShzLHEpO3ZhciByPXRoaXMuZ2V0S2V5RnJvbVBsYWluUHJpdmF0ZVBLQ1M4SGV4KHApO3JldHVybiByfSxwYXJzZVBsYWluUHJpdmF0ZVBLQ1M4SGV4OmZ1bmN0aW9uKHMpe3ZhciB2PUFTTjFIRVg7dmFyIHU9di5nZXRDaGlsZElkeDt2YXIgdD12LmdldFY7dmFyIHE9e307cS5hbGdwYXJhbT1udWxsO2lmKHMuc3Vic3RyKDAsMikhPVwiMzBcIil7dGhyb3dcIm1hbGZvcm1lZCBwbGFpbiBQS0NTOCBwcml2YXRlIGtleShjb2RlOjAwMSlcIn12YXIgcj11KHMsMCk7aWYoci5sZW5ndGghPTMpe3Rocm93XCJtYWxmb3JtZWQgcGxhaW4gUEtDUzggcHJpdmF0ZSBrZXkoY29kZTowMDIpXCJ9aWYocy5zdWJzdHIoclsxXSwyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHByaXZhdGUga2V5KGNvZGU6MDAzKVwifXZhciBwPXUocyxyWzFdKTtpZihwLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwcml2YXRlIGtleShjb2RlOjAwNClcIn1pZihzLnN1YnN0cihwWzBdLDIpIT1cIjA2XCIpe3Rocm93XCJtYWxmb3JtZWQgUEtDUzggcHJpdmF0ZSBrZXkoY29kZTowMDUpXCJ9cS5hbGdvaWQ9dChzLHBbMF0pO2lmKHMuc3Vic3RyKHBbMV0sMik9PVwiMDZcIil7cS5hbGdwYXJhbT10KHMscFsxXSl9aWYocy5zdWJzdHIoclsyXSwyKSE9XCIwNFwiKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHByaXZhdGUga2V5KGNvZGU6MDA2KVwifXEua2V5aWR4PXYuZ2V0VmlkeChzLHJbMl0pO3JldHVybiBxfSxnZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhQRU06ZnVuY3Rpb24ocSl7dmFyIHA9cGVtdG9oZXgocSxcIlBSSVZBVEUgS0VZXCIpO3ZhciByPXRoaXMuZ2V0S2V5RnJvbVBsYWluUHJpdmF0ZVBLQ1M4SGV4KHApO3JldHVybiByfSxnZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhIZXg6ZnVuY3Rpb24ocCl7dmFyIHE9dGhpcy5wYXJzZVBsYWluUHJpdmF0ZVBLQ1M4SGV4KHApO3ZhciByO2lmKHEuYWxnb2lkPT1cIjJhODY0ODg2ZjcwZDAxMDEwMVwiKXtyPW5ldyBSU0FLZXkoKX1lbHNle2lmKHEuYWxnb2lkPT1cIjJhODY0OGNlMzgwNDAxXCIpe3I9bmV3IEtKVVIuY3J5cHRvLkRTQSgpfWVsc2V7aWYocS5hbGdvaWQ9PVwiMmE4NjQ4Y2UzZDAyMDFcIil7cj1uZXcgS0pVUi5jcnlwdG8uRUNEU0EoKX1lbHNle3Rocm93XCJ1bnN1cHBvcnRlZCBwcml2YXRlIGtleSBhbGdvcml0aG1cIn19fXIucmVhZFBLQ1M4UHJ2S2V5SGV4KHApO3JldHVybiByfSxfZ2V0S2V5RnJvbVB1YmxpY1BLQ1M4SGV4OmZ1bmN0aW9uKHEpe3ZhciBwO3ZhciByPUFTTjFIRVguZ2V0VmJ5TGlzdChxLDAsWzAsMF0sXCIwNlwiKTtpZihyPT09XCIyYTg2NDg4NmY3MGQwMTAxMDFcIil7cD1uZXcgUlNBS2V5KCl9ZWxzZXtpZihyPT09XCIyYTg2NDhjZTM4MDQwMVwiKXtwPW5ldyBLSlVSLmNyeXB0by5EU0EoKX1lbHNle2lmKHI9PT1cIjJhODY0OGNlM2QwMjAxXCIpe3A9bmV3IEtKVVIuY3J5cHRvLkVDRFNBKCl9ZWxzZXt0aHJvd1widW5zdXBwb3J0ZWQgUEtDUyM4IHB1YmxpYyBrZXkgaGV4XCJ9fX1wLnJlYWRQS0NTOFB1YktleUhleChxKTtyZXR1cm4gcH0scGFyc2VQdWJsaWNSYXdSU0FLZXlIZXg6ZnVuY3Rpb24ocil7dmFyIHU9QVNOMUhFWDt2YXIgdD11LmdldENoaWxkSWR4O3ZhciBzPXUuZ2V0Vjt2YXIgcD17fTtpZihyLnN1YnN0cigwLDIpIT1cIjMwXCIpe3Rocm93XCJtYWxmb3JtZWQgUlNBIGtleShjb2RlOjAwMSlcIn12YXIgcT10KHIsMCk7aWYocS5sZW5ndGghPTIpe3Rocm93XCJtYWxmb3JtZWQgUlNBIGtleShjb2RlOjAwMilcIn1pZihyLnN1YnN0cihxWzBdLDIpIT1cIjAyXCIpe3Rocm93XCJtYWxmb3JtZWQgUlNBIGtleShjb2RlOjAwMylcIn1wLm49cyhyLHFbMF0pO2lmKHIuc3Vic3RyKHFbMV0sMikhPVwiMDJcIil7dGhyb3dcIm1hbGZvcm1lZCBSU0Ega2V5KGNvZGU6MDA0KVwifXAuZT1zKHIscVsxXSk7cmV0dXJuIHB9LHBhcnNlUHVibGljUEtDUzhIZXg6ZnVuY3Rpb24odCl7dmFyIHY9QVNOMUhFWDt2YXIgdT12LmdldENoaWxkSWR4O3ZhciBzPXYuZ2V0Vjt2YXIgcT17fTtxLmFsZ3BhcmFtPW51bGw7dmFyIHI9dSh0LDApO2lmKHIubGVuZ3RoIT0yKXt0aHJvd1wib3V0ZXIgREVSU2VxdWVuY2Ugc2hhbGwgaGF2ZSAyIGVsZW1lbnRzOiBcIityLmxlbmd0aH12YXIgdz1yWzBdO2lmKHQuc3Vic3RyKHcsMikhPVwiMzBcIil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwdWJsaWMga2V5KGNvZGU6MDAxKVwifXZhciBwPXUodCx3KTtpZihwLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwdWJsaWMga2V5KGNvZGU6MDAyKVwifWlmKHQuc3Vic3RyKHBbMF0sMikhPVwiMDZcIil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwdWJsaWMga2V5KGNvZGU6MDAzKVwifXEuYWxnb2lkPXModCxwWzBdKTtpZih0LnN1YnN0cihwWzFdLDIpPT1cIjA2XCIpe3EuYWxncGFyYW09cyh0LHBbMV0pfWVsc2V7aWYodC5zdWJzdHIocFsxXSwyKT09XCIzMFwiKXtxLmFsZ3BhcmFtPXt9O3EuYWxncGFyYW0ucD12LmdldFZieUxpc3QodCxwWzFdLFswXSxcIjAyXCIpO3EuYWxncGFyYW0ucT12LmdldFZieUxpc3QodCxwWzFdLFsxXSxcIjAyXCIpO3EuYWxncGFyYW0uZz12LmdldFZieUxpc3QodCxwWzFdLFsyXSxcIjAyXCIpfX1pZih0LnN1YnN0cihyWzFdLDIpIT1cIjAzXCIpe3Rocm93XCJtYWxmb3JtZWQgUEtDUzggcHVibGljIGtleShjb2RlOjAwNClcIn1xLmtleT1zKHQsclsxXSkuc3Vic3RyKDIpO3JldHVybiBxfSx9fSgpO0tFWVVUSUwuZ2V0S2V5PWZ1bmN0aW9uKGwsayxuKXt2YXIgRz1BU04xSEVYLEw9Ry5nZXRDaGlsZElkeCx2PUcuZ2V0VixkPUcuZ2V0VmJ5TGlzdCxjPUtKVVIuY3J5cHRvLGk9Yy5FQ0RTQSxDPWMuRFNBLHc9UlNBS2V5LE09cGVtdG9oZXgsRj1LRVlVVElMO2lmKHR5cGVvZiB3IT1cInVuZGVmaW5lZFwiJiZsIGluc3RhbmNlb2Ygdyl7cmV0dXJuIGx9aWYodHlwZW9mIGkhPVwidW5kZWZpbmVkXCImJmwgaW5zdGFuY2VvZiBpKXtyZXR1cm4gbH1pZih0eXBlb2YgQyE9XCJ1bmRlZmluZWRcIiYmbCBpbnN0YW5jZW9mIEMpe3JldHVybiBsfWlmKGwuY3VydmUhPT11bmRlZmluZWQmJmwueHkhPT11bmRlZmluZWQmJmwuZD09PXVuZGVmaW5lZCl7cmV0dXJuIG5ldyBpKHtwdWI6bC54eSxjdXJ2ZTpsLmN1cnZlfSl9aWYobC5jdXJ2ZSE9PXVuZGVmaW5lZCYmbC5kIT09dW5kZWZpbmVkKXtyZXR1cm4gbmV3IGkoe3BydjpsLmQsY3VydmU6bC5jdXJ2ZX0pfWlmKGwua3R5PT09dW5kZWZpbmVkJiZsLm4hPT11bmRlZmluZWQmJmwuZSE9PXVuZGVmaW5lZCYmbC5kPT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgdygpO1Auc2V0UHVibGljKGwubixsLmUpO3JldHVybiBQfWlmKGwua3R5PT09dW5kZWZpbmVkJiZsLm4hPT11bmRlZmluZWQmJmwuZSE9PXVuZGVmaW5lZCYmbC5kIT09dW5kZWZpbmVkJiZsLnAhPT11bmRlZmluZWQmJmwucSE9PXVuZGVmaW5lZCYmbC5kcCE9PXVuZGVmaW5lZCYmbC5kcSE9PXVuZGVmaW5lZCYmbC5jbyE9PXVuZGVmaW5lZCYmbC5xaT09PXVuZGVmaW5lZCl7dmFyIFA9bmV3IHcoKTtQLnNldFByaXZhdGVFeChsLm4sbC5lLGwuZCxsLnAsbC5xLGwuZHAsbC5kcSxsLmNvKTtyZXR1cm4gUH1pZihsLmt0eT09PXVuZGVmaW5lZCYmbC5uIT09dW5kZWZpbmVkJiZsLmUhPT11bmRlZmluZWQmJmwuZCE9PXVuZGVmaW5lZCYmbC5wPT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgdygpO1Auc2V0UHJpdmF0ZShsLm4sbC5lLGwuZCk7cmV0dXJuIFB9aWYobC5wIT09dW5kZWZpbmVkJiZsLnEhPT11bmRlZmluZWQmJmwuZyE9PXVuZGVmaW5lZCYmbC55IT09dW5kZWZpbmVkJiZsLng9PT11bmRlZmluZWQpe3ZhciBQPW5ldyBDKCk7UC5zZXRQdWJsaWMobC5wLGwucSxsLmcsbC55KTtyZXR1cm4gUH1pZihsLnAhPT11bmRlZmluZWQmJmwucSE9PXVuZGVmaW5lZCYmbC5nIT09dW5kZWZpbmVkJiZsLnkhPT11bmRlZmluZWQmJmwueCE9PXVuZGVmaW5lZCl7dmFyIFA9bmV3IEMoKTtQLnNldFByaXZhdGUobC5wLGwucSxsLmcsbC55LGwueCk7cmV0dXJuIFB9aWYobC5rdHk9PT1cIlJTQVwiJiZsLm4hPT11bmRlZmluZWQmJmwuZSE9PXVuZGVmaW5lZCYmbC5kPT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgdygpO1Auc2V0UHVibGljKGI2NHV0b2hleChsLm4pLGI2NHV0b2hleChsLmUpKTtyZXR1cm4gUH1pZihsLmt0eT09PVwiUlNBXCImJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQhPT11bmRlZmluZWQmJmwucCE9PXVuZGVmaW5lZCYmbC5xIT09dW5kZWZpbmVkJiZsLmRwIT09dW5kZWZpbmVkJiZsLmRxIT09dW5kZWZpbmVkJiZsLnFpIT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgdygpO1Auc2V0UHJpdmF0ZUV4KGI2NHV0b2hleChsLm4pLGI2NHV0b2hleChsLmUpLGI2NHV0b2hleChsLmQpLGI2NHV0b2hleChsLnApLGI2NHV0b2hleChsLnEpLGI2NHV0b2hleChsLmRwKSxiNjR1dG9oZXgobC5kcSksYjY0dXRvaGV4KGwucWkpKTtyZXR1cm4gUH1pZihsLmt0eT09PVwiUlNBXCImJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQhPT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQcml2YXRlKGI2NHV0b2hleChsLm4pLGI2NHV0b2hleChsLmUpLGI2NHV0b2hleChsLmQpKTtyZXR1cm4gUH1pZihsLmt0eT09PVwiRUNcIiYmbC5jcnYhPT11bmRlZmluZWQmJmwueCE9PXVuZGVmaW5lZCYmbC55IT09dW5kZWZpbmVkJiZsLmQ9PT11bmRlZmluZWQpe3ZhciBqPW5ldyBpKHtjdXJ2ZTpsLmNydn0pO3ZhciB0PWouZWNwYXJhbXMua2V5bGVuLzQ7dmFyIEI9KFwiMDAwMDAwMDAwMFwiK2I2NHV0b2hleChsLngpKS5zbGljZSgtdCk7dmFyIHo9KFwiMDAwMDAwMDAwMFwiK2I2NHV0b2hleChsLnkpKS5zbGljZSgtdCk7dmFyIHU9XCIwNFwiK0IrejtqLnNldFB1YmxpY0tleUhleCh1KTtyZXR1cm4gan1pZihsLmt0eT09PVwiRUNcIiYmbC5jcnYhPT11bmRlZmluZWQmJmwueCE9PXVuZGVmaW5lZCYmbC55IT09dW5kZWZpbmVkJiZsLmQhPT11bmRlZmluZWQpe3ZhciBqPW5ldyBpKHtjdXJ2ZTpsLmNydn0pO3ZhciB0PWouZWNwYXJhbXMua2V5bGVuLzQ7dmFyIEI9KFwiMDAwMDAwMDAwMFwiK2I2NHV0b2hleChsLngpKS5zbGljZSgtdCk7dmFyIHo9KFwiMDAwMDAwMDAwMFwiK2I2NHV0b2hleChsLnkpKS5zbGljZSgtdCk7dmFyIHU9XCIwNFwiK0Irejt2YXIgYj0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwuZCkpLnNsaWNlKC10KTtqLnNldFB1YmxpY0tleUhleCh1KTtqLnNldFByaXZhdGVLZXlIZXgoYik7cmV0dXJuIGp9aWYobj09PVwicGtjczVwcnZcIil7dmFyIEo9bCxHPUFTTjFIRVgsTixQO049TChKLDApO2lmKE4ubGVuZ3RoPT09OSl7UD1uZXcgdygpO1AucmVhZFBLQ1M1UHJ2S2V5SGV4KEopfWVsc2V7aWYoTi5sZW5ndGg9PT02KXtQPW5ldyBDKCk7UC5yZWFkUEtDUzVQcnZLZXlIZXgoSil9ZWxzZXtpZihOLmxlbmd0aD4yJiZKLnN1YnN0cihOWzFdLDIpPT09XCIwNFwiKXtQPW5ldyBpKCk7UC5yZWFkUEtDUzVQcnZLZXlIZXgoSil9ZWxzZXt0aHJvd1widW5zdXBwb3J0ZWQgUEtDUyMxLzUgaGV4YWRlY2ltYWwga2V5XCJ9fX1yZXR1cm4gUH1pZihuPT09XCJwa2NzOHBydlwiKXt2YXIgUD1GLmdldEtleUZyb21QbGFpblByaXZhdGVQS0NTOEhleChsKTtyZXR1cm4gUH1pZihuPT09XCJwa2NzOHB1YlwiKXtyZXR1cm4gRi5fZ2V0S2V5RnJvbVB1YmxpY1BLQ1M4SGV4KGwpfWlmKG49PT1cIng1MDlwdWJcIil7cmV0dXJuIFg1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRIZXgobCl9aWYobC5pbmRleE9mKFwiLUVORCBDRVJUSUZJQ0FURS1cIiwwKSE9LTF8fGwuaW5kZXhPZihcIi1FTkQgWDUwOSBDRVJUSUZJQ0FURS1cIiwwKSE9LTF8fGwuaW5kZXhPZihcIi1FTkQgVFJVU1RFRCBDRVJUSUZJQ0FURS1cIiwwKSE9LTEpe3JldHVybiBYNTA5LmdldFB1YmxpY0tleUZyb21DZXJ0UEVNKGwpfWlmKGwuaW5kZXhPZihcIi1FTkQgUFVCTElDIEtFWS1cIikhPS0xKXt2YXIgTz1wZW10b2hleChsLFwiUFVCTElDIEtFWVwiKTtyZXR1cm4gRi5fZ2V0S2V5RnJvbVB1YmxpY1BLQ1M4SGV4KE8pfWlmKGwuaW5kZXhPZihcIi1FTkQgUlNBIFBSSVZBVEUgS0VZLVwiKSE9LTEmJmwuaW5kZXhPZihcIjQsRU5DUllQVEVEXCIpPT0tMSl7dmFyIG09TShsLFwiUlNBIFBSSVZBVEUgS0VZXCIpO3JldHVybiBGLmdldEtleShtLG51bGwsXCJwa2NzNXBydlwiKX1pZihsLmluZGV4T2YoXCItRU5EIERTQSBQUklWQVRFIEtFWS1cIikhPS0xJiZsLmluZGV4T2YoXCI0LEVOQ1JZUFRFRFwiKT09LTEpe3ZhciBJPU0obCxcIkRTQSBQUklWQVRFIEtFWVwiKTt2YXIgRT1kKEksMCxbMV0sXCIwMlwiKTt2YXIgRD1kKEksMCxbMl0sXCIwMlwiKTt2YXIgSz1kKEksMCxbM10sXCIwMlwiKTt2YXIgcj1kKEksMCxbNF0sXCIwMlwiKTt2YXIgcz1kKEksMCxbNV0sXCIwMlwiKTt2YXIgUD1uZXcgQygpO1Auc2V0UHJpdmF0ZShuZXcgQmlnSW50ZWdlcihFLDE2KSxuZXcgQmlnSW50ZWdlcihELDE2KSxuZXcgQmlnSW50ZWdlcihLLDE2KSxuZXcgQmlnSW50ZWdlcihyLDE2KSxuZXcgQmlnSW50ZWdlcihzLDE2KSk7cmV0dXJuIFB9aWYobC5pbmRleE9mKFwiLUVORCBQUklWQVRFIEtFWS1cIikhPS0xKXtyZXR1cm4gRi5nZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhQRU0obCl9aWYobC5pbmRleE9mKFwiLUVORCBSU0EgUFJJVkFURSBLRVktXCIpIT0tMSYmbC5pbmRleE9mKFwiNCxFTkNSWVBURURcIikhPS0xKXt2YXIgbz1GLmdldERlY3J5cHRlZEtleUhleChsLGspO3ZhciBIPW5ldyBSU0FLZXkoKTtILnJlYWRQS0NTNVBydktleUhleChvKTtyZXR1cm4gSH1pZihsLmluZGV4T2YoXCItRU5EIEVDIFBSSVZBVEUgS0VZLVwiKSE9LTEmJmwuaW5kZXhPZihcIjQsRU5DUllQVEVEXCIpIT0tMSl7dmFyIEk9Ri5nZXREZWNyeXB0ZWRLZXlIZXgobCxrKTt2YXIgUD1kKEksMCxbMV0sXCIwNFwiKTt2YXIgZj1kKEksMCxbMiwwXSxcIjA2XCIpO3ZhciBBPWQoSSwwLFszLDBdLFwiMDNcIikuc3Vic3RyKDIpO3ZhciBlPVwiXCI7aWYoS0pVUi5jcnlwdG8uT0lELm9pZGhleDJuYW1lW2ZdIT09dW5kZWZpbmVkKXtlPUtKVVIuY3J5cHRvLk9JRC5vaWRoZXgybmFtZVtmXX1lbHNle3Rocm93XCJ1bmRlZmluZWQgT0lEKGhleCkgaW4gS0pVUi5jcnlwdG8uT0lEOiBcIitmfXZhciBqPW5ldyBpKHtjdXJ2ZTplfSk7ai5zZXRQdWJsaWNLZXlIZXgoQSk7ai5zZXRQcml2YXRlS2V5SGV4KFApO2ouaXNQdWJsaWM9ZmFsc2U7cmV0dXJuIGp9aWYobC5pbmRleE9mKFwiLUVORCBEU0EgUFJJVkFURSBLRVktXCIpIT0tMSYmbC5pbmRleE9mKFwiNCxFTkNSWVBURURcIikhPS0xKXt2YXIgST1GLmdldERlY3J5cHRlZEtleUhleChsLGspO3ZhciBFPWQoSSwwLFsxXSxcIjAyXCIpO3ZhciBEPWQoSSwwLFsyXSxcIjAyXCIpO3ZhciBLPWQoSSwwLFszXSxcIjAyXCIpO3ZhciByPWQoSSwwLFs0XSxcIjAyXCIpO3ZhciBzPWQoSSwwLFs1XSxcIjAyXCIpO3ZhciBQPW5ldyBDKCk7UC5zZXRQcml2YXRlKG5ldyBCaWdJbnRlZ2VyKEUsMTYpLG5ldyBCaWdJbnRlZ2VyKEQsMTYpLG5ldyBCaWdJbnRlZ2VyKEssMTYpLG5ldyBCaWdJbnRlZ2VyKHIsMTYpLG5ldyBCaWdJbnRlZ2VyKHMsMTYpKTtyZXR1cm4gUH1pZihsLmluZGV4T2YoXCItRU5EIEVOQ1JZUFRFRCBQUklWQVRFIEtFWS1cIikhPS0xKXtyZXR1cm4gRi5nZXRLZXlGcm9tRW5jcnlwdGVkUEtDUzhQRU0obCxrKX10aHJvd1wibm90IHN1cHBvcnRlZCBhcmd1bWVudFwifTtLRVlVVElMLmdlbmVyYXRlS2V5cGFpcj1mdW5jdGlvbihhLGMpe2lmKGE9PVwiUlNBXCIpe3ZhciBiPWM7dmFyIGg9bmV3IFJTQUtleSgpO2guZ2VuZXJhdGUoYixcIjEwMDAxXCIpO2guaXNQcml2YXRlPXRydWU7aC5pc1B1YmxpYz10cnVlO3ZhciBmPW5ldyBSU0FLZXkoKTt2YXIgZT1oLm4udG9TdHJpbmcoMTYpO3ZhciBpPWguZS50b1N0cmluZygxNik7Zi5zZXRQdWJsaWMoZSxpKTtmLmlzUHJpdmF0ZT1mYWxzZTtmLmlzUHVibGljPXRydWU7dmFyIGs9e307ay5wcnZLZXlPYmo9aDtrLnB1YktleU9iaj1mO3JldHVybiBrfWVsc2V7aWYoYT09XCJFQ1wiKXt2YXIgZD1jO3ZhciBnPW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6ZH0pO3ZhciBqPWcuZ2VuZXJhdGVLZXlQYWlySGV4KCk7dmFyIGg9bmV3IEtKVVIuY3J5cHRvLkVDRFNBKHtjdXJ2ZTpkfSk7aC5zZXRQdWJsaWNLZXlIZXgoai5lY3B1YmhleCk7aC5zZXRQcml2YXRlS2V5SGV4KGouZWNwcnZoZXgpO2guaXNQcml2YXRlPXRydWU7aC5pc1B1YmxpYz1mYWxzZTt2YXIgZj1uZXcgS0pVUi5jcnlwdG8uRUNEU0Eoe2N1cnZlOmR9KTtmLnNldFB1YmxpY0tleUhleChqLmVjcHViaGV4KTtmLmlzUHJpdmF0ZT1mYWxzZTtmLmlzUHVibGljPXRydWU7dmFyIGs9e307ay5wcnZLZXlPYmo9aDtrLnB1YktleU9iaj1mO3JldHVybiBrfWVsc2V7dGhyb3dcInVua25vd24gYWxnb3JpdGhtOiBcIithfX19O0tFWVVUSUwuZ2V0UEVNPWZ1bmN0aW9uKGIsRCx5LG0scSxqKXt2YXIgRj1LSlVSLGs9Ri5hc24xLHo9ay5ERVJPYmplY3RJZGVudGlmaWVyLGY9ay5ERVJJbnRlZ2VyLGw9ay5BU04xVXRpbC5uZXdPYmplY3QsYT1rLng1MDksQz1hLlN1YmplY3RQdWJsaWNLZXlJbmZvLGU9Ri5jcnlwdG8sdT1lLkRTQSxyPWUuRUNEU0Esbj1SU0FLZXk7ZnVuY3Rpb24gQShzKXt2YXIgRz1sKHtzZXE6W3tcImludFwiOjB9LHtcImludFwiOntiaWdpbnQ6cy5ufX0se1wiaW50XCI6cy5lfSx7XCJpbnRcIjp7YmlnaW50OnMuZH19LHtcImludFwiOntiaWdpbnQ6cy5wfX0se1wiaW50XCI6e2JpZ2ludDpzLnF9fSx7XCJpbnRcIjp7YmlnaW50OnMuZG1wMX19LHtcImludFwiOntiaWdpbnQ6cy5kbXExfX0se1wiaW50XCI6e2JpZ2ludDpzLmNvZWZmfX1dfSk7cmV0dXJuIEd9ZnVuY3Rpb24gQihHKXt2YXIgcz1sKHtzZXE6W3tcImludFwiOjF9LHtvY3RzdHI6e2hleDpHLnBydktleUhleH19LHt0YWc6W1wiYTBcIix0cnVlLHtvaWQ6e25hbWU6Ry5jdXJ2ZU5hbWV9fV19LHt0YWc6W1wiYTFcIix0cnVlLHtiaXRzdHI6e2hleDpcIjAwXCIrRy5wdWJLZXlIZXh9fV19XX0pO3JldHVybiBzfWZ1bmN0aW9uIHgocyl7dmFyIEc9bCh7c2VxOlt7XCJpbnRcIjowfSx7XCJpbnRcIjp7YmlnaW50OnMucH19LHtcImludFwiOntiaWdpbnQ6cy5xfX0se1wiaW50XCI6e2JpZ2ludDpzLmd9fSx7XCJpbnRcIjp7YmlnaW50OnMueX19LHtcImludFwiOntiaWdpbnQ6cy54fX1dfSk7cmV0dXJuIEd9aWYoKChuIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2Ygbil8fCh1IT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgdSl8fChyIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgcikpJiZiLmlzUHVibGljPT10cnVlJiYoRD09PXVuZGVmaW5lZHx8RD09XCJQS0NTOFBVQlwiKSl7dmFyIEU9bmV3IEMoYik7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7cmV0dXJuIGhleHRvcGVtKHcsXCJQVUJMSUMgS0VZXCIpfWlmKEQ9PVwiUEtDUzFQUlZcIiYmbiE9PXVuZGVmaW5lZCYmYiBpbnN0YW5jZW9mIG4mJih5PT09dW5kZWZpbmVkfHx5PT1udWxsKSYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBFPUEoYik7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7cmV0dXJuIGhleHRvcGVtKHcsXCJSU0EgUFJJVkFURSBLRVlcIil9aWYoRD09XCJQS0NTMVBSVlwiJiZyIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgciYmKHk9PT11bmRlZmluZWR8fHk9PW51bGwpJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIGk9bmV3IHooe25hbWU6Yi5jdXJ2ZU5hbWV9KTt2YXIgdj1pLmdldEVuY29kZWRIZXgoKTt2YXIgaD1CKGIpO3ZhciB0PWguZ2V0RW5jb2RlZEhleCgpO3ZhciBwPVwiXCI7cCs9aGV4dG9wZW0odixcIkVDIFBBUkFNRVRFUlNcIik7cCs9aGV4dG9wZW0odCxcIkVDIFBSSVZBVEUgS0VZXCIpO3JldHVybiBwfWlmKEQ9PVwiUEtDUzFQUlZcIiYmdSE9PXVuZGVmaW5lZCYmYiBpbnN0YW5jZW9mIHUmJih5PT09dW5kZWZpbmVkfHx5PT1udWxsKSYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBFPXgoYik7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7cmV0dXJuIGhleHRvcGVtKHcsXCJEU0EgUFJJVkFURSBLRVlcIil9aWYoRD09XCJQS0NTNVBSVlwiJiZuIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgbiYmKHkhPT11bmRlZmluZWQmJnkhPW51bGwpJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIEU9QShiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtpZihtPT09dW5kZWZpbmVkKXttPVwiREVTLUVERTMtQ0JDXCJ9cmV0dXJuIHRoaXMuZ2V0RW5jcnlwdGVkUEtDUzVQRU1Gcm9tUHJ2S2V5SGV4KFwiUlNBXCIsdyx5LG0sail9aWYoRD09XCJQS0NTNVBSVlwiJiZyIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgciYmKHkhPT11bmRlZmluZWQmJnkhPW51bGwpJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIEU9QihiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtpZihtPT09dW5kZWZpbmVkKXttPVwiREVTLUVERTMtQ0JDXCJ9cmV0dXJuIHRoaXMuZ2V0RW5jcnlwdGVkUEtDUzVQRU1Gcm9tUHJ2S2V5SGV4KFwiRUNcIix3LHksbSxqKX1pZihEPT1cIlBLQ1M1UFJWXCImJnUhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiB1JiYoeSE9PXVuZGVmaW5lZCYmeSE9bnVsbCkmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgRT14KGIpO3ZhciB3PUUuZ2V0RW5jb2RlZEhleCgpO2lmKG09PT11bmRlZmluZWQpe209XCJERVMtRURFMy1DQkNcIn1yZXR1cm4gdGhpcy5nZXRFbmNyeXB0ZWRQS0NTNVBFTUZyb21QcnZLZXlIZXgoXCJEU0FcIix3LHksbSxqKX12YXIgbz1mdW5jdGlvbihHLHMpe3ZhciBJPWMoRyxzKTt2YXIgSD1uZXcgbCh7c2VxOlt7c2VxOlt7b2lkOntuYW1lOlwicGtjczVQQkVTMlwifX0se3NlcTpbe3NlcTpbe29pZDp7bmFtZTpcInBrY3M1UEJLREYyXCJ9fSx7c2VxOlt7b2N0c3RyOntoZXg6SS5wYmtkZjJTYWx0fX0se1wiaW50XCI6SS5wYmtkZjJJdGVyfV19XX0se3NlcTpbe29pZDp7bmFtZTpcImRlcy1FREUzLUNCQ1wifX0se29jdHN0cjp7aGV4OkkuZW5jcnlwdGlvblNjaGVtZUlWfX1dfV19XX0se29jdHN0cjp7aGV4OkkuY2lwaGVydGV4dH19XX0pO3JldHVybiBILmdldEVuY29kZWRIZXgoKX07dmFyIGM9ZnVuY3Rpb24oTixPKXt2YXIgSD0xMDA7dmFyIE09Q3J5cHRvSlMubGliLldvcmRBcnJheS5yYW5kb20oOCk7dmFyIEw9XCJERVMtRURFMy1DQkNcIjt2YXIgcz1DcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSg4KTt2YXIgST1DcnlwdG9KUy5QQktERjIoTyxNLHtrZXlTaXplOjE5Mi8zMixpdGVyYXRpb25zOkh9KTt2YXIgSj1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKE4pO3ZhciBLPUNyeXB0b0pTLlRyaXBsZURFUy5lbmNyeXB0KEosSSx7aXY6c30pK1wiXCI7dmFyIEc9e307Ry5jaXBoZXJ0ZXh0PUs7Ry5wYmtkZjJTYWx0PUNyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KE0pO0cucGJrZGYySXRlcj1IO0cuZW5jcnlwdGlvblNjaGVtZUFsZz1MO0cuZW5jcnlwdGlvblNjaGVtZUlWPUNyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHMpO3JldHVybiBHfTtpZihEPT1cIlBLQ1M4UFJWXCImJm4hPXVuZGVmaW5lZCYmYiBpbnN0YW5jZW9mIG4mJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgZz1BKGIpO3ZhciBkPWcuZ2V0RW5jb2RlZEhleCgpO3ZhciBFPWwoe3NlcTpbe1wiaW50XCI6MH0se3NlcTpbe29pZDp7bmFtZTpcInJzYUVuY3J5cHRpb25cIn19LHtcIm51bGxcIjp0cnVlfV19LHtvY3RzdHI6e2hleDpkfX1dfSk7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7aWYoeT09PXVuZGVmaW5lZHx8eT09bnVsbCl7cmV0dXJuIGhleHRvcGVtKHcsXCJQUklWQVRFIEtFWVwiKX1lbHNle3ZhciB0PW8odyx5KTtyZXR1cm4gaGV4dG9wZW0odCxcIkVOQ1JZUFRFRCBQUklWQVRFIEtFWVwiKX19aWYoRD09XCJQS0NTOFBSVlwiJiZyIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgciYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBnPW5ldyBsKHtzZXE6W3tcImludFwiOjF9LHtvY3RzdHI6e2hleDpiLnBydktleUhleH19LHt0YWc6W1wiYTFcIix0cnVlLHtiaXRzdHI6e2hleDpcIjAwXCIrYi5wdWJLZXlIZXh9fV19XX0pO3ZhciBkPWcuZ2V0RW5jb2RlZEhleCgpO3ZhciBFPWwoe3NlcTpbe1wiaW50XCI6MH0se3NlcTpbe29pZDp7bmFtZTpcImVjUHVibGljS2V5XCJ9fSx7b2lkOntuYW1lOmIuY3VydmVOYW1lfX1dfSx7b2N0c3RyOntoZXg6ZH19XX0pO3ZhciB3PUUuZ2V0RW5jb2RlZEhleCgpO2lmKHk9PT11bmRlZmluZWR8fHk9PW51bGwpe3JldHVybiBoZXh0b3BlbSh3LFwiUFJJVkFURSBLRVlcIil9ZWxzZXt2YXIgdD1vKHcseSk7cmV0dXJuIGhleHRvcGVtKHQsXCJFTkNSWVBURUQgUFJJVkFURSBLRVlcIil9fWlmKEQ9PVwiUEtDUzhQUlZcIiYmdSE9PXVuZGVmaW5lZCYmYiBpbnN0YW5jZW9mIHUmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgZz1uZXcgZih7YmlnaW50OmIueH0pO3ZhciBkPWcuZ2V0RW5jb2RlZEhleCgpO3ZhciBFPWwoe3NlcTpbe1wiaW50XCI6MH0se3NlcTpbe29pZDp7bmFtZTpcImRzYVwifX0se3NlcTpbe1wiaW50XCI6e2JpZ2ludDpiLnB9fSx7XCJpbnRcIjp7YmlnaW50OmIucX19LHtcImludFwiOntiaWdpbnQ6Yi5nfX1dfV19LHtvY3RzdHI6e2hleDpkfX1dfSk7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7aWYoeT09PXVuZGVmaW5lZHx8eT09bnVsbCl7cmV0dXJuIGhleHRvcGVtKHcsXCJQUklWQVRFIEtFWVwiKX1lbHNle3ZhciB0PW8odyx5KTtyZXR1cm4gaGV4dG9wZW0odCxcIkVOQ1JZUFRFRCBQUklWQVRFIEtFWVwiKX19dGhyb3dcInVuc3VwcG9ydGVkIG9iamVjdCBub3IgZm9ybWF0XCJ9O0tFWVVUSUwuZ2V0S2V5RnJvbUNTUlBFTT1mdW5jdGlvbihiKXt2YXIgYT1wZW10b2hleChiLFwiQ0VSVElGSUNBVEUgUkVRVUVTVFwiKTt2YXIgYz1LRVlVVElMLmdldEtleUZyb21DU1JIZXgoYSk7cmV0dXJuIGN9O0tFWVVUSUwuZ2V0S2V5RnJvbUNTUkhleD1mdW5jdGlvbihhKXt2YXIgYz1LRVlVVElMLnBhcnNlQ1NSSGV4KGEpO3ZhciBiPUtFWVVUSUwuZ2V0S2V5KGMucDhwdWJrZXloZXgsbnVsbCxcInBrY3M4cHViXCIpO3JldHVybiBifTtLRVlVVElMLnBhcnNlQ1NSSGV4PWZ1bmN0aW9uKGQpe3ZhciBpPUFTTjFIRVg7dmFyIGY9aS5nZXRDaGlsZElkeDt2YXIgYz1pLmdldFRMVjt2YXIgYj17fTt2YXIgZz1kO2lmKGcuc3Vic3RyKDAsMikhPVwiMzBcIil7dGhyb3dcIm1hbGZvcm1lZCBDU1IoY29kZTowMDEpXCJ9dmFyIGU9ZihnLDApO2lmKGUubGVuZ3RoPDEpe3Rocm93XCJtYWxmb3JtZWQgQ1NSKGNvZGU6MDAyKVwifWlmKGcuc3Vic3RyKGVbMF0sMikhPVwiMzBcIil7dGhyb3dcIm1hbGZvcm1lZCBDU1IoY29kZTowMDMpXCJ9dmFyIGE9ZihnLGVbMF0pO2lmKGEubGVuZ3RoPDMpe3Rocm93XCJtYWxmb3JtZWQgQ1NSKGNvZGU6MDA0KVwifWIucDhwdWJrZXloZXg9YyhnLGFbMl0pO3JldHVybiBifTtLRVlVVElMLmdldEpXS0Zyb21LZXk9ZnVuY3Rpb24oZCl7dmFyIGI9e307aWYoZCBpbnN0YW5jZW9mIFJTQUtleSYmZC5pc1ByaXZhdGUpe2Iua3R5PVwiUlNBXCI7Yi5uPWhleHRvYjY0dShkLm4udG9TdHJpbmcoMTYpKTtiLmU9aGV4dG9iNjR1KGQuZS50b1N0cmluZygxNikpO2IuZD1oZXh0b2I2NHUoZC5kLnRvU3RyaW5nKDE2KSk7Yi5wPWhleHRvYjY0dShkLnAudG9TdHJpbmcoMTYpKTtiLnE9aGV4dG9iNjR1KGQucS50b1N0cmluZygxNikpO2IuZHA9aGV4dG9iNjR1KGQuZG1wMS50b1N0cmluZygxNikpO2IuZHE9aGV4dG9iNjR1KGQuZG1xMS50b1N0cmluZygxNikpO2IucWk9aGV4dG9iNjR1KGQuY29lZmYudG9TdHJpbmcoMTYpKTtyZXR1cm4gYn1lbHNle2lmKGQgaW5zdGFuY2VvZiBSU0FLZXkmJmQuaXNQdWJsaWMpe2Iua3R5PVwiUlNBXCI7Yi5uPWhleHRvYjY0dShkLm4udG9TdHJpbmcoMTYpKTtiLmU9aGV4dG9iNjR1KGQuZS50b1N0cmluZygxNikpO3JldHVybiBifWVsc2V7aWYoZCBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkVDRFNBJiZkLmlzUHJpdmF0ZSl7dmFyIGE9ZC5nZXRTaG9ydE5JU1RQQ3VydmVOYW1lKCk7aWYoYSE9PVwiUC0yNTZcIiYmYSE9PVwiUC0zODRcIil7dGhyb3dcInVuc3VwcG9ydGVkIGN1cnZlIG5hbWUgZm9yIEpXVDogXCIrYX12YXIgYz1kLmdldFB1YmxpY0tleVhZSGV4KCk7Yi5rdHk9XCJFQ1wiO2IuY3J2PWE7Yi54PWhleHRvYjY0dShjLngpO2IueT1oZXh0b2I2NHUoYy55KTtiLmQ9aGV4dG9iNjR1KGQucHJ2S2V5SGV4KTtyZXR1cm4gYn1lbHNle2lmKGQgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5FQ0RTQSYmZC5pc1B1YmxpYyl7dmFyIGE9ZC5nZXRTaG9ydE5JU1RQQ3VydmVOYW1lKCk7aWYoYSE9PVwiUC0yNTZcIiYmYSE9PVwiUC0zODRcIil7dGhyb3dcInVuc3VwcG9ydGVkIGN1cnZlIG5hbWUgZm9yIEpXVDogXCIrYX12YXIgYz1kLmdldFB1YmxpY0tleVhZSGV4KCk7Yi5rdHk9XCJFQ1wiO2IuY3J2PWE7Yi54PWhleHRvYjY0dShjLngpO2IueT1oZXh0b2I2NHUoYy55KTtyZXR1cm4gYn19fX10aHJvd1wibm90IHN1cHBvcnRlZCBrZXkgb2JqZWN0XCJ9O1xuUlNBS2V5LmdldFBvc0FycmF5T2ZDaGlsZHJlbkZyb21IZXg9ZnVuY3Rpb24oYSl7cmV0dXJuIEFTTjFIRVguZ2V0Q2hpbGRJZHgoYSwwKX07UlNBS2V5LmdldEhleFZhbHVlQXJyYXlPZkNoaWxkcmVuRnJvbUhleD1mdW5jdGlvbihmKXt2YXIgbj1BU04xSEVYO3ZhciBpPW4uZ2V0Vjt2YXIgaz1SU0FLZXkuZ2V0UG9zQXJyYXlPZkNoaWxkcmVuRnJvbUhleChmKTt2YXIgZT1pKGYsa1swXSk7dmFyIGo9aShmLGtbMV0pO3ZhciBiPWkoZixrWzJdKTt2YXIgYz1pKGYsa1szXSk7dmFyIGg9aShmLGtbNF0pO3ZhciBnPWkoZixrWzVdKTt2YXIgbT1pKGYsa1s2XSk7dmFyIGw9aShmLGtbN10pO3ZhciBkPWkoZixrWzhdKTt2YXIgaz1uZXcgQXJyYXkoKTtrLnB1c2goZSxqLGIsYyxoLGcsbSxsLGQpO3JldHVybiBrfTtSU0FLZXkucHJvdG90eXBlLnJlYWRQcml2YXRlS2V5RnJvbVBFTVN0cmluZz1mdW5jdGlvbihkKXt2YXIgYz1wZW10b2hleChkKTt2YXIgYj1SU0FLZXkuZ2V0SGV4VmFsdWVBcnJheU9mQ2hpbGRyZW5Gcm9tSGV4KGMpO3RoaXMuc2V0UHJpdmF0ZUV4KGJbMV0sYlsyXSxiWzNdLGJbNF0sYls1XSxiWzZdLGJbN10sYls4XSl9O1JTQUtleS5wcm90b3R5cGUucmVhZFBLQ1M1UHJ2S2V5SGV4PWZ1bmN0aW9uKGMpe3ZhciBiPVJTQUtleS5nZXRIZXhWYWx1ZUFycmF5T2ZDaGlsZHJlbkZyb21IZXgoYyk7dGhpcy5zZXRQcml2YXRlRXgoYlsxXSxiWzJdLGJbM10sYls0XSxiWzVdLGJbNl0sYls3XSxiWzhdKX07UlNBS2V5LnByb3RvdHlwZS5yZWFkUEtDUzhQcnZLZXlIZXg9ZnVuY3Rpb24oZSl7dmFyIGMsaixsLGIsYSxmLGQsazt2YXIgbT1BU04xSEVYO3ZhciBnPW0uZ2V0VmJ5TGlzdDtpZihtLmlzQVNOMUhFWChlKT09PWZhbHNlKXt0aHJvd1wibm90IEFTTi4xIGhleCBzdHJpbmdcIn10cnl7Yz1nKGUsMCxbMiwwLDFdLFwiMDJcIik7aj1nKGUsMCxbMiwwLDJdLFwiMDJcIik7bD1nKGUsMCxbMiwwLDNdLFwiMDJcIik7Yj1nKGUsMCxbMiwwLDRdLFwiMDJcIik7YT1nKGUsMCxbMiwwLDVdLFwiMDJcIik7Zj1nKGUsMCxbMiwwLDZdLFwiMDJcIik7ZD1nKGUsMCxbMiwwLDddLFwiMDJcIik7az1nKGUsMCxbMiwwLDhdLFwiMDJcIil9Y2F0Y2goaSl7dGhyb3dcIm1hbGZvcm1lZCBQS0NTIzggcGxhaW4gUlNBIHByaXZhdGUga2V5XCJ9dGhpcy5zZXRQcml2YXRlRXgoYyxqLGwsYixhLGYsZCxrKX07UlNBS2V5LnByb3RvdHlwZS5yZWFkUEtDUzVQdWJLZXlIZXg9ZnVuY3Rpb24oYyl7dmFyIGU9QVNOMUhFWDt2YXIgYj1lLmdldFY7aWYoZS5pc0FTTjFIRVgoYyk9PT1mYWxzZSl7dGhyb3dcImtleUhleCBpcyBub3QgQVNOLjEgaGV4IHN0cmluZ1wifXZhciBhPWUuZ2V0Q2hpbGRJZHgoYywwKTtpZihhLmxlbmd0aCE9PTJ8fGMuc3Vic3RyKGFbMF0sMikhPT1cIjAyXCJ8fGMuc3Vic3RyKGFbMV0sMikhPT1cIjAyXCIpe3Rocm93XCJ3cm9uZyBoZXggZm9yIFBLQ1MjNSBwdWJsaWMga2V5XCJ9dmFyIGY9YihjLGFbMF0pO3ZhciBkPWIoYyxhWzFdKTt0aGlzLnNldFB1YmxpYyhmLGQpfTtSU0FLZXkucHJvdG90eXBlLnJlYWRQS0NTOFB1YktleUhleD1mdW5jdGlvbihiKXt2YXIgYz1BU04xSEVYO2lmKGMuaXNBU04xSEVYKGIpPT09ZmFsc2Upe3Rocm93XCJub3QgQVNOLjEgaGV4IHN0cmluZ1wifWlmKGMuZ2V0VExWYnlMaXN0KGIsMCxbMCwwXSkhPT1cIjA2MDkyYTg2NDg4NmY3MGQwMTAxMDFcIil7dGhyb3dcIm5vdCBQS0NTOCBSU0EgcHVibGljIGtleVwifXZhciBhPWMuZ2V0VExWYnlMaXN0KGIsMCxbMSwwXSk7dGhpcy5yZWFkUEtDUzVQdWJLZXlIZXgoYSl9O1JTQUtleS5wcm90b3R5cGUucmVhZENlcnRQdWJLZXlIZXg9ZnVuY3Rpb24oYixkKXt2YXIgYSxjO2E9bmV3IFg1MDkoKTthLnJlYWRDZXJ0SGV4KGIpO2M9YS5nZXRQdWJsaWNLZXlIZXgoKTt0aGlzLnJlYWRQS0NTOFB1YktleUhleChjKX07XG52YXIgX1JFX0hFWERFQ09OTFk9bmV3IFJlZ0V4cChcIlwiKTtfUkVfSEVYREVDT05MWS5jb21waWxlKFwiW14wLTlhLWZdXCIsXCJnaVwiKTtmdW5jdGlvbiBfcnNhc2lnbl9nZXRIZXhQYWRkZWREaWdlc3RJbmZvRm9yU3RyaW5nKGQsZSxhKXt2YXIgYj1mdW5jdGlvbihmKXtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5oYXNoU3RyaW5nKGYsYSl9O3ZhciBjPWIoZCk7cmV0dXJuIEtKVVIuY3J5cHRvLlV0aWwuZ2V0UGFkZGVkRGlnZXN0SW5mb0hleChjLGEsZSl9ZnVuY3Rpb24gX3plcm9QYWRkaW5nT2ZTaWduYXR1cmUoZSxkKXt2YXIgYz1cIlwiO3ZhciBhPWQvNC1lLmxlbmd0aDtmb3IodmFyIGI9MDtiPGE7YisrKXtjPWMrXCIwXCJ9cmV0dXJuIGMrZX1SU0FLZXkucHJvdG90eXBlLnNpZ249ZnVuY3Rpb24oZCxhKXt2YXIgYj1mdW5jdGlvbihlKXtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5oYXNoU3RyaW5nKGUsYSl9O3ZhciBjPWIoZCk7cmV0dXJuIHRoaXMuc2lnbldpdGhNZXNzYWdlSGFzaChjLGEpfTtSU0FLZXkucHJvdG90eXBlLnNpZ25XaXRoTWVzc2FnZUhhc2g9ZnVuY3Rpb24oZSxjKXt2YXIgZj1LSlVSLmNyeXB0by5VdGlsLmdldFBhZGRlZERpZ2VzdEluZm9IZXgoZSxjLHRoaXMubi5iaXRMZW5ndGgoKSk7dmFyIGI9cGFyc2VCaWdJbnQoZiwxNik7dmFyIGQ9dGhpcy5kb1ByaXZhdGUoYik7dmFyIGE9ZC50b1N0cmluZygxNik7cmV0dXJuIF96ZXJvUGFkZGluZ09mU2lnbmF0dXJlKGEsdGhpcy5uLmJpdExlbmd0aCgpKX07ZnVuY3Rpb24gcHNzX21nZjFfc3RyKGMsYSxlKXt2YXIgYj1cIlwiLGQ9MDt3aGlsZShiLmxlbmd0aDxhKXtiKz1oZXh0b3JzdHIoZShyc3RydG9oZXgoYytTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxbKGQmNDI3ODE5MDA4MCk+PjI0LChkJjE2NzExNjgwKT4+MTYsKGQmNjUyODApPj44LGQmMjU1XSkpKSk7ZCs9MX1yZXR1cm4gYn1SU0FLZXkucHJvdG90eXBlLnNpZ25QU1M9ZnVuY3Rpb24oZSxhLGQpe3ZhciBjPWZ1bmN0aW9uKGYpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hIZXgoZixhKX07dmFyIGI9Yyhyc3RydG9oZXgoZSkpO2lmKGQ9PT11bmRlZmluZWQpe2Q9LTF9cmV0dXJuIHRoaXMuc2lnbldpdGhNZXNzYWdlSGFzaFBTUyhiLGEsZCl9O1JTQUtleS5wcm90b3R5cGUuc2lnbldpdGhNZXNzYWdlSGFzaFBTUz1mdW5jdGlvbihsLGEsayl7dmFyIGI9aGV4dG9yc3RyKGwpO3ZhciBnPWIubGVuZ3RoO3ZhciBtPXRoaXMubi5iaXRMZW5ndGgoKS0xO3ZhciBjPU1hdGguY2VpbChtLzgpO3ZhciBkO3ZhciBvPWZ1bmN0aW9uKGkpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hIZXgoaSxhKX07aWYoaz09PS0xfHxrPT09dW5kZWZpbmVkKXtrPWd9ZWxzZXtpZihrPT09LTIpe2s9Yy1nLTJ9ZWxzZXtpZihrPC0yKXt0aHJvd1wiaW52YWxpZCBzYWx0IGxlbmd0aFwifX19aWYoYzwoZytrKzIpKXt0aHJvd1wiZGF0YSB0b28gbG9uZ1wifXZhciBmPVwiXCI7aWYoaz4wKXtmPW5ldyBBcnJheShrKTtuZXcgU2VjdXJlUmFuZG9tKCkubmV4dEJ5dGVzKGYpO2Y9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsZil9dmFyIG49aGV4dG9yc3RyKG8ocnN0cnRvaGV4KFwiXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFwiK2IrZikpKTt2YXIgaj1bXTtmb3IoZD0wO2Q8Yy1rLWctMjtkKz0xKXtqW2RdPTB9dmFyIGU9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsaikrXCJcXHgwMVwiK2Y7dmFyIGg9cHNzX21nZjFfc3RyKG4sZS5sZW5ndGgsbyk7dmFyIHE9W107Zm9yKGQ9MDtkPGUubGVuZ3RoO2QrPTEpe3FbZF09ZS5jaGFyQ29kZUF0KGQpXmguY2hhckNvZGVBdChkKX12YXIgcD0oNjUyODA+Pig4KmMtbSkpJjI1NTtxWzBdJj1+cDtmb3IoZD0wO2Q8ZztkKyspe3EucHVzaChuLmNoYXJDb2RlQXQoZCkpfXEucHVzaCgxODgpO3JldHVybiBfemVyb1BhZGRpbmdPZlNpZ25hdHVyZSh0aGlzLmRvUHJpdmF0ZShuZXcgQmlnSW50ZWdlcihxKSkudG9TdHJpbmcoMTYpLHRoaXMubi5iaXRMZW5ndGgoKSl9O2Z1bmN0aW9uIF9yc2FzaWduX2dldERlY3J5cHRTaWduYXR1cmVCSShhLGQsYyl7dmFyIGI9bmV3IFJTQUtleSgpO2Iuc2V0UHVibGljKGQsYyk7dmFyIGU9Yi5kb1B1YmxpYyhhKTtyZXR1cm4gZX1mdW5jdGlvbiBfcnNhc2lnbl9nZXRIZXhEaWdlc3RJbmZvRnJvbVNpZyhhLGMsYil7dmFyIGU9X3JzYXNpZ25fZ2V0RGVjcnlwdFNpZ25hdHVyZUJJKGEsYyxiKTt2YXIgZD1lLnRvU3RyaW5nKDE2KS5yZXBsYWNlKC9eMWYrMDAvLFwiXCIpO3JldHVybiBkfWZ1bmN0aW9uIF9yc2FzaWduX2dldEFsZ05hbWVBbmRIYXNoRnJvbUhleERpc2dlc3RJbmZvKGYpe2Zvcih2YXIgZSBpbiBLSlVSLmNyeXB0by5VdGlsLkRJR0VTVElORk9IRUFEKXt2YXIgZD1LSlVSLmNyeXB0by5VdGlsLkRJR0VTVElORk9IRUFEW2VdO3ZhciBiPWQubGVuZ3RoO2lmKGYuc3Vic3RyaW5nKDAsYik9PWQpe3ZhciBjPVtlLGYuc3Vic3RyaW5nKGIpXTtyZXR1cm4gY319cmV0dXJuW119UlNBS2V5LnByb3RvdHlwZS52ZXJpZnk9ZnVuY3Rpb24oZixqKXtqPWoucmVwbGFjZShfUkVfSEVYREVDT05MWSxcIlwiKTtqPWoucmVwbGFjZSgvWyBcXG5dKy9nLFwiXCIpO3ZhciBiPXBhcnNlQmlnSW50KGosMTYpO2lmKGIuYml0TGVuZ3RoKCk+dGhpcy5uLmJpdExlbmd0aCgpKXtyZXR1cm4gMH12YXIgaT10aGlzLmRvUHVibGljKGIpO3ZhciBlPWkudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sXCJcIik7dmFyIGc9X3JzYXNpZ25fZ2V0QWxnTmFtZUFuZEhhc2hGcm9tSGV4RGlzZ2VzdEluZm8oZSk7aWYoZy5sZW5ndGg9PTApe3JldHVybiBmYWxzZX12YXIgZD1nWzBdO3ZhciBoPWdbMV07dmFyIGE9ZnVuY3Rpb24oayl7cmV0dXJuIEtKVVIuY3J5cHRvLlV0aWwuaGFzaFN0cmluZyhrLGQpfTt2YXIgYz1hKGYpO3JldHVybihoPT1jKX07UlNBS2V5LnByb3RvdHlwZS52ZXJpZnlXaXRoTWVzc2FnZUhhc2g9ZnVuY3Rpb24oZSxhKXthPWEucmVwbGFjZShfUkVfSEVYREVDT05MWSxcIlwiKTthPWEucmVwbGFjZSgvWyBcXG5dKy9nLFwiXCIpO3ZhciBiPXBhcnNlQmlnSW50KGEsMTYpO2lmKGIuYml0TGVuZ3RoKCk+dGhpcy5uLmJpdExlbmd0aCgpKXtyZXR1cm4gMH12YXIgaD10aGlzLmRvUHVibGljKGIpO3ZhciBnPWgudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sXCJcIik7dmFyIGM9X3JzYXNpZ25fZ2V0QWxnTmFtZUFuZEhhc2hGcm9tSGV4RGlzZ2VzdEluZm8oZyk7aWYoYy5sZW5ndGg9PTApe3JldHVybiBmYWxzZX12YXIgZD1jWzBdO3ZhciBmPWNbMV07cmV0dXJuKGY9PWUpfTtSU0FLZXkucHJvdG90eXBlLnZlcmlmeVBTUz1mdW5jdGlvbihjLGIsYSxmKXt2YXIgZT1mdW5jdGlvbihnKXtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5oYXNoSGV4KGcsYSl9O3ZhciBkPWUocnN0cnRvaGV4KGMpKTtpZihmPT09dW5kZWZpbmVkKXtmPS0xfXJldHVybiB0aGlzLnZlcmlmeVdpdGhNZXNzYWdlSGFzaFBTUyhkLGIsYSxmKX07UlNBS2V5LnByb3RvdHlwZS52ZXJpZnlXaXRoTWVzc2FnZUhhc2hQU1M9ZnVuY3Rpb24oZixzLGwsYyl7dmFyIGs9bmV3IEJpZ0ludGVnZXIocywxNik7aWYoay5iaXRMZW5ndGgoKT50aGlzLm4uYml0TGVuZ3RoKCkpe3JldHVybiBmYWxzZX12YXIgcj1mdW5jdGlvbihpKXtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5oYXNoSGV4KGksbCl9O3ZhciBqPWhleHRvcnN0cihmKTt2YXIgaD1qLmxlbmd0aDt2YXIgZz10aGlzLm4uYml0TGVuZ3RoKCktMTt2YXIgbT1NYXRoLmNlaWwoZy84KTt2YXIgcTtpZihjPT09LTF8fGM9PT11bmRlZmluZWQpe2M9aH1lbHNle2lmKGM9PT0tMil7Yz1tLWgtMn1lbHNle2lmKGM8LTIpe3Rocm93XCJpbnZhbGlkIHNhbHQgbGVuZ3RoXCJ9fX1pZihtPChoK2MrMikpe3Rocm93XCJkYXRhIHRvbyBsb25nXCJ9dmFyIGE9dGhpcy5kb1B1YmxpYyhrKS50b0J5dGVBcnJheSgpO2ZvcihxPTA7cTxhLmxlbmd0aDtxKz0xKXthW3FdJj0yNTV9d2hpbGUoYS5sZW5ndGg8bSl7YS51bnNoaWZ0KDApfWlmKGFbbS0xXSE9PTE4OCl7dGhyb3dcImVuY29kZWQgbWVzc2FnZSBkb2VzIG5vdCBlbmQgaW4gMHhiY1wifWE9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsYSk7dmFyIGQ9YS5zdWJzdHIoMCxtLWgtMSk7dmFyIGU9YS5zdWJzdHIoZC5sZW5ndGgsaCk7dmFyIHA9KDY1MjgwPj4oOCptLWcpKSYyNTU7aWYoKGQuY2hhckNvZGVBdCgwKSZwKSE9PTApe3Rocm93XCJiaXRzIGJleW9uZCBrZXlzaXplIG5vdCB6ZXJvXCJ9dmFyIG49cHNzX21nZjFfc3RyKGUsZC5sZW5ndGgscik7dmFyIG89W107Zm9yKHE9MDtxPGQubGVuZ3RoO3ErPTEpe29bcV09ZC5jaGFyQ29kZUF0KHEpXm4uY2hhckNvZGVBdChxKX1vWzBdJj1+cDt2YXIgYj1tLWgtYy0yO2ZvcihxPTA7cTxiO3ErPTEpe2lmKG9bcV0hPT0wKXt0aHJvd1wibGVmdG1vc3Qgb2N0ZXRzIG5vdCB6ZXJvXCJ9fWlmKG9bYl0hPT0xKXt0aHJvd1wiMHgwMSBtYXJrZXIgbm90IGZvdW5kXCJ9cmV0dXJuIGU9PT1oZXh0b3JzdHIocihyc3RydG9oZXgoXCJcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXCIraitTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxvLnNsaWNlKC1jKSkpKSl9O1JTQUtleS5TQUxUX0xFTl9ITEVOPS0xO1JTQUtleS5TQUxUX0xFTl9NQVg9LTI7UlNBS2V5LlNBTFRfTEVOX1JFQ09WRVI9LTI7XG5mdW5jdGlvbiBYNTA5KCl7dmFyIGs9QVNOMUhFWCxqPWsuZ2V0Q2hpbGRJZHgsaD1rLmdldFYsYj1rLmdldFRMVixmPWsuZ2V0VmJ5TGlzdCxjPWsuZ2V0VExWYnlMaXN0LGc9ay5nZXRJZHhieUxpc3QsZD1rLmdldFZpZHgsaT1rLm9pZG5hbWUsYT1YNTA5LGU9cGVtdG9oZXg7dGhpcy5oZXg9bnVsbDt0aGlzLnZlcnNpb249MDt0aGlzLmZvZmZzZXQ9MDt0aGlzLmFFeHRJbmZvPW51bGw7dGhpcy5nZXRWZXJzaW9uPWZ1bmN0aW9uKCl7aWYodGhpcy5oZXg9PT1udWxsfHx0aGlzLnZlcnNpb24hPT0wKXtyZXR1cm4gdGhpcy52ZXJzaW9ufWlmKGModGhpcy5oZXgsMCxbMCwwXSkhPT1cImEwMDMwMjAxMDJcIil7dGhpcy52ZXJzaW9uPTE7dGhpcy5mb2Zmc2V0PS0xO3JldHVybiAxfXRoaXMudmVyc2lvbj0zO3JldHVybiAzfTt0aGlzLmdldFNlcmlhbE51bWJlckhleD1mdW5jdGlvbigpe3JldHVybiBmKHRoaXMuaGV4LDAsWzAsMSt0aGlzLmZvZmZzZXRdLFwiMDJcIil9O3RoaXMuZ2V0U2lnbmF0dXJlQWxnb3JpdGhtRmllbGQ9ZnVuY3Rpb24oKXtyZXR1cm4gaShmKHRoaXMuaGV4LDAsWzAsMit0aGlzLmZvZmZzZXQsMF0sXCIwNlwiKSl9O3RoaXMuZ2V0SXNzdWVySGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGModGhpcy5oZXgsMCxbMCwzK3RoaXMuZm9mZnNldF0sXCIzMFwiKX07dGhpcy5nZXRJc3N1ZXJTdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gYS5oZXgyZG4odGhpcy5nZXRJc3N1ZXJIZXgoKSl9O3RoaXMuZ2V0U3ViamVjdEhleD1mdW5jdGlvbigpe3JldHVybiBjKHRoaXMuaGV4LDAsWzAsNSt0aGlzLmZvZmZzZXRdLFwiMzBcIil9O3RoaXMuZ2V0U3ViamVjdFN0cmluZz1mdW5jdGlvbigpe3JldHVybiBhLmhleDJkbih0aGlzLmdldFN1YmplY3RIZXgoKSl9O3RoaXMuZ2V0Tm90QmVmb3JlPWZ1bmN0aW9uKCl7dmFyIGw9Zih0aGlzLmhleCwwLFswLDQrdGhpcy5mb2Zmc2V0LDBdKTtsPWwucmVwbGFjZSgvKC4uKS9nLFwiJSQxXCIpO2w9ZGVjb2RlVVJJQ29tcG9uZW50KGwpO3JldHVybiBsfTt0aGlzLmdldE5vdEFmdGVyPWZ1bmN0aW9uKCl7dmFyIGw9Zih0aGlzLmhleCwwLFswLDQrdGhpcy5mb2Zmc2V0LDFdKTtsPWwucmVwbGFjZSgvKC4uKS9nLFwiJSQxXCIpO2w9ZGVjb2RlVVJJQ29tcG9uZW50KGwpO3JldHVybiBsfTt0aGlzLmdldFB1YmxpY0tleUhleD1mdW5jdGlvbigpe3JldHVybiBrLmdldFRMVmJ5TGlzdCh0aGlzLmhleCwwLFswLDYrdGhpcy5mb2Zmc2V0XSxcIjMwXCIpfTt0aGlzLmdldFB1YmxpY0tleUlkeD1mdW5jdGlvbigpe3JldHVybiBnKHRoaXMuaGV4LDAsWzAsNit0aGlzLmZvZmZzZXRdLFwiMzBcIil9O3RoaXMuZ2V0UHVibGljS2V5Q29udGVudElkeD1mdW5jdGlvbigpe3ZhciBsPXRoaXMuZ2V0UHVibGljS2V5SWR4KCk7cmV0dXJuIGcodGhpcy5oZXgsbCxbMSwwXSxcIjMwXCIpfTt0aGlzLmdldFB1YmxpY0tleT1mdW5jdGlvbigpe3JldHVybiBLRVlVVElMLmdldEtleSh0aGlzLmdldFB1YmxpY0tleUhleCgpLG51bGwsXCJwa2NzOHB1YlwiKX07dGhpcy5nZXRTaWduYXR1cmVBbGdvcml0aG1OYW1lPWZ1bmN0aW9uKCl7cmV0dXJuIGkoZih0aGlzLmhleCwwLFsxLDBdLFwiMDZcIikpfTt0aGlzLmdldFNpZ25hdHVyZVZhbHVlSGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcy5oZXgsMCxbMl0sXCIwM1wiLHRydWUpfTt0aGlzLnZlcmlmeVNpZ25hdHVyZT1mdW5jdGlvbihuKXt2YXIgbz10aGlzLmdldFNpZ25hdHVyZUFsZ29yaXRobU5hbWUoKTt2YXIgbD10aGlzLmdldFNpZ25hdHVyZVZhbHVlSGV4KCk7dmFyIG09Yyh0aGlzLmhleCwwLFswXSxcIjMwXCIpO3ZhciBwPW5ldyBLSlVSLmNyeXB0by5TaWduYXR1cmUoe2FsZzpvfSk7cC5pbml0KG4pO3AudXBkYXRlSGV4KG0pO3JldHVybiBwLnZlcmlmeShsKX07dGhpcy5wYXJzZUV4dD1mdW5jdGlvbigpe2lmKHRoaXMudmVyc2lvbiE9PTMpe3JldHVybiAtMX12YXIgcD1nKHRoaXMuaGV4LDAsWzAsNywwXSxcIjMwXCIpO3ZhciBtPWoodGhpcy5oZXgscCk7dGhpcy5hRXh0SW5mbz1uZXcgQXJyYXkoKTtmb3IodmFyIG49MDtuPG0ubGVuZ3RoO24rKyl7dmFyIHE9e307cS5jcml0aWNhbD1mYWxzZTt2YXIgbD1qKHRoaXMuaGV4LG1bbl0pO3ZhciByPTA7aWYobC5sZW5ndGg9PT0zKXtxLmNyaXRpY2FsPXRydWU7cj0xfXEub2lkPWsuaGV4dG9vaWRzdHIoZih0aGlzLmhleCxtW25dLFswXSxcIjA2XCIpKTt2YXIgbz1nKHRoaXMuaGV4LG1bbl0sWzErcl0pO3EudmlkeD1kKHRoaXMuaGV4LG8pO3RoaXMuYUV4dEluZm8ucHVzaChxKX19O3RoaXMuZ2V0RXh0SW5mbz1mdW5jdGlvbihuKXt2YXIgbD10aGlzLmFFeHRJbmZvO3ZhciBvPW47aWYoIW4ubWF0Y2goL15bMC05Ll0rJC8pKXtvPUtKVVIuYXNuMS54NTA5Lk9JRC5uYW1lMm9pZChuKX1pZihvPT09XCJcIil7cmV0dXJuIHVuZGVmaW5lZH1mb3IodmFyIG09MDttPGwubGVuZ3RoO20rKyl7aWYobFttXS5vaWQ9PT1vKXtyZXR1cm4gbFttXX19cmV0dXJuIHVuZGVmaW5lZH07dGhpcy5nZXRFeHRCYXNpY0NvbnN0cmFpbnRzPWZ1bmN0aW9uKCl7dmFyIG49dGhpcy5nZXRFeHRJbmZvKFwiYmFzaWNDb25zdHJhaW50c1wiKTtpZihuPT09dW5kZWZpbmVkKXtyZXR1cm4gbn12YXIgbD1oKHRoaXMuaGV4LG4udmlkeCk7aWYobD09PVwiXCIpe3JldHVybnt9fWlmKGw9PT1cIjAxMDFmZlwiKXtyZXR1cm57Y0E6dHJ1ZX19aWYobC5zdWJzdHIoMCw4KT09PVwiMDEwMWZmMDJcIil7dmFyIG89aChsLDYpO3ZhciBtPXBhcnNlSW50KG8sMTYpO3JldHVybntjQTp0cnVlLHBhdGhMZW46bX19dGhyb3dcImJhc2ljQ29uc3RyYWludHMgcGFyc2UgZXJyb3JcIn07dGhpcy5nZXRFeHRLZXlVc2FnZUJpbj1mdW5jdGlvbigpe3ZhciBvPXRoaXMuZ2V0RXh0SW5mbyhcImtleVVzYWdlXCIpO2lmKG89PT11bmRlZmluZWQpe3JldHVyblwiXCJ9dmFyIG09aCh0aGlzLmhleCxvLnZpZHgpO2lmKG0ubGVuZ3RoJTIhPTB8fG0ubGVuZ3RoPD0yKXt0aHJvd1wibWFsZm9ybWVkIGtleSB1c2FnZSB2YWx1ZVwifXZhciBsPXBhcnNlSW50KG0uc3Vic3RyKDAsMikpO3ZhciBuPXBhcnNlSW50KG0uc3Vic3RyKDIpLDE2KS50b1N0cmluZygyKTtyZXR1cm4gbi5zdWJzdHIoMCxuLmxlbmd0aC1sKX07dGhpcy5nZXRFeHRLZXlVc2FnZVN0cmluZz1mdW5jdGlvbigpe3ZhciBuPXRoaXMuZ2V0RXh0S2V5VXNhZ2VCaW4oKTt2YXIgbD1uZXcgQXJyYXkoKTtmb3IodmFyIG09MDttPG4ubGVuZ3RoO20rKyl7aWYobi5zdWJzdHIobSwxKT09XCIxXCIpe2wucHVzaChYNTA5LktFWVVTQUdFX05BTUVbbV0pfX1yZXR1cm4gbC5qb2luKFwiLFwiKX07dGhpcy5nZXRFeHRTdWJqZWN0S2V5SWRlbnRpZmllcj1mdW5jdGlvbigpe3ZhciBsPXRoaXMuZ2V0RXh0SW5mbyhcInN1YmplY3RLZXlJZGVudGlmaWVyXCIpO2lmKGw9PT11bmRlZmluZWQpe3JldHVybiBsfXJldHVybiBoKHRoaXMuaGV4LGwudmlkeCl9O3RoaXMuZ2V0RXh0QXV0aG9yaXR5S2V5SWRlbnRpZmllcj1mdW5jdGlvbigpe3ZhciBwPXRoaXMuZ2V0RXh0SW5mbyhcImF1dGhvcml0eUtleUlkZW50aWZpZXJcIik7aWYocD09PXVuZGVmaW5lZCl7cmV0dXJuIHB9dmFyIGw9e307dmFyIG89Yih0aGlzLmhleCxwLnZpZHgpO3ZhciBtPWoobywwKTtmb3IodmFyIG49MDtuPG0ubGVuZ3RoO24rKyl7aWYoby5zdWJzdHIobVtuXSwyKT09PVwiODBcIil7bC5raWQ9aChvLG1bbl0pfX1yZXR1cm4gbH07dGhpcy5nZXRFeHRFeHRLZXlVc2FnZU5hbWU9ZnVuY3Rpb24oKXt2YXIgcD10aGlzLmdldEV4dEluZm8oXCJleHRLZXlVc2FnZVwiKTtpZihwPT09dW5kZWZpbmVkKXtyZXR1cm4gcH12YXIgbD1uZXcgQXJyYXkoKTt2YXIgbz1iKHRoaXMuaGV4LHAudmlkeCk7aWYobz09PVwiXCIpe3JldHVybiBsfXZhciBtPWoobywwKTtmb3IodmFyIG49MDtuPG0ubGVuZ3RoO24rKyl7bC5wdXNoKGkoaChvLG1bbl0pKSl9cmV0dXJuIGx9O3RoaXMuZ2V0RXh0U3ViamVjdEFsdE5hbWU9ZnVuY3Rpb24oKXt2YXIgbT10aGlzLmdldEV4dFN1YmplY3RBbHROYW1lMigpO3ZhciBsPW5ldyBBcnJheSgpO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXtpZihtW25dWzBdPT09XCJETlNcIil7bC5wdXNoKG1bbl1bMV0pfX1yZXR1cm4gbH07dGhpcy5nZXRFeHRTdWJqZWN0QWx0TmFtZTI9ZnVuY3Rpb24oKXt2YXIgcCxzLHI7dmFyIHE9dGhpcy5nZXRFeHRJbmZvKFwic3ViamVjdEFsdE5hbWVcIik7aWYocT09PXVuZGVmaW5lZCl7cmV0dXJuIHF9dmFyIGw9bmV3IEFycmF5KCk7dmFyIG89Yih0aGlzLmhleCxxLnZpZHgpO3ZhciBtPWoobywwKTtmb3IodmFyIG49MDtuPG0ubGVuZ3RoO24rKyl7cj1vLnN1YnN0cihtW25dLDIpO3A9aChvLG1bbl0pO2lmKHI9PT1cIjgxXCIpe3M9aGV4dG91dGY4KHApO2wucHVzaChbXCJNQUlMXCIsc10pfWlmKHI9PT1cIjgyXCIpe3M9aGV4dG91dGY4KHApO2wucHVzaChbXCJETlNcIixzXSl9aWYocj09PVwiODRcIil7cz1YNTA5LmhleDJkbihwLDApO2wucHVzaChbXCJETlwiLHNdKX1pZihyPT09XCI4NlwiKXtzPWhleHRvdXRmOChwKTtsLnB1c2goW1wiVVJJXCIsc10pfWlmKHI9PT1cIjg3XCIpe3M9aGV4dG9pcChwKTtsLnB1c2goW1wiSVBcIixzXSl9fXJldHVybiBsfTt0aGlzLmdldEV4dENSTERpc3RyaWJ1dGlvblBvaW50c1VSST1mdW5jdGlvbigpe3ZhciBxPXRoaXMuZ2V0RXh0SW5mbyhcImNSTERpc3RyaWJ1dGlvblBvaW50c1wiKTtpZihxPT09dW5kZWZpbmVkKXtyZXR1cm4gcX12YXIgbD1uZXcgQXJyYXkoKTt2YXIgbT1qKHRoaXMuaGV4LHEudmlkeCk7Zm9yKHZhciBvPTA7bzxtLmxlbmd0aDtvKyspe3RyeXt2YXIgcj1mKHRoaXMuaGV4LG1bb10sWzAsMCwwXSxcIjg2XCIpO3ZhciBwPWhleHRvdXRmOChyKTtsLnB1c2gocCl9Y2F0Y2gobil7fX1yZXR1cm4gbH07dGhpcy5nZXRFeHRBSUFJbmZvPWZ1bmN0aW9uKCl7dmFyIHA9dGhpcy5nZXRFeHRJbmZvKFwiYXV0aG9yaXR5SW5mb0FjY2Vzc1wiKTtpZihwPT09dW5kZWZpbmVkKXtyZXR1cm4gcH12YXIgbD17b2NzcDpbXSxjYWlzc3VlcjpbXX07dmFyIG09aih0aGlzLmhleCxwLnZpZHgpO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXt2YXIgcT1mKHRoaXMuaGV4LG1bbl0sWzBdLFwiMDZcIik7dmFyIG89Zih0aGlzLmhleCxtW25dLFsxXSxcIjg2XCIpO2lmKHE9PT1cIjJiMDYwMTA1MDUwNzMwMDFcIil7bC5vY3NwLnB1c2goaGV4dG91dGY4KG8pKX1pZihxPT09XCIyYjA2MDEwNTA1MDczMDAyXCIpe2wuY2Fpc3N1ZXIucHVzaChoZXh0b3V0ZjgobykpfX1yZXR1cm4gbH07dGhpcy5nZXRFeHRDZXJ0aWZpY2F0ZVBvbGljaWVzPWZ1bmN0aW9uKCl7dmFyIG89dGhpcy5nZXRFeHRJbmZvKFwiY2VydGlmaWNhdGVQb2xpY2llc1wiKTtpZihvPT09dW5kZWZpbmVkKXtyZXR1cm4gb312YXIgbD1iKHRoaXMuaGV4LG8udmlkeCk7dmFyIHU9W107dmFyIHM9aihsLDApO2Zvcih2YXIgcj0wO3I8cy5sZW5ndGg7cisrKXt2YXIgdD17fTt2YXIgbj1qKGwsc1tyXSk7dC5pZD1pKGgobCxuWzBdKSk7aWYobi5sZW5ndGg9PT0yKXt2YXIgbT1qKGwsblsxXSk7Zm9yKHZhciBxPTA7cTxtLmxlbmd0aDtxKyspe3ZhciBwPWYobCxtW3FdLFswXSxcIjA2XCIpO2lmKHA9PT1cIjJiMDYwMTA1MDUwNzAyMDFcIil7dC5jcHM9aGV4dG91dGY4KGYobCxtW3FdLFsxXSkpfWVsc2V7aWYocD09PVwiMmIwNjAxMDUwNTA3MDIwMlwiKXt0LnVub3RpY2U9aGV4dG91dGY4KGYobCxtW3FdLFsxLDBdKSl9fX19dS5wdXNoKHQpfXJldHVybiB1fTt0aGlzLnJlYWRDZXJ0UEVNPWZ1bmN0aW9uKGwpe3RoaXMucmVhZENlcnRIZXgoZShsKSl9O3RoaXMucmVhZENlcnRIZXg9ZnVuY3Rpb24obCl7dGhpcy5oZXg9bDt0aGlzLmdldFZlcnNpb24oKTt0cnl7Zyh0aGlzLmhleCwwLFswLDddLFwiYTNcIik7dGhpcy5wYXJzZUV4dCgpfWNhdGNoKG0pe319O3RoaXMuZ2V0SW5mbz1mdW5jdGlvbigpe3ZhciBtPVg1MDk7dmFyIEIsdSx6O0I9XCJCYXNpYyBGaWVsZHNcXG5cIjtCKz1cIiAgc2VyaWFsIG51bWJlcjogXCIrdGhpcy5nZXRTZXJpYWxOdW1iZXJIZXgoKStcIlxcblwiO0IrPVwiICBzaWduYXR1cmUgYWxnb3JpdGhtOiBcIit0aGlzLmdldFNpZ25hdHVyZUFsZ29yaXRobUZpZWxkKCkrXCJcXG5cIjtCKz1cIiAgaXNzdWVyOiBcIit0aGlzLmdldElzc3VlclN0cmluZygpK1wiXFxuXCI7Qis9XCIgIG5vdEJlZm9yZTogXCIrdGhpcy5nZXROb3RCZWZvcmUoKStcIlxcblwiO0IrPVwiICBub3RBZnRlcjogXCIrdGhpcy5nZXROb3RBZnRlcigpK1wiXFxuXCI7Qis9XCIgIHN1YmplY3Q6IFwiK3RoaXMuZ2V0U3ViamVjdFN0cmluZygpK1wiXFxuXCI7Qis9XCIgIHN1YmplY3QgcHVibGljIGtleSBpbmZvOiBcXG5cIjt1PXRoaXMuZ2V0UHVibGljS2V5KCk7Qis9XCIgICAga2V5IGFsZ29yaXRobTogXCIrdS50eXBlK1wiXFxuXCI7aWYodS50eXBlPT09XCJSU0FcIil7Qis9XCIgICAgbj1cIitoZXh0b3Bvc2hleCh1Lm4udG9TdHJpbmcoMTYpKS5zdWJzdHIoMCwxNikrXCIuLi5cXG5cIjtCKz1cIiAgICBlPVwiK2hleHRvcG9zaGV4KHUuZS50b1N0cmluZygxNikpK1wiXFxuXCJ9ej10aGlzLmFFeHRJbmZvO2lmKHohPT11bmRlZmluZWQmJnohPT1udWxsKXtCKz1cIlg1MDl2MyBFeHRlbnNpb25zOlxcblwiO2Zvcih2YXIgcj0wO3I8ei5sZW5ndGg7cisrKXt2YXIgbj16W3JdO3ZhciBBPUtKVVIuYXNuMS54NTA5Lk9JRC5vaWQybmFtZShuLm9pZCk7aWYoQT09PVwiXCIpe0E9bi5vaWR9dmFyIHg9XCJcIjtpZihuLmNyaXRpY2FsPT09dHJ1ZSl7eD1cIkNSSVRJQ0FMXCJ9Qis9XCIgIFwiK0ErXCIgXCIreCtcIjpcXG5cIjtpZihBPT09XCJiYXNpY0NvbnN0cmFpbnRzXCIpe3ZhciB2PXRoaXMuZ2V0RXh0QmFzaWNDb25zdHJhaW50cygpO2lmKHYuY0E9PT11bmRlZmluZWQpe0IrPVwiICAgIHt9XFxuXCJ9ZWxzZXtCKz1cIiAgICBjQT10cnVlXCI7aWYodi5wYXRoTGVuIT09dW5kZWZpbmVkKXtCKz1cIiwgcGF0aExlbj1cIit2LnBhdGhMZW59Qis9XCJcXG5cIn19ZWxzZXtpZihBPT09XCJrZXlVc2FnZVwiKXtCKz1cIiAgICBcIit0aGlzLmdldEV4dEtleVVzYWdlU3RyaW5nKCkrXCJcXG5cIn1lbHNle2lmKEE9PT1cInN1YmplY3RLZXlJZGVudGlmaWVyXCIpe0IrPVwiICAgIFwiK3RoaXMuZ2V0RXh0U3ViamVjdEtleUlkZW50aWZpZXIoKStcIlxcblwifWVsc2V7aWYoQT09PVwiYXV0aG9yaXR5S2V5SWRlbnRpZmllclwiKXt2YXIgbD10aGlzLmdldEV4dEF1dGhvcml0eUtleUlkZW50aWZpZXIoKTtpZihsLmtpZCE9PXVuZGVmaW5lZCl7Qis9XCIgICAga2lkPVwiK2wua2lkK1wiXFxuXCJ9fWVsc2V7aWYoQT09PVwiZXh0S2V5VXNhZ2VcIil7dmFyIHc9dGhpcy5nZXRFeHRFeHRLZXlVc2FnZU5hbWUoKTtCKz1cIiAgICBcIit3LmpvaW4oXCIsIFwiKStcIlxcblwifWVsc2V7aWYoQT09PVwic3ViamVjdEFsdE5hbWVcIil7dmFyIHQ9dGhpcy5nZXRFeHRTdWJqZWN0QWx0TmFtZTIoKTtCKz1cIiAgICBcIit0K1wiXFxuXCJ9ZWxzZXtpZihBPT09XCJjUkxEaXN0cmlidXRpb25Qb2ludHNcIil7dmFyIHk9dGhpcy5nZXRFeHRDUkxEaXN0cmlidXRpb25Qb2ludHNVUkkoKTtCKz1cIiAgICBcIit5K1wiXFxuXCJ9ZWxzZXtpZihBPT09XCJhdXRob3JpdHlJbmZvQWNjZXNzXCIpe3ZhciBwPXRoaXMuZ2V0RXh0QUlBSW5mbygpO2lmKHAub2NzcCE9PXVuZGVmaW5lZCl7Qis9XCIgICAgb2NzcDogXCIrcC5vY3NwLmpvaW4oXCIsXCIpK1wiXFxuXCJ9aWYocC5jYWlzc3VlciE9PXVuZGVmaW5lZCl7Qis9XCIgICAgY2Fpc3N1ZXI6IFwiK3AuY2Fpc3N1ZXIuam9pbihcIixcIikrXCJcXG5cIn19ZWxzZXtpZihBPT09XCJjZXJ0aWZpY2F0ZVBvbGljaWVzXCIpe3ZhciBvPXRoaXMuZ2V0RXh0Q2VydGlmaWNhdGVQb2xpY2llcygpO2Zvcih2YXIgcT0wO3E8by5sZW5ndGg7cSsrKXtpZihvW3FdLmlkIT09dW5kZWZpbmVkKXtCKz1cIiAgICBwb2xpY3kgb2lkOiBcIitvW3FdLmlkK1wiXFxuXCJ9aWYob1txXS5jcHMhPT11bmRlZmluZWQpe0IrPVwiICAgIGNwczogXCIrb1txXS5jcHMrXCJcXG5cIn19fX19fX19fX19fX1CKz1cInNpZ25hdHVyZSBhbGdvcml0aG06IFwiK3RoaXMuZ2V0U2lnbmF0dXJlQWxnb3JpdGhtTmFtZSgpK1wiXFxuXCI7Qis9XCJzaWduYXR1cmU6IFwiK3RoaXMuZ2V0U2lnbmF0dXJlVmFsdWVIZXgoKS5zdWJzdHIoMCwxNikrXCIuLi5cXG5cIjtyZXR1cm4gQn19WDUwOS5oZXgyZG49ZnVuY3Rpb24oZixiKXtpZihiPT09dW5kZWZpbmVkKXtiPTB9aWYoZi5zdWJzdHIoYiwyKSE9PVwiMzBcIil7dGhyb3dcIm1hbGZvcm1lZCBETlwifXZhciBjPW5ldyBBcnJheSgpO3ZhciBkPUFTTjFIRVguZ2V0Q2hpbGRJZHgoZixiKTtmb3IodmFyIGU9MDtlPGQubGVuZ3RoO2UrKyl7Yy5wdXNoKFg1MDkuaGV4MnJkbihmLGRbZV0pKX1jPWMubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBhLnJlcGxhY2UoXCIvXCIsXCJcXFxcL1wiKX0pO3JldHVyblwiL1wiK2Muam9pbihcIi9cIil9O1g1MDkuaGV4MnJkbj1mdW5jdGlvbihmLGIpe2lmKGI9PT11bmRlZmluZWQpe2I9MH1pZihmLnN1YnN0cihiLDIpIT09XCIzMVwiKXt0aHJvd1wibWFsZm9ybWVkIFJETlwifXZhciBjPW5ldyBBcnJheSgpO3ZhciBkPUFTTjFIRVguZ2V0Q2hpbGRJZHgoZixiKTtmb3IodmFyIGU9MDtlPGQubGVuZ3RoO2UrKyl7Yy5wdXNoKFg1MDkuaGV4MmF0dHJUeXBlVmFsdWUoZixkW2VdKSl9Yz1jLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gYS5yZXBsYWNlKFwiK1wiLFwiXFxcXCtcIil9KTtyZXR1cm4gYy5qb2luKFwiK1wiKX07WDUwOS5oZXgyYXR0clR5cGVWYWx1ZT1mdW5jdGlvbihkLGkpe3ZhciBqPUFTTjFIRVg7dmFyIGg9ai5nZXRWO2lmKGk9PT11bmRlZmluZWQpe2k9MH1pZihkLnN1YnN0cihpLDIpIT09XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIGF0dHJpYnV0ZSB0eXBlIGFuZCB2YWx1ZVwifXZhciBnPWouZ2V0Q2hpbGRJZHgoZCxpKTtpZihnLmxlbmd0aCE9PTJ8fGQuc3Vic3RyKGdbMF0sMikhPT1cIjA2XCIpe1wibWFsZm9ybWVkIGF0dHJpYnV0ZSB0eXBlIGFuZCB2YWx1ZVwifXZhciBiPWgoZCxnWzBdKTt2YXIgZj1LSlVSLmFzbjEuQVNOMVV0aWwub2lkSGV4VG9JbnQoYik7dmFyIGU9S0pVUi5hc24xLng1MDkuT0lELm9pZDJhdHlwZShmKTt2YXIgYT1oKGQsZ1sxXSk7dmFyIGM9aGV4dG9yc3RyKGEpO3JldHVybiBlK1wiPVwiK2N9O1g1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRIZXg9ZnVuY3Rpb24oYil7dmFyIGE9bmV3IFg1MDkoKTthLnJlYWRDZXJ0SGV4KGIpO3JldHVybiBhLmdldFB1YmxpY0tleSgpfTtYNTA5LmdldFB1YmxpY0tleUZyb21DZXJ0UEVNPWZ1bmN0aW9uKGIpe3ZhciBhPW5ldyBYNTA5KCk7YS5yZWFkQ2VydFBFTShiKTtyZXR1cm4gYS5nZXRQdWJsaWNLZXkoKX07WDUwOS5nZXRQdWJsaWNLZXlJbmZvUHJvcE9mQ2VydFBFTT1mdW5jdGlvbihjKXt2YXIgZT1BU04xSEVYO3ZhciBnPWUuZ2V0VmJ5TGlzdDt2YXIgYj17fTt2YXIgYSxmLGQ7Yi5hbGdwYXJhbT1udWxsO2E9bmV3IFg1MDkoKTthLnJlYWRDZXJ0UEVNKGMpO2Y9YS5nZXRQdWJsaWNLZXlIZXgoKTtiLmtleWhleD1nKGYsMCxbMV0sXCIwM1wiKS5zdWJzdHIoMik7Yi5hbGdvaWQ9ZyhmLDAsWzAsMF0sXCIwNlwiKTtpZihiLmFsZ29pZD09PVwiMmE4NjQ4Y2UzZDAyMDFcIil7Yi5hbGdwYXJhbT1nKGYsMCxbMCwxXSxcIjA2XCIpfXJldHVybiBifTtYNTA5LktFWVVTQUdFX05BTUU9W1wiZGlnaXRhbFNpZ25hdHVyZVwiLFwibm9uUmVwdWRpYXRpb25cIixcImtleUVuY2lwaGVybWVudFwiLFwiZGF0YUVuY2lwaGVybWVudFwiLFwia2V5QWdyZWVtZW50XCIsXCJrZXlDZXJ0U2lnblwiLFwiY1JMU2lnblwiLFwiZW5jaXBoZXJPbmx5XCIsXCJkZWNpcGhlck9ubHlcIl07XG5pZih0eXBlb2YgS0pVUj09XCJ1bmRlZmluZWRcInx8IUtKVVIpe0tKVVI9e319aWYodHlwZW9mIEtKVVIuandzPT1cInVuZGVmaW5lZFwifHwhS0pVUi5qd3Mpe0tKVVIuandzPXt9fUtKVVIuandzLkpXUz1mdW5jdGlvbigpe3ZhciBiPUtKVVIsYT1iLmp3cy5KV1MsYz1hLmlzU2FmZUpTT05TdHJpbmc7dGhpcy5wYXJzZUpXUz1mdW5jdGlvbihnLGope2lmKCh0aGlzLnBhcnNlZEpXUyE9PXVuZGVmaW5lZCkmJihqfHwodGhpcy5wYXJzZWRKV1Muc2lndmFsSCE9PXVuZGVmaW5lZCkpKXtyZXR1cm59dmFyIGk9Zy5tYXRjaCgvXihbXi5dKylcXC4oW14uXSspXFwuKFteLl0rKSQvKTtpZihpPT1udWxsKXt0aHJvd1wiSldTIHNpZ25hdHVyZSBpcyBub3QgYSBmb3JtIG9mICdIZWFkLlBheWxvYWQuU2lnVmFsdWUnLlwifXZhciBrPWlbMV07dmFyIGU9aVsyXTt2YXIgbD1pWzNdO3ZhciBuPWsrXCIuXCIrZTt0aGlzLnBhcnNlZEpXUz17fTt0aGlzLnBhcnNlZEpXUy5oZWFkQjY0VT1rO3RoaXMucGFyc2VkSldTLnBheWxvYWRCNjRVPWU7dGhpcy5wYXJzZWRKV1Muc2lndmFsQjY0VT1sO3RoaXMucGFyc2VkSldTLnNpPW47aWYoIWope3ZhciBoPWI2NHV0b2hleChsKTt2YXIgZj1wYXJzZUJpZ0ludChoLDE2KTt0aGlzLnBhcnNlZEpXUy5zaWd2YWxIPWg7dGhpcy5wYXJzZWRKV1Muc2lndmFsQkk9Zn12YXIgZD1iNjR1dG91dGY4KGspO3ZhciBtPWI2NHV0b3V0ZjgoZSk7dGhpcy5wYXJzZWRKV1MuaGVhZFM9ZDt0aGlzLnBhcnNlZEpXUy5wYXlsb2FkUz1tO2lmKCFjKGQsdGhpcy5wYXJzZWRKV1MsXCJoZWFkUFwiKSl7dGhyb3dcIm1hbGZvcm1lZCBKU09OIHN0cmluZyBmb3IgSldTIEhlYWQ6IFwiK2R9fX07S0pVUi5qd3MuSldTLnNpZ249ZnVuY3Rpb24oaSx2LHkseixhKXt2YXIgdz1LSlVSLG09dy5qd3MscT1tLkpXUyxnPXEucmVhZFNhZmVKU09OU3RyaW5nLHA9cS5pc1NhZmVKU09OU3RyaW5nLGQ9dy5jcnlwdG8saz1kLkVDRFNBLG89ZC5NYWMsYz1kLlNpZ25hdHVyZSx0PUpTT047dmFyIHMsaixuO2lmKHR5cGVvZiB2IT1cInN0cmluZ1wiJiZ0eXBlb2YgdiE9XCJvYmplY3RcIil7dGhyb3dcInNwSGVhZGVyIG11c3QgYmUgSlNPTiBzdHJpbmcgb3Igb2JqZWN0OiBcIit2fWlmKHR5cGVvZiB2PT1cIm9iamVjdFwiKXtqPXY7cz10LnN0cmluZ2lmeShqKX1pZih0eXBlb2Ygdj09XCJzdHJpbmdcIil7cz12O2lmKCFwKHMpKXt0aHJvd1wiSldTIEhlYWQgaXMgbm90IHNhZmUgSlNPTiBzdHJpbmc6IFwiK3N9aj1nKHMpfW49eTtpZih0eXBlb2YgeT09XCJvYmplY3RcIil7bj10LnN0cmluZ2lmeSh5KX1pZigoaT09XCJcInx8aT09bnVsbCkmJmouYWxnIT09dW5kZWZpbmVkKXtpPWouYWxnfWlmKChpIT1cIlwiJiZpIT1udWxsKSYmai5hbGc9PT11bmRlZmluZWQpe2ouYWxnPWk7cz10LnN0cmluZ2lmeShqKX1pZihpIT09ai5hbGcpe3Rocm93XCJhbGcgYW5kIHNIZWFkZXIuYWxnIGRvZXNuJ3QgbWF0Y2g6IFwiK2krXCIhPVwiK2ouYWxnfXZhciByPW51bGw7aWYocS5qd3NhbGcyc2lnYWxnW2ldPT09dW5kZWZpbmVkKXt0aHJvd1widW5zdXBwb3J0ZWQgYWxnIG5hbWU6IFwiK2l9ZWxzZXtyPXEuandzYWxnMnNpZ2FsZ1tpXX12YXIgZT11dGY4dG9iNjR1KHMpO3ZhciBsPXV0Zjh0b2I2NHUobik7dmFyIGI9ZStcIi5cIitsO3ZhciB4PVwiXCI7aWYoci5zdWJzdHIoMCw0KT09XCJIbWFjXCIpe2lmKHo9PT11bmRlZmluZWQpe3Rocm93XCJtYWMga2V5IHNoYWxsIGJlIHNwZWNpZmllZCBmb3IgSFMqIGFsZ1wifXZhciBoPW5ldyBvKHthbGc6cixwcm92OlwiY3J5cHRvanNcIixwYXNzOnp9KTtoLnVwZGF0ZVN0cmluZyhiKTt4PWguZG9GaW5hbCgpfWVsc2V7aWYoci5pbmRleE9mKFwid2l0aEVDRFNBXCIpIT0tMSl7dmFyIGY9bmV3IGMoe2FsZzpyfSk7Zi5pbml0KHosYSk7Zi51cGRhdGVTdHJpbmcoYik7aEFTTjFTaWc9Zi5zaWduKCk7eD1LSlVSLmNyeXB0by5FQ0RTQS5hc24xU2lnVG9Db25jYXRTaWcoaEFTTjFTaWcpfWVsc2V7aWYociE9XCJub25lXCIpe3ZhciBmPW5ldyBjKHthbGc6cn0pO2YuaW5pdCh6LGEpO2YudXBkYXRlU3RyaW5nKGIpO3g9Zi5zaWduKCl9fX12YXIgdT1oZXh0b2I2NHUoeCk7cmV0dXJuIGIrXCIuXCIrdX07S0pVUi5qd3MuSldTLnZlcmlmeT1mdW5jdGlvbih3LEIsbil7dmFyIHg9S0pVUixxPXguandzLHQ9cS5KV1MsaT10LnJlYWRTYWZlSlNPTlN0cmluZyxlPXguY3J5cHRvLHA9ZS5FQ0RTQSxzPWUuTWFjLGQ9ZS5TaWduYXR1cmUsbTtpZih0eXBlb2YgUlNBS2V5IT09dW5kZWZpbmVkKXttPVJTQUtleX12YXIgeT13LnNwbGl0KFwiLlwiKTtpZih5Lmxlbmd0aCE9PTMpe3JldHVybiBmYWxzZX12YXIgZj15WzBdO3ZhciByPXlbMV07dmFyIGM9ZitcIi5cIityO3ZhciBBPWI2NHV0b2hleCh5WzJdKTt2YXIgbD1pKGI2NHV0b3V0ZjgoeVswXSkpO3ZhciBrPW51bGw7dmFyIHo9bnVsbDtpZihsLmFsZz09PXVuZGVmaW5lZCl7dGhyb3dcImFsZ29yaXRobSBub3Qgc3BlY2lmaWVkIGluIGhlYWRlclwifWVsc2V7az1sLmFsZzt6PWsuc3Vic3RyKDAsMil9aWYobiE9bnVsbCYmT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG4pPT09XCJbb2JqZWN0IEFycmF5XVwiJiZuLmxlbmd0aD4wKXt2YXIgYj1cIjpcIituLmpvaW4oXCI6XCIpK1wiOlwiO2lmKGIuaW5kZXhPZihcIjpcIitrK1wiOlwiKT09LTEpe3Rocm93XCJhbGdvcml0aG0gJ1wiK2srXCInIG5vdCBhY2NlcHRlZCBpbiB0aGUgbGlzdFwifX1pZihrIT1cIm5vbmVcIiYmQj09PW51bGwpe3Rocm93XCJrZXkgc2hhbGwgYmUgc3BlY2lmaWVkIHRvIHZlcmlmeS5cIn1pZih0eXBlb2YgQj09XCJzdHJpbmdcIiYmQi5pbmRleE9mKFwiLS0tLS1CRUdJTiBcIikhPS0xKXtCPUtFWVVUSUwuZ2V0S2V5KEIpfWlmKHo9PVwiUlNcInx8ej09XCJQU1wiKXtpZighKEIgaW5zdGFuY2VvZiBtKSl7dGhyb3dcImtleSBzaGFsbCBiZSBhIFJTQUtleSBvYmogZm9yIFJTKiBhbmQgUFMqIGFsZ3NcIn19aWYoej09XCJFU1wiKXtpZighKEIgaW5zdGFuY2VvZiBwKSl7dGhyb3dcImtleSBzaGFsbCBiZSBhIEVDRFNBIG9iaiBmb3IgRVMqIGFsZ3NcIn19aWYoaz09XCJub25lXCIpe312YXIgdT1udWxsO2lmKHQuandzYWxnMnNpZ2FsZ1tsLmFsZ109PT11bmRlZmluZWQpe3Rocm93XCJ1bnN1cHBvcnRlZCBhbGcgbmFtZTogXCIra31lbHNle3U9dC5qd3NhbGcyc2lnYWxnW2tdfWlmKHU9PVwibm9uZVwiKXt0aHJvd1wibm90IHN1cHBvcnRlZFwifWVsc2V7aWYodS5zdWJzdHIoMCw0KT09XCJIbWFjXCIpe3ZhciBvPW51bGw7aWYoQj09PXVuZGVmaW5lZCl7dGhyb3dcImhleGFkZWNpbWFsIGtleSBzaGFsbCBiZSBzcGVjaWZpZWQgZm9yIEhNQUNcIn12YXIgaj1uZXcgcyh7YWxnOnUscGFzczpCfSk7ai51cGRhdGVTdHJpbmcoYyk7bz1qLmRvRmluYWwoKTtyZXR1cm4gQT09b31lbHNle2lmKHUuaW5kZXhPZihcIndpdGhFQ0RTQVwiKSE9LTEpe3ZhciBoPW51bGw7dHJ5e2g9cC5jb25jYXRTaWdUb0FTTjFTaWcoQSl9Y2F0Y2godil7cmV0dXJuIGZhbHNlfXZhciBnPW5ldyBkKHthbGc6dX0pO2cuaW5pdChCKTtnLnVwZGF0ZVN0cmluZyhjKTtyZXR1cm4gZy52ZXJpZnkoaCl9ZWxzZXt2YXIgZz1uZXcgZCh7YWxnOnV9KTtnLmluaXQoQik7Zy51cGRhdGVTdHJpbmcoYyk7cmV0dXJuIGcudmVyaWZ5KEEpfX19fTtLSlVSLmp3cy5KV1MucGFyc2U9ZnVuY3Rpb24oZyl7dmFyIGM9Zy5zcGxpdChcIi5cIik7dmFyIGI9e307dmFyIGYsZSxkO2lmKGMubGVuZ3RoIT0yJiZjLmxlbmd0aCE9Myl7dGhyb3dcIm1hbGZvcm1lZCBzSldTOiB3cm9uZyBudW1iZXIgb2YgJy4nIHNwbGl0dGVkIGVsZW1lbnRzXCJ9Zj1jWzBdO2U9Y1sxXTtpZihjLmxlbmd0aD09Myl7ZD1jWzJdfWIuaGVhZGVyT2JqPUtKVVIuandzLkpXUy5yZWFkU2FmZUpTT05TdHJpbmcoYjY0dXRvdXRmOChmKSk7Yi5wYXlsb2FkT2JqPUtKVVIuandzLkpXUy5yZWFkU2FmZUpTT05TdHJpbmcoYjY0dXRvdXRmOChlKSk7Yi5oZWFkZXJQUD1KU09OLnN0cmluZ2lmeShiLmhlYWRlck9iaixudWxsLFwiICBcIik7aWYoYi5wYXlsb2FkT2JqPT1udWxsKXtiLnBheWxvYWRQUD1iNjR1dG91dGY4KGUpfWVsc2V7Yi5wYXlsb2FkUFA9SlNPTi5zdHJpbmdpZnkoYi5wYXlsb2FkT2JqLG51bGwsXCIgIFwiKX1pZihkIT09dW5kZWZpbmVkKXtiLnNpZ0hleD1iNjR1dG9oZXgoZCl9cmV0dXJuIGJ9O0tKVVIuandzLkpXUy52ZXJpZnlKV1Q9ZnVuY3Rpb24oZSxsLHIpe3ZhciBkPUtKVVIsaj1kLmp3cyxvPWouSldTLG49by5yZWFkU2FmZUpTT05TdHJpbmcscD1vLmluQXJyYXksZj1vLmluY2x1ZGVkQXJyYXk7dmFyIGs9ZS5zcGxpdChcIi5cIik7dmFyIGM9a1swXTt2YXIgaT1rWzFdO3ZhciBxPWMrXCIuXCIraTt2YXIgbT1iNjR1dG9oZXgoa1syXSk7dmFyIGg9bihiNjR1dG91dGY4KGMpKTt2YXIgZz1uKGI2NHV0b3V0ZjgoaSkpO2lmKGguYWxnPT09dW5kZWZpbmVkKXtyZXR1cm4gZmFsc2V9aWYoci5hbGc9PT11bmRlZmluZWQpe3Rocm93XCJhY2NlcHRGaWVsZC5hbGcgc2hhbGwgYmUgc3BlY2lmaWVkXCJ9aWYoIXAoaC5hbGcsci5hbGcpKXtyZXR1cm4gZmFsc2V9aWYoZy5pc3MhPT11bmRlZmluZWQmJnR5cGVvZiByLmlzcz09PVwib2JqZWN0XCIpe2lmKCFwKGcuaXNzLHIuaXNzKSl7cmV0dXJuIGZhbHNlfX1pZihnLnN1YiE9PXVuZGVmaW5lZCYmdHlwZW9mIHIuc3ViPT09XCJvYmplY3RcIil7aWYoIXAoZy5zdWIsci5zdWIpKXtyZXR1cm4gZmFsc2V9fWlmKGcuYXVkIT09dW5kZWZpbmVkJiZ0eXBlb2Ygci5hdWQ9PT1cIm9iamVjdFwiKXtpZih0eXBlb2YgZy5hdWQ9PVwic3RyaW5nXCIpe2lmKCFwKGcuYXVkLHIuYXVkKSl7cmV0dXJuIGZhbHNlfX1lbHNle2lmKHR5cGVvZiBnLmF1ZD09XCJvYmplY3RcIil7aWYoIWYoZy5hdWQsci5hdWQpKXtyZXR1cm4gZmFsc2V9fX19dmFyIGI9ai5JbnREYXRlLmdldE5vdygpO2lmKHIudmVyaWZ5QXQhPT11bmRlZmluZWQmJnR5cGVvZiByLnZlcmlmeUF0PT09XCJudW1iZXJcIil7Yj1yLnZlcmlmeUF0fWlmKHIuZ3JhY2VQZXJpb2Q9PT11bmRlZmluZWR8fHR5cGVvZiByLmdyYWNlUGVyaW9kIT09XCJudW1iZXJcIil7ci5ncmFjZVBlcmlvZD0wfWlmKGcuZXhwIT09dW5kZWZpbmVkJiZ0eXBlb2YgZy5leHA9PVwibnVtYmVyXCIpe2lmKGcuZXhwK3IuZ3JhY2VQZXJpb2Q8Yil7cmV0dXJuIGZhbHNlfX1pZihnLm5iZiE9PXVuZGVmaW5lZCYmdHlwZW9mIGcubmJmPT1cIm51bWJlclwiKXtpZihiPGcubmJmLXIuZ3JhY2VQZXJpb2Qpe3JldHVybiBmYWxzZX19aWYoZy5pYXQhPT11bmRlZmluZWQmJnR5cGVvZiBnLmlhdD09XCJudW1iZXJcIil7aWYoYjxnLmlhdC1yLmdyYWNlUGVyaW9kKXtyZXR1cm4gZmFsc2V9fWlmKGcuanRpIT09dW5kZWZpbmVkJiZyLmp0aSE9PXVuZGVmaW5lZCl7aWYoZy5qdGkhPT1yLmp0aSl7cmV0dXJuIGZhbHNlfX1pZighby52ZXJpZnkoZSxsLHIuYWxnKSl7cmV0dXJuIGZhbHNlfXJldHVybiB0cnVlfTtLSlVSLmp3cy5KV1MuaW5jbHVkZWRBcnJheT1mdW5jdGlvbihiLGEpe3ZhciBjPUtKVVIuandzLkpXUy5pbkFycmF5O2lmKGI9PT1udWxsKXtyZXR1cm4gZmFsc2V9aWYodHlwZW9mIGIhPT1cIm9iamVjdFwiKXtyZXR1cm4gZmFsc2V9aWYodHlwZW9mIGIubGVuZ3RoIT09XCJudW1iZXJcIil7cmV0dXJuIGZhbHNlfWZvcih2YXIgZD0wO2Q8Yi5sZW5ndGg7ZCsrKXtpZighYyhiW2RdLGEpKXtyZXR1cm4gZmFsc2V9fXJldHVybiB0cnVlfTtLSlVSLmp3cy5KV1MuaW5BcnJheT1mdW5jdGlvbihkLGIpe2lmKGI9PT1udWxsKXtyZXR1cm4gZmFsc2V9aWYodHlwZW9mIGIhPT1cIm9iamVjdFwiKXtyZXR1cm4gZmFsc2V9aWYodHlwZW9mIGIubGVuZ3RoIT09XCJudW1iZXJcIil7cmV0dXJuIGZhbHNlfWZvcih2YXIgYz0wO2M8Yi5sZW5ndGg7YysrKXtpZihiW2NdPT1kKXtyZXR1cm4gdHJ1ZX19cmV0dXJuIGZhbHNlfTtLSlVSLmp3cy5KV1MuandzYWxnMnNpZ2FsZz17SFMyNTY6XCJIbWFjU0hBMjU2XCIsSFMzODQ6XCJIbWFjU0hBMzg0XCIsSFM1MTI6XCJIbWFjU0hBNTEyXCIsUlMyNTY6XCJTSEEyNTZ3aXRoUlNBXCIsUlMzODQ6XCJTSEEzODR3aXRoUlNBXCIsUlM1MTI6XCJTSEE1MTJ3aXRoUlNBXCIsRVMyNTY6XCJTSEEyNTZ3aXRoRUNEU0FcIixFUzM4NDpcIlNIQTM4NHdpdGhFQ0RTQVwiLFBTMjU2OlwiU0hBMjU2d2l0aFJTQWFuZE1HRjFcIixQUzM4NDpcIlNIQTM4NHdpdGhSU0FhbmRNR0YxXCIsUFM1MTI6XCJTSEE1MTJ3aXRoUlNBYW5kTUdGMVwiLG5vbmU6XCJub25lXCIsfTtLSlVSLmp3cy5KV1MuaXNTYWZlSlNPTlN0cmluZz1mdW5jdGlvbihjLGIsZCl7dmFyIGU9bnVsbDt0cnl7ZT1qc29uUGFyc2UoYyk7aWYodHlwZW9mIGUhPVwib2JqZWN0XCIpe3JldHVybiAwfWlmKGUuY29uc3RydWN0b3I9PT1BcnJheSl7cmV0dXJuIDB9aWYoYil7YltkXT1lfXJldHVybiAxfWNhdGNoKGEpe3JldHVybiAwfX07S0pVUi5qd3MuSldTLnJlYWRTYWZlSlNPTlN0cmluZz1mdW5jdGlvbihiKXt2YXIgYz1udWxsO3RyeXtjPWpzb25QYXJzZShiKTtpZih0eXBlb2YgYyE9XCJvYmplY3RcIil7cmV0dXJuIG51bGx9aWYoYy5jb25zdHJ1Y3Rvcj09PUFycmF5KXtyZXR1cm4gbnVsbH1yZXR1cm4gY31jYXRjaChhKXtyZXR1cm4gbnVsbH19O0tKVVIuandzLkpXUy5nZXRFbmNvZGVkU2lnbmF0dXJlVmFsdWVGcm9tSldTPWZ1bmN0aW9uKGIpe3ZhciBhPWIubWF0Y2goL15bXi5dK1xcLlteLl0rXFwuKFteLl0rKSQvKTtpZihhPT1udWxsKXt0aHJvd1wiSldTIHNpZ25hdHVyZSBpcyBub3QgYSBmb3JtIG9mICdIZWFkLlBheWxvYWQuU2lnVmFsdWUnLlwifXJldHVybiBhWzFdfTtLSlVSLmp3cy5KV1MuZ2V0SldLdGh1bWJwcmludD1mdW5jdGlvbihkKXtpZihkLmt0eSE9PVwiUlNBXCImJmQua3R5IT09XCJFQ1wiJiZkLmt0eSE9PVwib2N0XCIpe3Rocm93XCJ1bnN1cHBvcnRlZCBhbGdvcml0aG0gZm9yIEpXSyBUaHVtcHJpbnRcIn12YXIgYT1cIntcIjtpZihkLmt0eT09PVwiUlNBXCIpe2lmKHR5cGVvZiBkLm4hPVwic3RyaW5nXCJ8fHR5cGVvZiBkLmUhPVwic3RyaW5nXCIpe3Rocm93XCJ3cm9uZyBuIGFuZCBlIHZhbHVlIGZvciBSU0Ega2V5XCJ9YSs9J1wiZVwiOlwiJytkLmUrJ1wiLCc7YSs9J1wia3R5XCI6XCInK2Qua3R5KydcIiwnO2ErPSdcIm5cIjpcIicrZC5uKydcIn0nfWVsc2V7aWYoZC5rdHk9PT1cIkVDXCIpe2lmKHR5cGVvZiBkLmNydiE9XCJzdHJpbmdcInx8dHlwZW9mIGQueCE9XCJzdHJpbmdcInx8dHlwZW9mIGQueSE9XCJzdHJpbmdcIil7dGhyb3dcIndyb25nIGNydiwgeCBhbmQgeSB2YWx1ZSBmb3IgRUMga2V5XCJ9YSs9J1wiY3J2XCI6XCInK2QuY3J2KydcIiwnO2ErPSdcImt0eVwiOlwiJytkLmt0eSsnXCIsJzthKz0nXCJ4XCI6XCInK2QueCsnXCIsJzthKz0nXCJ5XCI6XCInK2QueSsnXCJ9J31lbHNle2lmKGQua3R5PT09XCJvY3RcIil7aWYodHlwZW9mIGQuayE9XCJzdHJpbmdcIil7dGhyb3dcIndyb25nIGsgdmFsdWUgZm9yIG9jdChzeW1tZXRyaWMpIGtleVwifWErPSdcImt0eVwiOlwiJytkLmt0eSsnXCIsJzthKz0nXCJrXCI6XCInK2QuaysnXCJ9J319fXZhciBiPXJzdHJ0b2hleChhKTt2YXIgYz1LSlVSLmNyeXB0by5VdGlsLmhhc2hIZXgoYixcInNoYTI1NlwiKTt2YXIgZT1oZXh0b2I2NHUoYyk7cmV0dXJuIGV9O0tKVVIuandzLkludERhdGU9e307S0pVUi5qd3MuSW50RGF0ZS5nZXQ9ZnVuY3Rpb24oYyl7dmFyIGI9S0pVUi5qd3MuSW50RGF0ZSxkPWIuZ2V0Tm93LGE9Yi5nZXRadWx1O2lmKGM9PVwibm93XCIpe3JldHVybiBkKCl9ZWxzZXtpZihjPT1cIm5vdyArIDFob3VyXCIpe3JldHVybiBkKCkrNjAqNjB9ZWxzZXtpZihjPT1cIm5vdyArIDFkYXlcIil7cmV0dXJuIGQoKSs2MCo2MCoyNH1lbHNle2lmKGM9PVwibm93ICsgMW1vbnRoXCIpe3JldHVybiBkKCkrNjAqNjAqMjQqMzB9ZWxzZXtpZihjPT1cIm5vdyArIDF5ZWFyXCIpe3JldHVybiBkKCkrNjAqNjAqMjQqMzY1fWVsc2V7aWYoYy5tYXRjaCgvWiQvKSl7cmV0dXJuIGEoYyl9ZWxzZXtpZihjLm1hdGNoKC9eWzAtOV0rJC8pKXtyZXR1cm4gcGFyc2VJbnQoYyl9fX19fX19dGhyb3dcInVuc3VwcG9ydGVkIGZvcm1hdDogXCIrY307S0pVUi5qd3MuSW50RGF0ZS5nZXRadWx1PWZ1bmN0aW9uKGEpe3JldHVybiB6dWx1dG9zZWMoYSl9O0tKVVIuandzLkludERhdGUuZ2V0Tm93PWZ1bmN0aW9uKCl7dmFyIGE9fn4obmV3IERhdGUoKS8xMDAwKTtyZXR1cm4gYX07S0pVUi5qd3MuSW50RGF0ZS5pbnREYXRlMlVUQ1N0cmluZz1mdW5jdGlvbihhKXt2YXIgYj1uZXcgRGF0ZShhKjEwMDApO3JldHVybiBiLnRvVVRDU3RyaW5nKCl9O0tKVVIuandzLkludERhdGUuaW50RGF0ZTJadWx1PWZ1bmN0aW9uKGUpe3ZhciBpPW5ldyBEYXRlKGUqMTAwMCksaD0oXCIwMDAwXCIraS5nZXRVVENGdWxsWWVhcigpKS5zbGljZSgtNCksZz0oXCIwMFwiKyhpLmdldFVUQ01vbnRoKCkrMSkpLnNsaWNlKC0yKSxiPShcIjAwXCIraS5nZXRVVENEYXRlKCkpLnNsaWNlKC0yKSxhPShcIjAwXCIraS5nZXRVVENIb3VycygpKS5zbGljZSgtMiksYz0oXCIwMFwiK2kuZ2V0VVRDTWludXRlcygpKS5zbGljZSgtMiksZj0oXCIwMFwiK2kuZ2V0VVRDU2Vjb25kcygpKS5zbGljZSgtMik7cmV0dXJuIGgrZytiK2ErYytmK1wiWlwifTtcbmV4cG9ydCB7IFNlY3VyZVJhbmRvbSB9O1xyXG5leHBvcnQgeyBybmdfc2VlZF90aW1lIH07XHJcblxyXG5leHBvcnQgeyBCaWdJbnRlZ2VyIH07XHJcbmV4cG9ydCB7IFJTQUtleSB9O1xyXG5leHBvcnQgY29uc3QgeyBFRFNBIH0gPSBLSlVSLmNyeXB0bztcclxuZXhwb3J0IGNvbnN0IHsgRFNBIH0gPSBLSlVSLmNyeXB0bztcclxuZXhwb3J0IGNvbnN0IHsgU2lnbmF0dXJlIH0gPSBLSlVSLmNyeXB0bztcclxuZXhwb3J0IGNvbnN0IHsgTWVzc2FnZURpZ2VzdCB9ID0gIEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBNYWMgfSA9IEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBDaXBoZXIgfSA9ICBLSlVSLmNyeXB0bztcclxuZXhwb3J0IHsgS0VZVVRJTCB9O1xyXG5leHBvcnQgeyBBU04xSEVYIH07XHJcbmV4cG9ydCB7IFg1MDkgfTtcclxuZXhwb3J0IHsgQ3J5cHRvSlMgfTtcclxuXHJcbi8vIGV4dC9iYXNlNjQuanNcclxuZXhwb3J0IHsgYjY0dG9oZXggfTtcclxuZXhwb3J0IHsgYjY0dG9CQSB9O1xyXG5cclxuLy8gYmFzZTY0eC5qc1xyXG5leHBvcnQgeyBzdG9CQSB9O1xyXG5leHBvcnQgeyBCQXRvcyB9O1xyXG5leHBvcnQgeyBCQXRvaGV4IH07XHJcbmV4cG9ydCB7IHN0b2hleCB9O1xyXG5leHBvcnQgeyBzdG9iNjQgfTtcclxuZXhwb3J0IHsgc3RvYjY0dSB9O1xyXG5leHBvcnQgeyBiNjR1dG9zIH07XHJcbmV4cG9ydCB7IGI2NHRvYjY0dSB9O1xyXG5leHBvcnQgeyBiNjR1dG9iNjQgfTtcclxuZXhwb3J0IHsgaGV4MmI2NCB9O1xyXG5leHBvcnQgeyBoZXh0b2I2NHUgfTtcclxuZXhwb3J0IHsgYjY0dXRvaGV4IH07XHJcbmV4cG9ydCB7IHV0Zjh0b2I2NHUgfTtcclxuZXhwb3J0IHsgYjY0dXRvdXRmOCB9O1xyXG5leHBvcnQgeyB1dGY4dG9iNjQgfTtcclxuZXhwb3J0IHsgYjY0dG91dGY4IH07XHJcbmV4cG9ydCB7IHV0Zjh0b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b3V0ZjggfTtcclxuZXhwb3J0IHsgaGV4dG9yc3RyIH07XHJcbmV4cG9ydCB7IHJzdHJ0b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b2I2NCB9O1xyXG5leHBvcnQgeyBoZXh0b2I2NG5sIH07XHJcbmV4cG9ydCB7IGI2NG5sdG9oZXggfTtcclxuZXhwb3J0IHsgaGV4dG9wZW0gfTtcclxuZXhwb3J0IHsgcGVtdG9oZXggfTtcclxuZXhwb3J0IHsgaGV4dG9BcnJheUJ1ZmZlciB9O1xyXG5leHBvcnQgeyBBcnJheUJ1ZmZlcnRvaGV4IH07XHJcbmV4cG9ydCB7IHp1bHV0b21zZWMgfTtcclxuZXhwb3J0IHsgenVsdXRvc2VjIH07XHJcbmV4cG9ydCB7IHp1bHV0b2RhdGUgfTtcclxuZXhwb3J0IHsgZGF0ZXRvenVsdSB9O1xyXG5leHBvcnQgeyB1cmljbXB0b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b3VyaWNtcCB9O1xyXG5leHBvcnQgeyBpcHY2dG9oZXggfTtcclxuZXhwb3J0IHsgaGV4dG9pcHY2IH07XHJcbmV4cG9ydCB7IGhleHRvaXAgfTtcclxuZXhwb3J0IHsgaXB0b2hleCB9O1xyXG5leHBvcnQgeyBlbmNvZGVVUklDb21wb25lbnRBbGwgfTtcclxuZXhwb3J0IHsgbmV3bGluZV90b1VuaXggfTtcclxuZXhwb3J0IHsgbmV3bGluZV90b0RvcyB9O1xyXG5leHBvcnQgeyBoZXh0b3Bvc2hleCB9O1xyXG5leHBvcnQgeyBpbnRhcnlzdHJ0b2hleCB9O1xyXG5leHBvcnQgeyBzdHJkaWZmaWR4IH07XHJcblxyXG4vLyBuYW1lIHNwYWNlc1xyXG5leHBvcnQgeyBLSlVSIH07XHJcbmNvbnN0IF9jcnlwdG8gPSAgS0pVUi5jcnlwdG87XHJcbmV4cG9ydCB7IF9jcnlwdG8gYXMgY3J5cHRvIH07XHJcbmV4cG9ydCBjb25zdCB7IGFzbjEgfSA9IEtKVVI7XHJcbmV4cG9ydCBjb25zdCB7IGp3cyB9ID0gS0pVUjtcclxuZXhwb3J0IGNvbnN0IHsgbGFuZyB9ID0gS0pVUjtcclxuXHJcblxyXG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQgIT09IHVuZGVmaW5lZFxuICA/IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gIDogdHlwZWRBcnJheVN1cHBvcnQoKVxuXG4vKlxuICogRXhwb3J0IGtNYXhMZW5ndGggYWZ0ZXIgdHlwZWQgYXJyYXkgc3VwcG9ydCBpcyBkZXRlcm1pbmVkLlxuICovXG5leHBvcnRzLmtNYXhMZW5ndGggPSBrTWF4TGVuZ3RoKClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5fX3Byb3RvX18gPSB7X19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9fVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChrTWF4TGVuZ3RoKCkgPCBsZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlZCBhcnJheSBsZW5ndGgnKVxuICB9XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIGlmICh0aGF0ID09PSBudWxsKSB7XG4gICAgICB0aGF0ID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gICAgfVxuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiAhKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZSh0aGlzLCBhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20odGhpcywgYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG4vLyBUT0RPOiBMZWdhY3ksIG5vdCBuZWVkZWQgYW55bW9yZS4gUmVtb3ZlIGluIG5leHQgbWFqb3IgdmVyc2lvbi5cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiBmcm9tICh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhhdCwgdmFsdWUpXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20obnVsbCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICYmXG4gICAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgICAvLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IHRoYXQud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIHRoYXQgPSB0aGF0LnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKHRoYXQsIGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgYXJyYXkuYnl0ZUxlbmd0aCAvLyB0aGlzIHRocm93cyBpZiBgYXJyYXlgIGlzIG5vdCBhIHZhbGlkIEFycmF5QnVmZmVyXG5cbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ29mZnNldFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnbGVuZ3RoXFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW4pXG5cbiAgICBpZiAodGhhdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGF0XG4gICAgfVxuXG4gICAgb2JqLmNvcHkodGhhdCwgMCwgMCwgbGVuKVxuICAgIHJldHVybiB0aGF0XG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGgoKWAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgc3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhlIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgYW5kIGBpcy1idWZmZXJgIChpbiBTYWZhcmkgNS03KSB0byBkZXRlY3Rcbi8vIEJ1ZmZlciBpbnN0YW5jZXMuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgIC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChpc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmXG4gICAgICAgIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgKytpKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDQpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuICB2YXIgaVxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIGlmIChsZW4gPCAxMDAwIHx8ICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIGFzY2VuZGluZyBjb3B5IGZyb20gc3RhcnRcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKGNvZGUgPCAyNTYpIHtcbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IHV0ZjhUb0J5dGVzKG5ldyBCdWZmZXIodmFsLCBlbmNvZGluZykudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gaXNuYW4gKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSB2YWwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnByb21pc2UnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpLlByb21pc2U7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5maW5kO1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXknKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLkFycmF5LmlzQXJyYXk7XG4iLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5hcnJheS5zb21lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5zb21lO1xuIiwiLy8gZm9yIGEgbGVnYWN5IGNvZGUgYW5kIGZ1dHVyZSBmaXhlc1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBGdW5jdGlvbi5jYWxsLmFwcGx5KEFycmF5LnByb3RvdHlwZS5zcGxpY2UsIGFyZ3VtZW50cyk7XG59O1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZCcpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuRnVuY3Rpb24uYmluZDtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24nKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLk9iamVjdC5hc3NpZ247XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIvLyAyMi4xLjMuMzEgQXJyYXkucHJvdG90eXBlW0BAdW5zY29wYWJsZXNdXG52YXIgVU5TQ09QQUJMRVMgPSByZXF1aXJlKCcuL193a3MnKSgndW5zY29wYWJsZXMnKTtcbnZhciBBcnJheVByb3RvID0gQXJyYXkucHJvdG90eXBlO1xuaWYgKEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdID09IHVuZGVmaW5lZCkgcmVxdWlyZSgnLi9faGlkZScpKEFycmF5UHJvdG8sIFVOU0NPUEFCTEVTLCB7fSk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgQXJyYXlQcm90b1tVTlNDT1BBQkxFU11ba2V5XSA9IHRydWU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIENvbnN0cnVjdG9yLCBuYW1lLCBmb3JiaWRkZW5GaWVsZCkge1xuICBpZiAoIShpdCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSB8fCAoZm9yYmlkZGVuRmllbGQgIT09IHVuZGVmaW5lZCAmJiBmb3JiaWRkZW5GaWVsZCBpbiBpdCkpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IobmFtZSArICc6IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICB9IHJldHVybiBpdDtcbn07XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmICghaXNPYmplY3QoaXQpKSB0aHJvdyBUeXBlRXJyb3IoaXQgKyAnIGlzIG5vdCBhbiBvYmplY3QhJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCIvLyBmYWxzZSAtPiBBcnJheSNpbmRleE9mXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChJU19JTkNMVURFUykge1xuICByZXR1cm4gZnVuY3Rpb24gKCR0aGlzLCBlbCwgZnJvbUluZGV4KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoJHRoaXMpO1xuICAgIHZhciBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgdmFyIGluZGV4ID0gdG9BYnNvbHV0ZUluZGV4KGZyb21JbmRleCwgbGVuZ3RoKTtcbiAgICB2YXIgdmFsdWU7XG4gICAgLy8gQXJyYXkjaW5jbHVkZXMgdXNlcyBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICBpZiAoSVNfSU5DTFVERVMgJiYgZWwgIT0gZWwpIHdoaWxlIChsZW5ndGggPiBpbmRleCkge1xuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgICAgaWYgKHZhbHVlICE9IHZhbHVlKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBBcnJheSNpbmRleE9mIGlnbm9yZXMgaG9sZXMsIEFycmF5I2luY2x1ZGVzIC0gbm90XG4gICAgfSBlbHNlIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoSVNfSU5DTFVERVMgfHwgaW5kZXggaW4gTykge1xuICAgICAgaWYgKE9baW5kZXhdID09PSBlbCkgcmV0dXJuIElTX0lOQ0xVREVTIHx8IGluZGV4IHx8IDA7XG4gICAgfSByZXR1cm4gIUlTX0lOQ0xVREVTICYmIC0xO1xuICB9O1xufTtcbiIsIi8vIDAgLT4gQXJyYXkjZm9yRWFjaFxuLy8gMSAtPiBBcnJheSNtYXBcbi8vIDIgLT4gQXJyYXkjZmlsdGVyXG4vLyAzIC0+IEFycmF5I3NvbWVcbi8vIDQgLT4gQXJyYXkjZXZlcnlcbi8vIDUgLT4gQXJyYXkjZmluZFxuLy8gNiAtPiBBcnJheSNmaW5kSW5kZXhcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBhc2MgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoVFlQRSwgJGNyZWF0ZSkge1xuICB2YXIgSVNfTUFQID0gVFlQRSA9PSAxO1xuICB2YXIgSVNfRklMVEVSID0gVFlQRSA9PSAyO1xuICB2YXIgSVNfU09NRSA9IFRZUEUgPT0gMztcbiAgdmFyIElTX0VWRVJZID0gVFlQRSA9PSA0O1xuICB2YXIgSVNfRklORF9JTkRFWCA9IFRZUEUgPT0gNjtcbiAgdmFyIE5PX0hPTEVTID0gVFlQRSA9PSA1IHx8IElTX0ZJTkRfSU5ERVg7XG4gIHZhciBjcmVhdGUgPSAkY3JlYXRlIHx8IGFzYztcbiAgcmV0dXJuIGZ1bmN0aW9uICgkdGhpcywgY2FsbGJhY2tmbiwgdGhhdCkge1xuICAgIHZhciBPID0gdG9PYmplY3QoJHRoaXMpO1xuICAgIHZhciBzZWxmID0gSU9iamVjdChPKTtcbiAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCB0aGF0LCAzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoc2VsZi5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHJlc3VsdCA9IElTX01BUCA/IGNyZWF0ZSgkdGhpcywgbGVuZ3RoKSA6IElTX0ZJTFRFUiA/IGNyZWF0ZSgkdGhpcywgMCkgOiB1bmRlZmluZWQ7XG4gICAgdmFyIHZhbCwgcmVzO1xuICAgIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoTk9fSE9MRVMgfHwgaW5kZXggaW4gc2VsZikge1xuICAgICAgdmFsID0gc2VsZltpbmRleF07XG4gICAgICByZXMgPSBmKHZhbCwgaW5kZXgsIE8pO1xuICAgICAgaWYgKFRZUEUpIHtcbiAgICAgICAgaWYgKElTX01BUCkgcmVzdWx0W2luZGV4XSA9IHJlczsgICAvLyBtYXBcbiAgICAgICAgZWxzZSBpZiAocmVzKSBzd2l0Y2ggKFRZUEUpIHtcbiAgICAgICAgICBjYXNlIDM6IHJldHVybiB0cnVlOyAgICAgICAgICAgICAvLyBzb21lXG4gICAgICAgICAgY2FzZSA1OiByZXR1cm4gdmFsOyAgICAgICAgICAgICAgLy8gZmluZFxuICAgICAgICAgIGNhc2UgNjogcmV0dXJuIGluZGV4OyAgICAgICAgICAgIC8vIGZpbmRJbmRleFxuICAgICAgICAgIGNhc2UgMjogcmVzdWx0LnB1c2godmFsKTsgICAgICAgIC8vIGZpbHRlclxuICAgICAgICB9IGVsc2UgaWYgKElTX0VWRVJZKSByZXR1cm4gZmFsc2U7IC8vIGV2ZXJ5XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBJU19GSU5EX0lOREVYID8gLTEgOiBJU19TT01FIHx8IElTX0VWRVJZID8gSVNfRVZFUlkgOiByZXN1bHQ7XG4gIH07XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9yaWdpbmFsKSB7XG4gIHZhciBDO1xuICBpZiAoaXNBcnJheShvcmlnaW5hbCkpIHtcbiAgICBDID0gb3JpZ2luYWwuY29uc3RydWN0b3I7XG4gICAgLy8gY3Jvc3MtcmVhbG0gZmFsbGJhY2tcbiAgICBpZiAodHlwZW9mIEMgPT0gJ2Z1bmN0aW9uJyAmJiAoQyA9PT0gQXJyYXkgfHwgaXNBcnJheShDLnByb3RvdHlwZSkpKSBDID0gdW5kZWZpbmVkO1xuICAgIGlmIChpc09iamVjdChDKSkge1xuICAgICAgQyA9IENbU1BFQ0lFU107XG4gICAgICBpZiAoQyA9PT0gbnVsbCkgQyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gcmV0dXJuIEMgPT09IHVuZGVmaW5lZCA/IEFycmF5IDogQztcbn07XG4iLCIvLyA5LjQuMi4zIEFycmF5U3BlY2llc0NyZWF0ZShvcmlnaW5hbEFycmF5LCBsZW5ndGgpXG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcmlnaW5hbCwgbGVuZ3RoKSB7XG4gIHJldHVybiBuZXcgKHNwZWNpZXNDb25zdHJ1Y3RvcihvcmlnaW5hbCkpKGxlbmd0aCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGFycmF5U2xpY2UgPSBbXS5zbGljZTtcbnZhciBmYWN0b3JpZXMgPSB7fTtcblxudmFyIGNvbnN0cnVjdCA9IGZ1bmN0aW9uIChGLCBsZW4sIGFyZ3MpIHtcbiAgaWYgKCEobGVuIGluIGZhY3RvcmllcykpIHtcbiAgICBmb3IgKHZhciBuID0gW10sIGkgPSAwOyBpIDwgbGVuOyBpKyspIG5baV0gPSAnYVsnICsgaSArICddJztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICBmYWN0b3JpZXNbbGVuXSA9IEZ1bmN0aW9uKCdGLGEnLCAncmV0dXJuIG5ldyBGKCcgKyBuLmpvaW4oJywnKSArICcpJyk7XG4gIH0gcmV0dXJuIGZhY3Rvcmllc1tsZW5dKEYsIGFyZ3MpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5iaW5kIHx8IGZ1bmN0aW9uIGJpbmQodGhhdCAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgdmFyIGZuID0gYUZ1bmN0aW9uKHRoaXMpO1xuICB2YXIgcGFydEFyZ3MgPSBhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgdmFyIGJvdW5kID0gZnVuY3Rpb24gKC8qIGFyZ3MuLi4gKi8pIHtcbiAgICB2YXIgYXJncyA9IHBhcnRBcmdzLmNvbmNhdChhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBib3VuZCA/IGNvbnN0cnVjdChmbiwgYXJncy5sZW5ndGgsIGFyZ3MpIDogaW52b2tlKGZuLCBhcmdzLCB0aGF0KTtcbiAgfTtcbiAgaWYgKGlzT2JqZWN0KGZuLnByb3RvdHlwZSkpIGJvdW5kLnByb3RvdHlwZSA9IGZuLnByb3RvdHlwZTtcbiAgcmV0dXJuIGJvdW5kO1xufTtcbiIsIi8vIGdldHRpbmcgdGFnIGZyb20gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgVEFHID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyk7XG4vLyBFUzMgd3JvbmcgaGVyZVxudmFyIEFSRyA9IGNvZihmdW5jdGlvbiAoKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPT0gJ0FyZ3VtZW50cyc7XG5cbi8vIGZhbGxiYWNrIGZvciBJRTExIFNjcmlwdCBBY2Nlc3MgRGVuaWVkIGVycm9yXG52YXIgdHJ5R2V0ID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gaXRba2V5XTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgTywgVCwgQjtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyAnVW5kZWZpbmVkJyA6IGl0ID09PSBudWxsID8gJ051bGwnXG4gICAgLy8gQEB0b1N0cmluZ1RhZyBjYXNlXG4gICAgOiB0eXBlb2YgKFQgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRBRykpID09ICdzdHJpbmcnID8gVFxuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQVJHID8gY29mKE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKEIgPSBjb2YoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiBCO1xufTtcbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTtcbiIsInZhciBjb3JlID0gbW9kdWxlLmV4cG9ydHMgPSB7IHZlcnNpb246ICcyLjYuNCcgfTtcbmlmICh0eXBlb2YgX19lID09ICdudW1iZXInKSBfX2UgPSBjb3JlOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCIvLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgdGhhdCwgbGVuZ3RoKSB7XG4gIGFGdW5jdGlvbihmbik7XG4gIGlmICh0aGF0ID09PSB1bmRlZmluZWQpIHJldHVybiBmbjtcbiAgc3dpdGNoIChsZW5ndGgpIHtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSk7XG4gICAgfTtcbiAgICBjYXNlIDI6IHJldHVybiBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYik7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbiAoYSwgYiwgYykge1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKC8qIC4uLmFyZ3MgKi8pIHtcbiAgICByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJndW1lbnRzKTtcbiAgfTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xuLy8gdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgaXMgJ29iamVjdCcgaW4gb2xkIElFXG52YXIgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXMgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG5cbnZhciAkZXhwb3J0ID0gZnVuY3Rpb24gKHR5cGUsIG5hbWUsIHNvdXJjZSkge1xuICB2YXIgSVNfRk9SQ0VEID0gdHlwZSAmICRleHBvcnQuRjtcbiAgdmFyIElTX0dMT0JBTCA9IHR5cGUgJiAkZXhwb3J0Lkc7XG4gIHZhciBJU19TVEFUSUMgPSB0eXBlICYgJGV4cG9ydC5TO1xuICB2YXIgSVNfUFJPVE8gPSB0eXBlICYgJGV4cG9ydC5QO1xuICB2YXIgSVNfQklORCA9IHR5cGUgJiAkZXhwb3J0LkI7XG4gIHZhciB0YXJnZXQgPSBJU19HTE9CQUwgPyBnbG9iYWwgOiBJU19TVEFUSUMgPyBnbG9iYWxbbmFtZV0gfHwgKGdsb2JhbFtuYW1lXSA9IHt9KSA6IChnbG9iYWxbbmFtZV0gfHwge30pW1BST1RPVFlQRV07XG4gIHZhciBleHBvcnRzID0gSVNfR0xPQkFMID8gY29yZSA6IGNvcmVbbmFtZV0gfHwgKGNvcmVbbmFtZV0gPSB7fSk7XG4gIHZhciBleHBQcm90byA9IGV4cG9ydHNbUFJPVE9UWVBFXSB8fCAoZXhwb3J0c1tQUk9UT1RZUEVdID0ge30pO1xuICB2YXIga2V5LCBvd24sIG91dCwgZXhwO1xuICBpZiAoSVNfR0xPQkFMKSBzb3VyY2UgPSBuYW1lO1xuICBmb3IgKGtleSBpbiBzb3VyY2UpIHtcbiAgICAvLyBjb250YWlucyBpbiBuYXRpdmVcbiAgICBvd24gPSAhSVNfRk9SQ0VEICYmIHRhcmdldCAmJiB0YXJnZXRba2V5XSAhPT0gdW5kZWZpbmVkO1xuICAgIC8vIGV4cG9ydCBuYXRpdmUgb3IgcGFzc2VkXG4gICAgb3V0ID0gKG93biA/IHRhcmdldCA6IHNvdXJjZSlba2V5XTtcbiAgICAvLyBiaW5kIHRpbWVycyB0byBnbG9iYWwgZm9yIGNhbGwgZnJvbSBleHBvcnQgY29udGV4dFxuICAgIGV4cCA9IElTX0JJTkQgJiYgb3duID8gY3R4KG91dCwgZ2xvYmFsKSA6IElTX1BST1RPICYmIHR5cGVvZiBvdXQgPT0gJ2Z1bmN0aW9uJyA/IGN0eChGdW5jdGlvbi5jYWxsLCBvdXQpIDogb3V0O1xuICAgIC8vIGV4dGVuZCBnbG9iYWxcbiAgICBpZiAodGFyZ2V0KSByZWRlZmluZSh0YXJnZXQsIGtleSwgb3V0LCB0eXBlICYgJGV4cG9ydC5VKTtcbiAgICAvLyBleHBvcnRcbiAgICBpZiAoZXhwb3J0c1trZXldICE9IG91dCkgaGlkZShleHBvcnRzLCBrZXksIGV4cCk7XG4gICAgaWYgKElTX1BST1RPICYmIGV4cFByb3RvW2tleV0gIT0gb3V0KSBleHBQcm90b1trZXldID0gb3V0O1xuICB9XG59O1xuZ2xvYmFsLmNvcmUgPSBjb3JlO1xuLy8gdHlwZSBiaXRtYXBcbiRleHBvcnQuRiA9IDE7ICAgLy8gZm9yY2VkXG4kZXhwb3J0LkcgPSAyOyAgIC8vIGdsb2JhbFxuJGV4cG9ydC5TID0gNDsgICAvLyBzdGF0aWNcbiRleHBvcnQuUCA9IDg7ICAgLy8gcHJvdG9cbiRleHBvcnQuQiA9IDE2OyAgLy8gYmluZFxuJGV4cG9ydC5XID0gMzI7ICAvLyB3cmFwXG4kZXhwb3J0LlUgPSA2NDsgIC8vIHNhZmVcbiRleHBvcnQuUiA9IDEyODsgLy8gcmVhbCBwcm90byBtZXRob2QgZm9yIGBsaWJyYXJ5YFxubW9kdWxlLmV4cG9ydHMgPSAkZXhwb3J0O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYykge1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbnZhciBCUkVBSyA9IHt9O1xudmFyIFJFVFVSTiA9IHt9O1xudmFyIGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYWJsZSwgZW50cmllcywgZm4sIHRoYXQsIElURVJBVE9SKSB7XG4gIHZhciBpdGVyRm4gPSBJVEVSQVRPUiA/IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXJhYmxlOyB9IDogZ2V0SXRlckZuKGl0ZXJhYmxlKTtcbiAgdmFyIGYgPSBjdHgoZm4sIHRoYXQsIGVudHJpZXMgPyAyIDogMSk7XG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsZW5ndGgsIHN0ZXAsIGl0ZXJhdG9yLCByZXN1bHQ7XG4gIGlmICh0eXBlb2YgaXRlckZuICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdGVyYWJsZSArICcgaXMgbm90IGl0ZXJhYmxlIScpO1xuICAvLyBmYXN0IGNhc2UgZm9yIGFycmF5cyB3aXRoIGRlZmF1bHQgaXRlcmF0b3JcbiAgaWYgKGlzQXJyYXlJdGVyKGl0ZXJGbikpIGZvciAobGVuZ3RoID0gdG9MZW5ndGgoaXRlcmFibGUubGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICByZXN1bHQgPSBlbnRyaWVzID8gZihhbk9iamVjdChzdGVwID0gaXRlcmFibGVbaW5kZXhdKVswXSwgc3RlcFsxXSkgOiBmKGl0ZXJhYmxlW2luZGV4XSk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH0gZWxzZSBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoaXRlcmFibGUpOyAhKHN0ZXAgPSBpdGVyYXRvci5uZXh0KCkpLmRvbmU7KSB7XG4gICAgcmVzdWx0ID0gY2FsbChpdGVyYXRvciwgZiwgc3RlcC52YWx1ZSwgZW50cmllcyk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQlJFQUsgfHwgcmVzdWx0ID09PSBSRVRVUk4pIHJldHVybiByZXN1bHQ7XG4gIH1cbn07XG5leHBvcnRzLkJSRUFLID0gQlJFQUs7XG5leHBvcnRzLlJFVFVSTiA9IFJFVFVSTjtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ25hdGl2ZS1mdW5jdGlvbi10by1zdHJpbmcnLCBGdW5jdGlvbi50b1N0cmluZyk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvODYjaXNzdWVjb21tZW50LTExNTc1OTAyOFxudmFyIGdsb2JhbCA9IG1vZHVsZS5leHBvcnRzID0gdHlwZW9mIHdpbmRvdyAhPSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuTWF0aCA9PSBNYXRoXG4gID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09IE1hdGggPyBzZWxmXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICA6IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5pZiAodHlwZW9mIF9fZyA9PSAnbnVtYmVyJykgX19nID0gZ2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIGRQLmYob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuIiwidmFyIGRvY3VtZW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnQ7XG5tb2R1bGUuZXhwb3J0cyA9IGRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiIsIm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnZGl2JyksICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCIvLyBmYXN0IGFwcGx5LCBodHRwOi8vanNwZXJmLmxua2l0LmNvbS9mYXN0LWFwcGx5LzVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCBhcmdzLCB0aGF0KSB7XG4gIHZhciB1biA9IHRoYXQgPT09IHVuZGVmaW5lZDtcbiAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgIGNhc2UgMDogcmV0dXJuIHVuID8gZm4oKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0KTtcbiAgICBjYXNlIDE6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0pO1xuICAgIGNhc2UgMjogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgY2FzZSAzOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICBjYXNlIDQ6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICB9IHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmdzKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QoJ3onKS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgwKSA/IE9iamVjdCA6IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gY29mKGl0KSA9PSAnU3RyaW5nJyA/IGl0LnNwbGl0KCcnKSA6IE9iamVjdChpdCk7XG59O1xuIiwiLy8gY2hlY2sgb24gZGVmYXVsdCBBcnJheSBpdGVyYXRvclxudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ICE9PSB1bmRlZmluZWQgJiYgKEl0ZXJhdG9ycy5BcnJheSA9PT0gaXQgfHwgQXJyYXlQcm90b1tJVEVSQVRPUl0gPT09IGl0KTtcbn07XG4iLCIvLyA3LjIuMiBJc0FycmF5KGFyZ3VtZW50KVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIHJldHVybiBjb2YoYXJnKSA9PSAnQXJyYXknO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0eXBlb2YgaXQgPT09ICdvYmplY3QnID8gaXQgIT09IG51bGwgOiB0eXBlb2YgaXQgPT09ICdmdW5jdGlvbic7XG59O1xuIiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcbiAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgfSBjYXRjaCAoZSkge1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkKSBhbk9iamVjdChyZXQuY2FsbChpdGVyYXRvcikpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGRlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG5cbi8vIDI1LjEuMi4xLjEgJUl0ZXJhdG9yUHJvdG90eXBlJVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19oaWRlJykoSXRlcmF0b3JQcm90b3R5cGUsIHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpLCBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpIHtcbiAgQ29uc3RydWN0b3IucHJvdG90eXBlID0gY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlLCB7IG5leHQ6IGRlc2NyaXB0b3IoMSwgbmV4dCkgfSk7XG4gIHNldFRvU3RyaW5nVGFnKENvbnN0cnVjdG9yLCBOQU1FICsgJyBJdGVyYXRvcicpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciAkaXRlckNyZWF0ZSA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQlVHR1kgPSAhKFtdLmtleXMgJiYgJ25leHQnIGluIFtdLmtleXMoKSk7IC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbnZhciBGRl9JVEVSQVRPUiA9ICdAQGl0ZXJhdG9yJztcbnZhciBLRVlTID0gJ2tleXMnO1xudmFyIFZBTFVFUyA9ICd2YWx1ZXMnO1xuXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEJhc2UsIE5BTUUsIENvbnN0cnVjdG9yLCBuZXh0LCBERUZBVUxULCBJU19TRVQsIEZPUkNFRCkge1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoa2luZCkge1xuICAgIGlmICghQlVHR1kgJiYga2luZCBpbiBwcm90bykgcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgPSBOQU1FICsgJyBJdGVyYXRvcic7XG4gIHZhciBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVM7XG4gIHZhciBWQUxVRVNfQlVHID0gZmFsc2U7XG4gIHZhciBwcm90byA9IEJhc2UucHJvdG90eXBlO1xuICB2YXIgJG5hdGl2ZSA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXTtcbiAgdmFyICRkZWZhdWx0ID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVCk7XG4gIHZhciAkZW50cmllcyA9IERFRkFVTFQgPyAhREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKCdlbnRyaWVzJykgOiB1bmRlZmluZWQ7XG4gIHZhciAkYW55TmF0aXZlID0gTkFNRSA9PSAnQXJyYXknID8gcHJvdG8uZW50cmllcyB8fCAkbmF0aXZlIDogJG5hdGl2ZTtcbiAgdmFyIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYgKCRhbnlOYXRpdmUpIHtcbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKCRhbnlOYXRpdmUuY2FsbChuZXcgQmFzZSgpKSk7XG4gICAgaWYgKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlICYmIEl0ZXJhdG9yUHJvdG90eXBlLm5leHQpIHtcbiAgICAgIC8vIFNldCBAQHRvU3RyaW5nVGFnIHRvIG5hdGl2ZSBpdGVyYXRvcnNcbiAgICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG4gICAgICBpZiAoIUxJQlJBUlkgJiYgdHlwZW9mIEl0ZXJhdG9yUHJvdG90eXBlW0lURVJBVE9SXSAhPSAnZnVuY3Rpb24nKSBoaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG4gICAgfVxuICB9XG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcbiAgaWYgKERFRl9WQUxVRVMgJiYgJG5hdGl2ZSAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUykge1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZiAoKCFMSUJSQVJZIHx8IEZPUkNFRCkgJiYgKEJVR0dZIHx8IFZBTFVFU19CVUcgfHwgIXByb3RvW0lURVJBVE9SXSkpIHtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddID0gcmV0dXJuVGhpcztcbiAgaWYgKERFRkFVTFQpIHtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6IElTX1NFVCA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKEtFWVMpLFxuICAgICAgZW50cmllczogJGVudHJpZXNcbiAgICB9O1xuICAgIGlmIChGT1JDRUQpIGZvciAoa2V5IGluIG1ldGhvZHMpIHtcbiAgICAgIGlmICghKGtleSBpbiBwcm90bykpIHJlZGVmaW5lKHByb3RvLCBrZXksIG1ldGhvZHNba2V5XSk7XG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcbiAgfVxuICByZXR1cm4gbWV0aG9kcztcbn07XG4iLCJ2YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbiAoKSB7IFNBRkVfQ0xPU0lORyA9IHRydWU7IH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uICgpIHsgdGhyb3cgMjsgfSk7XG59IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYywgc2tpcENsb3NpbmcpIHtcbiAgaWYgKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKSByZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IFs3XTtcbiAgICB2YXIgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB7IGRvbmU6IHNhZmUgPSB0cnVlIH07IH07XG4gICAgYXJyW0lURVJBVE9SXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZG9uZSwgdmFsdWUpIHtcbiAgcmV0dXJuIHsgdmFsdWU6IHZhbHVlLCBkb25lOiAhIWRvbmUgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmYWxzZTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBtYWNyb3Rhc2sgPSByZXF1aXJlKCcuL190YXNrJykuc2V0O1xudmFyIE9ic2VydmVyID0gZ2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgZ2xvYmFsLldlYktpdE11dGF0aW9uT2JzZXJ2ZXI7XG52YXIgcHJvY2VzcyA9IGdsb2JhbC5wcm9jZXNzO1xudmFyIFByb21pc2UgPSBnbG9iYWwuUHJvbWlzZTtcbnZhciBpc05vZGUgPSByZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaGVhZCwgbGFzdCwgbm90aWZ5O1xuXG4gIHZhciBmbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcGFyZW50LCBmbjtcbiAgICBpZiAoaXNOb2RlICYmIChwYXJlbnQgPSBwcm9jZXNzLmRvbWFpbikpIHBhcmVudC5leGl0KCk7XG4gICAgd2hpbGUgKGhlYWQpIHtcbiAgICAgIGZuID0gaGVhZC5mbjtcbiAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICB0cnkge1xuICAgICAgICBmbigpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaGVhZCkgbm90aWZ5KCk7XG4gICAgICAgIGVsc2UgbGFzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LmVudGVyKCk7XG4gIH07XG5cbiAgLy8gTm9kZS5qc1xuICBpZiAoaXNOb2RlKSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgfTtcbiAgLy8gYnJvd3NlcnMgd2l0aCBNdXRhdGlvbk9ic2VydmVyLCBleGNlcHQgaU9TIFNhZmFyaSAtIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8zMzlcbiAgfSBlbHNlIGlmIChPYnNlcnZlciAmJiAhKGdsb2JhbC5uYXZpZ2F0b3IgJiYgZ2xvYmFsLm5hdmlnYXRvci5zdGFuZGFsb25lKSkge1xuICAgIHZhciB0b2dnbGUgPSB0cnVlO1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICAgIG5ldyBPYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlID0gIXRvZ2dsZTtcbiAgICB9O1xuICAvLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxuICB9IGVsc2UgaWYgKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKSB7XG4gICAgLy8gUHJvbWlzZS5yZXNvbHZlIHdpdGhvdXQgYW4gYXJndW1lbnQgdGhyb3dzIGFuIGVycm9yIGluIExHIFdlYk9TIDJcbiAgICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHByb21pc2UudGhlbihmbHVzaCk7XG4gICAgfTtcbiAgLy8gZm9yIG90aGVyIGVudmlyb25tZW50cyAtIG1hY3JvdGFzayBiYXNlZCBvbjpcbiAgLy8gLSBzZXRJbW1lZGlhdGVcbiAgLy8gLSBNZXNzYWdlQ2hhbm5lbFxuICAvLyAtIHdpbmRvdy5wb3N0TWVzc2FnXG4gIC8vIC0gb25yZWFkeXN0YXRlY2hhbmdlXG4gIC8vIC0gc2V0VGltZW91dFxuICB9IGVsc2Uge1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHN0cmFuZ2UgSUUgKyB3ZWJwYWNrIGRldiBzZXJ2ZXIgYnVnIC0gdXNlIC5jYWxsKGdsb2JhbClcbiAgICAgIG1hY3JvdGFzay5jYWxsKGdsb2JhbCwgZmx1c2gpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKGZuKSB7XG4gICAgdmFyIHRhc2sgPSB7IGZuOiBmbiwgbmV4dDogdW5kZWZpbmVkIH07XG4gICAgaWYgKGxhc3QpIGxhc3QubmV4dCA9IHRhc2s7XG4gICAgaWYgKCFoZWFkKSB7XG4gICAgICBoZWFkID0gdGFzaztcbiAgICAgIG5vdGlmeSgpO1xuICAgIH0gbGFzdCA9IHRhc2s7XG4gIH07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjUuNC4xLjUgTmV3UHJvbWlzZUNhcGFiaWxpdHkoQylcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5cbmZ1bmN0aW9uIFByb21pc2VDYXBhYmlsaXR5KEMpIHtcbiAgdmFyIHJlc29sdmUsIHJlamVjdDtcbiAgdGhpcy5wcm9taXNlID0gbmV3IEMoZnVuY3Rpb24gKCQkcmVzb2x2ZSwgJCRyZWplY3QpIHtcbiAgICBpZiAocmVzb2x2ZSAhPT0gdW5kZWZpbmVkIHx8IHJlamVjdCAhPT0gdW5kZWZpbmVkKSB0aHJvdyBUeXBlRXJyb3IoJ0JhZCBQcm9taXNlIGNvbnN0cnVjdG9yJyk7XG4gICAgcmVzb2x2ZSA9ICQkcmVzb2x2ZTtcbiAgICByZWplY3QgPSAkJHJlamVjdDtcbiAgfSk7XG4gIHRoaXMucmVzb2x2ZSA9IGFGdW5jdGlvbihyZXNvbHZlKTtcbiAgdGhpcy5yZWplY3QgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZiA9IGZ1bmN0aW9uIChDKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZUNhcGFiaWxpdHkoQyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4yLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSwgLi4uKVxudmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIGdPUFMgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wcycpO1xudmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgJGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5cbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxubW9kdWxlLmV4cG9ydHMgPSAhJGFzc2lnbiB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgdmFyIEEgPSB7fTtcbiAgdmFyIEIgPSB7fTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIHZhciBTID0gU3ltYm9sKCk7XG4gIHZhciBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGspIHsgQltrXSA9IGs7IH0pO1xuICByZXR1cm4gJGFzc2lnbih7fSwgQSlbU10gIT0gNyB8fCBPYmplY3Qua2V5cygkYXNzaWduKHt9LCBCKSkuam9pbignJykgIT0gSztcbn0pID8gZnVuY3Rpb24gYXNzaWduKHRhcmdldCwgc291cmNlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgPSB0b09iamVjdCh0YXJnZXQpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IDE7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICB2YXIgaXNFbnVtID0gcElFLmY7XG4gIHdoaWxlIChhTGVuID4gaW5kZXgpIHtcbiAgICB2YXIgUyA9IElPYmplY3QoYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICB2YXIga2V5cyA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUyk7XG4gICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICAgIHZhciBqID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBqKSBpZiAoaXNFbnVtLmNhbGwoUywga2V5ID0ga2V5c1tqKytdKSkgVFtrZXldID0gU1trZXldO1xuICB9IHJldHVybiBUO1xufSA6ICRhc3NpZ247XG4iLCIvLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGRQcyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBFbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxudmFyIGNyZWF0ZURpY3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpO1xuICB2YXIgaSA9IGVudW1CdWdLZXlzLmxlbmd0aDtcbiAgdmFyIGx0ID0gJzwnO1xuICB2YXIgZ3QgPSAnPic7XG4gIHZhciBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xuICB3aGlsZSAoaS0tKSBkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0O1xuICBpZiAoTyAhPT0gbnVsbCkge1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcbiAgICByZXN1bHQgPSBuZXcgRW1wdHkoKTtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcbiAgICAvLyBhZGQgXCJfX3Byb3RvX19cIiBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mIHBvbHlmaWxsXG4gICAgcmVzdWx0W0lFX1BST1RPXSA9IE87XG4gIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XG4gIHJldHVybiBQcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiBkUHMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBkUCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgYW5PYmplY3QoQXR0cmlidXRlcyk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZFAoTywgUCwgQXR0cmlidXRlcyk7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICBpZiAoJ2dldCcgaW4gQXR0cmlidXRlcyB8fCAnc2V0JyBpbiBBdHRyaWJ1dGVzKSB0aHJvdyBUeXBlRXJyb3IoJ0FjY2Vzc29ycyBub3Qgc3VwcG9ydGVkIScpO1xuICBpZiAoJ3ZhbHVlJyBpbiBBdHRyaWJ1dGVzKSBPW1BdID0gQXR0cmlidXRlcy52YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIHZhciBrZXlzID0gZ2V0S2V5cyhQcm9wZXJ0aWVzKTtcbiAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICB2YXIgaSA9IDA7XG4gIHZhciBQO1xuICB3aGlsZSAobGVuZ3RoID4gaSkgZFAuZihPLCBQID0ga2V5c1tpKytdLCBQcm9wZXJ0aWVzW1BdKTtcbiAgcmV0dXJuIE87XG59O1xuIiwiZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcbiIsIi8vIDE5LjEuMi45IC8gMTUuMi4zLjIgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBPYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmdldFByb3RvdHlwZU9mIHx8IGZ1bmN0aW9uIChPKSB7XG4gIE8gPSB0b09iamVjdChPKTtcbiAgaWYgKGhhcyhPLCBJRV9QUk9UTykpIHJldHVybiBPW0lFX1BST1RPXTtcbiAgaWYgKHR5cGVvZiBPLmNvbnN0cnVjdG9yID09ICdmdW5jdGlvbicgJiYgTyBpbnN0YW5jZW9mIE8uY29uc3RydWN0b3IpIHtcbiAgICByZXR1cm4gTy5jb25zdHJ1Y3Rvci5wcm90b3R5cGU7XG4gIH0gcmV0dXJuIE8gaW5zdGFuY2VvZiBPYmplY3QgPyBPYmplY3RQcm90byA6IG51bGw7XG59O1xuIiwidmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBhcnJheUluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lcykge1xuICB2YXIgTyA9IHRvSU9iamVjdChvYmplY3QpO1xuICB2YXIgaSA9IDA7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGtleTtcbiAgZm9yIChrZXkgaW4gTykgaWYgKGtleSAhPSBJRV9QUk9UTykgaGFzKE8sIGtleSkgJiYgcmVzdWx0LnB1c2goa2V5KTtcbiAgLy8gRG9uJ3QgZW51bSBidWcgJiBoaWRkZW4ga2V5c1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkgaWYgKGhhcyhPLCBrZXkgPSBuYW1lc1tpKytdKSkge1xuICAgIH5hcnJheUluZGV4T2YocmVzdWx0LCBrZXkpIHx8IHJlc3VsdC5wdXNoKGtleSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvLyAxOS4xLjIuMTQgLyAxNS4yLjMuMTQgT2JqZWN0LmtleXMoTylcbnZhciAka2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJyk7XG52YXIgZW51bUJ1Z0tleXMgPSByZXF1aXJlKCcuL19lbnVtLWJ1Zy1rZXlzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyhPKSB7XG4gIHJldHVybiAka2V5cyhPLCBlbnVtQnVnS2V5cyk7XG59O1xuIiwiZXhwb3J0cy5mID0ge30ucHJvcGVydHlJc0VudW1lcmFibGU7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChleGVjKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHsgZTogZmFsc2UsIHY6IGV4ZWMoKSB9O1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHsgZTogdHJ1ZSwgdjogZSB9O1xuICB9XG59O1xuIiwidmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQywgeCkge1xuICBhbk9iamVjdChDKTtcbiAgaWYgKGlzT2JqZWN0KHgpICYmIHguY29uc3RydWN0b3IgPT09IEMpIHJldHVybiB4O1xuICB2YXIgcHJvbWlzZUNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eS5mKEMpO1xuICB2YXIgcmVzb2x2ZSA9IHByb21pc2VDYXBhYmlsaXR5LnJlc29sdmU7XG4gIHJlc29sdmUoeCk7XG4gIHJldHVybiBwcm9taXNlQ2FwYWJpbGl0eS5wcm9taXNlO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdG1hcCwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBlbnVtZXJhYmxlOiAhKGJpdG1hcCAmIDEpLFxuICAgIGNvbmZpZ3VyYWJsZTogIShiaXRtYXAgJiAyKSxcbiAgICB3cml0YWJsZTogIShiaXRtYXAgJiA0KSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfTtcbn07XG4iLCJ2YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGFyZ2V0LCBzcmMsIHNhZmUpIHtcbiAgZm9yICh2YXIga2V5IGluIHNyYykgcmVkZWZpbmUodGFyZ2V0LCBrZXksIHNyY1trZXldLCBzYWZlKTtcbiAgcmV0dXJuIHRhcmdldDtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBTUkMgPSByZXF1aXJlKCcuL191aWQnKSgnc3JjJyk7XG52YXIgJHRvU3RyaW5nID0gcmVxdWlyZSgnLi9fZnVuY3Rpb24tdG8tc3RyaW5nJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciBUUEwgPSAoJycgKyAkdG9TdHJpbmcpLnNwbGl0KFRPX1NUUklORyk7XG5cbnJlcXVpcmUoJy4vX2NvcmUnKS5pbnNwZWN0U291cmNlID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiAkdG9TdHJpbmcuY2FsbChpdCk7XG59O1xuXG4obW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTywga2V5LCB2YWwsIHNhZmUpIHtcbiAgdmFyIGlzRnVuY3Rpb24gPSB0eXBlb2YgdmFsID09ICdmdW5jdGlvbic7XG4gIGlmIChpc0Z1bmN0aW9uKSBoYXModmFsLCAnbmFtZScpIHx8IGhpZGUodmFsLCAnbmFtZScsIGtleSk7XG4gIGlmIChPW2tleV0gPT09IHZhbCkgcmV0dXJuO1xuICBpZiAoaXNGdW5jdGlvbikgaGFzKHZhbCwgU1JDKSB8fCBoaWRlKHZhbCwgU1JDLCBPW2tleV0gPyAnJyArIE9ba2V5XSA6IFRQTC5qb2luKFN0cmluZyhrZXkpKSk7XG4gIGlmIChPID09PSBnbG9iYWwpIHtcbiAgICBPW2tleV0gPSB2YWw7XG4gIH0gZWxzZSBpZiAoIXNhZmUpIHtcbiAgICBkZWxldGUgT1trZXldO1xuICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICB9IGVsc2UgaWYgKE9ba2V5XSkge1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIHtcbiAgICBoaWRlKE8sIGtleSwgdmFsKTtcbiAgfVxuLy8gYWRkIGZha2UgRnVuY3Rpb24jdG9TdHJpbmcgZm9yIGNvcnJlY3Qgd29yayB3cmFwcGVkIG1ldGhvZHMgLyBjb25zdHJ1Y3RvcnMgd2l0aCBtZXRob2RzIGxpa2UgTG9EYXNoIGlzTmF0aXZlXG59KShGdW5jdGlvbi5wcm90b3R5cGUsIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gIHJldHVybiB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nICYmIHRoaXNbU1JDXSB8fCAkdG9TdHJpbmcuY2FsbCh0aGlzKTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpO1xudmFyIFNQRUNJRVMgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChLRVkpIHtcbiAgdmFyIEMgPSBnbG9iYWxbS0VZXTtcbiAgaWYgKERFU0NSSVBUT1JTICYmIEMgJiYgIUNbU1BFQ0lFU10pIGRQLmYoQywgU1BFQ0lFUywge1xuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH1cbiAgfSk7XG59O1xuIiwidmFyIGRlZiA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgVEFHID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCB0YWcsIHN0YXQpIHtcbiAgaWYgKGl0ICYmICFoYXMoaXQgPSBzdGF0ID8gaXQgOiBpdC5wcm90b3R5cGUsIFRBRykpIGRlZihpdCwgVEFHLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHRhZyB9KTtcbn07XG4iLCJ2YXIgc2hhcmVkID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ2tleXMnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICByZXR1cm4gc2hhcmVkW2tleV0gfHwgKHNoYXJlZFtrZXldID0gdWlkKGtleSkpO1xufTtcbiIsInZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIFNIQVJFRCA9ICdfX2NvcmUtanNfc2hhcmVkX18nO1xudmFyIHN0b3JlID0gZ2xvYmFsW1NIQVJFRF0gfHwgKGdsb2JhbFtTSEFSRURdID0ge30pO1xuXG4obW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICByZXR1cm4gc3RvcmVba2V5XSB8fCAoc3RvcmVba2V5XSA9IHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IHt9KTtcbn0pKCd2ZXJzaW9ucycsIFtdKS5wdXNoKHtcbiAgdmVyc2lvbjogY29yZS52ZXJzaW9uLFxuICBtb2RlOiByZXF1aXJlKCcuL19saWJyYXJ5JykgPyAncHVyZScgOiAnZ2xvYmFsJyxcbiAgY29weXJpZ2h0OiAnwqkgMjAxOSBEZW5pcyBQdXNoa2FyZXYgKHpsb2lyb2NrLnJ1KSdcbn0pO1xuIiwiLy8gNy4zLjIwIFNwZWNpZXNDb25zdHJ1Y3RvcihPLCBkZWZhdWx0Q29uc3RydWN0b3IpXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChPLCBEKSB7XG4gIHZhciBDID0gYW5PYmplY3QoTykuY29uc3RydWN0b3I7XG4gIHZhciBTO1xuICByZXR1cm4gQyA9PT0gdW5kZWZpbmVkIHx8IChTID0gYW5PYmplY3QoQylbU1BFQ0lFU10pID09IHVuZGVmaW5lZCA/IEQgOiBhRnVuY3Rpb24oUyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobWV0aG9kLCBhcmcpIHtcbiAgcmV0dXJuICEhbWV0aG9kICYmIGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlbGVzcy1jYWxsXG4gICAgYXJnID8gbWV0aG9kLmNhbGwobnVsbCwgZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9LCAxKSA6IG1ldGhvZC5jYWxsKG51bGwpO1xuICB9KTtcbn07XG4iLCJ2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG4vLyB0cnVlICAtPiBTdHJpbmcjYXRcbi8vIGZhbHNlIC0+IFN0cmluZyNjb2RlUG9pbnRBdFxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoVE9fU1RSSU5HKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGhhdCwgcG9zKSB7XG4gICAgdmFyIHMgPSBTdHJpbmcoZGVmaW5lZCh0aGF0KSk7XG4gICAgdmFyIGkgPSB0b0ludGVnZXIocG9zKTtcbiAgICB2YXIgbCA9IHMubGVuZ3RoO1xuICAgIHZhciBhLCBiO1xuICAgIGlmIChpIDwgMCB8fCBpID49IGwpIHJldHVybiBUT19TVFJJTkcgPyAnJyA6IHVuZGVmaW5lZDtcbiAgICBhID0gcy5jaGFyQ29kZUF0KGkpO1xuICAgIHJldHVybiBhIDwgMHhkODAwIHx8IGEgPiAweGRiZmYgfHwgaSArIDEgPT09IGwgfHwgKGIgPSBzLmNoYXJDb2RlQXQoaSArIDEpKSA8IDB4ZGMwMCB8fCBiID4gMHhkZmZmXG4gICAgICA/IFRPX1NUUklORyA/IHMuY2hhckF0KGkpIDogYVxuICAgICAgOiBUT19TVFJJTkcgPyBzLnNsaWNlKGksIGkgKyAyKSA6IChhIC0gMHhkODAwIDw8IDEwKSArIChiIC0gMHhkYzAwKSArIDB4MTAwMDA7XG4gIH07XG59O1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGh0bWwgPSByZXF1aXJlKCcuL19odG1sJyk7XG52YXIgY2VsID0gcmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIHByb2Nlc3MgPSBnbG9iYWwucHJvY2VzcztcbnZhciBzZXRUYXNrID0gZ2xvYmFsLnNldEltbWVkaWF0ZTtcbnZhciBjbGVhclRhc2sgPSBnbG9iYWwuY2xlYXJJbW1lZGlhdGU7XG52YXIgTWVzc2FnZUNoYW5uZWwgPSBnbG9iYWwuTWVzc2FnZUNoYW5uZWw7XG52YXIgRGlzcGF0Y2ggPSBnbG9iYWwuRGlzcGF0Y2g7XG52YXIgY291bnRlciA9IDA7XG52YXIgcXVldWUgPSB7fTtcbnZhciBPTlJFQURZU1RBVEVDSEFOR0UgPSAnb25yZWFkeXN0YXRlY2hhbmdlJztcbnZhciBkZWZlciwgY2hhbm5lbCwgcG9ydDtcbnZhciBydW4gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpZCA9ICt0aGlzO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gIGlmIChxdWV1ZS5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcbiAgICB2YXIgZm4gPSBxdWV1ZVtpZF07XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgICBmbigpO1xuICB9XG59O1xudmFyIGxpc3RlbmVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIHJ1bi5jYWxsKGV2ZW50LmRhdGEpO1xufTtcbi8vIE5vZGUuanMgMC45KyAmIElFMTArIGhhcyBzZXRJbW1lZGlhdGUsIG90aGVyd2lzZTpcbmlmICghc2V0VGFzayB8fCAhY2xlYXJUYXNrKSB7XG4gIHNldFRhc2sgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pIHtcbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIHZhciBpID0gMTtcbiAgICB3aGlsZSAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgcXVldWVbKytjb3VudGVyXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgaW52b2tlKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbiksIGFyZ3MpO1xuICAgIH07XG4gICAgZGVmZXIoY291bnRlcik7XG4gICAgcmV0dXJuIGNvdW50ZXI7XG4gIH07XG4gIGNsZWFyVGFzayA9IGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGlkKSB7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmIChyZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2VzcycpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjdHgocnVuLCBpZCwgMSkpO1xuICAgIH07XG4gIC8vIFNwaGVyZSAoSlMgZ2FtZSBlbmdpbmUpIERpc3BhdGNoIEFQSVxuICB9IGVsc2UgaWYgKERpc3BhdGNoICYmIERpc3BhdGNoLm5vdykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBEaXNwYXRjaC5ub3coY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBCcm93c2VycyB3aXRoIE1lc3NhZ2VDaGFubmVsLCBpbmNsdWRlcyBXZWJXb3JrZXJzXG4gIH0gZWxzZSBpZiAoTWVzc2FnZUNoYW5uZWwpIHtcbiAgICBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgcG9ydCA9IGNoYW5uZWwucG9ydDI7XG4gICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaXN0ZW5lcjtcbiAgICBkZWZlciA9IGN0eChwb3J0LnBvc3RNZXNzYWdlLCBwb3J0LCAxKTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBwb3N0TWVzc2FnZSwgc2tpcCBXZWJXb3JrZXJzXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIgJiYgdHlwZW9mIHBvc3RNZXNzYWdlID09ICdmdW5jdGlvbicgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShpZCArICcnLCAnKicpO1xuICAgIH07XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lciwgZmFsc2UpO1xuICAvLyBJRTgtXG4gIH0gZWxzZSBpZiAoT05SRUFEWVNUQVRFQ0hBTkdFIGluIGNlbCgnc2NyaXB0JykpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjZWwoJ3NjcmlwdCcpKVtPTlJFQURZU1RBVEVDSEFOR0VdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICBydW4uY2FsbChpZCk7XG4gICAgICB9O1xuICAgIH07XG4gIC8vIFJlc3Qgb2xkIGJyb3dzZXJzXG4gIH0gZWxzZSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIHNldFRpbWVvdXQoY3R4KHJ1biwgaWQsIDEpLCAwKTtcbiAgICB9O1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBzZXRUYXNrLFxuICBjbGVhcjogY2xlYXJUYXNrXG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBtYXggPSBNYXRoLm1heDtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGluZGV4LCBsZW5ndGgpIHtcbiAgaW5kZXggPSB0b0ludGVnZXIoaW5kZXgpO1xuICByZXR1cm4gaW5kZXggPCAwID8gbWF4KGluZGV4ICsgbGVuZ3RoLCAwKSA6IG1pbihpbmRleCwgbGVuZ3RoKTtcbn07XG4iLCIvLyA3LjEuNCBUb0ludGVnZXJcbnZhciBjZWlsID0gTWF0aC5jZWlsO1xudmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpc05hTihpdCA9ICtpdCkgPyAwIDogKGl0ID4gMCA/IGZsb29yIDogY2VpbCkoaXQpO1xufTtcbiIsIi8vIHRvIGluZGV4ZWQgb2JqZWN0LCB0b09iamVjdCB3aXRoIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgc3RyaW5nc1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBJT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG4iLCIvLyA3LjEuMTUgVG9MZW5ndGhcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgbWluID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgPiAwID8gbWluKHRvSW50ZWdlcihpdCksIDB4MWZmZmZmZmZmZmZmZmYpIDogMDsgLy8gcG93KDIsIDUzKSAtIDEgPT0gOTAwNzE5OTI1NDc0MDk5MVxufTtcbiIsIi8vIDcuMS4xMyBUb09iamVjdChhcmd1bWVudClcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIE9iamVjdChkZWZpbmVkKGl0KSk7XG59O1xuIiwiLy8gNy4xLjEgVG9QcmltaXRpdmUoaW5wdXQgWywgUHJlZmVycmVkVHlwZV0pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbi8vIGluc3RlYWQgb2YgdGhlIEVTNiBzcGVjIHZlcnNpb24sIHdlIGRpZG4ndCBpbXBsZW1lbnQgQEB0b1ByaW1pdGl2ZSBjYXNlXG4vLyBhbmQgdGhlIHNlY29uZCBhcmd1bWVudCAtIGZsYWcgLSBwcmVmZXJyZWQgdHlwZSBpcyBhIHN0cmluZ1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIFMpIHtcbiAgaWYgKCFpc09iamVjdChpdCkpIHJldHVybiBpdDtcbiAgdmFyIGZuLCB2YWw7XG4gIGlmIChTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAodHlwZW9mIChmbiA9IGl0LnZhbHVlT2YpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgaWYgKCFTICYmIHR5cGVvZiAoZm4gPSBpdC50b1N0cmluZykgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICB0aHJvdyBUeXBlRXJyb3IoXCJDYW4ndCBjb252ZXJ0IG9iamVjdCB0byBwcmltaXRpdmUgdmFsdWVcIik7XG59O1xuIiwidmFyIGlkID0gMDtcbnZhciBweCA9IE1hdGgucmFuZG9tKCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuICdTeW1ib2woJy5jb25jYXQoa2V5ID09PSB1bmRlZmluZWQgPyAnJyA6IGtleSwgJylfJywgKCsraWQgKyBweCkudG9TdHJpbmcoMzYpKTtcbn07XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgbmF2aWdhdG9yID0gZ2xvYmFsLm5hdmlnYXRvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBuYXZpZ2F0b3IgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCAnJztcbiIsInZhciBzdG9yZSA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCd3a3MnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5TeW1ib2w7XG52YXIgVVNFX1NZTUJPTCA9IHR5cGVvZiBTeW1ib2wgPT0gJ2Z1bmN0aW9uJztcblxudmFyICRleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSkge1xuICByZXR1cm4gc3RvcmVbbmFtZV0gfHwgKHN0b3JlW25hbWVdID1cbiAgICBVU0VfU1lNQk9MICYmIFN5bWJvbFtuYW1lXSB8fCAoVVNFX1NZTUJPTCA/IFN5bWJvbCA6IHVpZCkoJ1N5bWJvbC4nICsgbmFtZSkpO1xufTtcblxuJGV4cG9ydHMuc3RvcmUgPSBzdG9yZTtcbiIsInZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2NvcmUnKS5nZXRJdGVyYXRvck1ldGhvZCA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoaXQgIT0gdW5kZWZpbmVkKSByZXR1cm4gaXRbSVRFUkFUT1JdXG4gICAgfHwgaXRbJ0BAaXRlcmF0b3InXVxuICAgIHx8IEl0ZXJhdG9yc1tjbGFzc29mKGl0KV07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjIuMS4zLjggQXJyYXkucHJvdG90eXBlLmZpbmQocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZmluZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg1KTtcbnZhciBLRVkgPSAnZmluZCc7XG52YXIgZm9yY2VkID0gdHJ1ZTtcbi8vIFNob3VsZG4ndCBza2lwIGhvbGVzXG5pZiAoS0VZIGluIFtdKSBBcnJheSgxKVtLRVldKGZ1bmN0aW9uICgpIHsgZm9yY2VkID0gZmFsc2U7IH0pO1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmb3JjZWQsICdBcnJheScsIHtcbiAgZmluZDogZnVuY3Rpb24gZmluZChjYWxsYmFja2ZuIC8qICwgdGhhdCA9IHVuZGVmaW5lZCAqLykge1xuICAgIHJldHVybiAkZmluZCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoS0VZKTtcbiIsIi8vIDIyLjEuMi4yIC8gMTUuNC4zLjIgQXJyYXkuaXNBcnJheShhcmcpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0FycmF5JywgeyBpc0FycmF5OiByZXF1aXJlKCcuL19pcy1hcnJheScpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKTtcbnZhciBzdGVwID0gcmVxdWlyZSgnLi9faXRlci1zdGVwJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xuXG4vLyAyMi4xLjMuNCBBcnJheS5wcm90b3R5cGUuZW50cmllcygpXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmtleXMoKVxuLy8gMjIuMS4zLjI5IEFycmF5LnByb3RvdHlwZS52YWx1ZXMoKVxuLy8gMjIuMS4zLjMwIEFycmF5LnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIga2luZCA9IHRoaXMuX2s7XG4gIHZhciBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYgKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKSB7XG4gICAgdGhpcy5fdCA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gc3RlcCgxKTtcbiAgfVxuICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGluZGV4KTtcbiAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHNvbWUgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5zb21lLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMjMgLyAxNS40LjQuMTcgQXJyYXkucHJvdG90eXBlLnNvbWUoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgc29tZTogZnVuY3Rpb24gc29tZShjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgIHJldHVybiAkc29tZSh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIi8vIDE5LjIuMy4yIC8gMTUuMy40LjUgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQodGhpc0FyZywgYXJncy4uLilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnRnVuY3Rpb24nLCB7IGJpbmQ6IHJlcXVpcmUoJy4vX2JpbmQnKSB9KTtcbiIsIi8vIDE5LjEuMy4xIE9iamVjdC5hc3NpZ24odGFyZ2V0LCBzb3VyY2UpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiwgJ09iamVjdCcsIHsgYXNzaWduOiByZXF1aXJlKCcuL19vYmplY3QtYXNzaWduJykgfSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjMuNiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKClcbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIHRlc3QgPSB7fTtcbnRlc3RbcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyldID0gJ3onO1xuaWYgKHRlc3QgKyAnJyAhPSAnW29iamVjdCB6XScpIHtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShPYmplY3QucHJvdG90eXBlLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gJ1tvYmplY3QgJyArIGNsYXNzb2YodGhpcykgKyAnXSc7XG4gIH0sIHRydWUpO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcbnZhciBwZXJmb3JtID0gcmVxdWlyZSgnLi9fcGVyZm9ybScpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4vX3Byb21pc2UtcmVzb2x2ZScpO1xudmFyIFBST01JU0UgPSAnUHJvbWlzZSc7XG52YXIgVHlwZUVycm9yID0gZ2xvYmFsLlR5cGVFcnJvcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgdmVyc2lvbnMgPSBwcm9jZXNzICYmIHByb2Nlc3MudmVyc2lvbnM7XG52YXIgdjggPSB2ZXJzaW9ucyAmJiB2ZXJzaW9ucy52OCB8fCAnJztcbnZhciAkUHJvbWlzZSA9IGdsb2JhbFtQUk9NSVNFXTtcbnZhciBpc05vZGUgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJztcbnZhciBlbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBJbnRlcm5hbCwgbmV3R2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBPd25Qcm9taXNlQ2FwYWJpbGl0eSwgV3JhcHBlcjtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmY7XG5cbnZhciBVU0VfTkFUSVZFID0gISFmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgLy8gY29ycmVjdCBzdWJjbGFzc2luZyB3aXRoIEBAc3BlY2llcyBzdXBwb3J0XG4gICAgdmFyIHByb21pc2UgPSAkUHJvbWlzZS5yZXNvbHZlKDEpO1xuICAgIHZhciBGYWtlUHJvbWlzZSA9IChwcm9taXNlLmNvbnN0cnVjdG9yID0ge30pW3JlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyldID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgICAgIGV4ZWMoZW1wdHksIGVtcHR5KTtcbiAgICB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpXG4gICAgICAmJiBwcm9taXNlLnRoZW4oZW1wdHkpIGluc3RhbmNlb2YgRmFrZVByb21pc2VcbiAgICAgIC8vIHY4IDYuNiAoTm9kZSAxMCBhbmQgQ2hyb21lIDY2KSBoYXZlIGEgYnVnIHdpdGggcmVzb2x2aW5nIGN1c3RvbSB0aGVuYWJsZXNcbiAgICAgIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTgzMDU2NVxuICAgICAgLy8gd2UgY2FuJ3QgZGV0ZWN0IGl0IHN5bmNocm9ub3VzbHksIHNvIGp1c3QgY2hlY2sgdmVyc2lvbnNcbiAgICAgICYmIHY4LmluZGV4T2YoJzYuNicpICE9PSAwXG4gICAgICAmJiB1c2VyQWdlbnQuaW5kZXhPZignQ2hyb21lLzY2JykgPT09IC0xO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn0oKTtcblxuLy8gaGVscGVyc1xudmFyIGlzVGhlbmFibGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIHRoZW47XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcbn07XG52YXIgbm90aWZ5ID0gZnVuY3Rpb24gKHByb21pc2UsIGlzUmVqZWN0KSB7XG4gIGlmIChwcm9taXNlLl9uKSByZXR1cm47XG4gIHByb21pc2UuX24gPSB0cnVlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9jO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIG9rID0gcHJvbWlzZS5fcyA9PSAxO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24gKHJlYWN0aW9uKSB7XG4gICAgICB2YXIgaGFuZGxlciA9IG9rID8gcmVhY3Rpb24ub2sgOiByZWFjdGlvbi5mYWlsO1xuICAgICAgdmFyIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlO1xuICAgICAgdmFyIHJlamVjdCA9IHJlYWN0aW9uLnJlamVjdDtcbiAgICAgIHZhciBkb21haW4gPSByZWFjdGlvbi5kb21haW47XG4gICAgICB2YXIgcmVzdWx0LCB0aGVuLCBleGl0ZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgIGlmIChwcm9taXNlLl9oID09IDIpIG9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xuICAgICAgICAgICAgcHJvbWlzZS5faCA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChoYW5kbGVyID09PSB0cnVlKSByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkb21haW4pIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7IC8vIG1heSB0aHJvd1xuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICBleGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKSB7XG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGRvbWFpbiAmJiAhZXhpdGVkKSBkb21haW4uZXhpdCgpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aGlsZSAoY2hhaW4ubGVuZ3RoID4gaSkgcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYgKGlzUmVqZWN0ICYmICFwcm9taXNlLl9oKSBvblVuaGFuZGxlZChwcm9taXNlKTtcbiAgfSk7XG59O1xudmFyIG9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgdGFzay5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIHVuaGFuZGxlZCA9IGlzVW5oYW5kbGVkKHByb21pc2UpO1xuICAgIHZhciByZXN1bHQsIGhhbmRsZXIsIGNvbnNvbGU7XG4gICAgaWYgKHVuaGFuZGxlZCkge1xuICAgICAgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChpc05vZGUpIHtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYW5kbGVyID0gZ2xvYmFsLm9udW5oYW5kbGVkcmVqZWN0aW9uKSB7XG4gICAgICAgICAgaGFuZGxlcih7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKGNvbnNvbGUgPSBnbG9iYWwuY29uc29sZSkgJiYgY29uc29sZS5lcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZiAodW5oYW5kbGVkICYmIHJlc3VsdC5lKSB0aHJvdyByZXN1bHQudjtcbiAgfSk7XG59O1xudmFyIGlzVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgcmV0dXJuIHByb21pc2UuX2ggIT09IDEgJiYgKHByb21pc2UuX2EgfHwgcHJvbWlzZS5fYykubGVuZ3RoID09PSAwO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFuZGxlcjtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYgKGhhbmRsZXIgPSBnbG9iYWwub25yZWplY3Rpb25oYW5kbGVkKSB7XG4gICAgICBoYW5kbGVyKHsgcHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92IH0pO1xuICAgIH1cbiAgfSk7XG59O1xudmFyICRyZWplY3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fcyA9IDI7XG4gIGlmICghcHJvbWlzZS5fYSkgcHJvbWlzZS5fYSA9IHByb21pc2UuX2Muc2xpY2UoKTtcbiAgbm90aWZ5KHByb21pc2UsIHRydWUpO1xufTtcbnZhciAkcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIHZhciB0aGVuO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB0aHJvdyBUeXBlRXJyb3IoXCJQcm9taXNlIGNhbid0IGJlIHJlc29sdmVkIGl0c2VsZlwiKTtcbiAgICBpZiAodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKSB7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgd3JhcHBlciA9IHsgX3c6IHByb21pc2UsIF9kOiBmYWxzZSB9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgJHJlamVjdC5jYWxsKHdyYXBwZXIsIGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZS5fdiA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fcyA9IDE7XG4gICAgICBub3RpZnkocHJvbWlzZSwgZmFsc2UpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgICRyZWplY3QuY2FsbCh7IF93OiBwcm9taXNlLCBfZDogZmFsc2UgfSwgZSk7IC8vIHdyYXBcbiAgfVxufTtcblxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcbmlmICghVVNFX05BVElWRSkge1xuICAvLyAyNS40LjMuMSBQcm9taXNlKGV4ZWN1dG9yKVxuICAkUHJvbWlzZSA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRQcm9taXNlLCBQUk9NSVNFLCAnX2gnKTtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGN0eCgkcmVzb2x2ZSwgdGhpcywgMSksIGN0eCgkcmVqZWN0LCB0aGlzLCAxKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAkcmVqZWN0LmNhbGwodGhpcywgZXJyKTtcbiAgICB9XG4gIH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBJbnRlcm5hbCA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgIHZhciByZWFjdGlvbiA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkUHJvbWlzZSkpO1xuICAgICAgcmVhY3Rpb24ub2sgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgPSB0eXBlb2Ygb25SZWplY3RlZCA9PSAnZnVuY3Rpb24nICYmIG9uUmVqZWN0ZWQ7XG4gICAgICByZWFjdGlvbi5kb21haW4gPSBpc05vZGUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX2MucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAodGhpcy5fYSkgdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmICh0aGlzLl9zKSBub3RpZnkodGhpcywgZmFsc2UpO1xuICAgICAgcmV0dXJuIHJlYWN0aW9uLnByb21pc2U7XG4gICAgfSxcbiAgICAvLyAyNS40LjUuMSBQcm9taXNlLnByb3RvdHlwZS5jYXRjaChvblJlamVjdGVkKVxuICAgICdjYXRjaCc6IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy50aGVuKHVuZGVmaW5lZCwgb25SZWplY3RlZCk7XG4gICAgfVxuICB9KTtcbiAgT3duUHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgSW50ZXJuYWwoKTtcbiAgICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xuICAgIHRoaXMucmVzb2x2ZSA9IGN0eCgkcmVzb2x2ZSwgcHJvbWlzZSwgMSk7XG4gICAgdGhpcy5yZWplY3QgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG4gIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmYgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uIChDKSB7XG4gICAgcmV0dXJuIEMgPT09ICRQcm9taXNlIHx8IEMgPT09IFdyYXBwZXJcbiAgICAgID8gbmV3IE93blByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICA6IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgfTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgeyBQcm9taXNlOiAkUHJvbWlzZSB9KTtcbnJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJykoJFByb21pc2UsIFBST01JU0UpO1xucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShQUk9NSVNFKTtcbldyYXBwZXIgPSByZXF1aXJlKCcuL19jb3JlJylbUFJPTUlTRV07XG5cbi8vIHN0YXRpY3NcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjUgUHJvbWlzZS5yZWplY3QocilcbiAgcmVqZWN0OiBmdW5jdGlvbiByZWplY3Qocikge1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcyk7XG4gICAgdmFyICQkcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgJCRyZWplY3Qocik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChMSUJSQVJZIHx8ICFVU0VfTkFUSVZFKSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNiBQcm9taXNlLnJlc29sdmUoeClcbiAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKExJQlJBUlkgJiYgdGhpcyA9PT0gV3JhcHBlciA/ICRQcm9taXNlIDogdGhpcywgeCk7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKFVTRV9OQVRJVkUgJiYgcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikge1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICAgIHZhciBDID0gdGhpcztcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpO1xuICAgIHZhciByZXNvbHZlID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgIHZhciByZWplY3QgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgdmFyIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgIHZhciAkaW5kZXggPSBpbmRleCsrO1xuICAgICAgICB2YXIgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKGFscmVhZHlDYWxsZWQpIHJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuZSkgcmVqZWN0KHJlc3VsdC52KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICBDLnJlc29sdmUocHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmUpIHJlamVjdChyZXN1bHQudik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24gKGl0ZXJhdGVkKSB7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIgaW5kZXggPSB0aGlzLl9pO1xuICB2YXIgcG9pbnQ7XG4gIGlmIChpbmRleCA+PSBPLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4geyB2YWx1ZTogcG9pbnQsIGRvbmU6IGZhbHNlIH07XG59KTtcbiIsInZhciAkaXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciBJVEVSQVRPUiA9IHdrcygnaXRlcmF0b3InKTtcbnZhciBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xudmFyIEFycmF5VmFsdWVzID0gSXRlcmF0b3JzLkFycmF5O1xuXG52YXIgRE9NSXRlcmFibGVzID0ge1xuICBDU1NSdWxlTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIENTU1N0eWxlRGVjbGFyYXRpb246IGZhbHNlLFxuICBDU1NWYWx1ZUxpc3Q6IGZhbHNlLFxuICBDbGllbnRSZWN0TGlzdDogZmFsc2UsXG4gIERPTVJlY3RMaXN0OiBmYWxzZSxcbiAgRE9NU3RyaW5nTGlzdDogZmFsc2UsXG4gIERPTVRva2VuTGlzdDogdHJ1ZSxcbiAgRGF0YVRyYW5zZmVySXRlbUxpc3Q6IGZhbHNlLFxuICBGaWxlTGlzdDogZmFsc2UsXG4gIEhUTUxBbGxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTENvbGxlY3Rpb246IGZhbHNlLFxuICBIVE1MRm9ybUVsZW1lbnQ6IGZhbHNlLFxuICBIVE1MU2VsZWN0RWxlbWVudDogZmFsc2UsXG4gIE1lZGlhTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIE1pbWVUeXBlQXJyYXk6IGZhbHNlLFxuICBOYW1lZE5vZGVNYXA6IGZhbHNlLFxuICBOb2RlTGlzdDogdHJ1ZSxcbiAgUGFpbnRSZXF1ZXN0TGlzdDogZmFsc2UsXG4gIFBsdWdpbjogZmFsc2UsXG4gIFBsdWdpbkFycmF5OiBmYWxzZSxcbiAgU1ZHTGVuZ3RoTGlzdDogZmFsc2UsXG4gIFNWR051bWJlckxpc3Q6IGZhbHNlLFxuICBTVkdQYXRoU2VnTGlzdDogZmFsc2UsXG4gIFNWR1BvaW50TGlzdDogZmFsc2UsXG4gIFNWR1N0cmluZ0xpc3Q6IGZhbHNlLFxuICBTVkdUcmFuc2Zvcm1MaXN0OiBmYWxzZSxcbiAgU291cmNlQnVmZmVyTGlzdDogZmFsc2UsXG4gIFN0eWxlU2hlZXRMaXN0OiB0cnVlLCAvLyBUT0RPOiBOb3Qgc3BlYyBjb21wbGlhbnQsIHNob3VsZCBiZSBmYWxzZS5cbiAgVGV4dFRyYWNrQ3VlTGlzdDogZmFsc2UsXG4gIFRleHRUcmFja0xpc3Q6IGZhbHNlLFxuICBUb3VjaExpc3Q6IGZhbHNlXG59O1xuXG5mb3IgKHZhciBjb2xsZWN0aW9ucyA9IGdldEtleXMoRE9NSXRlcmFibGVzKSwgaSA9IDA7IGkgPCBjb2xsZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICB2YXIgTkFNRSA9IGNvbGxlY3Rpb25zW2ldO1xuICB2YXIgZXhwbGljaXQgPSBET01JdGVyYWJsZXNbTkFNRV07XG4gIHZhciBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgcHJvdG8gPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICB2YXIga2V5O1xuICBpZiAocHJvdG8pIHtcbiAgICBpZiAoIXByb3RvW0lURVJBVE9SXSkgaGlkZShwcm90bywgSVRFUkFUT1IsIEFycmF5VmFsdWVzKTtcbiAgICBpZiAoIXByb3RvW1RPX1NUUklOR19UQUddKSBoaWRlKHByb3RvLCBUT19TVFJJTkdfVEFHLCBOQU1FKTtcbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBBcnJheVZhbHVlcztcbiAgICBpZiAoZXhwbGljaXQpIGZvciAoa2V5IGluICRpdGVyYXRvcnMpIGlmICghcHJvdG9ba2V5XSkgcmVkZWZpbmUocHJvdG8sIGtleSwgJGl0ZXJhdG9yc1trZXldLCB0cnVlKTtcbiAgfVxufVxuIiwiZXhwb3J0cy5yZWFkID0gZnVuY3Rpb24gKGJ1ZmZlciwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG1cbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSAoZSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBlID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBtTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSAobSAqIDI1NikgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCkge31cblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXNcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpXG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBNYXRoLnBvdygyLCBtTGVuKVxuICAgIGUgPSBlIC0gZUJpYXNcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKVxufVxuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24gKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjXG4gIHZhciBlTGVuID0gKG5CeXRlcyAqIDgpIC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICgodmFsdWUgKiBjKSAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSBlICsgZUJpYXNcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gMFxuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBtTGVuID49IDg7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IG0gJiAweGZmLCBpICs9IGQsIG0gLz0gMjU2LCBtTGVuIC09IDgpIHt9XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbVxuICBlTGVuICs9IG1MZW5cbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBlICYgMHhmZiwgaSArPSBkLCBlIC89IDI1NiwgZUxlbiAtPSA4KSB7fVxuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyOFxufVxuIiwiLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG52YXIgYnl0ZVRvSGV4ID0gW107XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gIGJ5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG59XG5cbmZ1bmN0aW9uIGJ5dGVzVG9VdWlkKGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gb2Zmc2V0IHx8IDA7XG4gIHZhciBidGggPSBieXRlVG9IZXg7XG4gIC8vIGpvaW4gdXNlZCB0byBmaXggbWVtb3J5IGlzc3VlIGNhdXNlZCBieSBjb25jYXRlbmF0aW9uOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMTc1I2M0XG4gIHJldHVybiAoW2J0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sIFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV1dKS5qb2luKCcnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBieXRlc1RvVXVpZDtcbiIsIi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBJbiB0aGVcbi8vIGJyb3dzZXIgdGhpcyBpcyBhIGxpdHRsZSBjb21wbGljYXRlZCBkdWUgdG8gdW5rbm93biBxdWFsaXR5IG9mIE1hdGgucmFuZG9tKClcbi8vIGFuZCBpbmNvbnNpc3RlbnQgc3VwcG9ydCBmb3IgdGhlIGBjcnlwdG9gIEFQSS4gIFdlIGRvIHRoZSBiZXN0IHdlIGNhbiB2aWFcbi8vIGZlYXR1cmUtZGV0ZWN0aW9uXG5cbi8vIGdldFJhbmRvbVZhbHVlcyBuZWVkcyB0byBiZSBpbnZva2VkIGluIGEgY29udGV4dCB3aGVyZSBcInRoaXNcIiBpcyBhIENyeXB0b1xuLy8gaW1wbGVtZW50YXRpb24uIEFsc28sIGZpbmQgdGhlIGNvbXBsZXRlIGltcGxlbWVudGF0aW9uIG9mIGNyeXB0byBvbiBJRTExLlxudmFyIGdldFJhbmRvbVZhbHVlcyA9ICh0eXBlb2YoY3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICh0eXBlb2YobXNDcnlwdG8pICE9ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzID09ICdmdW5jdGlvbicgJiYgbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQobXNDcnlwdG8pKTtcblxuaWYgKGdldFJhbmRvbVZhbHVlcykge1xuICAvLyBXSEFUV0cgY3J5cHRvIFJORyAtIGh0dHA6Ly93aWtpLndoYXR3Zy5vcmcvd2lraS9DcnlwdG9cbiAgdmFyIHJuZHM4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB3aGF0d2dSTkcoKSB7XG4gICAgZ2V0UmFuZG9tVmFsdWVzKHJuZHM4KTtcbiAgICByZXR1cm4gcm5kczg7XG4gIH07XG59IGVsc2Uge1xuICAvLyBNYXRoLnJhbmRvbSgpLWJhc2VkIChSTkcpXG4gIC8vXG4gIC8vIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgTWF0aC5yYW5kb20oKS4gIEl0J3MgZmFzdCwgYnV0IGlzIG9mIHVuc3BlY2lmaWVkXG4gIC8vIHF1YWxpdHkuXG4gIHZhciBybmRzID0gbmV3IEFycmF5KDE2KTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1hdGhSTkcoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIHI7IGkgPCAxNjsgaSsrKSB7XG4gICAgICBpZiAoKGkgJiAweDAzKSA9PT0gMCkgciA9IE1hdGgucmFuZG9tKCkgKiAweDEwMDAwMDAwMDtcbiAgICAgIHJuZHNbaV0gPSByID4+PiAoKGkgJiAweDAzKSA8PCAzKSAmIDB4ZmY7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJuZHM7XG4gIH07XG59XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICB2YXIgaSA9IGJ1ZiAmJiBvZmZzZXQgfHwgMDtcblxuICBpZiAodHlwZW9mKG9wdGlvbnMpID09ICdzdHJpbmcnKSB7XG4gICAgYnVmID0gb3B0aW9ucyA9PT0gJ2JpbmFyeScgPyBuZXcgQXJyYXkoMTYpIDogbnVsbDtcbiAgICBvcHRpb25zID0gbnVsbDtcbiAgfVxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBybmcpKCk7XG5cbiAgLy8gUGVyIDQuNCwgc2V0IGJpdHMgZm9yIHZlcnNpb24gYW5kIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYFxuICBybmRzWzZdID0gKHJuZHNbNl0gJiAweDBmKSB8IDB4NDA7XG4gIHJuZHNbOF0gPSAocm5kc1s4XSAmIDB4M2YpIHwgMHg4MDtcblxuICAvLyBDb3B5IGJ5dGVzIHRvIGJ1ZmZlciwgaWYgcHJvdmlkZWRcbiAgaWYgKGJ1Zikge1xuICAgIGZvciAodmFyIGlpID0gMDsgaWkgPCAxNjsgKytpaSkge1xuICAgICAgYnVmW2kgKyBpaV0gPSBybmRzW2lpXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIHx8IGJ5dGVzVG9VdWlkKHJuZHMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHY0O1xuIiwidmFyIGc7XG5cbi8vIFRoaXMgd29ya3MgaW4gbm9uLXN0cmljdCBtb2RlXG5nID0gKGZ1bmN0aW9uKCkge1xuXHRyZXR1cm4gdGhpcztcbn0pKCk7XG5cbnRyeSB7XG5cdC8vIFRoaXMgd29ya3MgaWYgZXZhbCBpcyBhbGxvd2VkIChzZWUgQ1NQKVxuXHRnID0gZyB8fCBuZXcgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpO1xufSBjYXRjaCAoZSkge1xuXHQvLyBUaGlzIHdvcmtzIGlmIHRoZSB3aW5kb3cgcmVmZXJlbmNlIGlzIGF2YWlsYWJsZVxuXHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIikgZyA9IHdpbmRvdztcbn1cblxuLy8gZyBjYW4gc3RpbGwgYmUgdW5kZWZpbmVkLCBidXQgbm90aGluZyB0byBkbyBhYm91dCBpdC4uLlxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3Ncbi8vIGVhc2llciB0byBoYW5kbGUgdGhpcyBjYXNlLiBpZighZ2xvYmFsKSB7IC4uLn1cblxubW9kdWxlLmV4cG9ydHMgPSBnO1xuIiwiLy8gRGVjbGFyZSB0aGUgRVM2IGZlYXR1cmVzIHdlJ3JlIHVzaW5nXHJcblxyXG4vLyBUT0RPOiBDb25zaWRlciB1c2luZyB0aGUgbG9jYWwgZnVuY3Rpb24gdmVyc2lvbnMgb2YgdGhlc2UsIHNvIHRoYXQgd2VcclxuLy8gYXZvaWQgbW9kaWZ5aW5nIGJyb3dzZXIgZ2xvYmFscyAocG90ZW50aWFsIGZvciBpbnRlcm9wIGJ1Z3Mgd2l0aCBvdGhlciBsaWJyYXJpZXNcclxuLy8gb24gdGhlIHBhZ2UgdGhhdCBtaWdodCBiZSBwb2x5ZmlsbGluZyBFUzYgZmVhdHVyZXMpXHJcblxyXG5pbXBvcnQgJ2NvcmUtanMvZXM2L3Byb21pc2UnO1xyXG5pbXBvcnQgJ2NvcmUtanMvZm4vZnVuY3Rpb24vYmluZCc7XHJcbmltcG9ydCAnY29yZS1qcy9mbi9vYmplY3QvYXNzaWduJztcclxuaW1wb3J0ICdjb3JlLWpzL2ZuL2FycmF5L2ZpbmQnO1xyXG5pbXBvcnQgJ2NvcmUtanMvZm4vYXJyYXkvc29tZSc7XHJcbmltcG9ydCAnY29yZS1qcy9mbi9hcnJheS9pcy1hcnJheSc7XHJcbmltcG9ydCAnY29yZS1qcy9mbi9hcnJheS9zcGxpY2UnO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFRpbWVyIH0gZnJvbSAnLi9UaW1lci5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIEFjY2Vzc1Rva2VuRXZlbnRzIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ1RpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyaW5nXCIpLFxyXG4gICAgICAgIGFjY2Vzc1Rva2VuRXhwaXJlZFRpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyZWRcIilcclxuICAgIH0gPSB7fSkge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcgPSBhY2Nlc3NUb2tlbkV4cGlyaW5nVGltZXI7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkID0gYWNjZXNzVG9rZW5FeHBpcmVkVGltZXI7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZChjb250YWluZXIpIHtcclxuICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV2ZW50cyBpZiB0aGVyZSdzIGFuIGFjY2VzcyB0b2tlbiBhbmQgaXQgaGFzIGFuIGV4cGlyYXRpb25cclxuICAgICAgICBpZiAoY29udGFpbmVyLmFjY2Vzc190b2tlbiAmJiBjb250YWluZXIuZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbiA9IGNvbnRhaW5lci5leHBpcmVzX2luO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiBhY2Nlc3MgdG9rZW4gcHJlc2VudCwgcmVtYWluaW5nIGR1cmF0aW9uOlwiLCBkdXJhdGlvbik7XHJcblxyXG4gICAgICAgICAgICBpZiAoZHVyYXRpb24gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV4cGlyaW5nIGlmIHdlIHN0aWxsIGhhdmUgdGltZVxyXG4gICAgICAgICAgICAgICAgbGV0IGV4cGlyaW5nID0gZHVyYXRpb24gLSB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgICAgICAgICAgICAgIGlmIChleHBpcmluZyA8PSAwKXtcclxuICAgICAgICAgICAgICAgICAgICBleHBpcmluZyA9IDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkFjY2Vzc1Rva2VuRXZlbnRzLmxvYWQ6IHJlZ2lzdGVyaW5nIGV4cGlyaW5nIHRpbWVyIGluOlwiLCBleHBpcmluZyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmluaXQoZXhwaXJpbmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQWNjZXNzVG9rZW5FdmVudHMubG9hZDogY2FuY2VsaW5nIGV4aXN0aW5nIGV4cGlyaW5nIHRpbWVyIGJlY2FzZSB3ZSdyZSBwYXN0IGV4cGlyYXRpb24uXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmluZy5jYW5jZWwoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaWYgaXQncyBuZWdhdGl2ZSwgaXQgd2lsbCBzdGlsbCBmaXJlXHJcbiAgICAgICAgICAgIGxldCBleHBpcmVkID0gZHVyYXRpb24gKyAxO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiByZWdpc3RlcmluZyBleHBpcmVkIHRpbWVyIGluOlwiLCBleHBpcmVkKTtcclxuICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmluaXQoZXhwaXJlZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmNhbmNlbCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyZWQuY2FuY2VsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHVubG9hZCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy51bmxvYWQ6IGNhbmNlbGluZyBleGlzdGluZyBhY2Nlc3MgdG9rZW4gdGltZXJzXCIpO1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcuY2FuY2VsKCk7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmNhbmNlbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZEFjY2Vzc1Rva2VuRXhwaXJpbmcoY2IpIHtcclxuICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmluZyhjYikge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRJbnRlcnZhbCA9IDIwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgQ2hlY2tTZXNzaW9uSUZyYW1lIHtcclxuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCBjbGllbnRfaWQsIHVybCwgaW50ZXJ2YWwsIHN0b3BPbkVycm9yID0gdHJ1ZSkge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX3VybCA9IHVybDtcclxuICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IGludGVydmFsIHx8IERlZmF1bHRJbnRlcnZhbDtcclxuICAgICAgICB0aGlzLl9zdG9wT25FcnJvciA9IHN0b3BPbkVycm9yO1xyXG5cclxuICAgICAgICB2YXIgaWR4ID0gdXJsLmluZGV4T2YoXCIvXCIsIHVybC5pbmRleE9mKFwiLy9cIikgKyAyKTtcclxuICAgICAgICB0aGlzLl9mcmFtZV9vcmlnaW4gPSB1cmwuc3Vic3RyKDAsIGlkeCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpZnJhbWVcIik7XHJcblxyXG4gICAgICAgIC8vIHNob3RndW4gYXBwcm9hY2hcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUud2lkdGggPSAwO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmhlaWdodCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnNyYyA9IHVybDtcclxuICAgIH1cclxuICAgIGxvYWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfbWVzc2FnZShlKSB7XHJcbiAgICAgICAgaWYgKGUub3JpZ2luID09PSB0aGlzLl9mcmFtZV9vcmlnaW4gJiZcclxuICAgICAgICAgICAgZS5zb3VyY2UgPT09IHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3dcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgaWYgKGUuZGF0YSA9PT0gXCJlcnJvclwiKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJDaGVja1Nlc3Npb25JRnJhbWU6IGVycm9yIG1lc3NhZ2UgZnJvbSBjaGVjayBzZXNzaW9uIG9wIGlmcmFtZVwiKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdG9wT25FcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGUuZGF0YSA9PT0gXCJjaGFuZ2VkXCIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZTogY2hhbmdlZCBtZXNzYWdlIGZyb20gY2hlY2sgc2Vzc2lvbiBvcCBpZnJhbWVcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJDaGVja1Nlc3Npb25JRnJhbWU6IFwiICsgZS5kYXRhICsgXCIgbWVzc2FnZSBmcm9tIGNoZWNrIHNlc3Npb24gb3AgaWZyYW1lXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhcnQoc2Vzc2lvbl9zdGF0ZSkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXNzaW9uX3N0YXRlICE9PSBzZXNzaW9uX3N0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdGFydFwiKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcblxyXG4gICAgICAgICAgICBsZXQgc2VuZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UodGhpcy5fY2xpZW50X2lkICsgXCIgXCIgKyB0aGlzLl9zZXNzaW9uX3N0YXRlLCB0aGlzLl9mcmFtZV9vcmlnaW4pO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBub3dcclxuICAgICAgICAgICAgc2VuZCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gYW5kIHNldHVwIHRpbWVyXHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldEludGVydmFsKHNlbmQsIHRoaXMuX2ludGVydmFsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc3RvcCgpIHtcclxuICAgICAgICB0aGlzLl9zZXNzaW9uX3N0YXRlID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdG9wXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IENvcmRvdmFQb3B1cFdpbmRvdyB9IGZyb20gJy4vQ29yZG92YVBvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzID0gJ2hpZGRlbj15ZXMnO1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBDb3Jkb3ZhUG9wdXBXaW5kb3cgfSBmcm9tICcuL0NvcmRvdmFQb3B1cFdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgQ29yZG92YVBvcHVwTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHpvb209bm8nO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIENvcmRvdmFQb3B1cFdpbmRvdyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IocGFyYW1zKSB7XHJcbiAgICAgICAgdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZSA9IHJlc29sdmU7XHJcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdCA9IHJlamVjdDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5mZWF0dXJlcyA9IHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzIHx8IERlZmF1bHRQb3B1cEZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnJlZGlyZWN0X3VyaSA9IHBhcmFtcy5zdGFydFVybDtcclxuICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3cuY3RvcjogcmVkaXJlY3RfdXJpOiBcIiArIHRoaXMucmVkaXJlY3RfdXJpKTtcclxuICAgIH1cclxuXHJcbiAgICBfaXNJbkFwcEJyb3dzZXJJbnN0YWxsZWQoY29yZG92YU1ldGFkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIFtcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3NlclwiLCBcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3Nlci5pbmFwcGJyb3dzZXJcIiwgXCJvcmcuYXBhY2hlLmNvcmRvdmEuaW5hcHBicm93c2VyXCJdLnNvbWUoZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNvcmRvdmFNZXRhZGF0YS5oYXNPd25Qcm9wZXJ0eShuYW1lKVxyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbiAgICBcclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICghd2luZG93LmNvcmRvdmEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9lcnJvcihcImNvcmRvdmEgaXMgdW5kZWZpbmVkXCIpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHZhciBjb3Jkb3ZhTWV0YWRhdGEgPSB3aW5kb3cuY29yZG92YS5yZXF1aXJlKFwiY29yZG92YS9wbHVnaW5fbGlzdFwiKS5tZXRhZGF0YTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzSW5BcHBCcm93c2VySW5zdGFsbGVkKGNvcmRvdmFNZXRhZGF0YSkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3IoXCJJbkFwcEJyb3dzZXIgcGx1Z2luIG5vdCBmb3VuZFwiKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwID0gY29yZG92YS5JbkFwcEJyb3dzZXIub3BlbihwYXJhbXMudXJsLCB0aGlzLnRhcmdldCwgdGhpcy5mZWF0dXJlcyk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9wb3B1cCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQ29yZG92YVBvcHVwV2luZG93Lm5hdmlnYXRlOiBwb3B1cCBzdWNjZXNzZnVsbHkgY3JlYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQgPSB0aGlzLl9leGl0Q2FsbGJhY2suYmluZCh0aGlzKTsgXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkU3RhcnRDYWxsYmFja0V2ZW50ID0gdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2suYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcG9wdXAuYWRkRXZlbnRMaXN0ZW5lcihcImV4aXRcIiwgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BvcHVwLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2Fkc3RhcnRcIiwgdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJFcnJvciBvcGVuaW5nIHBvcHVwIHdpbmRvd1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwcm9taXNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkU3RhcnRDYWxsYmFjayhldmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC51cmwuaW5kZXhPZih0aGlzLnJlZGlyZWN0X3VyaSkgPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5fc3VjY2Vzcyh7IHVybDogZXZlbnQudXJsIH0pO1xyXG4gICAgICAgIH0gICAgXHJcbiAgICB9XHJcbiAgICBfZXhpdENhbGxiYWNrKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLl9lcnJvcihtZXNzYWdlKTsgICAgXHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICB0aGlzLl9jbGVhbnVwKCk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIkNvcmRvdmFQb3B1cFdpbmRvdzogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIGNvcmRvdmEgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fcG9wdXApe1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3c6IGNsZWFuaW5nIHVwIHBvcHVwXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXhpdFwiLCB0aGlzLl9leGl0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwibG9hZHN0YXJ0XCIsIHRoaXMuX2xvYWRTdGFydENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgdGhpcy5fcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSBudWxsO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFcnJvclJlc3BvbnNlIGV4dGVuZHMgRXJyb3Ige1xyXG4gICAgY29uc3RydWN0b3Ioe2Vycm9yLCBlcnJvcl9kZXNjcmlwdGlvbiwgZXJyb3JfdXJpLCBzdGF0ZSwgc2Vzc2lvbl9zdGF0ZX09e31cclxuICAgICkge1xyXG4gICAgICAgICBpZiAoIWVycm9yKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiTm8gZXJyb3IgcGFzc2VkIHRvIEVycm9yUmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImVycm9yXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3VwZXIoZXJyb3JfZGVzY3JpcHRpb24gfHwgZXJyb3IpO1xyXG5cclxuICAgICAgICB0aGlzLm5hbWUgPSBcIkVycm9yUmVzcG9uc2VcIjtcclxuXHJcbiAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSBlcnJvcl9kZXNjcmlwdGlvbjtcclxuICAgICAgICB0aGlzLmVycm9yX3VyaSA9IGVycm9yX3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEV2ZW50IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lKSB7XHJcbiAgICAgICAgdGhpcy5fbmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgYWRkSGFuZGxlcihjYikge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrcy5wdXNoKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVIYW5kbGVyKGNiKSB7XHJcbiAgICAgICAgdmFyIGlkeCA9IHRoaXMuX2NhbGxiYWNrcy5maW5kSW5kZXgoaXRlbSA9PiBpdGVtID09PSBjYik7XHJcbiAgICAgICAgaWYgKGlkeCA+PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmFpc2UoLi4ucGFyYW1zKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiRXZlbnQ6IFJhaXNpbmcgZXZlbnQ6IFwiICsgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9jYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzW2ldKC4uLnBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmNvbnN0IHRpbWVyID0ge1xyXG4gICAgc2V0SW50ZXJ2YWw6IGZ1bmN0aW9uIChjYiwgZHVyYXRpb24pIHtcclxuICAgICAgICByZXR1cm4gc2V0SW50ZXJ2YWwoY2IsIGR1cmF0aW9uKTtcclxuICAgIH0sXHJcbiAgICBjbGVhckludGVydmFsOiBmdW5jdGlvbiAoaGFuZGxlKSB7XHJcbiAgICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwoaGFuZGxlKTtcclxuICAgIH1cclxufTtcclxuXHJcbmxldCB0ZXN0aW5nID0gZmFsc2U7XHJcbmxldCByZXF1ZXN0ID0gbnVsbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBHbG9iYWwge1xyXG5cclxuICAgIHN0YXRpYyBfdGVzdGluZygpIHtcclxuICAgICAgICB0ZXN0aW5nID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IGxvY2F0aW9uKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgbG9jYWxTdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYWxTdG9yYWdlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IHNlc3Npb25TdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gc2Vzc2lvblN0b3JhZ2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBzZXRYTUxIdHRwUmVxdWVzdChuZXdSZXF1ZXN0KSB7XHJcbiAgICAgICAgcmVxdWVzdCA9IG5ld1JlcXVlc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGdldCBYTUxIdHRwUmVxdWVzdCgpIHtcclxuICAgICAgICBpZiAoIXRlc3RpbmcgJiYgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QgfHwgWE1MSHR0cFJlcXVlc3Q7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgdGltZXIoKSB7XHJcbiAgICAgICAgaWYgKCF0ZXN0aW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aW1lcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVXaW5kb3cgfSBmcm9tICcuL0lGcmFtZVdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBmcmFtZSA9IG5ldyBJRnJhbWVXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZyYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVOYXZpZ2F0b3IuY2FsbGJhY2tcIik7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIElGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQodXJsKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRUaW1lb3V0ID0gMTAwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZnJhbWUgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlmcmFtZVwiKTtcclxuXHJcbiAgICAgICAgLy8gc2hvdGd1biBhcHByb2FjaFxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnZpc2liaWxpdHkgPSBcImhpZGRlblwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS53aWR0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUuaGVpZ2h0ID0gMDtcclxuXHJcbiAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IHRpbWVvdXQgPSBwYXJhbXMuc2lsZW50UmVxdWVzdFRpbWVvdXQgfHwgRGVmYXVsdFRpbWVvdXQ7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5uYXZpZ2F0ZTogVXNpbmcgdGltZW91dCBvZjpcIiwgdGltZW91dCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldFRpbWVvdXQodGhpcy5fdGltZW91dC5iaW5kKHRoaXMpLCB0aW1lb3V0KTtcclxuICAgICAgICAgICAgdGhpcy5fZnJhbWUuc3JjID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHByb21pc2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgX3N1Y2Nlc3MoZGF0YSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBTdWNjZXNzZnVsIHJlc3BvbnNlIGZyb20gZnJhbWUgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fZnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBjbGVhbnVwXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLl9mcmFtZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lID0gbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdGltZW91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVXaW5kb3cudGltZW91dFwiKTtcclxuICAgICAgICB0aGlzLl9lcnJvcihcIkZyYW1lIHdpbmRvdyB0aW1lZCBvdXRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgX21lc3NhZ2UoZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5tZXNzYWdlXCIpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fdGltZXIgJiZcclxuICAgICAgICAgICAgZS5vcmlnaW4gPT09IHRoaXMuX29yaWdpbiAmJlxyXG4gICAgICAgICAgICBlLnNvdXJjZSA9PT0gdGhpcy5fZnJhbWUuY29udGVudFdpbmRvd1xyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICBsZXQgdXJsID0gZS5kYXRhO1xyXG4gICAgICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWNjZXNzKHsgdXJsOiB1cmwgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9lcnJvcihcIkludmFsaWQgcmVzcG9uc2UgZnJvbSBmcmFtZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX29yaWdpbigpIHtcclxuICAgICAgICByZXR1cm4gbG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyBsb2NhdGlvbi5ob3N0O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBub3RpZnlQYXJlbnQodXJsKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93Lm5vdGlmeVBhcmVudFwiKTtcclxuICAgICAgICBpZiAod2luZG93LmZyYW1lRWxlbWVudCkge1xyXG4gICAgICAgICAgICB1cmwgPSB1cmwgfHwgd2luZG93LmxvY2F0aW9uLmhyZWY7XHJcbiAgICAgICAgICAgIGlmICh1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQ6IHBvc3RpbmcgdXJsIG1lc3NhZ2UgdG8gcGFyZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZSh1cmwsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICsgbG9jYXRpb24uaG9zdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEluTWVtb3J5V2ViU3RvcmFnZXtcclxuICAgIGNvbnN0cnVjdG9yKCl7XHJcbiAgICAgICAgdGhpcy5fZGF0YSA9IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIGdldEl0ZW0oa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLmdldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIHNldEl0ZW0oa2V5LCB2YWx1ZSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnNldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICB0aGlzLl9kYXRhW2tleV0gPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVJdGVtKGtleSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnJlbW92ZUl0ZW1cIiwga2V5KTtcclxuICAgICAgICBkZWxldGUgdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBsZW5ndGgoKSB7XHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMuX2RhdGEpLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBrZXkoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcy5fZGF0YSlbaW5kZXhdO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IGp3cywgS2V5VXRpbCwgWDUwOSwgY3J5cHRvLCBoZXh0b2I2NHUsIGI2NHRvaGV4LCBBbGxvd2VkU2lnbmluZ0FsZ3MgfSBmcm9tICcuL2NyeXB0by9qc3JzYXNpZ24nO1xyXG5pbXBvcnQgZ2V0Sm9zZVV0aWwgZnJvbSAnLi9Kb3NlVXRpbEltcGwnO1xyXG5cclxuZXhwb3J0IGNvbnN0IEpvc2VVdGlsID0gZ2V0Sm9zZVV0aWwoeyBqd3MsIEtleVV0aWwsIFg1MDksIGNyeXB0bywgaGV4dG9iNjR1LCBiNjR0b2hleCwgQWxsb3dlZFNpZ25pbmdBbGdzIH0pO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRKb3NlVXRpbCh7IGp3cywgS2V5VXRpbCwgWDUwOSwgY3J5cHRvLCBoZXh0b2I2NHUsIGI2NHRvaGV4LCBBbGxvd2VkU2lnbmluZ0FsZ3MgfSkge1xyXG4gICAgcmV0dXJuIGNsYXNzIEpvc2VVdGlsIHtcclxuXHJcbiAgICAgICAgc3RhdGljIHBhcnNlSnd0KGp3dCkge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJKb3NlVXRpbC5wYXJzZUp3dFwiKTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHZhciB0b2tlbiA9IGp3cy5KV1MucGFyc2Uoand0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyOiB0b2tlbi5oZWFkZXJPYmosXHJcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDogdG9rZW4ucGF5bG9hZE9ialxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyB2YWxpZGF0ZUp3dChqd3QsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3LCBub3csIHRpbWVJbnNlbnNpdGl2ZSkge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dFwiKTtcclxuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoa2V5Lmt0eSA9PT0gXCJSU0FcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuZSAmJiBrZXkubikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBLZXlVdGlsLmdldEtleShrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5Lng1YyAmJiBrZXkueDVjLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGV4ID0gYjY0dG9oZXgoa2V5Lng1Y1swXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFg1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRIZXgoaGV4KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dDogUlNBIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiUlNBIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkua3R5ID09PSBcIkVDXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LmNydiAmJiBrZXkueCAmJiBrZXkueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBLZXlVdGlsLmdldEtleShrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLnZhbGlkYXRlSnd0OiBFQyBrZXkgbWlzc2luZyBrZXkgbWF0ZXJpYWxcIiwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkVDIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dDogVW5zdXBwb3J0ZWQga2V5IHR5cGVcIiwga2V5ICYmIGtleS5rdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBrZXkgdHlwZTogXCIgKyBrZXkgJiYga2V5Lmt0eSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBKb3NlVXRpbC5fdmFsaWRhdGVKd3Qoand0LCBrZXksIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSAmJiBlLm1lc3NhZ2UgfHwgZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJKV1QgdmFsaWRhdGlvbiBmYWlsZWRcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyB2YWxpZGF0ZUp3dEF0dHJpYnV0ZXMoand0LCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXcsIG5vdywgdGltZUluc2Vuc2l0aXZlKSB7XHJcbiAgICAgICAgICAgIGlmICghY2xvY2tTa2V3KSB7XHJcbiAgICAgICAgICAgICAgICBjbG9ja1NrZXcgPSAwO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIW5vdykge1xyXG4gICAgICAgICAgICAgICAgbm93ID0gcGFyc2VJbnQoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIgcGF5bG9hZCA9IEpvc2VVdGlsLnBhcnNlSnd0KGp3dCkucGF5bG9hZDtcclxuXHJcbiAgICAgICAgICAgIGlmICghcGF5bG9hZC5pc3MpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogaXNzdWVyIHdhcyBub3QgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaXNzdWVyIHdhcyBub3QgcHJvdmlkZWRcIikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmlzcyAhPT0gaXNzdWVyKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IEludmFsaWQgaXNzdWVyIGluIHRva2VuXCIsIHBheWxvYWQuaXNzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIGlzc3VlciBpbiB0b2tlbjogXCIgKyBwYXlsb2FkLmlzcykpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXBheWxvYWQuYXVkKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGF1ZCB3YXMgbm90IHByb3ZpZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImF1ZCB3YXMgbm90IHByb3ZpZGVkXCIpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgdmFsaWRBdWRpZW5jZSA9IHBheWxvYWQuYXVkID09PSBhdWRpZW5jZSB8fCAoQXJyYXkuaXNBcnJheShwYXlsb2FkLmF1ZCkgJiYgcGF5bG9hZC5hdWQuaW5kZXhPZihhdWRpZW5jZSkgPj0gMCk7XHJcbiAgICAgICAgICAgIGlmICghdmFsaWRBdWRpZW5jZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBJbnZhbGlkIGF1ZGllbmNlIGluIHRva2VuXCIsIHBheWxvYWQuYXVkKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIGF1ZGllbmNlIGluIHRva2VuOiBcIiArIHBheWxvYWQuYXVkKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuYXpwICYmIHBheWxvYWQuYXpwICE9PSBhdWRpZW5jZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBJbnZhbGlkIGF6cCBpbiB0b2tlblwiLCBwYXlsb2FkLmF6cCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBhenAgaW4gdG9rZW46IFwiICsgcGF5bG9hZC5henApKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aW1lSW5zZW5zaXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHZhciBsb3dlck5vdyA9IG5vdyArIGNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgIHZhciB1cHBlck5vdyA9IG5vdyAtIGNsb2NrU2tldztcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXBheWxvYWQuaWF0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBpYXQgd2FzIG5vdCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaWF0IHdhcyBub3QgcHJvdmlkZWRcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGxvd2VyTm93IDwgcGF5bG9hZC5pYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGlhdCBpcyBpbiB0aGUgZnV0dXJlXCIsIHBheWxvYWQuaWF0KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaWF0IGlzIGluIHRoZSBmdXR1cmU6IFwiICsgcGF5bG9hZC5pYXQpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5uYmYgJiYgbG93ZXJOb3cgPCBwYXlsb2FkLm5iZikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogbmJmIGlzIGluIHRoZSBmdXR1cmVcIiwgcGF5bG9hZC5uYmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJuYmYgaXMgaW4gdGhlIGZ1dHVyZTogXCIgKyBwYXlsb2FkLm5iZikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5leHApIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGV4cCB3YXMgbm90IHByb3ZpZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJleHAgd2FzIG5vdCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5leHAgPCB1cHBlck5vdykge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogZXhwIGlzIGluIHRoZSBwYXN0XCIsIHBheWxvYWQuZXhwKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiZXhwIGlzIGluIHRoZSBwYXN0OlwiICsgcGF5bG9hZC5leHApKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwYXlsb2FkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyBfdmFsaWRhdGVKd3Qoand0LCBrZXksIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBKb3NlVXRpbC52YWxpZGF0ZUp3dEF0dHJpYnV0ZXMoand0LCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXcsIG5vdywgdGltZUluc2Vuc2l0aXZlKS50aGVuKHBheWxvYWQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWp3cy5KV1MudmVyaWZ5KGp3dCwga2V5LCBBbGxvd2VkU2lnbmluZ0FsZ3MpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogc2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihlICYmIGUubWVzc2FnZSB8fCBlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGF0aWMgaGFzaFN0cmluZyh2YWx1ZSwgYWxnKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY3J5cHRvLlV0aWwuaGFzaFN0cmluZyh2YWx1ZSwgYWxnKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGF0aWMgaGV4VG9CYXNlNjRVcmwodmFsdWUpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBoZXh0b2I2NHUodmFsdWUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSnNvblNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgYWRkaXRpb25hbENvbnRlbnRUeXBlcyA9IG51bGwsIFxyXG4gICAgICAgIFhNTEh0dHBSZXF1ZXN0Q3RvciA9IEdsb2JhbC5YTUxIdHRwUmVxdWVzdCwgXHJcbiAgICAgICAgand0SGFuZGxlciA9IG51bGxcclxuICAgICkge1xyXG4gICAgICAgIGlmIChhZGRpdGlvbmFsQ29udGVudFR5cGVzICYmIEFycmF5LmlzQXJyYXkoYWRkaXRpb25hbENvbnRlbnRUeXBlcykpXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMgPSBhZGRpdGlvbmFsQ29udGVudFR5cGVzLnNsaWNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcyA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMucHVzaCgnYXBwbGljYXRpb24vanNvbicpO1xyXG4gICAgICAgIGlmIChqd3RIYW5kbGVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcy5wdXNoKCdhcHBsaWNhdGlvbi9qd3QnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX1hNTEh0dHBSZXF1ZXN0ID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX2p3dEhhbmRsZXIgPSBqd3RIYW5kbGVyO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEpzb24odXJsLCB0b2tlbikge1xyXG4gICAgICAgIGlmICghdXJsKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbiwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ0dFVCcsIHVybCk7XHJcblxyXG4gICAgICAgICAgICB2YXIgYWxsb3dlZENvbnRlbnRUeXBlcyA9IHRoaXMuX2NvbnRlbnRUeXBlcztcclxuICAgICAgICAgICAgdmFyIGp3dEhhbmRsZXIgPSB0aGlzLl9qd3RIYW5kbGVyO1xyXG5cclxuICAgICAgICAgICAgcmVxLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kID09IFwiYXBwbGljYXRpb24vand0XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp3dEhhbmRsZXIocmVxKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKEpTT04ucGFyc2UocmVxLnJlc3BvbnNlVGV4dCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IocmVxLnN0YXR1c1RleHQgKyBcIiAoXCIgKyByZXEuc3RhdHVzICsgXCIpXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5nZXRKc29uOiBuZXR3b3JrIGVycm9yXCIpO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiTmV0d29yayBFcnJvclwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkpzb25TZXJ2aWNlLmdldEpzb246IHRva2VuIHBhc3NlZCwgc2V0dGluZyBBdXRob3JpemF0aW9uIGhlYWRlclwiKTtcclxuICAgICAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyKFwiQXV0aG9yaXphdGlvblwiLCBcIkJlYXJlciBcIiArIHRva2VuKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNlbmQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwb3N0Rm9ybSh1cmwsIHBheWxvYWQpIHtcclxuICAgICAgICBpZiAoIXVybCl7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybSwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ1BPU1QnLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGFsbG93ZWRDb250ZW50VHlwZXMgPSB0aGlzLl9jb250ZW50VHlwZXM7XHJcblxyXG4gICAgICAgICAgICByZXEub25sb2FkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSA0MDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXlsb2FkID0gSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF5bG9hZCAmJiBwYXlsb2FkLmVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBFcnJvciBmcm9tIHNlcnZlcjogXCIsIHBheWxvYWQuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKHBheWxvYWQuZXJyb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IEVycm9yIHBhcnNpbmcgSlNPTiByZXNwb25zZVwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlcS5zdGF0dXNUZXh0ICsgXCIgKFwiICsgcmVxLnN0YXR1cyArIFwiKVwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IG5ldHdvcmsgZXJyb3JcIik7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IoXCJOZXR3b3JrIEVycm9yXCIpKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGxldCBib2R5ID0gXCJcIjtcclxuICAgICAgICAgICAgZm9yKGxldCBrZXkgaW4gcGF5bG9hZCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHBheWxvYWRba2V5XTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJvZHkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiJlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYm9keSArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KTtcclxuICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiPVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIik7XHJcbiAgICAgICAgICAgIHJlcS5zZW5kKGJvZHkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmxldCBub3BMb2dnZXIgPSB7XHJcbiAgICBkZWJ1Zygpe30sXHJcbiAgICBpbmZvKCl7fSxcclxuICAgIHdhcm4oKXt9LFxyXG4gICAgZXJyb3IoKXt9XHJcbn07XHJcblxyXG5jb25zdCBOT05FID0gMDtcclxuY29uc3QgRVJST1IgPSAxO1xyXG5jb25zdCBXQVJOID0gMjtcclxuY29uc3QgSU5GTyA9IDM7XHJcbmNvbnN0IERFQlVHID0gNDtcclxuXHJcbmxldCBsb2dnZXI7XHJcbmxldCBsZXZlbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBMb2cge1xyXG4gICAgc3RhdGljIGdldCBOT05FKCkge3JldHVybiBOT05FfTtcclxuICAgIHN0YXRpYyBnZXQgRVJST1IoKSB7cmV0dXJuIEVSUk9SfTtcclxuICAgIHN0YXRpYyBnZXQgV0FSTigpIHtyZXR1cm4gV0FSTn07XHJcbiAgICBzdGF0aWMgZ2V0IElORk8oKSB7cmV0dXJuIElORk99O1xyXG4gICAgc3RhdGljIGdldCBERUJVRygpIHtyZXR1cm4gREVCVUd9O1xyXG4gICAgXHJcbiAgICBzdGF0aWMgcmVzZXQoKXtcclxuICAgICAgICBsZXZlbCA9IElORk87XHJcbiAgICAgICAgbG9nZ2VyID0gbm9wTG9nZ2VyO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxldmVsKCl7XHJcbiAgICAgICAgcmV0dXJuIGxldmVsO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIHNldCBsZXZlbCh2YWx1ZSl7XHJcbiAgICAgICAgaWYgKE5PTkUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gREVCVUcpe1xyXG4gICAgICAgICAgICBsZXZlbCA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBsb2cgbGV2ZWxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxvZ2dlcigpe1xyXG4gICAgICAgIHJldHVybiBsb2dnZXI7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgc2V0IGxvZ2dlcih2YWx1ZSl7XHJcbiAgICAgICAgaWYgKCF2YWx1ZS5kZWJ1ZyAmJiB2YWx1ZS5pbmZvKSB7XHJcbiAgICAgICAgICAgIC8vIGp1c3QgdG8gc3RheSBiYWNrd2FyZHMgY29tcGF0LiBjYW4gcmVtb3ZlIGluIDIuMFxyXG4gICAgICAgICAgICB2YWx1ZS5kZWJ1ZyA9IHZhbHVlLmluZm87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmFsdWUuZGVidWcgJiYgdmFsdWUuaW5mbyAmJiB2YWx1ZS53YXJuICYmIHZhbHVlLmVycm9yKXtcclxuICAgICAgICAgICAgbG9nZ2VyID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGxvZ2dlclwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHN0YXRpYyBkZWJ1ZyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gREVCVUcpe1xyXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgaW5mbyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gSU5GTyl7XHJcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvLmFwcGx5KGxvZ2dlciwgQXJyYXkuZnJvbShhcmdzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIHdhcm4oLi4uYXJncyl7XHJcbiAgICAgICAgaWYgKGxldmVsID49IFdBUk4pe1xyXG4gICAgICAgICAgICBsb2dnZXIud2Fybi5hcHBseShsb2dnZXIsIEFycmF5LmZyb20oYXJncykpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHN0YXRpYyBlcnJvciguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gRVJST1Ipe1xyXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbkxvZy5yZXNldCgpO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmV4cG9ydCBjbGFzcyBNZXRhZGF0YVNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MsIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2U6IE5vIHNldHRpbmdzIHBhc3NlZCB0byBNZXRhZGF0YVNlcnZpY2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IoWydhcHBsaWNhdGlvbi9qd2stc2V0K2pzb24nXSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1ldGFkYXRhVXJsKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5fbWV0YWRhdGFVcmwpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgPSB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsICYmIHRoaXMuX21ldGFkYXRhVXJsLmluZGV4T2YoT2lkY01ldGFkYXRhVXJsUGF0aCkgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsW3RoaXMuX21ldGFkYXRhVXJsLmxlbmd0aCAtIDFdICE9PSAnLycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCArPSBPaWRjTWV0YWRhdGFVcmxQYXRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TWV0YWRhdGEoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogUmV0dXJuaW5nIG1ldGFkYXRhIGZyb20gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fc2V0dGluZ3MubWV0YWRhdGEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogTm8gYXV0aG9yaXR5IG9yIG1ldGFkYXRhVXJsIGNvbmZpZ3VyZWQgb24gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb3IgbWV0YWRhdGFVcmwgY29uZmlndXJlZCBvbiBzZXR0aW5nc1wiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGE6IGdldHRpbmcgbWV0YWRhdGEgZnJvbVwiLCB0aGlzLm1ldGFkYXRhVXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24odGhpcy5tZXRhZGF0YVVybClcclxuICAgICAgICAgICAgLnRoZW4obWV0YWRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiTWV0YWRhdGFTZXJ2aWNlLmdldE1ldGFkYXRhOiBqc29uIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MubWV0YWRhdGEgPSBtZXRhZGF0YTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0SXNzdWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiaXNzdWVyXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEF1dGhvcml6YXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImF1dGhvcml6YXRpb25fZW5kcG9pbnRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlckluZm9FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInVzZXJpbmZvX2VuZHBvaW50XCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFRva2VuRW5kcG9pbnQob3B0aW9uYWw9dHJ1ZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwidG9rZW5fZW5kcG9pbnRcIiwgb3B0aW9uYWwpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENoZWNrU2Vzc2lvbklmcmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImNoZWNrX3Nlc3Npb25faWZyYW1lXCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEVuZFNlc3Npb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImVuZF9zZXNzaW9uX2VuZHBvaW50XCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFJldm9jYXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInJldm9jYXRpb25fZW5kcG9pbnRcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0S2V5c0VuZHBvaW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldE1ldGFkYXRhUHJvcGVydHkobmFtZSwgb3B0aW9uYWw9ZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eSBmb3I6IFwiICsgbmFtZSk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1ldGFkYXRhKCkudGhlbihtZXRhZGF0YSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YVByb3BlcnR5OiBtZXRhZGF0YSByZWNpZXZlZFwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChtZXRhZGF0YVtuYW1lXSA9PT0gdW5kZWZpbmVkKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBvcHRpb25hbCBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGFkYXRhIGRvZXMgbm90IGNvbnRhaW4gcHJvcGVydHkgXCIgKyBuYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhW25hbWVdO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IFJldHVybmluZyBzaWduaW5nS2V5cyBmcm9tIHNldHRpbmdzXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIikudGhlbihqd2tzX3VyaSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czogandrc191cmkgcmVjZWl2ZWRcIiwgandrc191cmkpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24oandrc191cmkpLnRoZW4oa2V5U2V0ID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czoga2V5IHNldCByZWNlaXZlZFwiLCBrZXlTZXQpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICgha2V5U2V0LmtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IE1pc3Npbmcga2V5cyBvbiBrZXlzZXRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBrZXlzIG9uIGtleXNldFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cyA9IGtleVNldC5rZXlzO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE9pZGNDbGllbnRTZXR0aW5ncyB9IGZyb20gJy4vT2lkY0NsaWVudFNldHRpbmdzLmpzJztcclxuaW1wb3J0IHsgRXJyb3JSZXNwb25zZSB9IGZyb20gJy4vRXJyb3JSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblJlcXVlc3QgfSBmcm9tICcuL1NpZ25pblJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWduaW5SZXNwb25zZSB9IGZyb20gJy4vU2lnbmluUmVzcG9uc2UuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVxdWVzdCB9IGZyb20gJy4vU2lnbm91dFJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVzcG9uc2UgfSBmcm9tICcuL1NpZ25vdXRSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9KSB7XHJcbiAgICAgICAgaWYgKHNldHRpbmdzIGluc3RhbmNlb2YgT2lkY0NsaWVudFNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5ncyA9IG5ldyBPaWRjQ2xpZW50U2V0dGluZ3Moc2V0dGluZ3MpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3N0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3Muc3RhdGVTdG9yZTtcclxuICAgIH1cclxuICAgIGdldCBfdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnZhbGlkYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLm1ldGFkYXRhU2VydmljZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2V0dGluZ3MoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG5cclxuICAgIGNyZWF0ZVNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgIHJlc3BvbnNlX3R5cGUsIHNjb3BlLCByZWRpcmVjdF91cmksXHJcbiAgICAgICAgLy8gZGF0YSB3YXMgbWVhbnQgdG8gYmUgdGhlIHBsYWNlIGEgY2FsbGVyIGNvdWxkIGluZGljYXRlIHRoZSBkYXRhIHRvXHJcbiAgICAgICAgLy8gaGF2ZSByb3VuZCB0cmlwcGVkLCBidXQgcGVvcGxlIHdlcmUgZ2V0dGluZyBjb25mdXNlZCwgc28gaSBhZGRlZCBzdGF0ZSAoc2luY2UgdGhhdCBtYXRjaGVzIHRoZSBzcGVjKVxyXG4gICAgICAgIC8vIGFuZCBzbyBub3cgaWYgZGF0YSBpcyBub3QgcGFzc2VkLCBidXQgc3RhdGUgaXMgdGhlbiBzdGF0ZSB3aWxsIGJlIHVzZWRcclxuICAgICAgICBkYXRhLCBzdGF0ZSwgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBpZF90b2tlbl9oaW50LCBsb2dpbl9oaW50LCBhY3JfdmFsdWVzLFxyXG4gICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgcmVzcG9uc2VfbW9kZSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCBza2lwVXNlckluZm8gfSA9IHt9LFxyXG4gICAgICAgIHN0YXRlU3RvcmVcclxuICAgICkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbmluUmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICByZXNwb25zZV90eXBlID0gcmVzcG9uc2VfdHlwZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHNjb3BlID0gc2NvcGUgfHwgdGhpcy5fc2V0dGluZ3Muc2NvcGU7XHJcbiAgICAgICAgcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgLy8gaWRfdG9rZW5faGludCwgbG9naW5faGludCBhcmVuJ3QgYWxsb3dlZCBvbiBfc2V0dGluZ3NcclxuICAgICAgICBwcm9tcHQgPSBwcm9tcHQgfHwgdGhpcy5fc2V0dGluZ3MucHJvbXB0O1xyXG4gICAgICAgIGRpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuX3NldHRpbmdzLmRpc3BsYXk7XHJcbiAgICAgICAgbWF4X2FnZSA9IG1heF9hZ2UgfHwgdGhpcy5fc2V0dGluZ3MubWF4X2FnZTtcclxuICAgICAgICB1aV9sb2NhbGVzID0gdWlfbG9jYWxlcyB8fCB0aGlzLl9zZXR0aW5ncy51aV9sb2NhbGVzO1xyXG4gICAgICAgIGFjcl92YWx1ZXMgPSBhY3JfdmFsdWVzIHx8IHRoaXMuX3NldHRpbmdzLmFjcl92YWx1ZXM7XHJcbiAgICAgICAgcmVzb3VyY2UgPSByZXNvdXJjZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNvdXJjZTtcclxuICAgICAgICByZXNwb25zZV9tb2RlID0gcmVzcG9uc2VfbW9kZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlO1xyXG4gICAgICAgIGV4dHJhUXVlcnlQYXJhbXMgPSBleHRyYVF1ZXJ5UGFyYW1zIHx8IHRoaXMuX3NldHRpbmdzLmV4dHJhUXVlcnlQYXJhbXM7XHJcbiAgICAgICAgZXh0cmFUb2tlblBhcmFtcyA9IGV4dHJhVG9rZW5QYXJhbXMgfHwgdGhpcy5fc2V0dGluZ3MuZXh0cmFUb2tlblBhcmFtcztcclxuXHJcbiAgICAgICAgbGV0IGF1dGhvcml0eSA9IHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eTtcclxuXHJcbiAgICAgICAgaWYgKFNpZ25pblJlcXVlc3QuaXNDb2RlKHJlc3BvbnNlX3R5cGUpICYmIHJlc3BvbnNlX3R5cGUgIT09IFwiY29kZVwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJPcGVuSUQgQ29ubmVjdCBoeWJyaWQgZmxvdyBpcyBub3Qgc3VwcG9ydGVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0QXV0aG9yaXphdGlvbkVuZHBvaW50KCkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25pblJlcXVlc3Q6IFJlY2VpdmVkIGF1dGhvcml6YXRpb24gZW5kcG9pbnRcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBzaWduaW5SZXF1ZXN0ID0gbmV3IFNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X2lkLFxyXG4gICAgICAgICAgICAgICAgcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VfdHlwZSxcclxuICAgICAgICAgICAgICAgIHNjb3BlLFxyXG4gICAgICAgICAgICAgICAgZGF0YTogZGF0YSB8fCBzdGF0ZSxcclxuICAgICAgICAgICAgICAgIGF1dGhvcml0eSxcclxuICAgICAgICAgICAgICAgIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcyxcclxuICAgICAgICAgICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCByZXNwb25zZV9tb2RlLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X3NlY3JldDogdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgICAgIHNraXBVc2VySW5mb1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHZhciBzaWduaW5TdGF0ZSA9IHNpZ25pblJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gc3RhdGVTdG9yZS5zZXQoc2lnbmluU3RhdGUuaWQsIHNpZ25pblN0YXRlLnRvU3RvcmFnZVN0cmluZygpKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzaWduaW5SZXF1ZXN0O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbmluUmVzcG9uc2VTdGF0ZSh1cmwsIHN0YXRlU3RvcmUsIHJlbW92ZVN0YXRlID0gZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBsZXQgdXNlUXVlcnkgPSB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlID09PSBcInF1ZXJ5XCIgfHwgXHJcbiAgICAgICAgICAgICghdGhpcy5fc2V0dGluZ3MucmVzcG9uc2VfbW9kZSAmJiBTaWduaW5SZXF1ZXN0LmlzQ29kZSh0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlKSk7XHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9IHVzZVF1ZXJ5ID8gXCI/XCIgOiBcIiNcIjtcclxuXHJcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNpZ25pblJlc3BvbnNlKHVybCwgZGVsaW1pdGVyKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN0YXRlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUFwaSA9IHJlbW92ZVN0YXRlID8gc3RhdGVTdG9yZS5yZW1vdmUuYmluZChzdGF0ZVN0b3JlKSA6IHN0YXRlU3RvcmUuZ2V0LmJpbmQoc3RhdGVTdG9yZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShyZXNwb25zZS5zdGF0ZSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25pblJlc3BvbnNlU3RhdGU6IE5vIG1hdGNoaW5nIHN0YXRlIGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgc3RhdGUgPSBTaWduaW5TdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhzdG9yZWRTdGF0ZVN0cmluZyk7XHJcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGUsIHJlc3BvbnNlfTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcm9jZXNzU2lnbmluUmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCwgc3RhdGVTdG9yZSwgdHJ1ZSkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2U6IFJlY2VpdmVkIHN0YXRlIGZyb20gc3RvcmFnZTsgdmFsaWRhdGluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY3JlYXRlU2lnbm91dFJlcXVlc3Qoe2lkX3Rva2VuX2hpbnQsIGRhdGEsIHN0YXRlLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSB9ID0ge30sXHJcbiAgICAgICAgc3RhdGVTdG9yZVxyXG4gICAgKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5jcmVhdGVTaWdub3V0UmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zID0gZXh0cmFRdWVyeVBhcmFtcyB8fCB0aGlzLl9zZXR0aW5ncy5leHRyYVF1ZXJ5UGFyYW1zO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldEVuZFNlc3Npb25FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IE5vIGVuZCBzZXNzaW9uIGVuZHBvaW50IHVybCByZXR1cm5lZFwiKTtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vIGVuZCBzZXNzaW9uIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25vdXRSZXF1ZXN0OiBSZWNlaXZlZCBlbmQgc2Vzc2lvbiBlbmRwb2ludFwiLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgU2lnbm91dFJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgaWRfdG9rZW5faGludCxcclxuICAgICAgICAgICAgICAgIHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEgfHwgc3RhdGUsXHJcbiAgICAgICAgICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zLFxyXG4gICAgICAgICAgICAgICAgcmVxdWVzdF90eXBlXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdmFyIHNpZ25vdXRTdGF0ZSA9IHJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIGlmIChzaWdub3V0U3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IFNpZ25vdXQgcmVxdWVzdCBoYXMgc3RhdGUgdG8gcGVyc2lzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG4gICAgICAgICAgICAgICAgc3RhdGVTdG9yZS5zZXQoc2lnbm91dFN0YXRlLmlkLCBzaWdub3V0U3RhdGUudG9TdG9yYWdlU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCByZW1vdmVTdGF0ZSA9IGZhbHNlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGVcIik7XHJcblxyXG4gICAgICAgIHZhciByZXNwb25zZSA9IG5ldyBTaWdub3V0UmVzcG9uc2UodXJsKTtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLndhcm4oXCJPaWRjQ2xpZW50LnJlYWRTaWdub3V0UmVzcG9uc2VTdGF0ZTogUmVzcG9uc2Ugd2FzIGVycm9yOiBcIiwgcmVzcG9uc2UuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe3VuZGVmaW5lZCwgcmVzcG9uc2V9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUtleSA9IHJlc3BvbnNlLnN0YXRlO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICB2YXIgc3RhdGVBcGkgPSByZW1vdmVTdGF0ZSA/IHN0YXRlU3RvcmUucmVtb3ZlLmJpbmQoc3RhdGVTdG9yZSkgOiBzdGF0ZVN0b3JlLmdldC5iaW5kKHN0YXRlU3RvcmUpO1xyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShzdGF0ZUtleSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWF0Y2hpbmcgc3RhdGUgZm91bmQgaW4gc3RvcmFnZVwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IHN0YXRlID0gU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmVkU3RhdGVTdHJpbmcpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtzdGF0ZSwgcmVzcG9uc2V9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCB0cnVlKS50aGVuKCh7c3RhdGUsIHJlc3BvbnNlfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoc3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucHJvY2Vzc1NpZ25vdXRSZXNwb25zZTogUmVjZWl2ZWQgc3RhdGUgZnJvbSBzdG9yYWdlOyB2YWxpZGF0aW5nIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlOiBObyBzdGF0ZSBmcm9tIHN0b3JhZ2U7IHNraXBwaW5nIHZhbGlkYXRpbmcgcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhclN0YWxlU3RhdGUoc3RhdGVTdG9yZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY2xlYXJTdGFsZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICByZXR1cm4gU3RhdGUuY2xlYXJTdGFsZVN0YXRlKHN0YXRlU3RvcmUsIHRoaXMuc2V0dGluZ3Muc3RhbGVTdGF0ZUFnZSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB9IGZyb20gJy4vV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMnO1xyXG5pbXBvcnQgeyBSZXNwb25zZVZhbGlkYXRvciB9IGZyb20gJy4vUmVzcG9uc2VWYWxpZGF0b3IuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmNvbnN0IERlZmF1bHRSZXNwb25zZVR5cGUgPSBcImlkX3Rva2VuXCI7XHJcbmNvbnN0IERlZmF1bHRTY29wZSA9IFwib3BlbmlkXCI7XHJcbmNvbnN0IERlZmF1bHRTdGFsZVN0YXRlQWdlID0gNjAgKiAxNTsgLy8gc2Vjb25kc1xyXG5jb25zdCBEZWZhdWx0Q2xvY2tTa2V3SW5TZWNvbmRzID0gNjAgKiA1O1xyXG5cclxuZXhwb3J0IGNsYXNzIE9pZGNDbGllbnRTZXR0aW5ncyB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWV0YWRhdGEgcmVsYXRlZFxyXG4gICAgICAgIGF1dGhvcml0eSwgbWV0YWRhdGFVcmwsIG1ldGFkYXRhLCBzaWduaW5nS2V5cyxcclxuICAgICAgICAvLyBjbGllbnQgcmVsYXRlZFxyXG4gICAgICAgIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgcmVzcG9uc2VfdHlwZSA9IERlZmF1bHRSZXNwb25zZVR5cGUsIHNjb3BlID0gRGVmYXVsdFNjb3BlLFxyXG4gICAgICAgIHJlZGlyZWN0X3VyaSwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIC8vIG9wdGlvbmFsIHByb3RvY29sXHJcbiAgICAgICAgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBhY3JfdmFsdWVzLCByZXNvdXJjZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAvLyBiZWhhdmlvciBmbGFnc1xyXG4gICAgICAgIGZpbHRlclByb3RvY29sQ2xhaW1zID0gdHJ1ZSwgbG9hZFVzZXJJbmZvID0gdHJ1ZSxcclxuICAgICAgICBzdGFsZVN0YXRlQWdlID0gRGVmYXVsdFN0YWxlU3RhdGVBZ2UsIGNsb2NrU2tldyA9IERlZmF1bHRDbG9ja1NrZXdJblNlY29uZHMsXHJcbiAgICAgICAgdXNlckluZm9Kd3RJc3N1ZXIgPSAnT1AnLFxyXG4gICAgICAgIC8vIG90aGVyIGJlaGF2aW9yXHJcbiAgICAgICAgc3RhdGVTdG9yZSA9IG5ldyBXZWJTdG9yYWdlU3RhdGVTdG9yZSgpLFxyXG4gICAgICAgIFJlc3BvbnNlVmFsaWRhdG9yQ3RvciA9IFJlc3BvbnNlVmFsaWRhdG9yLFxyXG4gICAgICAgIE1ldGFkYXRhU2VydmljZUN0b3IgPSBNZXRhZGF0YVNlcnZpY2UsXHJcbiAgICAgICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICAgICAgZXh0cmFRdWVyeVBhcmFtcyA9IHt9LFxyXG4gICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgPSB7fVxyXG4gICAgfSA9IHt9KSB7XHJcblxyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IG1ldGFkYXRhVXJsO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gbWV0YWRhdGE7XHJcbiAgICAgICAgdGhpcy5fc2lnbmluZ0tleXMgPSBzaWduaW5nS2V5cztcclxuXHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX2NsaWVudF9zZWNyZXQgPSBjbGllbnRfc2VjcmV0O1xyXG4gICAgICAgIHRoaXMuX3Jlc3BvbnNlX3R5cGUgPSByZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHRoaXMuX3Njb3BlID0gc2NvcGU7XHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSA9IHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5fcHJvbXB0ID0gcHJvbXB0O1xyXG4gICAgICAgIHRoaXMuX2Rpc3BsYXkgPSBkaXNwbGF5O1xyXG4gICAgICAgIHRoaXMuX21heF9hZ2UgPSBtYXhfYWdlO1xyXG4gICAgICAgIHRoaXMuX3VpX2xvY2FsZXMgPSB1aV9sb2NhbGVzO1xyXG4gICAgICAgIHRoaXMuX2Fjcl92YWx1ZXMgPSBhY3JfdmFsdWVzO1xyXG4gICAgICAgIHRoaXMuX3Jlc291cmNlID0gcmVzb3VyY2U7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZpbHRlclByb3RvY29sQ2xhaW1zID0gISFmaWx0ZXJQcm90b2NvbENsYWltcztcclxuICAgICAgICB0aGlzLl9sb2FkVXNlckluZm8gPSAhIWxvYWRVc2VySW5mbztcclxuICAgICAgICB0aGlzLl9zdGFsZVN0YXRlQWdlID0gc3RhbGVTdGF0ZUFnZTtcclxuICAgICAgICB0aGlzLl9jbG9ja1NrZXcgPSBjbG9ja1NrZXc7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXIgPSB1c2VySW5mb0p3dElzc3VlcjtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RhdGVTdG9yZSA9IHN0YXRlU3RvcmU7XHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yID0gbmV3IFJlc3BvbnNlVmFsaWRhdG9yQ3Rvcih0aGlzKTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHR5cGVvZiBleHRyYVF1ZXJ5UGFyYW1zID09PSAnb2JqZWN0JyA/IGV4dHJhUXVlcnlQYXJhbXMgOiB7fTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gdHlwZW9mIGV4dHJhVG9rZW5QYXJhbXMgPT09ICdvYmplY3QnID8gZXh0cmFUb2tlblBhcmFtcyA6IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGNsaWVudCBjb25maWdcclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIHNldCBjbGllbnRfaWQodmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NsaWVudF9pZCkge1xyXG4gICAgICAgICAgICAvLyBvbmUtdGltZSBzZXQgb25seVxyXG4gICAgICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnRTZXR0aW5ncy5zZXRfY2xpZW50X2lkOiBjbGllbnRfaWQgaGFzIGFscmVhZHkgYmVlbiBhc3NpZ25lZC5cIilcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkIGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzcG9uc2VfdHlwZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVzcG9uc2VfdHlwZTtcclxuICAgIH1cclxuICAgIGdldCBzY29wZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2NvcGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG9wdGlvbmFsIHByb3RvY29sIHBhcmFtc1xyXG4gICAgZ2V0IHByb21wdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbXB0O1xyXG4gICAgfVxyXG4gICAgZ2V0IGRpc3BsYXkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3BsYXk7XHJcbiAgICB9XHJcbiAgICBnZXQgbWF4X2FnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWF4X2FnZTtcclxuICAgIH1cclxuICAgIGdldCB1aV9sb2NhbGVzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl91aV9sb2NhbGVzO1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjcl92YWx1ZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Fjcl92YWx1ZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzb3VyY2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc291cmNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IHJlc3BvbnNlX21vZGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc3BvbnNlX21vZGU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG1ldGFkYXRhXHJcbiAgICBnZXQgYXV0aG9yaXR5KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hdXRob3JpdHk7XHJcbiAgICB9XHJcbiAgICBzZXQgYXV0aG9yaXR5KHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgLy8gb25lLXRpbWUgc2V0IG9ubHlcclxuICAgICAgICAgICAgdGhpcy5fYXV0aG9yaXR5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50U2V0dGluZ3Muc2V0X2F1dGhvcml0eTogYXV0aG9yaXR5IGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eSBoYXMgYWxyZWFkeSBiZWVuIGFzc2lnbmVkLlwiKVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBtZXRhZGF0YVVybCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX21ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhVXJsID0gdGhpcy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5fbWV0YWRhdGFVcmwgJiYgdGhpcy5fbWV0YWRhdGFVcmwuaW5kZXhPZihPaWRjTWV0YWRhdGFVcmxQYXRoKSA8IDApIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9tZXRhZGF0YVVybFt0aGlzLl9tZXRhZGF0YVVybC5sZW5ndGggLSAxXSAhPT0gJy8nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gT2lkY01ldGFkYXRhVXJsUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhVXJsO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHNldHRhYmxlL2NhY2hhYmxlIG1ldGFkYXRhIHZhbHVlc1xyXG4gICAgZ2V0IG1ldGFkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YTtcclxuICAgIH1cclxuICAgIHNldCBtZXRhZGF0YSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5nS2V5cztcclxuICAgIH1cclxuICAgIHNldCBzaWduaW5nS2V5cyh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX3NpZ25pbmdLZXlzID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYmVoYXZpb3IgZmxhZ3NcclxuICAgIGdldCBmaWx0ZXJQcm90b2NvbENsYWltcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyUHJvdG9jb2xDbGFpbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgbG9hZFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBnZXQgc3RhbGVTdGF0ZUFnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhbGVTdGF0ZUFnZTtcclxuICAgIH1cclxuICAgIGdldCBjbG9ja1NrZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrU2tldztcclxuICAgIH1cclxuICAgIGdldCB1c2VySW5mb0p3dElzc3VlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHN0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlU3RvcmU7XHJcbiAgICB9XHJcbiAgICBnZXQgdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICBnZXQgZXh0cmFRdWVyeVBhcmFtcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZXh0cmFRdWVyeVBhcmFtcztcclxuICAgIH1cclxuICAgIHNldCBleHRyYVF1ZXJ5UGFyYW1zKHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpe1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVF1ZXJ5UGFyYW1zID0gdmFsdWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHt9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBleHRyYSB0b2tlbiBwYXJhbXNcclxuICAgIGdldCBleHRyYVRva2VuUGFyYW1zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHRyYVRva2VuUGFyYW1zO1xyXG4gICAgfVxyXG4gICAgc2V0IGV4dHJhVG9rZW5QYXJhbXModmFsdWUpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jyl7XHJcbiAgICAgICAgICAgIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXMgPSB2YWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0ge307XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgUG9wdXBXaW5kb3cgfSBmcm9tICcuL1BvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBQb3B1cE5hdmlnYXRvciB7XHJcblxyXG4gICAgcHJlcGFyZShwYXJhbXMpIHtcclxuICAgICAgICBsZXQgcG9wdXAgPSBuZXcgUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwsIGtlZXBPcGVuLCBkZWxpbWl0ZXIpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cE5hdmlnYXRvci5jYWxsYmFja1wiKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgUG9wdXBXaW5kb3cubm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgQ2hlY2tGb3JQb3B1cENsb3NlZEludGVydmFsID0gNTAwO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7JztcclxuLy9jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7cmVzaXphYmxlPXllcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFBvcHVwV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsZXQgdGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBsZXQgZmVhdHVyZXMgPSBwYXJhbXMucG9wdXBXaW5kb3dGZWF0dXJlcyB8fCBEZWZhdWx0UG9wdXBGZWF0dXJlcztcclxuXHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSB3aW5kb3cub3BlbignJywgdGFyZ2V0LCBmZWF0dXJlcyk7XHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmN0b3I6IHBvcHVwIHN1Y2Nlc3NmdWxseSBjcmVhdGVkXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSB3aW5kb3cuc2V0SW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZC5iaW5kKHRoaXMpLCBDaGVja0ZvclBvcHVwQ2xvc2VkSW50ZXJ2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgcHJvbWlzZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICBuYXZpZ2F0ZShwYXJhbXMpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IEVycm9yIG9wZW5pbmcgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IG5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJObyB1cmwgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5uYXZpZ2F0ZTogU2V0dGluZyBVUkwgaW4gcG9wdXBcIik7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9pZCA9IHBhcmFtcy5pZDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lkKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3dbXCJwb3B1cENhbGxiYWNrX1wiICsgcGFyYW1zLmlkXSA9IHRoaXMuX2NhbGxiYWNrLmJpbmQodGhpcyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLndpbmRvdy5sb2NhdGlvbiA9IHBhcmFtcy51cmw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5jYWxsYmFjazogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIHBvcHVwIHdpbmRvd1wiKTtcclxuXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIExvZy5lcnJvcihcIlBvcHVwV2luZG93LmVycm9yOiBcIiwgbWVzc2FnZSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIF9jbGVhbnVwKGtlZXBPcGVuKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUG9wdXBXaW5kb3cuY2xlYW51cFwiKTtcclxuXHJcbiAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZFRpbWVyKTtcclxuICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSBudWxsO1xyXG5cclxuICAgICAgICBkZWxldGUgd2luZG93W1wicG9wdXBDYWxsYmFja19cIiArIHRoaXMuX2lkXTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwICYmICFrZWVwT3Blbikge1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5jbG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9wb3B1cCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgX2NoZWNrRm9yUG9wdXBDbG9zZWQoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9wb3B1cCB8fCB0aGlzLl9wb3B1cC5jbG9zZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJQb3B1cCB3aW5kb3cgY2xvc2VkXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfY2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoa2VlcE9wZW4pO1xyXG5cclxuICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrIHN1Y2Nlc3NcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX3N1Y2Nlc3MoeyB1cmw6IHVybCB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrOiBJbnZhbGlkIHJlc3BvbnNlIGZyb20gcG9wdXBcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiSW52YWxpZCByZXNwb25zZSBmcm9tIHBvcHVwXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgbm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcikge1xyXG4gICAgICAgIGlmICh3aW5kb3cub3BlbmVyKSB7XHJcbiAgICAgICAgICAgIHVybCA9IHVybCB8fCB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWUgPSBcInBvcHVwQ2FsbGJhY2tfXCIgKyBkYXRhLnN0YXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IHdpbmRvdy5vcGVuZXJbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogcGFzc2luZyB1cmwgbWVzc2FnZSB0byBvcGVuZXJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJQb3B1cFdpbmRvdy5ub3RpZnlPcGVuZXI6IG5vIG1hdGNoaW5nIGNhbGxiYWNrIGZvdW5kIG9uIG9wZW5lclwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gc3RhdGUgZm91bmQgaW4gcmVzcG9uc2UgdXJsXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gd2luZG93Lm9wZW5lci4gQ2FuJ3QgY29tcGxldGUgbm90aWZpY2F0aW9uLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlZGlyZWN0TmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKCkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgbmF2aWdhdGUocGFyYW1zKSB7XHJcbiAgICAgICAgaWYgKCFwYXJhbXMgfHwgIXBhcmFtcy51cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVkaXJlY3ROYXZpZ2F0b3IubmF2aWdhdGU6IE5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHVybCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyYW1zLnVzZVJlcGxhY2VUb05hdmlnYXRlKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHBhcmFtcy51cmwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdXJsKCkge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgVXNlckluZm9TZXJ2aWNlIH0gZnJvbSAnLi9Vc2VySW5mb1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBUb2tlbkNsaWVudCB9IGZyb20gJy4vVG9rZW5DbGllbnQuanMnO1xyXG5pbXBvcnQgeyBFcnJvclJlc3BvbnNlIH0gZnJvbSAnLi9FcnJvclJlc3BvbnNlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmNvbnN0IFByb3RvY29sQ2xhaW1zID0gW1wibm9uY2VcIiwgXCJhdF9oYXNoXCIsIFwiaWF0XCIsIFwibmJmXCIsIFwiZXhwXCIsIFwiYXVkXCIsIFwiaXNzXCIsIFwiY19oYXNoXCJdO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlc3BvbnNlVmFsaWRhdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgXHJcbiAgICAgICAgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSxcclxuICAgICAgICBVc2VySW5mb1NlcnZpY2VDdG9yID0gVXNlckluZm9TZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsLFxyXG4gICAgICAgIFRva2VuQ2xpZW50Q3RvciA9IFRva2VuQ2xpZW50KSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWQgdG8gUmVzcG9uc2VWYWxpZGF0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9TZXJ2aWNlID0gbmV3IFVzZXJJbmZvU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICAgICAgdGhpcy5fdG9rZW5DbGllbnQgPSBuZXcgVG9rZW5DbGllbnRDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzU2lnbmluUGFyYW1zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2U6IHN0YXRlIHByb2Nlc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlVG9rZW5zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiB0b2tlbnMgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3NDbGFpbXMoc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiBjbGFpbXMgcHJvY2Vzc2VkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoc3RhdGUuaWQgIT09IHJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbm91dFJlc3BvbnNlOiBTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlN0YXRlIGRvZXMgbm90IG1hdGNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG5vdyB0aGF0IHdlIGtub3cgdGhlIHN0YXRlIG1hdGNoZXMsIHRha2UgdGhlIHN0b3JlZCBkYXRhXHJcbiAgICAgICAgLy8gYW5kIHNldCBpdCBpbnRvIHRoZSByZXNwb25zZSBzbyBjYWxsZXJzIGNhbiBnZXQgdGhlaXIgc3RhdGVcclxuICAgICAgICAvLyB0aGlzIGlzIGltcG9ydGFudCBmb3IgYm90aCBzdWNjZXNzICYgZXJyb3Igb3V0Y29tZXNcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZTogc3RhdGUgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgIHJlc3BvbnNlLnN0YXRlID0gc3RhdGUuZGF0YTtcclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmVycm9yKSB7XHJcbiAgICAgICAgICAgIExvZy53YXJuKFwiUmVzcG9uc2VWYWxpZGF0b3IudmFsaWRhdGVTaWdub3V0UmVzcG9uc2U6IFJlc3BvbnNlIHdhcyBlcnJvclwiLCByZXNwb25zZS5lcnJvcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3JSZXNwb25zZShyZXNwb25zZSkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NTaWduaW5QYXJhbXMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHN0YXRlLmlkICE9PSByZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogU3RhdGUgZG9lcyBub3QgbWF0Y2hcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuYXV0aG9yaXR5KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBObyBhdXRob3JpdHkgb24gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb24gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gdGhpcyBhbGxvd3MgdGhlIGF1dGhvcml0eSB0byBiZSBsb2FkZWQgZnJvbSB0aGUgc2lnbmluIHN0YXRlXHJcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MuYXV0aG9yaXR5ID0gc3RhdGUuYXV0aG9yaXR5O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBlbnN1cmUgd2UncmUgdXNpbmcgdGhlIGNvcnJlY3QgYXV0aG9yaXR5IGlmIHRoZSBhdXRob3JpdHkgaXMgbm90IGxvYWRlZCBmcm9tIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eSAmJiB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkgIT09IHN0YXRlLmF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogYXV0aG9yaXR5IG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJhdXRob3JpdHkgbWlzbWF0Y2ggb24gc2V0dGluZ3MgdnMuIHNpZ25pbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRoaXMgYWxsb3dzIHRoZSBjbGllbnRfaWQgdG8gYmUgbG9hZGVkIGZyb20gdGhlIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZCA9IHN0YXRlLmNsaWVudF9pZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZW5zdXJlIHdlJ3JlIHVzaW5nIHRoZSBjb3JyZWN0IGNsaWVudF9pZCBpZiB0aGUgY2xpZW50X2lkIGlzIG5vdCBsb2FkZWQgZnJvbSBzaWduaW4gc3RhdGVcclxuICAgICAgICBlbHNlIGlmICh0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQgJiYgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkICE9PSBzdGF0ZS5jbGllbnRfaWQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NTaWduaW5QYXJhbXM6IGNsaWVudF9pZCBtaXNtYXRjaCBvbiBzZXR0aW5ncyB2cy4gc2lnbmluIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiY2xpZW50X2lkIG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gbm93IHRoYXQgd2Uga25vdyB0aGUgc3RhdGUgbWF0Y2hlcywgdGFrZSB0aGUgc3RvcmVkIGRhdGFcclxuICAgICAgICAvLyBhbmQgc2V0IGl0IGludG8gdGhlIHJlc3BvbnNlIHNvIGNhbGxlcnMgY2FuIGdldCB0aGVpciBzdGF0ZVxyXG4gICAgICAgIC8vIHRoaXMgaXMgaW1wb3J0YW50IGZvciBib3RoIHN1Y2Nlc3MgJiBlcnJvciBvdXRjb21lc1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBzdGF0ZSB2YWxpZGF0ZWRcIik7XHJcbiAgICAgICAgcmVzcG9uc2Uuc3RhdGUgPSBzdGF0ZS5kYXRhO1xyXG5cclxuICAgICAgICBpZiAocmVzcG9uc2UuZXJyb3IpIHtcclxuICAgICAgICAgICAgTG9nLndhcm4oXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogUmVzcG9uc2Ugd2FzIGVycm9yXCIsIHJlc3BvbnNlLmVycm9yKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUubm9uY2UgJiYgIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBFeHBlY3RpbmcgaWRfdG9rZW4gaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLm5vbmNlICYmIHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGlkX3Rva2VuIGluIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5leHBlY3RlZCBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUuY29kZV92ZXJpZmllciAmJiAhcmVzcG9uc2UuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogRXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBjb2RlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuY29kZV92ZXJpZmllciAmJiByZXNwb25zZS5jb2RlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGNvZGUgaW4gcmVzcG9uc2VcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zY29wZSkge1xyXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSdzIG5vIHNjb3BlIG9uIHRoZSByZXNwb25zZSwgdGhlbiBhc3N1bWUgYWxsIHNjb3BlcyBncmFudGVkIChwZXItc3BlYykgYW5kIGNvcHkgb3ZlciBzY29wZXMgZnJvbSBvcmlnaW5hbCByZXF1ZXN0XHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnNjb3BlID0gc3RhdGUuc2NvcGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcHJvY2Vzc0NsYWltcyhzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAocmVzcG9uc2UuaXNPcGVuSWRDb25uZWN0KSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiByZXNwb25zZSBpcyBPSURDLCBwcm9jZXNzaW5nIGNsYWltc1wiKTtcclxuXHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnByb2ZpbGUgPSB0aGlzLl9maWx0ZXJQcm90b2NvbENsYWltcyhyZXNwb25zZS5wcm9maWxlKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5za2lwVXNlckluZm8gIT09IHRydWUgJiYgdGhpcy5fc2V0dGluZ3MubG9hZFVzZXJJbmZvICYmIHJlc3BvbnNlLmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IGxvYWRpbmcgdXNlciBpbmZvXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zKHJlc3BvbnNlLmFjY2Vzc190b2tlbikudGhlbihjbGFpbXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiB1c2VyIGluZm8gY2xhaW1zIHJlY2VpdmVkIGZyb20gdXNlciBpbmZvIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xhaW1zLnN1YiAhPT0gcmVzcG9uc2UucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHN1YiBmcm9tIHVzZXIgaW5mbyBlbmRwb2ludCBkb2VzIG5vdCBtYXRjaCBzdWIgaW4gYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic3ViIGZyb20gdXNlciBpbmZvIGVuZHBvaW50IGRvZXMgbm90IG1hdGNoIHN1YiBpbiBhY2Nlc3NfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UucHJvZmlsZSA9IHRoaXMuX21lcmdlQ2xhaW1zKHJlc3BvbnNlLnByb2ZpbGUsIGNsYWltcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHVzZXIgaW5mbyBjbGFpbXMgcmVjZWl2ZWQsIHVwZGF0ZWQgcHJvZmlsZTpcIiwgcmVzcG9uc2UucHJvZmlsZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IG5vdCBsb2FkaW5nIHVzZXIgaW5mb1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHJlc3BvbnNlIGlzIG5vdCBPSURDLCBub3QgcHJvY2Vzc2luZyBjbGFpbXNcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfbWVyZ2VDbGFpbXMoY2xhaW1zMSwgY2xhaW1zMikge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSBPYmplY3QuYXNzaWduKHt9LCBjbGFpbXMxKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBjbGFpbXMyKSB7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBjbGFpbXMyW25hbWVdO1xyXG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzID0gW3ZhbHVlc107XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSB2YWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdFtuYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRbbmFtZV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtuYW1lXS5pbmRleE9mKHZhbHVlKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W25hbWVdLnB1c2godmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdFtuYW1lXSAhPT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSB0aGlzLl9tZXJnZUNsYWltcyhyZXN1bHRbbmFtZV0sIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSBbcmVzdWx0W25hbWVdLCB2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIF9maWx0ZXJQcm90b2NvbENsYWltcyhjbGFpbXMpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyUHJvdG9jb2xDbGFpbXMsIGluY29taW5nIGNsYWltczpcIiwgY2xhaW1zKTtcclxuXHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oe30sIGNsYWltcyk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5fZmlsdGVyUHJvdG9jb2xDbGFpbXMpIHtcclxuICAgICAgICAgICAgUHJvdG9jb2xDbGFpbXMuZm9yRWFjaCh0eXBlID0+IHtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRbdHlwZV07XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlclByb3RvY29sQ2xhaW1zOiBwcm90b2NvbCBjbGFpbXMgZmlsdGVyZWRcIiwgcmVzdWx0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJQcm90b2NvbENsYWltczogcHJvdG9jb2wgY2xhaW1zIG5vdCBmaWx0ZXJlZFwiKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBfdmFsaWRhdGVUb2tlbnMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmNvZGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBWYWxpZGF0aW5nIGNvZGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzQ29kZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5hY2Nlc3NfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlbiBhbmQgYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbihzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBObyBjb2RlIHRvIHByb2Nlc3Mgb3IgaWRfdG9rZW4gdG8gdmFsaWRhdGVcIik7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NDb2RlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHZhciByZXF1ZXN0ID0ge1xyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHN0YXRlLmNsaWVudF9pZCxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldDogc3RhdGUuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgY29kZSA6IHJlc3BvbnNlLmNvZGUsXHJcbiAgICAgICAgICAgIHJlZGlyZWN0X3VyaTogc3RhdGUucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBjb2RlX3ZlcmlmaWVyOiBzdGF0ZS5jb2RlX3ZlcmlmaWVyXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMgJiYgdHlwZW9mKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHJlcXVlc3QsIHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5DbGllbnQuZXhjaGFuZ2VDb2RlKHJlcXVlc3QpLnRoZW4odG9rZW5SZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBmb3IodmFyIGtleSBpbiB0b2tlblJlc3BvbnNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gdG9rZW5SZXNwb25zZVtrZXldO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuaWRfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ29kZTogdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc2Z1bCwgcHJvY2Vzc2luZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc0NvZGU6IHRva2VuIHJlc3BvbnNlIHN1Y2Nlc3NmdWwsIHJldHVybmluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCkudGhlbihpc3N1ZXIgPT4ge1xyXG5cclxuICAgICAgICAgICAgbGV0IGF1ZGllbmNlID0gc3RhdGUuY2xpZW50X2lkO1xyXG4gICAgICAgICAgICBsZXQgY2xvY2tTa2V3SW5TZWNvbmRzID0gdGhpcy5fc2V0dGluZ3MuY2xvY2tTa2V3O1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogVmFsaWRhaW5nIEpXVCBhdHRyaWJ1dGVzOyB1c2luZyBjbG9jayBza2V3IChpbiBzZWNvbmRzKSBvZjogXCIsIGNsb2NrU2tld0luU2Vjb25kcyk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3RBdHRyaWJ1dGVzKHJlc3BvbnNlLmlkX3Rva2VuLCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXdJblNlY29uZHMpLnRoZW4ocGF5bG9hZCA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLm5vbmNlICYmIHN0YXRlLm5vbmNlICE9PSBwYXlsb2FkLm5vbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbkF0dHJpYnV0ZXM6IEludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN1YiBwcmVzZW50IGluIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gcGF5bG9hZDtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKCFzdGF0ZS5ub25jZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBub25jZSBvbiBzdGF0ZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIG5vbmNlIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzdGF0ZS5ub25jZSAhPT0gand0LnBheWxvYWQubm9uY2UpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSW52YWxpZCBub25jZSBpbiBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGtpZCA9IGp3dC5oZWFkZXIua2lkO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogUmVjZWl2ZWQgaXNzdWVyXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5cygpLnRoZW4oa2V5cyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gc2lnbmluZyBrZXlzIGZyb20gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFJlY2VpdmVkIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleXMgPSB0aGlzLl9maWx0ZXJCeUFsZyhrZXlzLCBqd3QuaGVhZGVyLmFsZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGtpZCBmb3VuZCBpbiBpZF90b2tlbiBhbmQgbW9yZSB0aGFuIG9uZSBrZXkgZm91bmQgaW4gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8ga2lkIGlzIG1hbmRhdG9yeSBvbmx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIGtleXMgaW4gdGhlIHJlZmVyZW5jZWQgSldLIFNldCBkb2N1bWVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cDovL29wZW5pZC5uZXQvc3BlY3Mvb3BlbmlkLWNvbm5lY3QtY29yZS0xXzAuaHRtbCNTaWduaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5cy5maWx0ZXIoa2V5ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5raWQgPT09IGtpZDtcclxuICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IE5vIGtleSBtYXRjaGluZyBraWQgb3IgYWxnIGZvdW5kIGluIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgYXVkaWVuY2UgPSBzdGF0ZS5jbGllbnRfaWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3QocmVzcG9uc2UuaWRfdG9rZW4sIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzKS50aGVuKCgpPT57XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSldUIHZhbGlkYXRpb24gc3VjY2Vzc2Z1bFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqd3QucGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzdWIgcHJlc2VudCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gand0LnBheWxvYWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKXtcclxuICAgICAgICB2YXIga3R5ID0gbnVsbDtcclxuICAgICAgICBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJSU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlJTQVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChhbGcuc3RhcnRzV2l0aChcIlBTXCIpKSB7XHJcbiAgICAgICAgICAgIGt0eSA9IFwiUFNcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJFU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIkVDXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyQnlBbGc6IGFsZyBub3Qgc3VwcG9ydGVkOiBcIiwgYWxnKTtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJCeUFsZzogTnVtYmVyIG9mIGtleXMgdGhhdCBtYXRjaCBrdHk6IFwiLCBrdHksIGtleXMubGVuZ3RoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGtleXM7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnByb2ZpbGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IE5vIHByb2ZpbGUgbG9hZGVkIGZyb20gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBwcm9maWxlIGxvYWRlZCBmcm9tIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBhdF9oYXNoIGluIGlkX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gYXRfaGFzaCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQWxnID0gand0LmhlYWRlci5hbGc7XHJcbiAgICAgICAgaWYgKCFoYXNoQWxnIHx8IGhhc2hBbGcubGVuZ3RoICE9PSA1KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBVbnN1cHBvcnRlZCBhbGc6XCIsIGhhc2hBbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQml0cyA9IGhhc2hBbGcuc3Vic3RyKDIsIDMpO1xyXG4gICAgICAgIGlmICghaGFzaEJpdHMpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IFVuc3VwcG9ydGVkIGFsZzpcIiwgaGFzaEFsZywgaGFzaEJpdHMpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGhhc2hCaXRzID0gcGFyc2VJbnQoaGFzaEJpdHMpO1xyXG4gICAgICAgIGlmIChoYXNoQml0cyAhPT0gMjU2ICYmIGhhc2hCaXRzICE9PSAzODQgJiYgaGFzaEJpdHMgIT09IDUxMikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogVW5zdXBwb3J0ZWQgYWxnOlwiLCBoYXNoQWxnLCBoYXNoQml0cyk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBhbGc6IFwiICsgaGFzaEFsZykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHNoYSA9IFwic2hhXCIgKyBoYXNoQml0cztcclxuICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2pvc2VVdGlsLmhhc2hTdHJpbmcocmVzcG9uc2UuYWNjZXNzX3Rva2VuLCBzaGEpO1xyXG4gICAgICAgIGlmICghaGFzaCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogYWNjZXNzX3Rva2VuIGhhc2ggZmFpbGVkOlwiLCBzaGEpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGF0X2hhc2hcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGxlZnQgPSBoYXNoLnN1YnN0cigwLCBoYXNoLmxlbmd0aCAvIDIpO1xyXG4gICAgICAgIHZhciBsZWZ0X2I2NHUgPSB0aGlzLl9qb3NlVXRpbC5oZXhUb0Jhc2U2NFVybChsZWZ0KTtcclxuICAgICAgICBpZiAobGVmdF9iNjR1ICE9PSByZXNwb25zZS5wcm9maWxlLmF0X2hhc2gpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIsIGxlZnRfYjY0dSwgcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBzdWNjZXNzXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IENoZWNrU2Vzc2lvbklGcmFtZSB9IGZyb20gJy4vQ2hlY2tTZXNzaW9uSUZyYW1lLmpzJztcclxuaW1wb3J0IHsgR2xvYmFsIH0gZnJvbSAnLi9HbG9iYWwuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNlc3Npb25Nb25pdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih1c2VyTWFuYWdlciwgQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvciA9IENoZWNrU2Vzc2lvbklGcmFtZSwgdGltZXIgPSBHbG9iYWwudGltZXIpIHtcclxuICAgICAgICBpZiAoIXVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLmN0b3I6IE5vIHVzZXIgbWFuYWdlciBwYXNzZWQgdG8gU2Vzc2lvbk1vbml0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVzZXJNYW5hZ2VyXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgICAgICB0aGlzLl9DaGVja1Nlc3Npb25JRnJhbWVDdG9yID0gQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvcjtcclxuICAgICAgICB0aGlzLl90aW1lciA9IHRpbWVyO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlckxvYWRlZCh0aGlzLl9zdGFydC5iaW5kKHRoaXMpKTtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlclVubG9hZGVkKHRoaXMuX3N0b3AuYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICAvLyBkb2luZyB0aGlzIG1hbnVhbGx5IGhlcmUgc2luY2UgY2FsbGluZyBnZXRVc2VyIFxyXG4gICAgICAgICAgICAvLyBkb2Vzbid0IHRyaWdnZXIgbG9hZCBldmVudC5cclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHVzZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLm1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXMoKS50aGVuKHNlc3Npb24gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0bXBVc2VyID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uX3N0YXRlIDogc2Vzc2lvbi5zZXNzaW9uX3N0YXRlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgJiYgc2Vzc2lvbi5zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG1wVXNlci5wcm9maWxlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViOiBzZXNzaW9uLnN1YixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2Vzc2lvbi5zaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodG1wVXNlcik7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yIGN0b3I6IGVycm9yIGZyb20gcXVlcnlTZXNzaW9uU3RhdHVzOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBhIGN0b3JcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2Vzc2lvbk1vbml0b3IgY3RvcjogZXJyb3IgZnJvbSBnZXRVc2VyOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IF9zZXR0aW5ncygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIuc2V0dGluZ3M7XHJcbiAgICB9XHJcbiAgICBnZXQgX21ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIubWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9jbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCBfY2hlY2tTZXNzaW9uSW50ZXJ2YWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9zdG9wQ2hlY2tTZXNzaW9uT25FcnJvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3Muc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgX3N0YXJ0KHVzZXIpIHtcclxuICAgICAgICBsZXQgc2Vzc2lvbl9zdGF0ZSA9IHVzZXIuc2Vzc2lvbl9zdGF0ZTtcclxuXHJcbiAgICAgICAgaWYgKHNlc3Npb25fc3RhdGUpIHtcclxuICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3ViID0gdXNlci5wcm9maWxlLnN1YjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NpZCA9IHVzZXIucHJvZmlsZS5zaWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBzdWI6XCIsIHRoaXMuX3N1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWIgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBhbm9ueW1vdXMgdXNlclwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRDaGVja1Nlc3Npb25JZnJhbWUoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IEluaXRpYWxpemluZyBjaGVjayBzZXNzaW9uIGlmcmFtZVwiKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX2NsaWVudF9pZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGludGVydmFsID0gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdG9wT25FcnJvciA9IHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lID0gbmV3IHRoaXMuX0NoZWNrU2Vzc2lvbklGcmFtZUN0b3IodGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKSwgY2xpZW50X2lkLCB1cmwsIGludGVydmFsLCBzdG9wT25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5sb2FkKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IE5vIGNoZWNrIHNlc3Npb24gaWZyYW1lIGZvdW5kIGluIHRoZSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBub24tcHJvbWlzZSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLl9zdGFydDogRXJyb3IgZnJvbSBnZXRDaGVja1Nlc3Npb25JZnJhbWU6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lLnN0YXJ0KHNlc3Npb25fc3RhdGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9zdG9wKCkge1xyXG4gICAgICAgIHRoaXMuX3N1YiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX3N0b3BcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5zdG9wKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fc2V0dGluZ3MubW9uaXRvckFub255bW91c1Nlc3Npb24pIHtcclxuICAgICAgICAgICAgLy8gdXNpbmcgYSB0aW1lciB0byBkZWxheSByZS1pbml0aWFsaXphdGlvbiB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnMgZHVyaW5nIHNpZ25vdXRcclxuICAgICAgICAgICAgbGV0IHRpbWVySGFuZGxlID0gdGhpcy5fdGltZXIuc2V0SW50ZXJ2YWwoKCk9PntcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGltZXJIYW5kbGUpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRtcFVzZXIgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGUgOiBzZXNzaW9uLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uLnN1YiAmJiBzZXNzaW9uLnNpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0bXBVc2VyLnByb2ZpbGUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWI6IHNlc3Npb24uc3ViLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lkOiBzZXNzaW9uLnNpZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0bXBVc2VyKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjYXRjaCB0byBzdXBwcmVzcyBlcnJvcnMgc2luY2Ugd2UncmUgaW4gYSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yOiBlcnJvciBmcm9tIHF1ZXJ5U2Vzc2lvblN0YXR1czpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB9LCAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgX2NhbGxiYWNrKCkge1xyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgIHZhciByYWlzZUV2ZW50ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgPT09IHRoaXMuX3N1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJhaXNlRXZlbnQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24uc2lkID09PSB0aGlzLl9zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTYW1lIHN1YiBzdGlsbCBsb2dnZWQgaW4gYXQgT1AsIHJlc3RhcnRpbmcgY2hlY2sgc2Vzc2lvbiBpZnJhbWU7IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb24uc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s6IFNhbWUgc3ViIHN0aWxsIGxvZ2dlZCBpbiBhdCBPUCwgc2Vzc2lvbiBzdGF0ZSBoYXMgY2hhbmdlZCwgcmVzdGFydGluZyBjaGVjayBzZXNzaW9uIGlmcmFtZTsgc2Vzc2lvbl9zdGF0ZTpcIiwgc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTZXNzaW9uQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRGlmZmVyZW50IHN1YmplY3Qgc2lnbmVkIGludG8gT1A6XCIsIHNlc3Npb24uc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogU3ViamVjdCBubyBsb25nZXIgc2lnbmVkIGludG8gT1BcIik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIG91dCBldmVudFwiKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlVXNlclNpZ25lZE91dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIGluIGV2ZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkSW4oKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdWIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRXJyb3IgY2FsbGluZyBxdWVyeUN1cnJlbnRTaWduaW5TZXNzaW9uOyByYWlzaW5nIHNpZ25lZCBvdXQgZXZlbnRcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTaWduZWRPdXQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluUmVxdWVzdCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWFuZGF0b3J5XHJcbiAgICAgICAgdXJsLCBjbGllbnRfaWQsIHJlZGlyZWN0X3VyaSwgcmVzcG9uc2VfdHlwZSwgc2NvcGUsIGF1dGhvcml0eSxcclxuICAgICAgICAvLyBvcHRpb25hbFxyXG4gICAgICAgIGRhdGEsIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgcmVxdWVzdCwgcmVxdWVzdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSwgY2xpZW50X3NlY3JldCwgZXh0cmFUb2tlblBhcmFtcywgc2tpcFVzZXJJbmZvXHJcbiAgICB9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlZGlyZWN0X3VyaVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gcmVzcG9uc2VfdHlwZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlc3BvbnNlX3R5cGVcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghc2NvcGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyBzY29wZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNjb3BlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIGF1dGhvcml0eSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eVwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBvaWRjID0gU2lnbmluUmVxdWVzdC5pc09pZGMocmVzcG9uc2VfdHlwZSk7XHJcbiAgICAgICAgbGV0IGNvZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV9tb2RlKSB7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlX21vZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKSA/IFwicXVlcnlcIiA6IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFNpZ25pblN0YXRlKHsgbm9uY2U6IG9pZGMsIFxyXG4gICAgICAgICAgICBkYXRhLCBjbGllbnRfaWQsIGF1dGhvcml0eSwgcmVkaXJlY3RfdXJpLCBcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogY29kZSwgXHJcbiAgICAgICAgICAgIHJlcXVlc3RfdHlwZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldCwgc2NvcGUsIGV4dHJhVG9rZW5QYXJhbXMsIHNraXBVc2VySW5mbyB9KTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJjbGllbnRfaWRcIiwgY2xpZW50X2lkKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInJlZGlyZWN0X3VyaVwiLCByZWRpcmVjdF91cmkpO1xyXG4gICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIFwicmVzcG9uc2VfdHlwZVwiLCByZXNwb25zZV90eXBlKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInNjb3BlXCIsIHNjb3BlKTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICBpZiAob2lkYykge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcIm5vbmNlXCIsIHRoaXMuc3RhdGUubm9uY2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29kZSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlXCIsIHRoaXMuc3RhdGUuY29kZV9jaGFsbGVuZ2UpO1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlX21ldGhvZFwiLCBcIlMyNTZcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgb3B0aW9uYWwgPSB7IHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlcXVlc3QsIHJlcXVlc3RfdXJpLCByZXNwb25zZV9tb2RlIH07XHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gb3B0aW9uYWwpe1xyXG4gICAgICAgICAgICBpZiAob3B0aW9uYWxba2V5XSkge1xyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwga2V5LCBvcHRpb25hbFtrZXldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGlzT2lkYyhyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiaWRfdG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgaXNPQXV0aChyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwidG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgc3RhdGljIGlzQ29kZShyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiY29kZVwiO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiAhIShyZXN1bHRbMF0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgT2lkY1Njb3BlID0gXCJvcGVuaWRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWduaW5SZXNwb25zZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih1cmwsIGRlbGltaXRlciA9IFwiI1wiKSB7XHJcblxyXG4gICAgICAgIHZhciB2YWx1ZXMgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLmNvZGUgPSB2YWx1ZXMuY29kZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgICAgIHRoaXMuaWRfdG9rZW4gPSB2YWx1ZXMuaWRfdG9rZW47XHJcbiAgICAgICAgdGhpcy5zZXNzaW9uX3N0YXRlID0gdmFsdWVzLnNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSB2YWx1ZXMuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgIHRoaXMudG9rZW5fdHlwZSA9IHZhbHVlcy50b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSB2YWx1ZXMuc2NvcGU7XHJcbiAgICAgICAgdGhpcy5wcm9maWxlID0gdW5kZWZpbmVkOyAvLyB3aWxsIGJlIHNldCBmcm9tIFJlc3BvbnNlVmFsaWRhdG9yXHJcblxyXG4gICAgICAgIHRoaXMuZXhwaXJlc19pbiA9IHZhbHVlcy5leHBpcmVzX2luO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKXtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHBhcnNlSW50KHZhbHVlKTtcclxuICAgICAgICBpZiAodHlwZW9mIGV4cGlyZXNfaW4gPT09ICdudW1iZXInICYmIGV4cGlyZXNfaW4gPiAwKSB7XHJcbiAgICAgICAgICAgIGxldCBub3cgPSBwYXJzZUludChEYXRlLm5vdygpIC8gMTAwMCk7XHJcbiAgICAgICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IG5vdyArIGV4cGlyZXNfaW47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVkKCkge1xyXG4gICAgICAgIGxldCBleHBpcmVzX2luID0gdGhpcy5leHBpcmVzX2luO1xyXG4gICAgICAgIGlmIChleHBpcmVzX2luICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4cGlyZXNfaW4gPD0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2NvcGVzKCkge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5zY29wZSB8fCBcIlwiKS5zcGxpdChcIiBcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGlzT3BlbklkQ29ubmVjdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zY29wZXMuaW5kZXhPZihPaWRjU2NvcGUpID49IDAgfHwgISF0aGlzLmlkX3Rva2VuO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuL1N0YXRlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluU3RhdGUgZXh0ZW5kcyBTdGF0ZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7bm9uY2UsIGF1dGhvcml0eSwgY2xpZW50X2lkLCByZWRpcmVjdF91cmksIGNvZGVfdmVyaWZpZXIsIHJlc3BvbnNlX21vZGUsIGNsaWVudF9zZWNyZXQsIHNjb3BlLCBleHRyYVRva2VuUGFyYW1zLCBza2lwVXNlckluZm99ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICBpZiAobm9uY2UgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSByYW5kb20oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAobm9uY2UpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSBub25jZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjb2RlX3ZlcmlmaWVyID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIC8vIHJhbmRvbSgpIHByb2R1Y2VzIDMyIGxlbmd0aFxyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX3ZlcmlmaWVyID0gcmFuZG9tKCkgKyByYW5kb20oKSArIHJhbmRvbSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChjb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvZGVfdmVyaWZpZXIgPSBjb2RlX3ZlcmlmaWVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAodGhpcy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIGxldCBoYXNoID0gSm9zZVV0aWwuaGFzaFN0cmluZyh0aGlzLmNvZGVfdmVyaWZpZXIsIFwiU0hBMjU2XCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX2NoYWxsZW5nZSA9IEpvc2VVdGlsLmhleFRvQmFzZTY0VXJsKGhhc2gpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSBjbGllbnRfaWQ7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X3NlY3JldCA9IGNsaWVudF9zZWNyZXQ7XHJcbiAgICAgICAgdGhpcy5fc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gZXh0cmFUb2tlblBhcmFtcztcclxuICAgICAgICB0aGlzLl9za2lwVXNlckluZm8gPSBza2lwVXNlckluZm87XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG5vbmNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub25jZTtcclxuICAgIH1cclxuICAgIGdldCBhdXRob3JpdHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dGhvcml0eTtcclxuICAgIH1cclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCByZWRpcmVjdF91cmkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZGlyZWN0X3VyaTtcclxuICAgIH1cclxuICAgIGdldCBjb2RlX3ZlcmlmaWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX3ZlcmlmaWVyO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNvZGVfY2hhbGxlbmdlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX2NoYWxsZW5nZTtcclxuICAgIH1cclxuICAgIGdldCByZXNwb25zZV9tb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNwb25zZV9tb2RlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgc2NvcGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Njb3BlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGV4dHJhVG9rZW5QYXJhbXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgc2tpcFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9za2lwVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJTaWduaW5TdGF0ZS50b1N0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgICAgICAgaWQ6IHRoaXMuaWQsXHJcbiAgICAgICAgICAgIGRhdGE6IHRoaXMuZGF0YSxcclxuICAgICAgICAgICAgY3JlYXRlZDogdGhpcy5jcmVhdGVkLFxyXG4gICAgICAgICAgICByZXF1ZXN0X3R5cGU6IHRoaXMucmVxdWVzdF90eXBlLFxyXG4gICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogdGhpcy5jb2RlX3ZlcmlmaWVyLFxyXG4gICAgICAgICAgICByZWRpcmVjdF91cmk6IHRoaXMucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBhdXRob3JpdHk6IHRoaXMuYXV0aG9yaXR5LFxyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY2xpZW50X2lkLFxyXG4gICAgICAgICAgICByZXNwb25zZV9tb2RlOiB0aGlzLnJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgICAgIGNsaWVudF9zZWNyZXQ6IHRoaXMuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgOiB0aGlzLmV4dHJhVG9rZW5QYXJhbXMsXHJcbiAgICAgICAgICAgIHNraXBVc2VySW5mbzogdGhpcy5za2lwVXNlckluZm9cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmFnZVN0cmluZykge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlNpZ25pblN0YXRlLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHZhciBkYXRhID0gSlNPTi5wYXJzZShzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICByZXR1cm4gbmV3IFNpZ25pblN0YXRlKGRhdGEpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlcXVlc3Qge1xyXG4gICAgY29uc3RydWN0b3Ioe3VybCwgaWRfdG9rZW5faGludCwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLCBkYXRhLCBleHRyYVF1ZXJ5UGFyYW1zLCByZXF1ZXN0X3R5cGV9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbm91dFJlcXVlc3QuY3RvcjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGlkX3Rva2VuX2hpbnQpIHtcclxuICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJpZF90b2tlbl9oaW50XCIsIGlkX3Rva2VuX2hpbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaVwiLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBuZXcgU3RhdGUoeyBkYXRhLCByZXF1ZXN0X3R5cGUgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlc3BvbnNlIHtcclxuICAgIGNvbnN0cnVjdG9yKHVybCkge1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVzID0gVXJsVXRpbGl0eS5wYXJzZVVybEZyYWdtZW50KHVybCwgXCI/XCIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWxlbnRSZW5ld1NlcnZpY2Uge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgIH1cclxuXHJcbiAgICBzdGFydCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrID0gdGhpcy5fdG9rZW5FeHBpcmluZy5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkQWNjZXNzVG9rZW5FeHBpcmluZyh0aGlzLl9jYWxsYmFjayk7XHJcblxyXG4gICAgICAgICAgICAvLyB0aGlzIHdpbGwgdHJpZ2dlciBsb2FkaW5nIG9mIHRoZSB1c2VyIHNvIHRoZSBleHBpcmluZyBldmVudHMgY2FuIGJlIGluaXRpYWxpemVkXHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXI9PntcclxuICAgICAgICAgICAgICAgIC8vIGRlbGliZXJhdGUgbm9wXHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVycj0+e1xyXG4gICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLnN0YXJ0OiBFcnJvciBmcm9tIGdldFVzZXI6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0b3AoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5yZW1vdmVBY2Nlc3NUb2tlbkV4cGlyaW5nKHRoaXMuX2NhbGxiYWNrKTtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdG9rZW5FeHBpcmluZygpIHtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5zaWduaW5TaWxlbnQoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTaWxlbnRSZW5ld1NlcnZpY2UuX3Rva2VuRXhwaXJpbmc6IFNpbGVudCB0b2tlbiByZW5ld2FsIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgfSwgZXJyID0+IHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLl90b2tlbkV4cGlyaW5nOiBFcnJvciBmcm9tIHNpZ25pblNpbGVudDpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlcnIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU3RhdGUge1xyXG4gICAgY29uc3RydWN0b3Ioe2lkLCBkYXRhLCBjcmVhdGVkLCByZXF1ZXN0X3R5cGV9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9pZCA9IGlkIHx8IHJhbmRvbSgpO1xyXG4gICAgICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xyXG5cclxuICAgICAgICBpZiAodHlwZW9mIGNyZWF0ZWQgPT09ICdudW1iZXInICYmIGNyZWF0ZWQgPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZWQgPSBjcmVhdGVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fY3JlYXRlZCA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdF90eXBlID0gIHJlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lkO1xyXG4gICAgfVxyXG4gICAgZ2V0IGRhdGEoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XHJcbiAgICB9XHJcbiAgICBnZXQgY3JlYXRlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlZDtcclxuICAgIH1cclxuICAgIGdldCByZXF1ZXN0X3R5cGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICB0b1N0b3JhZ2VTdHJpbmcoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUudG9TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxyXG4gICAgICAgICAgICBkYXRhOiB0aGlzLmRhdGEsXHJcbiAgICAgICAgICAgIGNyZWF0ZWQ6IHRoaXMuY3JlYXRlZCxcclxuICAgICAgICAgICAgcmVxdWVzdF90eXBlOiB0aGlzLnJlcXVlc3RfdHlwZVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBmcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBTdGF0ZShKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgY2xlYXJTdGFsZVN0YXRlKHN0b3JhZ2UsIGFnZSkge1xyXG5cclxuICAgICAgICB2YXIgY3V0b2ZmID0gRGF0ZS5ub3coKSAvIDEwMDAgLSBhZ2U7XHJcblxyXG4gICAgICAgIHJldHVybiBzdG9yYWdlLmdldEFsbEtleXMoKS50aGVuKGtleXMgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IGdvdCBrZXlzXCIsIGtleXMpO1xyXG5cclxuICAgICAgICAgICAgdmFyIHByb21pc2VzID0gW107XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGtleSA9IGtleXNbaV07XHJcbiAgICAgICAgICAgICAgICB2YXIgcCA9IHN0b3JhZ2UuZ2V0KGtleSkudGhlbihpdGVtID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVtb3ZlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBTdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhpdGVtKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogZ290IGl0ZW0gZnJvbSBrZXk6IFwiLCBrZXksIHN0YXRlLmNyZWF0ZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5jcmVhdGVkIDw9IGN1dG9mZikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogRXJyb3IgcGFyc2luZyBzdGF0ZSBmb3Iga2V5XCIsIGtleSwgZS5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogbm8gaXRlbSBpbiBzdG9yYWdlIGZvciBrZXk6IFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IHJlbW92ZWQgaXRlbSBmb3Iga2V5OiBcIiwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0b3JhZ2UucmVtb3ZlKGtleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChwKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuY2xlYXJTdGFsZVN0YXRlOiB3YWl0aW5nIG9uIHByb21pc2UgY291bnQ6XCIsIHByb21pc2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5jb25zdCBUaW1lckR1cmF0aW9uID0gNTsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIFRpbWVyIGV4dGVuZHMgRXZlbnQge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKG5hbWUsIHRpbWVyID0gR2xvYmFsLnRpbWVyLCBub3dGdW5jID0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc3VwZXIobmFtZSk7XHJcbiAgICAgICAgdGhpcy5fdGltZXIgPSB0aW1lcjtcclxuXHJcbiAgICAgICAgaWYgKG5vd0Z1bmMpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm93RnVuYyA9IG5vd0Z1bmM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9ub3dGdW5jID0gKCkgPT4gRGF0ZS5ub3coKSAvIDEwMDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBub3coKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuX25vd0Z1bmMoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdChkdXJhdGlvbikge1xyXG4gICAgICAgIGlmIChkdXJhdGlvbiA8PSAwKSB7XHJcbiAgICAgICAgICAgIGR1cmF0aW9uID0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZHVyYXRpb24gPSBwYXJzZUludChkdXJhdGlvbik7XHJcblxyXG4gICAgICAgIHZhciBleHBpcmF0aW9uID0gdGhpcy5ub3cgKyBkdXJhdGlvbjtcclxuICAgICAgICBpZiAodGhpcy5leHBpcmF0aW9uID09PSBleHBpcmF0aW9uICYmIHRoaXMuX3RpbWVySGFuZGxlKSB7XHJcbiAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gcmVpbml0aWFsaXplIHRvIHNhbWUgZXhwaXJhdGlvbiwgc28gYmFpbCBvdXRcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuaW5pdCB0aW1lciBcIiArIHRoaXMuX25hbWUgKyBcIiBza2lwcGluZyBpbml0aWFsaXphdGlvbiBzaW5jZSBhbHJlYWR5IGluaXRpYWxpemVkIGZvciBleHBpcmF0aW9uOlwiLCB0aGlzLmV4cGlyYXRpb24pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmNhbmNlbCgpO1xyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5pbml0IHRpbWVyIFwiICsgdGhpcy5fbmFtZSArIFwiIGZvciBkdXJhdGlvbjpcIiwgZHVyYXRpb24pO1xyXG4gICAgICAgIHRoaXMuX2V4cGlyYXRpb24gPSBleHBpcmF0aW9uO1xyXG5cclxuICAgICAgICAvLyB3ZSdyZSB1c2luZyBhIGZhaXJseSBzaG9ydCB0aW1lciBhbmQgdGhlbiBjaGVja2luZyB0aGUgZXhwaXJhdGlvbiBpbiB0aGVcclxuICAgICAgICAvLyBjYWxsYmFjayB0byBoYW5kbGUgc2NlbmFyaW9zIHdoZXJlIHRoZSBicm93c2VyIGRldmljZSBzbGVlcHMsIGFuZCB0aGVuXHJcbiAgICAgICAgLy8gdGhlIHRpbWVycyBlbmQgdXAgZ2V0dGluZyBkZWxheWVkLlxyXG4gICAgICAgIHZhciB0aW1lckR1cmF0aW9uID0gVGltZXJEdXJhdGlvbjtcclxuICAgICAgICBpZiAoZHVyYXRpb24gPCB0aW1lckR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHRpbWVyRHVyYXRpb24gPSBkdXJhdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fdGltZXJIYW5kbGUgPSB0aGlzLl90aW1lci5zZXRJbnRlcnZhbCh0aGlzLl9jYWxsYmFjay5iaW5kKHRoaXMpLCB0aW1lckR1cmF0aW9uICogMTAwMCk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCBleHBpcmF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHBpcmF0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGNhbmNlbCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fdGltZXJIYW5kbGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuY2FuY2VsOiBcIiwgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXJIYW5kbGUpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lckhhbmRsZSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9jYWxsYmFjaygpIHtcclxuICAgICAgICB2YXIgZGlmZiA9IHRoaXMuX2V4cGlyYXRpb24gLSB0aGlzLm5vdztcclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5jYWxsYmFjazsgXCIgKyB0aGlzLl9uYW1lICsgXCIgdGltZXIgZXhwaXJlcyBpbjpcIiwgZGlmZik7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9leHBpcmF0aW9uIDw9IHRoaXMubm93KSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsKCk7XHJcbiAgICAgICAgICAgIHN1cGVyLnJhaXNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuQ2xpZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHNldHRpbmdzLCBKc29uU2VydmljZUN0b3IgPSBKc29uU2VydmljZSwgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSkge1xyXG4gICAgICAgIGlmICghc2V0dGluZ3MpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZXR0aW5nc1wiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fanNvblNlcnZpY2UgPSBuZXcgSnNvblNlcnZpY2VDdG9yKCk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGV4Y2hhbmdlQ29kZShhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcImF1dGhvcml6YXRpb25fY29kZVwiO1xyXG4gICAgICAgIGFyZ3MuY2xpZW50X2lkID0gYXJncy5jbGllbnRfaWQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkO1xyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gYXJncy5yZWRpcmVjdF91cmkgfHwgdGhpcy5fc2V0dGluZ3MucmVkaXJlY3RfdXJpO1xyXG5cclxuICAgICAgICBpZiAoIWFyZ3MuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIGNvZGUgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSBjb2RlIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHJlZGlyZWN0X3VyaSBpcyByZXF1aXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghYXJncy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY29kZV92ZXJpZmllciBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIGNvZGVfdmVyaWZpZXIgaXMgcmVxdWlyZWRcIikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWFyZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IFJlY2VpdmVkIHRva2VuIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLnBvc3RGb3JtKHVybCwgYXJncykudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IHJlc3BvbnNlIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBleGNoYW5nZVJlZnJlc2hUb2tlbihhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcInJlZnJlc2hfdG9rZW5cIjtcclxuICAgICAgICBhcmdzLmNsaWVudF9pZCA9IGFyZ3MuY2xpZW50X2lkIHx8IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICBhcmdzLmNsaWVudF9zZWNyZXQgPSBhcmdzLmNsaWVudF9zZWNyZXQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuXHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuZXhjaGFuZ2VSZWZyZXNoVG9rZW46IE5vIHJlZnJlc2hfdG9rZW4gcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSByZWZyZXNoX3Rva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogUmVjZWl2ZWQgdG9rZW4gZW5kcG9pbnRcIik7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UucG9zdEZvcm0odXJsLCBhcmdzKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuOiByZXNwb25zZSByZWNlaXZlZFwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmNvbnN0IEFjY2Vzc1Rva2VuVHlwZUhpbnQgPSBcImFjY2Vzc190b2tlblwiO1xyXG5jb25zdCBSZWZyZXNoVG9rZW5UeXBlSGludCA9IFwicmVmcmVzaF90b2tlblwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuUmV2b2NhdGlvbkNsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgWE1MSHR0cFJlcXVlc3RDdG9yID0gR2xvYmFsLlhNTEh0dHBSZXF1ZXN0LCBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHNldHRpbmdzIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fWE1MSHR0cFJlcXVlc3RDdG9yID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZSA9IG5ldyBNZXRhZGF0YVNlcnZpY2VDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICByZXZva2UodG9rZW4sIHJlcXVpcmVkLCB0eXBlID0gXCJhY2Nlc3NfdG9rZW5cIikge1xyXG4gICAgICAgIGlmICghdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogTm8gdG9rZW4gcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHRva2VuIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0eXBlICE9PSBBY2Nlc3NUb2tlblR5cGVIaW50ICYmIHR5cGUgIT0gUmVmcmVzaFRva2VuVHlwZUhpbnQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogSW52YWxpZCB0b2tlbiB0eXBlXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRva2VuIHR5cGUuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRSZXZvY2F0aW9uRW5kcG9pbnQoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdXJsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBSZXZvY2F0aW9uIG5vdCBzdXBwb3J0ZWRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmV2b2NhdGlvbiBub3Qgc3VwcG9ydGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIG5vdCByZXF1aXJlZCwgc28gZG9uJ3QgZXJyb3IgYW5kIGp1c3QgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2U6IFJldm9raW5nIFwiICsgdHlwZSk7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfaWQgPSB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQ7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfc2VjcmV0ID0gdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZSh1cmwsIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgdG9rZW4sIHR5cGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2UodXJsLCBjbGllbnRfaWQsIGNsaWVudF9zZWNyZXQsIHRva2VuLCB0eXBlKSB7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblxyXG4gICAgICAgICAgICB2YXIgeGhyID0gbmV3IHRoaXMuX1hNTEh0dHBSZXF1ZXN0Q3RvcigpO1xyXG4gICAgICAgICAgICB4aHIub3BlbihcIlBPU1RcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIHhoci5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBIVFRQIHJlc3BvbnNlIHJlY2VpdmVkLCBzdGF0dXNcIiwgeGhyLnN0YXR1cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcih4aHIuc3RhdHVzVGV4dCArIFwiIChcIiArIHhoci5zdGF0dXMgKyBcIilcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB4aHIub25lcnJvciA9ICgpID0+IHsgXHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBOZXR3b3JrIEVycm9yLlwiKVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KFwiTmV0d29yayBFcnJvclwiKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHZhciBib2R5ID0gXCJjbGllbnRfaWQ9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoY2xpZW50X2lkKTtcclxuICAgICAgICAgICAgaWYgKGNsaWVudF9zZWNyZXQpIHtcclxuICAgICAgICAgICAgICAgIGJvZHkgKz0gXCImY2xpZW50X3NlY3JldD1cIiArIGVuY29kZVVSSUNvbXBvbmVudChjbGllbnRfc2VjcmV0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBib2R5ICs9IFwiJnRva2VuX3R5cGVfaGludD1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0eXBlKTtcclxuICAgICAgICAgICAgYm9keSArPSBcIiZ0b2tlbj1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0b2tlbik7XHJcblxyXG4gICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKTtcclxuICAgICAgICAgICAgeGhyLnNlbmQoYm9keSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXJsVXRpbGl0eSB7XHJcbiAgICBzdGF0aWMgYWRkUXVlcnlQYXJhbSh1cmwsIG5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKCc/JykgPCAwKSB7XHJcbiAgICAgICAgICAgIHVybCArPSBcIj9cIjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh1cmxbdXJsLmxlbmd0aCAtIDFdICE9PSBcIj9cIikge1xyXG4gICAgICAgICAgICB1cmwgKz0gXCImXCI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KG5hbWUpO1xyXG4gICAgICAgIHVybCArPSBcIj1cIjtcclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHVybDtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgcGFyc2VVcmxGcmFnbWVudCh2YWx1ZSwgZGVsaW1pdGVyID0gXCIjXCIsIGdsb2JhbCA9IEdsb2JhbCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKXtcclxuICAgICAgICAgICAgdmFsdWUgPSBnbG9iYWwubG9jYXRpb24uaHJlZjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBpZHggPSB2YWx1ZS5sYXN0SW5kZXhPZihkZWxpbWl0ZXIpO1xyXG4gICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cihpZHggKyAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChkZWxpbWl0ZXIgPT09IFwiP1wiKSB7XHJcbiAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGRvaW5nIHF1ZXJ5LCB0aGVuIHN0cmlwIG9mZiBoYXNoIGZyYWdtZW50IGJlZm9yZSB3ZSBwYXJzZVxyXG4gICAgICAgICAgICBpZHggPSB2YWx1ZS5pbmRleE9mKCcjJyk7XHJcbiAgICAgICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHIoMCwgaWR4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHBhcmFtcyA9IHt9LFxyXG4gICAgICAgICAgICByZWdleCA9IC8oW14mPV0rKT0oW14mXSopL2csXHJcbiAgICAgICAgICAgIG07XHJcblxyXG4gICAgICAgIHZhciBjb3VudGVyID0gMDtcclxuICAgICAgICB3aGlsZSAobSA9IHJlZ2V4LmV4ZWModmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHBhcmFtc1tkZWNvZGVVUklDb21wb25lbnQobVsxXSldID0gZGVjb2RlVVJJQ29tcG9uZW50KG1bMl0pO1xyXG4gICAgICAgICAgICBpZiAoY291bnRlcisrID4gNTApIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVybFV0aWxpdHkucGFyc2VVcmxGcmFnbWVudDogcmVzcG9uc2UgZXhjZWVkZWQgZXhwZWN0ZWQgbnVtYmVyIG9mIHBhcmFtZXRlcnNcIiwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogXCJSZXNwb25zZSBleGNlZWRlZCBleHBlY3RlZCBudW1iZXIgb2YgcGFyYW1ldGVyc1wiXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHBhcmFtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gcGFyYW1zO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHt9O1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyIHtcclxuICAgIGNvbnN0cnVjdG9yKHtpZF90b2tlbiwgc2Vzc2lvbl9zdGF0ZSwgYWNjZXNzX3Rva2VuLCByZWZyZXNoX3Rva2VuLCB0b2tlbl90eXBlLCBzY29wZSwgcHJvZmlsZSwgZXhwaXJlc19hdCwgc3RhdGV9KSB7XHJcbiAgICAgICAgdGhpcy5pZF90b2tlbiA9IGlkX3Rva2VuO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSBhY2Nlc3NfdG9rZW47XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoX3Rva2VuID0gcmVmcmVzaF90b2tlbjtcclxuICAgICAgICB0aGlzLnRva2VuX3R5cGUgPSB0b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLnByb2ZpbGUgPSBwcm9maWxlO1xyXG4gICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IGV4cGlyZXNfYXQ7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKSB7XHJcbiAgICAgICAgbGV0IGV4cGlyZXNfaW4gPSBwYXJzZUludCh2YWx1ZSk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBleHBpcmVzX2luID09PSAnbnVtYmVyJyAmJiBleHBpcmVzX2luID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgbm93ID0gcGFyc2VJbnQoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG4gICAgICAgICAgICB0aGlzLmV4cGlyZXNfYXQgPSBub3cgKyBleHBpcmVzX2luO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXhwaXJlZCgpIHtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHRoaXMuZXhwaXJlc19pbjtcclxuICAgICAgICBpZiAoZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHBpcmVzX2luIDw9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNjb3BlcygpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuc2NvcGUgfHwgXCJcIikuc3BsaXQoXCIgXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLnRvU3RvcmFnZVN0cmluZ1wiKTtcclxuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xyXG4gICAgICAgICAgICBpZF90b2tlbjogdGhpcy5pZF90b2tlbixcclxuICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogdGhpcy5zZXNzaW9uX3N0YXRlLFxyXG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46IHRoaXMuYWNjZXNzX3Rva2VuLFxyXG4gICAgICAgICAgICByZWZyZXNoX3Rva2VuOiB0aGlzLnJlZnJlc2hfdG9rZW4sXHJcbiAgICAgICAgICAgIHRva2VuX3R5cGU6IHRoaXMudG9rZW5fdHlwZSxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIHByb2ZpbGU6IHRoaXMucHJvZmlsZSxcclxuICAgICAgICAgICAgZXhwaXJlc19hdDogdGhpcy5leHBpcmVzX2F0XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGZyb21TdG9yYWdlU3RyaW5nKHN0b3JhZ2VTdHJpbmcpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgVXNlcihKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBKc29uU2VydmljZSB9IGZyb20gJy4vSnNvblNlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VySW5mb1NlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgc2V0dGluZ3MsIFxyXG4gICAgICAgIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlLCBcclxuICAgICAgICBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuICAgICAgICBpZiAoIXNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IodW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMuX2dldENsYWltc0Zyb21Kd3QuYmluZCh0aGlzKSk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Q2xhaW1zKHRva2VuKSB7XHJcbiAgICAgICAgaWYgKCF0b2tlbikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBObyB0b2tlbiBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHRva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VXNlckluZm9FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLmdldENsYWltczogcmVjZWl2ZWQgdXNlcmluZm8gdXJsXCIsIHVybCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UuZ2V0SnNvbih1cmwsIHRva2VuKS50aGVuKGNsYWltcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBjbGFpbXMgcmVjZWl2ZWRcIiwgY2xhaW1zKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjbGFpbXM7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRDbGFpbXNGcm9tSnd0KHJlcSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEZhaWxlZCB0byBwYXJzZSBKV1RcIiwgand0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcGFyc2UgaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIga2lkID0gand0LmhlYWRlci5raWQ7XHJcblxyXG4gICAgICAgICAgICBsZXQgaXNzdWVyUHJvbWlzZTtcclxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnT1AnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdBTlknOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoand0LnBheWxvYWQuaXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVyUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBpc3N1ZXJQcm9taXNlLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgaXNzdWVyOlwiICsgaXNzdWVyKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldFNpZ25pbmdLZXlzKCkudGhlbihrZXlzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlckluZm9TZXJ2aWNlLl9nZXRDbGFpbXNGcm9tSnd0OiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpZ25pbmcga2V5cyBmcm9tIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFraWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5cyA9IHRoaXMuX2ZpbHRlckJ5QWxnKGtleXMsIGp3dC5oZWFkZXIuYWxnKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBraWQgZm91bmQgaW4gaWRfdG9rZW4gYW5kIG1vcmUgdGhhbiBvbmUga2V5IGZvdW5kIGluIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGtpZCBpcyBtYW5kYXRvcnkgb25seSB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBrZXlzIGluIHRoZSByZWZlcmVuY2VkIEpXSyBTZXQgZG9jdW1lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwOi8vb3BlbmlkLm5ldC9zcGVjcy9vcGVuaWQtY29ubmVjdC1jb3JlLTFfMC5odG1sI1NpZ25pbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5LmtpZCA9PT0ga2lkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgha2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhdWRpZW5jZSA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0KHJlcS5yZXNwb25zZVRleHQsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzLCB1bmRlZmluZWQsIHRydWUpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEpXVCB2YWxpZGF0aW9uIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBqd3QucGF5bG9hZDtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEVycm9yIHBhcnNpbmcgSldUIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKSB7XHJcbiAgICAgICAgdmFyIGt0eSA9IG51bGw7XHJcbiAgICAgICAgaWYgKGFsZy5zdGFydHNXaXRoKFwiUlNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJSU0FcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJQU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlBTXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGFsZy5zdGFydHNXaXRoKFwiRVNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJFQ1wiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLl9maWx0ZXJCeUFsZzogYWxnIG5vdCBzdXBwb3J0ZWQ6IFwiLCBhbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZmlsdGVyQnlBbGc6IE51bWJlciBvZiBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5LCBrZXlzLmxlbmd0aCk7XHJcblxyXG4gICAgICAgIHJldHVybiBrZXlzO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudCB9IGZyb20gJy4vT2lkY0NsaWVudC5qcyc7XHJcbmltcG9ydCB7IFVzZXJNYW5hZ2VyU2V0dGluZ3MgfSBmcm9tICcuL1VzZXJNYW5hZ2VyU2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi9Vc2VyLmpzJztcclxuaW1wb3J0IHsgVXNlck1hbmFnZXJFdmVudHMgfSBmcm9tICcuL1VzZXJNYW5hZ2VyRXZlbnRzLmpzJztcclxuaW1wb3J0IHsgU2lsZW50UmVuZXdTZXJ2aWNlIH0gZnJvbSAnLi9TaWxlbnRSZW5ld1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBTZXNzaW9uTW9uaXRvciB9IGZyb20gJy4vU2Vzc2lvbk1vbml0b3IuanMnO1xyXG5pbXBvcnQgeyBUb2tlblJldm9jYXRpb25DbGllbnQgfSBmcm9tICcuL1Rva2VuUmV2b2NhdGlvbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IFRva2VuQ2xpZW50IH0gZnJvbSAnLi9Ub2tlbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IEpvc2VVdGlsIH0gZnJvbSAnLi9Kb3NlVXRpbC5qcyc7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFVzZXJNYW5hZ2VyIGV4dGVuZHMgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9LFxyXG4gICAgICAgIFNpbGVudFJlbmV3U2VydmljZUN0b3IgPSBTaWxlbnRSZW5ld1NlcnZpY2UsXHJcbiAgICAgICAgU2Vzc2lvbk1vbml0b3JDdG9yID0gU2Vzc2lvbk1vbml0b3IsXHJcbiAgICAgICAgVG9rZW5SZXZvY2F0aW9uQ2xpZW50Q3RvciA9IFRva2VuUmV2b2NhdGlvbkNsaWVudCxcclxuICAgICAgICBUb2tlbkNsaWVudEN0b3IgPSBUb2tlbkNsaWVudCxcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuXHJcbiAgICAgICAgaWYgKCEoc2V0dGluZ3MgaW5zdGFuY2VvZiBVc2VyTWFuYWdlclNldHRpbmdzKSkge1xyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IG5ldyBVc2VyTWFuYWdlclNldHRpbmdzKHNldHRpbmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xyXG5cclxuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVXNlck1hbmFnZXJFdmVudHMoc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3U2VydmljZSA9IG5ldyBTaWxlbnRSZW5ld1NlcnZpY2VDdG9yKHRoaXMpO1xyXG5cclxuICAgICAgICAvLyBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczsgdGhlc2Ugc2VydmljZXMgZGVwZW5kIHVwb24gdGhlIGV2ZW50cy5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5hdXRvbWF0aWNTaWxlbnRSZW5ldykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBhdXRvbWF0aWNTaWxlbnRSZW5ldyBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNpbGVudCByZW5ld1wiKTtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNpbGVudFJlbmV3KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5tb25pdG9yU2Vzc2lvbikge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBtb25pdG9yU2Vzc2lvbiBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNlc3Npb24gbW9uaXRvclwiKTtcclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbk1vbml0b3IgPSBuZXcgU2Vzc2lvbk1vbml0b3JDdG9yKHRoaXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50ID0gbmV3IFRva2VuUmV2b2NhdGlvbkNsaWVudEN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3Rva2VuQ2xpZW50ID0gbmV3IFRva2VuQ2xpZW50Q3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fam9zZVV0aWwgPSBqb3NlVXRpbDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3JlZGlyZWN0TmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9wb3B1cE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5ncy5wb3B1cE5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfaWZyYW1lTmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLmlmcmFtZU5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfdXNlclN0b3JlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnVzZXJTdG9yZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXZlbnRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5nZXRVc2VyOiB1c2VyIGxvYWRlZFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMubG9hZCh1c2VyLCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLmdldFVzZXI6IHVzZXIgbm90IGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVVzZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKG51bGwpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnJlbW92ZVVzZXI6IHVzZXIgcmVtb3ZlZCBmcm9tIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy51bmxvYWQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5SZWRpcmVjdChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpyXCI7XHJcbiAgICAgICAgbGV0IG5hdlBhcmFtcyA9IHtcclxuICAgICAgICAgICAgdXNlUmVwbGFjZVRvTmF2aWdhdGUgOiBhcmdzLnVzZVJlcGxhY2VUb05hdmlnYXRlXHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0OiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbmluUmVkaXJlY3RDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5SZWRpcmVjdENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmluUG9wdXAoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6cFwiO1xyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnBvcHVwX3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cDogTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pbihhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IHNpZ25pblBvcHVwIHN1Y2Nlc3NmdWwsIHNpZ25lZCBpbiBzdWI6IFwiLCB1c2VyLnByb2ZpbGUuc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBzaWduaW5Qb3B1cENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5DYWxsYmFjayh1cmwsIHRoaXMuX3BvcHVwTmF2aWdhdG9yKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSAmJiB1c2VyLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSkuY2F0Y2goZXJyPT57XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2sgZXJyb3I6IFwiICsgZXJyICYmIGVyci5tZXNzYWdlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnQoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6c1wiO1xyXG4gICAgICAgIC8vIGZpcnN0IGRldGVybWluZSBpZiB3ZSBoYXZlIGEgcmVmcmVzaCB0b2tlbiwgb3IgbmVlZCB0byB1c2UgaWZyYW1lXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIgJiYgdXNlci5yZWZyZXNoX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICBhcmdzLnJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlUmVmcmVzaFRva2VuKGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYXJncy5pZF90b2tlbl9oaW50ID0gYXJncy5pZF90b2tlbl9oaW50IHx8ICh0aGlzLnNldHRpbmdzLmluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyAmJiB1c2VyICYmIHVzZXIuaWRfdG9rZW4pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIgJiYgdGhpcy5fc2V0dGluZ3MudmFsaWRhdGVTdWJPblNpbGVudFJlbmV3KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50LCBzdWJqZWN0IHByaW9yIHRvIHNpbGVudCByZW5ldzogXCIsIHVzZXIucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MuY3VycmVudF9zdWIgPSB1c2VyLnByb2ZpbGUuc3ViO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblNpbGVudElmcmFtZShhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF91c2VSZWZyZXNoVG9rZW4oYXJncyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuKGFyZ3MpLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IE5vIHJlc3BvbnNlIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyByZXNwb25zZSByZXR1cm5lZCBmcm9tIHRva2VuIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghcmVzdWx0LmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3VzZVJlZnJlc2hUb2tlbjogTm8gYWNjZXNzIHRva2VuIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyBhY2Nlc3MgdG9rZW4gcmV0dXJuZWQgZnJvbSB0b2tlbiBlbmRwb2ludFwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGlkVG9rZW5WYWxpZGF0aW9uID0gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pZF90b2tlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZFRva2VuVmFsaWRhdGlvbiA9IHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbih1c2VyLnByb2ZpbGUsIHJlc3VsdC5pZF90b2tlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWRUb2tlblZhbGlkYXRpb24udGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IHJlZnJlc2ggdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc1wiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5pZF90b2tlbiA9IHJlc3VsdC5pZF90b2tlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSByZXN1bHQuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VyLnJlZnJlc2hfdG9rZW4gPSByZXN1bHQucmVmcmVzaF90b2tlbiB8fCB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXIuZXhwaXJlc19pbiA9IHJlc3VsdC5leHBpcmVzX2luO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKHVzZXIpLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW4ocHJvZmlsZSwgaWRfdG9rZW4pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0QXR0cmlidXRlcyhpZF90b2tlbiwgaXNzdWVyLCB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQsIHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldykudGhlbihwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLnN1YiAhPT0gcHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5fdmFsaWRhdGVJZFRva2VuRnJvbVRva2VuUmVmcmVzaFRva2VuOiBzdWIgaW4gaWRfdG9rZW4gZG9lcyBub3QgbWF0Y2ggY3VycmVudCBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcInN1YiBpbiBpZF90b2tlbiBkb2VzIG5vdCBtYXRjaCBjdXJyZW50IHN1YlwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5hdXRoX3RpbWUgJiYgcGF5bG9hZC5hdXRoX3RpbWUgIT09IHByb2ZpbGUuYXV0aF90aW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5henAgJiYgcGF5bG9hZC5henAgIT09IHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIXBheWxvYWQuYXpwICYmIHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIG5vdCBpbiBpZF90b2tlbiwgYnV0IHByZXNlbnQgaW4gb3JpZ2luYWwgaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImF6cCBub3QgaW4gaWRfdG9rZW4sIGJ1dCBwcmVzZW50IGluIG9yaWdpbmFsIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zaWduaW5TaWxlbnRJZnJhbWUoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3Muc2lsZW50X3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5TaWxlbnQ6IE5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhcmdzLnJlZGlyZWN0X3VyaSA9IHVybDtcclxuICAgICAgICBhcmdzLnByb21wdCA9IGFyZ3MucHJvbXB0IHx8IFwibm9uZVwiO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluKGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50OiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudDogbm8gc3ViXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdXNlcjtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluQ2FsbGJhY2sodXJsLCB0aGlzLl9pZnJhbWVOYXZpZ2F0b3IpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodXNlci5wcm9maWxlICYmIHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBubyBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25pbkNhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlLnJlcXVlc3RfdHlwZSA9PT0gXCJzaTpyXCIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2sodXJsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNpOnBcIikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2lnbmluUG9wdXBDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5yZXF1ZXN0X3R5cGUgPT09IFwic2k6c1wiKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJpbnZhbGlkIHJlc3BvbnNlX3R5cGUgaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRDYWxsYmFjayh1cmwsIGtlZXBPcGVuKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnBcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRQb3B1cENhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImludmFsaWQgcmVzcG9uc2VfdHlwZSBpbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHF1ZXJ5U2Vzc2lvblN0YXR1cyhhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpzXCI7IC8vIHRoaXMgYWN0cyBsaWtlIGEgc2lnbmluIHNpbGVudFxyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnNpbGVudF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXJncy5yZWRpcmVjdF91cmkgPSB1cmw7XHJcbiAgICAgICAgYXJncy5wcm9tcHQgPSBcIm5vbmVcIjtcclxuICAgICAgICBhcmdzLnJlc3BvbnNlX3R5cGUgPSBhcmdzLnJlc3BvbnNlX3R5cGUgfHwgdGhpcy5zZXR0aW5ncy5xdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZTtcclxuICAgICAgICBhcmdzLnNjb3BlID0gYXJncy5zY29wZSB8fCBcIm9wZW5pZFwiO1xyXG4gICAgICAgIGFyZ3Muc2tpcFVzZXJJbmZvID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblN0YXJ0KGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZShuYXZSZXNwb25zZS51cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzaWduaW5SZXNwb25zZS5zZXNzaW9uX3N0YXRlICYmIHNpZ25pblJlc3BvbnNlLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXM6IHF1ZXJ5U2Vzc2lvblN0YXR1cyBzdWNjZXNzIGZvciBzdWI6IFwiLCAgc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGU6IHNpZ25pblJlc3BvbnNlLnNlc3Npb25fc3RhdGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Yjogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zaWRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJxdWVyeVNlc3Npb25TdGF0dXMgc3VjY2Vzc2Z1bCwgdXNlciBub3QgYXV0aGVudGljYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyLnNlc3Npb25fc3RhdGUgJiYgdGhpcy5zZXR0aW5ncy5tb25pdG9yQW5vbnltb3VzU2Vzc2lvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIubWVzc2FnZSA9PSBcImxvZ2luX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiY29uc2VudF9yZXF1aXJlZFwiIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnIubWVzc2FnZSA9PSBcImludGVyYWN0aW9uX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiYWNjb3VudF9zZWxlY3Rpb25fcmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1czogcXVlcnlTZXNzaW9uU3RhdHVzIHN1Y2Nlc3MgZm9yIGFub255bW91cyB1c2VyXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogZXJyLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbmluKGFyZ3MsIG5hdmlnYXRvciwgbmF2aWdhdG9yUGFyYW1zID0ge30pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMpLnRoZW4obmF2UmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKG5hdlJlc3BvbnNlLnVybCwgYXJncyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG5cclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnByZXBhcmUobmF2aWdhdG9yUGFyYW1zKS50aGVuKGhhbmRsZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5TdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2lnbmluUmVxdWVzdChhcmdzKS50aGVuKHNpZ25pblJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBnb3Qgc2lnbmluIHJlcXVlc3RcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLnVybCA9IHNpZ25pblJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbmluUmVxdWVzdC5zdGF0ZS5pZDtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBFcnJvciBhZnRlciBwcmVwYXJpbmcgbmF2aWdhdG9yLCBjbG9zaW5nIG5hdmlnYXRvciB3aW5kb3dcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgX3NpZ25pbkVuZCh1cmwsIGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZSh1cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHVzZXIgPSBuZXcgVXNlcihzaWduaW5SZXNwb25zZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoYXJncy5jdXJyZW50X3N1Yikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MuY3VycmVudF9zdWIgIT09IHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBjdXJyZW50IHVzZXIgZG9lcyBub3QgbWF0Y2ggdXNlciByZXR1cm5lZCBmcm9tIHNpZ25pbi4gc3ViIGZyb20gc2lnbmluOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImxvZ2luX3JlcXVpcmVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IGN1cnJlbnQgdXNlciBtYXRjaGVzIHVzZXIgcmV0dXJuZWQgZnJvbSBzaWduaW5cIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0b3JlVXNlcih1c2VyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IHVzZXIgc3RvcmVkXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWduaW5DYWxsYmFjayh1cmwsIG5hdmlnYXRvcikge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5DYWxsYmFja1wiKTtcclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLmNhbGxiYWNrKHVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbm91dFJlZGlyZWN0KGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIGFyZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBhcmdzKTtcclxuXHJcbiAgICAgICAgYXJncy5yZXF1ZXN0X3R5cGUgPSBcInNvOnJcIjtcclxuICAgICAgICBsZXQgcG9zdExvZ291dFJlZGlyZWN0VXJpID0gYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKHBvc3RMb2dvdXRSZWRpcmVjdFVyaSl7XHJcbiAgICAgICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdExvZ291dFJlZGlyZWN0VXJpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgbmF2UGFyYW1zID0ge1xyXG4gICAgICAgICAgICB1c2VSZXBsYWNlVG9OYXZpZ2F0ZSA6IGFyZ3MudXNlUmVwbGFjZVRvTmF2aWdhdGVcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0U3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25vdXRSZWRpcmVjdDogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4ocmVzcG9uc2U9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UmVkaXJlY3RDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRQb3B1cChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzbzpwXCI7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuICAgICAgICBpZiAoYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpe1xyXG4gICAgICAgICAgICAvLyB3ZSdyZSBwdXR0aW5nIGEgZHVtbXkgZW50cnkgaW4gaGVyZSBiZWNhdXNlIHdlXHJcbiAgICAgICAgICAgIC8vIG5lZWQgYSB1bmlxdWUgaWQgZnJvbSB0aGUgc3RhdGUgZm9yIG5vdGlmaWNhdGlvblxyXG4gICAgICAgICAgICAvLyB0byB0aGUgcGFyZW50IHdpbmRvdywgd2hpY2ggaXMgbmVjZXNzYXJ5IGlmIHdlXHJcbiAgICAgICAgICAgIC8vIHBsYW4gdG8gcmV0dXJuIGJhY2sgdG8gdGhlIGNsaWVudCBhZnRlciBzaWdub3V0XHJcbiAgICAgICAgICAgIC8vIGFuZCBzbyB3ZSBjYW4gY2xvc2UgdGhlIHBvcHVwIGFmdGVyIHNpZ25vdXRcclxuICAgICAgICAgICAgYXJncy5zdGF0ZSA9IGFyZ3Muc3RhdGUgfHwge307XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbm91dChhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbm91dFBvcHVwOiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbm91dFBvcHVwQ2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Yoa2VlcE9wZW4pID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YodXJsKSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgICAgICAgIGtlZXBPcGVuID0gdXJsO1xyXG4gICAgICAgICAgICB1cmwgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9ICc/JztcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBOYXZpZ2F0b3IuY2FsbGJhY2sodXJsLCBrZWVwT3BlbiwgZGVsaW1pdGVyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UG9wdXBDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbm91dChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25vdXRTdGFydChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcykudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKG5hdlJlc3BvbnNlLnVybCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbm91dFN0YXJ0KGFyZ3MgPSB7fSwgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiBuYXZpZ2F0b3IucHJlcGFyZShuYXZpZ2F0b3JQYXJhbXMpLnRoZW4oaGFuZGxlID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IGxvYWRlZCBjdXJyZW50IHVzZXIgZnJvbSBzdG9yYWdlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciByZXZva2VQcm9taXNlID0gdGhpcy5fc2V0dGluZ3MucmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQgPyB0aGlzLl9yZXZva2VJbnRlcm5hbCh1c2VyKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldm9rZVByb21pc2UudGhlbigoKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZF90b2tlbiA9IGFyZ3MuaWRfdG9rZW5faGludCB8fCB1c2VyICYmIHVzZXIuaWRfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IFNldHRpbmcgaWRfdG9rZW4gaW50byBzaWdub3V0IHJlcXVlc3RcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MuaWRfdG9rZW5faGludCA9IGlkX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlVXNlcigpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbm91dFN0YXJ0OiB1c2VyIHJlbW92ZWQsIGNyZWF0aW5nIHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVNpZ25vdXRSZXF1ZXN0KGFyZ3MpLnRoZW4oc2lnbm91dFJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3JQYXJhbXMudXJsID0gc2lnbm91dFJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpZ25vdXRSZXF1ZXN0LnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbm91dFJlcXVlc3Quc3RhdGUuaWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogRXJyb3IgYWZ0ZXIgcHJlcGFyaW5nIG5hdmlnYXRvciwgY2xvc2luZyBuYXZpZ2F0b3Igd2luZG93XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZS5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWdub3V0RW5kKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsKS50aGVuKHNpZ25vdXRSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0RW5kOiBnb3Qgc2lnbm91dCByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBzaWdub3V0UmVzcG9uc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV2b2tlQWNjZXNzVG9rZW4oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUludGVybmFsKHVzZXIsIHRydWUpLnRoZW4oc3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3VjY2Vzcykge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiByZW1vdmluZyB0b2tlbiBwcm9wZXJ0aWVzIGZyb20gdXNlciBhbmQgcmUtc3RvcmluZ1wiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHVzZXIucmVmcmVzaF90b2tlbiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5leHBpcmVzX2F0ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB1c2VyLnRva2VuX3R5cGUgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdG9yZVVzZXIodXNlcikudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiB1c2VyIHN0b3JlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmxvYWQodXNlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5yZXZva2VBY2Nlc3NUb2tlbjogYWNjZXNzIHRva2VuIHJldm9rZWQgc3VjY2Vzc2Z1bGx5XCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2VJbnRlcm5hbCh1c2VyLCByZXF1aXJlZCkge1xyXG4gICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgIHZhciBhY2Nlc3NfdG9rZW4gPSB1c2VyLmFjY2Vzc190b2tlbjtcclxuICAgICAgICAgICAgdmFyIHJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oYXRTdWNjZXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJ0U3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0U3VjY2VzcyAmJiAhcnRTdWNjZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucmV2b2tlQWNjZXNzVG9rZW46IG5vIG5lZWQgdG8gcmV2b2tlIGR1ZSB0byBubyB0b2tlbihzKSwgb3IgSldUIGZvcm1hdFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0U3VjY2VzcyB8fCBydFN1Y2Nlc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKSB7XHJcbiAgICAgICAgLy8gY2hlY2sgZm9yIEpXVCB2cy4gcmVmZXJlbmNlIHRva2VuXHJcbiAgICAgICAgaWYgKCFhY2Nlc3NfdG9rZW4gfHwgYWNjZXNzX3Rva2VuLmluZGV4T2YoJy4nKSA+PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2UoYWNjZXNzX3Rva2VuLCByZXF1aXJlZCkudGhlbigoKSA9PiB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpIHtcclxuICAgICAgICBpZiAoIXJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZShyZWZyZXNoX3Rva2VuLCByZXF1aXJlZCwgXCJyZWZyZXNoX3Rva2VuXCIpLnRoZW4oKCkgPT4gdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhcnRTaWxlbnRSZW5ldygpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld1NlcnZpY2Uuc3RhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBzdG9wU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdTZXJ2aWNlLnN0b3AoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3VzZXJTdG9yZUtleSgpIHtcclxuICAgICAgICByZXR1cm4gYHVzZXI6JHt0aGlzLnNldHRpbmdzLmF1dGhvcml0eX06JHt0aGlzLnNldHRpbmdzLmNsaWVudF9pZH1gO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkVXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLmdldCh0aGlzLl91c2VyU3RvcmVLZXkpLnRoZW4oc3RvcmFnZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmIChzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fbG9hZFVzZXI6IHVzZXIgc3RvcmFnZVN0cmluZyBsb2FkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXNlci5mcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX2xvYWRVc2VyOiBubyB1c2VyIHN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0b3JlVXNlcih1c2VyKSB7XHJcbiAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc3RvcmVVc2VyOiBzdG9yaW5nIHVzZXJcIik7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RvcmFnZVN0cmluZyA9IHVzZXIudG9TdG9yYWdlU3RyaW5nKCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VyU3RvcmUuc2V0KHRoaXMuX3VzZXJTdG9yZUtleSwgc3RvcmFnZVN0cmluZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJzdG9yZVVzZXIuc3RvcmVVc2VyOiByZW1vdmluZyB1c2VyXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLnJlbW92ZSh0aGlzLl91c2VyU3RvcmVLZXkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEFjY2Vzc1Rva2VuRXZlbnRzIH0gZnJvbSAnLi9BY2Nlc3NUb2tlbkV2ZW50cy5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXNlck1hbmFnZXJFdmVudHMgZXh0ZW5kcyBBY2Nlc3NUb2tlbkV2ZW50cyB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcclxuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgbG9hZGVkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgdW5sb2FkZWRcIik7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvciA9IG5ldyBFdmVudChcIlNpbGVudCByZW5ldyBlcnJvclwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4gPSBuZXcgRXZlbnQoXCJVc2VyIHNpZ25lZCBpblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0ID0gbmV3IEV2ZW50KFwiVXNlciBzaWduZWQgb3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZCA9IG5ldyBFdmVudChcIlVzZXIgc2Vzc2lvbiBjaGFuZ2VkXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGxvYWQodXNlciwgcmFpc2VFdmVudD10cnVlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMubG9hZFwiKTtcclxuICAgICAgICBzdXBlci5sb2FkKHVzZXIpO1xyXG4gICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJMb2FkZWQucmFpc2UodXNlcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdW5sb2FkKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLnVubG9hZFwiKTtcclxuICAgICAgICBzdXBlci51bmxvYWQoKTtcclxuICAgICAgICB0aGlzLl91c2VyVW5sb2FkZWQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyTG9hZGVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJMb2FkZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyTG9hZGVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZFVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5yZW1vdmVIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRTaWxlbnRSZW5ld0Vycm9yKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvci5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVNpbGVudFJlbmV3RXJyb3IoY2IpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld0Vycm9yLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvclwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3RXJyb3IucmFpc2UoZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZEluKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLl9yYWlzZVVzZXJTaWduZWRJblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4ucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2lnbmVkT3V0KGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZE91dC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJTaWduZWRPdXQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0LnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZE91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlckV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkT3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTaWduZWRPdXQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQuYWRkSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICByZW1vdmVVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICBfcmFpc2VVc2VyU2Vzc2lvbkNoYW5nZWQoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlVXNlclNlc3Npb25DaGFuZ2VkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZC5yYWlzZSgpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudFNldHRpbmdzIH0gZnJvbSAnLi9PaWRjQ2xpZW50U2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBSZWRpcmVjdE5hdmlnYXRvciB9IGZyb20gJy4vUmVkaXJlY3ROYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBQb3B1cE5hdmlnYXRvciB9IGZyb20gJy4vUG9wdXBOYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVOYXZpZ2F0b3IgfSBmcm9tICcuL0lGcmFtZU5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IFdlYlN0b3JhZ2VTdGF0ZVN0b3JlIH0gZnJvbSAnLi9XZWJTdG9yYWdlU3RhdGVTdG9yZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuaW1wb3J0IHsgU2lnbmluUmVxdWVzdCB9IGZyb20gJy4vU2lnbmluUmVxdWVzdC5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDtcclxuY29uc3QgRGVmYXVsdENoZWNrU2Vzc2lvbkludGVydmFsID0gMjAwMDtcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyTWFuYWdlclNldHRpbmdzIGV4dGVuZHMgT2lkY0NsaWVudFNldHRpbmdzIHtcclxuICAgIGNvbnN0cnVjdG9yKHtcclxuICAgICAgICBwb3B1cF9yZWRpcmVjdF91cmksXHJcbiAgICAgICAgcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIHBvcHVwV2luZG93RmVhdHVyZXMsXHJcbiAgICAgICAgcG9wdXBXaW5kb3dUYXJnZXQsXHJcbiAgICAgICAgc2lsZW50X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dCxcclxuICAgICAgICBhdXRvbWF0aWNTaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyA9IHRydWUsXHJcbiAgICAgICAgbW9uaXRvclNlc3Npb24gPSB0cnVlLFxyXG4gICAgICAgIG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uID0gZmFsc2UsXHJcbiAgICAgICAgY2hlY2tTZXNzaW9uSW50ZXJ2YWwgPSBEZWZhdWx0Q2hlY2tTZXNzaW9uSW50ZXJ2YWwsXHJcbiAgICAgICAgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IgPSB0cnVlLFxyXG4gICAgICAgIHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlLFxyXG4gICAgICAgIHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0ID0gZmFsc2UsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgcmVkaXJlY3ROYXZpZ2F0b3IgPSBuZXcgUmVkaXJlY3ROYXZpZ2F0b3IoKSxcclxuICAgICAgICBwb3B1cE5hdmlnYXRvciA9IG5ldyBQb3B1cE5hdmlnYXRvcigpLFxyXG4gICAgICAgIGlmcmFtZU5hdmlnYXRvciA9IG5ldyBJRnJhbWVOYXZpZ2F0b3IoKSxcclxuICAgICAgICB1c2VyU3RvcmUgPSBuZXcgV2ViU3RvcmFnZVN0YXRlU3RvcmUoeyBzdG9yZTogR2xvYmFsLnNlc3Npb25TdG9yYWdlIH0pXHJcbiAgICB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICB0aGlzLl9wb3B1cF9yZWRpcmVjdF91cmkgPSBwb3B1cF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXMgPSBwb3B1cFdpbmRvd0ZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0ID0gcG9wdXBXaW5kb3dUYXJnZXQ7XHJcblxyXG4gICAgICAgIHRoaXMuX3NpbGVudF9yZWRpcmVjdF91cmkgPSBzaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlcXVlc3RUaW1lb3V0ID0gc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICAgICAgdGhpcy5fYXV0b21hdGljU2lsZW50UmVuZXcgPSBhdXRvbWF0aWNTaWxlbnRSZW5ldztcclxuICAgICAgICB0aGlzLl92YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXcgPSB2YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXc7XHJcbiAgICAgICAgdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3ID0gaW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX21vbml0b3JTZXNzaW9uID0gbW9uaXRvclNlc3Npb247XHJcbiAgICAgICAgdGhpcy5fbW9uaXRvckFub255bW91c1Nlc3Npb24gPSBtb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JbnRlcnZhbCA9IGNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgICAgIHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yID0gc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICAgICAgaWYgKHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICAgICAgfSBcclxuICAgICAgICBlbHNlIGlmIChhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnJlc3BvbnNlX3R5cGUpIHtcclxuICAgICAgICAgICAgdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUgPSBTaWduaW5SZXF1ZXN0LmlzT2lkYyhhcmd1bWVudHNbMF0ucmVzcG9uc2VfdHlwZSkgPyBcImlkX3Rva2VuXCIgOiBcImNvZGVcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gXCJpZF90b2tlblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9yZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCA9IHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG5cclxuICAgICAgICB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvciA9IHJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwTmF2aWdhdG9yID0gcG9wdXBOYXZpZ2F0b3I7XHJcbiAgICAgICAgdGhpcy5faWZyYW1lTmF2aWdhdG9yID0gaWZyYW1lTmF2aWdhdG9yO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyU3RvcmUgPSB1c2VyU3RvcmU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHBvcHVwX3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwV2luZG93RmVhdHVyZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBXaW5kb3dUYXJnZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzaWxlbnRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgIGdldCBzaWxlbnRSZXF1ZXN0VGltZW91dCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgYXV0b21hdGljU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9tYXRpY1NpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVTdWJPblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9uaXRvclNlc3Npb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vbml0b3JTZXNzaW9uO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgIH1cclxuICAgIGdldCBjaGVja1Nlc3Npb25JbnRlcnZhbCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICB9XHJcbiAgICBnZXQgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCByZWRpcmVjdE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBOYXZpZ2F0b3IoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwTmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IGlmcmFtZU5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faWZyYW1lTmF2aWdhdG9yO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB1c2VyU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VzZXJTdG9yZTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7cHJlZml4ID0gXCJvaWRjLlwiLCBzdG9yZSA9IEdsb2JhbC5sb2NhbFN0b3JhZ2V9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9zdG9yZSA9IHN0b3JlO1xyXG4gICAgICAgIHRoaXMuX3ByZWZpeCA9IHByZWZpeDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnNldFwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIHRoaXMuX3N0b3JlLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQoa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiV2ViU3RvcmFnZVN0YXRlU3RvcmUuZ2V0XCIsIGtleSk7XHJcblxyXG4gICAgICAgIGtleSA9IHRoaXMuX3ByZWZpeCArIGtleTtcclxuXHJcbiAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLl9zdG9yZS5nZXRJdGVtKGtleSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoaXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlKGtleSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnJlbW92ZVwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIGxldCBpdGVtID0gdGhpcy5fc3RvcmUuZ2V0SXRlbShrZXkpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlLnJlbW92ZUl0ZW0oa2V5KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpdGVtKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRBbGxLZXlzKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLmdldEFsbEtleXNcIik7XHJcblxyXG4gICAgICAgIHZhciBrZXlzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLl9zdG9yZS5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgbGV0IGtleSA9IHRoaXMuX3N0b3JlLmtleShpbmRleCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YodGhpcy5fcHJlZml4KSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleS5zdWJzdHIodGhpcy5fcHJlZml4Lmxlbmd0aCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGtleXMpO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IGp3cywgS0VZVVRJTCBhcyBLZXlVdGlsLCBYNTA5LCBjcnlwdG8sIGhleHRvYjY0dSwgYjY0dG9oZXggfSBmcm9tICcuLi8uLi9qc3JzYXNpZ24vZGlzdC9qc3JzYXNpZ24uanMnO1xyXG5cclxuY29uc3QgQWxsb3dlZFNpZ25pbmdBbGdzID0gWydSUzI1NicsICdSUzM4NCcsICdSUzUxMicsICdQUzI1NicsICdQUzM4NCcsICdQUzUxMicsICdFUzI1NicsICdFUzM4NCcsICdFUzUxMiddO1xyXG5cclxuZXhwb3J0IHtcclxuICAgIGp3cyxcclxuICAgIEtleVV0aWwsXHJcbiAgICBYNTA5LFxyXG4gICAgY3J5cHRvLFxyXG4gICAgaGV4dG9iNjR1LFxyXG4gICAgYjY0dG9oZXgsXHJcbiAgICBBbGxvd2VkU2lnbmluZ0FsZ3NcclxufTtcclxuIiwiaW1wb3J0IHV1aWQ0IGZyb20gJ3V1aWQvdjQnO1xyXG5cclxuLyoqXHJcbiAqIEdlbmVyYXRlcyBSRkM0MTIyIHZlcnNpb24gNCBndWlkICgpXHJcbiAqL1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmFuZG9tKCkge1xyXG4gIHJldHVybiB1dWlkNCgpLnJlcGxhY2UoLy0vZywgJycpO1xyXG59XHJcbiIsImNvbnN0IFZlcnNpb24gPSBcIjEuMTAuMVwiOyBleHBvcnQge1ZlcnNpb259OyJdLCJzb3VyY2VSb290IjoiIn0="
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/popup.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n<head>\n    <title></title>\n</head>\n<body>\n   \n    <script src=\"libs/oidc-client.js\"></script>\n    <script src=\"popup.js\"></script>\n</body>\n</html>\n\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/popup.js",
    "content": "﻿var mgr = new Oidc.UserManager();\nmgr.signinPopupCallback();\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/silent.html",
    "content": "﻿<!DOCTYPE html>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <title></title>\n</head>\n<body>\n    <script src=\"libs/oidc-client.js\"></script>\n    <script src=\"silent.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/src/JsOidc/wwwroot/silent.js",
    "content": "﻿var mgr = new Oidc.UserManager();\nmgr.signinSilentCallback();\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly IHttpClientFactory _httpClientFactory;\n\n    public HomeController(IHttpClientFactory httpClientFactory)\n    {\n        _httpClientFactory = httpClientFactory;\n    }\n\n    [AllowAnonymous]\n    public IActionResult Index() => View();\n\n    public IActionResult Secure() => View();\n\n    public IActionResult Logout() => SignOut(\"oidc\");\n\n    public async Task<IActionResult> CallApi()\n    {\n        var client = _httpClientFactory.CreateClient(\"client\");\n\n        var response = await client.GetStringAsync(\"identity\");\n        ViewBag.Json = JsonSerializer.Deserialize<JsonElement>(response).ToString();\n\n        return View();\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Clients;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/MvcAutomaticTokenManagement.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\ntry\n{\n    Log.Information(\"Starting host...\");\n    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n    var builder = WebApplication.CreateBuilder(args);\n    builder.Host.UseSerilog();\n    var services = builder.Services;\n\n\n    // add MVC\n    services.AddControllersWithViews();\n\n    // add cookie-based session management with OpenID Connect authentication\n    services.AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"cookie\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n        .AddCookie(\"cookie\", options =>\n        {\n            options.Cookie.Name = \"mvcclient\";\n\n            options.ExpireTimeSpan = TimeSpan.FromHours(8);\n            options.SlidingExpiration = false;\n\n            // could be used to automatically trigger re-authentication (if you want to do that at the pipeline level)\n            //options.Events.OnValidatePrincipal = async e =>\n            //{\n            //    var currentToken = await e.HttpContext.GetAccessTokenAsync();\n\n            //    if (string.IsNullOrWhiteSpace(currentToken))\n            //    {\n            //        e.RejectPrincipal();\n            //    }\n            //};\n\n            options.Events.OnSigningOut = async e =>\n            {\n                // automatically revoke refresh token at signout time\n                await e.HttpContext.RevokeUserRefreshTokenAsync();\n            };\n        })\n        .AddOpenIdConnect(\"oidc\", options =>\n        {\n            options.Authority = Constants.Authority;\n            options.RequireHttpsMetadata = false;\n\n            options.ClientId = \"mvc.tokenmanagement\";\n            options.ClientSecret = \"secret\";\n\n            // code flow + PKCE (PKCE is turned on by default)\n            options.ResponseType = \"code\";\n            options.UsePkce = true;\n\n            options.Scope.Clear();\n            options.Scope.Add(\"openid\");\n            options.Scope.Add(\"profile\");\n            options.Scope.Add(\"resource1.scope1\");\n            options.Scope.Add(\"offline_access\");\n\n            // keeps id_token smaller\n            options.GetClaimsFromUserInfoEndpoint = true;\n            options.SaveTokens = true;\n\n            options.TokenValidationParameters = new TokenValidationParameters\n            {\n                NameClaimType = \"name\",\n                RoleClaimType = \"role\"\n            };\n        });\n\n    // add automatic token management\n    services.AddAccessTokenManagement();\n\n    // add HTTP client to call protected API\n    services.AddUserAccessTokenHttpClient(\"client\", configureClient: client =>\n    {\n        client.BaseAddress = new Uri(Constants.SampleApi);\n    });\n\n    using (var app = builder.Build())\n    {\n        app\n            .UseSerilogRequestLogging()\n            .UseDeveloperExceptionPage()\n            .UseHttpsRedirection()\n            .UseStaticFiles()\n            .UseRouting()\n            .UseAuthentication()\n            .UseAuthorization();\n\n        app.MapDefaultControllerRoute().RequireAuthorization();\n\n        await app.RunAsync();\n        return 0;\n    }\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\nSerilog.ILogger ConfigureLogger() =>\n    Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Warning()\n    .MinimumLevel.Override(\"IdentityModel\", LogEventLevel.Debug)\n    .MinimumLevel.Override(\"System.Net.Http\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\")\n    .CreateLogger();"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:44301/\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Views/Home/CallApi.cshtml",
    "content": "﻿<h1>API Response</h1>\n\n<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n<div class=\"text-center\">\n    <h1 class=\"display-4\">Welcome</h1>\n    <p>Learn about <a href=\"https://docs.microsoft.com/aspnet/core\">building Web apps with ASP.NET Core</a>.</p>\n</div>\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Views/Home/Secure.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Views/Shared/_Layout.cshtml",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MVC Client</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcCode</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Secure\">Secure</a>\n                        </li>\n\n                        @if (User.Identity.IsAuthenticated)\n                        {\n                            <li class=\"nav-item\">\n                                <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"CallApi\">Call API</a>\n                            </li>\n                            <li class=\"nav-item\">\n                                <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                            </li>\n                        }\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcAutomaticTokenManagement/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly IHttpClientFactory _httpClientFactory;\n    private readonly IDiscoveryCache _discoveryCache;\n\n    public HomeController(IHttpClientFactory httpClientFactory, IDiscoveryCache discoveryCache)\n    {\n        _httpClientFactory = httpClientFactory;\n        _discoveryCache = discoveryCache;\n    }\n\n    [AllowAnonymous]\n    public IActionResult Index() => View();\n\n    public IActionResult Secure() => View();\n\n    public IActionResult Logout() => SignOut(\"oidc\");\n\n    public async Task<IActionResult> CallApi()\n    {\n        var token = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = _httpClientFactory.CreateClient();\n        client.SetBearerToken(token);\n\n        var response = await client.GetStringAsync(Constants.SampleApi + \"identity\");\n        ViewBag.Json = JsonSerializer.Deserialize<JsonElement>(response).ToString();\n\n        return View();\n    }\n\n    public async Task<IActionResult> RenewTokens()\n    {\n        var disco = await _discoveryCache.GetAsync();\n        if (disco.IsError) throw new Exception(disco.Error);\n\n        var rt = await HttpContext.GetTokenAsync(\"refresh_token\");\n        var tokenClient = _httpClientFactory.CreateClient();\n\n        var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = disco.TokenEndpoint,\n\n            ClientId = \"mvc.code\",\n            ClientSecret = \"secret\",\n            RefreshToken = rt\n        });\n\n        if (!tokenResult.IsError)\n        {\n            var oldIdToken = await HttpContext.GetTokenAsync(\"id_token\");\n            var newAccessToken = tokenResult.AccessToken;\n            var newRefreshToken = tokenResult.RefreshToken;\n            var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);\n\n            var info = await HttpContext.AuthenticateAsync(\"Cookies\");\n\n            info.Properties.UpdateTokenValue(\"refresh_token\", newRefreshToken);\n            info.Properties.UpdateTokenValue(\"access_token\", newAccessToken);\n            info.Properties.UpdateTokenValue(\"expires_at\", expiresAt.ToString(\"o\", CultureInfo.InvariantCulture));\n\n            await HttpContext.SignInAsync(\"Cookies\", info.Principal, info.Properties);\n            return Redirect(\"~/Home/Secure\");\n        }\n\n        ViewData[\"Error\"] = tokenResult.Error;\n        return View(\"Error\");\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Clients;\nglobal using IdentityModel;\nglobal using IdentityModel.Client;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authentication.Cookies;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using System.Globalization;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/MvcCode.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\nvar builder = WebApplication.CreateBuilder(args);\n\nvar services = builder.Services;\n\nservices.AddControllersWithViews();\n\nservices\n.AddHttpClient()\n.AddSingleton<IDiscoveryCache>(r =>\n{\n    var factory = r.GetRequiredService<IHttpClientFactory>();\n    return new DiscoveryCache(Constants.Authority, () => factory.CreateClient());\n}\n)\n.AddAuthentication(options =>\n{\n    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;\n    options.DefaultChallengeScheme = \"oidc\";\n})\n.AddCookie(options =>\n{\n    options.Cookie.Name = \"mvccode\";\n})\n.AddOpenIdConnect(\"oidc\", options =>\n{\n    options.Authority = Constants.Authority;\n    options.RequireHttpsMetadata = false;\n\n    options.ClientId = \"mvc.code\";\n    options.ClientSecret = \"secret\";\n\n    // code flow + PKCE (PKCE is turned on by default)\n    options.ResponseType = \"code\";\n    options.UsePkce = true;\n\n    options.Scope.Clear();\n    options.Scope.Add(\"openid\");\n    options.Scope.Add(\"profile\");\n    options.Scope.Add(\"email\");\n    options.Scope.Add(\"resource1.scope1\");\n    options.Scope.Add(\"transaction:123\");\n    //options.Scope.Add(\"transaction\");\n    options.Scope.Add(\"offline_access\");\n\n    // not mapped by default\n    options.ClaimActions.MapJsonKey(\"website\", \"website\");\n\n    // keeps id_token smaller\n    options.GetClaimsFromUserInfoEndpoint = true;\n    options.SaveTokens = true;\n\n    options.TokenValidationParameters = new TokenValidationParameters\n    {\n        NameClaimType = JwtClaimTypes.Name,\n        RoleClaimType = JwtClaimTypes.Role,\n    };\n});\n\nvar app = builder.Build();\n\napp.UseSerilogRequestLogging()\n.UseDeveloperExceptionPage()\n.UseHttpsRedirection()\n.UseStaticFiles()\n.UseRouting()\n.UseAuthentication()\n.UseAuthorization();\n\napp.MapDefaultControllerRoute().RequireAuthorization();\n\nawait app.RunAsync();\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Properties/launchSettings.json",
    "content": "﻿{\n  \"profiles\": {\n    \"Host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"https://localhost:44302\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/Home/CallApi.cshtml",
    "content": "﻿<h1>API Response</h1>\n\n<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n<div class=\"text-center\">\n    <h1 class=\"display-4\">Welcome</h1>\n    <p>Learn about <a href=\"https://docs.microsoft.com/aspnet/core\">building Web apps with ASP.NET Core</a>.</p>\n</div>\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/Home/Secure.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<div class=\"panel\">\n    <a class=\"btn btn-primary\" href=\"~/home/callapi\">Call API</a>\n    <a class=\"btn btn-primary\" href=\"~/home/renewtokens\">Renew Tokens</a>\n</div>\n\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/Shared/Error.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.\n</p>\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/Shared/_Layout.cshtml",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcCode</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcCode</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Secure\">Secure</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/src/MvcCode/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcCode/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly IHttpClientFactory _httpClientFactory;\n    private readonly IDiscoveryCache _discoveryCache;\n\n    public HomeController(IHttpClientFactory httpClientFactory, IDiscoveryCache discoveryCache)\n    {\n        _httpClientFactory = httpClientFactory;\n        _discoveryCache = discoveryCache;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public IActionResult Secure()\n    {\n        return View();\n    }\n\n    [Authorize]\n    public async Task<IActionResult> CallApi()\n    {\n        var token = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = _httpClientFactory.CreateClient();\n        client.SetBearerToken(token);\n\n        var response = await client.GetStringAsync(Constants.SampleApi + \"identity\");\n        ViewBag.Json = JsonSerializer.Deserialize<JsonElement>(response).ToString();\n\n        return View();\n    }\n\n    public async Task<IActionResult> RenewTokens()\n    {\n        var disco = await _discoveryCache.GetAsync();\n        if (disco.IsError) throw new Exception(disco.Error);\n\n        var rt = await HttpContext.GetTokenAsync(\"refresh_token\");\n        var tokenClient = _httpClientFactory.CreateClient();\n\n        var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = disco.TokenEndpoint,\n\n            ClientId = \"mvc.hybrid.backchannel\",\n            ClientSecret = \"secret\",\n            RefreshToken = rt\n        });\n\n        if (!tokenResult.IsError)\n        {\n            var old_id_token = await HttpContext.GetTokenAsync(\"id_token\");\n            var new_access_token = tokenResult.AccessToken;\n            var new_refresh_token = tokenResult.RefreshToken;\n            var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);\n\n            var info = await HttpContext.AuthenticateAsync(\"Cookies\");\n\n            info.Properties.UpdateTokenValue(\"refresh_token\", new_refresh_token);\n            info.Properties.UpdateTokenValue(\"access_token\", new_access_token);\n            info.Properties.UpdateTokenValue(\"expires_at\", expiresAt.ToString(\"o\", CultureInfo.InvariantCulture));\n\n            await HttpContext.SignInAsync(\"Cookies\", info.Principal, info.Properties);\n            return Redirect(\"~/Home/Secure\");\n        }\n\n        ViewData[\"Error\"] = tokenResult.Error;\n        return View(\"Error\");\n    }\n\n    public IActionResult Logout()\n    {\n        return new SignOutResult(new[] { \"Cookies\", \"oidc\" });\n    }\n\n    public IActionResult Error()\n    {\n        return View();\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Controllers/LogoutController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class LogoutController : Controller\n{\n    public LogoutSessionManager LogoutSessions { get; }\n\n    public LogoutController(LogoutSessionManager logoutSessions)\n    {\n        LogoutSessions = logoutSessions;\n    }\n\n    [HttpPost]\n    [AllowAnonymous]\n    public async Task<IActionResult> Index(string logout_token)\n    {\n        Response.Headers.Append(\"Cache-Control\", \"no-cache, no-store\");\n        Response.Headers.Append(\"Pragma\", \"no-cache\");\n\n        try\n        {\n            var user = await ValidateLogoutToken(logout_token);\n\n            // these are the sub & sid to signout\n            var sub = user.FindFirst(\"sub\")?.Value;\n            var sid = user.FindFirst(\"sid\")?.Value;\n\n            LogoutSessions.Add(sub, sid);\n\n            return Ok();\n        }\n        catch { }\n\n        return BadRequest();\n    }\n\n    private async Task<ClaimsPrincipal> ValidateLogoutToken(string logoutToken)\n    {\n        var claims = await ValidateJwt(logoutToken);\n\n        if (claims.FindFirst(\"sub\") == null && claims.FindFirst(\"sid\") == null) throw new Exception(\"Invalid logout token\");\n\n        var nonce = claims.FindFirstValue(\"nonce\");\n        if (!String.IsNullOrWhiteSpace(nonce)) throw new Exception(\"Invalid logout token\");\n\n        var eventsJson = claims.FindFirst(\"events\")?.Value;\n        if (String.IsNullOrWhiteSpace(eventsJson)) throw new Exception(\"Invalid logout token\");\n\n        var events =JsonSerializer.Deserialize<JsonElement>(eventsJson);\n        var logoutEvent = events.TryGetValue(\"http://schemas.openid.net/event/backchannel-logout\");\n        if (logoutEvent.ValueKind == JsonValueKind.Null) throw new Exception(\"Invalid logout token\");\n\n        return claims;\n    }\n\n    private static async Task<ClaimsPrincipal> ValidateJwt(string jwt)\n    {\n        // read discovery document to find issuer and key material\n        var client = new HttpClient();\n        var disco = await client.GetDiscoveryDocumentAsync(Constants.Authority);\n\n        var keys = new List<SecurityKey>();\n        foreach (var webKey in disco.KeySet.Keys)\n        {\n            var key = new JsonWebKey()\n            {\n                Kty = webKey.Kty,\n                Alg = webKey.Alg,\n                Kid = webKey.Kid,\n                X = webKey.X,\n                Y = webKey.Y,\n                Crv = webKey.Crv,\n                E = webKey.E,\n                N = webKey.N,\n            };\n            keys.Add(key);\n        }\n\n        var parameters = new TokenValidationParameters\n        {\n            ValidIssuer = disco.Issuer,\n            ValidAudience = \"mvc.hybrid.backchannel\",\n            IssuerSigningKeys = keys,\n\n            NameClaimType = JwtClaimTypes.Name,\n            RoleClaimType = JwtClaimTypes.Role\n        };\n\n        var handler = new JwtSecurityTokenHandler();\n        handler.InboundClaimTypeMap.Clear();\n\n        var user = handler.ValidateToken(jwt, parameters, out var _);\n        return user;\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/CookieEventHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class CookieEventHandler : CookieAuthenticationEvents\n{\n    public CookieEventHandler(LogoutSessionManager logoutSessions)\n    {\n        LogoutSessions = logoutSessions;\n    }\n\n    public LogoutSessionManager LogoutSessions { get; }\n\n    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)\n    {\n        if (context.Principal.Identity.IsAuthenticated)\n        {\n            var sub = context.Principal.FindFirst(\"sub\")?.Value;\n            var sid = context.Principal.FindFirst(\"sid\")?.Value;\n\n            if (LogoutSessions.IsLoggedOut(sub, sid))\n            {\n                context.RejectPrincipal();\n                await context.HttpContext.SignOutAsync();\n\n                // todo: if we have a refresh token, it should be revoked here.\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Clients;\nglobal using IdentityModel;\nglobal using IdentityModel.Client;\nglobal using Microsoft.AspNetCore;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authentication.Cookies;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using System.Globalization;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Security.Claims;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/LogoutSessionManager.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class LogoutSessionManager\n{\n    // yes - that needs to be thread-safe, distributed etc (it's a sample)\n    List<Session> _sessions = new List<Session>();\n\n    public void Add(string sub, string sid)\n    {\n        _sessions.Add(new Session { Sub = sub, Sid = sid }); \n    }\n\n    public bool IsLoggedOut(string sub, string sid)\n    {\n        var matches = _sessions.Any(s => s.IsMatch(sub, sid));\n        return matches;\n    }\n\n    private class Session\n    {\n        public string Sub { get; set; }\n        public string Sid { get; set; }\n\n        public bool IsMatch(string sub, string sid)\n        {\n            return (Sid == sid && Sub == sub) ||\n                   (Sid == sid && Sub == null) ||\n                   (Sid == null && Sub == sub);\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/MvcHybridBackChannel.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n\nvar builder= WebApplication.CreateBuilder(args);\n\nvar services = builder.Services;\n\nservices.AddControllersWithViews();\n\nservices\n.AddHttpClient()\n.AddSingleton<IDiscoveryCache>(r =>\n{\n    var factory = r.GetRequiredService<IHttpClientFactory>();\n    return new DiscoveryCache(Constants.Authority, () => factory.CreateClient());\n})\n.AddTransient<CookieEventHandler>()\n.AddSingleton<LogoutSessionManager>()\n.AddAuthentication(options =>\n{\n    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;\n    options.DefaultChallengeScheme = \"oidc\";\n})\n.AddCookie(options =>\n{\n    options.ExpireTimeSpan = TimeSpan.FromMinutes(60);\n    options.Cookie.Name = \"mvchybridbc\";\n\n    options.EventsType = typeof(CookieEventHandler);\n})\n.AddOpenIdConnect(\"oidc\", options =>\n{\n    options.Authority = Constants.Authority;\n    options.RequireHttpsMetadata = false;\n\n    options.ClientSecret = \"secret\";\n    options.ClientId = \"mvc.hybrid.backchannel\";\n\n    options.ResponseType = \"code id_token\";\n\n    options.Scope.Clear();\n    options.Scope.Add(\"openid\");\n    options.Scope.Add(\"profile\");\n    options.Scope.Add(\"email\");\n    options.Scope.Add(\"resource1.scope1\");\n    options.Scope.Add(\"offline_access\");\n\n    options.ClaimActions.MapAllExcept(\"iss\", \"nbf\", \"exp\", \"aud\", \"nonce\", \"iat\", \"c_hash\");\n\n    options.GetClaimsFromUserInfoEndpoint = true;\n    options.SaveTokens = true;\n\n    options.TokenValidationParameters = new TokenValidationParameters\n    {\n        NameClaimType = JwtClaimTypes.Name,\n        RoleClaimType = JwtClaimTypes.Role,\n    };\n});\n\n\n\nusing (var app = builder.Build())\n{\n    await app.RunAsync();\n}"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:44303\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Views/Home/CallApi.cshtml",
    "content": "﻿<h1>API Response</h1>\n\n<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Views/Home/Index.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Home Page\";\n}\n\n@if(User.Identity.IsAuthenticated)\n{\n    <h1>Logged in as: @User.Identity.Name</h1>\n}\nelse\n{\n    <h1>Not Logged In</h1>\n}"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Views/Home/Secure.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<div class=\"panel\">\n    <a class=\"btn btn-primary\" href=\"~/home/callapi\">Call API</a>\n    <a class=\"btn btn-primary\" href=\"~/home/renewtokens\">Renew Tokens</a>\n</div>\n\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Views/Shared/Error.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.\n</p>\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Views/Shared/_Layout.cshtml",
    "content": "﻿<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcHybrid</title>\n\n    <environment names=\"Development\">\n        <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.css\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n    </environment>\n    <environment names=\"Staging,Production\">\n        <link rel=\"stylesheet\" href=\"https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css\"\n              asp-fallback-href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\"\n              asp-fallback-test-class=\"sr-only\" asp-fallback-test-property=\"position\" asp-fallback-test-value=\"absolute\" />\n        <link rel=\"stylesheet\" href=\"~/css/site.min.css\" asp-append-version=\"true\" />\n    </environment>\n</head>\n<body>\n    <div class=\"navbar navbar-inverse navbar-fixed-top\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <button type=\"button\" class=\"navbar-toggle\" data-toggle=\"collapse\" data-target=\".navbar-collapse\">\n                    <span class=\"sr-only\">Toggle navigation</span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                    <span class=\"icon-bar\"></span>\n                </button>\n                <a asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\" class=\"navbar-brand\">MvcHybrid</a>\n            </div>\n            <div class=\"navbar-collapse collapse\">\n                <ul class=\"nav navbar-nav\">\n                    <li><a asp-controller=\"Home\" asp-action=\"Secure\">Secure</a></li>\n                    <li><a asp-controller=\"Home\" asp-action=\"Logout\">Logout</a></li>\n                </ul>\n            </div>\n        </div>\n    </div>\n    <div class=\"container body-content\">\n        @RenderBody()\n        <hr />\n        <footer>\n            <p>&copy; 2016 - MvcHybrid</p>\n        </footer>\n    </div>\n\n    <environment names=\"Development\">\n        <script src=\"~/lib/jquery/dist/jquery.js\"></script>\n        <script src=\"~/lib/bootstrap/dist/js/bootstrap.js\"></script>\n        <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    </environment>\n    <environment names=\"Staging,Production\">\n        <script src=\"https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js\"\n                asp-fallback-src=\"~/lib/jquery/dist/jquery.min.js\"\n                asp-fallback-test=\"window.jQuery\">\n        </script>\n        <script src=\"https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js\"\n                asp-fallback-src=\"~/lib/bootstrap/dist/js/bootstrap.min.js\"\n                asp-fallback-test=\"window.jQuery && window.jQuery.fn && window.jQuery.fn.modal\">\n        </script>\n        <script src=\"~/js/site.min.js\" asp-append-version=\"true\"></script>\n    </environment>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/wwwroot/_references.js",
    "content": "﻿/// <autosync enabled=\"true\" />\n/// <reference path=\"js/site.js\" />\n/// <reference path=\"lib/bootstrap/dist/js/bootstrap.js\" />\n/// <reference path=\"lib/jquery/dist/jquery.js\" />\n/// <reference path=\"lib/jquery-validation/dist/jquery.validate.js\" />\n/// <reference path=\"lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js\" />\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/wwwroot/css/site.css",
    "content": "﻿body {\n    padding-top: 50px;\n    padding-bottom: 20px;\n}\n\n/* Wrapping element */\n/* Set some basic padding to keep content from hitting the edges */\n.body-content {\n    padding-left: 15px;\n    padding-right: 15px;\n}\n\n/* Set widths on the form inputs since otherwise they're 100% wide */\ninput,\nselect,\ntextarea {\n    max-width: 280px;\n}\n\n/* Carousel */\n.carousel-caption p {\n    font-size: 20px;\n    line-height: 1.4;\n}\n\n/* Make .svg files in the carousel display properly in older browsers */\n.carousel-inner .item img[src$=\".svg\"]\n{\n    width: 100%;\n}\n\n/* Hide/rearrange for smaller screens */\n@media screen and (max-width: 767px) {\n  /* Hide captions */\n  .carousel-caption {\n    display: none\n  }\n}\n"
  },
  {
    "path": "samples/Clients/src/MvcHybridBackChannel/wwwroot/js/site.js",
    "content": "﻿// Write your Javascript code.\n"
  },
  {
    "path": "samples/Clients/src/WindowsConsoleSystemBrowser/CallbackManager.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO.Pipes;\n\nclass CallbackManager\n{\n    private readonly string _name;\n\n    public CallbackManager(string name)\n    {\n        _name = name ?? throw new ArgumentNullException(nameof(name));\n    }\n\n    public int ClientConnectTimeoutSeconds { get; set; } = 1;\n\n    public async Task RunClient(string args)\n    {\n        using (var client = new NamedPipeClientStream(\".\", _name, PipeDirection.Out))\n        {\n            await client.ConnectAsync(ClientConnectTimeoutSeconds * 1000);\n\n            using (var sw = new StreamWriter(client) { AutoFlush = true })\n            {\n                await sw.WriteAsync(args);\n            }\n        }\n    }\n\n    public async Task<string> RunServer(CancellationToken? token = null)\n    {\n        token = CancellationToken.None;\n\n        using (var server = new NamedPipeServerStream(_name, PipeDirection.In))\n        {\n            await server.WaitForConnectionAsync(token.Value);\n\n            using (var sr = new StreamReader(server))\n            {\n                var msg = await sr.ReadToEndAsync();\n                return msg;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/WindowsConsoleSystemBrowser/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Logging;\n\nIdentityModelEventSource.ShowPII = true;\n\nif (args.Any())\n{\n    await ProcessCallback(args[0]);\n}\nelse\n{\n    await Run();\n}\n\nasync Task ProcessCallback(string args)\n{\n    var response = new AuthorizeResponse(args);\n    if (!String.IsNullOrWhiteSpace(response.State))\n    {\n        Console.WriteLine($\"Found state: {response.State}\");\n        var callbackManager = new CallbackManager(response.State);\n        await callbackManager.RunClient(args);\n    }\n    else\n    {\n        Console.WriteLine(\"Error: no state on response\");\n    }\n}\n\nconst string CustomUriScheme = \"sample-windows-client\";\n\n[SupportedOSPlatform(\"windows\")]\nasync Task Run()\n{\n    new RegistryConfig(CustomUriScheme).Configure();\n\n    Console.WriteLine(\"+-----------------------+\");\n    Console.WriteLine(\"|  Sign in with OIDC    |\");\n    Console.WriteLine(\"+-----------------------+\");\n    Console.WriteLine(\"\");\n    Console.WriteLine(\"Press any key to sign in...\");\n    Console.ReadKey();\n\n    await SignIn();\n\n    Console.ReadKey();\n}\n\nasync Task SignIn()\n{\n    // create a redirect URI using the custom redirect uri\n    string redirectUri = string.Format(CustomUriScheme + \"://callback\");\n    Console.WriteLine(\"redirect URI: \" + redirectUri);\n\n    var options = new OidcClientOptions\n    {\n        Authority = Constants.Authority,\n        ClientId = \"winconsole\",\n        Scope = \"openid profile scope1\",\n        RedirectUri = redirectUri,\n    };\n\n    var serilog = new LoggerConfiguration()\n          .MinimumLevel.Verbose()\n          .Enrich.FromLogContext()\n          .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}{Exception}{NewLine}\")\n          .CreateLogger();\n\n    options.LoggerFactory.AddSerilog(serilog);\n\n    var client = new OidcClient(options);\n    var state = await client.PrepareLoginAsync();\n\n    Console.WriteLine($\"Start URL: {state.StartUrl}\");\n\n    var callbackManager = new CallbackManager(state.State);\n\n    // open system browser to start authentication\n    Process.Start(state.StartUrl);\n\n    Console.WriteLine(\"Running callback manager\");\n    var response = await callbackManager.RunServer();\n\n    Console.WriteLine($\"Response from authorize endpoint: {response}\");\n\n    // Brings the Console to Focus.\n    BringConsoleToFront();\n\n    var result = await client.ProcessResponseAsync(response, state);\n\n    BringConsoleToFront();\n\n    if (result.IsError)\n    {\n        Console.WriteLine(\"\\n\\nError:\\n{0}\", result.Error);\n    }\n    else\n    {\n        Console.WriteLine(\"\\n\\nClaims:\");\n        foreach (var claim in result.User.Claims)\n        {\n            Console.WriteLine(\"{0}: {1}\", claim.Type, claim.Value);\n        }\n\n        Console.WriteLine();\n\n        if (!string.IsNullOrEmpty(result.IdentityToken))\n        {\n            Console.WriteLine(\"Identity token:\\n{0}\", result.IdentityToken);\n        }\n\n        if (!string.IsNullOrEmpty(result.AccessToken))\n        {\n            Console.WriteLine(\"Access token:\\n{0}\", result.AccessToken);\n        }\n\n        if (!string.IsNullOrWhiteSpace(result.RefreshToken))\n        {\n            Console.WriteLine(\"Refresh token:\\n{0}\", result.RefreshToken);\n        }\n    }\n}\n\n// Hack to bring the Console window to front.\n// ref: http://stackoverflow.com/a/12066376\n[DllImport(\"kernel32.dll\", ExactSpelling = true)]\nstatic extern IntPtr GetConsoleWindow();\n\n[DllImport(\"user32.dll\")]\n[return: MarshalAs(UnmanagedType.Bool)]\nstatic extern bool SetForegroundWindow(IntPtr hWnd);\n\nvoid BringConsoleToFront()\n{\n    SetForegroundWindow(GetConsoleWindow());\n}\n\nstatic string GetRequestPostData(HttpListenerRequest request)\n{\n    if (!request.HasEntityBody)\n    {\n        return null;\n    }\n\n    using (var body = request.InputStream)\n    {\n        using (var reader = new System.IO.StreamReader(body, request.ContentEncoding))\n        {\n            return reader.ReadToEnd();\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/WindowsConsoleSystemBrowser/RegistryConfig.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.Win32;\nusing System.Reflection;\n\nclass RegistryConfig\n{\n    public RegistryConfig(string uriScheme)\n    {\n        CustomUriScheme = uriScheme;\n    }\n\n\n    [SupportedOSPlatform(\"windows\")]\n    public void Configure()\n    {\n        if (NeedToAddKeys()) AddRegKeys();\n    }\n\n    string CustomUriScheme { get; }\n\n    string CustomUriSchemeKeyPath => RootKeyPath + @\"\\\" + CustomUriScheme;\n    string CustomUriSchemeKeyValueValue => \"URL:\" + CustomUriScheme;\n    string CommandKeyPath => CustomUriSchemeKeyPath + @\"\\shell\\open\\command\";\n\n    const string RootKeyPath = @\"Software\\Classes\";\n\n    const string CustomUriSchemeKeyValueName = \"\";\n\n    const string ShellKeyName = \"shell\";\n    const string OpenKeyName = \"open\";\n    const string CommandKeyName = \"command\";\n\n    const string CommandKeyValueName = \"\";\n    const string CommandKeyValueFormat = \"\\\"{0}\\\" \\\"%1\\\"\";\n    static string CommandKeyValueValue => String.Format(CommandKeyValueFormat, Assembly.GetExecutingAssembly().Location);\n\n    const string UrlProtocolValueName = \"URL Protocol\";\n    const string UrlProtocolValueValue = \"\";\n\n    [SupportedOSPlatform(\"windows\")]\n    bool NeedToAddKeys()\n    {\n        var addKeys = false;\n\n        using (var commandKey = Registry.CurrentUser.OpenSubKey(CommandKeyPath))\n        {\n            var commandValue = commandKey?.GetValue(CommandKeyValueName);\n            addKeys |= !CommandKeyValueValue.Equals(commandValue);\n        }\n\n        using (var customUriSchemeKey = Registry.CurrentUser.OpenSubKey(CustomUriSchemeKeyPath))\n        {\n            var uriValue = customUriSchemeKey?.GetValue(CustomUriSchemeKeyValueName);\n            var protocolValue = customUriSchemeKey?.GetValue(UrlProtocolValueName);\n\n            addKeys |= !CustomUriSchemeKeyValueValue.Equals(uriValue);\n            addKeys |= !UrlProtocolValueValue.Equals(protocolValue);\n        }\n\n        return addKeys;\n    }\n\n    [SupportedOSPlatform(\"windows\")]\n    void AddRegKeys()\n    {\n        using (var classesKey = Registry.CurrentUser.OpenSubKey(RootKeyPath, true))\n        {\n            using (var root = classesKey.OpenSubKey(CustomUriScheme, true) ??\n                classesKey.CreateSubKey(CustomUriScheme, true))\n            {\n                root.SetValue(CustomUriSchemeKeyValueName, CustomUriSchemeKeyValueValue);\n                root.SetValue(UrlProtocolValueName, UrlProtocolValueValue);\n\n                using (var shell = root.OpenSubKey(ShellKeyName, true) ??\n                        root.CreateSubKey(ShellKeyName, true))\n                {\n                    using (var open = shell.OpenSubKey(OpenKeyName, true) ??\n                            shell.CreateSubKey(OpenKeyName, true))\n                    {\n                        using (var command = open.OpenSubKey(CommandKeyName, true) ??\n                                open.CreateSubKey(CommandKeyName, true))\n                        {\n                            command.SetValue(CommandKeyValueName, CommandKeyValueValue);\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Clients/src/WindowsConsoleSystemBrowser/WindowsConsoleSystemBrowser.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n    <PropertyGroup>\n        <OutputType>Exe</OutputType>\n    </PropertyGroup>\n</Project>"
  },
  {
    "path": "samples/Directory.Build.props",
    "content": "<Project>\n  <PropertyGroup>\n\t<IdentityServerVersion>8.0.4-alpha.2</IdentityServerVersion>\n  </PropertyGroup>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n  <ItemGroup>  \n\t<None Remove=\"$(SolutionDir)../icon.jpg\"/>\n\t<None Remove=\"$(SolutionDir)../LICENSE\" />\n\t<None Remove=\"$(SolutionDir)../README.md\" />\n  </ItemGroup>\n  <PropertyGroup>\n\t<SignAssembly>false</SignAssembly>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageVersion Include=\"HigginsSoft.IdentityServer8\" Version=\"$(IdentityServerVersion)\" />\n\t<PackageVersion Include=\"HigginsSoft.IdentityServer8.Security\" Version=\"$(IdentityServerVersion)\" />\n\t<PackageVersion Include=\"HigginsSoft.IdentityServer8.AspNetIdentity\" Version=\"$(IdentityServerVersion)\" />\n    <PackageVersion Include=\"HigginsSoft.IdentityServer8.EntityFramework\" Version=\"$(IdentityServerVersion)\" />\n  </ItemGroup> \n  <ItemGroup>\n    <PackageReference Include=\"IdentityModel.OidcClient\" />\n    <PackageReference Include=\"IdentityModel.AspNetCore\" />\n    <PackageReference Include=\"IdentityModel.AspNetCore.AccessTokenValidation\" />\n    <PackageReference Include=\"IdentityModel.AspNetCore.OAuth2Introspection\"  />\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.JwtBearer\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.OpenIdConnect\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Server.Kestrel\" />\n    <PackageReference Include=\"Microsoft.IdentityModel.Protocols.OpenIdConnect\" />\n\t<PackageReference Include=\"Microsoft.Extensions.DependencyInjection\" />\n    <PackageReference Include=\"SeriLog\" />\n    <PackageReference Include=\"Serilog.AspNetCore\" />\n    <PackageReference Include=\"Serilog.Extensions.Logging\" />\n    <PackageReference Include=\"Serilog.Sinks.Console\" />\n    <PackageReference Include=\"System.IdentityModel.Tokens.Jwt\" />\n    <Compile Include=\"$(SolutionDir)..\\..\\SamplesGlobalUsings.cs\" Link=\"SamplesGlobalUsings.cs\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/KeyManagement/Directory.Build.props",
    "content": "<Project>\n    <ImportGroup>\n        <Import Project=\"../Directory.Build.props\" />\n    </ImportGroup>\n  <ItemGroup>\n    <PackageReference Include=\"IdentityServer4.KeyManagement\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" >\n\t   <PrivateAssets>all</PrivateAssets>\n\t   <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <Compile Include=\"$(SolutionDir)..\\KeyManagementGlobalUsings.cs\" Link=\"KeyManagementGlobalUsings\" />\n  </ItemGroup>\t\n</Project>"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/Directory.Build.props",
    "content": "<Project>\n    <ImportGroup>\n        <Import Project=\"../Directory.Build.props\" />\n    </ImportGroup>\n</Project>"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/FileSystem/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> GetIdentityResources()\n    {\n        return new IdentityResource[]\n        {\n            new IdentityResources.OpenId()\n        };\n    }\n\n    public static IEnumerable<ApiResource> GetApis()\n    {\n        return new ApiResource[] { };\n    }\n\n    public static IEnumerable<Client> GetClients()\n    {\n        return new Client[] { };\n    }\n}\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/FileSystem/FileSystemSample.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <Folder Include=\"dataprotectionkeys\\\" />\n    <Folder Include=\"signingkeys\\\" />\n  </ItemGroup>\n \n</Project>\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/FileSystem/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConsole.Title = \"IdentityServer8\";\n\nvar app = CreateWebHostBuilder(args);\nawait app.RunAsync();\n\n\nWebApplication CreateWebHostBuilder(string[] args)\n{\n    var builder = WebApplication.CreateBuilder(args);\n    builder.Host.UseSerilog((context, configuration) =>\n    {\n        configuration\n            .MinimumLevel.Debug()\n            .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n            .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n            .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n            .Enrich.FromLogContext()\n            .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Literate);\n    });\n\n    var services = builder.Services;\n    var name = \"CN=test.dataprotection\";\n    var cert = X509.LocalMachine.My.SubjectDistinguishedName.Find(name, false).FirstOrDefault();\n\n    var Environment = builder.Environment;\n    services.AddDataProtection()\n        .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Environment.ContentRootPath, \"dataprotectionkeys\")));\n    //.ProtectKeysWithCertificate(cert);\n\n    services.AddIdentityServer()\n       .AddInMemoryIdentityResources(Config.GetIdentityResources())\n       .AddInMemoryApiResources(Config.GetApis())\n       .AddInMemoryClients(Config.GetClients())\n       .AddSigningKeyManagement(\n           options => // configuring options is optional :)\n           {\n               options.DeleteRetiredKeys = true;\n               options.KeyType = IdentityServer4.KeyManagement.KeyType.RSA;\n\n               // all of these values in here are changed for local testing\n               options.InitializationDuration = TimeSpan.FromSeconds(5);\n               options.InitializationSynchronizationDelay = TimeSpan.FromSeconds(1);\n\n               options.KeyActivationDelay = TimeSpan.FromSeconds(10);\n               options.KeyExpiration = options.KeyActivationDelay * 2;\n               options.KeyRetirement = options.KeyActivationDelay * 3;\n\n               // You can get your own license from:\n               // https://www.identityserver8.com/products/KeyManagement\n               options.Licensee = \"your licensee\";\n               options.License = \"your license key\";\n           })\n           //.EnableInMemoryCaching()\n           .PersistKeysToFileSystem(Path.Combine(Environment.ContentRootPath, @\"signingkeys\"))\n           .ProtectKeysWithDataProtection();\n\n    // .PersistKeysWith<TYourStore>() // use this when you implement your own ISigningKeyStore\n    //.EnableInMemoryCaching() // caching disabled unless explicitly enabled\n    // run \"..\\cert\\cert.ps1\" from a powershell prompt to create new cert/pfx\n    // put the pfx created in the local machine store\n    //.ProtectKeysWithX509Certificate(\"CN=SigningKeysMasterKey\")\n    ;\n\n\n    var app = builder.Build();\n\n    if (Environment.IsDevelopment())\n    {\n        app.UseDeveloperExceptionPage();\n    }\n\n    app.UseIdentityServer();\n\n    return app;\n\n\n\n}\n\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/FileSystem/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:5000\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"http://localhost:5000/.well-known/openid-configuration/jwks\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:5000\"\n    }\n  }\n}"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/FileSystem/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\npublic class Startup\n{\n    public IWebHostEnvironment Environment { get; }\n\n    public Startup(IConfiguration config, IWebHostEnvironment environment)\n    {\n        Environment = environment;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var name = \"CN=test.dataprotection\";\n        var cert = X509.LocalMachine.My.SubjectDistinguishedName.Find(name, false).FirstOrDefault();\n\n        services.AddDataProtection()\n            .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Environment.ContentRootPath, \"dataprotectionkeys\")));\n            //.ProtectKeysWithCertificate(cert);\n\n        var builder = services.AddIdentityServer()\n            .AddInMemoryIdentityResources(Config.GetIdentityResources())\n            .AddInMemoryApiResources(Config.GetApis())\n            .AddInMemoryClients(Config.GetClients())\n            .AddSigningKeyManagement(\n                options => // configuring options is optional :)\n                {\n                    options.DeleteRetiredKeys = true;\n                    options.KeyType = IdentityServer4.KeyManagement.KeyType.RSA;\n\n                    // all of these values in here are changed for local testing\n                    options.InitializationDuration = TimeSpan.FromSeconds(5);\n                    options.InitializationSynchronizationDelay = TimeSpan.FromSeconds(1);\n\n                    options.KeyActivationDelay = TimeSpan.FromSeconds(10);\n                    options.KeyExpiration = options.KeyActivationDelay * 2;\n                    options.KeyRetirement = options.KeyActivationDelay * 3;\n\n                    // You can get your own license from:\n                    // https://www.identityserver8.com/products/KeyManagement\n                    options.Licensee = \"your licensee\";\n                    options.License = \"your license key\";\n                })\n                //.EnableInMemoryCaching()\n                .PersistKeysToFileSystem(Path.Combine(Environment.ContentRootPath, @\"signingkeys\"))\n                .ProtectKeysWithDataProtection();\n\n                // .PersistKeysWith<TYourStore>() // use this when you implement your own ISigningKeyStore\n                //.EnableInMemoryCaching() // caching disabled unless explicitly enabled\n                // run \"..\\cert\\cert.ps1\" from a powershell prompt to create new cert/pfx\n                // put the pfx created in the local machine store\n                //.ProtectKeysWithX509Certificate(\"CN=SigningKeysMasterKey\")\n            ;\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        if (Environment.IsDevelopment())\n        {\n            app.UseDeveloperExceptionPage();\n        }\n\n        app.UseIdentityServer();\n    }\n}\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/FileSystem/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"db\": \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.KeyManagement;trusted_connection=yes;\"\n  }\n}"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/KeyManagement.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"filesystem\", \"filesystem\", \"{66069BF5-F9C7-446A-8AD6-C4FA556F99CD}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"database\", \"database\", \"{5460F146-2FAA-4D3B-B3FF-6E0222824293}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"FileSystemSample\", \"FileSystem\\FileSystemSample.csproj\", \"{59A7BDFE-02E5-4FA5-9B7F-A5888C8CACCB}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"EfSample\", \"database\\EF\\EfSample.csproj\", \"{7B9531E7-47A4-4C36-95B9-ADAA4FADF732}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"migrations\", \"database\\migrations\\migrations.csproj\", \"{1979B108-6006-4CFC-81F1-6397659580AB}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Files\", \"Solution Files\", \"{0287EA18-2EE5-4878-A2D7-B8FBA31DCE44}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tDirectory.Build.props = Directory.Build.props\n\t\tKeyManagement.sln.licenseheader = KeyManagement.sln.licenseheader\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{59A7BDFE-02E5-4FA5-9B7F-A5888C8CACCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{59A7BDFE-02E5-4FA5-9B7F-A5888C8CACCB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{59A7BDFE-02E5-4FA5-9B7F-A5888C8CACCB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{59A7BDFE-02E5-4FA5-9B7F-A5888C8CACCB}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{7B9531E7-47A4-4C36-95B9-ADAA4FADF732}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{7B9531E7-47A4-4C36-95B9-ADAA4FADF732}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{7B9531E7-47A4-4C36-95B9-ADAA4FADF732}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{7B9531E7-47A4-4C36-95B9-ADAA4FADF732}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{1979B108-6006-4CFC-81F1-6397659580AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{1979B108-6006-4CFC-81F1-6397659580AB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{1979B108-6006-4CFC-81F1-6397659580AB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{1979B108-6006-4CFC-81F1-6397659580AB}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{59A7BDFE-02E5-4FA5-9B7F-A5888C8CACCB} = {66069BF5-F9C7-446A-8AD6-C4FA556F99CD}\n\t\t{7B9531E7-47A4-4C36-95B9-ADAA4FADF732} = {5460F146-2FAA-4D3B-B3FF-6E0222824293}\n\t\t{1979B108-6006-4CFC-81F1-6397659580AB} = {5460F146-2FAA-4D3B-B3FF-6E0222824293}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {34FB2185-9C34-4130-ADA6-2AF52DFBF5DA}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/KeyManagement.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/EF/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> GetIdentityResources()\n    {\n        return new IdentityResource[]\n        {\n                new IdentityResources.OpenId()\n        };\n    }\n\n    public static IEnumerable<ApiResource> GetApis()\n    {\n        return new ApiResource[] { };\n    }\n\n    public static IEnumerable<Client> GetClients()\n    {\n        return new Client[] { };\n    }\n}\n\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/EF/EfSample.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n</Project>\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/EF/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConsole.Title = \"IdentityServer8\";\n\nvar builder = WebApplication.CreateBuilder(args);\nbuilder.Host.UseSerilog((context, configuration) =>\n{\n    configuration\n        .MinimumLevel.Debug()\n        .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n        .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n        .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n        .Enrich.FromLogContext()\n        .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Literate);\n});\nvar services = builder.Services;\n\n//var name = \"CN=test.dataprotection\";\n//var cert = X509.LocalMachine.My.SubjectDistinguishedName.Find(name, false).FirstOrDefault();\n\nvar cn = builder.Configuration.GetConnectionString(\"db\");\nvar Environment = builder.Environment;\nservices.AddDataProtection()\n    .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Environment.ContentRootPath, \"dataprotectionkeys\")));\n//.PersistKeysToDatabase(new DatabaseKeyManagementOptions\n//{\n//    ConfigureDbContext = b => b.UseSqlServer(cn),\n//    LoggerFactory = LoggerFactory,\n//});\n//.ProtectKeysWithCertificate(cert);\n\nservices.AddIdentityServer()\n     .AddInMemoryIdentityResources(Config.GetIdentityResources())\n     .AddInMemoryApiResources(Config.GetApis())\n     .AddInMemoryClients(Config.GetClients())\n     .AddSigningKeyManagement(\n         options => // configuring options is optional :)\n         {\n             options.DeleteRetiredKeys = true;\n             options.KeyType = IdentityServer4.KeyManagement.KeyType.RSA;\n\n             // all of these values in here are changed for local testing\n             options.InitializationDuration = TimeSpan.FromSeconds(5);\n             options.InitializationSynchronizationDelay = TimeSpan.FromSeconds(1);\n\n             options.KeyActivationDelay = TimeSpan.FromSeconds(10);\n             options.KeyExpiration = options.KeyActivationDelay * 2;\n             options.KeyRetirement = options.KeyActivationDelay * 3;\n\n             // You can get your own license from:\n             // https://www.identityserver8.com/products/KeyManagement\n             options.Licensee = \"your licensee\";\n             options.License = \"your license key\";\n         })\n         .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Environment.ContentRootPath, \"signingkeys\")).FullName)\n         //.PersistKeysToDatabase(new DatabaseKeyManagementOptions {\n         //    ConfigureDbContext = b => b.UseSqlServer(cn),\n         //})\n         .ProtectKeysWithDataProtection()\n     //.EnableInMemoryCaching() // caching disabled unless explicitly enabled\n     ;\nvar app = builder.Build();\n\nif (Environment.IsDevelopment())\n{\n    app.UseDeveloperExceptionPage();\n}\n\napp.UseIdentityServer();\n\nawait app.RunAsync();\n\n\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/EF/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:5000\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"http://localhost:5000/.well-known/openid-configuration/jwks\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:5000\"\n    }\n  }\n}"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/EF/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n\npublic class Startup\n{\n    public IConfiguration Configuration { get; }\n    public IWebHostEnvironment Environment { get; }\n    public ILoggerFactory LoggerFactory { get; set; }\n\n    public Startup(IConfiguration config, IWebHostEnvironment environment, ILoggerFactory loggerFactory)\n    {\n        Configuration = config;\n        Environment = environment;\n        LoggerFactory = loggerFactory;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        //var name = \"CN=test.dataprotection\";\n        //var cert = X509.LocalMachine.My.SubjectDistinguishedName.Find(name, false).FirstOrDefault();\n\n        var cn = Configuration.GetConnectionString(\"db\");\n\n        services.AddDataProtection()\n            .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Environment.ContentRootPath, \"dataprotectionkeys\")));\n        //.PersistKeysToDatabase(new DatabaseKeyManagementOptions\n        //{\n        //    ConfigureDbContext = b => b.UseSqlServer(cn),\n        //    LoggerFactory = LoggerFactory,\n        //});\n        //.ProtectKeysWithCertificate(cert);\n\n        var builder = services.AddIdentityServer()\n            .AddInMemoryIdentityResources(Config.GetIdentityResources())\n            .AddInMemoryApiResources(Config.GetApis())\n            .AddInMemoryClients(Config.GetClients())\n            .AddSigningKeyManagement(\n                options => // configuring options is optional :)\n                {\n                    options.DeleteRetiredKeys = true;\n                    options.KeyType = IdentityServer4.KeyManagement.KeyType.RSA;\n\n                    // all of these values in here are changed for local testing\n                    options.InitializationDuration = TimeSpan.FromSeconds(5);\n                    options.InitializationSynchronizationDelay = TimeSpan.FromSeconds(1);\n\n                    options.KeyActivationDelay = TimeSpan.FromSeconds(10);\n                    options.KeyExpiration = options.KeyActivationDelay * 2;\n                    options.KeyRetirement = options.KeyActivationDelay * 3;\n\n                    // You can get your own license from:\n                    // https://www.identityserver8.com/products/KeyManagement\n                    options.Licensee = \"your licensee\";\n                    options.License = \"your license key\";\n                })\n                .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Environment.ContentRootPath, \"signingkeys\")).FullName)\n                //.PersistKeysToDatabase(new DatabaseKeyManagementOptions {\n                //    ConfigureDbContext = b => b.UseSqlServer(cn),\n                //})\n                .ProtectKeysWithDataProtection()\n            //.EnableInMemoryCaching() // caching disabled unless explicitly enabled\n            ;\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        if (Environment.IsDevelopment())\n        {\n            app.UseDeveloperExceptionPage();\n        }\n\n        app.UseIdentityServer();\n    }\n}\n\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/EF/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"db\": \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.KeyManagement;trusted_connection=yes;\"\n  }\n}"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/Migrations/KeyManagement/20200327143521_KeyManagement.Designer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\n//[DbContext(typeof(KeyManagementDbContext))]\n[Migration(\"20200327143521_KeyManagement\")]\npartial class KeyManagement\n{\n    protected override void BuildTargetModel(ModelBuilder modelBuilder)\n    {\n#pragma warning disable 612, 618\n        modelBuilder\n            .HasAnnotation(\"ProductVersion\", \"3.1.3\")\n            .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n            .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n        modelBuilder.Entity(\"IdentityServer8.KeyManagement.EntityFramework.DataProtectionKey\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Name\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"Name\")\n                    .IsUnique()\n                    .HasFilter(\"[Name] IS NOT NULL\");\n\n                b.ToTable(\"DataProtectionKeys\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.KeyManagement.EntityFramework.SigningKey\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Name\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"Name\")\n                    .IsUnique()\n                    .HasFilter(\"[Name] IS NOT NULL\");\n\n                b.ToTable(\"SigningKeys\");\n            });\n#pragma warning restore 612, 618\n    }\n}\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/Migrations/KeyManagement/20200327143521_KeyManagement.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic partial class KeyManagement : Migration\n{\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.CreateTable(\n            name: \"DataProtectionKeys\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Created = table.Column<DateTime>(nullable: false),\n                Name = table.Column<string>(maxLength: 200, nullable: true),\n                Value = table.Column<string>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_DataProtectionKeys\", x => x.Id);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"SigningKeys\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Created = table.Column<DateTime>(nullable: false),\n                Name = table.Column<string>(maxLength: 200, nullable: true),\n                Value = table.Column<string>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_SigningKeys\", x => x.Id);\n            });\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_DataProtectionKeys_Name\",\n            table: \"DataProtectionKeys\",\n            column: \"Name\",\n            unique: true,\n            filter: \"[Name] IS NOT NULL\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_SigningKeys_Name\",\n            table: \"SigningKeys\",\n            column: \"Name\",\n            unique: true,\n            filter: \"[Name] IS NOT NULL\");\n    }\n\n    protected override void Down(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.DropTable(\n            name: \"DataProtectionKeys\");\n\n        migrationBuilder.DropTable(\n            name: \"SigningKeys\");\n    }\n}\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/Migrations/KeyManagement/KeyManagementDbContextModelSnapshot.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\n// [DbContext(typeof(KeyManagementDbContext))]\npartial class KeyManagementDbContextModelSnapshot : ModelSnapshot\n{\n    protected override void BuildModel(ModelBuilder modelBuilder)\n    {\n#pragma warning disable 612, 618\n        modelBuilder\n            .HasAnnotation(\"ProductVersion\", \"3.1.3\")\n            .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n            .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n        modelBuilder.Entity(\"IdentityServer8.KeyManagement.EntityFramework.DataProtectionKey\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Name\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"Name\")\n                    .IsUnique()\n                    .HasFilter(\"[Name] IS NOT NULL\");\n\n                b.ToTable(\"DataProtectionKeys\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.KeyManagement.EntityFramework.SigningKey\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Name\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"Name\")\n                    .IsUnique()\n                    .HasFilter(\"[Name] IS NOT NULL\");\n\n                b.ToTable(\"SigningKeys\");\n            });\n#pragma warning restore 612, 618\n    }\n}\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/Migrations/KeyManagement.sql",
    "content": "﻿IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL\nBEGIN\n    CREATE TABLE [__EFMigrationsHistory] (\n        [MigrationId] nvarchar(150) NOT NULL,\n        [ProductVersion] nvarchar(32) NOT NULL,\n        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])\n    );\nEND;\n\nGO\n\nCREATE TABLE [DataProtectionKeys] (\n    [Id] int NOT NULL IDENTITY,\n    [Created] datetime2 NOT NULL,\n    [Name] nvarchar(200) NULL,\n    [Value] nvarchar(max) NOT NULL,\n    CONSTRAINT [PK_DataProtectionKeys] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE TABLE [SigningKeys] (\n    [Id] int NOT NULL IDENTITY,\n    [Created] datetime2 NOT NULL,\n    [Name] nvarchar(200) NULL,\n    [Value] nvarchar(max) NOT NULL,\n    CONSTRAINT [PK_SigningKeys] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE UNIQUE INDEX [IX_DataProtectionKeys_Name] ON [DataProtectionKeys] ([Name]) WHERE [Name] IS NOT NULL;\n\nGO\n\nCREATE UNIQUE INDEX [IX_SigningKeys_Name] ON [SigningKeys] ([Name]) WHERE [Name] IS NOT NULL;\n\nGO\n\nINSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])\nVALUES (N'20200327143521_KeyManagement', N'3.1.3');\n\nGO\n\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nIWebHostBuilder CreateWebHostBuilder(string[] args) =>\n    WebHost.CreateDefaultBuilder(args)\n        .UseStartup<Startup>();\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/Properties/launchSettings.json",
    "content": "﻿{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false, \n    \"anonymousAuthentication\": true, \n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:60249\",\n      \"sslPort\": 44348\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"migrations\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"applicationUrl\": \"https://localhost:5001;http://localhost:5000\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class Startup\n{\n    public IConfiguration Configuration { get; }\n\n    public Startup(IConfiguration config)\n    {\n        Configuration = config;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var cn = Configuration.GetConnectionString(\"db\");\n\n        //services.AddKeyManagementDbContext(new DatabaseKeyManagementOptions {\n        //    ConfigureDbContext = b =>\n        //         b.UseSqlServer(cn, dbOpts => dbOpts.MigrationsAssembly(typeof(Startup).Assembly.FullName))\n        //});\n    }\n\n    public void Configure(IApplicationBuilder app, IHostingEnvironment env)\n    {\n    }\n}\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"db\": \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.KeyManagement;trusted_connection=yes;\"\n  }\n}"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/builddb.bat",
    "content": "dotnet ef database drop -c KeyManagementDbContext\n\nrmdir /S /Q Migrations\n\ndotnet ef migrations add KeyManagement -c KeyManagementDbContext -o Migrations/KeyManagement\ndotnet ef migrations script -c KeyManagementDbContext -o Migrations/KeyManagement.sql\ndotnet ef database update -c KeyManagementDbContext\n"
  },
  {
    "path": "samples/KeyManagement/FileSystemKeys/database/migrations/migrations.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\" />\n"
  },
  {
    "path": "samples/KeyManagement/KeyManagementGlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityServer4.Models;\nglobal using Microsoft.AspNetCore;\nglobal using IHostingEnvironment = Microsoft.Extensions.Hosting.IHostingEnvironment;\nglobal using Microsoft.EntityFrameworkCore.Migrations;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.EntityFrameworkCore.Infrastructure;\nglobal using Microsoft.EntityFrameworkCore.Metadata;\n"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/Quickstart.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{BD8BA25C-A91D-419D-99B6-B575ADD6D061}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer\", \"src\\IdentityServer\\IdentityServer.csproj\", \"{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Api\", \"..\\Shared\\src\\Api\\Api.csproj\", \"{085FFBFE-436E-4622-A4E0-4828CC357F9B}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Client\", \"..\\Shared\\src\\Client\\Client.csproj\", \"{E6DBD7EC-D769-4226-A58C-17121F6E144B}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Release|x64.Build.0 = Release|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{085FFBFE-436E-4622-A4E0-4828CC357F9B}.Release|x86.Build.0 = Release|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Release|x64.Build.0 = Release|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{E6DBD7EC-D769-4226-A58C-17121F6E144B}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {84D5AF06-1243-46F1-9D58-70ED572832C3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/Quickstart.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/src/IdentityServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityServer8.Models;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\n"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/src/IdentityServer/IdentityServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"HigginsSoft.IdentityServer8\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/src/IdentityServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Secret = IdentityServer8.Models.Secret;\n\nConfigureLogger();\n\ntry\n{\n    Log.Information(\"Starting host...\");\n\n    var builder = WebApplication.CreateBuilder(args);\n\n    var services = builder.Services;\n\n    // uncomment, if you want to add an MVC-based UI\n    //services.AddControllersWithViews();\n\n    services\n        .AddIdentityServer()\n        .AddInMemoryApiScopes(new ApiScope[] { new(\"api1\", \"My API\") })\n        .AddDeveloperSigningCredential()\n        .AddInMemoryClients(new Client[] { new()\n            {\n                    ClientId = \"client\",\n\n                    // no interactive user, use the clientid/secret for authentication\n                    AllowedGrantTypes = GrantTypes.ClientCredentials,\n\n                    // secret for authentication\n                    ClientSecrets = new Secret[] {new (\"secret\".Sha256()) },\n\n                    // scopes that client has access to\n                    AllowedScopes = { \"api1\" }\n            }\n        });\n\n\n    using (var app = builder.Build())\n    {\n        if (app.Environment.IsDevelopment())\n            app.UseDeveloperExceptionPage();\n\n        // uncomment if you want to add MVC\n        //app.UseStaticFiles();\n        //app.UseRouting();\n\n        app.UseIdentityServer();\n\n        // uncomment, if you want to add MVC-based\n        //app.UseAuthorization();\n        //app.UseEndpoints(endpoints =>\n        //{\n        //    endpoints.MapDefaultControllerRoute();\n        //});\n\n        await app.RunAsync();\n    }\n\n    return 0;\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\n\nvoid ConfigureLogger() => Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Debug()\n    .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    // uncomment to write to Azure diagnostics stream\n    //.WriteTo.File(\n    //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n    //    fileSizeLimitBytes: 1_000_000,\n    //    rollOnFileSizeLimit: true,\n    //    shared: true,\n    //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n    .CreateLogger();\n"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/src/IdentityServer/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/1_ClientCredentials/src/IdentityServer/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/Quickstart.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{BD8BA25C-A91D-419D-99B6-B575ADD6D061}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer\", \"src\\IdentityServer\\IdentityServer.csproj\", \"{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcClient\", \"src\\MvcClient\\MvcClient.csproj\", \"{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Api\", \"..\\Shared\\src\\Api\\Api.csproj\", \"{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Client\", \"..\\Shared\\src\\Client\\Client.csproj\", \"{225A262C-3B2D-4064-9C6C-5A3136046237}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.Build.0 = Release|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Release|x64.Build.0 = Release|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{6E3FD384-F4EA-420B-A0F4-E9BF08127F68}.Release|x86.Build.0 = Release|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Release|x64.Build.0 = Release|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{225A262C-3B2D-4064-9C6C-5A3136046237}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {84D5AF06-1243-46F1-9D58-70ED572832C3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/Quickstart.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Secret = IdentityServer8.Models.Secret;\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> IdentityResources =>\n        new List<IdentityResource>\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n        };\n\n\n    public static IEnumerable<ApiScope> ApiScopes =>\n        new List<ApiScope>\n        {\n            new ApiScope(\"api1\", \"My API\")\n        };\n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            // machine to machine client\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            },\n            \n            // interactive ASP.NET Core MVC client\n            new Client\n            {\n                ClientId = \"mvc\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                \n                // where to redirect to after login\n                RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                // where to redirect to after logout\n                PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                AllowedScopes = new List<string>\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    \"api1\"\n                }\n            }\n        };\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using System.Text.Json;\nglobal using static IdentityModel.JwtClaimTypes;\nglobal using IdentityServerClaimValueTypes = IdentityServer8.IdentityServerConstants.ClaimValueTypes;\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/IdentityServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"HigginsSoft.IdentityServer8\" />\n    <PackageReference Include=\"HigginsSoft.IdentityServer8.Security\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Google\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\ntry\n{\n    Log.Information(\"Starting host...\");\n\n    var builder = WebApplication.CreateBuilder(args);\n\n    var services = builder.Services;\n\n    services.AddControllersWithViews();\n\n    services\n        .AddIdentityServer()\n        .AddInMemoryIdentityResources(Config.IdentityResources)\n        .AddInMemoryApiScopes(Config.ApiScopes)\n        .AddInMemoryClients(Config.Clients)\n        .AddTestUsers(TestUsers.Users)\n        .AddDeveloperSigningCredential();\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"<insert here>\";\n            options.ClientSecret = \"<insert here>\";\n        })\n        .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n            options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n            options.SaveTokens = true;\n\n            options.Authority = \"https://demo.identityserver8.io/\";\n            options.ClientId = \"interactive.confidential\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.TokenValidationParameters = new()\n            {\n                NameClaimType = \"name\",\n                RoleClaimType = \"role\"\n            };\n        });\n\n\n    using (var app = builder.Build())\n    {\n        if (app.Environment.IsDevelopment())\n            app.UseDeveloperExceptionPage();\n\n        app.UseStaticFiles()\n            .UseRouting()\n            .UseIdentityServer()\n            .UseAuthorization();\n\n        app.MapDefaultControllerRoute();\n\n        await app.RunAsync();\n    }\n\n    return 0;\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\n\nvoid ConfigureLogger() => Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Debug()\n    .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    // uncomment to write to Azure diagnostics stream\n    //.WriteTo.File(\n    //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n    //    fileSizeLimitBytes: 1_000_000,\n    //    rollOnFileSizeLimit: true,\n    //    shared: true,\n    //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n    .CreateLogger();\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (ModelState.IsValid)\n        {\n            // validate username/password against in-memory store\n            if (_users.ValidateCredentials(model.Username, model.Password))\n            {\n                var user = _users.FindByUsername(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                // only set explicit expiration here if user chooses \"remember me\". \n                // otherwise we rely upon expiration configured in cookie middleware.\n                AuthenticationProperties props = null;\n                if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                {\n                    props = new AuthenticationProperties\n                    {\n                        IsPersistent = true,\n                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                    };\n                };\n\n                // issue authentication cookie with subject ID and username\n                var isuser = new IdentityServerUser(user.SubjectId)\n                {\n                    DisplayName = user.Username\n                };\n\n                await HttpContext.SignInAsync(isuser, props);\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI\n{\n    public class AccountOptions\n    {\n        public static bool AllowLocalLogin = true;\n        public static bool AllowRememberLogin = true;\n        public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n        public static bool ShowLogoutPrompt = true;\n        public static bool AutomaticRedirectAfterSignOut = false;\n\n        public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly ILogger<ExternalController> _logger;\n    private readonly IEventService _events;\n\n    public ExternalController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _logger = logger;\n        _events = events;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = AutoProvisionUser(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        var isuser = new IdentityServerUser(user.SubjectId)\n        {\n            DisplayName = user.Username,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = _users.FindByExternalProvider(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonSerializer.Deserialize<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n\n    static readonly object UserAddress = new\n    {\n        street_address = \"One Hacker Way\",\n        locality = \"Heidelberg\",\n        postal_code = 69118,\n        country = \"Germany\"\n    };\n\n    public static List<TestUser> Users => new List<TestUser>\n    {\n        new()\n        {\n            SubjectId = \"818727\",\n            Username = \"alice\",\n            Password = \"alice\",\n            Claims =\n            {\n                new (Name, \"Alice Smith\"),\n                new (GivenName, \"Alice\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"AliceSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://alice.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        },\n        new()\n        {\n            SubjectId = \"88421113\",\n            Username = \"bob\",\n            Password = \"bob\",\n            Claims =\n            {\n                new (Name, \"Bob Smith\"),\n                new (GivenName, \"Bob\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"BobSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://bob.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n\n@{\n    var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Ioc.Sanitizer.Url.Sanitize(Model.RedirectUrl)';\n    window.location.href = url;\n</script>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/wwwroot/js/signin-redirect.js",
    "content": "//window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/IdentityServer/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly ILogger<HomeController> _logger;\n\n    public HomeController(ILogger<HomeController> logger)\n    {\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    public async Task<IActionResult> CallApi()\n    {\n        var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = new HttpClient();\n        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n        var content = await client.GetStringAsync(\"https://localhost:6001/identity\");\n\n        var obj = JsonSerializer.Deserialize<JsonElement>(content);\n        ViewBag.Json = obj.ToString();\n        return View(\"json\");\n    }\n\n    public IActionResult Logout()\n    {\n        return SignOut(\"Cookies\", \"oidc\");\n    }\n\n    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n    public IActionResult Error()\n    {\n        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using System.Diagnostics;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net.Http.Headers;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Models/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class ErrorViewModel\n{\n    public string RequestId { get; set; }\n\n    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/MvcClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Update=\"Views\\Shared\\Json.cshtml\">\n      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n    </Content>\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddControllersWithViews();\nbuilder.Services\n    .AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"Cookies\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n    .AddCookie(\"Cookies\")\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        options.Authority = \"https://localhost:5001\";\n\n        options.ClientId = \"mvc\";\n        options.ClientSecret = \"secret\";\n        options.ResponseType = \"code\";\n\n        options.Scope.Add(\"api1\");\n\n        options.SaveTokens = true;\n    });\n\n\nusing (var app = builder.Build())\n{\n    if (app.Environment.IsDevelopment())\n        app.UseDeveloperExceptionPage();\n    else\n        app.UseExceptionHandler(\"/Home/Error\");\n\n    app.UseStaticFiles();\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n    app.MapDefaultControllerRoute().RequireAuthorization();\n\n    await app.RunAsync();\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"MvcClient\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5002\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/Home/Index.cshtml",
    "content": "@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/Home/Privacy.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Privacy Policy\";\n}\n<h1>@ViewData[\"Title\"]</h1>\n\n<p>Use this page to detail your site's privacy policy.</p>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/Shared/Error.cshtml",
    "content": "﻿@model ErrorViewModel\n@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n@if (Model.ShowRequestId)\n{\n    <p>\n        <strong>Request ID:</strong> <code>@Model.RequestId</code>\n    </p>\n}\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n    It can result in displaying sensitive information from exceptions to end users.\n    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n    and restarting the app.\n</p>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcClient</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcClient</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/Shared/json.cshtml",
    "content": "<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Quickstarts/2_InteractiveAspNetCore/src/MvcClient/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/Quickstart.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{BD8BA25C-A91D-419D-99B6-B575ADD6D061}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer\", \"src\\IdentityServer\\IdentityServer.csproj\", \"{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcClient\", \"src\\MvcClient\\MvcClient.csproj\", \"{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Api\", \"..\\Shared\\src\\Api\\Api.csproj\", \"{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Client\", \"..\\Shared\\src\\Client\\Client.csproj\", \"{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.Build.0 = Release|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Release|x64.Build.0 = Release|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{FB7DDF43-1EB6-4FBF-B83D-6E19F723D7E4}.Release|x86.Build.0 = Release|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Release|x64.Build.0 = Release|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{78C0AEF8-E8B7-4F62-948C-FEFBF0ED881B}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {84D5AF06-1243-46F1-9D58-70ED572832C3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/Quickstart.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Secret = IdentityServer8.Models.Secret;\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> IdentityResources =>\n        new List<IdentityResource>\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n        };\n\n\n    public static IEnumerable<ApiScope> ApiScopes =>\n        new List<ApiScope>\n        {\n            new ApiScope(\"api1\", \"My API\")\n        };\n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            // machine to machine client\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            },\n            \n            // interactive ASP.NET Core MVC client\n            new Client\n            {\n                ClientId = \"mvc\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                \n                // where to redirect to after login\n                RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                // where to redirect to after logout\n                PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                AllowedScopes = new List<string>\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    \"api1\"\n                }\n            }\n        };\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using System.Text.Json;\nglobal using static IdentityModel.JwtClaimTypes;\nglobal using IdentityServerClaimValueTypes = IdentityServer8.IdentityServerConstants.ClaimValueTypes;\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/IdentityServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"HigginsSoft.IdentityServer8\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Google\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\ntry\n{\n    Log.Information(\"Starting host...\");\n\n    var builder = WebApplication.CreateBuilder(args);\n\n    var services = builder.Services;\n\n    services.AddControllersWithViews();\n\n    services\n        .AddIdentityServer()\n        .AddInMemoryIdentityResources(Config.IdentityResources)\n        .AddInMemoryApiScopes(Config.ApiScopes)\n        .AddInMemoryClients(Config.Clients)\n        .AddTestUsers(TestUsers.Users)\n        .AddDeveloperSigningCredential();\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"<insert here>\";\n            options.ClientSecret = \"<insert here>\";\n        })\n        .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n            options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n            options.SaveTokens = true;\n\n            options.Authority = \"https://demo.identityserver8.io/\";\n            options.ClientId = \"interactive.confidential\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.TokenValidationParameters = new()\n            {\n                NameClaimType = \"name\",\n                RoleClaimType = \"role\"\n            };\n        });\n\n\n    using (var app = builder.Build())\n    {\n        if (app.Environment.IsDevelopment())\n            app.UseDeveloperExceptionPage();\n\n        app.UseStaticFiles()\n            .UseRouting()\n            .UseIdentityServer()\n            .UseAuthorization();\n\n        app.MapDefaultControllerRoute();\n\n        await app.RunAsync();\n    }\n\n    return 0;\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\n\nvoid ConfigureLogger() => Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Debug()\n    .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    // uncomment to write to Azure diagnostics stream\n    //.WriteTo.File(\n    //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n    //    fileSizeLimitBytes: 1_000_000,\n    //    rollOnFileSizeLimit: true,\n    //    shared: true,\n    //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n    .CreateLogger();\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (ModelState.IsValid)\n        {\n            // validate username/password against in-memory store\n            if (_users.ValidateCredentials(model.Username, model.Password))\n            {\n                var user = _users.FindByUsername(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                // only set explicit expiration here if user chooses \"remember me\". \n                // otherwise we rely upon expiration configured in cookie middleware.\n                AuthenticationProperties props = null;\n                if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                {\n                    props = new AuthenticationProperties\n                    {\n                        IsPersistent = true,\n                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                    };\n                };\n\n                // issue authentication cookie with subject ID and username\n                var isuser = new IdentityServerUser(user.SubjectId)\n                {\n                    DisplayName = user.Username\n                };\n\n                await HttpContext.SignInAsync(isuser, props);\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI\n{\n    public class AccountOptions\n    {\n        public static bool AllowLocalLogin = true;\n        public static bool AllowRememberLogin = true;\n        public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n        public static bool ShowLogoutPrompt = true;\n        public static bool AutomaticRedirectAfterSignOut = false;\n\n        public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly ILogger<ExternalController> _logger;\n    private readonly IEventService _events;\n\n    public ExternalController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _logger = logger;\n        _events = events;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = AutoProvisionUser(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        var isuser = new IdentityServerUser(user.SubjectId)\n        {\n            DisplayName = user.Username,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = _users.FindByExternalProvider(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonSerializer.Deserialize<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n\n    static readonly object UserAddress = new\n    {\n        street_address = \"One Hacker Way\",\n        locality = \"Heidelberg\",\n        postal_code = 69118,\n        country = \"Germany\"\n    };\n\n    public static List<TestUser> Users => new List<TestUser>\n    {\n        new()\n        {\n            SubjectId = \"818727\",\n            Username = \"alice\",\n            Password = \"alice\",\n            Claims =\n            {\n                new (Name, \"Alice Smith\"),\n                new (GivenName, \"Alice\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"AliceSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://alice.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        },\n        new()\n        {\n            SubjectId = \"88421113\",\n            Username = \"bob\",\n            Password = \"bob\",\n            Claims =\n            {\n                new (Name, \"Bob Smith\"),\n                new (GivenName, \"Bob\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"BobSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://bob.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n\n@{\n    var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Ioc.Sanitizer.Url.Sanitize(Model.RedirectUrl)';\n    window.location.href = url;\n</script>\n\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/wwwroot/js/signin-redirect.js",
    "content": "//window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/IdentityServer/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly ILogger<HomeController> _logger;\n\n    public HomeController(ILogger<HomeController> logger)\n    {\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    public async Task<IActionResult> CallApi()\n    {\n        var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = new HttpClient();\n        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n        var content = await client.GetStringAsync(\"https://localhost:6001/identity\");\n\n        var obj = JsonSerializer.Deserialize<JsonElement>(content);\n        ViewBag.Json = obj.ToString();\n        return View(\"json\");\n    }\n\n    public IActionResult Logout()\n    {\n        return SignOut(\"Cookies\", \"oidc\");\n    }\n\n    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n    public IActionResult Error()\n    {\n        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using System.Diagnostics;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net.Http.Headers;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Models/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class ErrorViewModel\n{\n    public string RequestId { get; set; }\n\n    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/MvcClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Update=\"Views\\Shared\\Json.cshtml\">\n      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n    </Content>\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddControllersWithViews();\nbuilder.Services\n    .AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"Cookies\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n    .AddCookie(\"Cookies\")\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        options.Authority = \"https://localhost:5001\";\n\n        options.ClientId = \"mvc\";\n        options.ClientSecret = \"secret\";\n        options.ResponseType = \"code\";\n\n        options.Scope.Add(\"api1\");\n\n        options.SaveTokens = true;\n    });\n\n\nusing (var app = builder.Build())\n{\n    if (app.Environment.IsDevelopment())\n        app.UseDeveloperExceptionPage();\n    else\n        app.UseExceptionHandler(\"/Home/Error\");\n\n    app.UseStaticFiles();\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n    app.MapDefaultControllerRoute().RequireAuthorization();\n\n    await app.RunAsync();\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"MvcClient\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5002\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/Home/Index.cshtml",
    "content": "@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/Home/Privacy.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Privacy Policy\";\n}\n<h1>@ViewData[\"Title\"]</h1>\n\n<p>Use this page to detail your site's privacy policy.</p>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/Shared/Error.cshtml",
    "content": "﻿@model ErrorViewModel\n@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n@if (Model.ShowRequestId)\n{\n    <p>\n        <strong>Request ID:</strong> <code>@Model.RequestId</code>\n    </p>\n}\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n    It can result in displaying sensitive information from exceptions to end users.\n    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n    and restarting the app.\n</p>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcClient</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcClient</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/Shared/json.cshtml",
    "content": "<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Quickstarts/3_AspNetCoreAndApis/src/MvcClient/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/Quickstart.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{BD8BA25C-A91D-419D-99B6-B575ADD6D061}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer\", \"src\\IdentityServer\\IdentityServer.csproj\", \"{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcClient\", \"src\\MvcClient\\MvcClient.csproj\", \"{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"JavaScriptClient\", \"src\\JavaScriptClient\\JavaScriptClient.csproj\", \"{DD8D4022-0073-40EE-84F0-8E4833522BB9}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Api\", \"..\\Shared\\src\\Api\\Api.csproj\", \"{8D0EA8BB-7B55-4F60-8011-EF220103BADB}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Client\", \"..\\Shared\\src\\Client\\Client.csproj\", \"{8FC8CFB9-740B-4D13-B396-99283AA758AC}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.Build.0 = Release|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Release|x64.Build.0 = Release|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9}.Release|x86.Build.0 = Release|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Release|x64.Build.0 = Release|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{8D0EA8BB-7B55-4F60-8011-EF220103BADB}.Release|x86.Build.0 = Release|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Release|x64.Build.0 = Release|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{8FC8CFB9-740B-4D13-B396-99283AA758AC}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\t\t{DD8D4022-0073-40EE-84F0-8E4833522BB9} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {84D5AF06-1243-46F1-9D58-70ED572832C3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/Quickstart.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Secret = IdentityServer8.Models.Secret;\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> IdentityResources =>\n        new List<IdentityResource>\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n        };\n\n\n    public static IEnumerable<ApiScope> ApiScopes =>\n        new List<ApiScope>\n        {\n            new ApiScope(\"api1\", \"My API\")\n        };\n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            // machine to machine client\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            },\n            \n            // interactive ASP.NET Core MVC client\n            new Client\n            {\n                ClientId = \"mvc\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                \n                // where to redirect to after login\n                RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                // where to redirect to after logout\n                PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                AllowedScopes = new List<string>\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    \"api1\"\n                }\n            }\n        };\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using System.Text.Json;\nglobal using static IdentityModel.JwtClaimTypes;\nglobal using IdentityServerClaimValueTypes = IdentityServer8.IdentityServerConstants.ClaimValueTypes;"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/IdentityServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"HigginsSoft.IdentityServer8\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />  \n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Google\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\ntry\n{\n    Log.Information(\"Starting host...\");\n\n    var builder = WebApplication.CreateBuilder(args);\n\n    var services = builder.Services;\n\n    services.AddControllersWithViews();\n\n    services\n        .AddIdentityServer()\n        .AddInMemoryIdentityResources(Config.IdentityResources)\n        .AddInMemoryApiScopes(Config.ApiScopes)\n        .AddInMemoryClients(Config.Clients)\n        .AddTestUsers(TestUsers.Users)\n        .AddDeveloperSigningCredential();\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"<insert here>\";\n            options.ClientSecret = \"<insert here>\";\n        })\n        .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n            options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n            options.SaveTokens = true;\n\n            options.Authority = \"https://demo.identityserver8.io/\";\n            options.ClientId = \"interactive.confidential\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.TokenValidationParameters = new()\n            {\n                NameClaimType = \"name\",\n                RoleClaimType = \"role\"\n            };\n        });\n\n\n    using (var app = builder.Build())\n    {\n        if (app.Environment.IsDevelopment())\n            app.UseDeveloperExceptionPage();\n\n        app.UseStaticFiles()\n            .UseRouting()\n            .UseIdentityServer()\n            .UseAuthorization();\n\n        app.MapDefaultControllerRoute();\n\n        await app.RunAsync();\n    }\n\n    return 0;\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\n\nvoid ConfigureLogger() => Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Debug()\n    .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    // uncomment to write to Azure diagnostics stream\n    //.WriteTo.File(\n    //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n    //    fileSizeLimitBytes: 1_000_000,\n    //    rollOnFileSizeLimit: true,\n    //    shared: true,\n    //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n    .CreateLogger();\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (ModelState.IsValid)\n        {\n            // validate username/password against in-memory store\n            if (_users.ValidateCredentials(model.Username, model.Password))\n            {\n                var user = _users.FindByUsername(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                // only set explicit expiration here if user chooses \"remember me\". \n                // otherwise we rely upon expiration configured in cookie middleware.\n                AuthenticationProperties props = null;\n                if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                {\n                    props = new AuthenticationProperties\n                    {\n                        IsPersistent = true,\n                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                    };\n                };\n\n                // issue authentication cookie with subject ID and username\n                var isuser = new IdentityServerUser(user.SubjectId)\n                {\n                    DisplayName = user.Username\n                };\n\n                await HttpContext.SignInAsync(isuser, props);\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI\n{\n    public class AccountOptions\n    {\n        public static bool AllowLocalLogin = true;\n        public static bool AllowRememberLogin = true;\n        public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n        public static bool ShowLogoutPrompt = true;\n        public static bool AutomaticRedirectAfterSignOut = false;\n\n        public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly ILogger<ExternalController> _logger;\n    private readonly IEventService _events;\n\n    public ExternalController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _logger = logger;\n        _events = events;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = AutoProvisionUser(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        var isuser = new IdentityServerUser(user.SubjectId)\n        {\n            DisplayName = user.Username,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = _users.FindByExternalProvider(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonSerializer.Deserialize<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n\n    static readonly object UserAddress = new\n    {\n        street_address = \"One Hacker Way\",\n        locality = \"Heidelberg\",\n        postal_code = 69118,\n        country = \"Germany\"\n    };\n\n    public static List<TestUser> Users => new List<TestUser>\n    {\n        new()\n        {\n            SubjectId = \"818727\",\n            Username = \"alice\",\n            Password = \"alice\",\n            Claims =\n            {\n                new (Name, \"Alice Smith\"),\n                new (GivenName, \"Alice\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"AliceSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://alice.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        },\n        new()\n        {\n            SubjectId = \"88421113\",\n            Username = \"bob\",\n            Password = \"bob\",\n            Claims =\n            {\n                new (Name, \"Bob Smith\"),\n                new (GivenName, \"Bob\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"BobSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://bob.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8;\nusing IdentityServerHost.Quickstart.UI;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer\n{\n    public class Startup\n    {\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddControllersWithViews();\n\n            var builder = services.AddIdentityServer()\n                .AddInMemoryIdentityResources(Config.IdentityResources)\n                .AddInMemoryApiScopes(Config.ApiScopes)\n                .AddInMemoryClients(Config.Clients)\n                .AddTestUsers(TestUsers.Users);\n\n            builder.AddDeveloperSigningCredential();\n\n            services.AddAuthentication()\n                .AddGoogle(\"Google\", options =>\n                {\n                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n                    options.ClientId = \"<insert here>\";\n                    options.ClientSecret = \"<insert here>\";\n                })\n                .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n                {\n                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n                    options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n                    options.SaveTokens = true;\n\n                    options.Authority = \"https://demo.identityserver8.io/\";\n                    options.ClientId = \"interactive.confidential\";\n                    options.ClientSecret = \"secret\";\n                    options.ResponseType = \"code\";\n\n                    options.TokenValidationParameters = new TokenValidationParameters\n                    {\n                        NameClaimType = \"name\",\n                        RoleClaimType = \"role\"\n                    };\n                });\n        }\n\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n            }\n\n            app.UseStaticFiles();\n            app.UseRouting();\n\n            app.UseIdentityServer();\n            app.UseAuthorization();\n\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapDefaultControllerRoute();\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n\n@{\n    var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Ioc.Sanitizer.Url.Sanitize(Model.RedirectUrl)';\n    window.location.href = url;\n</script>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/wwwroot/js/signin-redirect.js",
    "content": "// window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/IdentityServer/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/JavaScriptClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nvar app = WebApplication.Create(args);\napp.UseDefaultFiles();\napp.UseStaticFiles();\nawait app.RunAsync();\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:5003\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"JavaScriptClient\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5003\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.Builder;\n\nnamespace JavaScriptClient\n{\n    public class Startup\n    {\n        public void Configure(IApplicationBuilder app)\n        {\n            app.UseDefaultFiles();\n            app.UseStaticFiles();\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/wwwroot/app.js",
    "content": "/// <reference path=\"oidc-client.js\" />\n\nfunction log() {\n    document.getElementById('results').innerText = '';\n\n    Array.prototype.forEach.call(arguments, function (msg) {\n        if (msg instanceof Error) {\n            msg = \"Error: \" + msg.message;\n        }\n        else if (typeof msg !== 'string') {\n            msg = JSON.stringify(msg, null, 2);\n        }\n        document.getElementById('results').innerText += msg + '\\r\\n';\n    });\n}\n\ndocument.getElementById(\"login\").addEventListener(\"click\", login, false);\ndocument.getElementById(\"api\").addEventListener(\"click\", api, false);\ndocument.getElementById(\"logout\").addEventListener(\"click\", logout, false);\n\nvar config = {\n    authority: \"https://localhost:5001\",\n    client_id: \"js\",\n    redirect_uri: \"https://localhost:5003/callback.html\",\n    response_type: \"code\",\n    scope:\"openid profile api1\",\n    post_logout_redirect_uri : \"https://localhost:5003/index.html\",\n};\nvar mgr = new Oidc.UserManager(config);\n\nmgr.getUser().then(function (user) {\n    if (user) {\n        log(\"User logged in\", user.profile);\n    }\n    else {\n        log(\"User not logged in\");\n    }\n});\n\nfunction login() {\n    mgr.signinRedirect();\n}\n\nfunction api() {\n    mgr.getUser().then(function (user) {\n        var url = \"https://localhost:6001/identity\";\n\n        var xhr = new XMLHttpRequest();\n        xhr.open(\"GET\", url);\n        xhr.onload = function () {\n            log(xhr.status, JSON.parse(xhr.responseText));\n        }\n        xhr.setRequestHeader(\"Authorization\", \"Bearer \" + user.access_token);\n        xhr.send();\n    });\n}\n\nfunction logout() {\n    mgr.signoutRedirect();\n}"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/wwwroot/callback.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <title></title>\n</head>\n<body>\n    <script src=\"oidc-client.js\"></script>\n    <script>\n        new Oidc.UserManager({ response_mode: \"query\" }).signinRedirectCallback().then(function () {\n            window.location = \"index.html\";\n        }).catch(function (e) {\n            console.error(e);\n        });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/wwwroot/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\" />\n    <title></title>\n</head>\n<body>\n    <button id=\"login\">Login</button>\n    <button id=\"api\">Call API</button>\n    <button id=\"logout\">Logout</button>\n\n    <pre id=\"results\"></pre>\n\n    <script src=\"oidc-client.js\"></script>\n    <script src=\"app.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/JavaScriptClient/wwwroot/oidc-client.js",
    "content": "var Oidc =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ \"./index.js\":\n/*!******************!*\\\n  !*** ./index.js ***!\n  \\******************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _Log = __webpack_require__(/*! ./src/Log.js */ \"./src/Log.js\");\n\nvar _OidcClient = __webpack_require__(/*! ./src/OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./src/OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./src/WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _InMemoryWebStorage = __webpack_require__(/*! ./src/InMemoryWebStorage.js */ \"./src/InMemoryWebStorage.js\");\n\nvar _UserManager = __webpack_require__(/*! ./src/UserManager.js */ \"./src/UserManager.js\");\n\nvar _AccessTokenEvents = __webpack_require__(/*! ./src/AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./src/MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _CordovaPopupNavigator = __webpack_require__(/*! ./src/CordovaPopupNavigator.js */ \"./src/CordovaPopupNavigator.js\");\n\nvar _CordovaIFrameNavigator = __webpack_require__(/*! ./src/CordovaIFrameNavigator.js */ \"./src/CordovaIFrameNavigator.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./src/CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./src/TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./src/SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _Global = __webpack_require__(/*! ./src/Global.js */ \"./src/Global.js\");\n\nvar _User = __webpack_require__(/*! ./src/User.js */ \"./src/User.js\");\n\nvar _version = __webpack_require__(/*! ./version.js */ \"./version.js\");\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nexports.default = {\n    Version: _version.Version,\n    Log: _Log.Log,\n    OidcClient: _OidcClient.OidcClient,\n    OidcClientSettings: _OidcClientSettings.OidcClientSettings,\n    WebStorageStateStore: _WebStorageStateStore.WebStorageStateStore,\n    InMemoryWebStorage: _InMemoryWebStorage.InMemoryWebStorage,\n    UserManager: _UserManager.UserManager,\n    AccessTokenEvents: _AccessTokenEvents.AccessTokenEvents,\n    MetadataService: _MetadataService.MetadataService,\n    CordovaPopupNavigator: _CordovaPopupNavigator.CordovaPopupNavigator,\n    CordovaIFrameNavigator: _CordovaIFrameNavigator.CordovaIFrameNavigator,\n    CheckSessionIFrame: _CheckSessionIFrame.CheckSessionIFrame,\n    TokenRevocationClient: _TokenRevocationClient.TokenRevocationClient,\n    SessionMonitor: _SessionMonitor.SessionMonitor,\n    Global: _Global.Global,\n    User: _User.User\n};\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./jsrsasign/dist/jsrsasign.js\":\n/*!*************************************!*\\\n  !*** ./jsrsasign/dist/jsrsasign.js ***!\n  \\*************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(Buffer) {\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\n/*\n * jsrsasign(all) 8.0.12 (2018-04-22) (c) 2010-2018 Kenji Urushima | kjur.github.com/jsrsasign/license\n */\n\nvar navigator = {};\nnavigator.userAgent = false;\n\nvar window = {};\n\n/*!\nCopyright (c) 2011, Yahoo! Inc. All rights reserved.\nCode licensed under the BSD License:\nhttp://developer.yahoo.com/yui/license.html\nversion: 2.9.0\n*/\nif (YAHOO === undefined) {\n  var YAHOO = {};\n}YAHOO.lang = { extend: function extend(g, h, f) {\n    if (!h || !g) {\n      throw new Error(\"YAHOO.lang.extend failed, please check that all dependencies are included.\");\n    }var d = function d() {};d.prototype = h.prototype;g.prototype = new d();g.prototype.constructor = g;g.superclass = h.prototype;if (h.prototype.constructor == Object.prototype.constructor) {\n      h.prototype.constructor = h;\n    }if (f) {\n      var b;for (b in f) {\n        g.prototype[b] = f[b];\n      }var e = function e() {},\n          c = [\"toString\", \"valueOf\"];try {\n        if (/MSIE/.test(navigator.userAgent)) {\n          e = function e(j, i) {\n            for (b = 0; b < c.length; b = b + 1) {\n              var l = c[b],\n                  k = i[l];if (typeof k === \"function\" && k != Object.prototype[l]) {\n                j[l] = k;\n              }\n            }\n          };\n        }\n      } catch (a) {}e(g.prototype, f);\n    }\n  } };\n/*! CryptoJS v3.1.2 core-fix.js\n * code.google.com/p/crypto-js\n * (c) 2009-2013 by Jeff Mott. All rights reserved.\n * code.google.com/p/crypto-js/wiki/License\n * THIS IS FIX of 'core.js' to fix Hmac issue.\n * https://code.google.com/p/crypto-js/issues/detail?id=84\n * https://crypto-js.googlecode.com/svn-history/r667/branches/3.x/src/core.js\n */\nvar CryptoJS = CryptoJS || function (e, g) {\n  var a = {};var b = a.lib = {};var j = b.Base = function () {\n    function n() {}return { extend: function extend(p) {\n        n.prototype = this;var o = new n();if (p) {\n          o.mixIn(p);\n        }if (!o.hasOwnProperty(\"init\")) {\n          o.init = function () {\n            o.$super.init.apply(this, arguments);\n          };\n        }o.init.prototype = o;o.$super = this;return o;\n      }, create: function create() {\n        var o = this.extend();o.init.apply(o, arguments);return o;\n      }, init: function init() {}, mixIn: function mixIn(p) {\n        for (var o in p) {\n          if (p.hasOwnProperty(o)) {\n            this[o] = p[o];\n          }\n        }if (p.hasOwnProperty(\"toString\")) {\n          this.toString = p.toString;\n        }\n      }, clone: function clone() {\n        return this.init.prototype.extend(this);\n      } };\n  }();var l = b.WordArray = j.extend({ init: function init(o, n) {\n      o = this.words = o || [];if (n != g) {\n        this.sigBytes = n;\n      } else {\n        this.sigBytes = o.length * 4;\n      }\n    }, toString: function toString(n) {\n      return (n || h).stringify(this);\n    }, concat: function concat(t) {\n      var q = this.words;var p = t.words;var n = this.sigBytes;var s = t.sigBytes;this.clamp();if (n % 4) {\n        for (var r = 0; r < s; r++) {\n          var o = p[r >>> 2] >>> 24 - r % 4 * 8 & 255;q[n + r >>> 2] |= o << 24 - (n + r) % 4 * 8;\n        }\n      } else {\n        for (var r = 0; r < s; r += 4) {\n          q[n + r >>> 2] = p[r >>> 2];\n        }\n      }this.sigBytes += s;return this;\n    }, clamp: function clamp() {\n      var o = this.words;var n = this.sigBytes;o[n >>> 2] &= 4294967295 << 32 - n % 4 * 8;o.length = e.ceil(n / 4);\n    }, clone: function clone() {\n      var n = j.clone.call(this);n.words = this.words.slice(0);return n;\n    }, random: function random(p) {\n      var o = [];for (var n = 0; n < p; n += 4) {\n        o.push(e.random() * 4294967296 | 0);\n      }return new l.init(o, p);\n    } });var m = a.enc = {};var h = m.Hex = { stringify: function stringify(p) {\n      var r = p.words;var o = p.sigBytes;var q = [];for (var n = 0; n < o; n++) {\n        var s = r[n >>> 2] >>> 24 - n % 4 * 8 & 255;q.push((s >>> 4).toString(16));q.push((s & 15).toString(16));\n      }return q.join(\"\");\n    }, parse: function parse(p) {\n      var n = p.length;var q = [];for (var o = 0; o < n; o += 2) {\n        q[o >>> 3] |= parseInt(p.substr(o, 2), 16) << 24 - o % 8 * 4;\n      }return new l.init(q, n / 2);\n    } };var d = m.Latin1 = { stringify: function stringify(q) {\n      var r = q.words;var p = q.sigBytes;var n = [];for (var o = 0; o < p; o++) {\n        var s = r[o >>> 2] >>> 24 - o % 4 * 8 & 255;n.push(String.fromCharCode(s));\n      }return n.join(\"\");\n    }, parse: function parse(p) {\n      var n = p.length;var q = [];for (var o = 0; o < n; o++) {\n        q[o >>> 2] |= (p.charCodeAt(o) & 255) << 24 - o % 4 * 8;\n      }return new l.init(q, n);\n    } };var c = m.Utf8 = { stringify: function stringify(n) {\n      try {\n        return decodeURIComponent(escape(d.stringify(n)));\n      } catch (o) {\n        throw new Error(\"Malformed UTF-8 data\");\n      }\n    }, parse: function parse(n) {\n      return d.parse(unescape(encodeURIComponent(n)));\n    } };var i = b.BufferedBlockAlgorithm = j.extend({ reset: function reset() {\n      this._data = new l.init();this._nDataBytes = 0;\n    }, _append: function _append(n) {\n      if (typeof n == \"string\") {\n        n = c.parse(n);\n      }this._data.concat(n);this._nDataBytes += n.sigBytes;\n    }, _process: function _process(w) {\n      var q = this._data;var x = q.words;var n = q.sigBytes;var t = this.blockSize;var v = t * 4;var u = n / v;if (w) {\n        u = e.ceil(u);\n      } else {\n        u = e.max((u | 0) - this._minBufferSize, 0);\n      }var s = u * t;var r = e.min(s * 4, n);if (s) {\n        for (var p = 0; p < s; p += t) {\n          this._doProcessBlock(x, p);\n        }var o = x.splice(0, s);q.sigBytes -= r;\n      }return new l.init(o, r);\n    }, clone: function clone() {\n      var n = j.clone.call(this);n._data = this._data.clone();return n;\n    }, _minBufferSize: 0 });var f = b.Hasher = i.extend({ cfg: j.extend(), init: function init(n) {\n      this.cfg = this.cfg.extend(n);this.reset();\n    }, reset: function reset() {\n      i.reset.call(this);this._doReset();\n    }, update: function update(n) {\n      this._append(n);this._process();return this;\n    }, finalize: function finalize(n) {\n      if (n) {\n        this._append(n);\n      }var o = this._doFinalize();return o;\n    }, blockSize: 512 / 32, _createHelper: function _createHelper(n) {\n      return function (p, o) {\n        return new n.init(o).finalize(p);\n      };\n    }, _createHmacHelper: function _createHmacHelper(n) {\n      return function (p, o) {\n        return new k.HMAC.init(n, o).finalize(p);\n      };\n    } });var k = a.algo = {};return a;\n}(Math);\n/*\nCryptoJS v3.1.2 x64-core-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (g) {\n  var a = CryptoJS,\n      f = a.lib,\n      e = f.Base,\n      h = f.WordArray,\n      a = a.x64 = {};a.Word = e.extend({ init: function init(b, c) {\n      this.high = b;this.low = c;\n    } });a.WordArray = e.extend({ init: function init(b, c) {\n      b = this.words = b || [];this.sigBytes = c != g ? c : 8 * b.length;\n    }, toX32: function toX32() {\n      for (var b = this.words, c = b.length, a = [], d = 0; d < c; d++) {\n        var e = b[d];a.push(e.high);a.push(e.low);\n      }return h.create(a, this.sigBytes);\n    }, clone: function clone() {\n      for (var b = e.clone.call(this), c = b.words = this.words.slice(0), a = c.length, d = 0; d < a; d++) {\n        c[d] = c[d].clone();\n      }return b;\n    } });\n})();\n\n/*\nCryptoJS v3.1.2 enc-base64.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  var h = CryptoJS,\n      j = h.lib.WordArray;h.enc.Base64 = { stringify: function stringify(b) {\n      var e = b.words,\n          f = b.sigBytes,\n          c = this._map;b.clamp();b = [];for (var a = 0; a < f; a += 3) {\n        for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) {\n          b.push(c.charAt(d >>> 6 * (3 - g) & 63));\n        }\n      }if (e = c.charAt(64)) for (; b.length % 4;) {\n        b.push(e);\n      }return b.join(\"\");\n    }, parse: function parse(b) {\n      var e = b.length,\n          f = this._map,\n          c = f.charAt(64);c && (c = b.indexOf(c), -1 != c && (e = c));for (var c = [], a = 0, d = 0; d < e; d++) {\n        if (d % 4) {\n          var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4),\n              h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4);c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4);a++;\n        }\n      }return j.create(c, a);\n    }, _map: \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\" };\n})();\n\n/*\nCryptoJS v3.1.2 sha256-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function (k) {\n  for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function u(q) {\n    return 4294967296 * (q - (q | 0)) | 0;\n  }, l = 2, b = 0; 64 > b;) {\n    var d;a: {\n      d = l;for (var w = k.sqrt(d), r = 2; r <= w; r++) {\n        if (!(d % r)) {\n          d = !1;break a;\n        }\n      }d = !0;\n    }d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++);l++;\n  }var n = [],\n      h = h.SHA256 = j.extend({ _doReset: function _doReset() {\n      this._hash = new v.init(s.slice(0));\n    }, _doProcessBlock: function _doProcessBlock(q, h) {\n      for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) {\n        if (16 > e) n[e] = q[h + e] | 0;else {\n          var m = n[e - 15],\n              p = n[e - 2];n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16];\n        }m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e];p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b);l = j;j = g;g = f;f = k + m | 0;k = b;b = d;d = c;c = m + p | 0;\n      }a[0] = a[0] + c | 0;a[1] = a[1] + d | 0;a[2] = a[2] + b | 0;a[3] = a[3] + k | 0;a[4] = a[4] + f | 0;a[5] = a[5] + g | 0;a[6] = a[6] + j | 0;a[7] = a[7] + l | 0;\n    }, _doFinalize: function _doFinalize() {\n      var d = this._data,\n          b = d.words,\n          a = 8 * this._nDataBytes,\n          c = 8 * d.sigBytes;\n      b[c >>> 5] |= 128 << 24 - c % 32;b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296);b[(c + 64 >>> 9 << 4) + 15] = a;d.sigBytes = 4 * b.length;this._process();return this._hash;\n    }, clone: function clone() {\n      var b = j.clone.call(this);b._hash = this._hash.clone();return b;\n    } });g.SHA256 = j._createHelper(h);g.HmacSHA256 = j._createHmacHelper(h);\n})(Math);\n\n/*\nCryptoJS v3.1.2 sha512-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  function a() {\n    return d.create.apply(d, arguments);\n  }for (var n = CryptoJS, r = n.lib.Hasher, e = n.x64, d = e.Word, T = e.WordArray, e = n.algo, ea = [a(1116352408, 3609767458), a(1899447441, 602891725), a(3049323471, 3964484399), a(3921009573, 2173295548), a(961987163, 4081628472), a(1508970993, 3053834265), a(2453635748, 2937671579), a(2870763221, 3664609560), a(3624381080, 2734883394), a(310598401, 1164996542), a(607225278, 1323610764), a(1426881987, 3590304994), a(1925078388, 4068182383), a(2162078206, 991336113), a(2614888103, 633803317), a(3248222580, 3479774868), a(3835390401, 2666613458), a(4022224774, 944711139), a(264347078, 2341262773), a(604807628, 2007800933), a(770255983, 1495990901), a(1249150122, 1856431235), a(1555081692, 3175218132), a(1996064986, 2198950837), a(2554220882, 3999719339), a(2821834349, 766784016), a(2952996808, 2566594879), a(3210313671, 3203337956), a(3336571891, 1034457026), a(3584528711, 2466948901), a(113926993, 3758326383), a(338241895, 168717936), a(666307205, 1188179964), a(773529912, 1546045734), a(1294757372, 1522805485), a(1396182291, 2643833823), a(1695183700, 2343527390), a(1986661051, 1014477480), a(2177026350, 1206759142), a(2456956037, 344077627), a(2730485921, 1290863460), a(2820302411, 3158454273), a(3259730800, 3505952657), a(3345764771, 106217008), a(3516065817, 3606008344), a(3600352804, 1432725776), a(4094571909, 1467031594), a(275423344, 851169720), a(430227734, 3100823752), a(506948616, 1363258195), a(659060556, 3750685593), a(883997877, 3785050280), a(958139571, 3318307427), a(1322822218, 3812723403), a(1537002063, 2003034995), a(1747873779, 3602036899), a(1955562222, 1575990012), a(2024104815, 1125592928), a(2227730452, 2716904306), a(2361852424, 442776044), a(2428436474, 593698344), a(2756734187, 3733110249), a(3204031479, 2999351573), a(3329325298, 3815920427), a(3391569614, 3928383900), a(3515267271, 566280711), a(3940187606, 3454069534), a(4118630271, 4000239992), a(116418474, 1914138554), a(174292421, 2731055270), a(289380356, 3203993006), a(460393269, 320620315), a(685471733, 587496836), a(852142971, 1086792851), a(1017036298, 365543100), a(1126000580, 2618297676), a(1288033470, 3409855158), a(1501505948, 4234509866), a(1607167915, 987167468), a(1816402316, 1246189591)], v = [], w = 0; 80 > w; w++) {\n    v[w] = a();\n  }e = e.SHA512 = r.extend({ _doReset: function _doReset() {\n      this._hash = new T.init([new d.init(1779033703, 4089235720), new d.init(3144134277, 2227873595), new d.init(1013904242, 4271175723), new d.init(2773480762, 1595750129), new d.init(1359893119, 2917565137), new d.init(2600822924, 725511199), new d.init(528734635, 4215389547), new d.init(1541459225, 327033209)]);\n    }, _doProcessBlock: function _doProcessBlock(a, d) {\n      for (var f = this._hash.words, F = f[0], e = f[1], n = f[2], r = f[3], G = f[4], H = f[5], I = f[6], f = f[7], w = F.high, J = F.low, X = e.high, K = e.low, Y = n.high, L = n.low, Z = r.high, M = r.low, $ = G.high, N = G.low, aa = H.high, O = H.low, ba = I.high, P = I.low, ca = f.high, Q = f.low, k = w, g = J, z = X, x = K, A = Y, y = L, U = Z, B = M, l = $, h = N, R = aa, C = O, S = ba, D = P, V = ca, E = Q, m = 0; 80 > m; m++) {\n        var s = v[m];if (16 > m) var j = s.high = a[d + 2 * m] | 0,\n            b = s.low = a[d + 2 * m + 1] | 0;else {\n          var j = v[m - 15],\n              b = j.high,\n              p = j.low,\n              j = (b >>> 1 | p << 31) ^ (b >>> 8 | p << 24) ^ b >>> 7,\n              p = (p >>> 1 | b << 31) ^ (p >>> 8 | b << 24) ^ (p >>> 7 | b << 25),\n              u = v[m - 2],\n              b = u.high,\n              c = u.low,\n              u = (b >>> 19 | c << 13) ^ (b << 3 | c >>> 29) ^ b >>> 6,\n              c = (c >>> 19 | b << 13) ^ (c << 3 | b >>> 29) ^ (c >>> 6 | b << 26),\n              b = v[m - 7],\n              W = b.high,\n              t = v[m - 16],\n              q = t.high,\n              t = t.low,\n              b = p + b.low,\n              j = j + W + (b >>> 0 < p >>> 0 ? 1 : 0),\n              b = b + c,\n              j = j + u + (b >>> 0 < c >>> 0 ? 1 : 0),\n              b = b + t,\n              j = j + q + (b >>> 0 < t >>> 0 ? 1 : 0);s.high = j;s.low = b;\n        }var W = l & R ^ ~l & S,\n            t = h & C ^ ~h & D,\n            s = k & z ^ k & A ^ z & A,\n            T = g & x ^ g & y ^ x & y,\n            p = (k >>> 28 | g << 4) ^ (k << 30 | g >>> 2) ^ (k << 25 | g >>> 7),\n            u = (g >>> 28 | k << 4) ^ (g << 30 | k >>> 2) ^ (g << 25 | k >>> 7),\n            c = ea[m],\n            fa = c.high,\n            da = c.low,\n            c = E + ((h >>> 14 | l << 18) ^ (h >>> 18 | l << 14) ^ (h << 23 | l >>> 9)),\n            q = V + ((l >>> 14 | h << 18) ^ (l >>> 18 | h << 14) ^ (l << 23 | h >>> 9)) + (c >>> 0 < E >>> 0 ? 1 : 0),\n            c = c + t,\n            q = q + W + (c >>> 0 < t >>> 0 ? 1 : 0),\n            c = c + da,\n            q = q + fa + (c >>> 0 < da >>> 0 ? 1 : 0),\n            c = c + b,\n            q = q + j + (c >>> 0 < b >>> 0 ? 1 : 0),\n            b = u + T,\n            s = p + s + (b >>> 0 < u >>> 0 ? 1 : 0),\n            V = S,\n            E = D,\n            S = R,\n            D = C,\n            R = l,\n            C = h,\n            h = B + c | 0,\n            l = U + q + (h >>> 0 < B >>> 0 ? 1 : 0) | 0,\n            U = A,\n            B = y,\n            A = z,\n            y = x,\n            z = k,\n            x = g,\n            g = c + b | 0,\n            k = q + s + (g >>> 0 < c >>> 0 ? 1 : 0) | 0;\n      }J = F.low = J + g;F.high = w + k + (J >>> 0 < g >>> 0 ? 1 : 0);K = e.low = K + x;e.high = X + z + (K >>> 0 < x >>> 0 ? 1 : 0);L = n.low = L + y;n.high = Y + A + (L >>> 0 < y >>> 0 ? 1 : 0);M = r.low = M + B;r.high = Z + U + (M >>> 0 < B >>> 0 ? 1 : 0);N = G.low = N + h;G.high = $ + l + (N >>> 0 < h >>> 0 ? 1 : 0);O = H.low = O + C;H.high = aa + R + (O >>> 0 < C >>> 0 ? 1 : 0);P = I.low = P + D;\n      I.high = ba + S + (P >>> 0 < D >>> 0 ? 1 : 0);Q = f.low = Q + E;f.high = ca + V + (Q >>> 0 < E >>> 0 ? 1 : 0);\n    }, _doFinalize: function _doFinalize() {\n      var a = this._data,\n          d = a.words,\n          f = 8 * this._nDataBytes,\n          e = 8 * a.sigBytes;d[e >>> 5] |= 128 << 24 - e % 32;d[(e + 128 >>> 10 << 5) + 30] = Math.floor(f / 4294967296);d[(e + 128 >>> 10 << 5) + 31] = f;a.sigBytes = 4 * d.length;this._process();return this._hash.toX32();\n    }, clone: function clone() {\n      var a = r.clone.call(this);a._hash = this._hash.clone();return a;\n    }, blockSize: 32 });n.SHA512 = r._createHelper(e);n.HmacSHA512 = r._createHmacHelper(e);\n})();\n\n/*\nCryptoJS v3.1.2 sha384-min.js\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto-js/wiki/License\n*/\n(function () {\n  var c = CryptoJS,\n      a = c.x64,\n      b = a.Word,\n      e = a.WordArray,\n      a = c.algo,\n      d = a.SHA512,\n      a = a.SHA384 = d.extend({ _doReset: function _doReset() {\n      this._hash = new e.init([new b.init(3418070365, 3238371032), new b.init(1654270250, 914150663), new b.init(2438529370, 812702999), new b.init(355462360, 4144912697), new b.init(1731405415, 4290775857), new b.init(2394180231, 1750603025), new b.init(3675008525, 1694076839), new b.init(1203062813, 3204075428)]);\n    }, _doFinalize: function _doFinalize() {\n      var a = d._doFinalize.call(this);a.sigBytes -= 16;return a;\n    } });c.SHA384 = d._createHelper(a);c.HmacSHA384 = d._createHmacHelper(a);\n})();\n\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar b64map = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";var b64pad = \"=\";function hex2b64(d) {\n  var b;var e;var a = \"\";for (b = 0; b + 3 <= d.length; b += 3) {\n    e = parseInt(d.substring(b, b + 3), 16);a += b64map.charAt(e >> 6) + b64map.charAt(e & 63);\n  }if (b + 1 == d.length) {\n    e = parseInt(d.substring(b, b + 1), 16);a += b64map.charAt(e << 2);\n  } else {\n    if (b + 2 == d.length) {\n      e = parseInt(d.substring(b, b + 2), 16);a += b64map.charAt(e >> 2) + b64map.charAt((e & 3) << 4);\n    }\n  }if (b64pad) {\n    while ((a.length & 3) > 0) {\n      a += b64pad;\n    }\n  }return a;\n}function b64tohex(f) {\n  var d = \"\";var e;var b = 0;var c;var a;for (e = 0; e < f.length; ++e) {\n    if (f.charAt(e) == b64pad) {\n      break;\n    }a = b64map.indexOf(f.charAt(e));if (a < 0) {\n      continue;\n    }if (b == 0) {\n      d += int2char(a >> 2);c = a & 3;b = 1;\n    } else {\n      if (b == 1) {\n        d += int2char(c << 2 | a >> 4);c = a & 15;b = 2;\n      } else {\n        if (b == 2) {\n          d += int2char(c);d += int2char(a >> 2);c = a & 3;b = 3;\n        } else {\n          d += int2char(c << 2 | a >> 4);d += int2char(a & 15);b = 0;\n        }\n      }\n    }\n  }if (b == 1) {\n    d += int2char(c << 2);\n  }return d;\n}function b64toBA(e) {\n  var d = b64tohex(e);var c;var b = new Array();for (c = 0; 2 * c < d.length; ++c) {\n    b[c] = parseInt(d.substring(2 * c, 2 * c + 2), 16);\n  }return b;\n};\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar dbits;var canary = 244837814094590;var j_lm = (canary & 16777215) == 15715070;function BigInteger(e, d, f) {\n  if (e != null) {\n    if (\"number\" == typeof e) {\n      this.fromNumber(e, d, f);\n    } else {\n      if (d == null && \"string\" != typeof e) {\n        this.fromString(e, 256);\n      } else {\n        this.fromString(e, d);\n      }\n    }\n  }\n}function nbi() {\n  return new BigInteger(null);\n}function am1(f, a, b, e, h, g) {\n  while (--g >= 0) {\n    var d = a * this[f++] + b[e] + h;h = Math.floor(d / 67108864);b[e++] = d & 67108863;\n  }return h;\n}function am2(f, q, r, e, o, a) {\n  var k = q & 32767,\n      p = q >> 15;while (--a >= 0) {\n    var d = this[f] & 32767;var g = this[f++] >> 15;var b = p * d + g * k;d = k * d + ((b & 32767) << 15) + r[e] + (o & 1073741823);o = (d >>> 30) + (b >>> 15) + p * g + (o >>> 30);r[e++] = d & 1073741823;\n  }return o;\n}function am3(f, q, r, e, o, a) {\n  var k = q & 16383,\n      p = q >> 14;while (--a >= 0) {\n    var d = this[f] & 16383;var g = this[f++] >> 14;var b = p * d + g * k;d = k * d + ((b & 16383) << 14) + r[e] + o;o = (d >> 28) + (b >> 14) + p * g;r[e++] = d & 268435455;\n  }return o;\n}if (j_lm && navigator.appName == \"Microsoft Internet Explorer\") {\n  BigInteger.prototype.am = am2;dbits = 30;\n} else {\n  if (j_lm && navigator.appName != \"Netscape\") {\n    BigInteger.prototype.am = am1;dbits = 26;\n  } else {\n    BigInteger.prototype.am = am3;dbits = 28;\n  }\n}BigInteger.prototype.DB = dbits;BigInteger.prototype.DM = (1 << dbits) - 1;BigInteger.prototype.DV = 1 << dbits;var BI_FP = 52;BigInteger.prototype.FV = Math.pow(2, BI_FP);BigInteger.prototype.F1 = BI_FP - dbits;BigInteger.prototype.F2 = 2 * dbits - BI_FP;var BI_RM = \"0123456789abcdefghijklmnopqrstuvwxyz\";var BI_RC = new Array();var rr, vv;rr = \"0\".charCodeAt(0);for (vv = 0; vv <= 9; ++vv) {\n  BI_RC[rr++] = vv;\n}rr = \"a\".charCodeAt(0);for (vv = 10; vv < 36; ++vv) {\n  BI_RC[rr++] = vv;\n}rr = \"A\".charCodeAt(0);for (vv = 10; vv < 36; ++vv) {\n  BI_RC[rr++] = vv;\n}function int2char(a) {\n  return BI_RM.charAt(a);\n}function intAt(b, a) {\n  var d = BI_RC[b.charCodeAt(a)];return d == null ? -1 : d;\n}function bnpCopyTo(b) {\n  for (var a = this.t - 1; a >= 0; --a) {\n    b[a] = this[a];\n  }b.t = this.t;b.s = this.s;\n}function bnpFromInt(a) {\n  this.t = 1;this.s = a < 0 ? -1 : 0;if (a > 0) {\n    this[0] = a;\n  } else {\n    if (a < -1) {\n      this[0] = a + this.DV;\n    } else {\n      this.t = 0;\n    }\n  }\n}function nbv(a) {\n  var b = nbi();b.fromInt(a);return b;\n}function bnpFromString(h, c) {\n  var e;if (c == 16) {\n    e = 4;\n  } else {\n    if (c == 8) {\n      e = 3;\n    } else {\n      if (c == 256) {\n        e = 8;\n      } else {\n        if (c == 2) {\n          e = 1;\n        } else {\n          if (c == 32) {\n            e = 5;\n          } else {\n            if (c == 4) {\n              e = 2;\n            } else {\n              this.fromRadix(h, c);return;\n            }\n          }\n        }\n      }\n    }\n  }this.t = 0;this.s = 0;var g = h.length,\n      d = false,\n      f = 0;while (--g >= 0) {\n    var a = e == 8 ? h[g] & 255 : intAt(h, g);if (a < 0) {\n      if (h.charAt(g) == \"-\") {\n        d = true;\n      }continue;\n    }d = false;if (f == 0) {\n      this[this.t++] = a;\n    } else {\n      if (f + e > this.DB) {\n        this[this.t - 1] |= (a & (1 << this.DB - f) - 1) << f;this[this.t++] = a >> this.DB - f;\n      } else {\n        this[this.t - 1] |= a << f;\n      }\n    }f += e;if (f >= this.DB) {\n      f -= this.DB;\n    }\n  }if (e == 8 && (h[0] & 128) != 0) {\n    this.s = -1;if (f > 0) {\n      this[this.t - 1] |= (1 << this.DB - f) - 1 << f;\n    }\n  }this.clamp();if (d) {\n    BigInteger.ZERO.subTo(this, this);\n  }\n}function bnpClamp() {\n  var a = this.s & this.DM;while (this.t > 0 && this[this.t - 1] == a) {\n    --this.t;\n  }\n}function bnToString(c) {\n  if (this.s < 0) {\n    return \"-\" + this.negate().toString(c);\n  }var e;if (c == 16) {\n    e = 4;\n  } else {\n    if (c == 8) {\n      e = 3;\n    } else {\n      if (c == 2) {\n        e = 1;\n      } else {\n        if (c == 32) {\n          e = 5;\n        } else {\n          if (c == 4) {\n            e = 2;\n          } else {\n            return this.toRadix(c);\n          }\n        }\n      }\n    }\n  }var g = (1 << e) - 1,\n      l,\n      a = false,\n      h = \"\",\n      f = this.t;var j = this.DB - f * this.DB % e;if (f-- > 0) {\n    if (j < this.DB && (l = this[f] >> j) > 0) {\n      a = true;h = int2char(l);\n    }while (f >= 0) {\n      if (j < e) {\n        l = (this[f] & (1 << j) - 1) << e - j;l |= this[--f] >> (j += this.DB - e);\n      } else {\n        l = this[f] >> (j -= e) & g;if (j <= 0) {\n          j += this.DB;--f;\n        }\n      }if (l > 0) {\n        a = true;\n      }if (a) {\n        h += int2char(l);\n      }\n    }\n  }return a ? h : \"0\";\n}function bnNegate() {\n  var a = nbi();BigInteger.ZERO.subTo(this, a);return a;\n}function bnAbs() {\n  return this.s < 0 ? this.negate() : this;\n}function bnCompareTo(b) {\n  var d = this.s - b.s;if (d != 0) {\n    return d;\n  }var c = this.t;d = c - b.t;if (d != 0) {\n    return this.s < 0 ? -d : d;\n  }while (--c >= 0) {\n    if ((d = this[c] - b[c]) != 0) {\n      return d;\n    }\n  }return 0;\n}function nbits(a) {\n  var c = 1,\n      b;if ((b = a >>> 16) != 0) {\n    a = b;c += 16;\n  }if ((b = a >> 8) != 0) {\n    a = b;c += 8;\n  }if ((b = a >> 4) != 0) {\n    a = b;c += 4;\n  }if ((b = a >> 2) != 0) {\n    a = b;c += 2;\n  }if ((b = a >> 1) != 0) {\n    a = b;c += 1;\n  }return c;\n}function bnBitLength() {\n  if (this.t <= 0) {\n    return 0;\n  }return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ this.s & this.DM);\n}function bnpDLShiftTo(c, b) {\n  var a;for (a = this.t - 1; a >= 0; --a) {\n    b[a + c] = this[a];\n  }for (a = c - 1; a >= 0; --a) {\n    b[a] = 0;\n  }b.t = this.t + c;b.s = this.s;\n}function bnpDRShiftTo(c, b) {\n  for (var a = c; a < this.t; ++a) {\n    b[a - c] = this[a];\n  }b.t = Math.max(this.t - c, 0);b.s = this.s;\n}function bnpLShiftTo(j, e) {\n  var b = j % this.DB;var a = this.DB - b;var g = (1 << a) - 1;var f = Math.floor(j / this.DB),\n      h = this.s << b & this.DM,\n      d;for (d = this.t - 1; d >= 0; --d) {\n    e[d + f + 1] = this[d] >> a | h;h = (this[d] & g) << b;\n  }for (d = f - 1; d >= 0; --d) {\n    e[d] = 0;\n  }e[f] = h;e.t = this.t + f + 1;e.s = this.s;e.clamp();\n}function bnpRShiftTo(g, d) {\n  d.s = this.s;var e = Math.floor(g / this.DB);if (e >= this.t) {\n    d.t = 0;return;\n  }var b = g % this.DB;var a = this.DB - b;var f = (1 << b) - 1;d[0] = this[e] >> b;for (var c = e + 1; c < this.t; ++c) {\n    d[c - e - 1] |= (this[c] & f) << a;d[c - e] = this[c] >> b;\n  }if (b > 0) {\n    d[this.t - e - 1] |= (this.s & f) << a;\n  }d.t = this.t - e;d.clamp();\n}function bnpSubTo(d, f) {\n  var e = 0,\n      g = 0,\n      b = Math.min(d.t, this.t);while (e < b) {\n    g += this[e] - d[e];f[e++] = g & this.DM;g >>= this.DB;\n  }if (d.t < this.t) {\n    g -= d.s;while (e < this.t) {\n      g += this[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += this.s;\n  } else {\n    g += this.s;while (e < d.t) {\n      g -= d[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g -= d.s;\n  }f.s = g < 0 ? -1 : 0;if (g < -1) {\n    f[e++] = this.DV + g;\n  } else {\n    if (g > 0) {\n      f[e++] = g;\n    }\n  }f.t = e;f.clamp();\n}function bnpMultiplyTo(c, e) {\n  var b = this.abs(),\n      f = c.abs();var d = b.t;e.t = d + f.t;while (--d >= 0) {\n    e[d] = 0;\n  }for (d = 0; d < f.t; ++d) {\n    e[d + b.t] = b.am(0, f[d], e, d, 0, b.t);\n  }e.s = 0;e.clamp();if (this.s != c.s) {\n    BigInteger.ZERO.subTo(e, e);\n  }\n}function bnpSquareTo(d) {\n  var a = this.abs();var b = d.t = 2 * a.t;while (--b >= 0) {\n    d[b] = 0;\n  }for (b = 0; b < a.t - 1; ++b) {\n    var e = a.am(b, a[b], d, 2 * b, 0, 1);if ((d[b + a.t] += a.am(b + 1, 2 * a[b], d, 2 * b + 1, e, a.t - b - 1)) >= a.DV) {\n      d[b + a.t] -= a.DV;d[b + a.t + 1] = 1;\n    }\n  }if (d.t > 0) {\n    d[d.t - 1] += a.am(b, a[b], d, 2 * b, 0, 1);\n  }d.s = 0;d.clamp();\n}function bnpDivRemTo(n, h, g) {\n  var w = n.abs();if (w.t <= 0) {\n    return;\n  }var k = this.abs();if (k.t < w.t) {\n    if (h != null) {\n      h.fromInt(0);\n    }if (g != null) {\n      this.copyTo(g);\n    }return;\n  }if (g == null) {\n    g = nbi();\n  }var d = nbi(),\n      a = this.s,\n      l = n.s;var v = this.DB - nbits(w[w.t - 1]);if (v > 0) {\n    w.lShiftTo(v, d);k.lShiftTo(v, g);\n  } else {\n    w.copyTo(d);k.copyTo(g);\n  }var p = d.t;var b = d[p - 1];if (b == 0) {\n    return;\n  }var o = b * (1 << this.F1) + (p > 1 ? d[p - 2] >> this.F2 : 0);var A = this.FV / o,\n      z = (1 << this.F1) / o,\n      x = 1 << this.F2;var u = g.t,\n      s = u - p,\n      f = h == null ? nbi() : h;d.dlShiftTo(s, f);if (g.compareTo(f) >= 0) {\n    g[g.t++] = 1;g.subTo(f, g);\n  }BigInteger.ONE.dlShiftTo(p, f);f.subTo(d, d);while (d.t < p) {\n    d[d.t++] = 0;\n  }while (--s >= 0) {\n    var c = g[--u] == b ? this.DM : Math.floor(g[u] * A + (g[u - 1] + x) * z);if ((g[u] += d.am(0, c, g, s, 0, p)) < c) {\n      d.dlShiftTo(s, f);g.subTo(f, g);while (g[u] < --c) {\n        g.subTo(f, g);\n      }\n    }\n  }if (h != null) {\n    g.drShiftTo(p, h);if (a != l) {\n      BigInteger.ZERO.subTo(h, h);\n    }\n  }g.t = p;g.clamp();if (v > 0) {\n    g.rShiftTo(v, g);\n  }if (a < 0) {\n    BigInteger.ZERO.subTo(g, g);\n  }\n}function bnMod(b) {\n  var c = nbi();this.abs().divRemTo(b, null, c);if (this.s < 0 && c.compareTo(BigInteger.ZERO) > 0) {\n    b.subTo(c, c);\n  }return c;\n}function Classic(a) {\n  this.m = a;\n}function cConvert(a) {\n  if (a.s < 0 || a.compareTo(this.m) >= 0) {\n    return a.mod(this.m);\n  } else {\n    return a;\n  }\n}function cRevert(a) {\n  return a;\n}function cReduce(a) {\n  a.divRemTo(this.m, null, a);\n}function cMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}function cSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}Classic.prototype.convert = cConvert;Classic.prototype.revert = cRevert;Classic.prototype.reduce = cReduce;Classic.prototype.mulTo = cMulTo;Classic.prototype.sqrTo = cSqrTo;function bnpInvDigit() {\n  if (this.t < 1) {\n    return 0;\n  }var a = this[0];if ((a & 1) == 0) {\n    return 0;\n  }var b = a & 3;b = b * (2 - (a & 15) * b) & 15;b = b * (2 - (a & 255) * b) & 255;b = b * (2 - ((a & 65535) * b & 65535)) & 65535;b = b * (2 - a * b % this.DV) % this.DV;return b > 0 ? this.DV - b : -b;\n}function Montgomery(a) {\n  this.m = a;this.mp = a.invDigit();this.mpl = this.mp & 32767;this.mph = this.mp >> 15;this.um = (1 << a.DB - 15) - 1;this.mt2 = 2 * a.t;\n}function montConvert(a) {\n  var b = nbi();a.abs().dlShiftTo(this.m.t, b);b.divRemTo(this.m, null, b);if (a.s < 0 && b.compareTo(BigInteger.ZERO) > 0) {\n    this.m.subTo(b, b);\n  }return b;\n}function montRevert(a) {\n  var b = nbi();a.copyTo(b);this.reduce(b);return b;\n}function montReduce(a) {\n  while (a.t <= this.mt2) {\n    a[a.t++] = 0;\n  }for (var c = 0; c < this.m.t; ++c) {\n    var b = a[c] & 32767;var d = b * this.mpl + ((b * this.mph + (a[c] >> 15) * this.mpl & this.um) << 15) & a.DM;b = c + this.m.t;a[b] += this.m.am(0, d, a, c, 0, this.m.t);while (a[b] >= a.DV) {\n      a[b] -= a.DV;a[++b]++;\n    }\n  }a.clamp();a.drShiftTo(this.m.t, a);if (a.compareTo(this.m) >= 0) {\n    a.subTo(this.m, a);\n  }\n}function montSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}function montMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}Montgomery.prototype.convert = montConvert;Montgomery.prototype.revert = montRevert;Montgomery.prototype.reduce = montReduce;Montgomery.prototype.mulTo = montMulTo;Montgomery.prototype.sqrTo = montSqrTo;function bnpIsEven() {\n  return (this.t > 0 ? this[0] & 1 : this.s) == 0;\n}function bnpExp(h, j) {\n  if (h > 4294967295 || h < 1) {\n    return BigInteger.ONE;\n  }var f = nbi(),\n      a = nbi(),\n      d = j.convert(this),\n      c = nbits(h) - 1;d.copyTo(f);while (--c >= 0) {\n    j.sqrTo(f, a);if ((h & 1 << c) > 0) {\n      j.mulTo(a, d, f);\n    } else {\n      var b = f;f = a;a = b;\n    }\n  }return j.revert(f);\n}function bnModPowInt(b, a) {\n  var c;if (b < 256 || a.isEven()) {\n    c = new Classic(a);\n  } else {\n    c = new Montgomery(a);\n  }return this.exp(b, c);\n}BigInteger.prototype.copyTo = bnpCopyTo;BigInteger.prototype.fromInt = bnpFromInt;BigInteger.prototype.fromString = bnpFromString;BigInteger.prototype.clamp = bnpClamp;BigInteger.prototype.dlShiftTo = bnpDLShiftTo;BigInteger.prototype.drShiftTo = bnpDRShiftTo;BigInteger.prototype.lShiftTo = bnpLShiftTo;BigInteger.prototype.rShiftTo = bnpRShiftTo;BigInteger.prototype.subTo = bnpSubTo;BigInteger.prototype.multiplyTo = bnpMultiplyTo;BigInteger.prototype.squareTo = bnpSquareTo;BigInteger.prototype.divRemTo = bnpDivRemTo;BigInteger.prototype.invDigit = bnpInvDigit;BigInteger.prototype.isEven = bnpIsEven;BigInteger.prototype.exp = bnpExp;BigInteger.prototype.toString = bnToString;BigInteger.prototype.negate = bnNegate;BigInteger.prototype.abs = bnAbs;BigInteger.prototype.compareTo = bnCompareTo;BigInteger.prototype.bitLength = bnBitLength;BigInteger.prototype.mod = bnMod;BigInteger.prototype.modPowInt = bnModPowInt;BigInteger.ZERO = nbv(0);BigInteger.ONE = nbv(1);\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction bnClone() {\n  var a = nbi();this.copyTo(a);return a;\n}function bnIntValue() {\n  if (this.s < 0) {\n    if (this.t == 1) {\n      return this[0] - this.DV;\n    } else {\n      if (this.t == 0) {\n        return -1;\n      }\n    }\n  } else {\n    if (this.t == 1) {\n      return this[0];\n    } else {\n      if (this.t == 0) {\n        return 0;\n      }\n    }\n  }return (this[1] & (1 << 32 - this.DB) - 1) << this.DB | this[0];\n}function bnByteValue() {\n  return this.t == 0 ? this.s : this[0] << 24 >> 24;\n}function bnShortValue() {\n  return this.t == 0 ? this.s : this[0] << 16 >> 16;\n}function bnpChunkSize(a) {\n  return Math.floor(Math.LN2 * this.DB / Math.log(a));\n}function bnSigNum() {\n  if (this.s < 0) {\n    return -1;\n  } else {\n    if (this.t <= 0 || this.t == 1 && this[0] <= 0) {\n      return 0;\n    } else {\n      return 1;\n    }\n  }\n}function bnpToRadix(c) {\n  if (c == null) {\n    c = 10;\n  }if (this.signum() == 0 || c < 2 || c > 36) {\n    return \"0\";\n  }var f = this.chunkSize(c);var e = Math.pow(c, f);var i = nbv(e),\n      j = nbi(),\n      h = nbi(),\n      g = \"\";this.divRemTo(i, j, h);while (j.signum() > 0) {\n    g = (e + h.intValue()).toString(c).substr(1) + g;j.divRemTo(i, j, h);\n  }return h.intValue().toString(c) + g;\n}function bnpFromRadix(m, h) {\n  this.fromInt(0);if (h == null) {\n    h = 10;\n  }var f = this.chunkSize(h);var g = Math.pow(h, f),\n      e = false,\n      a = 0,\n      l = 0;for (var c = 0; c < m.length; ++c) {\n    var k = intAt(m, c);if (k < 0) {\n      if (m.charAt(c) == \"-\" && this.signum() == 0) {\n        e = true;\n      }continue;\n    }l = h * l + k;if (++a >= f) {\n      this.dMultiply(g);this.dAddOffset(l, 0);a = 0;l = 0;\n    }\n  }if (a > 0) {\n    this.dMultiply(Math.pow(h, a));this.dAddOffset(l, 0);\n  }if (e) {\n    BigInteger.ZERO.subTo(this, this);\n  }\n}function bnpFromNumber(f, e, h) {\n  if (\"number\" == typeof e) {\n    if (f < 2) {\n      this.fromInt(1);\n    } else {\n      this.fromNumber(f, h);if (!this.testBit(f - 1)) {\n        this.bitwiseTo(BigInteger.ONE.shiftLeft(f - 1), op_or, this);\n      }if (this.isEven()) {\n        this.dAddOffset(1, 0);\n      }while (!this.isProbablePrime(e)) {\n        this.dAddOffset(2, 0);if (this.bitLength() > f) {\n          this.subTo(BigInteger.ONE.shiftLeft(f - 1), this);\n        }\n      }\n    }\n  } else {\n    var d = new Array(),\n        g = f & 7;d.length = (f >> 3) + 1;e.nextBytes(d);if (g > 0) {\n      d[0] &= (1 << g) - 1;\n    } else {\n      d[0] = 0;\n    }this.fromString(d, 256);\n  }\n}function bnToByteArray() {\n  var b = this.t,\n      c = new Array();c[0] = this.s;var e = this.DB - b * this.DB % 8,\n      f,\n      a = 0;if (b-- > 0) {\n    if (e < this.DB && (f = this[b] >> e) != (this.s & this.DM) >> e) {\n      c[a++] = f | this.s << this.DB - e;\n    }while (b >= 0) {\n      if (e < 8) {\n        f = (this[b] & (1 << e) - 1) << 8 - e;f |= this[--b] >> (e += this.DB - 8);\n      } else {\n        f = this[b] >> (e -= 8) & 255;if (e <= 0) {\n          e += this.DB;--b;\n        }\n      }if ((f & 128) != 0) {\n        f |= -256;\n      }if (a == 0 && (this.s & 128) != (f & 128)) {\n        ++a;\n      }if (a > 0 || f != this.s) {\n        c[a++] = f;\n      }\n    }\n  }return c;\n}function bnEquals(b) {\n  return this.compareTo(b) == 0;\n}function bnMin(b) {\n  return this.compareTo(b) < 0 ? this : b;\n}function bnMax(b) {\n  return this.compareTo(b) > 0 ? this : b;\n}function bnpBitwiseTo(c, h, e) {\n  var d,\n      g,\n      b = Math.min(c.t, this.t);for (d = 0; d < b; ++d) {\n    e[d] = h(this[d], c[d]);\n  }if (c.t < this.t) {\n    g = c.s & this.DM;for (d = b; d < this.t; ++d) {\n      e[d] = h(this[d], g);\n    }e.t = this.t;\n  } else {\n    g = this.s & this.DM;for (d = b; d < c.t; ++d) {\n      e[d] = h(g, c[d]);\n    }e.t = c.t;\n  }e.s = h(this.s, c.s);e.clamp();\n}function op_and(a, b) {\n  return a & b;\n}function bnAnd(b) {\n  var c = nbi();this.bitwiseTo(b, op_and, c);return c;\n}function op_or(a, b) {\n  return a | b;\n}function bnOr(b) {\n  var c = nbi();this.bitwiseTo(b, op_or, c);return c;\n}function op_xor(a, b) {\n  return a ^ b;\n}function bnXor(b) {\n  var c = nbi();this.bitwiseTo(b, op_xor, c);return c;\n}function op_andnot(a, b) {\n  return a & ~b;\n}function bnAndNot(b) {\n  var c = nbi();this.bitwiseTo(b, op_andnot, c);return c;\n}function bnNot() {\n  var b = nbi();for (var a = 0; a < this.t; ++a) {\n    b[a] = this.DM & ~this[a];\n  }b.t = this.t;b.s = ~this.s;return b;\n}function bnShiftLeft(b) {\n  var a = nbi();if (b < 0) {\n    this.rShiftTo(-b, a);\n  } else {\n    this.lShiftTo(b, a);\n  }return a;\n}function bnShiftRight(b) {\n  var a = nbi();if (b < 0) {\n    this.lShiftTo(-b, a);\n  } else {\n    this.rShiftTo(b, a);\n  }return a;\n}function lbit(a) {\n  if (a == 0) {\n    return -1;\n  }var b = 0;if ((a & 65535) == 0) {\n    a >>= 16;b += 16;\n  }if ((a & 255) == 0) {\n    a >>= 8;b += 8;\n  }if ((a & 15) == 0) {\n    a >>= 4;b += 4;\n  }if ((a & 3) == 0) {\n    a >>= 2;b += 2;\n  }if ((a & 1) == 0) {\n    ++b;\n  }return b;\n}function bnGetLowestSetBit() {\n  for (var a = 0; a < this.t; ++a) {\n    if (this[a] != 0) {\n      return a * this.DB + lbit(this[a]);\n    }\n  }if (this.s < 0) {\n    return this.t * this.DB;\n  }return -1;\n}function cbit(a) {\n  var b = 0;while (a != 0) {\n    a &= a - 1;++b;\n  }return b;\n}function bnBitCount() {\n  var c = 0,\n      a = this.s & this.DM;for (var b = 0; b < this.t; ++b) {\n    c += cbit(this[b] ^ a);\n  }return c;\n}function bnTestBit(b) {\n  var a = Math.floor(b / this.DB);if (a >= this.t) {\n    return this.s != 0;\n  }return (this[a] & 1 << b % this.DB) != 0;\n}function bnpChangeBit(c, b) {\n  var a = BigInteger.ONE.shiftLeft(c);this.bitwiseTo(a, b, a);return a;\n}function bnSetBit(a) {\n  return this.changeBit(a, op_or);\n}function bnClearBit(a) {\n  return this.changeBit(a, op_andnot);\n}function bnFlipBit(a) {\n  return this.changeBit(a, op_xor);\n}function bnpAddTo(d, f) {\n  var e = 0,\n      g = 0,\n      b = Math.min(d.t, this.t);while (e < b) {\n    g += this[e] + d[e];f[e++] = g & this.DM;g >>= this.DB;\n  }if (d.t < this.t) {\n    g += d.s;while (e < this.t) {\n      g += this[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += this.s;\n  } else {\n    g += this.s;while (e < d.t) {\n      g += d[e];f[e++] = g & this.DM;g >>= this.DB;\n    }g += d.s;\n  }f.s = g < 0 ? -1 : 0;if (g > 0) {\n    f[e++] = g;\n  } else {\n    if (g < -1) {\n      f[e++] = this.DV + g;\n    }\n  }f.t = e;f.clamp();\n}function bnAdd(b) {\n  var c = nbi();this.addTo(b, c);return c;\n}function bnSubtract(b) {\n  var c = nbi();this.subTo(b, c);return c;\n}function bnMultiply(b) {\n  var c = nbi();this.multiplyTo(b, c);return c;\n}function bnSquare() {\n  var a = nbi();this.squareTo(a);return a;\n}function bnDivide(b) {\n  var c = nbi();this.divRemTo(b, c, null);return c;\n}function bnRemainder(b) {\n  var c = nbi();this.divRemTo(b, null, c);return c;\n}function bnDivideAndRemainder(b) {\n  var d = nbi(),\n      c = nbi();this.divRemTo(b, d, c);return new Array(d, c);\n}function bnpDMultiply(a) {\n  this[this.t] = this.am(0, a - 1, this, 0, 0, this.t);++this.t;this.clamp();\n}function bnpDAddOffset(b, a) {\n  if (b == 0) {\n    return;\n  }while (this.t <= a) {\n    this[this.t++] = 0;\n  }this[a] += b;while (this[a] >= this.DV) {\n    this[a] -= this.DV;if (++a >= this.t) {\n      this[this.t++] = 0;\n    }++this[a];\n  }\n}function NullExp() {}function nNop(a) {\n  return a;\n}function nMulTo(a, c, b) {\n  a.multiplyTo(c, b);\n}function nSqrTo(a, b) {\n  a.squareTo(b);\n}NullExp.prototype.convert = nNop;NullExp.prototype.revert = nNop;NullExp.prototype.mulTo = nMulTo;NullExp.prototype.sqrTo = nSqrTo;function bnPow(a) {\n  return this.exp(a, new NullExp());\n}function bnpMultiplyLowerTo(b, f, e) {\n  var d = Math.min(this.t + b.t, f);e.s = 0;e.t = d;while (d > 0) {\n    e[--d] = 0;\n  }var c;for (c = e.t - this.t; d < c; ++d) {\n    e[d + this.t] = this.am(0, b[d], e, d, 0, this.t);\n  }for (c = Math.min(b.t, f); d < c; ++d) {\n    this.am(0, b[d], e, d, 0, f - d);\n  }e.clamp();\n}function bnpMultiplyUpperTo(b, e, d) {\n  --e;var c = d.t = this.t + b.t - e;d.s = 0;while (--c >= 0) {\n    d[c] = 0;\n  }for (c = Math.max(e - this.t, 0); c < b.t; ++c) {\n    d[this.t + c - e] = this.am(e - c, b[c], d, 0, 0, this.t + c - e);\n  }d.clamp();d.drShiftTo(1, d);\n}function Barrett(a) {\n  this.r2 = nbi();this.q3 = nbi();BigInteger.ONE.dlShiftTo(2 * a.t, this.r2);this.mu = this.r2.divide(a);this.m = a;\n}function barrettConvert(a) {\n  if (a.s < 0 || a.t > 2 * this.m.t) {\n    return a.mod(this.m);\n  } else {\n    if (a.compareTo(this.m) < 0) {\n      return a;\n    } else {\n      var b = nbi();a.copyTo(b);this.reduce(b);return b;\n    }\n  }\n}function barrettRevert(a) {\n  return a;\n}function barrettReduce(a) {\n  a.drShiftTo(this.m.t - 1, this.r2);if (a.t > this.m.t + 1) {\n    a.t = this.m.t + 1;a.clamp();\n  }this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);while (a.compareTo(this.r2) < 0) {\n    a.dAddOffset(1, this.m.t + 1);\n  }a.subTo(this.r2, a);while (a.compareTo(this.m) >= 0) {\n    a.subTo(this.m, a);\n  }\n}function barrettSqrTo(a, b) {\n  a.squareTo(b);this.reduce(b);\n}function barrettMulTo(a, c, b) {\n  a.multiplyTo(c, b);this.reduce(b);\n}Barrett.prototype.convert = barrettConvert;Barrett.prototype.revert = barrettRevert;Barrett.prototype.reduce = barrettReduce;Barrett.prototype.mulTo = barrettMulTo;Barrett.prototype.sqrTo = barrettSqrTo;function bnModPow(q, f) {\n  var o = q.bitLength(),\n      h,\n      b = nbv(1),\n      v;if (o <= 0) {\n    return b;\n  } else {\n    if (o < 18) {\n      h = 1;\n    } else {\n      if (o < 48) {\n        h = 3;\n      } else {\n        if (o < 144) {\n          h = 4;\n        } else {\n          if (o < 768) {\n            h = 5;\n          } else {\n            h = 6;\n          }\n        }\n      }\n    }\n  }if (o < 8) {\n    v = new Classic(f);\n  } else {\n    if (f.isEven()) {\n      v = new Barrett(f);\n    } else {\n      v = new Montgomery(f);\n    }\n  }var p = new Array(),\n      d = 3,\n      s = h - 1,\n      a = (1 << h) - 1;p[1] = v.convert(this);if (h > 1) {\n    var A = nbi();v.sqrTo(p[1], A);while (d <= a) {\n      p[d] = nbi();v.mulTo(A, p[d - 2], p[d]);d += 2;\n    }\n  }var l = q.t - 1,\n      x,\n      u = true,\n      c = nbi(),\n      y;o = nbits(q[l]) - 1;while (l >= 0) {\n    if (o >= s) {\n      x = q[l] >> o - s & a;\n    } else {\n      x = (q[l] & (1 << o + 1) - 1) << s - o;if (l > 0) {\n        x |= q[l - 1] >> this.DB + o - s;\n      }\n    }d = h;while ((x & 1) == 0) {\n      x >>= 1;--d;\n    }if ((o -= d) < 0) {\n      o += this.DB;--l;\n    }if (u) {\n      p[x].copyTo(b);u = false;\n    } else {\n      while (d > 1) {\n        v.sqrTo(b, c);v.sqrTo(c, b);d -= 2;\n      }if (d > 0) {\n        v.sqrTo(b, c);\n      } else {\n        y = b;b = c;c = y;\n      }v.mulTo(c, p[x], b);\n    }while (l >= 0 && (q[l] & 1 << o) == 0) {\n      v.sqrTo(b, c);y = b;b = c;c = y;if (--o < 0) {\n        o = this.DB - 1;--l;\n      }\n    }\n  }return v.revert(b);\n}function bnGCD(c) {\n  var b = this.s < 0 ? this.negate() : this.clone();var h = c.s < 0 ? c.negate() : c.clone();if (b.compareTo(h) < 0) {\n    var e = b;b = h;h = e;\n  }var d = b.getLowestSetBit(),\n      f = h.getLowestSetBit();if (f < 0) {\n    return b;\n  }if (d < f) {\n    f = d;\n  }if (f > 0) {\n    b.rShiftTo(f, b);h.rShiftTo(f, h);\n  }while (b.signum() > 0) {\n    if ((d = b.getLowestSetBit()) > 0) {\n      b.rShiftTo(d, b);\n    }if ((d = h.getLowestSetBit()) > 0) {\n      h.rShiftTo(d, h);\n    }if (b.compareTo(h) >= 0) {\n      b.subTo(h, b);b.rShiftTo(1, b);\n    } else {\n      h.subTo(b, h);h.rShiftTo(1, h);\n    }\n  }if (f > 0) {\n    h.lShiftTo(f, h);\n  }return h;\n}function bnpModInt(e) {\n  if (e <= 0) {\n    return 0;\n  }var c = this.DV % e,\n      b = this.s < 0 ? e - 1 : 0;if (this.t > 0) {\n    if (c == 0) {\n      b = this[0] % e;\n    } else {\n      for (var a = this.t - 1; a >= 0; --a) {\n        b = (c * b + this[a]) % e;\n      }\n    }\n  }return b;\n}function bnModInverse(f) {\n  var j = f.isEven();if (this.isEven() && j || f.signum() == 0) {\n    return BigInteger.ZERO;\n  }var i = f.clone(),\n      h = this.clone();var g = nbv(1),\n      e = nbv(0),\n      l = nbv(0),\n      k = nbv(1);while (i.signum() != 0) {\n    while (i.isEven()) {\n      i.rShiftTo(1, i);if (j) {\n        if (!g.isEven() || !e.isEven()) {\n          g.addTo(this, g);e.subTo(f, e);\n        }g.rShiftTo(1, g);\n      } else {\n        if (!e.isEven()) {\n          e.subTo(f, e);\n        }\n      }e.rShiftTo(1, e);\n    }while (h.isEven()) {\n      h.rShiftTo(1, h);if (j) {\n        if (!l.isEven() || !k.isEven()) {\n          l.addTo(this, l);k.subTo(f, k);\n        }l.rShiftTo(1, l);\n      } else {\n        if (!k.isEven()) {\n          k.subTo(f, k);\n        }\n      }k.rShiftTo(1, k);\n    }if (i.compareTo(h) >= 0) {\n      i.subTo(h, i);if (j) {\n        g.subTo(l, g);\n      }e.subTo(k, e);\n    } else {\n      h.subTo(i, h);if (j) {\n        l.subTo(g, l);\n      }k.subTo(e, k);\n    }\n  }if (h.compareTo(BigInteger.ONE) != 0) {\n    return BigInteger.ZERO;\n  }if (k.compareTo(f) >= 0) {\n    return k.subtract(f);\n  }if (k.signum() < 0) {\n    k.addTo(f, k);\n  } else {\n    return k;\n  }if (k.signum() < 0) {\n    return k.add(f);\n  } else {\n    return k;\n  }\n}var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];function bnIsProbablePrime(e) {\n  var d,\n      b = this.abs();if (b.t == 1 && b[0] <= lowprimes[lowprimes.length - 1]) {\n    for (d = 0; d < lowprimes.length; ++d) {\n      if (b[0] == lowprimes[d]) {\n        return true;\n      }\n    }return false;\n  }if (b.isEven()) {\n    return false;\n  }d = 1;while (d < lowprimes.length) {\n    var a = lowprimes[d],\n        c = d + 1;while (c < lowprimes.length && a < lplim) {\n      a *= lowprimes[c++];\n    }a = b.modInt(a);while (d < c) {\n      if (a % lowprimes[d++] == 0) {\n        return false;\n      }\n    }\n  }return b.millerRabin(e);\n}function bnpMillerRabin(f) {\n  var g = this.subtract(BigInteger.ONE);var c = g.getLowestSetBit();if (c <= 0) {\n    return false;\n  }var h = g.shiftRight(c);f = f + 1 >> 1;if (f > lowprimes.length) {\n    f = lowprimes.length;\n  }var b = nbi();for (var e = 0; e < f; ++e) {\n    b.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);var l = b.modPow(h, this);if (l.compareTo(BigInteger.ONE) != 0 && l.compareTo(g) != 0) {\n      var d = 1;while (d++ < c && l.compareTo(g) != 0) {\n        l = l.modPowInt(2, this);if (l.compareTo(BigInteger.ONE) == 0) {\n          return false;\n        }\n      }if (l.compareTo(g) != 0) {\n        return false;\n      }\n    }\n  }return true;\n}BigInteger.prototype.chunkSize = bnpChunkSize;BigInteger.prototype.toRadix = bnpToRadix;BigInteger.prototype.fromRadix = bnpFromRadix;BigInteger.prototype.fromNumber = bnpFromNumber;BigInteger.prototype.bitwiseTo = bnpBitwiseTo;BigInteger.prototype.changeBit = bnpChangeBit;BigInteger.prototype.addTo = bnpAddTo;BigInteger.prototype.dMultiply = bnpDMultiply;BigInteger.prototype.dAddOffset = bnpDAddOffset;BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;BigInteger.prototype.modInt = bnpModInt;BigInteger.prototype.millerRabin = bnpMillerRabin;BigInteger.prototype.clone = bnClone;BigInteger.prototype.intValue = bnIntValue;BigInteger.prototype.byteValue = bnByteValue;BigInteger.prototype.shortValue = bnShortValue;BigInteger.prototype.signum = bnSigNum;BigInteger.prototype.toByteArray = bnToByteArray;BigInteger.prototype.equals = bnEquals;BigInteger.prototype.min = bnMin;BigInteger.prototype.max = bnMax;BigInteger.prototype.and = bnAnd;BigInteger.prototype.or = bnOr;BigInteger.prototype.xor = bnXor;BigInteger.prototype.andNot = bnAndNot;BigInteger.prototype.not = bnNot;BigInteger.prototype.shiftLeft = bnShiftLeft;BigInteger.prototype.shiftRight = bnShiftRight;BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;BigInteger.prototype.bitCount = bnBitCount;BigInteger.prototype.testBit = bnTestBit;BigInteger.prototype.setBit = bnSetBit;BigInteger.prototype.clearBit = bnClearBit;BigInteger.prototype.flipBit = bnFlipBit;BigInteger.prototype.add = bnAdd;BigInteger.prototype.subtract = bnSubtract;BigInteger.prototype.multiply = bnMultiply;BigInteger.prototype.divide = bnDivide;BigInteger.prototype.remainder = bnRemainder;BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;BigInteger.prototype.modPow = bnModPow;BigInteger.prototype.modInverse = bnModInverse;BigInteger.prototype.pow = bnPow;BigInteger.prototype.gcd = bnGCD;BigInteger.prototype.isProbablePrime = bnIsProbablePrime;BigInteger.prototype.square = bnSquare;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction Arcfour() {\n  this.i = 0;this.j = 0;this.S = new Array();\n}function ARC4init(d) {\n  var c, a, b;for (c = 0; c < 256; ++c) {\n    this.S[c] = c;\n  }a = 0;for (c = 0; c < 256; ++c) {\n    a = a + this.S[c] + d[c % d.length] & 255;b = this.S[c];this.S[c] = this.S[a];this.S[a] = b;\n  }this.i = 0;this.j = 0;\n}function ARC4next() {\n  var a;this.i = this.i + 1 & 255;this.j = this.j + this.S[this.i] & 255;a = this.S[this.i];this.S[this.i] = this.S[this.j];this.S[this.j] = a;return this.S[a + this.S[this.i] & 255];\n}Arcfour.prototype.init = ARC4init;Arcfour.prototype.next = ARC4next;function prng_newstate() {\n  return new Arcfour();\n}var rng_psize = 256;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nvar rng_state;var rng_pool;var rng_pptr;function rng_seed_int(a) {\n  rng_pool[rng_pptr++] ^= a & 255;rng_pool[rng_pptr++] ^= a >> 8 & 255;rng_pool[rng_pptr++] ^= a >> 16 & 255;rng_pool[rng_pptr++] ^= a >> 24 & 255;if (rng_pptr >= rng_psize) {\n    rng_pptr -= rng_psize;\n  }\n}function rng_seed_time() {\n  rng_seed_int(new Date().getTime());\n}if (rng_pool == null) {\n  rng_pool = new Array();rng_pptr = 0;var t;if (window !== undefined && (window.crypto !== undefined || window.msCrypto !== undefined)) {\n    var crypto = window.crypto || window.msCrypto;if (crypto.getRandomValues) {\n      var ua = new Uint8Array(32);crypto.getRandomValues(ua);for (t = 0; t < 32; ++t) {\n        rng_pool[rng_pptr++] = ua[t];\n      }\n    } else {\n      if (navigator.appName == \"Netscape\" && navigator.appVersion < \"5\") {\n        var z = window.crypto.random(32);for (t = 0; t < z.length; ++t) {\n          rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;\n        }\n      }\n    }\n  }while (rng_pptr < rng_psize) {\n    t = Math.floor(65536 * Math.random());rng_pool[rng_pptr++] = t >>> 8;rng_pool[rng_pptr++] = t & 255;\n  }rng_pptr = 0;rng_seed_time();\n}function rng_get_byte() {\n  if (rng_state == null) {\n    rng_seed_time();rng_state = prng_newstate();rng_state.init(rng_pool);for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {\n      rng_pool[rng_pptr] = 0;\n    }rng_pptr = 0;\n  }return rng_state.next();\n}function rng_get_bytes(b) {\n  var a;for (a = 0; a < b.length; ++a) {\n    b[a] = rng_get_byte();\n  }\n}function SecureRandom() {}SecureRandom.prototype.nextBytes = rng_get_bytes;\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction parseBigInt(b, a) {\n  return new BigInteger(b, a);\n}function linebrk(c, d) {\n  var a = \"\";var b = 0;while (b + d < c.length) {\n    a += c.substring(b, b + d) + \"\\n\";b += d;\n  }return a + c.substring(b, c.length);\n}function byte2Hex(a) {\n  if (a < 16) {\n    return \"0\" + a.toString(16);\n  } else {\n    return a.toString(16);\n  }\n}function pkcs1pad2(e, h) {\n  if (h < e.length + 11) {\n    throw \"Message too long for RSA\";return null;\n  }var g = new Array();var d = e.length - 1;while (d >= 0 && h > 0) {\n    var f = e.charCodeAt(d--);if (f < 128) {\n      g[--h] = f;\n    } else {\n      if (f > 127 && f < 2048) {\n        g[--h] = f & 63 | 128;g[--h] = f >> 6 | 192;\n      } else {\n        g[--h] = f & 63 | 128;g[--h] = f >> 6 & 63 | 128;g[--h] = f >> 12 | 224;\n      }\n    }\n  }g[--h] = 0;var b = new SecureRandom();var a = new Array();while (h > 2) {\n    a[0] = 0;while (a[0] == 0) {\n      b.nextBytes(a);\n    }g[--h] = a[0];\n  }g[--h] = 2;g[--h] = 0;return new BigInteger(g);\n}function oaep_mgf1_arr(c, a, e) {\n  var b = \"\",\n      d = 0;while (b.length < a) {\n    b += e(String.fromCharCode.apply(String, c.concat([(d & 4278190080) >> 24, (d & 16711680) >> 16, (d & 65280) >> 8, d & 255])));d += 1;\n  }return b;\n}function oaep_pad(q, a, f, l) {\n  var c = KJUR.crypto.MessageDigest;var o = KJUR.crypto.Util;var b = null;if (!f) {\n    f = \"sha1\";\n  }if (typeof f === \"string\") {\n    b = c.getCanonicalAlgName(f);l = c.getHashLength(b);f = function f(i) {\n      return hextorstr(o.hashHex(rstrtohex(i), b));\n    };\n  }if (q.length + 2 * l + 2 > a) {\n    throw \"Message too long for RSA\";\n  }var k = \"\",\n      e;for (e = 0; e < a - q.length - 2 * l - 2; e += 1) {\n    k += \"\\x00\";\n  }var h = f(\"\") + k + \"\\x01\" + q;var g = new Array(l);new SecureRandom().nextBytes(g);var j = oaep_mgf1_arr(g, h.length, f);var p = [];for (e = 0; e < h.length; e += 1) {\n    p[e] = h.charCodeAt(e) ^ j.charCodeAt(e);\n  }var m = oaep_mgf1_arr(p, g.length, f);var d = [0];for (e = 0; e < g.length; e += 1) {\n    d[e + 1] = g[e] ^ m.charCodeAt(e);\n  }return new BigInteger(d.concat(p));\n}function RSAKey() {\n  this.n = null;this.e = 0;this.d = null;this.p = null;this.q = null;this.dmp1 = null;this.dmq1 = null;this.coeff = null;\n}function RSASetPublic(b, a) {\n  this.isPublic = true;this.isPrivate = false;if (typeof b !== \"string\") {\n    this.n = b;this.e = a;\n  } else {\n    if (b != null && a != null && b.length > 0 && a.length > 0) {\n      this.n = parseBigInt(b, 16);this.e = parseInt(a, 16);\n    } else {\n      throw \"Invalid RSA public key\";\n    }\n  }\n}function RSADoPublic(a) {\n  return a.modPowInt(this.e, this.n);\n}function RSAEncrypt(d) {\n  var a = pkcs1pad2(d, this.n.bitLength() + 7 >> 3);if (a == null) {\n    return null;\n  }var e = this.doPublic(a);if (e == null) {\n    return null;\n  }var b = e.toString(16);if ((b.length & 1) == 0) {\n    return b;\n  } else {\n    return \"0\" + b;\n  }\n}function RSAEncryptOAEP(f, e, b) {\n  var a = oaep_pad(f, this.n.bitLength() + 7 >> 3, e, b);if (a == null) {\n    return null;\n  }var g = this.doPublic(a);if (g == null) {\n    return null;\n  }var d = g.toString(16);if ((d.length & 1) == 0) {\n    return d;\n  } else {\n    return \"0\" + d;\n  }\n}RSAKey.prototype.doPublic = RSADoPublic;RSAKey.prototype.setPublic = RSASetPublic;RSAKey.prototype.encrypt = RSAEncrypt;RSAKey.prototype.encryptOAEP = RSAEncryptOAEP;RSAKey.prototype.type = \"RSA\";\n/*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/\n */\nfunction ECFieldElementFp(b, a) {\n  this.x = a;this.q = b;\n}function feFpEquals(a) {\n  if (a == this) {\n    return true;\n  }return this.q.equals(a.q) && this.x.equals(a.x);\n}function feFpToBigInteger() {\n  return this.x;\n}function feFpNegate() {\n  return new ECFieldElementFp(this.q, this.x.negate().mod(this.q));\n}function feFpAdd(a) {\n  return new ECFieldElementFp(this.q, this.x.add(a.toBigInteger()).mod(this.q));\n}function feFpSubtract(a) {\n  return new ECFieldElementFp(this.q, this.x.subtract(a.toBigInteger()).mod(this.q));\n}function feFpMultiply(a) {\n  return new ECFieldElementFp(this.q, this.x.multiply(a.toBigInteger()).mod(this.q));\n}function feFpSquare() {\n  return new ECFieldElementFp(this.q, this.x.square().mod(this.q));\n}function feFpDivide(a) {\n  return new ECFieldElementFp(this.q, this.x.multiply(a.toBigInteger().modInverse(this.q)).mod(this.q));\n}ECFieldElementFp.prototype.equals = feFpEquals;ECFieldElementFp.prototype.toBigInteger = feFpToBigInteger;ECFieldElementFp.prototype.negate = feFpNegate;ECFieldElementFp.prototype.add = feFpAdd;ECFieldElementFp.prototype.subtract = feFpSubtract;ECFieldElementFp.prototype.multiply = feFpMultiply;ECFieldElementFp.prototype.square = feFpSquare;ECFieldElementFp.prototype.divide = feFpDivide;function ECPointFp(c, a, d, b) {\n  this.curve = c;this.x = a;this.y = d;if (b == null) {\n    this.z = BigInteger.ONE;\n  } else {\n    this.z = b;\n  }this.zinv = null;\n}function pointFpGetX() {\n  if (this.zinv == null) {\n    this.zinv = this.z.modInverse(this.curve.q);\n  }return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}function pointFpGetY() {\n  if (this.zinv == null) {\n    this.zinv = this.z.modInverse(this.curve.q);\n  }return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q));\n}function pointFpEquals(a) {\n  if (a == this) {\n    return true;\n  }if (this.isInfinity()) {\n    return a.isInfinity();\n  }if (a.isInfinity()) {\n    return this.isInfinity();\n  }var c, b;c = a.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(a.z)).mod(this.curve.q);if (!c.equals(BigInteger.ZERO)) {\n    return false;\n  }b = a.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(a.z)).mod(this.curve.q);return b.equals(BigInteger.ZERO);\n}function pointFpIsInfinity() {\n  if (this.x == null && this.y == null) {\n    return true;\n  }return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);\n}function pointFpNegate() {\n  return new ECPointFp(this.curve, this.x, this.y.negate(), this.z);\n}function pointFpAdd(l) {\n  if (this.isInfinity()) {\n    return l;\n  }if (l.isInfinity()) {\n    return this;\n  }var p = l.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(l.z)).mod(this.curve.q);var o = l.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(l.z)).mod(this.curve.q);if (BigInteger.ZERO.equals(o)) {\n    if (BigInteger.ZERO.equals(p)) {\n      return this.twice();\n    }return this.curve.getInfinity();\n  }var j = new BigInteger(\"3\");var e = this.x.toBigInteger();var n = this.y.toBigInteger();var c = l.x.toBigInteger();var k = l.y.toBigInteger();var m = o.square();var i = m.multiply(o);var d = e.multiply(m);var g = p.square().multiply(this.z);var a = g.subtract(d.shiftLeft(1)).multiply(l.z).subtract(i).multiply(o).mod(this.curve.q);var h = d.multiply(j).multiply(p).subtract(n.multiply(i)).subtract(g.multiply(p)).multiply(l.z).add(p.multiply(i)).mod(this.curve.q);var f = i.multiply(this.z).multiply(l.z).mod(this.curve.q);return new ECPointFp(this.curve, this.curve.fromBigInteger(a), this.curve.fromBigInteger(h), f);\n}function pointFpTwice() {\n  if (this.isInfinity()) {\n    return this;\n  }if (this.y.toBigInteger().signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = new BigInteger(\"3\");var c = this.x.toBigInteger();var h = this.y.toBigInteger();var e = h.multiply(this.z);var j = e.multiply(h).mod(this.curve.q);var i = this.curve.a.toBigInteger();var k = c.square().multiply(g);if (!BigInteger.ZERO.equals(i)) {\n    k = k.add(this.z.square().multiply(i));\n  }k = k.mod(this.curve.q);var b = k.square().subtract(c.shiftLeft(3).multiply(j)).shiftLeft(1).multiply(e).mod(this.curve.q);var f = k.multiply(g).multiply(c).subtract(j.shiftLeft(1)).shiftLeft(2).multiply(j).subtract(k.square().multiply(k)).mod(this.curve.q);var d = e.square().multiply(e).shiftLeft(3).mod(this.curve.q);return new ECPointFp(this.curve, this.curve.fromBigInteger(b), this.curve.fromBigInteger(f), d);\n}function pointFpMultiply(b) {\n  if (this.isInfinity()) {\n    return this;\n  }if (b.signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = b;var f = g.multiply(new BigInteger(\"3\"));var l = this.negate();var d = this;var c;for (c = f.bitLength() - 2; c > 0; --c) {\n    d = d.twice();var a = f.testBit(c);var j = g.testBit(c);if (a != j) {\n      d = d.add(a ? this : l);\n    }\n  }return d;\n}function pointFpMultiplyTwo(c, a, b) {\n  var d;if (c.bitLength() > b.bitLength()) {\n    d = c.bitLength() - 1;\n  } else {\n    d = b.bitLength() - 1;\n  }var f = this.curve.getInfinity();var e = this.add(a);while (d >= 0) {\n    f = f.twice();if (c.testBit(d)) {\n      if (b.testBit(d)) {\n        f = f.add(e);\n      } else {\n        f = f.add(this);\n      }\n    } else {\n      if (b.testBit(d)) {\n        f = f.add(a);\n      }\n    }--d;\n  }return f;\n}ECPointFp.prototype.getX = pointFpGetX;ECPointFp.prototype.getY = pointFpGetY;ECPointFp.prototype.equals = pointFpEquals;ECPointFp.prototype.isInfinity = pointFpIsInfinity;ECPointFp.prototype.negate = pointFpNegate;ECPointFp.prototype.add = pointFpAdd;ECPointFp.prototype.twice = pointFpTwice;ECPointFp.prototype.multiply = pointFpMultiply;ECPointFp.prototype.multiplyTwo = pointFpMultiplyTwo;function ECCurveFp(e, d, c) {\n  this.q = e;this.a = this.fromBigInteger(d);this.b = this.fromBigInteger(c);this.infinity = new ECPointFp(this, null, null);\n}function curveFpGetQ() {\n  return this.q;\n}function curveFpGetA() {\n  return this.a;\n}function curveFpGetB() {\n  return this.b;\n}function curveFpEquals(a) {\n  if (a == this) {\n    return true;\n  }return this.q.equals(a.q) && this.a.equals(a.a) && this.b.equals(a.b);\n}function curveFpGetInfinity() {\n  return this.infinity;\n}function curveFpFromBigInteger(a) {\n  return new ECFieldElementFp(this.q, a);\n}function curveFpDecodePointHex(d) {\n  switch (parseInt(d.substr(0, 2), 16)) {case 0:\n      return this.infinity;case 2:case 3:\n      return null;case 4:case 6:case 7:\n      var a = (d.length - 2) / 2;var c = d.substr(2, a);var b = d.substr(a + 2, a);return new ECPointFp(this, this.fromBigInteger(new BigInteger(c, 16)), this.fromBigInteger(new BigInteger(b, 16)));default:\n      return null;}\n}ECCurveFp.prototype.getQ = curveFpGetQ;ECCurveFp.prototype.getA = curveFpGetA;ECCurveFp.prototype.getB = curveFpGetB;ECCurveFp.prototype.equals = curveFpEquals;ECCurveFp.prototype.getInfinity = curveFpGetInfinity;ECCurveFp.prototype.fromBigInteger = curveFpFromBigInteger;ECCurveFp.prototype.decodePointHex = curveFpDecodePointHex;\n/*! (c) Stefan Thomas | https://github.com/bitcoinjs/bitcoinjs-lib\n */\nECFieldElementFp.prototype.getByteLength = function () {\n  return Math.floor((this.toBigInteger().bitLength() + 7) / 8);\n};ECPointFp.prototype.getEncoded = function (c) {\n  var d = function d(h, f) {\n    var g = h.toByteArrayUnsigned();if (f < g.length) {\n      g = g.slice(g.length - f);\n    } else {\n      while (f > g.length) {\n        g.unshift(0);\n      }\n    }return g;\n  };var a = this.getX().toBigInteger();var e = this.getY().toBigInteger();var b = d(a, 32);if (c) {\n    if (e.isEven()) {\n      b.unshift(2);\n    } else {\n      b.unshift(3);\n    }\n  } else {\n    b.unshift(4);b = b.concat(d(e, 32));\n  }return b;\n};ECPointFp.decodeFrom = function (g, c) {\n  var f = c[0];var e = c.length - 1;var d = c.slice(1, 1 + e / 2);var b = c.slice(1 + e / 2, 1 + e);d.unshift(0);b.unshift(0);var a = new BigInteger(d);var h = new BigInteger(b);return new ECPointFp(g, g.fromBigInteger(a), g.fromBigInteger(h));\n};ECPointFp.decodeFromHex = function (g, c) {\n  var f = c.substr(0, 2);var e = c.length - 2;var d = c.substr(2, e / 2);var b = c.substr(2 + e / 2, e / 2);var a = new BigInteger(d, 16);var h = new BigInteger(b, 16);return new ECPointFp(g, g.fromBigInteger(a), g.fromBigInteger(h));\n};ECPointFp.prototype.add2D = function (c) {\n  if (this.isInfinity()) {\n    return c;\n  }if (c.isInfinity()) {\n    return this;\n  }if (this.x.equals(c.x)) {\n    if (this.y.equals(c.y)) {\n      return this.twice();\n    }return this.curve.getInfinity();\n  }var g = c.x.subtract(this.x);var e = c.y.subtract(this.y);var a = e.divide(g);var d = a.square().subtract(this.x).subtract(c.x);var f = a.multiply(this.x.subtract(d)).subtract(this.y);return new ECPointFp(this.curve, d, f);\n};ECPointFp.prototype.twice2D = function () {\n  if (this.isInfinity()) {\n    return this;\n  }if (this.y.toBigInteger().signum() == 0) {\n    return this.curve.getInfinity();\n  }var b = this.curve.fromBigInteger(BigInteger.valueOf(2));var e = this.curve.fromBigInteger(BigInteger.valueOf(3));var a = this.x.square().multiply(e).add(this.curve.a).divide(this.y.multiply(b));var c = a.square().subtract(this.x.multiply(b));var d = a.multiply(this.x.subtract(c)).subtract(this.y);return new ECPointFp(this.curve, c, d);\n};ECPointFp.prototype.multiply2D = function (b) {\n  if (this.isInfinity()) {\n    return this;\n  }if (b.signum() == 0) {\n    return this.curve.getInfinity();\n  }var g = b;var f = g.multiply(new BigInteger(\"3\"));var l = this.negate();var d = this;var c;for (c = f.bitLength() - 2; c > 0; --c) {\n    d = d.twice();var a = f.testBit(c);var j = g.testBit(c);if (a != j) {\n      d = d.add2D(a ? this : l);\n    }\n  }return d;\n};ECPointFp.prototype.isOnCurve = function () {\n  var d = this.getX().toBigInteger();var i = this.getY().toBigInteger();var f = this.curve.getA().toBigInteger();var c = this.curve.getB().toBigInteger();var h = this.curve.getQ();var e = i.multiply(i).mod(h);var g = d.multiply(d).multiply(d).add(f.multiply(d)).add(c).mod(h);return e.equals(g);\n};ECPointFp.prototype.toString = function () {\n  return \"(\" + this.getX().toBigInteger().toString() + \",\" + this.getY().toBigInteger().toString() + \")\";\n};ECPointFp.prototype.validate = function () {\n  var c = this.curve.getQ();if (this.isInfinity()) {\n    throw new Error(\"Point is at infinity.\");\n  }var a = this.getX().toBigInteger();var b = this.getY().toBigInteger();if (a.compareTo(BigInteger.ONE) < 0 || a.compareTo(c.subtract(BigInteger.ONE)) > 0) {\n    throw new Error(\"x coordinate out of bounds\");\n  }if (b.compareTo(BigInteger.ONE) < 0 || b.compareTo(c.subtract(BigInteger.ONE)) > 0) {\n    throw new Error(\"y coordinate out of bounds\");\n  }if (!this.isOnCurve()) {\n    throw new Error(\"Point is not on the curve.\");\n  }if (this.multiply(c).isInfinity()) {\n    throw new Error(\"Point is not a scalar multiple of G.\");\n  }return true;\n};\n/*! Mike Samuel (c) 2009 | code.google.com/p/json-sans-eval\n */\nvar jsonParse = function () {\n  var e = \"(?:-?\\\\b(?:0|[1-9][0-9]*)(?:\\\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\\\b)\";var j = '(?:[^\\\\0-\\\\x08\\\\x0a-\\\\x1f\"\\\\\\\\]|\\\\\\\\(?:[\"/\\\\\\\\bfnrt]|u[0-9A-Fa-f]{4}))';var i = '(?:\"' + j + '*\")';var d = new RegExp(\"(?:false|true|null|[\\\\{\\\\}\\\\[\\\\]]|\" + e + \"|\" + i + \")\", \"g\");var k = new RegExp(\"\\\\\\\\(?:([^u])|u(.{4}))\", \"g\");var g = { '\"': '\"', \"/\": \"/\", \"\\\\\": \"\\\\\", b: \"\\b\", f: \"\\f\", n: \"\\n\", r: \"\\r\", t: \"\\t\" };function h(l, m, n) {\n    return m ? g[m] : String.fromCharCode(parseInt(n, 16));\n  }var c = new String(\"\");var a = \"\\\\\";var f = { \"{\": Object, \"[\": Array };var b = Object.hasOwnProperty;return function (u, q) {\n    var p = u.match(d);var x;var v = p[0];var l = false;if (\"{\" === v) {\n      x = {};\n    } else {\n      if (\"[\" === v) {\n        x = [];\n      } else {\n        x = [];l = true;\n      }\n    }var t;var r = [x];for (var o = 1 - l, m = p.length; o < m; ++o) {\n      v = p[o];var w;switch (v.charCodeAt(0)) {default:\n          w = r[0];w[t || w.length] = +v;t = void 0;break;case 34:\n          v = v.substring(1, v.length - 1);if (v.indexOf(a) !== -1) {\n            v = v.replace(k, h);\n          }w = r[0];if (!t) {\n            if (w instanceof Array) {\n              t = w.length;\n            } else {\n              t = v || c;break;\n            }\n          }w[t] = v;t = void 0;break;case 91:\n          w = r[0];r.unshift(w[t || w.length] = []);t = void 0;break;case 93:\n          r.shift();break;case 102:\n          w = r[0];w[t || w.length] = false;t = void 0;break;case 110:\n          w = r[0];w[t || w.length] = null;t = void 0;break;case 116:\n          w = r[0];w[t || w.length] = true;t = void 0;break;case 123:\n          w = r[0];r.unshift(w[t || w.length] = {});t = void 0;break;case 125:\n          r.shift();break;}\n    }if (l) {\n      if (r.length !== 1) {\n        throw new Error();\n      }x = x[0];\n    } else {\n      if (r.length) {\n        throw new Error();\n      }\n    }if (q) {\n      var s = function s(C, B) {\n        var D = C[B];if (D && (typeof D === \"undefined\" ? \"undefined\" : _typeof(D)) === \"object\") {\n          var n = null;for (var z in D) {\n            if (b.call(D, z) && D !== C) {\n              var y = s(D, z);if (y !== void 0) {\n                D[z] = y;\n              } else {\n                if (!n) {\n                  n = [];\n                }n.push(z);\n              }\n            }\n          }if (n) {\n            for (var A = n.length; --A >= 0;) {\n              delete D[n[A]];\n            }\n          }\n        }return q.call(C, B, D);\n      };x = s({ \"\": x }, \"\");\n    }return x;\n  };\n}();\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.asn1 == \"undefined\" || !KJUR.asn1) {\n  KJUR.asn1 = {};\n}KJUR.asn1.ASN1Util = new function () {\n  this.integerToByteHex = function (a) {\n    var b = a.toString(16);if (b.length % 2 == 1) {\n      b = \"0\" + b;\n    }return b;\n  };this.bigIntToMinTwosComplementsHex = function (j) {\n    var f = j.toString(16);if (f.substr(0, 1) != \"-\") {\n      if (f.length % 2 == 1) {\n        f = \"0\" + f;\n      } else {\n        if (!f.match(/^[0-7]/)) {\n          f = \"00\" + f;\n        }\n      }\n    } else {\n      var a = f.substr(1);var e = a.length;if (e % 2 == 1) {\n        e += 1;\n      } else {\n        if (!f.match(/^[0-7]/)) {\n          e += 2;\n        }\n      }var g = \"\";for (var d = 0; d < e; d++) {\n        g += \"f\";\n      }var c = new BigInteger(g, 16);var b = c.xor(j).add(BigInteger.ONE);f = b.toString(16).replace(/^-/, \"\");\n    }return f;\n  };this.getPEMStringFromHex = function (a, b) {\n    return hextopem(a, b);\n  };this.newObject = function (k) {\n    var D = KJUR,\n        n = D.asn1,\n        z = n.DERBoolean,\n        e = n.DERInteger,\n        s = n.DERBitString,\n        h = n.DEROctetString,\n        v = n.DERNull,\n        w = n.DERObjectIdentifier,\n        l = n.DEREnumerated,\n        g = n.DERUTF8String,\n        f = n.DERNumericString,\n        y = n.DERPrintableString,\n        u = n.DERTeletexString,\n        p = n.DERIA5String,\n        C = n.DERUTCTime,\n        j = n.DERGeneralizedTime,\n        m = n.DERSequence,\n        c = n.DERSet,\n        r = n.DERTaggedObject,\n        o = n.ASN1Util.newObject;var t = Object.keys(k);if (t.length != 1) {\n      throw \"key of param shall be only one.\";\n    }var F = t[0];if (\":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:\".indexOf(\":\" + F + \":\") == -1) {\n      throw \"undefined key: \" + F;\n    }if (F == \"bool\") {\n      return new z(k[F]);\n    }if (F == \"int\") {\n      return new e(k[F]);\n    }if (F == \"bitstr\") {\n      return new s(k[F]);\n    }if (F == \"octstr\") {\n      return new h(k[F]);\n    }if (F == \"null\") {\n      return new v(k[F]);\n    }if (F == \"oid\") {\n      return new w(k[F]);\n    }if (F == \"enum\") {\n      return new l(k[F]);\n    }if (F == \"utf8str\") {\n      return new g(k[F]);\n    }if (F == \"numstr\") {\n      return new f(k[F]);\n    }if (F == \"prnstr\") {\n      return new y(k[F]);\n    }if (F == \"telstr\") {\n      return new u(k[F]);\n    }if (F == \"ia5str\") {\n      return new p(k[F]);\n    }if (F == \"utctime\") {\n      return new C(k[F]);\n    }if (F == \"gentime\") {\n      return new j(k[F]);\n    }if (F == \"seq\") {\n      var d = k[F];var E = [];for (var x = 0; x < d.length; x++) {\n        var B = o(d[x]);E.push(B);\n      }return new m({ array: E });\n    }if (F == \"set\") {\n      var d = k[F];var E = [];for (var x = 0; x < d.length; x++) {\n        var B = o(d[x]);E.push(B);\n      }return new c({ array: E });\n    }if (F == \"tag\") {\n      var A = k[F];if (Object.prototype.toString.call(A) === \"[object Array]\" && A.length == 3) {\n        var q = o(A[2]);return new r({ tag: A[0], explicit: A[1], obj: q });\n      } else {\n        var b = {};if (A.explicit !== undefined) {\n          b.explicit = A.explicit;\n        }if (A.tag !== undefined) {\n          b.tag = A.tag;\n        }if (A.obj === undefined) {\n          throw \"obj shall be specified for 'tag'.\";\n        }b.obj = o(A.obj);return new r(b);\n      }\n    }\n  };this.jsonToASN1HEX = function (b) {\n    var a = this.newObject(b);return a.getEncodedHex();\n  };\n}();KJUR.asn1.ASN1Util.oidHexToInt = function (a) {\n  var j = \"\";var k = parseInt(a.substr(0, 2), 16);var d = Math.floor(k / 40);var c = k % 40;var j = d + \".\" + c;var e = \"\";for (var f = 2; f < a.length; f += 2) {\n    var g = parseInt(a.substr(f, 2), 16);var h = (\"00000000\" + g.toString(2)).slice(-8);e = e + h.substr(1, 7);if (h.substr(0, 1) == \"0\") {\n      var b = new BigInteger(e, 2);j = j + \".\" + b.toString(10);e = \"\";\n    }\n  }return j;\n};KJUR.asn1.ASN1Util.oidIntToHex = function (f) {\n  var e = function e(a) {\n    var k = a.toString(16);if (k.length == 1) {\n      k = \"0\" + k;\n    }return k;\n  };var d = function d(o) {\n    var n = \"\";var k = new BigInteger(o, 10);var a = k.toString(2);var l = 7 - a.length % 7;if (l == 7) {\n      l = 0;\n    }var q = \"\";for (var m = 0; m < l; m++) {\n      q += \"0\";\n    }a = q + a;for (var m = 0; m < a.length - 1; m += 7) {\n      var p = a.substr(m, 7);if (m != a.length - 7) {\n        p = \"1\" + p;\n      }n += e(parseInt(p, 2));\n    }return n;\n  };if (!f.match(/^[0-9.]+$/)) {\n    throw \"malformed oid string: \" + f;\n  }var g = \"\";var b = f.split(\".\");var j = parseInt(b[0]) * 40 + parseInt(b[1]);g += e(j);b.splice(0, 2);for (var c = 0; c < b.length; c++) {\n    g += d(b[c]);\n  }return g;\n};KJUR.asn1.ASN1Object = function () {\n  var c = true;var b = null;var d = \"00\";var e = \"00\";var a = \"\";this.getLengthHexFromValue = function () {\n    if (typeof this.hV == \"undefined\" || this.hV == null) {\n      throw \"this.hV is null or undefined.\";\n    }if (this.hV.length % 2 == 1) {\n      throw \"value hex must be even length: n=\" + a.length + \",v=\" + this.hV;\n    }var i = this.hV.length / 2;var h = i.toString(16);if (h.length % 2 == 1) {\n      h = \"0\" + h;\n    }if (i < 128) {\n      return h;\n    } else {\n      var g = h.length / 2;if (g > 15) {\n        throw \"ASN.1 length too long to represent by 8x: n = \" + i.toString(16);\n      }var f = 128 + g;return f.toString(16) + h;\n    }\n  };this.getEncodedHex = function () {\n    if (this.hTLV == null || this.isModified) {\n      this.hV = this.getFreshValueHex();this.hL = this.getLengthHexFromValue();this.hTLV = this.hT + this.hL + this.hV;this.isModified = false;\n    }return this.hTLV;\n  };this.getValueHex = function () {\n    this.getEncodedHex();return this.hV;\n  };this.getFreshValueHex = function () {\n    return \"\";\n  };\n};KJUR.asn1.DERAbstractString = function (c) {\n  KJUR.asn1.DERAbstractString.superclass.constructor.call(this);var b = null;var a = null;this.getString = function () {\n    return this.s;\n  };this.setString = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = d;this.hV = utf8tohex(this.s).toLowerCase();\n  };this.setStringHex = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = null;this.hV = d;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof c != \"undefined\") {\n    if (typeof c == \"string\") {\n      this.setString(c);\n    } else {\n      if (typeof c.str != \"undefined\") {\n        this.setString(c.str);\n      } else {\n        if (typeof c.hex != \"undefined\") {\n          this.setStringHex(c.hex);\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);KJUR.asn1.DERAbstractTime = function (c) {\n  KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);var b = null;var a = null;this.localDateToUTC = function (f) {\n    utc = f.getTime() + f.getTimezoneOffset() * 60000;var e = new Date(utc);return e;\n  };this.formatDate = function (m, o, e) {\n    var g = this.zeroPadding;var n = this.localDateToUTC(m);var p = String(n.getFullYear());if (o == \"utc\") {\n      p = p.substr(2, 2);\n    }var l = g(String(n.getMonth() + 1), 2);var q = g(String(n.getDate()), 2);var h = g(String(n.getHours()), 2);var i = g(String(n.getMinutes()), 2);var j = g(String(n.getSeconds()), 2);var r = p + l + q + h + i + j;if (e === true) {\n      var f = n.getMilliseconds();if (f != 0) {\n        var k = g(String(f), 3);k = k.replace(/[0]+$/, \"\");r = r + \".\" + k;\n      }\n    }return r + \"Z\";\n  };this.zeroPadding = function (e, d) {\n    if (e.length >= d) {\n      return e;\n    }return new Array(d - e.length + 1).join(\"0\") + e;\n  };this.getString = function () {\n    return this.s;\n  };this.setString = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = d;this.hV = stohex(d);\n  };this.setByDateValue = function (h, j, e, d, f, g) {\n    var i = new Date(Date.UTC(h, j - 1, e, d, f, g, 0));this.setByDate(i);\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);KJUR.asn1.DERAbstractStructured = function (b) {\n  KJUR.asn1.DERAbstractString.superclass.constructor.call(this);var a = null;this.setByASN1ObjectArray = function (c) {\n    this.hTLV = null;this.isModified = true;this.asn1Array = c;\n  };this.appendASN1Object = function (c) {\n    this.hTLV = null;this.isModified = true;this.asn1Array.push(c);\n  };this.asn1Array = new Array();if (typeof b != \"undefined\") {\n    if (typeof b.array != \"undefined\") {\n      this.asn1Array = b.array;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);KJUR.asn1.DERBoolean = function () {\n  KJUR.asn1.DERBoolean.superclass.constructor.call(this);this.hT = \"01\";this.hTLV = \"0101ff\";\n};YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);KJUR.asn1.DERInteger = function (a) {\n  KJUR.asn1.DERInteger.superclass.constructor.call(this);this.hT = \"02\";this.setByBigInteger = function (b) {\n    this.hTLV = null;this.isModified = true;this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(b);\n  };this.setByInteger = function (c) {\n    var b = new BigInteger(String(c), 10);this.setByBigInteger(b);\n  };this.setValueHex = function (b) {\n    this.hV = b;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.bigint != \"undefined\") {\n      this.setByBigInteger(a.bigint);\n    } else {\n      if (typeof a[\"int\"] != \"undefined\") {\n        this.setByInteger(a[\"int\"]);\n      } else {\n        if (typeof a == \"number\") {\n          this.setByInteger(a);\n        } else {\n          if (typeof a.hex != \"undefined\") {\n            this.setValueHex(a.hex);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);KJUR.asn1.DERBitString = function (b) {\n  if (b !== undefined && typeof b.obj !== \"undefined\") {\n    var a = KJUR.asn1.ASN1Util.newObject(b.obj);b.hex = \"00\" + a.getEncodedHex();\n  }KJUR.asn1.DERBitString.superclass.constructor.call(this);this.hT = \"03\";this.setHexValueIncludingUnusedBits = function (c) {\n    this.hTLV = null;this.isModified = true;this.hV = c;\n  };this.setUnusedBitsAndHexValue = function (c, e) {\n    if (c < 0 || 7 < c) {\n      throw \"unused bits shall be from 0 to 7: u = \" + c;\n    }var d = \"0\" + c;this.hTLV = null;this.isModified = true;this.hV = d + e;\n  };this.setByBinaryString = function (e) {\n    e = e.replace(/0+$/, \"\");var f = 8 - e.length % 8;if (f == 8) {\n      f = 0;\n    }for (var g = 0; g <= f; g++) {\n      e += \"0\";\n    }var j = \"\";for (var g = 0; g < e.length - 1; g += 8) {\n      var d = e.substr(g, 8);var c = parseInt(d, 2).toString(16);if (c.length == 1) {\n        c = \"0\" + c;\n      }j += c;\n    }this.hTLV = null;this.isModified = true;this.hV = \"0\" + f + j;\n  };this.setByBooleanArray = function (e) {\n    var d = \"\";for (var c = 0; c < e.length; c++) {\n      if (e[c] == true) {\n        d += \"1\";\n      } else {\n        d += \"0\";\n      }\n    }this.setByBinaryString(d);\n  };this.newFalseArray = function (e) {\n    var c = new Array(e);for (var d = 0; d < e; d++) {\n      c[d] = false;\n    }return c;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof b != \"undefined\") {\n    if (typeof b == \"string\" && b.toLowerCase().match(/^[0-9a-f]+$/)) {\n      this.setHexValueIncludingUnusedBits(b);\n    } else {\n      if (typeof b.hex != \"undefined\") {\n        this.setHexValueIncludingUnusedBits(b.hex);\n      } else {\n        if (typeof b.bin != \"undefined\") {\n          this.setByBinaryString(b.bin);\n        } else {\n          if (typeof b.array != \"undefined\") {\n            this.setByBooleanArray(b.array);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);KJUR.asn1.DEROctetString = function (b) {\n  if (b !== undefined && typeof b.obj !== \"undefined\") {\n    var a = KJUR.asn1.ASN1Util.newObject(b.obj);b.hex = a.getEncodedHex();\n  }KJUR.asn1.DEROctetString.superclass.constructor.call(this, b);this.hT = \"04\";\n};YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERNull = function () {\n  KJUR.asn1.DERNull.superclass.constructor.call(this);this.hT = \"05\";this.hTLV = \"0500\";\n};YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);KJUR.asn1.DERObjectIdentifier = function (c) {\n  var b = function b(d) {\n    var e = d.toString(16);if (e.length == 1) {\n      e = \"0\" + e;\n    }return e;\n  };var a = function a(k) {\n    var j = \"\";var e = new BigInteger(k, 10);var d = e.toString(2);var f = 7 - d.length % 7;if (f == 7) {\n      f = 0;\n    }var m = \"\";for (var g = 0; g < f; g++) {\n      m += \"0\";\n    }d = m + d;for (var g = 0; g < d.length - 1; g += 7) {\n      var l = d.substr(g, 7);if (g != d.length - 7) {\n        l = \"1\" + l;\n      }j += b(parseInt(l, 2));\n    }return j;\n  };KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);this.hT = \"06\";this.setValueHex = function (d) {\n    this.hTLV = null;this.isModified = true;this.s = null;this.hV = d;\n  };this.setValueOidString = function (f) {\n    if (!f.match(/^[0-9.]+$/)) {\n      throw \"malformed oid string: \" + f;\n    }var g = \"\";var d = f.split(\".\");var j = parseInt(d[0]) * 40 + parseInt(d[1]);g += b(j);d.splice(0, 2);for (var e = 0; e < d.length; e++) {\n      g += a(d[e]);\n    }this.hTLV = null;this.isModified = true;this.s = null;this.hV = g;\n  };this.setValueName = function (e) {\n    var d = KJUR.asn1.x509.OID.name2oid(e);if (d !== \"\") {\n      this.setValueOidString(d);\n    } else {\n      throw \"DERObjectIdentifier oidName undefined: \" + e;\n    }\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (c !== undefined) {\n    if (typeof c === \"string\") {\n      if (c.match(/^[0-2].[0-9.]+$/)) {\n        this.setValueOidString(c);\n      } else {\n        this.setValueName(c);\n      }\n    } else {\n      if (c.oid !== undefined) {\n        this.setValueOidString(c.oid);\n      } else {\n        if (c.hex !== undefined) {\n          this.setValueHex(c.hex);\n        } else {\n          if (c.name !== undefined) {\n            this.setValueName(c.name);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);KJUR.asn1.DEREnumerated = function (a) {\n  KJUR.asn1.DEREnumerated.superclass.constructor.call(this);this.hT = \"0a\";this.setByBigInteger = function (b) {\n    this.hTLV = null;this.isModified = true;this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(b);\n  };this.setByInteger = function (c) {\n    var b = new BigInteger(String(c), 10);this.setByBigInteger(b);\n  };this.setValueHex = function (b) {\n    this.hV = b;\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a[\"int\"] != \"undefined\") {\n      this.setByInteger(a[\"int\"]);\n    } else {\n      if (typeof a == \"number\") {\n        this.setByInteger(a);\n      } else {\n        if (typeof a.hex != \"undefined\") {\n          this.setValueHex(a.hex);\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);KJUR.asn1.DERUTF8String = function (a) {\n  KJUR.asn1.DERUTF8String.superclass.constructor.call(this, a);this.hT = \"0c\";\n};YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);KJUR.asn1.DERNumericString = function (a) {\n  KJUR.asn1.DERNumericString.superclass.constructor.call(this, a);this.hT = \"12\";\n};YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERPrintableString = function (a) {\n  KJUR.asn1.DERPrintableString.superclass.constructor.call(this, a);this.hT = \"13\";\n};YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERTeletexString = function (a) {\n  KJUR.asn1.DERTeletexString.superclass.constructor.call(this, a);this.hT = \"14\";\n};YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);KJUR.asn1.DERIA5String = function (a) {\n  KJUR.asn1.DERIA5String.superclass.constructor.call(this, a);this.hT = \"16\";\n};YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);KJUR.asn1.DERUTCTime = function (a) {\n  KJUR.asn1.DERUTCTime.superclass.constructor.call(this, a);this.hT = \"17\";this.setByDate = function (b) {\n    this.hTLV = null;this.isModified = true;this.date = b;this.s = this.formatDate(this.date, \"utc\");this.hV = stohex(this.s);\n  };this.getFreshValueHex = function () {\n    if (typeof this.date == \"undefined\" && typeof this.s == \"undefined\") {\n      this.date = new Date();this.s = this.formatDate(this.date, \"utc\");this.hV = stohex(this.s);\n    }return this.hV;\n  };if (a !== undefined) {\n    if (a.str !== undefined) {\n      this.setString(a.str);\n    } else {\n      if (typeof a == \"string\" && a.match(/^[0-9]{12}Z$/)) {\n        this.setString(a);\n      } else {\n        if (a.hex !== undefined) {\n          this.setStringHex(a.hex);\n        } else {\n          if (a.date !== undefined) {\n            this.setByDate(a.date);\n          }\n        }\n      }\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);KJUR.asn1.DERGeneralizedTime = function (a) {\n  KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, a);this.hT = \"18\";this.withMillis = false;this.setByDate = function (b) {\n    this.hTLV = null;this.isModified = true;this.date = b;this.s = this.formatDate(this.date, \"gen\", this.withMillis);this.hV = stohex(this.s);\n  };this.getFreshValueHex = function () {\n    if (this.date === undefined && this.s === undefined) {\n      this.date = new Date();this.s = this.formatDate(this.date, \"gen\", this.withMillis);this.hV = stohex(this.s);\n    }return this.hV;\n  };if (a !== undefined) {\n    if (a.str !== undefined) {\n      this.setString(a.str);\n    } else {\n      if (typeof a == \"string\" && a.match(/^[0-9]{14}Z$/)) {\n        this.setString(a);\n      } else {\n        if (a.hex !== undefined) {\n          this.setStringHex(a.hex);\n        } else {\n          if (a.date !== undefined) {\n            this.setByDate(a.date);\n          }\n        }\n      }\n    }if (a.millis === true) {\n      this.withMillis = true;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);KJUR.asn1.DERSequence = function (a) {\n  KJUR.asn1.DERSequence.superclass.constructor.call(this, a);this.hT = \"30\";this.getFreshValueHex = function () {\n    var c = \"\";for (var b = 0; b < this.asn1Array.length; b++) {\n      var d = this.asn1Array[b];c += d.getEncodedHex();\n    }this.hV = c;return this.hV;\n  };\n};YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);KJUR.asn1.DERSet = function (a) {\n  KJUR.asn1.DERSet.superclass.constructor.call(this, a);this.hT = \"31\";this.sortFlag = true;this.getFreshValueHex = function () {\n    var b = new Array();for (var c = 0; c < this.asn1Array.length; c++) {\n      var d = this.asn1Array[c];b.push(d.getEncodedHex());\n    }if (this.sortFlag == true) {\n      b.sort();\n    }this.hV = b.join(\"\");return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.sortflag != \"undefined\" && a.sortflag == false) {\n      this.sortFlag = false;\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);KJUR.asn1.DERTaggedObject = function (a) {\n  KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);this.hT = \"a0\";this.hV = \"\";this.isExplicit = true;this.asn1Object = null;this.setASN1Object = function (b, c, d) {\n    this.hT = c;this.isExplicit = b;this.asn1Object = d;if (this.isExplicit) {\n      this.hV = this.asn1Object.getEncodedHex();this.hTLV = null;this.isModified = true;\n    } else {\n      this.hV = null;this.hTLV = d.getEncodedHex();this.hTLV = this.hTLV.replace(/^../, c);this.isModified = false;\n    }\n  };this.getFreshValueHex = function () {\n    return this.hV;\n  };if (typeof a != \"undefined\") {\n    if (typeof a.tag != \"undefined\") {\n      this.hT = a.tag;\n    }if (typeof a.explicit != \"undefined\") {\n      this.isExplicit = a.explicit;\n    }if (typeof a.obj != \"undefined\") {\n      this.asn1Object = a.obj;this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);\n    }\n  }\n};YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);\nvar ASN1HEX = new function () {}();ASN1HEX.getLblen = function (c, a) {\n  if (c.substr(a + 2, 1) != \"8\") {\n    return 1;\n  }var b = parseInt(c.substr(a + 3, 1));if (b == 0) {\n    return -1;\n  }if (0 < b && b < 10) {\n    return b + 1;\n  }return -2;\n};ASN1HEX.getL = function (c, b) {\n  var a = ASN1HEX.getLblen(c, b);if (a < 1) {\n    return \"\";\n  }return c.substr(b + 2, a * 2);\n};ASN1HEX.getVblen = function (d, a) {\n  var c, b;c = ASN1HEX.getL(d, a);if (c == \"\") {\n    return -1;\n  }if (c.substr(0, 1) === \"8\") {\n    b = new BigInteger(c.substr(2), 16);\n  } else {\n    b = new BigInteger(c, 16);\n  }return b.intValue();\n};ASN1HEX.getVidx = function (c, b) {\n  var a = ASN1HEX.getLblen(c, b);if (a < 0) {\n    return a;\n  }return b + (a + 1) * 2;\n};ASN1HEX.getV = function (d, a) {\n  var c = ASN1HEX.getVidx(d, a);var b = ASN1HEX.getVblen(d, a);return d.substr(c, b * 2);\n};ASN1HEX.getTLV = function (b, a) {\n  return b.substr(a, 2) + ASN1HEX.getL(b, a) + ASN1HEX.getV(b, a);\n};ASN1HEX.getNextSiblingIdx = function (d, a) {\n  var c = ASN1HEX.getVidx(d, a);var b = ASN1HEX.getVblen(d, a);return c + b * 2;\n};ASN1HEX.getChildIdx = function (e, f) {\n  var j = ASN1HEX;var g = new Array();var i = j.getVidx(e, f);if (e.substr(f, 2) == \"03\") {\n    g.push(i + 2);\n  } else {\n    g.push(i);\n  }var l = j.getVblen(e, f);var c = i;var d = 0;while (1) {\n    var b = j.getNextSiblingIdx(e, c);if (b == null || b - i >= l * 2) {\n      break;\n    }if (d >= 200) {\n      break;\n    }g.push(b);c = b;d++;\n  }return g;\n};ASN1HEX.getNthChildIdx = function (d, b, e) {\n  var c = ASN1HEX.getChildIdx(d, b);return c[e];\n};ASN1HEX.getIdxbyList = function (e, d, c, i) {\n  var g = ASN1HEX;var f, b;if (c.length == 0) {\n    if (i !== undefined) {\n      if (e.substr(d, 2) !== i) {\n        throw \"checking tag doesn't match: \" + e.substr(d, 2) + \"!=\" + i;\n      }\n    }return d;\n  }f = c.shift();b = g.getChildIdx(e, d);return g.getIdxbyList(e, b[f], c, i);\n};ASN1HEX.getTLVbyList = function (d, c, b, f) {\n  var e = ASN1HEX;var a = e.getIdxbyList(d, c, b);if (a === undefined) {\n    throw \"can't find nthList object\";\n  }if (f !== undefined) {\n    if (d.substr(a, 2) != f) {\n      throw \"checking tag doesn't match: \" + d.substr(a, 2) + \"!=\" + f;\n    }\n  }return e.getTLV(d, a);\n};ASN1HEX.getVbyList = function (e, c, b, g, i) {\n  var f = ASN1HEX;var a, d;a = f.getIdxbyList(e, c, b, g);if (a === undefined) {\n    throw \"can't find nthList object\";\n  }d = f.getV(e, a);if (i === true) {\n    d = d.substr(2);\n  }return d;\n};ASN1HEX.hextooidstr = function (e) {\n  var h = function h(b, a) {\n    if (b.length >= a) {\n      return b;\n    }return new Array(a - b.length + 1).join(\"0\") + b;\n  };var l = [];var o = e.substr(0, 2);var f = parseInt(o, 16);l[0] = new String(Math.floor(f / 40));l[1] = new String(f % 40);var m = e.substr(2);var k = [];for (var g = 0; g < m.length / 2; g++) {\n    k.push(parseInt(m.substr(g * 2, 2), 16));\n  }var j = [];var d = \"\";for (var g = 0; g < k.length; g++) {\n    if (k[g] & 128) {\n      d = d + h((k[g] & 127).toString(2), 7);\n    } else {\n      d = d + h((k[g] & 127).toString(2), 7);j.push(new String(parseInt(d, 2)));d = \"\";\n    }\n  }var n = l.join(\".\");if (j.length > 0) {\n    n = n + \".\" + j.join(\".\");\n  }return n;\n};ASN1HEX.dump = function (t, c, l, g) {\n  var p = ASN1HEX;var j = p.getV;var y = p.dump;var w = p.getChildIdx;var e = t;if (t instanceof KJUR.asn1.ASN1Object) {\n    e = t.getEncodedHex();\n  }var q = function q(A, i) {\n    if (A.length <= i * 2) {\n      return A;\n    } else {\n      var v = A.substr(0, i) + \"..(total \" + A.length / 2 + \"bytes)..\" + A.substr(A.length - i, i);return v;\n    }\n  };if (c === undefined) {\n    c = { ommit_long_octet: 32 };\n  }if (l === undefined) {\n    l = 0;\n  }if (g === undefined) {\n    g = \"\";\n  }var x = c.ommit_long_octet;if (e.substr(l, 2) == \"01\") {\n    var h = j(e, l);if (h == \"00\") {\n      return g + \"BOOLEAN FALSE\\n\";\n    } else {\n      return g + \"BOOLEAN TRUE\\n\";\n    }\n  }if (e.substr(l, 2) == \"02\") {\n    var h = j(e, l);return g + \"INTEGER \" + q(h, x) + \"\\n\";\n  }if (e.substr(l, 2) == \"03\") {\n    var h = j(e, l);return g + \"BITSTRING \" + q(h, x) + \"\\n\";\n  }if (e.substr(l, 2) == \"04\") {\n    var h = j(e, l);if (p.isASN1HEX(h)) {\n      var k = g + \"OCTETSTRING, encapsulates\\n\";k = k + y(h, c, 0, g + \"  \");return k;\n    } else {\n      return g + \"OCTETSTRING \" + q(h, x) + \"\\n\";\n    }\n  }if (e.substr(l, 2) == \"05\") {\n    return g + \"NULL\\n\";\n  }if (e.substr(l, 2) == \"06\") {\n    var m = j(e, l);var a = KJUR.asn1.ASN1Util.oidHexToInt(m);var o = KJUR.asn1.x509.OID.oid2name(a);var b = a.replace(/\\./g, \" \");if (o != \"\") {\n      return g + \"ObjectIdentifier \" + o + \" (\" + b + \")\\n\";\n    } else {\n      return g + \"ObjectIdentifier (\" + b + \")\\n\";\n    }\n  }if (e.substr(l, 2) == \"0c\") {\n    return g + \"UTF8String '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"13\") {\n    return g + \"PrintableString '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"14\") {\n    return g + \"TeletexString '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"16\") {\n    return g + \"IA5String '\" + hextoutf8(j(e, l)) + \"'\\n\";\n  }if (e.substr(l, 2) == \"17\") {\n    return g + \"UTCTime \" + hextoutf8(j(e, l)) + \"\\n\";\n  }if (e.substr(l, 2) == \"18\") {\n    return g + \"GeneralizedTime \" + hextoutf8(j(e, l)) + \"\\n\";\n  }if (e.substr(l, 2) == \"30\") {\n    if (e.substr(l, 4) == \"3000\") {\n      return g + \"SEQUENCE {}\\n\";\n    }var k = g + \"SEQUENCE\\n\";var d = w(e, l);var f = c;if ((d.length == 2 || d.length == 3) && e.substr(d[0], 2) == \"06\" && e.substr(d[d.length - 1], 2) == \"04\") {\n      var o = p.oidname(j(e, d[0]));var r = JSON.parse(JSON.stringify(c));r.x509ExtName = o;f = r;\n    }for (var u = 0; u < d.length; u++) {\n      k = k + y(e, f, d[u], g + \"  \");\n    }return k;\n  }if (e.substr(l, 2) == \"31\") {\n    var k = g + \"SET\\n\";var d = w(e, l);for (var u = 0; u < d.length; u++) {\n      k = k + y(e, c, d[u], g + \"  \");\n    }return k;\n  }var z = parseInt(e.substr(l, 2), 16);if ((z & 128) != 0) {\n    var n = z & 31;if ((z & 32) != 0) {\n      var k = g + \"[\" + n + \"]\\n\";var d = w(e, l);for (var u = 0; u < d.length; u++) {\n        k = k + y(e, c, d[u], g + \"  \");\n      }return k;\n    } else {\n      var h = j(e, l);if (h.substr(0, 8) == \"68747470\") {\n        h = hextoutf8(h);\n      }if (c.x509ExtName === \"subjectAltName\" && n == 2) {\n        h = hextoutf8(h);\n      }var k = g + \"[\" + n + \"] \" + h + \"\\n\";return k;\n    }\n  }return g + \"UNKNOWN(\" + e.substr(l, 2) + \") \" + j(e, l) + \"\\n\";\n};ASN1HEX.isASN1HEX = function (e) {\n  var d = ASN1HEX;if (e.length % 2 == 1) {\n    return false;\n  }var c = d.getVblen(e, 0);var b = e.substr(0, 2);var f = d.getL(e, 0);var a = e.length - b.length - f.length;if (a == c * 2) {\n    return true;\n  }return false;\n};ASN1HEX.oidname = function (a) {\n  var c = KJUR.asn1;if (KJUR.lang.String.isHex(a)) {\n    a = c.ASN1Util.oidHexToInt(a);\n  }var b = c.x509.OID.oid2name(a);if (b === \"\") {\n    b = a;\n  }return b;\n};\nvar KJUR;if (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.lang == \"undefined\" || !KJUR.lang) {\n  KJUR.lang = {};\n}KJUR.lang.String = function () {};function Base64x() {}function stoBA(d) {\n  var b = new Array();for (var c = 0; c < d.length; c++) {\n    b[c] = d.charCodeAt(c);\n  }return b;\n}function BAtos(b) {\n  var d = \"\";for (var c = 0; c < b.length; c++) {\n    d = d + String.fromCharCode(b[c]);\n  }return d;\n}function BAtohex(b) {\n  var e = \"\";for (var d = 0; d < b.length; d++) {\n    var c = b[d].toString(16);if (c.length == 1) {\n      c = \"0\" + c;\n    }e = e + c;\n  }return e;\n}function stohex(a) {\n  return BAtohex(stoBA(a));\n}function stob64(a) {\n  return hex2b64(stohex(a));\n}function stob64u(a) {\n  return b64tob64u(hex2b64(stohex(a)));\n}function b64utos(a) {\n  return BAtos(b64toBA(b64utob64(a)));\n}function b64tob64u(a) {\n  a = a.replace(/\\=/g, \"\");a = a.replace(/\\+/g, \"-\");a = a.replace(/\\//g, \"_\");return a;\n}function b64utob64(a) {\n  if (a.length % 4 == 2) {\n    a = a + \"==\";\n  } else {\n    if (a.length % 4 == 3) {\n      a = a + \"=\";\n    }\n  }a = a.replace(/-/g, \"+\");a = a.replace(/_/g, \"/\");return a;\n}function hextob64u(a) {\n  if (a.length % 2 == 1) {\n    a = \"0\" + a;\n  }return b64tob64u(hex2b64(a));\n}function b64utohex(a) {\n  return b64tohex(b64utob64(a));\n}var utf8tob64u, b64utoutf8;if (typeof Buffer === \"function\") {\n  exports.utf8tob64u = utf8tob64u = function utf8tob64u(a) {\n    return b64tob64u(new Buffer(a, \"utf8\").toString(\"base64\"));\n  };exports.b64utoutf8 = b64utoutf8 = function b64utoutf8(a) {\n    return new Buffer(b64utob64(a), \"base64\").toString(\"utf8\");\n  };\n} else {\n  exports.utf8tob64u = utf8tob64u = function utf8tob64u(a) {\n    return hextob64u(uricmptohex(encodeURIComponentAll(a)));\n  };exports.b64utoutf8 = b64utoutf8 = function b64utoutf8(a) {\n    return decodeURIComponent(hextouricmp(b64utohex(a)));\n  };\n}function utf8tob64(a) {\n  return hex2b64(uricmptohex(encodeURIComponentAll(a)));\n}function b64toutf8(a) {\n  return decodeURIComponent(hextouricmp(b64tohex(a)));\n}function utf8tohex(a) {\n  return uricmptohex(encodeURIComponentAll(a));\n}function hextoutf8(a) {\n  return decodeURIComponent(hextouricmp(a));\n}function hextorstr(c) {\n  var b = \"\";for (var a = 0; a < c.length - 1; a += 2) {\n    b += String.fromCharCode(parseInt(c.substr(a, 2), 16));\n  }return b;\n}function rstrtohex(c) {\n  var a = \"\";for (var b = 0; b < c.length; b++) {\n    a += (\"0\" + c.charCodeAt(b).toString(16)).slice(-2);\n  }return a;\n}function hextob64(a) {\n  return hex2b64(a);\n}function hextob64nl(b) {\n  var a = hextob64(b);var c = a.replace(/(.{64})/g, \"$1\\r\\n\");c = c.replace(/\\r\\n$/, \"\");return c;\n}function b64nltohex(b) {\n  var a = b.replace(/[^0-9A-Za-z\\/+=]*/g, \"\");var c = b64tohex(a);return c;\n}function hextopem(a, b) {\n  var c = hextob64nl(a);return \"-----BEGIN \" + b + \"-----\\r\\n\" + c + \"\\r\\n-----END \" + b + \"-----\\r\\n\";\n}function pemtohex(a, b) {\n  if (a.indexOf(\"-----BEGIN \") == -1) {\n    throw \"can't find PEM header: \" + b;\n  }if (b !== undefined) {\n    a = a.replace(\"-----BEGIN \" + b + \"-----\", \"\");a = a.replace(\"-----END \" + b + \"-----\", \"\");\n  } else {\n    a = a.replace(/-----BEGIN [^-]+-----/, \"\");a = a.replace(/-----END [^-]+-----/, \"\");\n  }return b64nltohex(a);\n}function hextoArrayBuffer(d) {\n  if (d.length % 2 != 0) {\n    throw \"input is not even length\";\n  }if (d.match(/^[0-9A-Fa-f]+$/) == null) {\n    throw \"input is not hexadecimal\";\n  }var b = new ArrayBuffer(d.length / 2);var a = new DataView(b);for (var c = 0; c < d.length / 2; c++) {\n    a.setUint8(c, parseInt(d.substr(c * 2, 2), 16));\n  }return b;\n}function ArrayBuffertohex(b) {\n  var d = \"\";var a = new DataView(b);for (var c = 0; c < b.byteLength; c++) {\n    d += (\"00\" + a.getUint8(c).toString(16)).slice(-2);\n  }return d;\n}function zulutomsec(n) {\n  var l, j, m, e, f, i, b, k;var a, h, g, c;c = n.match(/^(\\d{2}|\\d{4})(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(|\\.\\d+)Z$/);if (c) {\n    a = c[1];l = parseInt(a);if (a.length === 2) {\n      if (50 <= l && l < 100) {\n        l = 1900 + l;\n      } else {\n        if (0 <= l && l < 50) {\n          l = 2000 + l;\n        }\n      }\n    }j = parseInt(c[2]) - 1;m = parseInt(c[3]);e = parseInt(c[4]);f = parseInt(c[5]);i = parseInt(c[6]);b = 0;h = c[7];if (h !== \"\") {\n      g = (h.substr(1) + \"00\").substr(0, 3);b = parseInt(g);\n    }return Date.UTC(l, j, m, e, f, i, b);\n  }throw \"unsupported zulu format: \" + n;\n}function zulutosec(a) {\n  var b = zulutomsec(a);return ~~(b / 1000);\n}function zulutodate(a) {\n  return new Date(zulutomsec(a));\n}function datetozulu(g, e, f) {\n  var b;var a = g.getUTCFullYear();if (e) {\n    if (a < 1950 || 2049 < a) {\n      throw \"not proper year for UTCTime: \" + a;\n    }b = (\"\" + a).slice(-2);\n  } else {\n    b = (\"000\" + a).slice(-4);\n  }b += (\"0\" + (g.getUTCMonth() + 1)).slice(-2);b += (\"0\" + g.getUTCDate()).slice(-2);b += (\"0\" + g.getUTCHours()).slice(-2);b += (\"0\" + g.getUTCMinutes()).slice(-2);b += (\"0\" + g.getUTCSeconds()).slice(-2);if (f) {\n    var c = g.getUTCMilliseconds();if (c !== 0) {\n      c = (\"00\" + c).slice(-3);c = c.replace(/0+$/g, \"\");b += \".\" + c;\n    }\n  }b += \"Z\";return b;\n}function uricmptohex(a) {\n  return a.replace(/%/g, \"\");\n}function hextouricmp(a) {\n  return a.replace(/(..)/g, \"%$1\");\n}function ipv6tohex(g) {\n  var b = \"malformed IPv6 address\";if (!g.match(/^[0-9A-Fa-f:]+$/)) {\n    throw b;\n  }g = g.toLowerCase();var d = g.split(\":\").length - 1;if (d < 2) {\n    throw b;\n  }var e = \":\".repeat(7 - d + 2);g = g.replace(\"::\", e);var c = g.split(\":\");if (c.length != 8) {\n    throw b;\n  }for (var f = 0; f < 8; f++) {\n    c[f] = (\"0000\" + c[f]).slice(-4);\n  }return c.join(\"\");\n}function hextoipv6(e) {\n  if (!e.match(/^[0-9A-Fa-f]{32}$/)) {\n    throw \"malformed IPv6 address octet\";\n  }e = e.toLowerCase();var b = e.match(/.{1,4}/g);for (var d = 0; d < 8; d++) {\n    b[d] = b[d].replace(/^0+/, \"\");if (b[d] == \"\") {\n      b[d] = \"0\";\n    }\n  }e = \":\" + b.join(\":\") + \":\";var c = e.match(/:(0:){2,}/g);if (c === null) {\n    return e.slice(1, -1);\n  }var f = \"\";for (var d = 0; d < c.length; d++) {\n    if (c[d].length > f.length) {\n      f = c[d];\n    }\n  }e = e.replace(f, \"::\");return e.slice(1, -1);\n}function hextoip(b) {\n  var d = \"malformed hex value\";if (!b.match(/^([0-9A-Fa-f][0-9A-Fa-f]){1,}$/)) {\n    throw d;\n  }if (b.length == 8) {\n    var c;try {\n      c = parseInt(b.substr(0, 2), 16) + \".\" + parseInt(b.substr(2, 2), 16) + \".\" + parseInt(b.substr(4, 2), 16) + \".\" + parseInt(b.substr(6, 2), 16);return c;\n    } catch (a) {\n      throw d;\n    }\n  } else {\n    if (b.length == 32) {\n      return hextoipv6(b);\n    } else {\n      return b;\n    }\n  }\n}function iptohex(f) {\n  var j = \"malformed IP address\";f = f.toLowerCase(f);if (f.match(/^[0-9.]+$/)) {\n    var b = f.split(\".\");if (b.length !== 4) {\n      throw j;\n    }var g = \"\";try {\n      for (var e = 0; e < 4; e++) {\n        var h = parseInt(b[e]);g += (\"0\" + h.toString(16)).slice(-2);\n      }return g;\n    } catch (c) {\n      throw j;\n    }\n  } else {\n    if (f.match(/^[0-9a-f:]+$/) && f.indexOf(\":\") !== -1) {\n      return ipv6tohex(f);\n    } else {\n      throw j;\n    }\n  }\n}function encodeURIComponentAll(a) {\n  var d = encodeURIComponent(a);var b = \"\";for (var c = 0; c < d.length; c++) {\n    if (d[c] == \"%\") {\n      b = b + d.substr(c, 3);c = c + 2;\n    } else {\n      b = b + \"%\" + stohex(d[c]);\n    }\n  }return b;\n}function newline_toUnix(a) {\n  a = a.replace(/\\r\\n/mg, \"\\n\");return a;\n}function newline_toDos(a) {\n  a = a.replace(/\\r\\n/mg, \"\\n\");a = a.replace(/\\n/mg, \"\\r\\n\");return a;\n}KJUR.lang.String.isInteger = function (a) {\n  if (a.match(/^[0-9]+$/)) {\n    return true;\n  } else {\n    if (a.match(/^-[0-9]+$/)) {\n      return true;\n    } else {\n      return false;\n    }\n  }\n};KJUR.lang.String.isHex = function (a) {\n  if (a.length % 2 == 0 && (a.match(/^[0-9a-f]+$/) || a.match(/^[0-9A-F]+$/))) {\n    return true;\n  } else {\n    return false;\n  }\n};KJUR.lang.String.isBase64 = function (a) {\n  a = a.replace(/\\s+/g, \"\");if (a.match(/^[0-9A-Za-z+\\/]+={0,3}$/) && a.length % 4 == 0) {\n    return true;\n  } else {\n    return false;\n  }\n};KJUR.lang.String.isBase64URL = function (a) {\n  if (a.match(/[+/=]/)) {\n    return false;\n  }a = b64utob64(a);return KJUR.lang.String.isBase64(a);\n};KJUR.lang.String.isIntegerArray = function (a) {\n  a = a.replace(/\\s+/g, \"\");if (a.match(/^\\[[0-9,]+\\]$/)) {\n    return true;\n  } else {\n    return false;\n  }\n};function hextoposhex(a) {\n  if (a.length % 2 == 1) {\n    return \"0\" + a;\n  }if (a.substr(0, 1) > \"7\") {\n    return \"00\" + a;\n  }return a;\n}function intarystrtohex(b) {\n  b = b.replace(/^\\s*\\[\\s*/, \"\");b = b.replace(/\\s*\\]\\s*$/, \"\");b = b.replace(/\\s*/g, \"\");try {\n    var c = b.split(/,/).map(function (g, e, h) {\n      var f = parseInt(g);if (f < 0 || 255 < f) {\n        throw \"integer not in range 0-255\";\n      }var d = (\"00\" + f.toString(16)).slice(-2);return d;\n    }).join(\"\");return c;\n  } catch (a) {\n    throw \"malformed integer array string: \" + a;\n  }\n}var strdiffidx = function strdiffidx(c, a) {\n  var d = c.length;if (c.length > a.length) {\n    d = a.length;\n  }for (var b = 0; b < d; b++) {\n    if (c.charCodeAt(b) != a.charCodeAt(b)) {\n      return b;\n    }\n  }if (c.length != a.length) {\n    return d;\n  }return -1;\n};\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.Util = new function () {\n  this.DIGESTINFOHEAD = { sha1: \"3021300906052b0e03021a05000414\", sha224: \"302d300d06096086480165030402040500041c\", sha256: \"3031300d060960864801650304020105000420\", sha384: \"3041300d060960864801650304020205000430\", sha512: \"3051300d060960864801650304020305000440\", md2: \"3020300c06082a864886f70d020205000410\", md5: \"3020300c06082a864886f70d020505000410\", ripemd160: \"3021300906052b2403020105000414\" };this.DEFAULTPROVIDER = { md5: \"cryptojs\", sha1: \"cryptojs\", sha224: \"cryptojs\", sha256: \"cryptojs\", sha384: \"cryptojs\", sha512: \"cryptojs\", ripemd160: \"cryptojs\", hmacmd5: \"cryptojs\", hmacsha1: \"cryptojs\", hmacsha224: \"cryptojs\", hmacsha256: \"cryptojs\", hmacsha384: \"cryptojs\", hmacsha512: \"cryptojs\", hmacripemd160: \"cryptojs\", MD5withRSA: \"cryptojs/jsrsa\", SHA1withRSA: \"cryptojs/jsrsa\", SHA224withRSA: \"cryptojs/jsrsa\", SHA256withRSA: \"cryptojs/jsrsa\", SHA384withRSA: \"cryptojs/jsrsa\", SHA512withRSA: \"cryptojs/jsrsa\", RIPEMD160withRSA: \"cryptojs/jsrsa\", MD5withECDSA: \"cryptojs/jsrsa\", SHA1withECDSA: \"cryptojs/jsrsa\", SHA224withECDSA: \"cryptojs/jsrsa\", SHA256withECDSA: \"cryptojs/jsrsa\", SHA384withECDSA: \"cryptojs/jsrsa\", SHA512withECDSA: \"cryptojs/jsrsa\", RIPEMD160withECDSA: \"cryptojs/jsrsa\", SHA1withDSA: \"cryptojs/jsrsa\", SHA224withDSA: \"cryptojs/jsrsa\", SHA256withDSA: \"cryptojs/jsrsa\", MD5withRSAandMGF1: \"cryptojs/jsrsa\", SHA1withRSAandMGF1: \"cryptojs/jsrsa\", SHA224withRSAandMGF1: \"cryptojs/jsrsa\", SHA256withRSAandMGF1: \"cryptojs/jsrsa\", SHA384withRSAandMGF1: \"cryptojs/jsrsa\", SHA512withRSAandMGF1: \"cryptojs/jsrsa\", RIPEMD160withRSAandMGF1: \"cryptojs/jsrsa\" };this.CRYPTOJSMESSAGEDIGESTNAME = { md5: CryptoJS.algo.MD5, sha1: CryptoJS.algo.SHA1, sha224: CryptoJS.algo.SHA224, sha256: CryptoJS.algo.SHA256, sha384: CryptoJS.algo.SHA384, sha512: CryptoJS.algo.SHA512, ripemd160: CryptoJS.algo.RIPEMD160 };this.getDigestInfoHex = function (a, b) {\n    if (typeof this.DIGESTINFOHEAD[b] == \"undefined\") {\n      throw \"alg not supported in Util.DIGESTINFOHEAD: \" + b;\n    }return this.DIGESTINFOHEAD[b] + a;\n  };this.getPaddedDigestInfoHex = function (h, a, j) {\n    var c = this.getDigestInfoHex(h, a);var d = j / 4;if (c.length + 22 > d) {\n      throw \"key is too short for SigAlg: keylen=\" + j + \",\" + a;\n    }var b = \"0001\";var k = \"00\" + c;var g = \"\";var l = d - b.length - k.length;for (var f = 0; f < l; f += 2) {\n      g += \"ff\";\n    }var e = b + g + k;return e;\n  };this.hashString = function (a, c) {\n    var b = new KJUR.crypto.MessageDigest({ alg: c });return b.digestString(a);\n  };this.hashHex = function (b, c) {\n    var a = new KJUR.crypto.MessageDigest({ alg: c });return a.digestHex(b);\n  };this.sha1 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha1\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha256 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha256\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha256Hex = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha256\", prov: \"cryptojs\" });return b.digestHex(a);\n  };this.sha512 = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha512\", prov: \"cryptojs\" });return b.digestString(a);\n  };this.sha512Hex = function (a) {\n    var b = new KJUR.crypto.MessageDigest({ alg: \"sha512\", prov: \"cryptojs\" });return b.digestHex(a);\n  };\n}();KJUR.crypto.Util.md5 = function (a) {\n  var b = new KJUR.crypto.MessageDigest({ alg: \"md5\", prov: \"cryptojs\" });return b.digestString(a);\n};KJUR.crypto.Util.ripemd160 = function (a) {\n  var b = new KJUR.crypto.MessageDigest({ alg: \"ripemd160\", prov: \"cryptojs\" });return b.digestString(a);\n};KJUR.crypto.Util.SECURERANDOMGEN = new SecureRandom();KJUR.crypto.Util.getRandomHexOfNbytes = function (b) {\n  var a = new Array(b);KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(a);return BAtohex(a);\n};KJUR.crypto.Util.getRandomBigIntegerOfNbytes = function (a) {\n  return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbytes(a), 16);\n};KJUR.crypto.Util.getRandomHexOfNbits = function (d) {\n  var c = d % 8;var a = (d - c) / 8;var b = new Array(a + 1);KJUR.crypto.Util.SECURERANDOMGEN.nextBytes(b);b[0] = (255 << c & 255 ^ 255) & b[0];return BAtohex(b);\n};KJUR.crypto.Util.getRandomBigIntegerOfNbits = function (a) {\n  return new BigInteger(KJUR.crypto.Util.getRandomHexOfNbits(a), 16);\n};KJUR.crypto.Util.getRandomBigIntegerZeroToMax = function (b) {\n  var a = b.bitLength();while (1) {\n    var c = KJUR.crypto.Util.getRandomBigIntegerOfNbits(a);if (b.compareTo(c) != -1) {\n      return c;\n    }\n  }\n};KJUR.crypto.Util.getRandomBigIntegerMinToMax = function (e, b) {\n  var c = e.compareTo(b);if (c == 1) {\n    throw \"biMin is greater than biMax\";\n  }if (c == 0) {\n    return e;\n  }var a = b.subtract(e);var d = KJUR.crypto.Util.getRandomBigIntegerZeroToMax(a);return d.add(e);\n};KJUR.crypto.MessageDigest = function (c) {\n  var b = null;var a = null;var d = null;this.setAlgAndProvider = function (g, f) {\n    g = KJUR.crypto.MessageDigest.getCanonicalAlgName(g);if (g !== null && f === undefined) {\n      f = KJUR.crypto.Util.DEFAULTPROVIDER[g];\n    }if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(g) != -1 && f == \"cryptojs\") {\n      try {\n        this.md = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[g].create();\n      } catch (e) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + g + \"/\" + e;\n      }this.updateString = function (h) {\n        this.md.update(h);\n      };this.updateHex = function (h) {\n        var i = CryptoJS.enc.Hex.parse(h);this.md.update(i);\n      };this.digest = function () {\n        var h = this.md.finalize();return h.toString(CryptoJS.enc.Hex);\n      };this.digestString = function (h) {\n        this.updateString(h);return this.digest();\n      };this.digestHex = function (h) {\n        this.updateHex(h);return this.digest();\n      };\n    }if (\":sha256:\".indexOf(g) != -1 && f == \"sjcl\") {\n      try {\n        this.md = new sjcl.hash.sha256();\n      } catch (e) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + g + \"/\" + e;\n      }this.updateString = function (h) {\n        this.md.update(h);\n      };this.updateHex = function (i) {\n        var h = sjcl.codec.hex.toBits(i);this.md.update(h);\n      };this.digest = function () {\n        var h = this.md.finalize();return sjcl.codec.hex.fromBits(h);\n      };this.digestString = function (h) {\n        this.updateString(h);return this.digest();\n      };this.digestHex = function (h) {\n        this.updateHex(h);return this.digest();\n      };\n    }\n  };this.updateString = function (e) {\n    throw \"updateString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.updateHex = function (e) {\n    throw \"updateHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digest = function () {\n    throw \"digest() not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digestString = function (e) {\n    throw \"digestString(str) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };this.digestHex = function (e) {\n    throw \"digestHex(hex) not supported for this alg/prov: \" + this.algName + \"/\" + this.provName;\n  };if (c !== undefined) {\n    if (c.alg !== undefined) {\n      this.algName = c.alg;if (c.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      }this.setAlgAndProvider(this.algName, this.provName);\n    }\n  }\n};KJUR.crypto.MessageDigest.getCanonicalAlgName = function (a) {\n  if (typeof a === \"string\") {\n    a = a.toLowerCase();a = a.replace(/-/, \"\");\n  }return a;\n};KJUR.crypto.MessageDigest.getHashLength = function (c) {\n  var b = KJUR.crypto.MessageDigest;var a = b.getCanonicalAlgName(c);if (b.HASHLENGTH[a] === undefined) {\n    throw \"not supported algorithm: \" + c;\n  }return b.HASHLENGTH[a];\n};KJUR.crypto.MessageDigest.HASHLENGTH = { md5: 16, sha1: 20, sha224: 28, sha256: 32, sha384: 48, sha512: 64, ripemd160: 20 };KJUR.crypto.Mac = function (d) {\n  var f = null;var c = null;var a = null;var e = null;var b = null;this.setAlgAndProvider = function (k, i) {\n    k = k.toLowerCase();if (k == null) {\n      k = \"hmacsha1\";\n    }k = k.toLowerCase();if (k.substr(0, 4) != \"hmac\") {\n      throw \"setAlgAndProvider unsupported HMAC alg: \" + k;\n    }if (i === undefined) {\n      i = KJUR.crypto.Util.DEFAULTPROVIDER[k];\n    }this.algProv = k + \"/\" + i;var g = k.substr(4);if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(g) != -1 && i == \"cryptojs\") {\n      try {\n        var j = KJUR.crypto.Util.CRYPTOJSMESSAGEDIGESTNAME[g];this.mac = CryptoJS.algo.HMAC.create(j, this.pass);\n      } catch (h) {\n        throw \"setAlgAndProvider hash alg set fail hashAlg=\" + g + \"/\" + h;\n      }this.updateString = function (l) {\n        this.mac.update(l);\n      };this.updateHex = function (l) {\n        var m = CryptoJS.enc.Hex.parse(l);this.mac.update(m);\n      };this.doFinal = function () {\n        var l = this.mac.finalize();return l.toString(CryptoJS.enc.Hex);\n      };this.doFinalString = function (l) {\n        this.updateString(l);return this.doFinal();\n      };this.doFinalHex = function (l) {\n        this.updateHex(l);return this.doFinal();\n      };\n    }\n  };this.updateString = function (g) {\n    throw \"updateString(str) not supported for this alg/prov: \" + this.algProv;\n  };this.updateHex = function (g) {\n    throw \"updateHex(hex) not supported for this alg/prov: \" + this.algProv;\n  };this.doFinal = function () {\n    throw \"digest() not supported for this alg/prov: \" + this.algProv;\n  };this.doFinalString = function (g) {\n    throw \"digestString(str) not supported for this alg/prov: \" + this.algProv;\n  };this.doFinalHex = function (g) {\n    throw \"digestHex(hex) not supported for this alg/prov: \" + this.algProv;\n  };this.setPassword = function (h) {\n    if (typeof h == \"string\") {\n      var g = h;if (h.length % 2 == 1 || !h.match(/^[0-9A-Fa-f]+$/)) {\n        g = rstrtohex(h);\n      }this.pass = CryptoJS.enc.Hex.parse(g);return;\n    }if ((typeof h === \"undefined\" ? \"undefined\" : _typeof(h)) != \"object\") {\n      throw \"KJUR.crypto.Mac unsupported password type: \" + h;\n    }var g = null;if (h.hex !== undefined) {\n      if (h.hex.length % 2 != 0 || !h.hex.match(/^[0-9A-Fa-f]+$/)) {\n        throw \"Mac: wrong hex password: \" + h.hex;\n      }g = h.hex;\n    }if (h.utf8 !== undefined) {\n      g = utf8tohex(h.utf8);\n    }if (h.rstr !== undefined) {\n      g = rstrtohex(h.rstr);\n    }if (h.b64 !== undefined) {\n      g = b64tohex(h.b64);\n    }if (h.b64u !== undefined) {\n      g = b64utohex(h.b64u);\n    }if (g == null) {\n      throw \"KJUR.crypto.Mac unsupported password type: \" + h;\n    }this.pass = CryptoJS.enc.Hex.parse(g);\n  };if (d !== undefined) {\n    if (d.pass !== undefined) {\n      this.setPassword(d.pass);\n    }if (d.alg !== undefined) {\n      this.algName = d.alg;if (d.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      }this.setAlgAndProvider(this.algName, this.provName);\n    }\n  }\n};KJUR.crypto.Signature = function (o) {\n  var q = null;var n = null;var r = null;var c = null;var l = null;var d = null;var k = null;var h = null;var p = null;var e = null;var b = -1;var g = null;var j = null;var a = null;var i = null;var f = null;this._setAlgNames = function () {\n    var s = this.algName.match(/^(.+)with(.+)$/);if (s) {\n      this.mdAlgName = s[1].toLowerCase();this.pubkeyAlgName = s[2].toLowerCase();\n    }\n  };this._zeroPaddingOfSignature = function (x, w) {\n    var v = \"\";var t = w / 4 - x.length;for (var u = 0; u < t; u++) {\n      v = v + \"0\";\n    }return v + x;\n  };this.setAlgAndProvider = function (u, t) {\n    this._setAlgNames();if (t != \"cryptojs/jsrsa\") {\n      throw \"provider not supported: \" + t;\n    }if (\":md5:sha1:sha224:sha256:sha384:sha512:ripemd160:\".indexOf(this.mdAlgName) != -1) {\n      try {\n        this.md = new KJUR.crypto.MessageDigest({ alg: this.mdAlgName });\n      } catch (s) {\n        throw \"setAlgAndProvider hash alg set fail alg=\" + this.mdAlgName + \"/\" + s;\n      }this.init = function (w, x) {\n        var y = null;try {\n          if (x === undefined) {\n            y = KEYUTIL.getKey(w);\n          } else {\n            y = KEYUTIL.getKey(w, x);\n          }\n        } catch (v) {\n          throw \"init failed:\" + v;\n        }if (y.isPrivate === true) {\n          this.prvKey = y;this.state = \"SIGN\";\n        } else {\n          if (y.isPublic === true) {\n            this.pubKey = y;this.state = \"VERIFY\";\n          } else {\n            throw \"init failed.:\" + y;\n          }\n        }\n      };this.updateString = function (v) {\n        this.md.updateString(v);\n      };this.updateHex = function (v) {\n        this.md.updateHex(v);\n      };this.sign = function () {\n        this.sHashHex = this.md.digest();if (typeof this.ecprvhex != \"undefined\" && typeof this.eccurvename != \"undefined\") {\n          var v = new KJUR.crypto.ECDSA({ curve: this.eccurvename });this.hSign = v.signHex(this.sHashHex, this.ecprvhex);\n        } else {\n          if (this.prvKey instanceof RSAKey && this.pubkeyAlgName === \"rsaandmgf1\") {\n            this.hSign = this.prvKey.signWithMessageHashPSS(this.sHashHex, this.mdAlgName, this.pssSaltLen);\n          } else {\n            if (this.prvKey instanceof RSAKey && this.pubkeyAlgName === \"rsa\") {\n              this.hSign = this.prvKey.signWithMessageHash(this.sHashHex, this.mdAlgName);\n            } else {\n              if (this.prvKey instanceof KJUR.crypto.ECDSA) {\n                this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n              } else {\n                if (this.prvKey instanceof KJUR.crypto.DSA) {\n                  this.hSign = this.prvKey.signWithMessageHash(this.sHashHex);\n                } else {\n                  throw \"Signature: unsupported private key alg: \" + this.pubkeyAlgName;\n                }\n              }\n            }\n          }\n        }return this.hSign;\n      };this.signString = function (v) {\n        this.updateString(v);return this.sign();\n      };this.signHex = function (v) {\n        this.updateHex(v);return this.sign();\n      };this.verify = function (v) {\n        this.sHashHex = this.md.digest();if (typeof this.ecpubhex != \"undefined\" && typeof this.eccurvename != \"undefined\") {\n          var w = new KJUR.crypto.ECDSA({ curve: this.eccurvename });return w.verifyHex(this.sHashHex, v, this.ecpubhex);\n        } else {\n          if (this.pubKey instanceof RSAKey && this.pubkeyAlgName === \"rsaandmgf1\") {\n            return this.pubKey.verifyWithMessageHashPSS(this.sHashHex, v, this.mdAlgName, this.pssSaltLen);\n          } else {\n            if (this.pubKey instanceof RSAKey && this.pubkeyAlgName === \"rsa\") {\n              return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n            } else {\n              if (KJUR.crypto.ECDSA !== undefined && this.pubKey instanceof KJUR.crypto.ECDSA) {\n                return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n              } else {\n                if (KJUR.crypto.DSA !== undefined && this.pubKey instanceof KJUR.crypto.DSA) {\n                  return this.pubKey.verifyWithMessageHash(this.sHashHex, v);\n                } else {\n                  throw \"Signature: unsupported public key alg: \" + this.pubkeyAlgName;\n                }\n              }\n            }\n          }\n        }\n      };\n    }\n  };this.init = function (s, t) {\n    throw \"init(key, pass) not supported for this alg:prov=\" + this.algProvName;\n  };this.updateString = function (s) {\n    throw \"updateString(str) not supported for this alg:prov=\" + this.algProvName;\n  };this.updateHex = function (s) {\n    throw \"updateHex(hex) not supported for this alg:prov=\" + this.algProvName;\n  };this.sign = function () {\n    throw \"sign() not supported for this alg:prov=\" + this.algProvName;\n  };this.signString = function (s) {\n    throw \"digestString(str) not supported for this alg:prov=\" + this.algProvName;\n  };this.signHex = function (s) {\n    throw \"digestHex(hex) not supported for this alg:prov=\" + this.algProvName;\n  };this.verify = function (s) {\n    throw \"verify(hSigVal) not supported for this alg:prov=\" + this.algProvName;\n  };this.initParams = o;if (o !== undefined) {\n    if (o.alg !== undefined) {\n      this.algName = o.alg;if (o.prov === undefined) {\n        this.provName = KJUR.crypto.Util.DEFAULTPROVIDER[this.algName];\n      } else {\n        this.provName = o.prov;\n      }this.algProvName = this.algName + \":\" + this.provName;this.setAlgAndProvider(this.algName, this.provName);this._setAlgNames();\n    }if (o.psssaltlen !== undefined) {\n      this.pssSaltLen = o.psssaltlen;\n    }if (o.prvkeypem !== undefined) {\n      if (o.prvkeypas !== undefined) {\n        throw \"both prvkeypem and prvkeypas parameters not supported\";\n      } else {\n        try {\n          var q = KEYUTIL.getKey(o.prvkeypem);this.init(q);\n        } catch (m) {\n          throw \"fatal error to load pem private key: \" + m;\n        }\n      }\n    }\n  }\n};KJUR.crypto.Cipher = function (a) {};KJUR.crypto.Cipher.encrypt = function (e, f, d) {\n  if (f instanceof RSAKey && f.isPublic) {\n    var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);if (c === \"RSA\") {\n      return f.encrypt(e);\n    }if (c === \"RSAOAEP\") {\n      return f.encryptOAEP(e, \"sha1\");\n    }var b = c.match(/^RSAOAEP(\\d+)$/);if (b !== null) {\n      return f.encryptOAEP(e, \"sha\" + b[1]);\n    }throw \"Cipher.encrypt: unsupported algorithm for RSAKey: \" + d;\n  } else {\n    throw \"Cipher.encrypt: unsupported key or algorithm\";\n  }\n};KJUR.crypto.Cipher.decrypt = function (e, f, d) {\n  if (f instanceof RSAKey && f.isPrivate) {\n    var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);if (c === \"RSA\") {\n      return f.decrypt(e);\n    }if (c === \"RSAOAEP\") {\n      return f.decryptOAEP(e, \"sha1\");\n    }var b = c.match(/^RSAOAEP(\\d+)$/);if (b !== null) {\n      return f.decryptOAEP(e, \"sha\" + b[1]);\n    }throw \"Cipher.decrypt: unsupported algorithm for RSAKey: \" + d;\n  } else {\n    throw \"Cipher.decrypt: unsupported key or algorithm\";\n  }\n};KJUR.crypto.Cipher.getAlgByKeyAndName = function (b, a) {\n  if (b instanceof RSAKey) {\n    if (\":RSA:RSAOAEP:RSAOAEP224:RSAOAEP256:RSAOAEP384:RSAOAEP512:\".indexOf(a) != -1) {\n      return a;\n    }if (a === null || a === undefined) {\n      return \"RSA\";\n    }throw \"getAlgByKeyAndName: not supported algorithm name for RSAKey: \" + a;\n  }throw \"getAlgByKeyAndName: not supported algorithm name: \" + a;\n};KJUR.crypto.OID = new function () {\n  this.oidhex2name = { \"2a864886f70d010101\": \"rsaEncryption\", \"2a8648ce3d0201\": \"ecPublicKey\", \"2a8648ce380401\": \"dsa\", \"2a8648ce3d030107\": \"secp256r1\", \"2b8104001f\": \"secp192k1\", \"2b81040021\": \"secp224r1\", \"2b8104000a\": \"secp256k1\", \"2b81040023\": \"secp521r1\", \"2b81040022\": \"secp384r1\", \"2a8648ce380403\": \"SHA1withDSA\", \"608648016503040301\": \"SHA224withDSA\", \"608648016503040302\": \"SHA256withDSA\" };\n}();\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.ECDSA = function (h) {\n  var e = \"secp256r1\";var g = null;var b = null;var f = null;var a = new SecureRandom();var d = null;this.type = \"EC\";this.isPrivate = false;this.isPublic = false;function c(s, o, r, n) {\n    var j = Math.max(o.bitLength(), n.bitLength());var t = s.add2D(r);var q = s.curve.getInfinity();for (var p = j - 1; p >= 0; --p) {\n      q = q.twice2D();q.z = BigInteger.ONE;if (o.testBit(p)) {\n        if (n.testBit(p)) {\n          q = q.add2D(t);\n        } else {\n          q = q.add2D(s);\n        }\n      } else {\n        if (n.testBit(p)) {\n          q = q.add2D(r);\n        }\n      }\n    }return q;\n  }this.getBigRandom = function (i) {\n    return new BigInteger(i.bitLength(), a).mod(i.subtract(BigInteger.ONE)).add(BigInteger.ONE);\n  };this.setNamedCurve = function (i) {\n    this.ecparams = KJUR.crypto.ECParameterDB.getByName(i);this.prvKeyHex = null;this.pubKeyHex = null;this.curveName = i;\n  };this.setPrivateKeyHex = function (i) {\n    this.isPrivate = true;this.prvKeyHex = i;\n  };this.setPublicKeyHex = function (i) {\n    this.isPublic = true;this.pubKeyHex = i;\n  };this.getPublicKeyXYHex = function () {\n    var k = this.pubKeyHex;if (k.substr(0, 2) !== \"04\") {\n      throw \"this method supports uncompressed format(04) only\";\n    }var j = this.ecparams.keylen / 4;if (k.length !== 2 + j * 2) {\n      throw \"malformed public key hex length\";\n    }var i = {};i.x = k.substr(2, j);i.y = k.substr(2 + j);return i;\n  };this.getShortNISTPCurveName = function () {\n    var i = this.curveName;if (i === \"secp256r1\" || i === \"NIST P-256\" || i === \"P-256\" || i === \"prime256v1\") {\n      return \"P-256\";\n    }if (i === \"secp384r1\" || i === \"NIST P-384\" || i === \"P-384\") {\n      return \"P-384\";\n    }return null;\n  };this.generateKeyPairHex = function () {\n    var k = this.ecparams.n;var n = this.getBigRandom(k);var l = this.ecparams.G.multiply(n);var q = l.getX().toBigInteger();var o = l.getY().toBigInteger();var i = this.ecparams.keylen / 4;var m = (\"0000000000\" + n.toString(16)).slice(-i);var r = (\"0000000000\" + q.toString(16)).slice(-i);var p = (\"0000000000\" + o.toString(16)).slice(-i);var j = \"04\" + r + p;this.setPrivateKeyHex(m);this.setPublicKeyHex(j);return { ecprvhex: m, ecpubhex: j };\n  };this.signWithMessageHash = function (i) {\n    return this.signHex(i, this.prvKeyHex);\n  };this.signHex = function (o, j) {\n    var t = new BigInteger(j, 16);var l = this.ecparams.n;var q = new BigInteger(o, 16);do {\n      var m = this.getBigRandom(l);var u = this.ecparams.G;var p = u.multiply(m);var i = p.getX().toBigInteger().mod(l);\n    } while (i.compareTo(BigInteger.ZERO) <= 0);var v = m.modInverse(l).multiply(q.add(t.multiply(i))).mod(l);return KJUR.crypto.ECDSA.biRSSigToASN1Sig(i, v);\n  };this.sign = function (m, u) {\n    var q = u;var j = this.ecparams.n;var p = BigInteger.fromByteArrayUnsigned(m);do {\n      var l = this.getBigRandom(j);var t = this.ecparams.G;var o = t.multiply(l);var i = o.getX().toBigInteger().mod(j);\n    } while (i.compareTo(BigInteger.ZERO) <= 0);var v = l.modInverse(j).multiply(p.add(q.multiply(i))).mod(j);return this.serializeSig(i, v);\n  };this.verifyWithMessageHash = function (j, i) {\n    return this.verifyHex(j, i, this.pubKeyHex);\n  };this.verifyHex = function (m, i, p) {\n    var l, j;var o = KJUR.crypto.ECDSA.parseSigHex(i);l = o.r;j = o.s;var k;k = ECPointFp.decodeFromHex(this.ecparams.curve, p);var n = new BigInteger(m, 16);return this.verifyRaw(n, l, j, k);\n  };this.verify = function (o, p, j) {\n    var l, i;if (Bitcoin.Util.isArray(p)) {\n      var n = this.parseSig(p);l = n.r;i = n.s;\n    } else {\n      if (\"object\" === (typeof p === \"undefined\" ? \"undefined\" : _typeof(p)) && p.r && p.s) {\n        l = p.r;i = p.s;\n      } else {\n        throw \"Invalid value for signature\";\n      }\n    }var k;if (j instanceof ECPointFp) {\n      k = j;\n    } else {\n      if (Bitcoin.Util.isArray(j)) {\n        k = ECPointFp.decodeFrom(this.ecparams.curve, j);\n      } else {\n        throw \"Invalid format for pubkey value, must be byte array or ECPointFp\";\n      }\n    }var m = BigInteger.fromByteArrayUnsigned(o);return this.verifyRaw(m, l, i, k);\n  };this.verifyRaw = function (o, i, w, m) {\n    var l = this.ecparams.n;var u = this.ecparams.G;if (i.compareTo(BigInteger.ONE) < 0 || i.compareTo(l) >= 0) {\n      return false;\n    }if (w.compareTo(BigInteger.ONE) < 0 || w.compareTo(l) >= 0) {\n      return false;\n    }var p = w.modInverse(l);var k = o.multiply(p).mod(l);var j = i.multiply(p).mod(l);var q = u.multiply(k).add(m.multiply(j));var t = q.getX().toBigInteger().mod(l);return t.equals(i);\n  };this.serializeSig = function (k, j) {\n    var l = k.toByteArraySigned();var i = j.toByteArraySigned();var m = [];m.push(2);m.push(l.length);m = m.concat(l);m.push(2);m.push(i.length);m = m.concat(i);m.unshift(m.length);m.unshift(48);return m;\n  };this.parseSig = function (n) {\n    var m;if (n[0] != 48) {\n      throw new Error(\"Signature not a valid DERSequence\");\n    }m = 2;if (n[m] != 2) {\n      throw new Error(\"First element in signature must be a DERInteger\");\n    }var l = n.slice(m + 2, m + 2 + n[m + 1]);m += 2 + n[m + 1];if (n[m] != 2) {\n      throw new Error(\"Second element in signature must be a DERInteger\");\n    }var i = n.slice(m + 2, m + 2 + n[m + 1]);m += 2 + n[m + 1];var k = BigInteger.fromByteArrayUnsigned(l);var j = BigInteger.fromByteArrayUnsigned(i);return { r: k, s: j };\n  };this.parseSigCompact = function (m) {\n    if (m.length !== 65) {\n      throw \"Signature has the wrong length\";\n    }var j = m[0] - 27;if (j < 0 || j > 7) {\n      throw \"Invalid signature type\";\n    }var o = this.ecparams.n;var l = BigInteger.fromByteArrayUnsigned(m.slice(1, 33)).mod(o);var k = BigInteger.fromByteArrayUnsigned(m.slice(33, 65)).mod(o);return { r: l, s: k, i: j };\n  };this.readPKCS5PrvKeyHex = function (l) {\n    var n = ASN1HEX;var m = KJUR.crypto.ECDSA.getName;var p = n.getVbyList;if (n.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var i, k, o;try {\n      i = p(l, 0, [2, 0], \"06\");k = p(l, 0, [1], \"04\");try {\n        o = p(l, 0, [3, 0], \"03\").substr(2);\n      } catch (j) {}\n    } catch (j) {\n      throw \"malformed PKCS#1/5 plain ECC private key\";\n    }this.curveName = m(i);if (this.curveName === undefined) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(o);this.setPrivateKeyHex(k);this.isPublic = false;\n  };this.readPKCS8PrvKeyHex = function (l) {\n    var q = ASN1HEX;var i = KJUR.crypto.ECDSA.getName;var n = q.getVbyList;if (q.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var j, p, m, k;try {\n      j = n(l, 0, [1, 0], \"06\");p = n(l, 0, [1, 1], \"06\");m = n(l, 0, [2, 0, 1], \"04\");try {\n        k = n(l, 0, [2, 0, 2, 0], \"03\").substr(2);\n      } catch (o) {}\n    } catch (o) {\n      throw \"malformed PKCS#8 plain ECC private key\";\n    }this.curveName = i(p);if (this.curveName === undefined) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(k);this.setPrivateKeyHex(m);this.isPublic = false;\n  };this.readPKCS8PubKeyHex = function (l) {\n    var n = ASN1HEX;var m = KJUR.crypto.ECDSA.getName;var p = n.getVbyList;if (n.isASN1HEX(l) === false) {\n      throw \"not ASN.1 hex string\";\n    }var k, i, o;try {\n      k = p(l, 0, [0, 0], \"06\");i = p(l, 0, [0, 1], \"06\");o = p(l, 0, [1], \"03\").substr(2);\n    } catch (j) {\n      throw \"malformed PKCS#8 ECC public key\";\n    }this.curveName = m(i);if (this.curveName === null) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(o);\n  };this.readCertPubKeyHex = function (k, p) {\n    if (p !== 5) {\n      p = 6;\n    }var m = ASN1HEX;var l = KJUR.crypto.ECDSA.getName;var o = m.getVbyList;if (m.isASN1HEX(k) === false) {\n      throw \"not ASN.1 hex string\";\n    }var i, n;try {\n      i = o(k, 0, [0, p, 0, 1], \"06\");n = o(k, 0, [0, p, 1], \"03\").substr(2);\n    } catch (j) {\n      throw \"malformed X.509 certificate ECC public key\";\n    }this.curveName = l(i);if (this.curveName === null) {\n      throw \"unsupported curve name\";\n    }this.setNamedCurve(this.curveName);this.setPublicKeyHex(n);\n  };if (h !== undefined) {\n    if (h.curve !== undefined) {\n      this.curveName = h.curve;\n    }\n  }if (this.curveName === undefined) {\n    this.curveName = e;\n  }this.setNamedCurve(this.curveName);if (h !== undefined) {\n    if (h.prv !== undefined) {\n      this.setPrivateKeyHex(h.prv);\n    }if (h.pub !== undefined) {\n      this.setPublicKeyHex(h.pub);\n    }\n  }\n};KJUR.crypto.ECDSA.parseSigHex = function (a) {\n  var b = KJUR.crypto.ECDSA.parseSigHexInHexRS(a);var d = new BigInteger(b.r, 16);var c = new BigInteger(b.s, 16);return { r: d, s: c };\n};KJUR.crypto.ECDSA.parseSigHexInHexRS = function (f) {\n  var j = ASN1HEX;var i = j.getChildIdx;var g = j.getV;if (f.substr(0, 2) != \"30\") {\n    throw \"signature is not a ASN.1 sequence\";\n  }var h = i(f, 0);if (h.length != 2) {\n    throw \"number of signature ASN.1 sequence elements seem wrong\";\n  }var e = h[0];var d = h[1];if (f.substr(e, 2) != \"02\") {\n    throw \"1st item of sequene of signature is not ASN.1 integer\";\n  }if (f.substr(d, 2) != \"02\") {\n    throw \"2nd item of sequene of signature is not ASN.1 integer\";\n  }var c = g(f, e);var b = g(f, d);return { r: c, s: b };\n};KJUR.crypto.ECDSA.asn1SigToConcatSig = function (c) {\n  var d = KJUR.crypto.ECDSA.parseSigHexInHexRS(c);var b = d.r;var a = d.s;if (b.substr(0, 2) == \"00\" && b.length % 32 == 2) {\n    b = b.substr(2);\n  }if (a.substr(0, 2) == \"00\" && a.length % 32 == 2) {\n    a = a.substr(2);\n  }if (b.length % 32 == 30) {\n    b = \"00\" + b;\n  }if (a.length % 32 == 30) {\n    a = \"00\" + a;\n  }if (b.length % 32 != 0) {\n    throw \"unknown ECDSA sig r length error\";\n  }if (a.length % 32 != 0) {\n    throw \"unknown ECDSA sig s length error\";\n  }return b + a;\n};KJUR.crypto.ECDSA.concatSigToASN1Sig = function (a) {\n  if (a.length / 2 * 8 % (16 * 8) != 0) {\n    throw \"unknown ECDSA concatinated r-s sig  length error\";\n  }var c = a.substr(0, a.length / 2);var b = a.substr(a.length / 2);return KJUR.crypto.ECDSA.hexRSSigToASN1Sig(c, b);\n};KJUR.crypto.ECDSA.hexRSSigToASN1Sig = function (b, a) {\n  var d = new BigInteger(b, 16);var c = new BigInteger(a, 16);return KJUR.crypto.ECDSA.biRSSigToASN1Sig(d, c);\n};KJUR.crypto.ECDSA.biRSSigToASN1Sig = function (f, d) {\n  var c = KJUR.asn1;var b = new c.DERInteger({ bigint: f });var a = new c.DERInteger({ bigint: d });var e = new c.DERSequence({ array: [b, a] });return e.getEncodedHex();\n};KJUR.crypto.ECDSA.getName = function (a) {\n  if (a === \"2a8648ce3d030107\") {\n    return \"secp256r1\";\n  }if (a === \"2b8104000a\") {\n    return \"secp256k1\";\n  }if (a === \"2b81040022\") {\n    return \"secp384r1\";\n  }if (\"|secp256r1|NIST P-256|P-256|prime256v1|\".indexOf(a) !== -1) {\n    return \"secp256r1\";\n  }if (\"|secp256k1|\".indexOf(a) !== -1) {\n    return \"secp256k1\";\n  }if (\"|secp384r1|NIST P-384|P-384|\".indexOf(a) !== -1) {\n    return \"secp384r1\";\n  }return null;\n};\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.crypto == \"undefined\" || !KJUR.crypto) {\n  KJUR.crypto = {};\n}KJUR.crypto.ECParameterDB = new function () {\n  var b = {};var c = {};function a(d) {\n    return new BigInteger(d, 16);\n  }this.getByName = function (e) {\n    var d = e;if (typeof c[d] != \"undefined\") {\n      d = c[e];\n    }if (typeof b[d] != \"undefined\") {\n      return b[d];\n    }throw \"unregistered EC curve name: \" + d;\n  };this.regist = function (A, l, o, g, m, e, j, f, k, u, d, x) {\n    b[A] = {};var s = a(o);var z = a(g);var y = a(m);var t = a(e);var w = a(j);var r = new ECCurveFp(s, z, y);var q = r.decodePointHex(\"04\" + f + k);b[A][\"name\"] = A;b[A][\"keylen\"] = l;b[A][\"curve\"] = r;b[A][\"G\"] = q;b[A][\"n\"] = t;b[A][\"h\"] = w;b[A][\"oid\"] = d;b[A][\"info\"] = x;for (var v = 0; v < u.length; v++) {\n      c[u[v]] = A;\n    }\n  };\n}();KJUR.crypto.ECParameterDB.regist(\"secp128r1\", 128, \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF\", \"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC\", \"E87579C11079F43DD824993C2CEE5ED3\", \"FFFFFFFE0000000075A30D1B9038A115\", \"1\", \"161FF7528B899B2D0C28607CA52C5B86\", \"CF5AC8395BAFEB13C02DA292DDED7A83\", [], \"\", \"secp128r1 : SECG curve over a 128 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp160k1\", 160, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73\", \"0\", \"7\", \"0100000000000000000001B8FA16DFAB9ACA16B6B3\", \"1\", \"3B4C382CE37AA192A4019E763036F4F5DD4D7EBB\", \"938CF935318FDCED6BC28286531733C3F03C4FEE\", [], \"\", \"secp160k1 : SECG curve over a 160 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp160r1\", 160, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC\", \"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45\", \"0100000000000000000001F4C8F927AED3CA752257\", \"1\", \"4A96B5688EF573284664698968C38BB913CBFC82\", \"23A628553168947D59DCC912042351377AC5FB32\", [], \"\", \"secp160r1 : SECG curve over a 160 bit prime field\");KJUR.crypto.ECParameterDB.regist(\"secp192k1\", 192, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37\", \"0\", \"3\", \"FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D\", \"1\", \"DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D\", \"9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D\", []);KJUR.crypto.ECParameterDB.regist(\"secp192r1\", 192, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC\", \"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1\", \"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831\", \"1\", \"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012\", \"07192B95FFC8DA78631011ED6B24CDD573F977A11E794811\", []);KJUR.crypto.ECParameterDB.regist(\"secp224r1\", 224, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE\", \"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D\", \"1\", \"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21\", \"BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34\", []);KJUR.crypto.ECParameterDB.regist(\"secp256k1\", 256, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F\", \"0\", \"7\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141\", \"1\", \"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798\", \"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8\", []);KJUR.crypto.ECParameterDB.regist(\"secp256r1\", 256, \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF\", \"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC\", \"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B\", \"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551\", \"1\", \"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296\", \"4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5\", [\"NIST P-256\", \"P-256\", \"prime256v1\"]);KJUR.crypto.ECParameterDB.regist(\"secp384r1\", 384, \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC\", \"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF\", \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973\", \"1\", \"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7\", \"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f\", [\"NIST P-384\", \"P-384\"]);KJUR.crypto.ECParameterDB.regist(\"secp521r1\", 521, \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\", \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC\", \"051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00\", \"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409\", \"1\", \"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66\", \"011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650\", [\"NIST P-521\", \"P-521\"]);\nvar KEYUTIL = function () {\n  var d = function d(p, r, q) {\n    return k(CryptoJS.AES, p, r, q);\n  };var e = function e(p, r, q) {\n    return k(CryptoJS.TripleDES, p, r, q);\n  };var a = function a(p, r, q) {\n    return k(CryptoJS.DES, p, r, q);\n  };var k = function k(s, x, u, q) {\n    var r = CryptoJS.enc.Hex.parse(x);var w = CryptoJS.enc.Hex.parse(u);var p = CryptoJS.enc.Hex.parse(q);var t = {};t.key = w;t.iv = p;t.ciphertext = r;var v = s.decrypt(t, w, { iv: p });return CryptoJS.enc.Hex.stringify(v);\n  };var l = function l(p, r, q) {\n    return g(CryptoJS.AES, p, r, q);\n  };var o = function o(p, r, q) {\n    return g(CryptoJS.TripleDES, p, r, q);\n  };var f = function f(p, r, q) {\n    return g(CryptoJS.DES, p, r, q);\n  };var g = function g(t, y, v, q) {\n    var s = CryptoJS.enc.Hex.parse(y);var x = CryptoJS.enc.Hex.parse(v);var p = CryptoJS.enc.Hex.parse(q);var w = t.encrypt(s, x, { iv: p });var r = CryptoJS.enc.Hex.parse(w.toString());var u = CryptoJS.enc.Base64.stringify(r);return u;\n  };var i = { \"AES-256-CBC\": { proc: d, eproc: l, keylen: 32, ivlen: 16 }, \"AES-192-CBC\": { proc: d, eproc: l, keylen: 24, ivlen: 16 }, \"AES-128-CBC\": { proc: d, eproc: l, keylen: 16, ivlen: 16 }, \"DES-EDE3-CBC\": { proc: e, eproc: o, keylen: 24, ivlen: 8 }, \"DES-CBC\": { proc: a, eproc: f, keylen: 8, ivlen: 8 } };var c = function c(p) {\n    return i[p][\"proc\"];\n  };var m = function m(p) {\n    var r = CryptoJS.lib.WordArray.random(p);var q = CryptoJS.enc.Hex.stringify(r);return q;\n  };var n = function n(v) {\n    var w = {};var q = v.match(new RegExp(\"DEK-Info: ([^,]+),([0-9A-Fa-f]+)\", \"m\"));if (q) {\n      w.cipher = q[1];w.ivsalt = q[2];\n    }var p = v.match(new RegExp(\"-----BEGIN ([A-Z]+) PRIVATE KEY-----\"));if (p) {\n      w.type = p[1];\n    }var u = -1;var x = 0;if (v.indexOf(\"\\r\\n\\r\\n\") != -1) {\n      u = v.indexOf(\"\\r\\n\\r\\n\");x = 2;\n    }if (v.indexOf(\"\\n\\n\") != -1) {\n      u = v.indexOf(\"\\n\\n\");x = 1;\n    }var t = v.indexOf(\"-----END\");if (u != -1 && t != -1) {\n      var r = v.substring(u + x * 2, t - x);r = r.replace(/\\s+/g, \"\");w.data = r;\n    }return w;\n  };var j = function j(q, y, p) {\n    var v = p.substring(0, 16);var t = CryptoJS.enc.Hex.parse(v);var r = CryptoJS.enc.Utf8.parse(y);var u = i[q][\"keylen\"] + i[q][\"ivlen\"];var x = \"\";var w = null;for (;;) {\n      var s = CryptoJS.algo.MD5.create();if (w != null) {\n        s.update(w);\n      }s.update(r);s.update(t);w = s.finalize();x = x + CryptoJS.enc.Hex.stringify(w);if (x.length >= u * 2) {\n        break;\n      }\n    }var z = {};z.keyhex = x.substr(0, i[q][\"keylen\"] * 2);z.ivhex = x.substr(i[q][\"keylen\"] * 2, i[q][\"ivlen\"] * 2);return z;\n  };var b = function b(p, v, r, w) {\n    var s = CryptoJS.enc.Base64.parse(p);var q = CryptoJS.enc.Hex.stringify(s);var u = i[v][\"proc\"];var t = u(q, r, w);return t;\n  };var h = function h(p, s, q, u) {\n    var r = i[s][\"eproc\"];var t = r(p, q, u);return t;\n  };return { version: \"1.0.0\", parsePKCS5PEM: function parsePKCS5PEM(p) {\n      return n(p);\n    }, getKeyAndUnusedIvByPasscodeAndIvsalt: function getKeyAndUnusedIvByPasscodeAndIvsalt(q, p, r) {\n      return j(q, p, r);\n    }, decryptKeyB64: function decryptKeyB64(p, r, q, s) {\n      return b(p, r, q, s);\n    }, getDecryptedKeyHex: function getDecryptedKeyHex(y, x) {\n      var q = n(y);var t = q.type;var r = q.cipher;var p = q.ivsalt;var s = q.data;var w = j(r, x, p);var v = w.keyhex;var u = b(s, r, v, p);return u;\n    }, getEncryptedPKCS5PEMFromPrvKeyHex: function getEncryptedPKCS5PEMFromPrvKeyHex(x, s, A, t, r) {\n      var p = \"\";if (typeof t == \"undefined\" || t == null) {\n        t = \"AES-256-CBC\";\n      }if (typeof i[t] == \"undefined\") {\n        throw \"KEYUTIL unsupported algorithm: \" + t;\n      }if (typeof r == \"undefined\" || r == null) {\n        var v = i[t][\"ivlen\"];var u = m(v);r = u.toUpperCase();\n      }var z = j(t, A, r);var y = z.keyhex;var w = h(s, t, y, r);var q = w.replace(/(.{64})/g, \"$1\\r\\n\");var p = \"-----BEGIN \" + x + \" PRIVATE KEY-----\\r\\n\";p += \"Proc-Type: 4,ENCRYPTED\\r\\n\";p += \"DEK-Info: \" + t + \",\" + r + \"\\r\\n\";p += \"\\r\\n\";p += q;p += \"\\r\\n-----END \" + x + \" PRIVATE KEY-----\\r\\n\";return p;\n    }, parseHexOfEncryptedPKCS8: function parseHexOfEncryptedPKCS8(y) {\n      var B = ASN1HEX;var z = B.getChildIdx;var w = B.getV;var t = {};var r = z(y, 0);if (r.length != 2) {\n        throw \"malformed format: SEQUENCE(0).items != 2: \" + r.length;\n      }t.ciphertext = w(y, r[1]);var A = z(y, r[0]);if (A.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0).items != 2: \" + A.length;\n      }if (w(y, A[0]) != \"2a864886f70d01050d\") {\n        throw \"this only supports pkcs5PBES2\";\n      }var p = z(y, A[1]);if (A.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1).items != 2: \" + p.length;\n      }var q = z(y, p[1]);if (q.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.1).items != 2: \" + q.length;\n      }if (w(y, q[0]) != \"2a864886f70d0307\") {\n        throw \"this only supports TripleDES\";\n      }t.encryptionSchemeAlg = \"TripleDES\";t.encryptionSchemeIV = w(y, q[1]);var s = z(y, p[0]);if (s.length != 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.0).items != 2: \" + s.length;\n      }if (w(y, s[0]) != \"2a864886f70d01050c\") {\n        throw \"this only supports pkcs5PBKDF2\";\n      }var x = z(y, s[1]);if (x.length < 2) {\n        throw \"malformed format: SEQUENCE(0.0.1.0.1).items < 2: \" + x.length;\n      }t.pbkdf2Salt = w(y, x[0]);var u = w(y, x[1]);try {\n        t.pbkdf2Iter = parseInt(u, 16);\n      } catch (v) {\n        throw \"malformed format pbkdf2Iter: \" + u;\n      }return t;\n    }, getPBKDF2KeyHexFromParam: function getPBKDF2KeyHexFromParam(u, p) {\n      var t = CryptoJS.enc.Hex.parse(u.pbkdf2Salt);var q = u.pbkdf2Iter;var s = CryptoJS.PBKDF2(p, t, { keySize: 192 / 32, iterations: q });var r = CryptoJS.enc.Hex.stringify(s);return r;\n    }, _getPlainPKCS8HexFromEncryptedPKCS8PEM: function _getPlainPKCS8HexFromEncryptedPKCS8PEM(x, y) {\n      var r = pemtohex(x, \"ENCRYPTED PRIVATE KEY\");var p = this.parseHexOfEncryptedPKCS8(r);var u = KEYUTIL.getPBKDF2KeyHexFromParam(p, y);var v = {};v.ciphertext = CryptoJS.enc.Hex.parse(p.ciphertext);var t = CryptoJS.enc.Hex.parse(u);var s = CryptoJS.enc.Hex.parse(p.encryptionSchemeIV);var w = CryptoJS.TripleDES.decrypt(v, t, { iv: s });var q = CryptoJS.enc.Hex.stringify(w);return q;\n    }, getKeyFromEncryptedPKCS8PEM: function getKeyFromEncryptedPKCS8PEM(s, q) {\n      var p = this._getPlainPKCS8HexFromEncryptedPKCS8PEM(s, q);var r = this.getKeyFromPlainPrivatePKCS8Hex(p);return r;\n    }, parsePlainPrivatePKCS8Hex: function parsePlainPrivatePKCS8Hex(s) {\n      var v = ASN1HEX;var u = v.getChildIdx;var t = v.getV;var q = {};q.algparam = null;if (s.substr(0, 2) != \"30\") {\n        throw \"malformed plain PKCS8 private key(code:001)\";\n      }var r = u(s, 0);if (r.length != 3) {\n        throw \"malformed plain PKCS8 private key(code:002)\";\n      }if (s.substr(r[1], 2) != \"30\") {\n        throw \"malformed PKCS8 private key(code:003)\";\n      }var p = u(s, r[1]);if (p.length != 2) {\n        throw \"malformed PKCS8 private key(code:004)\";\n      }if (s.substr(p[0], 2) != \"06\") {\n        throw \"malformed PKCS8 private key(code:005)\";\n      }q.algoid = t(s, p[0]);if (s.substr(p[1], 2) == \"06\") {\n        q.algparam = t(s, p[1]);\n      }if (s.substr(r[2], 2) != \"04\") {\n        throw \"malformed PKCS8 private key(code:006)\";\n      }q.keyidx = v.getVidx(s, r[2]);return q;\n    }, getKeyFromPlainPrivatePKCS8PEM: function getKeyFromPlainPrivatePKCS8PEM(q) {\n      var p = pemtohex(q, \"PRIVATE KEY\");var r = this.getKeyFromPlainPrivatePKCS8Hex(p);return r;\n    }, getKeyFromPlainPrivatePKCS8Hex: function getKeyFromPlainPrivatePKCS8Hex(p) {\n      var q = this.parsePlainPrivatePKCS8Hex(p);var r;if (q.algoid == \"2a864886f70d010101\") {\n        r = new RSAKey();\n      } else {\n        if (q.algoid == \"2a8648ce380401\") {\n          r = new KJUR.crypto.DSA();\n        } else {\n          if (q.algoid == \"2a8648ce3d0201\") {\n            r = new KJUR.crypto.ECDSA();\n          } else {\n            throw \"unsupported private key algorithm\";\n          }\n        }\n      }r.readPKCS8PrvKeyHex(p);return r;\n    }, _getKeyFromPublicPKCS8Hex: function _getKeyFromPublicPKCS8Hex(q) {\n      var p;var r = ASN1HEX.getVbyList(q, 0, [0, 0], \"06\");if (r === \"2a864886f70d010101\") {\n        p = new RSAKey();\n      } else {\n        if (r === \"2a8648ce380401\") {\n          p = new KJUR.crypto.DSA();\n        } else {\n          if (r === \"2a8648ce3d0201\") {\n            p = new KJUR.crypto.ECDSA();\n          } else {\n            throw \"unsupported PKCS#8 public key hex\";\n          }\n        }\n      }p.readPKCS8PubKeyHex(q);return p;\n    }, parsePublicRawRSAKeyHex: function parsePublicRawRSAKeyHex(r) {\n      var u = ASN1HEX;var t = u.getChildIdx;var s = u.getV;var p = {};if (r.substr(0, 2) != \"30\") {\n        throw \"malformed RSA key(code:001)\";\n      }var q = t(r, 0);if (q.length != 2) {\n        throw \"malformed RSA key(code:002)\";\n      }if (r.substr(q[0], 2) != \"02\") {\n        throw \"malformed RSA key(code:003)\";\n      }p.n = s(r, q[0]);if (r.substr(q[1], 2) != \"02\") {\n        throw \"malformed RSA key(code:004)\";\n      }p.e = s(r, q[1]);return p;\n    }, parsePublicPKCS8Hex: function parsePublicPKCS8Hex(t) {\n      var v = ASN1HEX;var u = v.getChildIdx;var s = v.getV;var q = {};q.algparam = null;var r = u(t, 0);if (r.length != 2) {\n        throw \"outer DERSequence shall have 2 elements: \" + r.length;\n      }var w = r[0];if (t.substr(w, 2) != \"30\") {\n        throw \"malformed PKCS8 public key(code:001)\";\n      }var p = u(t, w);if (p.length != 2) {\n        throw \"malformed PKCS8 public key(code:002)\";\n      }if (t.substr(p[0], 2) != \"06\") {\n        throw \"malformed PKCS8 public key(code:003)\";\n      }q.algoid = s(t, p[0]);if (t.substr(p[1], 2) == \"06\") {\n        q.algparam = s(t, p[1]);\n      } else {\n        if (t.substr(p[1], 2) == \"30\") {\n          q.algparam = {};q.algparam.p = v.getVbyList(t, p[1], [0], \"02\");q.algparam.q = v.getVbyList(t, p[1], [1], \"02\");q.algparam.g = v.getVbyList(t, p[1], [2], \"02\");\n        }\n      }if (t.substr(r[1], 2) != \"03\") {\n        throw \"malformed PKCS8 public key(code:004)\";\n      }q.key = s(t, r[1]).substr(2);return q;\n    } };\n}();KEYUTIL.getKey = function (l, k, n) {\n  var G = ASN1HEX,\n      L = G.getChildIdx,\n      v = G.getV,\n      d = G.getVbyList,\n      c = KJUR.crypto,\n      i = c.ECDSA,\n      C = c.DSA,\n      w = RSAKey,\n      M = pemtohex,\n      F = KEYUTIL;if (typeof w != \"undefined\" && l instanceof w) {\n    return l;\n  }if (typeof i != \"undefined\" && l instanceof i) {\n    return l;\n  }if (typeof C != \"undefined\" && l instanceof C) {\n    return l;\n  }if (l.curve !== undefined && l.xy !== undefined && l.d === undefined) {\n    return new i({ pub: l.xy, curve: l.curve });\n  }if (l.curve !== undefined && l.d !== undefined) {\n    return new i({ prv: l.d, curve: l.curve });\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d === undefined) {\n    var P = new w();P.setPublic(l.n, l.e);return P;\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p !== undefined && l.q !== undefined && l.dp !== undefined && l.dq !== undefined && l.co !== undefined && l.qi === undefined) {\n    var P = new w();P.setPrivateEx(l.n, l.e, l.d, l.p, l.q, l.dp, l.dq, l.co);return P;\n  }if (l.kty === undefined && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p === undefined) {\n    var P = new w();P.setPrivate(l.n, l.e, l.d);return P;\n  }if (l.p !== undefined && l.q !== undefined && l.g !== undefined && l.y !== undefined && l.x === undefined) {\n    var P = new C();P.setPublic(l.p, l.q, l.g, l.y);return P;\n  }if (l.p !== undefined && l.q !== undefined && l.g !== undefined && l.y !== undefined && l.x !== undefined) {\n    var P = new C();P.setPrivate(l.p, l.q, l.g, l.y, l.x);return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d === undefined) {\n    var P = new w();P.setPublic(b64utohex(l.n), b64utohex(l.e));return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d !== undefined && l.p !== undefined && l.q !== undefined && l.dp !== undefined && l.dq !== undefined && l.qi !== undefined) {\n    var P = new w();P.setPrivateEx(b64utohex(l.n), b64utohex(l.e), b64utohex(l.d), b64utohex(l.p), b64utohex(l.q), b64utohex(l.dp), b64utohex(l.dq), b64utohex(l.qi));return P;\n  }if (l.kty === \"RSA\" && l.n !== undefined && l.e !== undefined && l.d !== undefined) {\n    var P = new w();P.setPrivate(b64utohex(l.n), b64utohex(l.e), b64utohex(l.d));return P;\n  }if (l.kty === \"EC\" && l.crv !== undefined && l.x !== undefined && l.y !== undefined && l.d === undefined) {\n    var j = new i({ curve: l.crv });var t = j.ecparams.keylen / 4;var B = (\"0000000000\" + b64utohex(l.x)).slice(-t);var z = (\"0000000000\" + b64utohex(l.y)).slice(-t);var u = \"04\" + B + z;j.setPublicKeyHex(u);return j;\n  }if (l.kty === \"EC\" && l.crv !== undefined && l.x !== undefined && l.y !== undefined && l.d !== undefined) {\n    var j = new i({ curve: l.crv });var t = j.ecparams.keylen / 4;var B = (\"0000000000\" + b64utohex(l.x)).slice(-t);var z = (\"0000000000\" + b64utohex(l.y)).slice(-t);var u = \"04\" + B + z;var b = (\"0000000000\" + b64utohex(l.d)).slice(-t);j.setPublicKeyHex(u);j.setPrivateKeyHex(b);return j;\n  }if (n === \"pkcs5prv\") {\n    var J = l,\n        G = ASN1HEX,\n        N,\n        P;N = L(J, 0);if (N.length === 9) {\n      P = new w();P.readPKCS5PrvKeyHex(J);\n    } else {\n      if (N.length === 6) {\n        P = new C();P.readPKCS5PrvKeyHex(J);\n      } else {\n        if (N.length > 2 && J.substr(N[1], 2) === \"04\") {\n          P = new i();P.readPKCS5PrvKeyHex(J);\n        } else {\n          throw \"unsupported PKCS#1/5 hexadecimal key\";\n        }\n      }\n    }return P;\n  }if (n === \"pkcs8prv\") {\n    var P = F.getKeyFromPlainPrivatePKCS8Hex(l);return P;\n  }if (n === \"pkcs8pub\") {\n    return F._getKeyFromPublicPKCS8Hex(l);\n  }if (n === \"x509pub\") {\n    return X509.getPublicKeyFromCertHex(l);\n  }if (l.indexOf(\"-END CERTIFICATE-\", 0) != -1 || l.indexOf(\"-END X509 CERTIFICATE-\", 0) != -1 || l.indexOf(\"-END TRUSTED CERTIFICATE-\", 0) != -1) {\n    return X509.getPublicKeyFromCertPEM(l);\n  }if (l.indexOf(\"-END PUBLIC KEY-\") != -1) {\n    var O = pemtohex(l, \"PUBLIC KEY\");return F._getKeyFromPublicPKCS8Hex(O);\n  }if (l.indexOf(\"-END RSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") == -1) {\n    var m = M(l, \"RSA PRIVATE KEY\");return F.getKey(m, null, \"pkcs5prv\");\n  }if (l.indexOf(\"-END DSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") == -1) {\n    var I = M(l, \"DSA PRIVATE KEY\");var E = d(I, 0, [1], \"02\");var D = d(I, 0, [2], \"02\");var K = d(I, 0, [3], \"02\");var r = d(I, 0, [4], \"02\");var s = d(I, 0, [5], \"02\");var P = new C();P.setPrivate(new BigInteger(E, 16), new BigInteger(D, 16), new BigInteger(K, 16), new BigInteger(r, 16), new BigInteger(s, 16));return P;\n  }if (l.indexOf(\"-END PRIVATE KEY-\") != -1) {\n    return F.getKeyFromPlainPrivatePKCS8PEM(l);\n  }if (l.indexOf(\"-END RSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var o = F.getDecryptedKeyHex(l, k);var H = new RSAKey();H.readPKCS5PrvKeyHex(o);return H;\n  }if (l.indexOf(\"-END EC PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var I = F.getDecryptedKeyHex(l, k);var P = d(I, 0, [1], \"04\");var f = d(I, 0, [2, 0], \"06\");var A = d(I, 0, [3, 0], \"03\").substr(2);var e = \"\";if (KJUR.crypto.OID.oidhex2name[f] !== undefined) {\n      e = KJUR.crypto.OID.oidhex2name[f];\n    } else {\n      throw \"undefined OID(hex) in KJUR.crypto.OID: \" + f;\n    }var j = new i({ curve: e });j.setPublicKeyHex(A);j.setPrivateKeyHex(P);j.isPublic = false;return j;\n  }if (l.indexOf(\"-END DSA PRIVATE KEY-\") != -1 && l.indexOf(\"4,ENCRYPTED\") != -1) {\n    var I = F.getDecryptedKeyHex(l, k);var E = d(I, 0, [1], \"02\");var D = d(I, 0, [2], \"02\");var K = d(I, 0, [3], \"02\");var r = d(I, 0, [4], \"02\");var s = d(I, 0, [5], \"02\");var P = new C();P.setPrivate(new BigInteger(E, 16), new BigInteger(D, 16), new BigInteger(K, 16), new BigInteger(r, 16), new BigInteger(s, 16));return P;\n  }if (l.indexOf(\"-END ENCRYPTED PRIVATE KEY-\") != -1) {\n    return F.getKeyFromEncryptedPKCS8PEM(l, k);\n  }throw \"not supported argument\";\n};KEYUTIL.generateKeypair = function (a, c) {\n  if (a == \"RSA\") {\n    var b = c;var h = new RSAKey();h.generate(b, \"10001\");h.isPrivate = true;h.isPublic = true;var f = new RSAKey();var e = h.n.toString(16);var i = h.e.toString(16);f.setPublic(e, i);f.isPrivate = false;f.isPublic = true;var k = {};k.prvKeyObj = h;k.pubKeyObj = f;return k;\n  } else {\n    if (a == \"EC\") {\n      var d = c;var g = new KJUR.crypto.ECDSA({ curve: d });var j = g.generateKeyPairHex();var h = new KJUR.crypto.ECDSA({ curve: d });h.setPublicKeyHex(j.ecpubhex);h.setPrivateKeyHex(j.ecprvhex);h.isPrivate = true;h.isPublic = false;var f = new KJUR.crypto.ECDSA({ curve: d });f.setPublicKeyHex(j.ecpubhex);f.isPrivate = false;f.isPublic = true;var k = {};k.prvKeyObj = h;k.pubKeyObj = f;return k;\n    } else {\n      throw \"unknown algorithm: \" + a;\n    }\n  }\n};KEYUTIL.getPEM = function (b, D, y, m, q, j) {\n  var F = KJUR,\n      k = F.asn1,\n      z = k.DERObjectIdentifier,\n      f = k.DERInteger,\n      l = k.ASN1Util.newObject,\n      a = k.x509,\n      C = a.SubjectPublicKeyInfo,\n      e = F.crypto,\n      u = e.DSA,\n      r = e.ECDSA,\n      n = RSAKey;function A(s) {\n    var G = l({ seq: [{ \"int\": 0 }, { \"int\": { bigint: s.n } }, { \"int\": s.e }, { \"int\": { bigint: s.d } }, { \"int\": { bigint: s.p } }, { \"int\": { bigint: s.q } }, { \"int\": { bigint: s.dmp1 } }, { \"int\": { bigint: s.dmq1 } }, { \"int\": { bigint: s.coeff } }] });return G;\n  }function B(G) {\n    var s = l({ seq: [{ \"int\": 1 }, { octstr: { hex: G.prvKeyHex } }, { tag: [\"a0\", true, { oid: { name: G.curveName } }] }, { tag: [\"a1\", true, { bitstr: { hex: \"00\" + G.pubKeyHex } }] }] });return s;\n  }function x(s) {\n    var G = l({ seq: [{ \"int\": 0 }, { \"int\": { bigint: s.p } }, { \"int\": { bigint: s.q } }, { \"int\": { bigint: s.g } }, { \"int\": { bigint: s.y } }, { \"int\": { bigint: s.x } }] });return G;\n  }if ((n !== undefined && b instanceof n || u !== undefined && b instanceof u || r !== undefined && b instanceof r) && b.isPublic == true && (D === undefined || D == \"PKCS8PUB\")) {\n    var E = new C(b);var w = E.getEncodedHex();return hextopem(w, \"PUBLIC KEY\");\n  }if (D == \"PKCS1PRV\" && n !== undefined && b instanceof n && (y === undefined || y == null) && b.isPrivate == true) {\n    var E = A(b);var w = E.getEncodedHex();return hextopem(w, \"RSA PRIVATE KEY\");\n  }if (D == \"PKCS1PRV\" && r !== undefined && b instanceof r && (y === undefined || y == null) && b.isPrivate == true) {\n    var i = new z({ name: b.curveName });var v = i.getEncodedHex();var h = B(b);var t = h.getEncodedHex();var p = \"\";p += hextopem(v, \"EC PARAMETERS\");p += hextopem(t, \"EC PRIVATE KEY\");return p;\n  }if (D == \"PKCS1PRV\" && u !== undefined && b instanceof u && (y === undefined || y == null) && b.isPrivate == true) {\n    var E = x(b);var w = E.getEncodedHex();return hextopem(w, \"DSA PRIVATE KEY\");\n  }if (D == \"PKCS5PRV\" && n !== undefined && b instanceof n && y !== undefined && y != null && b.isPrivate == true) {\n    var E = A(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"RSA\", w, y, m, j);\n  }if (D == \"PKCS5PRV\" && r !== undefined && b instanceof r && y !== undefined && y != null && b.isPrivate == true) {\n    var E = B(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"EC\", w, y, m, j);\n  }if (D == \"PKCS5PRV\" && u !== undefined && b instanceof u && y !== undefined && y != null && b.isPrivate == true) {\n    var E = x(b);var w = E.getEncodedHex();if (m === undefined) {\n      m = \"DES-EDE3-CBC\";\n    }return this.getEncryptedPKCS5PEMFromPrvKeyHex(\"DSA\", w, y, m, j);\n  }var o = function o(G, s) {\n    var I = c(G, s);var H = new l({ seq: [{ seq: [{ oid: { name: \"pkcs5PBES2\" } }, { seq: [{ seq: [{ oid: { name: \"pkcs5PBKDF2\" } }, { seq: [{ octstr: { hex: I.pbkdf2Salt } }, { \"int\": I.pbkdf2Iter }] }] }, { seq: [{ oid: { name: \"des-EDE3-CBC\" } }, { octstr: { hex: I.encryptionSchemeIV } }] }] }] }, { octstr: { hex: I.ciphertext } }] });return H.getEncodedHex();\n  };var c = function c(N, O) {\n    var H = 100;var M = CryptoJS.lib.WordArray.random(8);var L = \"DES-EDE3-CBC\";var s = CryptoJS.lib.WordArray.random(8);var I = CryptoJS.PBKDF2(O, M, { keySize: 192 / 32, iterations: H });var J = CryptoJS.enc.Hex.parse(N);var K = CryptoJS.TripleDES.encrypt(J, I, { iv: s }) + \"\";var G = {};G.ciphertext = K;G.pbkdf2Salt = CryptoJS.enc.Hex.stringify(M);G.pbkdf2Iter = H;G.encryptionSchemeAlg = L;G.encryptionSchemeIV = CryptoJS.enc.Hex.stringify(s);return G;\n  };if (D == \"PKCS8PRV\" && n != undefined && b instanceof n && b.isPrivate == true) {\n    var g = A(b);var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"rsaEncryption\" } }, { \"null\": true }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }if (D == \"PKCS8PRV\" && r !== undefined && b instanceof r && b.isPrivate == true) {\n    var g = new l({ seq: [{ \"int\": 1 }, { octstr: { hex: b.prvKeyHex } }, { tag: [\"a1\", true, { bitstr: { hex: \"00\" + b.pubKeyHex } }] }] });var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"ecPublicKey\" } }, { oid: { name: b.curveName } }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }if (D == \"PKCS8PRV\" && u !== undefined && b instanceof u && b.isPrivate == true) {\n    var g = new f({ bigint: b.x });var d = g.getEncodedHex();var E = l({ seq: [{ \"int\": 0 }, { seq: [{ oid: { name: \"dsa\" } }, { seq: [{ \"int\": { bigint: b.p } }, { \"int\": { bigint: b.q } }, { \"int\": { bigint: b.g } }] }] }, { octstr: { hex: d } }] });var w = E.getEncodedHex();if (y === undefined || y == null) {\n      return hextopem(w, \"PRIVATE KEY\");\n    } else {\n      var t = o(w, y);return hextopem(t, \"ENCRYPTED PRIVATE KEY\");\n    }\n  }throw \"unsupported object nor format\";\n};KEYUTIL.getKeyFromCSRPEM = function (b) {\n  var a = pemtohex(b, \"CERTIFICATE REQUEST\");var c = KEYUTIL.getKeyFromCSRHex(a);return c;\n};KEYUTIL.getKeyFromCSRHex = function (a) {\n  var c = KEYUTIL.parseCSRHex(a);var b = KEYUTIL.getKey(c.p8pubkeyhex, null, \"pkcs8pub\");return b;\n};KEYUTIL.parseCSRHex = function (d) {\n  var i = ASN1HEX;var f = i.getChildIdx;var c = i.getTLV;var b = {};var g = d;if (g.substr(0, 2) != \"30\") {\n    throw \"malformed CSR(code:001)\";\n  }var e = f(g, 0);if (e.length < 1) {\n    throw \"malformed CSR(code:002)\";\n  }if (g.substr(e[0], 2) != \"30\") {\n    throw \"malformed CSR(code:003)\";\n  }var a = f(g, e[0]);if (a.length < 3) {\n    throw \"malformed CSR(code:004)\";\n  }b.p8pubkeyhex = c(g, a[2]);return b;\n};KEYUTIL.getJWKFromKey = function (d) {\n  var b = {};if (d instanceof RSAKey && d.isPrivate) {\n    b.kty = \"RSA\";b.n = hextob64u(d.n.toString(16));b.e = hextob64u(d.e.toString(16));b.d = hextob64u(d.d.toString(16));b.p = hextob64u(d.p.toString(16));b.q = hextob64u(d.q.toString(16));b.dp = hextob64u(d.dmp1.toString(16));b.dq = hextob64u(d.dmq1.toString(16));b.qi = hextob64u(d.coeff.toString(16));return b;\n  } else {\n    if (d instanceof RSAKey && d.isPublic) {\n      b.kty = \"RSA\";b.n = hextob64u(d.n.toString(16));b.e = hextob64u(d.e.toString(16));return b;\n    } else {\n      if (d instanceof KJUR.crypto.ECDSA && d.isPrivate) {\n        var a = d.getShortNISTPCurveName();if (a !== \"P-256\" && a !== \"P-384\") {\n          throw \"unsupported curve name for JWT: \" + a;\n        }var c = d.getPublicKeyXYHex();b.kty = \"EC\";b.crv = a;b.x = hextob64u(c.x);b.y = hextob64u(c.y);b.d = hextob64u(d.prvKeyHex);return b;\n      } else {\n        if (d instanceof KJUR.crypto.ECDSA && d.isPublic) {\n          var a = d.getShortNISTPCurveName();if (a !== \"P-256\" && a !== \"P-384\") {\n            throw \"unsupported curve name for JWT: \" + a;\n          }var c = d.getPublicKeyXYHex();b.kty = \"EC\";b.crv = a;b.x = hextob64u(c.x);b.y = hextob64u(c.y);return b;\n        }\n      }\n    }\n  }throw \"not supported key object\";\n};\nRSAKey.getPosArrayOfChildrenFromHex = function (a) {\n  return ASN1HEX.getChildIdx(a, 0);\n};RSAKey.getHexValueArrayOfChildrenFromHex = function (f) {\n  var n = ASN1HEX;var i = n.getV;var k = RSAKey.getPosArrayOfChildrenFromHex(f);var e = i(f, k[0]);var j = i(f, k[1]);var b = i(f, k[2]);var c = i(f, k[3]);var h = i(f, k[4]);var g = i(f, k[5]);var m = i(f, k[6]);var l = i(f, k[7]);var d = i(f, k[8]);var k = new Array();k.push(e, j, b, c, h, g, m, l, d);return k;\n};RSAKey.prototype.readPrivateKeyFromPEMString = function (d) {\n  var c = pemtohex(d);var b = RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]);\n};RSAKey.prototype.readPKCS5PrvKeyHex = function (c) {\n  var b = RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]);\n};RSAKey.prototype.readPKCS8PrvKeyHex = function (e) {\n  var c, j, l, b, a, f, d, k;var m = ASN1HEX;var g = m.getVbyList;if (m.isASN1HEX(e) === false) {\n    throw \"not ASN.1 hex string\";\n  }try {\n    c = g(e, 0, [2, 0, 1], \"02\");j = g(e, 0, [2, 0, 2], \"02\");l = g(e, 0, [2, 0, 3], \"02\");b = g(e, 0, [2, 0, 4], \"02\");a = g(e, 0, [2, 0, 5], \"02\");f = g(e, 0, [2, 0, 6], \"02\");d = g(e, 0, [2, 0, 7], \"02\");k = g(e, 0, [2, 0, 8], \"02\");\n  } catch (i) {\n    throw \"malformed PKCS#8 plain RSA private key\";\n  }this.setPrivateEx(c, j, l, b, a, f, d, k);\n};RSAKey.prototype.readPKCS5PubKeyHex = function (c) {\n  var e = ASN1HEX;var b = e.getV;if (e.isASN1HEX(c) === false) {\n    throw \"keyHex is not ASN.1 hex string\";\n  }var a = e.getChildIdx(c, 0);if (a.length !== 2 || c.substr(a[0], 2) !== \"02\" || c.substr(a[1], 2) !== \"02\") {\n    throw \"wrong hex for PKCS#5 public key\";\n  }var f = b(c, a[0]);var d = b(c, a[1]);this.setPublic(f, d);\n};RSAKey.prototype.readPKCS8PubKeyHex = function (b) {\n  var c = ASN1HEX;if (c.isASN1HEX(b) === false) {\n    throw \"not ASN.1 hex string\";\n  }if (c.getTLVbyList(b, 0, [0, 0]) !== \"06092a864886f70d010101\") {\n    throw \"not PKCS8 RSA public key\";\n  }var a = c.getTLVbyList(b, 0, [1, 0]);this.readPKCS5PubKeyHex(a);\n};RSAKey.prototype.readCertPubKeyHex = function (b, d) {\n  var a, c;a = new X509();a.readCertHex(b);c = a.getPublicKeyHex();this.readPKCS8PubKeyHex(c);\n};\nvar _RE_HEXDECONLY = new RegExp(\"\");_RE_HEXDECONLY.compile(\"[^0-9a-f]\", \"gi\");function _rsasign_getHexPaddedDigestInfoForString(d, e, a) {\n  var b = function b(f) {\n    return KJUR.crypto.Util.hashString(f, a);\n  };var c = b(d);return KJUR.crypto.Util.getPaddedDigestInfoHex(c, a, e);\n}function _zeroPaddingOfSignature(e, d) {\n  var c = \"\";var a = d / 4 - e.length;for (var b = 0; b < a; b++) {\n    c = c + \"0\";\n  }return c + e;\n}RSAKey.prototype.sign = function (d, a) {\n  var b = function b(e) {\n    return KJUR.crypto.Util.hashString(e, a);\n  };var c = b(d);return this.signWithMessageHash(c, a);\n};RSAKey.prototype.signWithMessageHash = function (e, c) {\n  var f = KJUR.crypto.Util.getPaddedDigestInfoHex(e, c, this.n.bitLength());var b = parseBigInt(f, 16);var d = this.doPrivate(b);var a = d.toString(16);return _zeroPaddingOfSignature(a, this.n.bitLength());\n};function pss_mgf1_str(c, a, e) {\n  var b = \"\",\n      d = 0;while (b.length < a) {\n    b += hextorstr(e(rstrtohex(c + String.fromCharCode.apply(String, [(d & 4278190080) >> 24, (d & 16711680) >> 16, (d & 65280) >> 8, d & 255]))));d += 1;\n  }return b;\n}RSAKey.prototype.signPSS = function (e, a, d) {\n  var c = function c(f) {\n    return KJUR.crypto.Util.hashHex(f, a);\n  };var b = c(rstrtohex(e));if (d === undefined) {\n    d = -1;\n  }return this.signWithMessageHashPSS(b, a, d);\n};RSAKey.prototype.signWithMessageHashPSS = function (l, a, k) {\n  var b = hextorstr(l);var g = b.length;var m = this.n.bitLength() - 1;var c = Math.ceil(m / 8);var d;var o = function o(i) {\n    return KJUR.crypto.Util.hashHex(i, a);\n  };if (k === -1 || k === undefined) {\n    k = g;\n  } else {\n    if (k === -2) {\n      k = c - g - 2;\n    } else {\n      if (k < -2) {\n        throw \"invalid salt length\";\n      }\n    }\n  }if (c < g + k + 2) {\n    throw \"data too long\";\n  }var f = \"\";if (k > 0) {\n    f = new Array(k);new SecureRandom().nextBytes(f);f = String.fromCharCode.apply(String, f);\n  }var n = hextorstr(o(rstrtohex(\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + b + f)));var j = [];for (d = 0; d < c - k - g - 2; d += 1) {\n    j[d] = 0;\n  }var e = String.fromCharCode.apply(String, j) + \"\\x01\" + f;var h = pss_mgf1_str(n, e.length, o);var q = [];for (d = 0; d < e.length; d += 1) {\n    q[d] = e.charCodeAt(d) ^ h.charCodeAt(d);\n  }var p = 65280 >> 8 * c - m & 255;q[0] &= ~p;for (d = 0; d < g; d++) {\n    q.push(n.charCodeAt(d));\n  }q.push(188);return _zeroPaddingOfSignature(this.doPrivate(new BigInteger(q)).toString(16), this.n.bitLength());\n};function _rsasign_getDecryptSignatureBI(a, d, c) {\n  var b = new RSAKey();b.setPublic(d, c);var e = b.doPublic(a);return e;\n}function _rsasign_getHexDigestInfoFromSig(a, c, b) {\n  var e = _rsasign_getDecryptSignatureBI(a, c, b);var d = e.toString(16).replace(/^1f+00/, \"\");return d;\n}function _rsasign_getAlgNameAndHashFromHexDisgestInfo(f) {\n  for (var e in KJUR.crypto.Util.DIGESTINFOHEAD) {\n    var d = KJUR.crypto.Util.DIGESTINFOHEAD[e];var b = d.length;if (f.substring(0, b) == d) {\n      var c = [e, f.substring(b)];return c;\n    }\n  }return [];\n}RSAKey.prototype.verify = function (f, j) {\n  j = j.replace(_RE_HEXDECONLY, \"\");j = j.replace(/[ \\n]+/g, \"\");var b = parseBigInt(j, 16);if (b.bitLength() > this.n.bitLength()) {\n    return 0;\n  }var i = this.doPublic(b);var e = i.toString(16).replace(/^1f+00/, \"\");var g = _rsasign_getAlgNameAndHashFromHexDisgestInfo(e);if (g.length == 0) {\n    return false;\n  }var d = g[0];var h = g[1];var a = function a(k) {\n    return KJUR.crypto.Util.hashString(k, d);\n  };var c = a(f);return h == c;\n};RSAKey.prototype.verifyWithMessageHash = function (e, a) {\n  a = a.replace(_RE_HEXDECONLY, \"\");a = a.replace(/[ \\n]+/g, \"\");var b = parseBigInt(a, 16);if (b.bitLength() > this.n.bitLength()) {\n    return 0;\n  }var h = this.doPublic(b);var g = h.toString(16).replace(/^1f+00/, \"\");var c = _rsasign_getAlgNameAndHashFromHexDisgestInfo(g);if (c.length == 0) {\n    return false;\n  }var d = c[0];var f = c[1];return f == e;\n};RSAKey.prototype.verifyPSS = function (c, b, a, f) {\n  var e = function e(g) {\n    return KJUR.crypto.Util.hashHex(g, a);\n  };var d = e(rstrtohex(c));if (f === undefined) {\n    f = -1;\n  }return this.verifyWithMessageHashPSS(d, b, a, f);\n};RSAKey.prototype.verifyWithMessageHashPSS = function (f, s, l, c) {\n  var k = new BigInteger(s, 16);if (k.bitLength() > this.n.bitLength()) {\n    return false;\n  }var r = function r(i) {\n    return KJUR.crypto.Util.hashHex(i, l);\n  };var j = hextorstr(f);var h = j.length;var g = this.n.bitLength() - 1;var m = Math.ceil(g / 8);var q;if (c === -1 || c === undefined) {\n    c = h;\n  } else {\n    if (c === -2) {\n      c = m - h - 2;\n    } else {\n      if (c < -2) {\n        throw \"invalid salt length\";\n      }\n    }\n  }if (m < h + c + 2) {\n    throw \"data too long\";\n  }var a = this.doPublic(k).toByteArray();for (q = 0; q < a.length; q += 1) {\n    a[q] &= 255;\n  }while (a.length < m) {\n    a.unshift(0);\n  }if (a[m - 1] !== 188) {\n    throw \"encoded message does not end in 0xbc\";\n  }a = String.fromCharCode.apply(String, a);var d = a.substr(0, m - h - 1);var e = a.substr(d.length, h);var p = 65280 >> 8 * m - g & 255;if ((d.charCodeAt(0) & p) !== 0) {\n    throw \"bits beyond keysize not zero\";\n  }var n = pss_mgf1_str(e, d.length, r);var o = [];for (q = 0; q < d.length; q += 1) {\n    o[q] = d.charCodeAt(q) ^ n.charCodeAt(q);\n  }o[0] &= ~p;var b = m - h - c - 2;for (q = 0; q < b; q += 1) {\n    if (o[q] !== 0) {\n      throw \"leftmost octets not zero\";\n    }\n  }if (o[b] !== 1) {\n    throw \"0x01 marker not found\";\n  }return e === hextorstr(r(rstrtohex(\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\" + j + String.fromCharCode.apply(String, o.slice(-c)))));\n};RSAKey.SALT_LEN_HLEN = -1;RSAKey.SALT_LEN_MAX = -2;RSAKey.SALT_LEN_RECOVER = -2;\nfunction X509() {\n  var k = ASN1HEX,\n      j = k.getChildIdx,\n      h = k.getV,\n      b = k.getTLV,\n      f = k.getVbyList,\n      c = k.getTLVbyList,\n      g = k.getIdxbyList,\n      d = k.getVidx,\n      i = k.oidname,\n      a = X509,\n      e = pemtohex;this.hex = null;this.version = 0;this.foffset = 0;this.aExtInfo = null;this.getVersion = function () {\n    if (this.hex === null || this.version !== 0) {\n      return this.version;\n    }if (c(this.hex, 0, [0, 0]) !== \"a003020102\") {\n      this.version = 1;this.foffset = -1;return 1;\n    }this.version = 3;return 3;\n  };this.getSerialNumberHex = function () {\n    return f(this.hex, 0, [0, 1 + this.foffset], \"02\");\n  };this.getSignatureAlgorithmField = function () {\n    return i(f(this.hex, 0, [0, 2 + this.foffset, 0], \"06\"));\n  };this.getIssuerHex = function () {\n    return c(this.hex, 0, [0, 3 + this.foffset], \"30\");\n  };this.getIssuerString = function () {\n    return a.hex2dn(this.getIssuerHex());\n  };this.getSubjectHex = function () {\n    return c(this.hex, 0, [0, 5 + this.foffset], \"30\");\n  };this.getSubjectString = function () {\n    return a.hex2dn(this.getSubjectHex());\n  };this.getNotBefore = function () {\n    var l = f(this.hex, 0, [0, 4 + this.foffset, 0]);l = l.replace(/(..)/g, \"%$1\");l = decodeURIComponent(l);return l;\n  };this.getNotAfter = function () {\n    var l = f(this.hex, 0, [0, 4 + this.foffset, 1]);l = l.replace(/(..)/g, \"%$1\");l = decodeURIComponent(l);return l;\n  };this.getPublicKeyHex = function () {\n    return k.getTLVbyList(this.hex, 0, [0, 6 + this.foffset], \"30\");\n  };this.getPublicKeyIdx = function () {\n    return g(this.hex, 0, [0, 6 + this.foffset], \"30\");\n  };this.getPublicKeyContentIdx = function () {\n    var l = this.getPublicKeyIdx();return g(this.hex, l, [1, 0], \"30\");\n  };this.getPublicKey = function () {\n    return KEYUTIL.getKey(this.getPublicKeyHex(), null, \"pkcs8pub\");\n  };this.getSignatureAlgorithmName = function () {\n    return i(f(this.hex, 0, [1, 0], \"06\"));\n  };this.getSignatureValueHex = function () {\n    return f(this.hex, 0, [2], \"03\", true);\n  };this.verifySignature = function (n) {\n    var o = this.getSignatureAlgorithmName();var l = this.getSignatureValueHex();var m = c(this.hex, 0, [0], \"30\");var p = new KJUR.crypto.Signature({ alg: o });p.init(n);p.updateHex(m);return p.verify(l);\n  };this.parseExt = function () {\n    if (this.version !== 3) {\n      return -1;\n    }var p = g(this.hex, 0, [0, 7, 0], \"30\");var m = j(this.hex, p);this.aExtInfo = new Array();for (var n = 0; n < m.length; n++) {\n      var q = {};q.critical = false;var l = j(this.hex, m[n]);var r = 0;if (l.length === 3) {\n        q.critical = true;r = 1;\n      }q.oid = k.hextooidstr(f(this.hex, m[n], [0], \"06\"));var o = g(this.hex, m[n], [1 + r]);q.vidx = d(this.hex, o);this.aExtInfo.push(q);\n    }\n  };this.getExtInfo = function (n) {\n    var l = this.aExtInfo;var o = n;if (!n.match(/^[0-9.]+$/)) {\n      o = KJUR.asn1.x509.OID.name2oid(n);\n    }if (o === \"\") {\n      return undefined;\n    }for (var m = 0; m < l.length; m++) {\n      if (l[m].oid === o) {\n        return l[m];\n      }\n    }return undefined;\n  };this.getExtBasicConstraints = function () {\n    var n = this.getExtInfo(\"basicConstraints\");if (n === undefined) {\n      return n;\n    }var l = h(this.hex, n.vidx);if (l === \"\") {\n      return {};\n    }if (l === \"0101ff\") {\n      return { cA: true };\n    }if (l.substr(0, 8) === \"0101ff02\") {\n      var o = h(l, 6);var m = parseInt(o, 16);return { cA: true, pathLen: m };\n    }throw \"basicConstraints parse error\";\n  };this.getExtKeyUsageBin = function () {\n    var o = this.getExtInfo(\"keyUsage\");if (o === undefined) {\n      return \"\";\n    }var m = h(this.hex, o.vidx);if (m.length % 2 != 0 || m.length <= 2) {\n      throw \"malformed key usage value\";\n    }var l = parseInt(m.substr(0, 2));var n = parseInt(m.substr(2), 16).toString(2);return n.substr(0, n.length - l);\n  };this.getExtKeyUsageString = function () {\n    var n = this.getExtKeyUsageBin();var l = new Array();for (var m = 0; m < n.length; m++) {\n      if (n.substr(m, 1) == \"1\") {\n        l.push(X509.KEYUSAGE_NAME[m]);\n      }\n    }return l.join(\",\");\n  };this.getExtSubjectKeyIdentifier = function () {\n    var l = this.getExtInfo(\"subjectKeyIdentifier\");if (l === undefined) {\n      return l;\n    }return h(this.hex, l.vidx);\n  };this.getExtAuthorityKeyIdentifier = function () {\n    var p = this.getExtInfo(\"authorityKeyIdentifier\");if (p === undefined) {\n      return p;\n    }var l = {};var o = b(this.hex, p.vidx);var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      if (o.substr(m[n], 2) === \"80\") {\n        l.kid = h(o, m[n]);\n      }\n    }return l;\n  };this.getExtExtKeyUsageName = function () {\n    var p = this.getExtInfo(\"extKeyUsage\");if (p === undefined) {\n      return p;\n    }var l = new Array();var o = b(this.hex, p.vidx);if (o === \"\") {\n      return l;\n    }var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      l.push(i(h(o, m[n])));\n    }return l;\n  };this.getExtSubjectAltName = function () {\n    var m = this.getExtSubjectAltName2();var l = new Array();for (var n = 0; n < m.length; n++) {\n      if (m[n][0] === \"DNS\") {\n        l.push(m[n][1]);\n      }\n    }return l;\n  };this.getExtSubjectAltName2 = function () {\n    var p, s, r;var q = this.getExtInfo(\"subjectAltName\");if (q === undefined) {\n      return q;\n    }var l = new Array();var o = b(this.hex, q.vidx);var m = j(o, 0);for (var n = 0; n < m.length; n++) {\n      r = o.substr(m[n], 2);p = h(o, m[n]);if (r === \"81\") {\n        s = hextoutf8(p);l.push([\"MAIL\", s]);\n      }if (r === \"82\") {\n        s = hextoutf8(p);l.push([\"DNS\", s]);\n      }if (r === \"84\") {\n        s = X509.hex2dn(p, 0);l.push([\"DN\", s]);\n      }if (r === \"86\") {\n        s = hextoutf8(p);l.push([\"URI\", s]);\n      }if (r === \"87\") {\n        s = hextoip(p);l.push([\"IP\", s]);\n      }\n    }return l;\n  };this.getExtCRLDistributionPointsURI = function () {\n    var q = this.getExtInfo(\"cRLDistributionPoints\");if (q === undefined) {\n      return q;\n    }var l = new Array();var m = j(this.hex, q.vidx);for (var o = 0; o < m.length; o++) {\n      try {\n        var r = f(this.hex, m[o], [0, 0, 0], \"86\");var p = hextoutf8(r);l.push(p);\n      } catch (n) {}\n    }return l;\n  };this.getExtAIAInfo = function () {\n    var p = this.getExtInfo(\"authorityInfoAccess\");if (p === undefined) {\n      return p;\n    }var l = { ocsp: [], caissuer: [] };var m = j(this.hex, p.vidx);for (var n = 0; n < m.length; n++) {\n      var q = f(this.hex, m[n], [0], \"06\");var o = f(this.hex, m[n], [1], \"86\");if (q === \"2b06010505073001\") {\n        l.ocsp.push(hextoutf8(o));\n      }if (q === \"2b06010505073002\") {\n        l.caissuer.push(hextoutf8(o));\n      }\n    }return l;\n  };this.getExtCertificatePolicies = function () {\n    var o = this.getExtInfo(\"certificatePolicies\");if (o === undefined) {\n      return o;\n    }var l = b(this.hex, o.vidx);var u = [];var s = j(l, 0);for (var r = 0; r < s.length; r++) {\n      var t = {};var n = j(l, s[r]);t.id = i(h(l, n[0]));if (n.length === 2) {\n        var m = j(l, n[1]);for (var q = 0; q < m.length; q++) {\n          var p = f(l, m[q], [0], \"06\");if (p === \"2b06010505070201\") {\n            t.cps = hextoutf8(f(l, m[q], [1]));\n          } else {\n            if (p === \"2b06010505070202\") {\n              t.unotice = hextoutf8(f(l, m[q], [1, 0]));\n            }\n          }\n        }\n      }u.push(t);\n    }return u;\n  };this.readCertPEM = function (l) {\n    this.readCertHex(e(l));\n  };this.readCertHex = function (l) {\n    this.hex = l;this.getVersion();try {\n      g(this.hex, 0, [0, 7], \"a3\");this.parseExt();\n    } catch (m) {}\n  };this.getInfo = function () {\n    var m = X509;var B, u, z;B = \"Basic Fields\\n\";B += \"  serial number: \" + this.getSerialNumberHex() + \"\\n\";B += \"  signature algorithm: \" + this.getSignatureAlgorithmField() + \"\\n\";B += \"  issuer: \" + this.getIssuerString() + \"\\n\";B += \"  notBefore: \" + this.getNotBefore() + \"\\n\";B += \"  notAfter: \" + this.getNotAfter() + \"\\n\";B += \"  subject: \" + this.getSubjectString() + \"\\n\";B += \"  subject public key info: \\n\";u = this.getPublicKey();B += \"    key algorithm: \" + u.type + \"\\n\";if (u.type === \"RSA\") {\n      B += \"    n=\" + hextoposhex(u.n.toString(16)).substr(0, 16) + \"...\\n\";B += \"    e=\" + hextoposhex(u.e.toString(16)) + \"\\n\";\n    }z = this.aExtInfo;if (z !== undefined && z !== null) {\n      B += \"X509v3 Extensions:\\n\";for (var r = 0; r < z.length; r++) {\n        var n = z[r];var A = KJUR.asn1.x509.OID.oid2name(n.oid);if (A === \"\") {\n          A = n.oid;\n        }var x = \"\";if (n.critical === true) {\n          x = \"CRITICAL\";\n        }B += \"  \" + A + \" \" + x + \":\\n\";if (A === \"basicConstraints\") {\n          var v = this.getExtBasicConstraints();if (v.cA === undefined) {\n            B += \"    {}\\n\";\n          } else {\n            B += \"    cA=true\";if (v.pathLen !== undefined) {\n              B += \", pathLen=\" + v.pathLen;\n            }B += \"\\n\";\n          }\n        } else {\n          if (A === \"keyUsage\") {\n            B += \"    \" + this.getExtKeyUsageString() + \"\\n\";\n          } else {\n            if (A === \"subjectKeyIdentifier\") {\n              B += \"    \" + this.getExtSubjectKeyIdentifier() + \"\\n\";\n            } else {\n              if (A === \"authorityKeyIdentifier\") {\n                var l = this.getExtAuthorityKeyIdentifier();if (l.kid !== undefined) {\n                  B += \"    kid=\" + l.kid + \"\\n\";\n                }\n              } else {\n                if (A === \"extKeyUsage\") {\n                  var w = this.getExtExtKeyUsageName();B += \"    \" + w.join(\", \") + \"\\n\";\n                } else {\n                  if (A === \"subjectAltName\") {\n                    var t = this.getExtSubjectAltName2();B += \"    \" + t + \"\\n\";\n                  } else {\n                    if (A === \"cRLDistributionPoints\") {\n                      var y = this.getExtCRLDistributionPointsURI();B += \"    \" + y + \"\\n\";\n                    } else {\n                      if (A === \"authorityInfoAccess\") {\n                        var p = this.getExtAIAInfo();if (p.ocsp !== undefined) {\n                          B += \"    ocsp: \" + p.ocsp.join(\",\") + \"\\n\";\n                        }if (p.caissuer !== undefined) {\n                          B += \"    caissuer: \" + p.caissuer.join(\",\") + \"\\n\";\n                        }\n                      } else {\n                        if (A === \"certificatePolicies\") {\n                          var o = this.getExtCertificatePolicies();for (var q = 0; q < o.length; q++) {\n                            if (o[q].id !== undefined) {\n                              B += \"    policy oid: \" + o[q].id + \"\\n\";\n                            }if (o[q].cps !== undefined) {\n                              B += \"    cps: \" + o[q].cps + \"\\n\";\n                            }\n                          }\n                        }\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }B += \"signature algorithm: \" + this.getSignatureAlgorithmName() + \"\\n\";B += \"signature: \" + this.getSignatureValueHex().substr(0, 16) + \"...\\n\";return B;\n  };\n}X509.hex2dn = function (f, b) {\n  if (b === undefined) {\n    b = 0;\n  }if (f.substr(b, 2) !== \"30\") {\n    throw \"malformed DN\";\n  }var c = new Array();var d = ASN1HEX.getChildIdx(f, b);for (var e = 0; e < d.length; e++) {\n    c.push(X509.hex2rdn(f, d[e]));\n  }c = c.map(function (a) {\n    return a.replace(\"/\", \"\\\\/\");\n  });return \"/\" + c.join(\"/\");\n};X509.hex2rdn = function (f, b) {\n  if (b === undefined) {\n    b = 0;\n  }if (f.substr(b, 2) !== \"31\") {\n    throw \"malformed RDN\";\n  }var c = new Array();var d = ASN1HEX.getChildIdx(f, b);for (var e = 0; e < d.length; e++) {\n    c.push(X509.hex2attrTypeValue(f, d[e]));\n  }c = c.map(function (a) {\n    return a.replace(\"+\", \"\\\\+\");\n  });return c.join(\"+\");\n};X509.hex2attrTypeValue = function (d, i) {\n  var j = ASN1HEX;var h = j.getV;if (i === undefined) {\n    i = 0;\n  }if (d.substr(i, 2) !== \"30\") {\n    throw \"malformed attribute type and value\";\n  }var g = j.getChildIdx(d, i);if (g.length !== 2 || d.substr(g[0], 2) !== \"06\") {\n    \"malformed attribute type and value\";\n  }var b = h(d, g[0]);var f = KJUR.asn1.ASN1Util.oidHexToInt(b);var e = KJUR.asn1.x509.OID.oid2atype(f);var a = h(d, g[1]);var c = hextorstr(a);return e + \"=\" + c;\n};X509.getPublicKeyFromCertHex = function (b) {\n  var a = new X509();a.readCertHex(b);return a.getPublicKey();\n};X509.getPublicKeyFromCertPEM = function (b) {\n  var a = new X509();a.readCertPEM(b);return a.getPublicKey();\n};X509.getPublicKeyInfoPropOfCertPEM = function (c) {\n  var e = ASN1HEX;var g = e.getVbyList;var b = {};var a, f, d;b.algparam = null;a = new X509();a.readCertPEM(c);f = a.getPublicKeyHex();b.keyhex = g(f, 0, [1], \"03\").substr(2);b.algoid = g(f, 0, [0, 0], \"06\");if (b.algoid === \"2a8648ce3d0201\") {\n    b.algparam = g(f, 0, [0, 1], \"06\");\n  }return b;\n};X509.KEYUSAGE_NAME = [\"digitalSignature\", \"nonRepudiation\", \"keyEncipherment\", \"dataEncipherment\", \"keyAgreement\", \"keyCertSign\", \"cRLSign\", \"encipherOnly\", \"decipherOnly\"];\nif (typeof KJUR == \"undefined\" || !KJUR) {\n  exports.KJUR = KJUR = {};\n}if (typeof KJUR.jws == \"undefined\" || !KJUR.jws) {\n  KJUR.jws = {};\n}KJUR.jws.JWS = function () {\n  var b = KJUR,\n      a = b.jws.JWS,\n      c = a.isSafeJSONString;this.parseJWS = function (g, j) {\n    if (this.parsedJWS !== undefined && (j || this.parsedJWS.sigvalH !== undefined)) {\n      return;\n    }var i = g.match(/^([^.]+)\\.([^.]+)\\.([^.]+)$/);if (i == null) {\n      throw \"JWS signature is not a form of 'Head.Payload.SigValue'.\";\n    }var k = i[1];var e = i[2];var l = i[3];var n = k + \".\" + e;this.parsedJWS = {};this.parsedJWS.headB64U = k;this.parsedJWS.payloadB64U = e;this.parsedJWS.sigvalB64U = l;this.parsedJWS.si = n;if (!j) {\n      var h = b64utohex(l);var f = parseBigInt(h, 16);this.parsedJWS.sigvalH = h;this.parsedJWS.sigvalBI = f;\n    }var d = b64utoutf8(k);var m = b64utoutf8(e);this.parsedJWS.headS = d;this.parsedJWS.payloadS = m;if (!c(d, this.parsedJWS, \"headP\")) {\n      throw \"malformed JSON string for JWS Head: \" + d;\n    }\n  };\n};KJUR.jws.JWS.sign = function (i, v, y, z, a) {\n  var w = KJUR,\n      m = w.jws,\n      q = m.JWS,\n      g = q.readSafeJSONString,\n      p = q.isSafeJSONString,\n      d = w.crypto,\n      k = d.ECDSA,\n      o = d.Mac,\n      c = d.Signature,\n      t = JSON;var s, j, n;if (typeof v != \"string\" && (typeof v === \"undefined\" ? \"undefined\" : _typeof(v)) != \"object\") {\n    throw \"spHeader must be JSON string or object: \" + v;\n  }if ((typeof v === \"undefined\" ? \"undefined\" : _typeof(v)) == \"object\") {\n    j = v;s = t.stringify(j);\n  }if (typeof v == \"string\") {\n    s = v;if (!p(s)) {\n      throw \"JWS Head is not safe JSON string: \" + s;\n    }j = g(s);\n  }n = y;if ((typeof y === \"undefined\" ? \"undefined\" : _typeof(y)) == \"object\") {\n    n = t.stringify(y);\n  }if ((i == \"\" || i == null) && j.alg !== undefined) {\n    i = j.alg;\n  }if (i != \"\" && i != null && j.alg === undefined) {\n    j.alg = i;s = t.stringify(j);\n  }if (i !== j.alg) {\n    throw \"alg and sHeader.alg doesn't match: \" + i + \"!=\" + j.alg;\n  }var r = null;if (q.jwsalg2sigalg[i] === undefined) {\n    throw \"unsupported alg name: \" + i;\n  } else {\n    r = q.jwsalg2sigalg[i];\n  }var e = utf8tob64u(s);var l = utf8tob64u(n);var b = e + \".\" + l;var x = \"\";if (r.substr(0, 4) == \"Hmac\") {\n    if (z === undefined) {\n      throw \"mac key shall be specified for HS* alg\";\n    }var h = new o({ alg: r, prov: \"cryptojs\", pass: z });h.updateString(b);x = h.doFinal();\n  } else {\n    if (r.indexOf(\"withECDSA\") != -1) {\n      var f = new c({ alg: r });f.init(z, a);f.updateString(b);hASN1Sig = f.sign();x = KJUR.crypto.ECDSA.asn1SigToConcatSig(hASN1Sig);\n    } else {\n      if (r != \"none\") {\n        var f = new c({ alg: r });f.init(z, a);f.updateString(b);x = f.sign();\n      }\n    }\n  }var u = hextob64u(x);return b + \".\" + u;\n};KJUR.jws.JWS.verify = function (w, B, n) {\n  var x = KJUR,\n      q = x.jws,\n      t = q.JWS,\n      i = t.readSafeJSONString,\n      e = x.crypto,\n      p = e.ECDSA,\n      s = e.Mac,\n      d = e.Signature,\n      m;if ((typeof RSAKey === \"undefined\" ? \"undefined\" : _typeof(RSAKey)) !== undefined) {\n    m = RSAKey;\n  }var y = w.split(\".\");if (y.length !== 3) {\n    return false;\n  }var f = y[0];var r = y[1];var c = f + \".\" + r;var A = b64utohex(y[2]);var l = i(b64utoutf8(y[0]));var k = null;var z = null;if (l.alg === undefined) {\n    throw \"algorithm not specified in header\";\n  } else {\n    k = l.alg;z = k.substr(0, 2);\n  }if (n != null && Object.prototype.toString.call(n) === \"[object Array]\" && n.length > 0) {\n    var b = \":\" + n.join(\":\") + \":\";if (b.indexOf(\":\" + k + \":\") == -1) {\n      throw \"algorithm '\" + k + \"' not accepted in the list\";\n    }\n  }if (k != \"none\" && B === null) {\n    throw \"key shall be specified to verify.\";\n  }if (typeof B == \"string\" && B.indexOf(\"-----BEGIN \") != -1) {\n    B = KEYUTIL.getKey(B);\n  }if (z == \"RS\" || z == \"PS\") {\n    if (!(B instanceof m)) {\n      throw \"key shall be a RSAKey obj for RS* and PS* algs\";\n    }\n  }if (z == \"ES\") {\n    if (!(B instanceof p)) {\n      throw \"key shall be a ECDSA obj for ES* algs\";\n    }\n  }if (k == \"none\") {}var u = null;if (t.jwsalg2sigalg[l.alg] === undefined) {\n    throw \"unsupported alg name: \" + k;\n  } else {\n    u = t.jwsalg2sigalg[k];\n  }if (u == \"none\") {\n    throw \"not supported\";\n  } else {\n    if (u.substr(0, 4) == \"Hmac\") {\n      var o = null;if (B === undefined) {\n        throw \"hexadecimal key shall be specified for HMAC\";\n      }var j = new s({ alg: u, pass: B });j.updateString(c);o = j.doFinal();return A == o;\n    } else {\n      if (u.indexOf(\"withECDSA\") != -1) {\n        var h = null;try {\n          h = p.concatSigToASN1Sig(A);\n        } catch (v) {\n          return false;\n        }var g = new d({ alg: u });g.init(B);g.updateString(c);return g.verify(h);\n      } else {\n        var g = new d({ alg: u });g.init(B);g.updateString(c);return g.verify(A);\n      }\n    }\n  }\n};KJUR.jws.JWS.parse = function (g) {\n  var c = g.split(\".\");var b = {};var f, e, d;if (c.length != 2 && c.length != 3) {\n    throw \"malformed sJWS: wrong number of '.' splitted elements\";\n  }f = c[0];e = c[1];if (c.length == 3) {\n    d = c[2];\n  }b.headerObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(f));b.payloadObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(e));b.headerPP = JSON.stringify(b.headerObj, null, \"  \");if (b.payloadObj == null) {\n    b.payloadPP = b64utoutf8(e);\n  } else {\n    b.payloadPP = JSON.stringify(b.payloadObj, null, \"  \");\n  }if (d !== undefined) {\n    b.sigHex = b64utohex(d);\n  }return b;\n};KJUR.jws.JWS.verifyJWT = function (e, l, r) {\n  var d = KJUR,\n      j = d.jws,\n      o = j.JWS,\n      n = o.readSafeJSONString,\n      p = o.inArray,\n      f = o.includedArray;var k = e.split(\".\");var c = k[0];var i = k[1];var q = c + \".\" + i;var m = b64utohex(k[2]);var h = n(b64utoutf8(c));var g = n(b64utoutf8(i));if (h.alg === undefined) {\n    return false;\n  }if (r.alg === undefined) {\n    throw \"acceptField.alg shall be specified\";\n  }if (!p(h.alg, r.alg)) {\n    return false;\n  }if (g.iss !== undefined && _typeof(r.iss) === \"object\") {\n    if (!p(g.iss, r.iss)) {\n      return false;\n    }\n  }if (g.sub !== undefined && _typeof(r.sub) === \"object\") {\n    if (!p(g.sub, r.sub)) {\n      return false;\n    }\n  }if (g.aud !== undefined && _typeof(r.aud) === \"object\") {\n    if (typeof g.aud == \"string\") {\n      if (!p(g.aud, r.aud)) {\n        return false;\n      }\n    } else {\n      if (_typeof(g.aud) == \"object\") {\n        if (!f(g.aud, r.aud)) {\n          return false;\n        }\n      }\n    }\n  }var b = j.IntDate.getNow();if (r.verifyAt !== undefined && typeof r.verifyAt === \"number\") {\n    b = r.verifyAt;\n  }if (r.gracePeriod === undefined || typeof r.gracePeriod !== \"number\") {\n    r.gracePeriod = 0;\n  }if (g.exp !== undefined && typeof g.exp == \"number\") {\n    if (g.exp + r.gracePeriod < b) {\n      return false;\n    }\n  }if (g.nbf !== undefined && typeof g.nbf == \"number\") {\n    if (b < g.nbf - r.gracePeriod) {\n      return false;\n    }\n  }if (g.iat !== undefined && typeof g.iat == \"number\") {\n    if (b < g.iat - r.gracePeriod) {\n      return false;\n    }\n  }if (g.jti !== undefined && r.jti !== undefined) {\n    if (g.jti !== r.jti) {\n      return false;\n    }\n  }if (!o.verify(e, l, r.alg)) {\n    return false;\n  }return true;\n};KJUR.jws.JWS.includedArray = function (b, a) {\n  var c = KJUR.jws.JWS.inArray;if (b === null) {\n    return false;\n  }if ((typeof b === \"undefined\" ? \"undefined\" : _typeof(b)) !== \"object\") {\n    return false;\n  }if (typeof b.length !== \"number\") {\n    return false;\n  }for (var d = 0; d < b.length; d++) {\n    if (!c(b[d], a)) {\n      return false;\n    }\n  }return true;\n};KJUR.jws.JWS.inArray = function (d, b) {\n  if (b === null) {\n    return false;\n  }if ((typeof b === \"undefined\" ? \"undefined\" : _typeof(b)) !== \"object\") {\n    return false;\n  }if (typeof b.length !== \"number\") {\n    return false;\n  }for (var c = 0; c < b.length; c++) {\n    if (b[c] == d) {\n      return true;\n    }\n  }return false;\n};KJUR.jws.JWS.jwsalg2sigalg = { HS256: \"HmacSHA256\", HS384: \"HmacSHA384\", HS512: \"HmacSHA512\", RS256: \"SHA256withRSA\", RS384: \"SHA384withRSA\", RS512: \"SHA512withRSA\", ES256: \"SHA256withECDSA\", ES384: \"SHA384withECDSA\", PS256: \"SHA256withRSAandMGF1\", PS384: \"SHA384withRSAandMGF1\", PS512: \"SHA512withRSAandMGF1\", none: \"none\" };KJUR.jws.JWS.isSafeJSONString = function (c, b, d) {\n  var e = null;try {\n    e = jsonParse(c);if ((typeof e === \"undefined\" ? \"undefined\" : _typeof(e)) != \"object\") {\n      return 0;\n    }if (e.constructor === Array) {\n      return 0;\n    }if (b) {\n      b[d] = e;\n    }return 1;\n  } catch (a) {\n    return 0;\n  }\n};KJUR.jws.JWS.readSafeJSONString = function (b) {\n  var c = null;try {\n    c = jsonParse(b);if ((typeof c === \"undefined\" ? \"undefined\" : _typeof(c)) != \"object\") {\n      return null;\n    }if (c.constructor === Array) {\n      return null;\n    }return c;\n  } catch (a) {\n    return null;\n  }\n};KJUR.jws.JWS.getEncodedSignatureValueFromJWS = function (b) {\n  var a = b.match(/^[^.]+\\.[^.]+\\.([^.]+)$/);if (a == null) {\n    throw \"JWS signature is not a form of 'Head.Payload.SigValue'.\";\n  }return a[1];\n};KJUR.jws.JWS.getJWKthumbprint = function (d) {\n  if (d.kty !== \"RSA\" && d.kty !== \"EC\" && d.kty !== \"oct\") {\n    throw \"unsupported algorithm for JWK Thumprint\";\n  }var a = \"{\";if (d.kty === \"RSA\") {\n    if (typeof d.n != \"string\" || typeof d.e != \"string\") {\n      throw \"wrong n and e value for RSA key\";\n    }a += '\"e\":\"' + d.e + '\",';a += '\"kty\":\"' + d.kty + '\",';a += '\"n\":\"' + d.n + '\"}';\n  } else {\n    if (d.kty === \"EC\") {\n      if (typeof d.crv != \"string\" || typeof d.x != \"string\" || typeof d.y != \"string\") {\n        throw \"wrong crv, x and y value for EC key\";\n      }a += '\"crv\":\"' + d.crv + '\",';a += '\"kty\":\"' + d.kty + '\",';a += '\"x\":\"' + d.x + '\",';a += '\"y\":\"' + d.y + '\"}';\n    } else {\n      if (d.kty === \"oct\") {\n        if (typeof d.k != \"string\") {\n          throw \"wrong k value for oct(symmetric) key\";\n        }a += '\"kty\":\"' + d.kty + '\",';a += '\"k\":\"' + d.k + '\"}';\n      }\n    }\n  }var b = rstrtohex(a);var c = KJUR.crypto.Util.hashHex(b, \"sha256\");var e = hextob64u(c);return e;\n};KJUR.jws.IntDate = {};KJUR.jws.IntDate.get = function (c) {\n  var b = KJUR.jws.IntDate,\n      d = b.getNow,\n      a = b.getZulu;if (c == \"now\") {\n    return d();\n  } else {\n    if (c == \"now + 1hour\") {\n      return d() + 60 * 60;\n    } else {\n      if (c == \"now + 1day\") {\n        return d() + 60 * 60 * 24;\n      } else {\n        if (c == \"now + 1month\") {\n          return d() + 60 * 60 * 24 * 30;\n        } else {\n          if (c == \"now + 1year\") {\n            return d() + 60 * 60 * 24 * 365;\n          } else {\n            if (c.match(/Z$/)) {\n              return a(c);\n            } else {\n              if (c.match(/^[0-9]+$/)) {\n                return parseInt(c);\n              }\n            }\n          }\n        }\n      }\n    }\n  }throw \"unsupported format: \" + c;\n};KJUR.jws.IntDate.getZulu = function (a) {\n  return zulutosec(a);\n};KJUR.jws.IntDate.getNow = function () {\n  var a = ~~(new Date() / 1000);return a;\n};KJUR.jws.IntDate.intDate2UTCString = function (a) {\n  var b = new Date(a * 1000);return b.toUTCString();\n};KJUR.jws.IntDate.intDate2Zulu = function (e) {\n  var i = new Date(e * 1000),\n      h = (\"0000\" + i.getUTCFullYear()).slice(-4),\n      g = (\"00\" + (i.getUTCMonth() + 1)).slice(-2),\n      b = (\"00\" + i.getUTCDate()).slice(-2),\n      a = (\"00\" + i.getUTCHours()).slice(-2),\n      c = (\"00\" + i.getUTCMinutes()).slice(-2),\n      f = (\"00\" + i.getUTCSeconds()).slice(-2);return h + g + b + a + c + f + \"Z\";\n};\nexports.SecureRandom = SecureRandom;\nexports.rng_seed_time = rng_seed_time;\nexports.BigInteger = BigInteger;\nexports.RSAKey = RSAKey;\nvar EDSA = KJUR.crypto.EDSA;\nexports.EDSA = EDSA;\nvar DSA = KJUR.crypto.DSA;\nexports.DSA = DSA;\nvar Signature = KJUR.crypto.Signature;\nexports.Signature = Signature;\nvar MessageDigest = KJUR.crypto.MessageDigest;\nexports.MessageDigest = MessageDigest;\nvar Mac = KJUR.crypto.Mac;\nexports.Mac = Mac;\nvar Cipher = KJUR.crypto.Cipher;\nexports.Cipher = Cipher;\nexports.KEYUTIL = KEYUTIL;\nexports.ASN1HEX = ASN1HEX;\nexports.X509 = X509;\nexports.CryptoJS = CryptoJS;\n\n// ext/base64.js\n\nexports.b64tohex = b64tohex;\nexports.b64toBA = b64toBA;\n\n// base64x.js\n\nexports.stoBA = stoBA;\nexports.BAtos = BAtos;\nexports.BAtohex = BAtohex;\nexports.stohex = stohex;\nexports.stob64 = stob64;\nexports.stob64u = stob64u;\nexports.b64utos = b64utos;\nexports.b64tob64u = b64tob64u;\nexports.b64utob64 = b64utob64;\nexports.hex2b64 = hex2b64;\nexports.hextob64u = hextob64u;\nexports.b64utohex = b64utohex;\nexports.utf8tob64u = utf8tob64u;\nexports.b64utoutf8 = b64utoutf8;\nexports.utf8tob64 = utf8tob64;\nexports.b64toutf8 = b64toutf8;\nexports.utf8tohex = utf8tohex;\nexports.hextoutf8 = hextoutf8;\nexports.hextorstr = hextorstr;\nexports.rstrtohex = rstrtohex;\nexports.hextob64 = hextob64;\nexports.hextob64nl = hextob64nl;\nexports.b64nltohex = b64nltohex;\nexports.hextopem = hextopem;\nexports.pemtohex = pemtohex;\nexports.hextoArrayBuffer = hextoArrayBuffer;\nexports.ArrayBuffertohex = ArrayBuffertohex;\nexports.zulutomsec = zulutomsec;\nexports.zulutosec = zulutosec;\nexports.zulutodate = zulutodate;\nexports.datetozulu = datetozulu;\nexports.uricmptohex = uricmptohex;\nexports.hextouricmp = hextouricmp;\nexports.ipv6tohex = ipv6tohex;\nexports.hextoipv6 = hextoipv6;\nexports.hextoip = hextoip;\nexports.iptohex = iptohex;\nexports.encodeURIComponentAll = encodeURIComponentAll;\nexports.newline_toUnix = newline_toUnix;\nexports.newline_toDos = newline_toDos;\nexports.hextoposhex = hextoposhex;\nexports.intarystrtohex = intarystrtohex;\nexports.strdiffidx = strdiffidx;\n\n// name spaces\n\nexports.KJUR = KJUR;\n\nvar _crypto = KJUR.crypto;\nexports.crypto = _crypto;\nvar _KJUR = KJUR;\nvar asn1 = _KJUR.asn1;\nexports.asn1 = asn1;\nvar _KJUR2 = KJUR;\nvar jws = _KJUR2.jws;\nexports.jws = jws;\nvar _KJUR3 = KJUR;\nvar lang = _KJUR3.lang;\nexports.lang = lang;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../node_modules/buffer/index.js */ \"./node_modules/buffer/index.js\").Buffer))\n\n/***/ }),\n\n/***/ \"./node_modules/babel-polyfill/lib/index.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/babel-polyfill/lib/index.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {\n\n__webpack_require__(/*! core-js/shim */ \"./node_modules/core-js/shim.js\");\n\n__webpack_require__(/*! regenerator-runtime/runtime */ \"./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js\");\n\n__webpack_require__(/*! core-js/fn/regexp/escape */ \"./node_modules/core-js/fn/regexp/escape.js\");\n\nif (global._babelPolyfill) {\n  throw new Error(\"only one instance of babel-polyfill is allowed\");\n}\nglobal._babelPolyfill = true;\n\nvar DEFINE_PROPERTY = \"defineProperty\";\nfunction define(O, key, value) {\n  O[key] || Object[DEFINE_PROPERTY](O, key, {\n    writable: true,\n    configurable: true,\n    value: value\n  });\n}\n\ndefine(String.prototype, \"padLeft\", \"\".padStart);\ndefine(String.prototype, \"padRight\", \"\".padEnd);\n\n\"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill\".split(\",\").forEach(function (key) {\n  [][key] && define(Array, key, Function.call.bind([][key]));\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js\":\n/*!*********************************************************************************!*\\\n  !*** ./node_modules/babel-polyfill/node_modules/regenerator-runtime/runtime.js ***!\n  \\*********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(global) {/**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * https://raw.github.com/facebook/regenerator/master/LICENSE file. An\n * additional grant of patent rights can be found in the PATENTS file in\n * the same directory.\n */\n\n!(function(global) {\n  \"use strict\";\n\n  var Op = Object.prototype;\n  var hasOwn = Op.hasOwnProperty;\n  var undefined; // More compressible than void 0.\n  var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n  var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n  var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n  var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n  var inModule = typeof module === \"object\";\n  var runtime = global.regeneratorRuntime;\n  if (runtime) {\n    if (inModule) {\n      // If regeneratorRuntime is defined globally and we're in a module,\n      // make the exports object identical to regeneratorRuntime.\n      module.exports = runtime;\n    }\n    // Don't bother evaluating the rest of this file if the runtime was\n    // already defined globally.\n    return;\n  }\n\n  // Define the runtime globally (as expected by generated code) as either\n  // module.exports (if we're in a module) or a new, empty object.\n  runtime = global.regeneratorRuntime = inModule ? module.exports : {};\n\n  function wrap(innerFn, outerFn, self, tryLocsList) {\n    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n    var generator = Object.create(protoGenerator.prototype);\n    var context = new Context(tryLocsList || []);\n\n    // The ._invoke method unifies the implementations of the .next,\n    // .throw, and .return methods.\n    generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n    return generator;\n  }\n  runtime.wrap = wrap;\n\n  // Try/catch helper to minimize deoptimizations. Returns a completion\n  // record like context.tryEntries[i].completion. This interface could\n  // have been (and was previously) designed to take a closure to be\n  // invoked without arguments, but in all the cases we care about we\n  // already have an existing method we want to call, so there's no need\n  // to create a new function object. We can even get away with assuming\n  // the method takes exactly one argument, since that happens to be true\n  // in every case, so we don't have to touch the arguments object. The\n  // only additional allocation required is the completion record, which\n  // has a stable shape and so hopefully should be cheap to allocate.\n  function tryCatch(fn, obj, arg) {\n    try {\n      return { type: \"normal\", arg: fn.call(obj, arg) };\n    } catch (err) {\n      return { type: \"throw\", arg: err };\n    }\n  }\n\n  var GenStateSuspendedStart = \"suspendedStart\";\n  var GenStateSuspendedYield = \"suspendedYield\";\n  var GenStateExecuting = \"executing\";\n  var GenStateCompleted = \"completed\";\n\n  // Returning this object from the innerFn has the same effect as\n  // breaking out of the dispatch switch statement.\n  var ContinueSentinel = {};\n\n  // Dummy constructor functions that we use as the .constructor and\n  // .constructor.prototype properties for functions that return Generator\n  // objects. For full spec compliance, you may wish to configure your\n  // minifier not to mangle the names of these two functions.\n  function Generator() {}\n  function GeneratorFunction() {}\n  function GeneratorFunctionPrototype() {}\n\n  // This is a polyfill for %IteratorPrototype% for environments that\n  // don't natively support it.\n  var IteratorPrototype = {};\n  IteratorPrototype[iteratorSymbol] = function () {\n    return this;\n  };\n\n  var getProto = Object.getPrototypeOf;\n  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n  if (NativeIteratorPrototype &&\n      NativeIteratorPrototype !== Op &&\n      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n    // This environment has a native %IteratorPrototype%; use it instead\n    // of the polyfill.\n    IteratorPrototype = NativeIteratorPrototype;\n  }\n\n  var Gp = GeneratorFunctionPrototype.prototype =\n    Generator.prototype = Object.create(IteratorPrototype);\n  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;\n  GeneratorFunctionPrototype.constructor = GeneratorFunction;\n  GeneratorFunctionPrototype[toStringTagSymbol] =\n    GeneratorFunction.displayName = \"GeneratorFunction\";\n\n  // Helper for defining the .next, .throw, and .return methods of the\n  // Iterator interface in terms of a single ._invoke method.\n  function defineIteratorMethods(prototype) {\n    [\"next\", \"throw\", \"return\"].forEach(function(method) {\n      prototype[method] = function(arg) {\n        return this._invoke(method, arg);\n      };\n    });\n  }\n\n  runtime.isGeneratorFunction = function(genFun) {\n    var ctor = typeof genFun === \"function\" && genFun.constructor;\n    return ctor\n      ? ctor === GeneratorFunction ||\n        // For the native GeneratorFunction constructor, the best we can\n        // do is to check its .name property.\n        (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n      : false;\n  };\n\n  runtime.mark = function(genFun) {\n    if (Object.setPrototypeOf) {\n      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n    } else {\n      genFun.__proto__ = GeneratorFunctionPrototype;\n      if (!(toStringTagSymbol in genFun)) {\n        genFun[toStringTagSymbol] = \"GeneratorFunction\";\n      }\n    }\n    genFun.prototype = Object.create(Gp);\n    return genFun;\n  };\n\n  // Within the body of any async function, `await x` is transformed to\n  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n  // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n  // meant to be awaited.\n  runtime.awrap = function(arg) {\n    return { __await: arg };\n  };\n\n  function AsyncIterator(generator) {\n    function invoke(method, arg, resolve, reject) {\n      var record = tryCatch(generator[method], generator, arg);\n      if (record.type === \"throw\") {\n        reject(record.arg);\n      } else {\n        var result = record.arg;\n        var value = result.value;\n        if (value &&\n            typeof value === \"object\" &&\n            hasOwn.call(value, \"__await\")) {\n          return Promise.resolve(value.__await).then(function(value) {\n            invoke(\"next\", value, resolve, reject);\n          }, function(err) {\n            invoke(\"throw\", err, resolve, reject);\n          });\n        }\n\n        return Promise.resolve(value).then(function(unwrapped) {\n          // When a yielded Promise is resolved, its final value becomes\n          // the .value of the Promise<{value,done}> result for the\n          // current iteration. If the Promise is rejected, however, the\n          // result for this iteration will be rejected with the same\n          // reason. Note that rejections of yielded Promises are not\n          // thrown back into the generator function, as is the case\n          // when an awaited Promise is rejected. This difference in\n          // behavior between yield and await is important, because it\n          // allows the consumer to decide what to do with the yielded\n          // rejection (swallow it and continue, manually .throw it back\n          // into the generator, abandon iteration, whatever). With\n          // await, by contrast, there is no opportunity to examine the\n          // rejection reason outside the generator function, so the\n          // only option is to throw it from the await expression, and\n          // let the generator function handle the exception.\n          result.value = unwrapped;\n          resolve(result);\n        }, reject);\n      }\n    }\n\n    if (typeof global.process === \"object\" && global.process.domain) {\n      invoke = global.process.domain.bind(invoke);\n    }\n\n    var previousPromise;\n\n    function enqueue(method, arg) {\n      function callInvokeWithMethodAndArg() {\n        return new Promise(function(resolve, reject) {\n          invoke(method, arg, resolve, reject);\n        });\n      }\n\n      return previousPromise =\n        // If enqueue has been called before, then we want to wait until\n        // all previous Promises have been resolved before calling invoke,\n        // so that results are always delivered in the correct order. If\n        // enqueue has not been called before, then it is important to\n        // call invoke immediately, without waiting on a callback to fire,\n        // so that the async generator function has the opportunity to do\n        // any necessary setup in a predictable way. This predictability\n        // is why the Promise constructor synchronously invokes its\n        // executor callback, and why async functions synchronously\n        // execute code before the first await. Since we implement simple\n        // async functions in terms of async generators, it is especially\n        // important to get this right, even though it requires care.\n        previousPromise ? previousPromise.then(\n          callInvokeWithMethodAndArg,\n          // Avoid propagating failures to Promises returned by later\n          // invocations of the iterator.\n          callInvokeWithMethodAndArg\n        ) : callInvokeWithMethodAndArg();\n    }\n\n    // Define the unified helper method that is used to implement .next,\n    // .throw, and .return (see defineIteratorMethods).\n    this._invoke = enqueue;\n  }\n\n  defineIteratorMethods(AsyncIterator.prototype);\n  AsyncIterator.prototype[asyncIteratorSymbol] = function () {\n    return this;\n  };\n  runtime.AsyncIterator = AsyncIterator;\n\n  // Note that simple async functions are implemented on top of\n  // AsyncIterator objects; they just return a Promise for the value of\n  // the final result produced by the iterator.\n  runtime.async = function(innerFn, outerFn, self, tryLocsList) {\n    var iter = new AsyncIterator(\n      wrap(innerFn, outerFn, self, tryLocsList)\n    );\n\n    return runtime.isGeneratorFunction(outerFn)\n      ? iter // If outerFn is a generator, return the full iterator.\n      : iter.next().then(function(result) {\n          return result.done ? result.value : iter.next();\n        });\n  };\n\n  function makeInvokeMethod(innerFn, self, context) {\n    var state = GenStateSuspendedStart;\n\n    return function invoke(method, arg) {\n      if (state === GenStateExecuting) {\n        throw new Error(\"Generator is already running\");\n      }\n\n      if (state === GenStateCompleted) {\n        if (method === \"throw\") {\n          throw arg;\n        }\n\n        // Be forgiving, per 25.3.3.3.3 of the spec:\n        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n        return doneResult();\n      }\n\n      context.method = method;\n      context.arg = arg;\n\n      while (true) {\n        var delegate = context.delegate;\n        if (delegate) {\n          var delegateResult = maybeInvokeDelegate(delegate, context);\n          if (delegateResult) {\n            if (delegateResult === ContinueSentinel) continue;\n            return delegateResult;\n          }\n        }\n\n        if (context.method === \"next\") {\n          // Setting context._sent for legacy support of Babel's\n          // function.sent implementation.\n          context.sent = context._sent = context.arg;\n\n        } else if (context.method === \"throw\") {\n          if (state === GenStateSuspendedStart) {\n            state = GenStateCompleted;\n            throw context.arg;\n          }\n\n          context.dispatchException(context.arg);\n\n        } else if (context.method === \"return\") {\n          context.abrupt(\"return\", context.arg);\n        }\n\n        state = GenStateExecuting;\n\n        var record = tryCatch(innerFn, self, context);\n        if (record.type === \"normal\") {\n          // If an exception is thrown from innerFn, we leave state ===\n          // GenStateExecuting and loop back for another invocation.\n          state = context.done\n            ? GenStateCompleted\n            : GenStateSuspendedYield;\n\n          if (record.arg === ContinueSentinel) {\n            continue;\n          }\n\n          return {\n            value: record.arg,\n            done: context.done\n          };\n\n        } else if (record.type === \"throw\") {\n          state = GenStateCompleted;\n          // Dispatch the exception by looping back around to the\n          // context.dispatchException(context.arg) call above.\n          context.method = \"throw\";\n          context.arg = record.arg;\n        }\n      }\n    };\n  }\n\n  // Call delegate.iterator[context.method](context.arg) and handle the\n  // result, either by returning a { value, done } result from the\n  // delegate iterator, or by modifying context.method and context.arg,\n  // setting context.delegate to null, and returning the ContinueSentinel.\n  function maybeInvokeDelegate(delegate, context) {\n    var method = delegate.iterator[context.method];\n    if (method === undefined) {\n      // A .throw or .return when the delegate iterator has no .throw\n      // method always terminates the yield* loop.\n      context.delegate = null;\n\n      if (context.method === \"throw\") {\n        if (delegate.iterator.return) {\n          // If the delegate iterator has a return method, give it a\n          // chance to clean up.\n          context.method = \"return\";\n          context.arg = undefined;\n          maybeInvokeDelegate(delegate, context);\n\n          if (context.method === \"throw\") {\n            // If maybeInvokeDelegate(context) changed context.method from\n            // \"return\" to \"throw\", let that override the TypeError below.\n            return ContinueSentinel;\n          }\n        }\n\n        context.method = \"throw\";\n        context.arg = new TypeError(\n          \"The iterator does not provide a 'throw' method\");\n      }\n\n      return ContinueSentinel;\n    }\n\n    var record = tryCatch(method, delegate.iterator, context.arg);\n\n    if (record.type === \"throw\") {\n      context.method = \"throw\";\n      context.arg = record.arg;\n      context.delegate = null;\n      return ContinueSentinel;\n    }\n\n    var info = record.arg;\n\n    if (! info) {\n      context.method = \"throw\";\n      context.arg = new TypeError(\"iterator result is not an object\");\n      context.delegate = null;\n      return ContinueSentinel;\n    }\n\n    if (info.done) {\n      // Assign the result of the finished delegate to the temporary\n      // variable specified by delegate.resultName (see delegateYield).\n      context[delegate.resultName] = info.value;\n\n      // Resume execution at the desired location (see delegateYield).\n      context.next = delegate.nextLoc;\n\n      // If context.method was \"throw\" but the delegate handled the\n      // exception, let the outer generator proceed normally. If\n      // context.method was \"next\", forget context.arg since it has been\n      // \"consumed\" by the delegate iterator. If context.method was\n      // \"return\", allow the original .return call to continue in the\n      // outer generator.\n      if (context.method !== \"return\") {\n        context.method = \"next\";\n        context.arg = undefined;\n      }\n\n    } else {\n      // Re-yield the result returned by the delegate method.\n      return info;\n    }\n\n    // The delegate iterator is finished, so forget it and continue with\n    // the outer generator.\n    context.delegate = null;\n    return ContinueSentinel;\n  }\n\n  // Define Generator.prototype.{next,throw,return} in terms of the\n  // unified ._invoke helper method.\n  defineIteratorMethods(Gp);\n\n  Gp[toStringTagSymbol] = \"Generator\";\n\n  // A Generator should always return itself as the iterator object when the\n  // @@iterator function is called on it. Some browsers' implementations of the\n  // iterator prototype chain incorrectly implement this, causing the Generator\n  // object to not be returned from this call. This ensures that doesn't happen.\n  // See https://github.com/facebook/regenerator/issues/274 for more details.\n  Gp[iteratorSymbol] = function() {\n    return this;\n  };\n\n  Gp.toString = function() {\n    return \"[object Generator]\";\n  };\n\n  function pushTryEntry(locs) {\n    var entry = { tryLoc: locs[0] };\n\n    if (1 in locs) {\n      entry.catchLoc = locs[1];\n    }\n\n    if (2 in locs) {\n      entry.finallyLoc = locs[2];\n      entry.afterLoc = locs[3];\n    }\n\n    this.tryEntries.push(entry);\n  }\n\n  function resetTryEntry(entry) {\n    var record = entry.completion || {};\n    record.type = \"normal\";\n    delete record.arg;\n    entry.completion = record;\n  }\n\n  function Context(tryLocsList) {\n    // The root entry object (effectively a try statement without a catch\n    // or a finally block) gives us a place to store values thrown from\n    // locations where there is no enclosing try statement.\n    this.tryEntries = [{ tryLoc: \"root\" }];\n    tryLocsList.forEach(pushTryEntry, this);\n    this.reset(true);\n  }\n\n  runtime.keys = function(object) {\n    var keys = [];\n    for (var key in object) {\n      keys.push(key);\n    }\n    keys.reverse();\n\n    // Rather than returning an object with a next method, we keep\n    // things simple and return the next function itself.\n    return function next() {\n      while (keys.length) {\n        var key = keys.pop();\n        if (key in object) {\n          next.value = key;\n          next.done = false;\n          return next;\n        }\n      }\n\n      // To avoid creating an additional object, we just hang the .value\n      // and .done properties off the next function object itself. This\n      // also ensures that the minifier will not anonymize the function.\n      next.done = true;\n      return next;\n    };\n  };\n\n  function values(iterable) {\n    if (iterable) {\n      var iteratorMethod = iterable[iteratorSymbol];\n      if (iteratorMethod) {\n        return iteratorMethod.call(iterable);\n      }\n\n      if (typeof iterable.next === \"function\") {\n        return iterable;\n      }\n\n      if (!isNaN(iterable.length)) {\n        var i = -1, next = function next() {\n          while (++i < iterable.length) {\n            if (hasOwn.call(iterable, i)) {\n              next.value = iterable[i];\n              next.done = false;\n              return next;\n            }\n          }\n\n          next.value = undefined;\n          next.done = true;\n\n          return next;\n        };\n\n        return next.next = next;\n      }\n    }\n\n    // Return an iterator with no values.\n    return { next: doneResult };\n  }\n  runtime.values = values;\n\n  function doneResult() {\n    return { value: undefined, done: true };\n  }\n\n  Context.prototype = {\n    constructor: Context,\n\n    reset: function(skipTempReset) {\n      this.prev = 0;\n      this.next = 0;\n      // Resetting context._sent for legacy support of Babel's\n      // function.sent implementation.\n      this.sent = this._sent = undefined;\n      this.done = false;\n      this.delegate = null;\n\n      this.method = \"next\";\n      this.arg = undefined;\n\n      this.tryEntries.forEach(resetTryEntry);\n\n      if (!skipTempReset) {\n        for (var name in this) {\n          // Not sure about the optimal order of these conditions:\n          if (name.charAt(0) === \"t\" &&\n              hasOwn.call(this, name) &&\n              !isNaN(+name.slice(1))) {\n            this[name] = undefined;\n          }\n        }\n      }\n    },\n\n    stop: function() {\n      this.done = true;\n\n      var rootEntry = this.tryEntries[0];\n      var rootRecord = rootEntry.completion;\n      if (rootRecord.type === \"throw\") {\n        throw rootRecord.arg;\n      }\n\n      return this.rval;\n    },\n\n    dispatchException: function(exception) {\n      if (this.done) {\n        throw exception;\n      }\n\n      var context = this;\n      function handle(loc, caught) {\n        record.type = \"throw\";\n        record.arg = exception;\n        context.next = loc;\n\n        if (caught) {\n          // If the dispatched exception was caught by a catch block,\n          // then let that catch block handle the exception normally.\n          context.method = \"next\";\n          context.arg = undefined;\n        }\n\n        return !! caught;\n      }\n\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        var record = entry.completion;\n\n        if (entry.tryLoc === \"root\") {\n          // Exception thrown outside of any try block that could handle\n          // it, so set the completion value of the entire function to\n          // throw the exception.\n          return handle(\"end\");\n        }\n\n        if (entry.tryLoc <= this.prev) {\n          var hasCatch = hasOwn.call(entry, \"catchLoc\");\n          var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n          if (hasCatch && hasFinally) {\n            if (this.prev < entry.catchLoc) {\n              return handle(entry.catchLoc, true);\n            } else if (this.prev < entry.finallyLoc) {\n              return handle(entry.finallyLoc);\n            }\n\n          } else if (hasCatch) {\n            if (this.prev < entry.catchLoc) {\n              return handle(entry.catchLoc, true);\n            }\n\n          } else if (hasFinally) {\n            if (this.prev < entry.finallyLoc) {\n              return handle(entry.finallyLoc);\n            }\n\n          } else {\n            throw new Error(\"try statement without catch or finally\");\n          }\n        }\n      }\n    },\n\n    abrupt: function(type, arg) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.tryLoc <= this.prev &&\n            hasOwn.call(entry, \"finallyLoc\") &&\n            this.prev < entry.finallyLoc) {\n          var finallyEntry = entry;\n          break;\n        }\n      }\n\n      if (finallyEntry &&\n          (type === \"break\" ||\n           type === \"continue\") &&\n          finallyEntry.tryLoc <= arg &&\n          arg <= finallyEntry.finallyLoc) {\n        // Ignore the finally entry if control is not jumping to a\n        // location outside the try/catch block.\n        finallyEntry = null;\n      }\n\n      var record = finallyEntry ? finallyEntry.completion : {};\n      record.type = type;\n      record.arg = arg;\n\n      if (finallyEntry) {\n        this.method = \"next\";\n        this.next = finallyEntry.finallyLoc;\n        return ContinueSentinel;\n      }\n\n      return this.complete(record);\n    },\n\n    complete: function(record, afterLoc) {\n      if (record.type === \"throw\") {\n        throw record.arg;\n      }\n\n      if (record.type === \"break\" ||\n          record.type === \"continue\") {\n        this.next = record.arg;\n      } else if (record.type === \"return\") {\n        this.rval = this.arg = record.arg;\n        this.method = \"return\";\n        this.next = \"end\";\n      } else if (record.type === \"normal\" && afterLoc) {\n        this.next = afterLoc;\n      }\n\n      return ContinueSentinel;\n    },\n\n    finish: function(finallyLoc) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.finallyLoc === finallyLoc) {\n          this.complete(entry.completion, entry.afterLoc);\n          resetTryEntry(entry);\n          return ContinueSentinel;\n        }\n      }\n    },\n\n    \"catch\": function(tryLoc) {\n      for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n        var entry = this.tryEntries[i];\n        if (entry.tryLoc === tryLoc) {\n          var record = entry.completion;\n          if (record.type === \"throw\") {\n            var thrown = record.arg;\n            resetTryEntry(entry);\n          }\n          return thrown;\n        }\n      }\n\n      // The context.catch method must only be called with a location\n      // argument that corresponds to a known catch block.\n      throw new Error(\"illegal catch attempt\");\n    },\n\n    delegateYield: function(iterable, resultName, nextLoc) {\n      this.delegate = {\n        iterator: values(iterable),\n        resultName: resultName,\n        nextLoc: nextLoc\n      };\n\n      if (this.method === \"next\") {\n        // Deliberately forget the last sent value so that we don't\n        // accidentally pass it on to the delegate.\n        this.arg = undefined;\n      }\n\n      return ContinueSentinel;\n    }\n  };\n})(\n  // Among the various tricks for obtaining a reference to the global\n  // object, this seems to be the most reliable technique that does not\n  // use indirect eval (which violates Content Security Policy).\n  typeof global === \"object\" ? global :\n  typeof window === \"object\" ? window :\n  typeof self === \"object\" ? self : this\n);\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./node_modules/base64-js/index.js\":\n/*!*****************************************!*\\\n  !*** ./node_modules/base64-js/index.js ***!\n  \\*****************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.byteLength = byteLength\nexports.toByteArray = toByteArray\nexports.fromByteArray = fromByteArray\n\nvar lookup = []\nvar revLookup = []\nvar Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array\n\nvar code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nfor (var i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i]\n  revLookup[code.charCodeAt(i)] = i\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62\nrevLookup['_'.charCodeAt(0)] = 63\n\nfunction getLens (b64) {\n  var len = b64.length\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4')\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  var validLen = b64.indexOf('=')\n  if (validLen === -1) validLen = len\n\n  var placeHoldersLen = validLen === len\n    ? 0\n    : 4 - (validLen % 4)\n\n  return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n  var tmp\n  var lens = getLens(b64)\n  var validLen = lens[0]\n  var placeHoldersLen = lens[1]\n\n  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n  var curByte = 0\n\n  // if there are placeholders, only get up to the last complete 4 chars\n  var len = placeHoldersLen > 0\n    ? validLen - 4\n    : validLen\n\n  for (var i = 0; i < len; i += 4) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 18) |\n      (revLookup[b64.charCodeAt(i + 1)] << 12) |\n      (revLookup[b64.charCodeAt(i + 2)] << 6) |\n      revLookup[b64.charCodeAt(i + 3)]\n    arr[curByte++] = (tmp >> 16) & 0xFF\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 2) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 2) |\n      (revLookup[b64.charCodeAt(i + 1)] >> 4)\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  if (placeHoldersLen === 1) {\n    tmp =\n      (revLookup[b64.charCodeAt(i)] << 10) |\n      (revLookup[b64.charCodeAt(i + 1)] << 4) |\n      (revLookup[b64.charCodeAt(i + 2)] >> 2)\n    arr[curByte++] = (tmp >> 8) & 0xFF\n    arr[curByte++] = tmp & 0xFF\n  }\n\n  return arr\n}\n\nfunction tripletToBase64 (num) {\n  return lookup[num >> 18 & 0x3F] +\n    lookup[num >> 12 & 0x3F] +\n    lookup[num >> 6 & 0x3F] +\n    lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n  var tmp\n  var output = []\n  for (var i = start; i < end; i += 3) {\n    tmp =\n      ((uint8[i] << 16) & 0xFF0000) +\n      ((uint8[i + 1] << 8) & 0xFF00) +\n      (uint8[i + 2] & 0xFF)\n    output.push(tripletToBase64(tmp))\n  }\n  return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n  var tmp\n  var len = uint8.length\n  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n  var parts = []\n  var maxChunkLength = 16383 // must be multiple of 3\n\n  // go through the array every three bytes, we'll deal with trailing stuff later\n  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n    parts.push(encodeChunk(\n      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n    ))\n  }\n\n  // pad the end with zeros, but make sure to not forget the extra bytes\n  if (extraBytes === 1) {\n    tmp = uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 2] +\n      lookup[(tmp << 4) & 0x3F] +\n      '=='\n    )\n  } else if (extraBytes === 2) {\n    tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n    parts.push(\n      lookup[tmp >> 10] +\n      lookup[(tmp >> 4) & 0x3F] +\n      lookup[(tmp << 2) & 0x3F] +\n      '='\n    )\n  }\n\n  return parts.join('')\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/buffer/index.js\":\n/*!**************************************!*\\\n  !*** ./node_modules/buffer/index.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>\n * @license  MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(/*! base64-js */ \"./node_modules/base64-js/index.js\")\nvar ieee754 = __webpack_require__(/*! ieee754 */ \"./node_modules/ieee754/index.js\")\nvar isArray = __webpack_require__(/*! isarray */ \"./node_modules/buffer/node_modules/isarray/index.js\")\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n *   === true    Use Uint8Array implementation (fastest)\n *   === false   Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n *     incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n  ? global.TYPED_ARRAY_SUPPORT\n  : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n  try {\n    var arr = new Uint8Array(1)\n    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n    return arr.foo() === 42 && // typed array instances can be augmented\n        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n  } catch (e) {\n    return false\n  }\n}\n\nfunction kMaxLength () {\n  return Buffer.TYPED_ARRAY_SUPPORT\n    ? 0x7fffffff\n    : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n  if (kMaxLength() < length) {\n    throw new RangeError('Invalid typed array length')\n  }\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = new Uint8Array(length)\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    if (that === null) {\n      that = new Buffer(length)\n    }\n    that.length = length\n  }\n\n  return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n    return new Buffer(arg, encodingOrOffset, length)\n  }\n\n  // Common case.\n  if (typeof arg === 'number') {\n    if (typeof encodingOrOffset === 'string') {\n      throw new Error(\n        'If encoding is specified then the first argument must be a string'\n      )\n    }\n    return allocUnsafe(this, arg)\n  }\n  return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n  arr.__proto__ = Buffer.prototype\n  return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n  if (typeof value === 'number') {\n    throw new TypeError('\"value\" argument must not be a number')\n  }\n\n  if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n    return fromArrayBuffer(that, value, encodingOrOffset, length)\n  }\n\n  if (typeof value === 'string') {\n    return fromString(that, value, encodingOrOffset)\n  }\n\n  return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n  return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n  Buffer.prototype.__proto__ = Uint8Array.prototype\n  Buffer.__proto__ = Uint8Array\n  if (typeof Symbol !== 'undefined' && Symbol.species &&\n      Buffer[Symbol.species] === Buffer) {\n    // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n    Object.defineProperty(Buffer, Symbol.species, {\n      value: null,\n      configurable: true\n    })\n  }\n}\n\nfunction assertSize (size) {\n  if (typeof size !== 'number') {\n    throw new TypeError('\"size\" argument must be a number')\n  } else if (size < 0) {\n    throw new RangeError('\"size\" argument must not be negative')\n  }\n}\n\nfunction alloc (that, size, fill, encoding) {\n  assertSize(size)\n  if (size <= 0) {\n    return createBuffer(that, size)\n  }\n  if (fill !== undefined) {\n    // Only pay attention to encoding if it's a string. This\n    // prevents accidentally sending in a number that would\n    // be interpretted as a start offset.\n    return typeof encoding === 'string'\n      ? createBuffer(that, size).fill(fill, encoding)\n      : createBuffer(that, size).fill(fill)\n  }\n  return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n  return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n  assertSize(size)\n  that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) {\n    for (var i = 0; i < size; ++i) {\n      that[i] = 0\n    }\n  }\n  return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n  return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n  return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n  if (typeof encoding !== 'string' || encoding === '') {\n    encoding = 'utf8'\n  }\n\n  if (!Buffer.isEncoding(encoding)) {\n    throw new TypeError('\"encoding\" must be a valid string encoding')\n  }\n\n  var length = byteLength(string, encoding) | 0\n  that = createBuffer(that, length)\n\n  var actual = that.write(string, encoding)\n\n  if (actual !== length) {\n    // Writing a hex string, for example, that contains invalid characters will\n    // cause everything after the first invalid character to be ignored. (e.g.\n    // 'abxxcd' will be treated as 'ab')\n    that = that.slice(0, actual)\n  }\n\n  return that\n}\n\nfunction fromArrayLike (that, array) {\n  var length = array.length < 0 ? 0 : checked(array.length) | 0\n  that = createBuffer(that, length)\n  for (var i = 0; i < length; i += 1) {\n    that[i] = array[i] & 255\n  }\n  return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n  array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n  if (byteOffset < 0 || array.byteLength < byteOffset) {\n    throw new RangeError('\\'offset\\' is out of bounds')\n  }\n\n  if (array.byteLength < byteOffset + (length || 0)) {\n    throw new RangeError('\\'length\\' is out of bounds')\n  }\n\n  if (byteOffset === undefined && length === undefined) {\n    array = new Uint8Array(array)\n  } else if (length === undefined) {\n    array = new Uint8Array(array, byteOffset)\n  } else {\n    array = new Uint8Array(array, byteOffset, length)\n  }\n\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    // Return an augmented `Uint8Array` instance, for best performance\n    that = array\n    that.__proto__ = Buffer.prototype\n  } else {\n    // Fallback: Return an object instance of the Buffer class\n    that = fromArrayLike(that, array)\n  }\n  return that\n}\n\nfunction fromObject (that, obj) {\n  if (Buffer.isBuffer(obj)) {\n    var len = checked(obj.length) | 0\n    that = createBuffer(that, len)\n\n    if (that.length === 0) {\n      return that\n    }\n\n    obj.copy(that, 0, 0, len)\n    return that\n  }\n\n  if (obj) {\n    if ((typeof ArrayBuffer !== 'undefined' &&\n        obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n      if (typeof obj.length !== 'number' || isnan(obj.length)) {\n        return createBuffer(that, 0)\n      }\n      return fromArrayLike(that, obj)\n    }\n\n    if (obj.type === 'Buffer' && isArray(obj.data)) {\n      return fromArrayLike(that, obj.data)\n    }\n  }\n\n  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n  // Note: cannot use `length < kMaxLength()` here because that fails when\n  // length is NaN (which is otherwise coerced to zero.)\n  if (length >= kMaxLength()) {\n    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n                         'size: 0x' + kMaxLength().toString(16) + ' bytes')\n  }\n  return length | 0\n}\n\nfunction SlowBuffer (length) {\n  if (+length != length) { // eslint-disable-line eqeqeq\n    length = 0\n  }\n  return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n  return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n    throw new TypeError('Arguments must be Buffers')\n  }\n\n  if (a === b) return 0\n\n  var x = a.length\n  var y = b.length\n\n  for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n    if (a[i] !== b[i]) {\n      x = a[i]\n      y = b[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n  switch (String(encoding).toLowerCase()) {\n    case 'hex':\n    case 'utf8':\n    case 'utf-8':\n    case 'ascii':\n    case 'latin1':\n    case 'binary':\n    case 'base64':\n    case 'ucs2':\n    case 'ucs-2':\n    case 'utf16le':\n    case 'utf-16le':\n      return true\n    default:\n      return false\n  }\n}\n\nBuffer.concat = function concat (list, length) {\n  if (!isArray(list)) {\n    throw new TypeError('\"list\" argument must be an Array of Buffers')\n  }\n\n  if (list.length === 0) {\n    return Buffer.alloc(0)\n  }\n\n  var i\n  if (length === undefined) {\n    length = 0\n    for (i = 0; i < list.length; ++i) {\n      length += list[i].length\n    }\n  }\n\n  var buffer = Buffer.allocUnsafe(length)\n  var pos = 0\n  for (i = 0; i < list.length; ++i) {\n    var buf = list[i]\n    if (!Buffer.isBuffer(buf)) {\n      throw new TypeError('\"list\" argument must be an Array of Buffers')\n    }\n    buf.copy(buffer, pos)\n    pos += buf.length\n  }\n  return buffer\n}\n\nfunction byteLength (string, encoding) {\n  if (Buffer.isBuffer(string)) {\n    return string.length\n  }\n  if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n      (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n    return string.byteLength\n  }\n  if (typeof string !== 'string') {\n    string = '' + string\n  }\n\n  var len = string.length\n  if (len === 0) return 0\n\n  // Use a for loop to avoid recursion\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'ascii':\n      case 'latin1':\n      case 'binary':\n        return len\n      case 'utf8':\n      case 'utf-8':\n      case undefined:\n        return utf8ToBytes(string).length\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return len * 2\n      case 'hex':\n        return len >>> 1\n      case 'base64':\n        return base64ToBytes(string).length\n      default:\n        if (loweredCase) return utf8ToBytes(string).length // assume utf8\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n  var loweredCase = false\n\n  // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n  // property of a typed array.\n\n  // This behaves neither like String nor Uint8Array in that we set start/end\n  // to their upper/lower bounds if the value passed is out of range.\n  // undefined is handled specially as per ECMA-262 6th Edition,\n  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n  if (start === undefined || start < 0) {\n    start = 0\n  }\n  // Return early if start > this.length. Done here to prevent potential uint32\n  // coercion fail below.\n  if (start > this.length) {\n    return ''\n  }\n\n  if (end === undefined || end > this.length) {\n    end = this.length\n  }\n\n  if (end <= 0) {\n    return ''\n  }\n\n  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n  end >>>= 0\n  start >>>= 0\n\n  if (end <= start) {\n    return ''\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  while (true) {\n    switch (encoding) {\n      case 'hex':\n        return hexSlice(this, start, end)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Slice(this, start, end)\n\n      case 'ascii':\n        return asciiSlice(this, start, end)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Slice(this, start, end)\n\n      case 'base64':\n        return base64Slice(this, start, end)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return utf16leSlice(this, start, end)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = (encoding + '').toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n  var i = b[n]\n  b[n] = b[m]\n  b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n  var len = this.length\n  if (len % 2 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 16-bits')\n  }\n  for (var i = 0; i < len; i += 2) {\n    swap(this, i, i + 1)\n  }\n  return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n  var len = this.length\n  if (len % 4 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 32-bits')\n  }\n  for (var i = 0; i < len; i += 4) {\n    swap(this, i, i + 3)\n    swap(this, i + 1, i + 2)\n  }\n  return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n  var len = this.length\n  if (len % 8 !== 0) {\n    throw new RangeError('Buffer size must be a multiple of 64-bits')\n  }\n  for (var i = 0; i < len; i += 8) {\n    swap(this, i, i + 7)\n    swap(this, i + 1, i + 6)\n    swap(this, i + 2, i + 5)\n    swap(this, i + 3, i + 4)\n  }\n  return this\n}\n\nBuffer.prototype.toString = function toString () {\n  var length = this.length | 0\n  if (length === 0) return ''\n  if (arguments.length === 0) return utf8Slice(this, 0, length)\n  return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n  if (this === b) return true\n  return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n  var str = ''\n  var max = exports.INSPECT_MAX_BYTES\n  if (this.length > 0) {\n    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n    if (this.length > max) str += ' ... '\n  }\n  return '<Buffer ' + str + '>'\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n  if (!Buffer.isBuffer(target)) {\n    throw new TypeError('Argument must be a Buffer')\n  }\n\n  if (start === undefined) {\n    start = 0\n  }\n  if (end === undefined) {\n    end = target ? target.length : 0\n  }\n  if (thisStart === undefined) {\n    thisStart = 0\n  }\n  if (thisEnd === undefined) {\n    thisEnd = this.length\n  }\n\n  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n    throw new RangeError('out of range index')\n  }\n\n  if (thisStart >= thisEnd && start >= end) {\n    return 0\n  }\n  if (thisStart >= thisEnd) {\n    return -1\n  }\n  if (start >= end) {\n    return 1\n  }\n\n  start >>>= 0\n  end >>>= 0\n  thisStart >>>= 0\n  thisEnd >>>= 0\n\n  if (this === target) return 0\n\n  var x = thisEnd - thisStart\n  var y = end - start\n  var len = Math.min(x, y)\n\n  var thisCopy = this.slice(thisStart, thisEnd)\n  var targetCopy = target.slice(start, end)\n\n  for (var i = 0; i < len; ++i) {\n    if (thisCopy[i] !== targetCopy[i]) {\n      x = thisCopy[i]\n      y = targetCopy[i]\n      break\n    }\n  }\n\n  if (x < y) return -1\n  if (y < x) return 1\n  return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n  // Empty buffer means no match\n  if (buffer.length === 0) return -1\n\n  // Normalize byteOffset\n  if (typeof byteOffset === 'string') {\n    encoding = byteOffset\n    byteOffset = 0\n  } else if (byteOffset > 0x7fffffff) {\n    byteOffset = 0x7fffffff\n  } else if (byteOffset < -0x80000000) {\n    byteOffset = -0x80000000\n  }\n  byteOffset = +byteOffset  // Coerce to Number.\n  if (isNaN(byteOffset)) {\n    // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n    byteOffset = dir ? 0 : (buffer.length - 1)\n  }\n\n  // Normalize byteOffset: negative offsets start from the end of the buffer\n  if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n  if (byteOffset >= buffer.length) {\n    if (dir) return -1\n    else byteOffset = buffer.length - 1\n  } else if (byteOffset < 0) {\n    if (dir) byteOffset = 0\n    else return -1\n  }\n\n  // Normalize val\n  if (typeof val === 'string') {\n    val = Buffer.from(val, encoding)\n  }\n\n  // Finally, search either indexOf (if dir is true) or lastIndexOf\n  if (Buffer.isBuffer(val)) {\n    // Special case: looking for empty string/buffer always fails\n    if (val.length === 0) {\n      return -1\n    }\n    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n  } else if (typeof val === 'number') {\n    val = val & 0xFF // Search for a byte value [0-255]\n    if (Buffer.TYPED_ARRAY_SUPPORT &&\n        typeof Uint8Array.prototype.indexOf === 'function') {\n      if (dir) {\n        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n      } else {\n        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n      }\n    }\n    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n  }\n\n  throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n  var indexSize = 1\n  var arrLength = arr.length\n  var valLength = val.length\n\n  if (encoding !== undefined) {\n    encoding = String(encoding).toLowerCase()\n    if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n        encoding === 'utf16le' || encoding === 'utf-16le') {\n      if (arr.length < 2 || val.length < 2) {\n        return -1\n      }\n      indexSize = 2\n      arrLength /= 2\n      valLength /= 2\n      byteOffset /= 2\n    }\n  }\n\n  function read (buf, i) {\n    if (indexSize === 1) {\n      return buf[i]\n    } else {\n      return buf.readUInt16BE(i * indexSize)\n    }\n  }\n\n  var i\n  if (dir) {\n    var foundIndex = -1\n    for (i = byteOffset; i < arrLength; i++) {\n      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n        if (foundIndex === -1) foundIndex = i\n        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n      } else {\n        if (foundIndex !== -1) i -= i - foundIndex\n        foundIndex = -1\n      }\n    }\n  } else {\n    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n    for (i = byteOffset; i >= 0; i--) {\n      var found = true\n      for (var j = 0; j < valLength; j++) {\n        if (read(arr, i + j) !== read(val, j)) {\n          found = false\n          break\n        }\n      }\n      if (found) return i\n    }\n  }\n\n  return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n  return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n  offset = Number(offset) || 0\n  var remaining = buf.length - offset\n  if (!length) {\n    length = remaining\n  } else {\n    length = Number(length)\n    if (length > remaining) {\n      length = remaining\n    }\n  }\n\n  // must be an even number of digits\n  var strLen = string.length\n  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n  if (length > strLen / 2) {\n    length = strLen / 2\n  }\n  for (var i = 0; i < length; ++i) {\n    var parsed = parseInt(string.substr(i * 2, 2), 16)\n    if (isNaN(parsed)) return i\n    buf[offset + i] = parsed\n  }\n  return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n  return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n  return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n  return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n  // Buffer#write(string)\n  if (offset === undefined) {\n    encoding = 'utf8'\n    length = this.length\n    offset = 0\n  // Buffer#write(string, encoding)\n  } else if (length === undefined && typeof offset === 'string') {\n    encoding = offset\n    length = this.length\n    offset = 0\n  // Buffer#write(string, offset[, length][, encoding])\n  } else if (isFinite(offset)) {\n    offset = offset | 0\n    if (isFinite(length)) {\n      length = length | 0\n      if (encoding === undefined) encoding = 'utf8'\n    } else {\n      encoding = length\n      length = undefined\n    }\n  // legacy write(string, encoding, offset, length) - remove in v0.13\n  } else {\n    throw new Error(\n      'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n    )\n  }\n\n  var remaining = this.length - offset\n  if (length === undefined || length > remaining) length = remaining\n\n  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n    throw new RangeError('Attempt to write outside buffer bounds')\n  }\n\n  if (!encoding) encoding = 'utf8'\n\n  var loweredCase = false\n  for (;;) {\n    switch (encoding) {\n      case 'hex':\n        return hexWrite(this, string, offset, length)\n\n      case 'utf8':\n      case 'utf-8':\n        return utf8Write(this, string, offset, length)\n\n      case 'ascii':\n        return asciiWrite(this, string, offset, length)\n\n      case 'latin1':\n      case 'binary':\n        return latin1Write(this, string, offset, length)\n\n      case 'base64':\n        // Warning: maxLength not taken into account in base64Write\n        return base64Write(this, string, offset, length)\n\n      case 'ucs2':\n      case 'ucs-2':\n      case 'utf16le':\n      case 'utf-16le':\n        return ucs2Write(this, string, offset, length)\n\n      default:\n        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n        encoding = ('' + encoding).toLowerCase()\n        loweredCase = true\n    }\n  }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n  return {\n    type: 'Buffer',\n    data: Array.prototype.slice.call(this._arr || this, 0)\n  }\n}\n\nfunction base64Slice (buf, start, end) {\n  if (start === 0 && end === buf.length) {\n    return base64.fromByteArray(buf)\n  } else {\n    return base64.fromByteArray(buf.slice(start, end))\n  }\n}\n\nfunction utf8Slice (buf, start, end) {\n  end = Math.min(buf.length, end)\n  var res = []\n\n  var i = start\n  while (i < end) {\n    var firstByte = buf[i]\n    var codePoint = null\n    var bytesPerSequence = (firstByte > 0xEF) ? 4\n      : (firstByte > 0xDF) ? 3\n      : (firstByte > 0xBF) ? 2\n      : 1\n\n    if (i + bytesPerSequence <= end) {\n      var secondByte, thirdByte, fourthByte, tempCodePoint\n\n      switch (bytesPerSequence) {\n        case 1:\n          if (firstByte < 0x80) {\n            codePoint = firstByte\n          }\n          break\n        case 2:\n          secondByte = buf[i + 1]\n          if ((secondByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n            if (tempCodePoint > 0x7F) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 3:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n              codePoint = tempCodePoint\n            }\n          }\n          break\n        case 4:\n          secondByte = buf[i + 1]\n          thirdByte = buf[i + 2]\n          fourthByte = buf[i + 3]\n          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n              codePoint = tempCodePoint\n            }\n          }\n      }\n    }\n\n    if (codePoint === null) {\n      // we did not generate a valid codePoint so insert a\n      // replacement char (U+FFFD) and advance only 1 byte\n      codePoint = 0xFFFD\n      bytesPerSequence = 1\n    } else if (codePoint > 0xFFFF) {\n      // encode to utf16 (surrogate pair dance)\n      codePoint -= 0x10000\n      res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n      codePoint = 0xDC00 | codePoint & 0x3FF\n    }\n\n    res.push(codePoint)\n    i += bytesPerSequence\n  }\n\n  return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n  var len = codePoints.length\n  if (len <= MAX_ARGUMENTS_LENGTH) {\n    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n  }\n\n  // Decode in chunks to avoid \"call stack size exceeded\".\n  var res = ''\n  var i = 0\n  while (i < len) {\n    res += String.fromCharCode.apply(\n      String,\n      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n    )\n  }\n  return res\n}\n\nfunction asciiSlice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i] & 0x7F)\n  }\n  return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n  var ret = ''\n  end = Math.min(buf.length, end)\n\n  for (var i = start; i < end; ++i) {\n    ret += String.fromCharCode(buf[i])\n  }\n  return ret\n}\n\nfunction hexSlice (buf, start, end) {\n  var len = buf.length\n\n  if (!start || start < 0) start = 0\n  if (!end || end < 0 || end > len) end = len\n\n  var out = ''\n  for (var i = start; i < end; ++i) {\n    out += toHex(buf[i])\n  }\n  return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n  var bytes = buf.slice(start, end)\n  var res = ''\n  for (var i = 0; i < bytes.length; i += 2) {\n    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n  }\n  return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n  var len = this.length\n  start = ~~start\n  end = end === undefined ? len : ~~end\n\n  if (start < 0) {\n    start += len\n    if (start < 0) start = 0\n  } else if (start > len) {\n    start = len\n  }\n\n  if (end < 0) {\n    end += len\n    if (end < 0) end = 0\n  } else if (end > len) {\n    end = len\n  }\n\n  if (end < start) end = start\n\n  var newBuf\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    newBuf = this.subarray(start, end)\n    newBuf.__proto__ = Buffer.prototype\n  } else {\n    var sliceLen = end - start\n    newBuf = new Buffer(sliceLen, undefined)\n    for (var i = 0; i < sliceLen; ++i) {\n      newBuf[i] = this[i + start]\n    }\n  }\n\n  return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    checkOffset(offset, byteLength, this.length)\n  }\n\n  var val = this[offset + --byteLength]\n  var mul = 1\n  while (byteLength > 0 && (mul *= 0x100)) {\n    val += this[offset + --byteLength] * mul\n  }\n\n  return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return ((this[offset]) |\n      (this[offset + 1] << 8) |\n      (this[offset + 2] << 16)) +\n      (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] * 0x1000000) +\n    ((this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var val = this[offset]\n  var mul = 1\n  var i = 0\n  while (++i < byteLength && (mul *= 0x100)) {\n    val += this[offset + i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n  var i = byteLength\n  var mul = 1\n  var val = this[offset + --i]\n  while (i > 0 && (mul *= 0x100)) {\n    val += this[offset + --i] * mul\n  }\n  mul *= 0x80\n\n  if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n  return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 1, this.length)\n  if (!(this[offset] & 0x80)) return (this[offset])\n  return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset] | (this[offset + 1] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 2, this.length)\n  var val = this[offset + 1] | (this[offset] << 8)\n  return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset]) |\n    (this[offset + 1] << 8) |\n    (this[offset + 2] << 16) |\n    (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n\n  return (this[offset] << 24) |\n    (this[offset + 1] << 16) |\n    (this[offset + 2] << 8) |\n    (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 4, this.length)\n  return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n  if (!noAssert) checkOffset(offset, 8, this.length)\n  return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n  if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n  if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var mul = 1\n  var i = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  byteLength = byteLength | 0\n  if (!noAssert) {\n    var maxBytes = Math.pow(2, 8 * byteLength) - 1\n    checkInt(this, value, offset, byteLength, maxBytes, 0)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    this[offset + i] = (value / mul) & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n      (littleEndian ? i : 1 - i) * 8\n  }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n  if (value < 0) value = 0xffffffff + value + 1\n  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n  }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset + 3] = (value >>> 24)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 1] = (value >>> 8)\n    this[offset] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = 0\n  var mul = 1\n  var sub = 0\n  this[offset] = value & 0xFF\n  while (++i < byteLength && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) {\n    var limit = Math.pow(2, 8 * byteLength - 1)\n\n    checkInt(this, value, offset, byteLength, limit - 1, -limit)\n  }\n\n  var i = byteLength - 1\n  var mul = 1\n  var sub = 0\n  this[offset + i] = value & 0xFF\n  while (--i >= 0 && (mul *= 0x100)) {\n    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n      sub = 1\n    }\n    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n  }\n\n  return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n  if (value < 0) value = 0xff + value + 1\n  this[offset] = (value & 0xff)\n  return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n  } else {\n    objectWriteUInt16(this, value, offset, true)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 8)\n    this[offset + 1] = (value & 0xff)\n  } else {\n    objectWriteUInt16(this, value, offset, false)\n  }\n  return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value & 0xff)\n    this[offset + 1] = (value >>> 8)\n    this[offset + 2] = (value >>> 16)\n    this[offset + 3] = (value >>> 24)\n  } else {\n    objectWriteUInt32(this, value, offset, true)\n  }\n  return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n  value = +value\n  offset = offset | 0\n  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n  if (value < 0) value = 0xffffffff + value + 1\n  if (Buffer.TYPED_ARRAY_SUPPORT) {\n    this[offset] = (value >>> 24)\n    this[offset + 1] = (value >>> 16)\n    this[offset + 2] = (value >>> 8)\n    this[offset + 3] = (value & 0xff)\n  } else {\n    objectWriteUInt32(this, value, offset, false)\n  }\n  return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n  if (offset + ext > buf.length) throw new RangeError('Index out of range')\n  if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 23, 4)\n  return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n  return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n  if (!noAssert) {\n    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n  }\n  ieee754.write(buf, value, offset, littleEndian, 52, 8)\n  return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n  return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n  if (!start) start = 0\n  if (!end && end !== 0) end = this.length\n  if (targetStart >= target.length) targetStart = target.length\n  if (!targetStart) targetStart = 0\n  if (end > 0 && end < start) end = start\n\n  // Copy 0 bytes; we're done\n  if (end === start) return 0\n  if (target.length === 0 || this.length === 0) return 0\n\n  // Fatal error conditions\n  if (targetStart < 0) {\n    throw new RangeError('targetStart out of bounds')\n  }\n  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n  if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n  // Are we oob?\n  if (end > this.length) end = this.length\n  if (target.length - targetStart < end - start) {\n    end = target.length - targetStart + start\n  }\n\n  var len = end - start\n  var i\n\n  if (this === target && start < targetStart && targetStart < end) {\n    // descending copy from end\n    for (i = len - 1; i >= 0; --i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n    // ascending copy from start\n    for (i = 0; i < len; ++i) {\n      target[i + targetStart] = this[i + start]\n    }\n  } else {\n    Uint8Array.prototype.set.call(\n      target,\n      this.subarray(start, start + len),\n      targetStart\n    )\n  }\n\n  return len\n}\n\n// Usage:\n//    buffer.fill(number[, offset[, end]])\n//    buffer.fill(buffer[, offset[, end]])\n//    buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n  // Handle string cases:\n  if (typeof val === 'string') {\n    if (typeof start === 'string') {\n      encoding = start\n      start = 0\n      end = this.length\n    } else if (typeof end === 'string') {\n      encoding = end\n      end = this.length\n    }\n    if (val.length === 1) {\n      var code = val.charCodeAt(0)\n      if (code < 256) {\n        val = code\n      }\n    }\n    if (encoding !== undefined && typeof encoding !== 'string') {\n      throw new TypeError('encoding must be a string')\n    }\n    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n      throw new TypeError('Unknown encoding: ' + encoding)\n    }\n  } else if (typeof val === 'number') {\n    val = val & 255\n  }\n\n  // Invalid ranges are not set to a default, so can range check early.\n  if (start < 0 || this.length < start || this.length < end) {\n    throw new RangeError('Out of range index')\n  }\n\n  if (end <= start) {\n    return this\n  }\n\n  start = start >>> 0\n  end = end === undefined ? this.length : end >>> 0\n\n  if (!val) val = 0\n\n  var i\n  if (typeof val === 'number') {\n    for (i = start; i < end; ++i) {\n      this[i] = val\n    }\n  } else {\n    var bytes = Buffer.isBuffer(val)\n      ? val\n      : utf8ToBytes(new Buffer(val, encoding).toString())\n    var len = bytes.length\n    for (i = 0; i < end - start; ++i) {\n      this[i + start] = bytes[i % len]\n    }\n  }\n\n  return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n  // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n  str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n  // Node converts strings with length < 2 to ''\n  if (str.length < 2) return ''\n  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n  while (str.length % 4 !== 0) {\n    str = str + '='\n  }\n  return str\n}\n\nfunction stringtrim (str) {\n  if (str.trim) return str.trim()\n  return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n  if (n < 16) return '0' + n.toString(16)\n  return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n  units = units || Infinity\n  var codePoint\n  var length = string.length\n  var leadSurrogate = null\n  var bytes = []\n\n  for (var i = 0; i < length; ++i) {\n    codePoint = string.charCodeAt(i)\n\n    // is surrogate component\n    if (codePoint > 0xD7FF && codePoint < 0xE000) {\n      // last char was a lead\n      if (!leadSurrogate) {\n        // no lead yet\n        if (codePoint > 0xDBFF) {\n          // unexpected trail\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        } else if (i + 1 === length) {\n          // unpaired lead\n          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n          continue\n        }\n\n        // valid lead\n        leadSurrogate = codePoint\n\n        continue\n      }\n\n      // 2 leads in a row\n      if (codePoint < 0xDC00) {\n        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n        leadSurrogate = codePoint\n        continue\n      }\n\n      // valid surrogate pair\n      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n    } else if (leadSurrogate) {\n      // valid bmp char, but last char was a lead\n      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n    }\n\n    leadSurrogate = null\n\n    // encode utf8\n    if (codePoint < 0x80) {\n      if ((units -= 1) < 0) break\n      bytes.push(codePoint)\n    } else if (codePoint < 0x800) {\n      if ((units -= 2) < 0) break\n      bytes.push(\n        codePoint >> 0x6 | 0xC0,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x10000) {\n      if ((units -= 3) < 0) break\n      bytes.push(\n        codePoint >> 0xC | 0xE0,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else if (codePoint < 0x110000) {\n      if ((units -= 4) < 0) break\n      bytes.push(\n        codePoint >> 0x12 | 0xF0,\n        codePoint >> 0xC & 0x3F | 0x80,\n        codePoint >> 0x6 & 0x3F | 0x80,\n        codePoint & 0x3F | 0x80\n      )\n    } else {\n      throw new Error('Invalid code point')\n    }\n  }\n\n  return bytes\n}\n\nfunction asciiToBytes (str) {\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    // Node's code seems to be doing this and not & 0x7F..\n    byteArray.push(str.charCodeAt(i) & 0xFF)\n  }\n  return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n  var c, hi, lo\n  var byteArray = []\n  for (var i = 0; i < str.length; ++i) {\n    if ((units -= 2) < 0) break\n\n    c = str.charCodeAt(i)\n    hi = c >> 8\n    lo = c % 256\n    byteArray.push(lo)\n    byteArray.push(hi)\n  }\n\n  return byteArray\n}\n\nfunction base64ToBytes (str) {\n  return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n  for (var i = 0; i < length; ++i) {\n    if ((i + offset >= dst.length) || (i >= src.length)) break\n    dst[i + offset] = src[i]\n  }\n  return i\n}\n\nfunction isnan (val) {\n  return val !== val // eslint-disable-line no-self-compare\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n/***/ }),\n\n/***/ \"./node_modules/buffer/node_modules/isarray/index.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/buffer/node_modules/isarray/index.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n  return toString.call(arr) == '[object Array]';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/fn/regexp/escape.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/fn/regexp/escape.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ../../modules/core.regexp.escape */ \"./node_modules/core-js/modules/core.regexp.escape.js\");\nmodule.exports = __webpack_require__(/*! ../../modules/_core */ \"./node_modules/core-js/modules/_core.js\").RegExp.escape;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_a-function.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_a-function.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_a-number-value.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_a-number-value.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nmodule.exports = function (it, msg) {\n  if (typeof it != 'number' && cof(it) != 'Number') throw TypeError(msg);\n  return +it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_add-to-unscopables.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_add-to-unscopables.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.31 Array.prototype[@@unscopables]\nvar UNSCOPABLES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('unscopables');\nvar ArrayProto = Array.prototype;\nif (ArrayProto[UNSCOPABLES] == undefined) __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(ArrayProto, UNSCOPABLES, {});\nmodule.exports = function (key) {\n  ArrayProto[UNSCOPABLES][key] = true;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_advance-string-index.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_advance-string-index.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n // `AdvanceStringIndex` abstract operation\n// https://tc39.github.io/ecma262/#sec-advancestringindex\nmodule.exports = function (S, index, unicode) {\n  return index + (unicode ? at(S, index).length : 1);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-instance.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-instance.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it, Constructor, name, forbiddenField) {\n  if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {\n    throw TypeError(name + ': incorrect invocation!');\n  } return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_an-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_an-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nmodule.exports = function (it) {\n  if (!isObject(it)) throw TypeError(it + ' is not an object!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-copy-within.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-copy-within.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)\n\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n\nmodule.exports = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {\n  var O = toObject(this);\n  var len = toLength(O.length);\n  var to = toAbsoluteIndex(target, len);\n  var from = toAbsoluteIndex(start, len);\n  var end = arguments.length > 2 ? arguments[2] : undefined;\n  var count = Math.min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);\n  var inc = 1;\n  if (from < to && to < from + count) {\n    inc = -1;\n    from += count - 1;\n    to += count - 1;\n  }\n  while (count-- > 0) {\n    if (from in O) O[to] = O[from];\n    else delete O[to];\n    to += inc;\n    from += inc;\n  } return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-fill.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-fill.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)\n\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nmodule.exports = function fill(value /* , start = 0, end = @length */) {\n  var O = toObject(this);\n  var length = toLength(O.length);\n  var aLen = arguments.length;\n  var index = toAbsoluteIndex(aLen > 1 ? arguments[1] : undefined, length);\n  var end = aLen > 2 ? arguments[2] : undefined;\n  var endPos = end === undefined ? length : toAbsoluteIndex(end, length);\n  while (endPos > index) O[index++] = value;\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-from-iterable.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-from-iterable.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\n\nmodule.exports = function (iter, ITERATOR) {\n  var result = [];\n  forOf(iter, false, result.push, result, ITERATOR);\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-includes.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-includes.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// false -> Array#indexOf\n// true  -> Array#includes\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nmodule.exports = function (IS_INCLUDES) {\n  return function ($this, el, fromIndex) {\n    var O = toIObject($this);\n    var length = toLength(O.length);\n    var index = toAbsoluteIndex(fromIndex, length);\n    var value;\n    // Array#includes uses SameValueZero equality algorithm\n    // eslint-disable-next-line no-self-compare\n    if (IS_INCLUDES && el != el) while (length > index) {\n      value = O[index++];\n      // eslint-disable-next-line no-self-compare\n      if (value != value) return true;\n    // Array#indexOf ignores holes, Array#includes - not\n    } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n      if (O[index] === el) return IS_INCLUDES || index || 0;\n    } return !IS_INCLUDES && -1;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-methods.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-methods.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 0 -> Array#forEach\n// 1 -> Array#map\n// 2 -> Array#filter\n// 3 -> Array#some\n// 4 -> Array#every\n// 5 -> Array#find\n// 6 -> Array#findIndex\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar asc = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\nmodule.exports = function (TYPE, $create) {\n  var IS_MAP = TYPE == 1;\n  var IS_FILTER = TYPE == 2;\n  var IS_SOME = TYPE == 3;\n  var IS_EVERY = TYPE == 4;\n  var IS_FIND_INDEX = TYPE == 6;\n  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;\n  var create = $create || asc;\n  return function ($this, callbackfn, that) {\n    var O = toObject($this);\n    var self = IObject(O);\n    var f = ctx(callbackfn, that, 3);\n    var length = toLength(self.length);\n    var index = 0;\n    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;\n    var val, res;\n    for (;length > index; index++) if (NO_HOLES || index in self) {\n      val = self[index];\n      res = f(val, index, O);\n      if (TYPE) {\n        if (IS_MAP) result[index] = res;   // map\n        else if (res) switch (TYPE) {\n          case 3: return true;             // some\n          case 5: return val;              // find\n          case 6: return index;            // findIndex\n          case 2: result.push(val);        // filter\n        } else if (IS_EVERY) return false; // every\n      }\n    }\n    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-reduce.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-reduce.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n\nmodule.exports = function (that, callbackfn, aLen, memo, isRight) {\n  aFunction(callbackfn);\n  var O = toObject(that);\n  var self = IObject(O);\n  var length = toLength(O.length);\n  var index = isRight ? length - 1 : 0;\n  var i = isRight ? -1 : 1;\n  if (aLen < 2) for (;;) {\n    if (index in self) {\n      memo = self[index];\n      index += i;\n      break;\n    }\n    index += i;\n    if (isRight ? index < 0 : length <= index) {\n      throw TypeError('Reduce of empty array with no initial value');\n    }\n  }\n  for (;isRight ? index >= 0 : length > index; index += i) if (index in self) {\n    memo = callbackfn(memo, self[index], index, O);\n  }\n  return memo;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-constructor.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-constructor.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (original) {\n  var C;\n  if (isArray(original)) {\n    C = original.constructor;\n    // cross-realm fallback\n    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;\n    if (isObject(C)) {\n      C = C[SPECIES];\n      if (C === null) C = undefined;\n    }\n  } return C === undefined ? Array : C;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_array-species-create.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_array-species-create.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 9.4.2.3 ArraySpeciesCreate(originalArray, length)\nvar speciesConstructor = __webpack_require__(/*! ./_array-species-constructor */ \"./node_modules/core-js/modules/_array-species-constructor.js\");\n\nmodule.exports = function (original, length) {\n  return new (speciesConstructor(original))(length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_bind.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_bind.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar arraySlice = [].slice;\nvar factories = {};\n\nvar construct = function (F, len, args) {\n  if (!(len in factories)) {\n    for (var n = [], i = 0; i < len; i++) n[i] = 'a[' + i + ']';\n    // eslint-disable-next-line no-new-func\n    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');\n  } return factories[len](F, args);\n};\n\nmodule.exports = Function.bind || function bind(that /* , ...args */) {\n  var fn = aFunction(this);\n  var partArgs = arraySlice.call(arguments, 1);\n  var bound = function (/* args... */) {\n    var args = partArgs.concat(arraySlice.call(arguments));\n    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);\n  };\n  if (isObject(fn.prototype)) bound.prototype = fn.prototype;\n  return bound;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_classof.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_classof.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n  try {\n    return it[key];\n  } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n  var O, T, B;\n  return it === undefined ? 'Undefined' : it === null ? 'Null'\n    // @@toStringTag case\n    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n    // builtinTag case\n    : ARG ? cof(O)\n    // ES3 arguments fallback\n    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_cof.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_cof.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar toString = {}.toString;\n\nmodule.exports = function (it) {\n  return toString.call(it).slice(8, -1);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection-strong.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection-strong.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar $iterDefine = __webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\");\nvar step = __webpack_require__(/*! ./_iter-step */ \"./node_modules/core-js/modules/_iter-step.js\");\nvar setSpecies = __webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar fastKey = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").fastKey;\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar SIZE = DESCRIPTORS ? '_s' : 'size';\n\nvar getEntry = function (that, key) {\n  // fast case\n  var index = fastKey(key);\n  var entry;\n  if (index !== 'F') return that._i[index];\n  // frozen object case\n  for (entry = that._f; entry; entry = entry.n) {\n    if (entry.k == key) return entry;\n  }\n};\n\nmodule.exports = {\n  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {\n    var C = wrapper(function (that, iterable) {\n      anInstance(that, C, NAME, '_i');\n      that._t = NAME;         // collection type\n      that._i = create(null); // index\n      that._f = undefined;    // first entry\n      that._l = undefined;    // last entry\n      that[SIZE] = 0;         // size\n      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);\n    });\n    redefineAll(C.prototype, {\n      // 23.1.3.1 Map.prototype.clear()\n      // 23.2.3.2 Set.prototype.clear()\n      clear: function clear() {\n        for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {\n          entry.r = true;\n          if (entry.p) entry.p = entry.p.n = undefined;\n          delete data[entry.i];\n        }\n        that._f = that._l = undefined;\n        that[SIZE] = 0;\n      },\n      // 23.1.3.3 Map.prototype.delete(key)\n      // 23.2.3.4 Set.prototype.delete(value)\n      'delete': function (key) {\n        var that = validate(this, NAME);\n        var entry = getEntry(that, key);\n        if (entry) {\n          var next = entry.n;\n          var prev = entry.p;\n          delete that._i[entry.i];\n          entry.r = true;\n          if (prev) prev.n = next;\n          if (next) next.p = prev;\n          if (that._f == entry) that._f = next;\n          if (that._l == entry) that._l = prev;\n          that[SIZE]--;\n        } return !!entry;\n      },\n      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)\n      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)\n      forEach: function forEach(callbackfn /* , that = undefined */) {\n        validate(this, NAME);\n        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);\n        var entry;\n        while (entry = entry ? entry.n : this._f) {\n          f(entry.v, entry.k, this);\n          // revert to the last existing entry\n          while (entry && entry.r) entry = entry.p;\n        }\n      },\n      // 23.1.3.7 Map.prototype.has(key)\n      // 23.2.3.7 Set.prototype.has(value)\n      has: function has(key) {\n        return !!getEntry(validate(this, NAME), key);\n      }\n    });\n    if (DESCRIPTORS) dP(C.prototype, 'size', {\n      get: function () {\n        return validate(this, NAME)[SIZE];\n      }\n    });\n    return C;\n  },\n  def: function (that, key, value) {\n    var entry = getEntry(that, key);\n    var prev, index;\n    // change existing entry\n    if (entry) {\n      entry.v = value;\n    // create new entry\n    } else {\n      that._l = entry = {\n        i: index = fastKey(key, true), // <- index\n        k: key,                        // <- key\n        v: value,                      // <- value\n        p: prev = that._l,             // <- previous entry\n        n: undefined,                  // <- next entry\n        r: false                       // <- removed\n      };\n      if (!that._f) that._f = entry;\n      if (prev) prev.n = entry;\n      that[SIZE]++;\n      // add to index\n      if (index !== 'F') that._i[index] = entry;\n    } return that;\n  },\n  getEntry: getEntry,\n  setStrong: function (C, NAME, IS_MAP) {\n    // add .keys, .values, .entries, [@@iterator]\n    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11\n    $iterDefine(C, NAME, function (iterated, kind) {\n      this._t = validate(iterated, NAME); // target\n      this._k = kind;                     // kind\n      this._l = undefined;                // previous\n    }, function () {\n      var that = this;\n      var kind = that._k;\n      var entry = that._l;\n      // revert to the last existing entry\n      while (entry && entry.r) entry = entry.p;\n      // get next entry\n      if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {\n        // or finish the iteration\n        that._t = undefined;\n        return step(1);\n      }\n      // return step by kind\n      if (kind == 'keys') return step(0, entry.k);\n      if (kind == 'values') return step(0, entry.v);\n      return step(0, [entry.k, entry.v]);\n    }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);\n\n    // add [@@species], 23.1.2.2, 23.2.2.2\n    setSpecies(NAME);\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection-to-json.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection-to-json.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar from = __webpack_require__(/*! ./_array-from-iterable */ \"./node_modules/core-js/modules/_array-from-iterable.js\");\nmodule.exports = function (NAME) {\n  return function toJSON() {\n    if (classof(this) != NAME) throw TypeError(NAME + \"#toJSON isn't generic\");\n    return from(this);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection-weak.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection-weak.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar getWeak = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").getWeak;\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar createArrayMethod = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\");\nvar $has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar arrayFind = createArrayMethod(5);\nvar arrayFindIndex = createArrayMethod(6);\nvar id = 0;\n\n// fallback for uncaught frozen keys\nvar uncaughtFrozenStore = function (that) {\n  return that._l || (that._l = new UncaughtFrozenStore());\n};\nvar UncaughtFrozenStore = function () {\n  this.a = [];\n};\nvar findUncaughtFrozen = function (store, key) {\n  return arrayFind(store.a, function (it) {\n    return it[0] === key;\n  });\n};\nUncaughtFrozenStore.prototype = {\n  get: function (key) {\n    var entry = findUncaughtFrozen(this, key);\n    if (entry) return entry[1];\n  },\n  has: function (key) {\n    return !!findUncaughtFrozen(this, key);\n  },\n  set: function (key, value) {\n    var entry = findUncaughtFrozen(this, key);\n    if (entry) entry[1] = value;\n    else this.a.push([key, value]);\n  },\n  'delete': function (key) {\n    var index = arrayFindIndex(this.a, function (it) {\n      return it[0] === key;\n    });\n    if (~index) this.a.splice(index, 1);\n    return !!~index;\n  }\n};\n\nmodule.exports = {\n  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {\n    var C = wrapper(function (that, iterable) {\n      anInstance(that, C, NAME, '_i');\n      that._t = NAME;      // collection type\n      that._i = id++;      // collection id\n      that._l = undefined; // leak store for uncaught frozen objects\n      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);\n    });\n    redefineAll(C.prototype, {\n      // 23.3.3.2 WeakMap.prototype.delete(key)\n      // 23.4.3.3 WeakSet.prototype.delete(value)\n      'delete': function (key) {\n        if (!isObject(key)) return false;\n        var data = getWeak(key);\n        if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key);\n        return data && $has(data, this._i) && delete data[this._i];\n      },\n      // 23.3.3.4 WeakMap.prototype.has(key)\n      // 23.4.3.4 WeakSet.prototype.has(value)\n      has: function has(key) {\n        if (!isObject(key)) return false;\n        var data = getWeak(key);\n        if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key);\n        return data && $has(data, this._i);\n      }\n    });\n    return C;\n  },\n  def: function (that, key, value) {\n    var data = getWeak(anObject(key), true);\n    if (data === true) uncaughtFrozenStore(that).set(key, value);\n    else data[that._i] = value;\n    return that;\n  },\n  ufstore: uncaughtFrozenStore\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_collection.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_collection.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar $iterDetect = __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ \"./node_modules/core-js/modules/_inherit-if-required.js\");\n\nmodule.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {\n  var Base = global[NAME];\n  var C = Base;\n  var ADDER = IS_MAP ? 'set' : 'add';\n  var proto = C && C.prototype;\n  var O = {};\n  var fixMethod = function (KEY) {\n    var fn = proto[KEY];\n    redefine(proto, KEY,\n      KEY == 'delete' ? function (a) {\n        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'has' ? function has(a) {\n        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'get' ? function get(a) {\n        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);\n      } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; }\n        : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; }\n    );\n  };\n  if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () {\n    new C().entries().next();\n  }))) {\n    // create collection constructor\n    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);\n    redefineAll(C.prototype, methods);\n    meta.NEED = true;\n  } else {\n    var instance = new C();\n    // early implementations not supports chaining\n    var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;\n    // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false\n    var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });\n    // most early implementations doesn't supports iterables, most modern - not close it correctly\n    var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new\n    // for early implementations -0 and +0 not the same\n    var BUGGY_ZERO = !IS_WEAK && fails(function () {\n      // V8 ~ Chromium 42- fails only with 5+ elements\n      var $instance = new C();\n      var index = 5;\n      while (index--) $instance[ADDER](index, index);\n      return !$instance.has(-0);\n    });\n    if (!ACCEPT_ITERABLES) {\n      C = wrapper(function (target, iterable) {\n        anInstance(target, C, NAME);\n        var that = inheritIfRequired(new Base(), target, C);\n        if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);\n        return that;\n      });\n      C.prototype = proto;\n      proto.constructor = C;\n    }\n    if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {\n      fixMethod('delete');\n      fixMethod('has');\n      IS_MAP && fixMethod('get');\n    }\n    if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);\n    // weak collections should not contains .clear method\n    if (IS_WEAK && proto.clear) delete proto.clear;\n  }\n\n  setToStringTag(C, NAME);\n\n  O[NAME] = C;\n  $export($export.G + $export.W + $export.F * (C != Base), O);\n\n  if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);\n\n  return C;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_core.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_core.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar core = module.exports = { version: '2.6.4' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_create-property.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_create-property.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\n\nmodule.exports = function (object, index, value) {\n  if (index in object) $defineProperty.f(object, index, createDesc(0, value));\n  else object[index] = value;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ctx.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_ctx.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// optional / simple context binding\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nmodule.exports = function (fn, that, length) {\n  aFunction(fn);\n  if (that === undefined) return fn;\n  switch (length) {\n    case 1: return function (a) {\n      return fn.call(that, a);\n    };\n    case 2: return function (a, b) {\n      return fn.call(that, a, b);\n    };\n    case 3: return function (a, b, c) {\n      return fn.call(that, a, b, c);\n    };\n  }\n  return function (/* ...args */) {\n    return fn.apply(that, arguments);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_date-to-iso-string.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_date-to-iso-string.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar getTime = Date.prototype.getTime;\nvar $toISOString = Date.prototype.toISOString;\n\nvar lz = function (num) {\n  return num > 9 ? num : '0' + num;\n};\n\n// PhantomJS / old WebKit has a broken implementations\nmodule.exports = (fails(function () {\n  return $toISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z';\n}) || !fails(function () {\n  $toISOString.call(new Date(NaN));\n})) ? function toISOString() {\n  if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value');\n  var d = this;\n  var y = d.getUTCFullYear();\n  var m = d.getUTCMilliseconds();\n  var s = y < 0 ? '-' : y > 9999 ? '+' : '';\n  return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +\n    '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +\n    'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +\n    ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';\n} : $toISOString;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_date-to-primitive.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_date-to-primitive.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar NUMBER = 'number';\n\nmodule.exports = function (hint) {\n  if (hint !== 'string' && hint !== NUMBER && hint !== 'default') throw TypeError('Incorrect hint');\n  return toPrimitive(anObject(this), hint != NUMBER);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_defined.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_defined.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n  if (it == undefined) throw TypeError(\"Can't call method on  \" + it);\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_descriptors.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_descriptors.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// Thank's IE8 for his funny defineProperty\nmodule.exports = !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_dom-create.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_dom-create.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n  return is ? document.createElement(it) : {};\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_enum-bug-keys.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_enum-bug-keys.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// IE 8- don't enum bug keys\nmodule.exports = (\n  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_enum-keys.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_enum-keys.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// all enumerable object keys, includes symbols\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nmodule.exports = function (it) {\n  var result = getKeys(it);\n  var getSymbols = gOPS.f;\n  if (getSymbols) {\n    var symbols = getSymbols(it);\n    var isEnum = pIE.f;\n    var i = 0;\n    var key;\n    while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key);\n  } return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_export.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_export.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n  var IS_FORCED = type & $export.F;\n  var IS_GLOBAL = type & $export.G;\n  var IS_STATIC = type & $export.S;\n  var IS_PROTO = type & $export.P;\n  var IS_BIND = type & $export.B;\n  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n  var key, own, out, exp;\n  if (IS_GLOBAL) source = name;\n  for (key in source) {\n    // contains in native\n    own = !IS_FORCED && target && target[key] !== undefined;\n    // export native or passed\n    out = (own ? target : source)[key];\n    // bind timers to global for call from export context\n    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n    // extend global\n    if (target) redefine(target, key, out, type & $export.U);\n    // export\n    if (exports[key] != out) hide(exports, key, exp);\n    if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n  }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1;   // forced\n$export.G = 2;   // global\n$export.S = 4;   // static\n$export.P = 8;   // proto\n$export.B = 16;  // bind\n$export.W = 32;  // wrap\n$export.U = 64;  // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fails-is-regexp.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fails-is-regexp.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar MATCH = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('match');\nmodule.exports = function (KEY) {\n  var re = /./;\n  try {\n    '/./'[KEY](re);\n  } catch (e) {\n    try {\n      re[MATCH] = false;\n      return !'/./'[KEY](re);\n    } catch (f) { /* empty */ }\n  } return true;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fails.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fails.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return !!exec();\n  } catch (e) {\n    return true;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_fix-re-wks.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_fix-re-wks.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n__webpack_require__(/*! ./es6.regexp.exec */ \"./node_modules/core-js/modules/es6.regexp.exec.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar regexpExec = __webpack_require__(/*! ./_regexp-exec */ \"./node_modules/core-js/modules/_regexp-exec.js\");\n\nvar SPECIES = wks('species');\n\nvar REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {\n  // #replace needs built-in support for named groups.\n  // #match works fine because it just return the exec results, even if it has\n  // a \"grops\" property.\n  var re = /./;\n  re.exec = function () {\n    var result = [];\n    result.groups = { a: '7' };\n    return result;\n  };\n  return ''.replace(re, '$<a>') !== '7';\n});\n\nvar SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () {\n  // Chrome 51 has a buggy \"split\" implementation when RegExp#exec !== nativeExec\n  var re = /(?:)/;\n  var originalExec = re.exec;\n  re.exec = function () { return originalExec.apply(this, arguments); };\n  var result = 'ab'.split(re);\n  return result.length === 2 && result[0] === 'a' && result[1] === 'b';\n})();\n\nmodule.exports = function (KEY, length, exec) {\n  var SYMBOL = wks(KEY);\n\n  var DELEGATES_TO_SYMBOL = !fails(function () {\n    // String methods call symbol-named RegEp methods\n    var O = {};\n    O[SYMBOL] = function () { return 7; };\n    return ''[KEY](O) != 7;\n  });\n\n  var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !fails(function () {\n    // Symbol-named RegExp methods call .exec\n    var execCalled = false;\n    var re = /a/;\n    re.exec = function () { execCalled = true; return null; };\n    if (KEY === 'split') {\n      // RegExp[@@split] doesn't call the regex's exec method, but first creates\n      // a new one. We need to return the patched regex when creating the new one.\n      re.constructor = {};\n      re.constructor[SPECIES] = function () { return re; };\n    }\n    re[SYMBOL]('');\n    return !execCalled;\n  }) : undefined;\n\n  if (\n    !DELEGATES_TO_SYMBOL ||\n    !DELEGATES_TO_EXEC ||\n    (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||\n    (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)\n  ) {\n    var nativeRegExpMethod = /./[SYMBOL];\n    var fns = exec(\n      defined,\n      SYMBOL,\n      ''[KEY],\n      function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {\n        if (regexp.exec === regexpExec) {\n          if (DELEGATES_TO_SYMBOL && !forceStringMethod) {\n            // The native String method already delegates to @@method (this\n            // polyfilled function), leasing to infinite recursion.\n            // We avoid it by directly calling the native @@method method.\n            return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };\n          }\n          return { done: true, value: nativeMethod.call(str, regexp, arg2) };\n        }\n        return { done: false };\n      }\n    );\n    var strfn = fns[0];\n    var rxfn = fns[1];\n\n    redefine(String.prototype, KEY, strfn);\n    hide(RegExp.prototype, SYMBOL, length == 2\n      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n      // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n      ? function (string, arg) { return rxfn.call(string, this, arg); }\n      // 21.2.5.6 RegExp.prototype[@@match](string)\n      // 21.2.5.9 RegExp.prototype[@@search](string)\n      : function (string) { return rxfn.call(string, this); }\n    );\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_flags.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_flags.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 21.2.5.3 get RegExp.prototype.flags\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nmodule.exports = function () {\n  var that = anObject(this);\n  var result = '';\n  if (that.global) result += 'g';\n  if (that.ignoreCase) result += 'i';\n  if (that.multiline) result += 'm';\n  if (that.unicode) result += 'u';\n  if (that.sticky) result += 'y';\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_flatten-into-array.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_flatten-into-array.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar IS_CONCAT_SPREADABLE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('isConcatSpreadable');\n\nfunction flattenIntoArray(target, original, source, sourceLen, start, depth, mapper, thisArg) {\n  var targetIndex = start;\n  var sourceIndex = 0;\n  var mapFn = mapper ? ctx(mapper, thisArg, 3) : false;\n  var element, spreadable;\n\n  while (sourceIndex < sourceLen) {\n    if (sourceIndex in source) {\n      element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];\n\n      spreadable = false;\n      if (isObject(element)) {\n        spreadable = element[IS_CONCAT_SPREADABLE];\n        spreadable = spreadable !== undefined ? !!spreadable : isArray(element);\n      }\n\n      if (spreadable && depth > 0) {\n        targetIndex = flattenIntoArray(target, original, element, toLength(element.length), targetIndex, depth - 1) - 1;\n      } else {\n        if (targetIndex >= 0x1fffffffffffff) throw TypeError();\n        target[targetIndex] = element;\n      }\n\n      targetIndex++;\n    }\n    sourceIndex++;\n  }\n  return targetIndex;\n}\n\nmodule.exports = flattenIntoArray;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_for-of.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_for-of.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar call = __webpack_require__(/*! ./_iter-call */ \"./node_modules/core-js/modules/_iter-call.js\");\nvar isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\nvar BREAK = {};\nvar RETURN = {};\nvar exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {\n  var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);\n  var f = ctx(fn, that, entries ? 2 : 1);\n  var index = 0;\n  var length, step, iterator, result;\n  if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');\n  // fast case for arrays with default iterator\n  if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {\n    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n    if (result === BREAK || result === RETURN) return result;\n  } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {\n    result = call(iterator, f, step.value, entries);\n    if (result === BREAK || result === RETURN) return result;\n  }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_function-to-string.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_function-to-string.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('native-function-to-string', Function.toString);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_global.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_global.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n  ? window : typeof self != 'undefined' && self.Math == Math ? self\n  // eslint-disable-next-line no-new-func\n  : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_has.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_has.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n  return hasOwnProperty.call(it, key);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_hide.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_hide.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? function (object, key, value) {\n  return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n  object[key] = value;\n  return object;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_html.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_html.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar document = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").document;\nmodule.exports = document && document.documentElement;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_ie8-dom-define.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_ie8-dom-define.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return Object.defineProperty(__webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_inherit-if-required.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_inherit-if-required.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar setPrototypeOf = __webpack_require__(/*! ./_set-proto */ \"./node_modules/core-js/modules/_set-proto.js\").set;\nmodule.exports = function (that, target, C) {\n  var S = target.constructor;\n  var P;\n  if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {\n    setPrototypeOf(that, P);\n  } return that;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_invoke.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_invoke.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// fast apply, http://jsperf.lnkit.com/fast-apply/5\nmodule.exports = function (fn, args, that) {\n  var un = that === undefined;\n  switch (args.length) {\n    case 0: return un ? fn()\n                      : fn.call(that);\n    case 1: return un ? fn(args[0])\n                      : fn.call(that, args[0]);\n    case 2: return un ? fn(args[0], args[1])\n                      : fn.call(that, args[0], args[1]);\n    case 3: return un ? fn(args[0], args[1], args[2])\n                      : fn.call(that, args[0], args[1], args[2]);\n    case 4: return un ? fn(args[0], args[1], args[2], args[3])\n                      : fn.call(that, args[0], args[1], args[2], args[3]);\n  } return fn.apply(that, args);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iobject.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iobject.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n  return cof(it) == 'String' ? it.split('') : Object(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array-iter.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array-iter.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// check on default Array iterator\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar ArrayProto = Array.prototype;\n\nmodule.exports = function (it) {\n  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-array.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-array.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.2.2 IsArray(argument)\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nmodule.exports = Array.isArray || function isArray(arg) {\n  return cof(arg) == 'Array';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-integer.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-integer.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.3 Number.isInteger(number)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar floor = Math.floor;\nmodule.exports = function isInteger(it) {\n  return !isObject(it) && isFinite(it) && floor(it) === it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (it) {\n  return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_is-regexp.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_is-regexp.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.2.8 IsRegExp(argument)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar MATCH = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('match');\nmodule.exports = function (it) {\n  var isRegExp;\n  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-call.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-call.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// call something on iterator step with safe closing on error\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nmodule.exports = function (iterator, fn, value, entries) {\n  try {\n    return entries ? fn(anObject(value)[0], value[1]) : fn(value);\n  // 7.4.6 IteratorClose(iterator, completion)\n  } catch (e) {\n    var ret = iterator['return'];\n    if (ret !== undefined) anObject(ret.call(iterator));\n    throw e;\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-create.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-create.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar descriptor = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\n__webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(IteratorPrototype, __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n  Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n  setToStringTag(Constructor, NAME + ' Iterator');\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-define.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-define.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar $iterCreate = __webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n  $iterCreate(Constructor, NAME, next);\n  var getMethod = function (kind) {\n    if (!BUGGY && kind in proto) return proto[kind];\n    switch (kind) {\n      case KEYS: return function keys() { return new Constructor(this, kind); };\n      case VALUES: return function values() { return new Constructor(this, kind); };\n    } return function entries() { return new Constructor(this, kind); };\n  };\n  var TAG = NAME + ' Iterator';\n  var DEF_VALUES = DEFAULT == VALUES;\n  var VALUES_BUG = false;\n  var proto = Base.prototype;\n  var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n  var $default = $native || getMethod(DEFAULT);\n  var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n  var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n  var methods, key, IteratorPrototype;\n  // Fix native\n  if ($anyNative) {\n    IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n    if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n      // Set @@toStringTag to native iterators\n      setToStringTag(IteratorPrototype, TAG, true);\n      // fix for some old engines\n      if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n    }\n  }\n  // fix Array#{values, @@iterator}.name in V8 / FF\n  if (DEF_VALUES && $native && $native.name !== VALUES) {\n    VALUES_BUG = true;\n    $default = function values() { return $native.call(this); };\n  }\n  // Define iterator\n  if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n    hide(proto, ITERATOR, $default);\n  }\n  // Plug for library\n  Iterators[NAME] = $default;\n  Iterators[TAG] = returnThis;\n  if (DEFAULT) {\n    methods = {\n      values: DEF_VALUES ? $default : getMethod(VALUES),\n      keys: IS_SET ? $default : getMethod(KEYS),\n      entries: $entries\n    };\n    if (FORCED) for (key in methods) {\n      if (!(key in proto)) redefine(proto, key, methods[key]);\n    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n  }\n  return methods;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-detect.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-detect.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar SAFE_CLOSING = false;\n\ntry {\n  var riter = [7][ITERATOR]();\n  riter['return'] = function () { SAFE_CLOSING = true; };\n  // eslint-disable-next-line no-throw-literal\n  Array.from(riter, function () { throw 2; });\n} catch (e) { /* empty */ }\n\nmodule.exports = function (exec, skipClosing) {\n  if (!skipClosing && !SAFE_CLOSING) return false;\n  var safe = false;\n  try {\n    var arr = [7];\n    var iter = arr[ITERATOR]();\n    iter.next = function () { return { done: safe = true }; };\n    arr[ITERATOR] = function () { return iter; };\n    exec(arr);\n  } catch (e) { /* empty */ }\n  return safe;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iter-step.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iter-step.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (done, value) {\n  return { value: value, done: !!done };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_iterators.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_iterators.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = {};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_library.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_library.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = false;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-expm1.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-expm1.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 20.2.2.14 Math.expm1(x)\nvar $expm1 = Math.expm1;\nmodule.exports = (!$expm1\n  // Old FF bug\n  || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168\n  // Tor Browser bug\n  || $expm1(-2e-17) != -2e-17\n) ? function expm1(x) {\n  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;\n} : $expm1;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-fround.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-fround.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.16 Math.fround(x)\nvar sign = __webpack_require__(/*! ./_math-sign */ \"./node_modules/core-js/modules/_math-sign.js\");\nvar pow = Math.pow;\nvar EPSILON = pow(2, -52);\nvar EPSILON32 = pow(2, -23);\nvar MAX32 = pow(2, 127) * (2 - EPSILON32);\nvar MIN32 = pow(2, -126);\n\nvar roundTiesToEven = function (n) {\n  return n + 1 / EPSILON - 1 / EPSILON;\n};\n\nmodule.exports = Math.fround || function fround(x) {\n  var $abs = Math.abs(x);\n  var $sign = sign(x);\n  var a, result;\n  if ($abs < MIN32) return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;\n  a = (1 + EPSILON32 / EPSILON) * $abs;\n  result = a - (a - $abs);\n  // eslint-disable-next-line no-self-compare\n  if (result > MAX32 || result != result) return $sign * Infinity;\n  return $sign * result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-log1p.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-log1p.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 20.2.2.20 Math.log1p(x)\nmodule.exports = Math.log1p || function log1p(x) {\n  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-scale.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-scale.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nmodule.exports = Math.scale || function scale(x, inLow, inHigh, outLow, outHigh) {\n  if (\n    arguments.length === 0\n      // eslint-disable-next-line no-self-compare\n      || x != x\n      // eslint-disable-next-line no-self-compare\n      || inLow != inLow\n      // eslint-disable-next-line no-self-compare\n      || inHigh != inHigh\n      // eslint-disable-next-line no-self-compare\n      || outLow != outLow\n      // eslint-disable-next-line no-self-compare\n      || outHigh != outHigh\n  ) return NaN;\n  if (x === Infinity || x === -Infinity) return x;\n  return (x - inLow) * (outHigh - outLow) / (inHigh - inLow) + outLow;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_math-sign.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_math-sign.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 20.2.2.28 Math.sign(x)\nmodule.exports = Math.sign || function sign(x) {\n  // eslint-disable-next-line no-self-compare\n  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_meta.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_meta.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar META = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\")('meta');\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar setDesc = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar id = 0;\nvar isExtensible = Object.isExtensible || function () {\n  return true;\n};\nvar FREEZE = !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function (it) {\n  setDesc(it, META, { value: {\n    i: 'O' + ++id, // object ID\n    w: {}          // weak collections IDs\n  } });\n};\nvar fastKey = function (it, create) {\n  // return primitive with prefix\n  if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n  if (!has(it, META)) {\n    // can't set metadata to uncaught frozen object\n    if (!isExtensible(it)) return 'F';\n    // not necessary to add metadata\n    if (!create) return 'E';\n    // add missing metadata\n    setMeta(it);\n  // return object ID\n  } return it[META].i;\n};\nvar getWeak = function (it, create) {\n  if (!has(it, META)) {\n    // can't set metadata to uncaught frozen object\n    if (!isExtensible(it)) return true;\n    // not necessary to add metadata\n    if (!create) return false;\n    // add missing metadata\n    setMeta(it);\n  // return hash weak collections IDs\n  } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function (it) {\n  if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);\n  return it;\n};\nvar meta = module.exports = {\n  KEY: META,\n  NEED: false,\n  fastKey: fastKey,\n  getWeak: getWeak,\n  onFreeze: onFreeze\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_metadata.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_metadata.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Map = __webpack_require__(/*! ./es6.map */ \"./node_modules/core-js/modules/es6.map.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('metadata');\nvar store = shared.store || (shared.store = new (__webpack_require__(/*! ./es6.weak-map */ \"./node_modules/core-js/modules/es6.weak-map.js\"))());\n\nvar getOrCreateMetadataMap = function (target, targetKey, create) {\n  var targetMetadata = store.get(target);\n  if (!targetMetadata) {\n    if (!create) return undefined;\n    store.set(target, targetMetadata = new Map());\n  }\n  var keyMetadata = targetMetadata.get(targetKey);\n  if (!keyMetadata) {\n    if (!create) return undefined;\n    targetMetadata.set(targetKey, keyMetadata = new Map());\n  } return keyMetadata;\n};\nvar ordinaryHasOwnMetadata = function (MetadataKey, O, P) {\n  var metadataMap = getOrCreateMetadataMap(O, P, false);\n  return metadataMap === undefined ? false : metadataMap.has(MetadataKey);\n};\nvar ordinaryGetOwnMetadata = function (MetadataKey, O, P) {\n  var metadataMap = getOrCreateMetadataMap(O, P, false);\n  return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey);\n};\nvar ordinaryDefineOwnMetadata = function (MetadataKey, MetadataValue, O, P) {\n  getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue);\n};\nvar ordinaryOwnMetadataKeys = function (target, targetKey) {\n  var metadataMap = getOrCreateMetadataMap(target, targetKey, false);\n  var keys = [];\n  if (metadataMap) metadataMap.forEach(function (_, key) { keys.push(key); });\n  return keys;\n};\nvar toMetaKey = function (it) {\n  return it === undefined || typeof it == 'symbol' ? it : String(it);\n};\nvar exp = function (O) {\n  $export($export.S, 'Reflect', O);\n};\n\nmodule.exports = {\n  store: store,\n  map: getOrCreateMetadataMap,\n  has: ordinaryHasOwnMetadata,\n  get: ordinaryGetOwnMetadata,\n  set: ordinaryDefineOwnMetadata,\n  keys: ordinaryOwnMetadataKeys,\n  key: toMetaKey,\n  exp: exp\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_microtask.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_microtask.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar macrotask = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar Observer = global.MutationObserver || global.WebKitMutationObserver;\nvar process = global.process;\nvar Promise = global.Promise;\nvar isNode = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process';\n\nmodule.exports = function () {\n  var head, last, notify;\n\n  var flush = function () {\n    var parent, fn;\n    if (isNode && (parent = process.domain)) parent.exit();\n    while (head) {\n      fn = head.fn;\n      head = head.next;\n      try {\n        fn();\n      } catch (e) {\n        if (head) notify();\n        else last = undefined;\n        throw e;\n      }\n    } last = undefined;\n    if (parent) parent.enter();\n  };\n\n  // Node.js\n  if (isNode) {\n    notify = function () {\n      process.nextTick(flush);\n    };\n  // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339\n  } else if (Observer && !(global.navigator && global.navigator.standalone)) {\n    var toggle = true;\n    var node = document.createTextNode('');\n    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new\n    notify = function () {\n      node.data = toggle = !toggle;\n    };\n  // environments with maybe non-completely correct, but existent Promise\n  } else if (Promise && Promise.resolve) {\n    // Promise.resolve without an argument throws an error in LG WebOS 2\n    var promise = Promise.resolve(undefined);\n    notify = function () {\n      promise.then(flush);\n    };\n  // for other environments - macrotask based on:\n  // - setImmediate\n  // - MessageChannel\n  // - window.postMessag\n  // - onreadystatechange\n  // - setTimeout\n  } else {\n    notify = function () {\n      // strange IE + webpack dev server bug - use .call(global)\n      macrotask.call(global, flush);\n    };\n  }\n\n  return function (fn) {\n    var task = { fn: fn, next: undefined };\n    if (last) last.next = task;\n    if (!head) {\n      head = task;\n      notify();\n    } last = task;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_new-promise-capability.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_new-promise-capability.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 25.4.1.5 NewPromiseCapability(C)\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\n\nfunction PromiseCapability(C) {\n  var resolve, reject;\n  this.promise = new C(function ($$resolve, $$reject) {\n    if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');\n    resolve = $$resolve;\n    reject = $$reject;\n  });\n  this.resolve = aFunction(resolve);\n  this.reject = aFunction(reject);\n}\n\nmodule.exports.f = function (C) {\n  return new PromiseCapability(C);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-assign.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-assign.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.2.1 Object.assign(target, source, ...)\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar $assign = Object.assign;\n\n// should work with symbols and should have deterministic property order (V8 bug)\nmodule.exports = !$assign || __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  var A = {};\n  var B = {};\n  // eslint-disable-next-line no-undef\n  var S = Symbol();\n  var K = 'abcdefghijklmnopqrst';\n  A[S] = 7;\n  K.split('').forEach(function (k) { B[k] = k; });\n  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;\n}) ? function assign(target, source) { // eslint-disable-line no-unused-vars\n  var T = toObject(target);\n  var aLen = arguments.length;\n  var index = 1;\n  var getSymbols = gOPS.f;\n  var isEnum = pIE.f;\n  while (aLen > index) {\n    var S = IObject(arguments[index++]);\n    var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);\n    var length = keys.length;\n    var j = 0;\n    var key;\n    while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];\n  } return T;\n} : $assign;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-create.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-create.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar dPs = __webpack_require__(/*! ./_object-dps */ \"./node_modules/core-js/modules/_object-dps.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n  // Thrash, waste and sodomy: IE GC bug\n  var iframe = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\")('iframe');\n  var i = enumBugKeys.length;\n  var lt = '<';\n  var gt = '>';\n  var iframeDocument;\n  iframe.style.display = 'none';\n  __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\").appendChild(iframe);\n  iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n  // createDict = iframe.contentWindow.Object;\n  // html.removeChild(iframe);\n  iframeDocument = iframe.contentWindow.document;\n  iframeDocument.open();\n  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n  iframeDocument.close();\n  createDict = iframeDocument.F;\n  while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n  return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n  var result;\n  if (O !== null) {\n    Empty[PROTOTYPE] = anObject(O);\n    result = new Empty();\n    Empty[PROTOTYPE] = null;\n    // add \"__proto__\" for Object.getPrototypeOf polyfill\n    result[IE_PROTO] = O;\n  } else result = createDict();\n  return Properties === undefined ? result : dPs(result, Properties);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dp.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dp.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ \"./node_modules/core-js/modules/_ie8-dom-define.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar dP = Object.defineProperty;\n\nexports.f = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n  anObject(O);\n  P = toPrimitive(P, true);\n  anObject(Attributes);\n  if (IE8_DOM_DEFINE) try {\n    return dP(O, P, Attributes);\n  } catch (e) { /* empty */ }\n  if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n  if ('value' in Attributes) O[P] = Attributes.value;\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-dps.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-dps.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\n\nmodule.exports = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? Object.defineProperties : function defineProperties(O, Properties) {\n  anObject(O);\n  var keys = getKeys(Properties);\n  var length = keys.length;\n  var i = 0;\n  var P;\n  while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n  return O;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-forced-pam.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-forced-pam.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// Forced replacement prototype accessors methods\nmodule.exports = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\") || !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  var K = Math.random();\n  // In FF throws only define methods\n  // eslint-disable-next-line no-undef, no-useless-call\n  __defineSetter__.call(null, K, function () { /* empty */ });\n  delete __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\")[K];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gopd.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gopd.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar pIE = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar IE8_DOM_DEFINE = __webpack_require__(/*! ./_ie8-dom-define */ \"./node_modules/core-js/modules/_ie8-dom-define.js\");\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? gOPD : function getOwnPropertyDescriptor(O, P) {\n  O = toIObject(O);\n  P = toPrimitive(P, true);\n  if (IE8_DOM_DEFINE) try {\n    return gOPD(O, P);\n  } catch (e) { /* empty */ }\n  if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gopn-ext.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gopn-ext.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar toString = {}.toString;\n\nvar windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames\n  ? Object.getOwnPropertyNames(window) : [];\n\nvar getWindowNames = function (it) {\n  try {\n    return gOPN(it);\n  } catch (e) {\n    return windowNames.slice();\n  }\n};\n\nmodule.exports.f = function getOwnPropertyNames(it) {\n  return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gopn.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gopn.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)\nvar $keys = __webpack_require__(/*! ./_object-keys-internal */ \"./node_modules/core-js/modules/_object-keys-internal.js\");\nvar hiddenKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\").concat('length', 'prototype');\n\nexports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {\n  return $keys(O, hiddenKeys);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gops.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gops.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = Object.getOwnPropertySymbols;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-gpo.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-gpo.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n  O = toObject(O);\n  if (has(O, IE_PROTO)) return O[IE_PROTO];\n  if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n    return O.constructor.prototype;\n  } return O instanceof Object ? ObjectProto : null;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys-internal.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys-internal.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar arrayIndexOf = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(false);\nvar IE_PROTO = __webpack_require__(/*! ./_shared-key */ \"./node_modules/core-js/modules/_shared-key.js\")('IE_PROTO');\n\nmodule.exports = function (object, names) {\n  var O = toIObject(object);\n  var i = 0;\n  var result = [];\n  var key;\n  for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n  // Don't enum bug & hidden keys\n  while (names.length > i) if (has(O, key = names[i++])) {\n    ~arrayIndexOf(result, key) || result.push(key);\n  }\n  return result;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-keys.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-keys.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = __webpack_require__(/*! ./_object-keys-internal */ \"./node_modules/core-js/modules/_object-keys-internal.js\");\nvar enumBugKeys = __webpack_require__(/*! ./_enum-bug-keys */ \"./node_modules/core-js/modules/_enum-bug-keys.js\");\n\nmodule.exports = Object.keys || function keys(O) {\n  return $keys(O, enumBugKeys);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-pie.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-pie.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.f = {}.propertyIsEnumerable;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-sap.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-sap.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// most Object methods by ES6 should accept primitives\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nmodule.exports = function (KEY, exec) {\n  var fn = (core.Object || {})[KEY] || Object[KEY];\n  var exp = {};\n  exp[KEY] = exec(fn);\n  $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_object-to-array.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_object-to-array.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar isEnum = __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\").f;\nmodule.exports = function (isEntries) {\n  return function (it) {\n    var O = toIObject(it);\n    var keys = getKeys(O);\n    var length = keys.length;\n    var i = 0;\n    var result = [];\n    var key;\n    while (length > i) if (isEnum.call(O, key = keys[i++])) {\n      result.push(isEntries ? [key, O[key]] : O[key]);\n    } return result;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_own-keys.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_own-keys.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// all object keys, includes non-enumerable and symbols\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\");\nvar gOPS = __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar Reflect = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Reflect;\nmodule.exports = Reflect && Reflect.ownKeys || function ownKeys(it) {\n  var keys = gOPN.f(anObject(it));\n  var getSymbols = gOPS.f;\n  return getSymbols ? keys.concat(getSymbols(it)) : keys;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_parse-float.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_parse-float.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $parseFloat = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").parseFloat;\nvar $trim = __webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\").trim;\n\nmodule.exports = 1 / $parseFloat(__webpack_require__(/*! ./_string-ws */ \"./node_modules/core-js/modules/_string-ws.js\") + '-0') !== -Infinity ? function parseFloat(str) {\n  var string = $trim(String(str), 3);\n  var result = $parseFloat(string);\n  return result === 0 && string.charAt(0) == '-' ? -0 : result;\n} : $parseFloat;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_parse-int.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_parse-int.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $parseInt = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").parseInt;\nvar $trim = __webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\").trim;\nvar ws = __webpack_require__(/*! ./_string-ws */ \"./node_modules/core-js/modules/_string-ws.js\");\nvar hex = /^[-+]?0[xX]/;\n\nmodule.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix) {\n  var string = $trim(String(str), 3);\n  return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));\n} : $parseInt;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_perform.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_perform.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (exec) {\n  try {\n    return { e: false, v: exec() };\n  } catch (e) {\n    return { e: true, v: e };\n  }\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_promise-resolve.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_promise-resolve.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar newPromiseCapability = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\n\nmodule.exports = function (C, x) {\n  anObject(C);\n  if (isObject(x) && x.constructor === C) return x;\n  var promiseCapability = newPromiseCapability.f(C);\n  var resolve = promiseCapability.resolve;\n  resolve(x);\n  return promiseCapability.promise;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_property-desc.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_property-desc.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (bitmap, value) {\n  return {\n    enumerable: !(bitmap & 1),\n    configurable: !(bitmap & 2),\n    writable: !(bitmap & 4),\n    value: value\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine-all.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine-all.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nmodule.exports = function (target, src, safe) {\n  for (var key in src) redefine(target, key, src[key], safe);\n  return target;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_redefine.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_redefine.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar SRC = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\")('src');\nvar $toString = __webpack_require__(/*! ./_function-to-string */ \"./node_modules/core-js/modules/_function-to-string.js\");\nvar TO_STRING = 'toString';\nvar TPL = ('' + $toString).split(TO_STRING);\n\n__webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").inspectSource = function (it) {\n  return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n  var isFunction = typeof val == 'function';\n  if (isFunction) has(val, 'name') || hide(val, 'name', key);\n  if (O[key] === val) return;\n  if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n  if (O === global) {\n    O[key] = val;\n  } else if (!safe) {\n    delete O[key];\n    hide(O, key, val);\n  } else if (O[key]) {\n    O[key] = val;\n  } else {\n    hide(O, key, val);\n  }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n  return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_regexp-exec-abstract.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar builtinExec = RegExp.prototype.exec;\n\n // `RegExpExec` abstract operation\n// https://tc39.github.io/ecma262/#sec-regexpexec\nmodule.exports = function (R, S) {\n  var exec = R.exec;\n  if (typeof exec === 'function') {\n    var result = exec.call(R, S);\n    if (typeof result !== 'object') {\n      throw new TypeError('RegExp exec method returned something other than an Object or null');\n    }\n    return result;\n  }\n  if (classof(R) !== 'RegExp') {\n    throw new TypeError('RegExp#exec called on incompatible receiver');\n  }\n  return builtinExec.call(R, S);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_regexp-exec.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_regexp-exec.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar regexpFlags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\n\nvar nativeExec = RegExp.prototype.exec;\n// This always refers to the native implementation, because the\n// String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,\n// which loads this file before patching the method.\nvar nativeReplace = String.prototype.replace;\n\nvar patchedExec = nativeExec;\n\nvar LAST_INDEX = 'lastIndex';\n\nvar UPDATES_LAST_INDEX_WRONG = (function () {\n  var re1 = /a/,\n      re2 = /b*/g;\n  nativeExec.call(re1, 'a');\n  nativeExec.call(re2, 'a');\n  return re1[LAST_INDEX] !== 0 || re2[LAST_INDEX] !== 0;\n})();\n\n// nonparticipating capturing group, copied from es5-shim's String#split patch.\nvar NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;\n\nvar PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;\n\nif (PATCH) {\n  patchedExec = function exec(str) {\n    var re = this;\n    var lastIndex, reCopy, match, i;\n\n    if (NPCG_INCLUDED) {\n      reCopy = new RegExp('^' + re.source + '$(?!\\\\s)', regexpFlags.call(re));\n    }\n    if (UPDATES_LAST_INDEX_WRONG) lastIndex = re[LAST_INDEX];\n\n    match = nativeExec.call(re, str);\n\n    if (UPDATES_LAST_INDEX_WRONG && match) {\n      re[LAST_INDEX] = re.global ? match.index + match[0].length : lastIndex;\n    }\n    if (NPCG_INCLUDED && match && match.length > 1) {\n      // Fix browsers whose `exec` methods don't consistently return `undefined`\n      // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/\n      // eslint-disable-next-line no-loop-func\n      nativeReplace.call(match[0], reCopy, function () {\n        for (i = 1; i < arguments.length - 2; i++) {\n          if (arguments[i] === undefined) match[i] = undefined;\n        }\n      });\n    }\n\n    return match;\n  };\n}\n\nmodule.exports = patchedExec;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_replacer.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_replacer.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = function (regExp, replace) {\n  var replacer = replace === Object(replace) ? function (part) {\n    return replace[part];\n  } : replace;\n  return function (it) {\n    return String(it).replace(regExp, replacer);\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_same-value.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_same-value.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.2.9 SameValue(x, y)\nmodule.exports = Object.is || function is(x, y) {\n  // eslint-disable-next-line no-self-compare\n  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-collection-from.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-collection-from.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-setmap-offrom/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\n\nmodule.exports = function (COLLECTION) {\n  $export($export.S, COLLECTION, { from: function from(source /* , mapFn, thisArg */) {\n    var mapFn = arguments[1];\n    var mapping, A, n, cb;\n    aFunction(this);\n    mapping = mapFn !== undefined;\n    if (mapping) aFunction(mapFn);\n    if (source == undefined) return new this();\n    A = [];\n    if (mapping) {\n      n = 0;\n      cb = ctx(mapFn, arguments[2], 2);\n      forOf(source, false, function (nextItem) {\n        A.push(cb(nextItem, n++));\n      });\n    } else {\n      forOf(source, false, A.push, A);\n    }\n    return new this(A);\n  } });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-collection-of.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-collection-of.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-setmap-offrom/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\nmodule.exports = function (COLLECTION) {\n  $export($export.S, COLLECTION, { of: function of() {\n    var length = arguments.length;\n    var A = new Array(length);\n    while (length--) A[length] = arguments[length];\n    return new this(A);\n  } });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-proto.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-proto.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// Works with __proto__ only. Old v8 can't work with null proto objects.\n/* eslint-disable no-proto */\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar check = function (O, proto) {\n  anObject(O);\n  if (!isObject(proto) && proto !== null) throw TypeError(proto + \": can't set as prototype!\");\n};\nmodule.exports = {\n  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line\n    function (test, buggy, set) {\n      try {\n        set = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\")(Function.call, __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f(Object.prototype, '__proto__').set, 2);\n        set(test, []);\n        buggy = !(test instanceof Array);\n      } catch (e) { buggy = true; }\n      return function setPrototypeOf(O, proto) {\n        check(O, proto);\n        if (buggy) O.__proto__ = proto;\n        else set(O, proto);\n        return O;\n      };\n    }({}, false) : undefined),\n  check: check\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-species.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-species.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\n\nmodule.exports = function (KEY) {\n  var C = global[KEY];\n  if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {\n    configurable: true,\n    get: function () { return this; }\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_set-to-string-tag.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_set-to-string-tag.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar def = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar TAG = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n  if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared-key.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared-key.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('keys');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nmodule.exports = function (key) {\n  return shared[key] || (shared[key] = uid(key));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_shared.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/_shared.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n  return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n  version: core.version,\n  mode: __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\") ? 'pure' : 'global',\n  copyright: '© 2019 Denis Pushkarev (zloirock.ru)'\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_species-constructor.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_species-constructor.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.3.20 SpeciesConstructor(O, defaultConstructor)\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar SPECIES = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species');\nmodule.exports = function (O, D) {\n  var C = anObject(O).constructor;\n  var S;\n  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_strict-method.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_strict-method.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\n\nmodule.exports = function (method, arg) {\n  return !!method && fails(function () {\n    // eslint-disable-next-line no-useless-call\n    arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);\n  });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-at.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-at.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n// true  -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n  return function (that, pos) {\n    var s = String(defined(that));\n    var i = toInteger(pos);\n    var l = s.length;\n    var a, b;\n    if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n    a = s.charCodeAt(i);\n    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n      ? TO_STRING ? s.charAt(i) : a\n      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n  };\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-context.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-context.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// helper for String#{startsWith, endsWith, includes}\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n\nmodule.exports = function (that, searchString, NAME) {\n  if (isRegExp(searchString)) throw TypeError('String#' + NAME + \" doesn't accept regex!\");\n  return String(defined(that));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-html.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-html.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar quot = /\"/g;\n// B.2.3.2.1 CreateHTML(string, tag, attribute, value)\nvar createHTML = function (string, tag, attribute, value) {\n  var S = String(defined(string));\n  var p1 = '<' + tag;\n  if (attribute !== '') p1 += ' ' + attribute + '=\"' + String(value).replace(quot, '&quot;') + '\"';\n  return p1 + '>' + S + '</' + tag + '>';\n};\nmodule.exports = function (NAME, exec) {\n  var O = {};\n  O[NAME] = exec(createHTML);\n  $export($export.P + $export.F * fails(function () {\n    var test = ''[NAME]('\"');\n    return test !== test.toLowerCase() || test.split('\"').length > 3;\n  }), 'String', O);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-pad.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-pad.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-string-pad-start-end\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar repeat = __webpack_require__(/*! ./_string-repeat */ \"./node_modules/core-js/modules/_string-repeat.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n\nmodule.exports = function (that, maxLength, fillString, left) {\n  var S = String(defined(that));\n  var stringLength = S.length;\n  var fillStr = fillString === undefined ? ' ' : String(fillString);\n  var intMaxLength = toLength(maxLength);\n  if (intMaxLength <= stringLength || fillStr == '') return S;\n  var fillLen = intMaxLength - stringLength;\n  var stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));\n  if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);\n  return left ? stringFiller + S : S + stringFiller;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-repeat.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-repeat.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\n\nmodule.exports = function repeat(count) {\n  var str = String(defined(this));\n  var res = '';\n  var n = toInteger(count);\n  if (n < 0 || n == Infinity) throw RangeError(\"Count can't be negative\");\n  for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str;\n  return res;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-trim.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-trim.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar spaces = __webpack_require__(/*! ./_string-ws */ \"./node_modules/core-js/modules/_string-ws.js\");\nvar space = '[' + spaces + ']';\nvar non = '\\u200b\\u0085';\nvar ltrim = RegExp('^' + space + space + '*');\nvar rtrim = RegExp(space + space + '*$');\n\nvar exporter = function (KEY, exec, ALIAS) {\n  var exp = {};\n  var FORCE = fails(function () {\n    return !!spaces[KEY]() || non[KEY]() != non;\n  });\n  var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];\n  if (ALIAS) exp[ALIAS] = fn;\n  $export($export.P + $export.F * FORCE, 'String', exp);\n};\n\n// 1 -> String#trimLeft\n// 2 -> String#trimRight\n// 3 -> String#trim\nvar trim = exporter.trim = function (string, TYPE) {\n  string = String(defined(string));\n  if (TYPE & 1) string = string.replace(ltrim, '');\n  if (TYPE & 2) string = string.replace(rtrim, '');\n  return string;\n};\n\nmodule.exports = exporter;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_string-ws.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_string-ws.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nmodule.exports = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' +\n  '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_task.js\":\n/*!***********************************************!*\\\n  !*** ./node_modules/core-js/modules/_task.js ***!\n  \\***********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar invoke = __webpack_require__(/*! ./_invoke */ \"./node_modules/core-js/modules/_invoke.js\");\nvar html = __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\");\nvar cel = __webpack_require__(/*! ./_dom-create */ \"./node_modules/core-js/modules/_dom-create.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar process = global.process;\nvar setTask = global.setImmediate;\nvar clearTask = global.clearImmediate;\nvar MessageChannel = global.MessageChannel;\nvar Dispatch = global.Dispatch;\nvar counter = 0;\nvar queue = {};\nvar ONREADYSTATECHANGE = 'onreadystatechange';\nvar defer, channel, port;\nvar run = function () {\n  var id = +this;\n  // eslint-disable-next-line no-prototype-builtins\n  if (queue.hasOwnProperty(id)) {\n    var fn = queue[id];\n    delete queue[id];\n    fn();\n  }\n};\nvar listener = function (event) {\n  run.call(event.data);\n};\n// Node.js 0.9+ & IE10+ has setImmediate, otherwise:\nif (!setTask || !clearTask) {\n  setTask = function setImmediate(fn) {\n    var args = [];\n    var i = 1;\n    while (arguments.length > i) args.push(arguments[i++]);\n    queue[++counter] = function () {\n      // eslint-disable-next-line no-new-func\n      invoke(typeof fn == 'function' ? fn : Function(fn), args);\n    };\n    defer(counter);\n    return counter;\n  };\n  clearTask = function clearImmediate(id) {\n    delete queue[id];\n  };\n  // Node.js 0.8-\n  if (__webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process') {\n    defer = function (id) {\n      process.nextTick(ctx(run, id, 1));\n    };\n  // Sphere (JS game engine) Dispatch API\n  } else if (Dispatch && Dispatch.now) {\n    defer = function (id) {\n      Dispatch.now(ctx(run, id, 1));\n    };\n  // Browsers with MessageChannel, includes WebWorkers\n  } else if (MessageChannel) {\n    channel = new MessageChannel();\n    port = channel.port2;\n    channel.port1.onmessage = listener;\n    defer = ctx(port.postMessage, port, 1);\n  // Browsers with postMessage, skip WebWorkers\n  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'\n  } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {\n    defer = function (id) {\n      global.postMessage(id + '', '*');\n    };\n    global.addEventListener('message', listener, false);\n  // IE8-\n  } else if (ONREADYSTATECHANGE in cel('script')) {\n    defer = function (id) {\n      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {\n        html.removeChild(this);\n        run.call(id);\n      };\n    };\n  // Rest old browsers\n  } else {\n    defer = function (id) {\n      setTimeout(ctx(run, id, 1), 0);\n    };\n  }\n}\nmodule.exports = {\n  set: setTask,\n  clear: clearTask\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-absolute-index.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-absolute-index.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n  index = toInteger(index);\n  return index < 0 ? max(index + length, 0) : min(index, length);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-index.js\":\n/*!***************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-index.js ***!\n  \\***************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/ecma262/#sec-toindex\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nmodule.exports = function (it) {\n  if (it === undefined) return 0;\n  var number = toInteger(it);\n  var length = toLength(number);\n  if (number !== length) throw RangeError('Wrong length!');\n  return length;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-integer.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-integer.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-iobject.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-iobject.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = __webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return IObject(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-length.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-length.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.15 ToLength\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar min = Math.min;\nmodule.exports = function (it) {\n  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-object.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-object.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.13 ToObject(argument)\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nmodule.exports = function (it) {\n  return Object(defined(it));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_to-primitive.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_to-primitive.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n  if (!isObject(it)) return it;\n  var fn, val;\n  if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n  if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n  throw TypeError(\"Can't convert object to primitive value\");\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_typed-array.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_typed-array.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nif (__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\")) {\n  var LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\n  var global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\n  var fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\n  var $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n  var $typed = __webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\");\n  var $buffer = __webpack_require__(/*! ./_typed-buffer */ \"./node_modules/core-js/modules/_typed-buffer.js\");\n  var ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\n  var anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\n  var propertyDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\n  var hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\n  var redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\n  var toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\n  var toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n  var toIndex = __webpack_require__(/*! ./_to-index */ \"./node_modules/core-js/modules/_to-index.js\");\n  var toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\n  var toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\n  var has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\n  var classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\n  var isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n  var toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\n  var isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\n  var create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\n  var getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\n  var gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\n  var getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\n  var uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\n  var wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\n  var createArrayMethod = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\");\n  var createArrayIncludes = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\");\n  var speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\n  var ArrayIterators = __webpack_require__(/*! ./es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\n  var Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\n  var $iterDetect = __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\");\n  var setSpecies = __webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\");\n  var arrayFill = __webpack_require__(/*! ./_array-fill */ \"./node_modules/core-js/modules/_array-fill.js\");\n  var arrayCopyWithin = __webpack_require__(/*! ./_array-copy-within */ \"./node_modules/core-js/modules/_array-copy-within.js\");\n  var $DP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\n  var $GOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\n  var dP = $DP.f;\n  var gOPD = $GOPD.f;\n  var RangeError = global.RangeError;\n  var TypeError = global.TypeError;\n  var Uint8Array = global.Uint8Array;\n  var ARRAY_BUFFER = 'ArrayBuffer';\n  var SHARED_BUFFER = 'Shared' + ARRAY_BUFFER;\n  var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';\n  var PROTOTYPE = 'prototype';\n  var ArrayProto = Array[PROTOTYPE];\n  var $ArrayBuffer = $buffer.ArrayBuffer;\n  var $DataView = $buffer.DataView;\n  var arrayForEach = createArrayMethod(0);\n  var arrayFilter = createArrayMethod(2);\n  var arraySome = createArrayMethod(3);\n  var arrayEvery = createArrayMethod(4);\n  var arrayFind = createArrayMethod(5);\n  var arrayFindIndex = createArrayMethod(6);\n  var arrayIncludes = createArrayIncludes(true);\n  var arrayIndexOf = createArrayIncludes(false);\n  var arrayValues = ArrayIterators.values;\n  var arrayKeys = ArrayIterators.keys;\n  var arrayEntries = ArrayIterators.entries;\n  var arrayLastIndexOf = ArrayProto.lastIndexOf;\n  var arrayReduce = ArrayProto.reduce;\n  var arrayReduceRight = ArrayProto.reduceRight;\n  var arrayJoin = ArrayProto.join;\n  var arraySort = ArrayProto.sort;\n  var arraySlice = ArrayProto.slice;\n  var arrayToString = ArrayProto.toString;\n  var arrayToLocaleString = ArrayProto.toLocaleString;\n  var ITERATOR = wks('iterator');\n  var TAG = wks('toStringTag');\n  var TYPED_CONSTRUCTOR = uid('typed_constructor');\n  var DEF_CONSTRUCTOR = uid('def_constructor');\n  var ALL_CONSTRUCTORS = $typed.CONSTR;\n  var TYPED_ARRAY = $typed.TYPED;\n  var VIEW = $typed.VIEW;\n  var WRONG_LENGTH = 'Wrong length!';\n\n  var $map = createArrayMethod(1, function (O, length) {\n    return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length);\n  });\n\n  var LITTLE_ENDIAN = fails(function () {\n    // eslint-disable-next-line no-undef\n    return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\n  });\n\n  var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function () {\n    new Uint8Array(1).set({});\n  });\n\n  var toOffset = function (it, BYTES) {\n    var offset = toInteger(it);\n    if (offset < 0 || offset % BYTES) throw RangeError('Wrong offset!');\n    return offset;\n  };\n\n  var validate = function (it) {\n    if (isObject(it) && TYPED_ARRAY in it) return it;\n    throw TypeError(it + ' is not a typed array!');\n  };\n\n  var allocate = function (C, length) {\n    if (!(isObject(C) && TYPED_CONSTRUCTOR in C)) {\n      throw TypeError('It is not a typed array constructor!');\n    } return new C(length);\n  };\n\n  var speciesFromList = function (O, list) {\n    return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list);\n  };\n\n  var fromList = function (C, list) {\n    var index = 0;\n    var length = list.length;\n    var result = allocate(C, length);\n    while (length > index) result[index] = list[index++];\n    return result;\n  };\n\n  var addGetter = function (it, key, internal) {\n    dP(it, key, { get: function () { return this._d[internal]; } });\n  };\n\n  var $from = function from(source /* , mapfn, thisArg */) {\n    var O = toObject(source);\n    var aLen = arguments.length;\n    var mapfn = aLen > 1 ? arguments[1] : undefined;\n    var mapping = mapfn !== undefined;\n    var iterFn = getIterFn(O);\n    var i, length, values, result, step, iterator;\n    if (iterFn != undefined && !isArrayIter(iterFn)) {\n      for (iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++) {\n        values.push(step.value);\n      } O = values;\n    }\n    if (mapping && aLen > 2) mapfn = ctx(mapfn, arguments[2], 2);\n    for (i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++) {\n      result[i] = mapping ? mapfn(O[i], i) : O[i];\n    }\n    return result;\n  };\n\n  var $of = function of(/* ...items */) {\n    var index = 0;\n    var length = arguments.length;\n    var result = allocate(this, length);\n    while (length > index) result[index] = arguments[index++];\n    return result;\n  };\n\n  // iOS Safari 6.x fails here\n  var TO_LOCALE_BUG = !!Uint8Array && fails(function () { arrayToLocaleString.call(new Uint8Array(1)); });\n\n  var $toLocaleString = function toLocaleString() {\n    return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments);\n  };\n\n  var proto = {\n    copyWithin: function copyWithin(target, start /* , end */) {\n      return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined);\n    },\n    every: function every(callbackfn /* , thisArg */) {\n      return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    fill: function fill(value /* , start, end */) { // eslint-disable-line no-unused-vars\n      return arrayFill.apply(validate(this), arguments);\n    },\n    filter: function filter(callbackfn /* , thisArg */) {\n      return speciesFromList(this, arrayFilter(validate(this), callbackfn,\n        arguments.length > 1 ? arguments[1] : undefined));\n    },\n    find: function find(predicate /* , thisArg */) {\n      return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    findIndex: function findIndex(predicate /* , thisArg */) {\n      return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    forEach: function forEach(callbackfn /* , thisArg */) {\n      arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    indexOf: function indexOf(searchElement /* , fromIndex */) {\n      return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    includes: function includes(searchElement /* , fromIndex */) {\n      return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    join: function join(separator) { // eslint-disable-line no-unused-vars\n      return arrayJoin.apply(validate(this), arguments);\n    },\n    lastIndexOf: function lastIndexOf(searchElement /* , fromIndex */) { // eslint-disable-line no-unused-vars\n      return arrayLastIndexOf.apply(validate(this), arguments);\n    },\n    map: function map(mapfn /* , thisArg */) {\n      return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    reduce: function reduce(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars\n      return arrayReduce.apply(validate(this), arguments);\n    },\n    reduceRight: function reduceRight(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars\n      return arrayReduceRight.apply(validate(this), arguments);\n    },\n    reverse: function reverse() {\n      var that = this;\n      var length = validate(that).length;\n      var middle = Math.floor(length / 2);\n      var index = 0;\n      var value;\n      while (index < middle) {\n        value = that[index];\n        that[index++] = that[--length];\n        that[length] = value;\n      } return that;\n    },\n    some: function some(callbackfn /* , thisArg */) {\n      return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n    },\n    sort: function sort(comparefn) {\n      return arraySort.call(validate(this), comparefn);\n    },\n    subarray: function subarray(begin, end) {\n      var O = validate(this);\n      var length = O.length;\n      var $begin = toAbsoluteIndex(begin, length);\n      return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))(\n        O.buffer,\n        O.byteOffset + $begin * O.BYTES_PER_ELEMENT,\n        toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - $begin)\n      );\n    }\n  };\n\n  var $slice = function slice(start, end) {\n    return speciesFromList(this, arraySlice.call(validate(this), start, end));\n  };\n\n  var $set = function set(arrayLike /* , offset */) {\n    validate(this);\n    var offset = toOffset(arguments[1], 1);\n    var length = this.length;\n    var src = toObject(arrayLike);\n    var len = toLength(src.length);\n    var index = 0;\n    if (len + offset > length) throw RangeError(WRONG_LENGTH);\n    while (index < len) this[offset + index] = src[index++];\n  };\n\n  var $iterators = {\n    entries: function entries() {\n      return arrayEntries.call(validate(this));\n    },\n    keys: function keys() {\n      return arrayKeys.call(validate(this));\n    },\n    values: function values() {\n      return arrayValues.call(validate(this));\n    }\n  };\n\n  var isTAIndex = function (target, key) {\n    return isObject(target)\n      && target[TYPED_ARRAY]\n      && typeof key != 'symbol'\n      && key in target\n      && String(+key) == String(key);\n  };\n  var $getDesc = function getOwnPropertyDescriptor(target, key) {\n    return isTAIndex(target, key = toPrimitive(key, true))\n      ? propertyDesc(2, target[key])\n      : gOPD(target, key);\n  };\n  var $setDesc = function defineProperty(target, key, desc) {\n    if (isTAIndex(target, key = toPrimitive(key, true))\n      && isObject(desc)\n      && has(desc, 'value')\n      && !has(desc, 'get')\n      && !has(desc, 'set')\n      // TODO: add validation descriptor w/o calling accessors\n      && !desc.configurable\n      && (!has(desc, 'writable') || desc.writable)\n      && (!has(desc, 'enumerable') || desc.enumerable)\n    ) {\n      target[key] = desc.value;\n      return target;\n    } return dP(target, key, desc);\n  };\n\n  if (!ALL_CONSTRUCTORS) {\n    $GOPD.f = $getDesc;\n    $DP.f = $setDesc;\n  }\n\n  $export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', {\n    getOwnPropertyDescriptor: $getDesc,\n    defineProperty: $setDesc\n  });\n\n  if (fails(function () { arrayToString.call({}); })) {\n    arrayToString = arrayToLocaleString = function toString() {\n      return arrayJoin.call(this);\n    };\n  }\n\n  var $TypedArrayPrototype$ = redefineAll({}, proto);\n  redefineAll($TypedArrayPrototype$, $iterators);\n  hide($TypedArrayPrototype$, ITERATOR, $iterators.values);\n  redefineAll($TypedArrayPrototype$, {\n    slice: $slice,\n    set: $set,\n    constructor: function () { /* noop */ },\n    toString: arrayToString,\n    toLocaleString: $toLocaleString\n  });\n  addGetter($TypedArrayPrototype$, 'buffer', 'b');\n  addGetter($TypedArrayPrototype$, 'byteOffset', 'o');\n  addGetter($TypedArrayPrototype$, 'byteLength', 'l');\n  addGetter($TypedArrayPrototype$, 'length', 'e');\n  dP($TypedArrayPrototype$, TAG, {\n    get: function () { return this[TYPED_ARRAY]; }\n  });\n\n  // eslint-disable-next-line max-statements\n  module.exports = function (KEY, BYTES, wrapper, CLAMPED) {\n    CLAMPED = !!CLAMPED;\n    var NAME = KEY + (CLAMPED ? 'Clamped' : '') + 'Array';\n    var GETTER = 'get' + KEY;\n    var SETTER = 'set' + KEY;\n    var TypedArray = global[NAME];\n    var Base = TypedArray || {};\n    var TAC = TypedArray && getPrototypeOf(TypedArray);\n    var FORCED = !TypedArray || !$typed.ABV;\n    var O = {};\n    var TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE];\n    var getter = function (that, index) {\n      var data = that._d;\n      return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN);\n    };\n    var setter = function (that, index, value) {\n      var data = that._d;\n      if (CLAMPED) value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff;\n      data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN);\n    };\n    var addElement = function (that, index) {\n      dP(that, index, {\n        get: function () {\n          return getter(this, index);\n        },\n        set: function (value) {\n          return setter(this, index, value);\n        },\n        enumerable: true\n      });\n    };\n    if (FORCED) {\n      TypedArray = wrapper(function (that, data, $offset, $length) {\n        anInstance(that, TypedArray, NAME, '_d');\n        var index = 0;\n        var offset = 0;\n        var buffer, byteLength, length, klass;\n        if (!isObject(data)) {\n          length = toIndex(data);\n          byteLength = length * BYTES;\n          buffer = new $ArrayBuffer(byteLength);\n        } else if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {\n          buffer = data;\n          offset = toOffset($offset, BYTES);\n          var $len = data.byteLength;\n          if ($length === undefined) {\n            if ($len % BYTES) throw RangeError(WRONG_LENGTH);\n            byteLength = $len - offset;\n            if (byteLength < 0) throw RangeError(WRONG_LENGTH);\n          } else {\n            byteLength = toLength($length) * BYTES;\n            if (byteLength + offset > $len) throw RangeError(WRONG_LENGTH);\n          }\n          length = byteLength / BYTES;\n        } else if (TYPED_ARRAY in data) {\n          return fromList(TypedArray, data);\n        } else {\n          return $from.call(TypedArray, data);\n        }\n        hide(that, '_d', {\n          b: buffer,\n          o: offset,\n          l: byteLength,\n          e: length,\n          v: new $DataView(buffer)\n        });\n        while (index < length) addElement(that, index++);\n      });\n      TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$);\n      hide(TypedArrayPrototype, 'constructor', TypedArray);\n    } else if (!fails(function () {\n      TypedArray(1);\n    }) || !fails(function () {\n      new TypedArray(-1); // eslint-disable-line no-new\n    }) || !$iterDetect(function (iter) {\n      new TypedArray(); // eslint-disable-line no-new\n      new TypedArray(null); // eslint-disable-line no-new\n      new TypedArray(1.5); // eslint-disable-line no-new\n      new TypedArray(iter); // eslint-disable-line no-new\n    }, true)) {\n      TypedArray = wrapper(function (that, data, $offset, $length) {\n        anInstance(that, TypedArray, NAME);\n        var klass;\n        // `ws` module bug, temporarily remove validation length for Uint8Array\n        // https://github.com/websockets/ws/pull/645\n        if (!isObject(data)) return new Base(toIndex(data));\n        if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {\n          return $length !== undefined\n            ? new Base(data, toOffset($offset, BYTES), $length)\n            : $offset !== undefined\n              ? new Base(data, toOffset($offset, BYTES))\n              : new Base(data);\n        }\n        if (TYPED_ARRAY in data) return fromList(TypedArray, data);\n        return $from.call(TypedArray, data);\n      });\n      arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function (key) {\n        if (!(key in TypedArray)) hide(TypedArray, key, Base[key]);\n      });\n      TypedArray[PROTOTYPE] = TypedArrayPrototype;\n      if (!LIBRARY) TypedArrayPrototype.constructor = TypedArray;\n    }\n    var $nativeIterator = TypedArrayPrototype[ITERATOR];\n    var CORRECT_ITER_NAME = !!$nativeIterator\n      && ($nativeIterator.name == 'values' || $nativeIterator.name == undefined);\n    var $iterator = $iterators.values;\n    hide(TypedArray, TYPED_CONSTRUCTOR, true);\n    hide(TypedArrayPrototype, TYPED_ARRAY, NAME);\n    hide(TypedArrayPrototype, VIEW, true);\n    hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray);\n\n    if (CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)) {\n      dP(TypedArrayPrototype, TAG, {\n        get: function () { return NAME; }\n      });\n    }\n\n    O[NAME] = TypedArray;\n\n    $export($export.G + $export.W + $export.F * (TypedArray != Base), O);\n\n    $export($export.S, NAME, {\n      BYTES_PER_ELEMENT: BYTES\n    });\n\n    $export($export.S + $export.F * fails(function () { Base.of.call(TypedArray, 1); }), NAME, {\n      from: $from,\n      of: $of\n    });\n\n    if (!(BYTES_PER_ELEMENT in TypedArrayPrototype)) hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES);\n\n    $export($export.P, NAME, proto);\n\n    setSpecies(NAME);\n\n    $export($export.P + $export.F * FORCED_SET, NAME, { set: $set });\n\n    $export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators);\n\n    if (!LIBRARY && TypedArrayPrototype.toString != arrayToString) TypedArrayPrototype.toString = arrayToString;\n\n    $export($export.P + $export.F * fails(function () {\n      new TypedArray(1).slice();\n    }), NAME, { slice: $slice });\n\n    $export($export.P + $export.F * (fails(function () {\n      return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString();\n    }) || !fails(function () {\n      TypedArrayPrototype.toLocaleString.call([1, 2]);\n    })), NAME, { toLocaleString: $toLocaleString });\n\n    Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator;\n    if (!LIBRARY && !CORRECT_ITER_NAME) hide(TypedArrayPrototype, ITERATOR, $iterator);\n  };\n} else module.exports = function () { /* empty */ };\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_typed-buffer.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/_typed-buffer.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar $typed = __webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toIndex = __webpack_require__(/*! ./_to-index */ \"./node_modules/core-js/modules/_to-index.js\");\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar arrayFill = __webpack_require__(/*! ./_array-fill */ \"./node_modules/core-js/modules/_array-fill.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar ARRAY_BUFFER = 'ArrayBuffer';\nvar DATA_VIEW = 'DataView';\nvar PROTOTYPE = 'prototype';\nvar WRONG_LENGTH = 'Wrong length!';\nvar WRONG_INDEX = 'Wrong index!';\nvar $ArrayBuffer = global[ARRAY_BUFFER];\nvar $DataView = global[DATA_VIEW];\nvar Math = global.Math;\nvar RangeError = global.RangeError;\n// eslint-disable-next-line no-shadow-restricted-names\nvar Infinity = global.Infinity;\nvar BaseBuffer = $ArrayBuffer;\nvar abs = Math.abs;\nvar pow = Math.pow;\nvar floor = Math.floor;\nvar log = Math.log;\nvar LN2 = Math.LN2;\nvar BUFFER = 'buffer';\nvar BYTE_LENGTH = 'byteLength';\nvar BYTE_OFFSET = 'byteOffset';\nvar $BUFFER = DESCRIPTORS ? '_b' : BUFFER;\nvar $LENGTH = DESCRIPTORS ? '_l' : BYTE_LENGTH;\nvar $OFFSET = DESCRIPTORS ? '_o' : BYTE_OFFSET;\n\n// IEEE754 conversions based on https://github.com/feross/ieee754\nfunction packIEEE754(value, mLen, nBytes) {\n  var buffer = new Array(nBytes);\n  var eLen = nBytes * 8 - mLen - 1;\n  var eMax = (1 << eLen) - 1;\n  var eBias = eMax >> 1;\n  var rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0;\n  var i = 0;\n  var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;\n  var e, m, c;\n  value = abs(value);\n  // eslint-disable-next-line no-self-compare\n  if (value != value || value === Infinity) {\n    // eslint-disable-next-line no-self-compare\n    m = value != value ? 1 : 0;\n    e = eMax;\n  } else {\n    e = floor(log(value) / LN2);\n    if (value * (c = pow(2, -e)) < 1) {\n      e--;\n      c *= 2;\n    }\n    if (e + eBias >= 1) {\n      value += rt / c;\n    } else {\n      value += rt * pow(2, 1 - eBias);\n    }\n    if (value * c >= 2) {\n      e++;\n      c /= 2;\n    }\n    if (e + eBias >= eMax) {\n      m = 0;\n      e = eMax;\n    } else if (e + eBias >= 1) {\n      m = (value * c - 1) * pow(2, mLen);\n      e = e + eBias;\n    } else {\n      m = value * pow(2, eBias - 1) * pow(2, mLen);\n      e = 0;\n    }\n  }\n  for (; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8);\n  e = e << mLen | m;\n  eLen += mLen;\n  for (; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8);\n  buffer[--i] |= s * 128;\n  return buffer;\n}\nfunction unpackIEEE754(buffer, mLen, nBytes) {\n  var eLen = nBytes * 8 - mLen - 1;\n  var eMax = (1 << eLen) - 1;\n  var eBias = eMax >> 1;\n  var nBits = eLen - 7;\n  var i = nBytes - 1;\n  var s = buffer[i--];\n  var e = s & 127;\n  var m;\n  s >>= 7;\n  for (; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8);\n  m = e & (1 << -nBits) - 1;\n  e >>= -nBits;\n  nBits += mLen;\n  for (; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);\n  if (e === 0) {\n    e = 1 - eBias;\n  } else if (e === eMax) {\n    return m ? NaN : s ? -Infinity : Infinity;\n  } else {\n    m = m + pow(2, mLen);\n    e = e - eBias;\n  } return (s ? -1 : 1) * m * pow(2, e - mLen);\n}\n\nfunction unpackI32(bytes) {\n  return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];\n}\nfunction packI8(it) {\n  return [it & 0xff];\n}\nfunction packI16(it) {\n  return [it & 0xff, it >> 8 & 0xff];\n}\nfunction packI32(it) {\n  return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff];\n}\nfunction packF64(it) {\n  return packIEEE754(it, 52, 8);\n}\nfunction packF32(it) {\n  return packIEEE754(it, 23, 4);\n}\n\nfunction addGetter(C, key, internal) {\n  dP(C[PROTOTYPE], key, { get: function () { return this[internal]; } });\n}\n\nfunction get(view, bytes, index, isLittleEndian) {\n  var numIndex = +index;\n  var intIndex = toIndex(numIndex);\n  if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);\n  var store = view[$BUFFER]._b;\n  var start = intIndex + view[$OFFSET];\n  var pack = store.slice(start, start + bytes);\n  return isLittleEndian ? pack : pack.reverse();\n}\nfunction set(view, bytes, index, conversion, value, isLittleEndian) {\n  var numIndex = +index;\n  var intIndex = toIndex(numIndex);\n  if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);\n  var store = view[$BUFFER]._b;\n  var start = intIndex + view[$OFFSET];\n  var pack = conversion(+value);\n  for (var i = 0; i < bytes; i++) store[start + i] = pack[isLittleEndian ? i : bytes - i - 1];\n}\n\nif (!$typed.ABV) {\n  $ArrayBuffer = function ArrayBuffer(length) {\n    anInstance(this, $ArrayBuffer, ARRAY_BUFFER);\n    var byteLength = toIndex(length);\n    this._b = arrayFill.call(new Array(byteLength), 0);\n    this[$LENGTH] = byteLength;\n  };\n\n  $DataView = function DataView(buffer, byteOffset, byteLength) {\n    anInstance(this, $DataView, DATA_VIEW);\n    anInstance(buffer, $ArrayBuffer, DATA_VIEW);\n    var bufferLength = buffer[$LENGTH];\n    var offset = toInteger(byteOffset);\n    if (offset < 0 || offset > bufferLength) throw RangeError('Wrong offset!');\n    byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);\n    if (offset + byteLength > bufferLength) throw RangeError(WRONG_LENGTH);\n    this[$BUFFER] = buffer;\n    this[$OFFSET] = offset;\n    this[$LENGTH] = byteLength;\n  };\n\n  if (DESCRIPTORS) {\n    addGetter($ArrayBuffer, BYTE_LENGTH, '_l');\n    addGetter($DataView, BUFFER, '_b');\n    addGetter($DataView, BYTE_LENGTH, '_l');\n    addGetter($DataView, BYTE_OFFSET, '_o');\n  }\n\n  redefineAll($DataView[PROTOTYPE], {\n    getInt8: function getInt8(byteOffset) {\n      return get(this, 1, byteOffset)[0] << 24 >> 24;\n    },\n    getUint8: function getUint8(byteOffset) {\n      return get(this, 1, byteOffset)[0];\n    },\n    getInt16: function getInt16(byteOffset /* , littleEndian */) {\n      var bytes = get(this, 2, byteOffset, arguments[1]);\n      return (bytes[1] << 8 | bytes[0]) << 16 >> 16;\n    },\n    getUint16: function getUint16(byteOffset /* , littleEndian */) {\n      var bytes = get(this, 2, byteOffset, arguments[1]);\n      return bytes[1] << 8 | bytes[0];\n    },\n    getInt32: function getInt32(byteOffset /* , littleEndian */) {\n      return unpackI32(get(this, 4, byteOffset, arguments[1]));\n    },\n    getUint32: function getUint32(byteOffset /* , littleEndian */) {\n      return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0;\n    },\n    getFloat32: function getFloat32(byteOffset /* , littleEndian */) {\n      return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4);\n    },\n    getFloat64: function getFloat64(byteOffset /* , littleEndian */) {\n      return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8);\n    },\n    setInt8: function setInt8(byteOffset, value) {\n      set(this, 1, byteOffset, packI8, value);\n    },\n    setUint8: function setUint8(byteOffset, value) {\n      set(this, 1, byteOffset, packI8, value);\n    },\n    setInt16: function setInt16(byteOffset, value /* , littleEndian */) {\n      set(this, 2, byteOffset, packI16, value, arguments[2]);\n    },\n    setUint16: function setUint16(byteOffset, value /* , littleEndian */) {\n      set(this, 2, byteOffset, packI16, value, arguments[2]);\n    },\n    setInt32: function setInt32(byteOffset, value /* , littleEndian */) {\n      set(this, 4, byteOffset, packI32, value, arguments[2]);\n    },\n    setUint32: function setUint32(byteOffset, value /* , littleEndian */) {\n      set(this, 4, byteOffset, packI32, value, arguments[2]);\n    },\n    setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) {\n      set(this, 4, byteOffset, packF32, value, arguments[2]);\n    },\n    setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) {\n      set(this, 8, byteOffset, packF64, value, arguments[2]);\n    }\n  });\n} else {\n  if (!fails(function () {\n    $ArrayBuffer(1);\n  }) || !fails(function () {\n    new $ArrayBuffer(-1); // eslint-disable-line no-new\n  }) || fails(function () {\n    new $ArrayBuffer(); // eslint-disable-line no-new\n    new $ArrayBuffer(1.5); // eslint-disable-line no-new\n    new $ArrayBuffer(NaN); // eslint-disable-line no-new\n    return $ArrayBuffer.name != ARRAY_BUFFER;\n  })) {\n    $ArrayBuffer = function ArrayBuffer(length) {\n      anInstance(this, $ArrayBuffer);\n      return new BaseBuffer(toIndex(length));\n    };\n    var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE];\n    for (var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j;) {\n      if (!((key = keys[j++]) in $ArrayBuffer)) hide($ArrayBuffer, key, BaseBuffer[key]);\n    }\n    if (!LIBRARY) ArrayBufferProto.constructor = $ArrayBuffer;\n  }\n  // iOS Safari 7.x bug\n  var view = new $DataView(new $ArrayBuffer(2));\n  var $setInt8 = $DataView[PROTOTYPE].setInt8;\n  view.setInt8(0, 2147483648);\n  view.setInt8(1, 2147483649);\n  if (view.getInt8(0) || !view.getInt8(1)) redefineAll($DataView[PROTOTYPE], {\n    setInt8: function setInt8(byteOffset, value) {\n      $setInt8.call(this, byteOffset, value << 24 >> 24);\n    },\n    setUint8: function setUint8(byteOffset, value) {\n      $setInt8.call(this, byteOffset, value << 24 >> 24);\n    }\n  }, true);\n}\nsetToStringTag($ArrayBuffer, ARRAY_BUFFER);\nsetToStringTag($DataView, DATA_VIEW);\nhide($DataView[PROTOTYPE], $typed.VIEW, true);\nexports[ARRAY_BUFFER] = $ArrayBuffer;\nexports[DATA_VIEW] = $DataView;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_typed.js\":\n/*!************************************************!*\\\n  !*** ./node_modules/core-js/modules/_typed.js ***!\n  \\************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar TYPED = uid('typed_array');\nvar VIEW = uid('view');\nvar ABV = !!(global.ArrayBuffer && global.DataView);\nvar CONSTR = ABV;\nvar i = 0;\nvar l = 9;\nvar Typed;\n\nvar TypedArrayConstructors = (\n  'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array'\n).split(',');\n\nwhile (i < l) {\n  if (Typed = global[TypedArrayConstructors[i++]]) {\n    hide(Typed.prototype, TYPED, true);\n    hide(Typed.prototype, VIEW, true);\n  } else CONSTR = false;\n}\n\nmodule.exports = {\n  ABV: ABV,\n  CONSTR: CONSTR,\n  TYPED: TYPED,\n  VIEW: VIEW\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_uid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_uid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_user-agent.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_user-agent.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar navigator = global.navigator;\n\nmodule.exports = navigator && navigator.userAgent || '';\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_validate-collection.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/_validate-collection.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nmodule.exports = function (it, TYPE) {\n  if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');\n  return it;\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks-define.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks-define.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar wksExt = __webpack_require__(/*! ./_wks-ext */ \"./node_modules/core-js/modules/_wks-ext.js\");\nvar defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nmodule.exports = function (name) {\n  var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});\n  if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) });\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks-ext.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks-ext.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nexports.f = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/_wks.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/core-js/modules/_wks.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar store = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\")('wks');\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar Symbol = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n  return store[name] || (store[name] =\n    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/core.get-iterator-method.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/core.get-iterator-method.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar ITERATOR = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('iterator');\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nmodule.exports = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\").getIteratorMethod = function (it) {\n  if (it != undefined) return it[ITERATOR]\n    || it['@@iterator']\n    || Iterators[classof(it)];\n};\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/core.regexp.escape.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/core.regexp.escape.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/benjamingr/RexExp.escape\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $re = __webpack_require__(/*! ./_replacer */ \"./node_modules/core-js/modules/_replacer.js\")(/[\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\n$export($export.S, 'RegExp', { escape: function escape(it) { return $re(it); } });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.copy-within.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.copy-within.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Array', { copyWithin: __webpack_require__(/*! ./_array-copy-within */ \"./node_modules/core-js/modules/_array-copy-within.js\") });\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('copyWithin');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.every.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.every.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $every = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(4);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].every, true), 'Array', {\n  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])\n  every: function every(callbackfn /* , thisArg */) {\n    return $every(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.fill.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.fill.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Array', { fill: __webpack_require__(/*! ./_array-fill */ \"./node_modules/core-js/modules/_array-fill.js\") });\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('fill');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.filter.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.filter.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $filter = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(2);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].filter, true), 'Array', {\n  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])\n  filter: function filter(callbackfn /* , thisArg */) {\n    return $filter(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.find-index.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.find-index.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $find = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(6);\nvar KEY = 'findIndex';\nvar forced = true;\n// Shouldn't skip holes\nif (KEY in []) Array(1)[KEY](function () { forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  findIndex: function findIndex(callbackfn /* , that = undefined */) {\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")(KEY);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.find.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.find.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $find = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(5);\nvar KEY = 'find';\nvar forced = true;\n// Shouldn't skip holes\nif (KEY in []) Array(1)[KEY](function () { forced = false; });\n$export($export.P + $export.F * forced, 'Array', {\n  find: function find(callbackfn /* , that = undefined */) {\n    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")(KEY);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.for-each.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.for-each.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $forEach = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(0);\nvar STRICT = __webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].forEach, true);\n\n$export($export.P + $export.F * !STRICT, 'Array', {\n  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])\n  forEach: function forEach(callbackfn /* , thisArg */) {\n    return $forEach(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.from.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.from.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar call = __webpack_require__(/*! ./_iter-call */ \"./node_modules/core-js/modules/_iter-call.js\");\nvar isArrayIter = __webpack_require__(/*! ./_is-array-iter */ \"./node_modules/core-js/modules/_is-array-iter.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar createProperty = __webpack_require__(/*! ./_create-property */ \"./node_modules/core-js/modules/_create-property.js\");\nvar getIterFn = __webpack_require__(/*! ./core.get-iterator-method */ \"./node_modules/core-js/modules/core.get-iterator-method.js\");\n\n$export($export.S + $export.F * !__webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\")(function (iter) { Array.from(iter); }), 'Array', {\n  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)\n  from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {\n    var O = toObject(arrayLike);\n    var C = typeof this == 'function' ? this : Array;\n    var aLen = arguments.length;\n    var mapfn = aLen > 1 ? arguments[1] : undefined;\n    var mapping = mapfn !== undefined;\n    var index = 0;\n    var iterFn = getIterFn(O);\n    var length, result, step, iterator;\n    if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);\n    // if object isn't iterable or it's array with default iterator - use simple case\n    if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) {\n      for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {\n        createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);\n      }\n    } else {\n      length = toLength(O.length);\n      for (result = new C(length); length > index; index++) {\n        createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);\n      }\n    }\n    result.length = index;\n    return result;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.index-of.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.index-of.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $indexOf = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(false);\nvar $native = [].indexOf;\nvar NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0;\n\n$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")($native)), 'Array', {\n  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])\n  indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {\n    return NEGATIVE_ZERO\n      // convert -0 to +0\n      ? $native.apply(this, arguments) || 0\n      : $indexOf(this, searchElement, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.is-array.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.is-array.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Array', { isArray: __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.iterator.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.iterator.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar addToUnscopables = __webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\");\nvar step = __webpack_require__(/*! ./_iter-step */ \"./node_modules/core-js/modules/_iter-step.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = __webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(Array, 'Array', function (iterated, kind) {\n  this._t = toIObject(iterated); // target\n  this._i = 0;                   // next index\n  this._k = kind;                // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var kind = this._k;\n  var index = this._i++;\n  if (!O || index >= O.length) {\n    this._t = undefined;\n    return step(1);\n  }\n  if (kind == 'keys') return step(0, index);\n  if (kind == 'values') return step(0, O[index]);\n  return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.join.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.join.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 22.1.3.13 Array.prototype.join(separator)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar arrayJoin = [].join;\n\n// fallback for not array-like strings\n$export($export.P + $export.F * (__webpack_require__(/*! ./_iobject */ \"./node_modules/core-js/modules/_iobject.js\") != Object || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")(arrayJoin)), 'Array', {\n  join: function join(separator) {\n    return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.last-index-of.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.last-index-of.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar $native = [].lastIndexOf;\nvar NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0;\n\n$export($export.P + $export.F * (NEGATIVE_ZERO || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")($native)), 'Array', {\n  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])\n  lastIndexOf: function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {\n    // convert -0 to +0\n    if (NEGATIVE_ZERO) return $native.apply(this, arguments) || 0;\n    var O = toIObject(this);\n    var length = toLength(O.length);\n    var index = length - 1;\n    if (arguments.length > 1) index = Math.min(index, toInteger(arguments[1]));\n    if (index < 0) index = length + index;\n    for (;index >= 0; index--) if (index in O) if (O[index] === searchElement) return index || 0;\n    return -1;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.map.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.map.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $map = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(1);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].map, true), 'Array', {\n  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])\n  map: function map(callbackfn /* , thisArg */) {\n    return $map(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.of.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.of.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar createProperty = __webpack_require__(/*! ./_create-property */ \"./node_modules/core-js/modules/_create-property.js\");\n\n// WebKit Array.of isn't generic\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  function F() { /* empty */ }\n  return !(Array.of.call(F) instanceof F);\n}), 'Array', {\n  // 22.1.2.3 Array.of( ...items)\n  of: function of(/* ...args */) {\n    var index = 0;\n    var aLen = arguments.length;\n    var result = new (typeof this == 'function' ? this : Array)(aLen);\n    while (aLen > index) createProperty(result, index, arguments[index++]);\n    result.length = aLen;\n    return result;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.reduce-right.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.reduce-right.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $reduce = __webpack_require__(/*! ./_array-reduce */ \"./node_modules/core-js/modules/_array-reduce.js\");\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].reduceRight, true), 'Array', {\n  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])\n  reduceRight: function reduceRight(callbackfn /* , initialValue */) {\n    return $reduce(this, callbackfn, arguments.length, arguments[1], true);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.reduce.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.reduce.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $reduce = __webpack_require__(/*! ./_array-reduce */ \"./node_modules/core-js/modules/_array-reduce.js\");\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].reduce, true), 'Array', {\n  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])\n  reduce: function reduce(callbackfn /* , initialValue */) {\n    return $reduce(this, callbackfn, arguments.length, arguments[1], false);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.slice.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.slice.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar html = __webpack_require__(/*! ./_html */ \"./node_modules/core-js/modules/_html.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar arraySlice = [].slice;\n\n// fallback for not array-like ES3 strings and DOM objects\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  if (html) arraySlice.call(html);\n}), 'Array', {\n  slice: function slice(begin, end) {\n    var len = toLength(this.length);\n    var klass = cof(this);\n    end = end === undefined ? len : end;\n    if (klass == 'Array') return arraySlice.call(this, begin, end);\n    var start = toAbsoluteIndex(begin, len);\n    var upTo = toAbsoluteIndex(end, len);\n    var size = toLength(upTo - start);\n    var cloned = new Array(size);\n    var i = 0;\n    for (; i < size; i++) cloned[i] = klass == 'String'\n      ? this.charAt(start + i)\n      : this[start + i];\n    return cloned;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.some.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.some.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $some = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(3);\n\n$export($export.P + $export.F * !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")([].some, true), 'Array', {\n  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])\n  some: function some(callbackfn /* , thisArg */) {\n    return $some(this, callbackfn, arguments[1]);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.sort.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.sort.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar $sort = [].sort;\nvar test = [1, 2, 3];\n\n$export($export.P + $export.F * (fails(function () {\n  // IE8-\n  test.sort(undefined);\n}) || !fails(function () {\n  // V8 bug\n  test.sort(null);\n  // Old WebKit\n}) || !__webpack_require__(/*! ./_strict-method */ \"./node_modules/core-js/modules/_strict-method.js\")($sort)), 'Array', {\n  // 22.1.3.25 Array.prototype.sort(comparefn)\n  sort: function sort(comparefn) {\n    return comparefn === undefined\n      ? $sort.call(toObject(this))\n      : $sort.call(toObject(this), aFunction(comparefn));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.array.species.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.array.species.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")('Array');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.now.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.now.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.3.3.1 / 15.9.4.4 Date.now()\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Date', { now: function () { return new Date().getTime(); } });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-iso-string.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-iso-string.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toISOString = __webpack_require__(/*! ./_date-to-iso-string */ \"./node_modules/core-js/modules/_date-to-iso-string.js\");\n\n// PhantomJS / old WebKit has a broken implementations\n$export($export.P + $export.F * (Date.prototype.toISOString !== toISOString), 'Date', {\n  toISOString: toISOString\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-json.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-json.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return new Date(NaN).toJSON() !== null\n    || Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1;\n}), 'Date', {\n  // eslint-disable-next-line no-unused-vars\n  toJSON: function toJSON(key) {\n    var O = toObject(this);\n    var pv = toPrimitive(O);\n    return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-primitive.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-primitive.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar TO_PRIMITIVE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toPrimitive');\nvar proto = Date.prototype;\n\nif (!(TO_PRIMITIVE in proto)) __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")(proto, TO_PRIMITIVE, __webpack_require__(/*! ./_date-to-primitive */ \"./node_modules/core-js/modules/_date-to-primitive.js\"));\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.date.to-string.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.date.to-string.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar DateProto = Date.prototype;\nvar INVALID_DATE = 'Invalid Date';\nvar TO_STRING = 'toString';\nvar $toString = DateProto[TO_STRING];\nvar getTime = DateProto.getTime;\nif (new Date(NaN) + '' != INVALID_DATE) {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(DateProto, TO_STRING, function toString() {\n    var value = getTime.call(this);\n    // eslint-disable-next-line no-self-compare\n    return value === value ? $toString.call(this) : INVALID_DATE;\n  });\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.bind.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.bind.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'Function', { bind: __webpack_require__(/*! ./_bind */ \"./node_modules/core-js/modules/_bind.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.has-instance.js\":\n/*!*******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.has-instance.js ***!\n  \\*******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar HAS_INSTANCE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('hasInstance');\nvar FunctionProto = Function.prototype;\n// 19.2.3.6 Function.prototype[@@hasInstance](V)\nif (!(HAS_INSTANCE in FunctionProto)) __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f(FunctionProto, HAS_INSTANCE, { value: function (O) {\n  if (typeof this != 'function' || !isObject(O)) return false;\n  if (!isObject(this.prototype)) return O instanceof this;\n  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:\n  while (O = getPrototypeOf(O)) if (this.prototype === O) return true;\n  return false;\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.function.name.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.function.name.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar FProto = Function.prototype;\nvar nameRE = /^\\s*function ([^ (]*)/;\nvar NAME = 'name';\n\n// 19.2.4.2 name\nNAME in FProto || __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && dP(FProto, NAME, {\n  configurable: true,\n  get: function () {\n    try {\n      return ('' + this).match(nameRE)[1];\n    } catch (e) {\n      return '';\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.map.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.map.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar strong = __webpack_require__(/*! ./_collection-strong */ \"./node_modules/core-js/modules/_collection-strong.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar MAP = 'Map';\n\n// 23.1 Map Objects\nmodule.exports = __webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(MAP, function (get) {\n  return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.1.3.6 Map.prototype.get(key)\n  get: function get(key) {\n    var entry = strong.getEntry(validate(this, MAP), key);\n    return entry && entry.v;\n  },\n  // 23.1.3.9 Map.prototype.set(key, value)\n  set: function set(key, value) {\n    return strong.def(validate(this, MAP), key === 0 ? 0 : key, value);\n  }\n}, strong, true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.acosh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.acosh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.3 Math.acosh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar log1p = __webpack_require__(/*! ./_math-log1p */ \"./node_modules/core-js/modules/_math-log1p.js\");\nvar sqrt = Math.sqrt;\nvar $acosh = Math.acosh;\n\n$export($export.S + $export.F * !($acosh\n  // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509\n  && Math.floor($acosh(Number.MAX_VALUE)) == 710\n  // Tor Browser bug: Math.acosh(Infinity) -> NaN\n  && $acosh(Infinity) == Infinity\n), 'Math', {\n  acosh: function acosh(x) {\n    return (x = +x) < 1 ? NaN : x > 94906265.62425156\n      ? Math.log(x) + Math.LN2\n      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.asinh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.asinh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.5 Math.asinh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $asinh = Math.asinh;\n\nfunction asinh(x) {\n  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));\n}\n\n// Tor Browser bug: Math.asinh(0) -> -0\n$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', { asinh: asinh });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.atanh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.atanh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.7 Math.atanh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $atanh = Math.atanh;\n\n// Tor Browser bug: Math.atanh(-0) -> 0\n$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {\n  atanh: function atanh(x) {\n    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.cbrt.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.cbrt.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.9 Math.cbrt(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar sign = __webpack_require__(/*! ./_math-sign */ \"./node_modules/core-js/modules/_math-sign.js\");\n\n$export($export.S, 'Math', {\n  cbrt: function cbrt(x) {\n    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.clz32.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.clz32.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.11 Math.clz32(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  clz32: function clz32(x) {\n    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.cosh.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.cosh.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.12 Math.cosh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar exp = Math.exp;\n\n$export($export.S, 'Math', {\n  cosh: function cosh(x) {\n    return (exp(x = +x) + exp(-x)) / 2;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.expm1.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.expm1.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.14 Math.expm1(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $expm1 = __webpack_require__(/*! ./_math-expm1 */ \"./node_modules/core-js/modules/_math-expm1.js\");\n\n$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', { expm1: $expm1 });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.fround.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.fround.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.16 Math.fround(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { fround: __webpack_require__(/*! ./_math-fround */ \"./node_modules/core-js/modules/_math-fround.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.hypot.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.hypot.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar abs = Math.abs;\n\n$export($export.S, 'Math', {\n  hypot: function hypot(value1, value2) { // eslint-disable-line no-unused-vars\n    var sum = 0;\n    var i = 0;\n    var aLen = arguments.length;\n    var larg = 0;\n    var arg, div;\n    while (i < aLen) {\n      arg = abs(arguments[i++]);\n      if (larg < arg) {\n        div = larg / arg;\n        sum = sum * div * div + 1;\n        larg = arg;\n      } else if (arg > 0) {\n        div = arg / larg;\n        sum += div * div;\n      } else sum += arg;\n    }\n    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.imul.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.imul.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.18 Math.imul(x, y)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $imul = Math.imul;\n\n// some WebKit versions fails with big numbers, some has wrong arity\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;\n}), 'Math', {\n  imul: function imul(x, y) {\n    var UINT16 = 0xffff;\n    var xn = +x;\n    var yn = +y;\n    var xl = UINT16 & xn;\n    var yl = UINT16 & yn;\n    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.log10.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.log10.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.21 Math.log10(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  log10: function log10(x) {\n    return Math.log(x) * Math.LOG10E;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.log1p.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.log1p.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.20 Math.log1p(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { log1p: __webpack_require__(/*! ./_math-log1p */ \"./node_modules/core-js/modules/_math-log1p.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.log2.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.log2.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.22 Math.log2(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  log2: function log2(x) {\n    return Math.log(x) / Math.LN2;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.sign.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.sign.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.28 Math.sign(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { sign: __webpack_require__(/*! ./_math-sign */ \"./node_modules/core-js/modules/_math-sign.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.sinh.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.sinh.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.30 Math.sinh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar expm1 = __webpack_require__(/*! ./_math-expm1 */ \"./node_modules/core-js/modules/_math-expm1.js\");\nvar exp = Math.exp;\n\n// V8 near Chromium 38 has a problem with very small numbers\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return !Math.sinh(-2e-17) != -2e-17;\n}), 'Math', {\n  sinh: function sinh(x) {\n    return Math.abs(x = +x) < 1\n      ? (expm1(x) - expm1(-x)) / 2\n      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.tanh.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.tanh.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.33 Math.tanh(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar expm1 = __webpack_require__(/*! ./_math-expm1 */ \"./node_modules/core-js/modules/_math-expm1.js\");\nvar exp = Math.exp;\n\n$export($export.S, 'Math', {\n  tanh: function tanh(x) {\n    var a = expm1(x = +x);\n    var b = expm1(-x);\n    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.math.trunc.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.math.trunc.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.2.2.34 Math.trunc(x)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  trunc: function trunc(it) {\n    return (it > 0 ? Math.floor : Math.ceil)(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.constructor.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.constructor.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\nvar inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ \"./node_modules/core-js/modules/_inherit-if-required.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar $trim = __webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\").trim;\nvar NUMBER = 'Number';\nvar $Number = global[NUMBER];\nvar Base = $Number;\nvar proto = $Number.prototype;\n// Opera ~12 has broken Object#toString\nvar BROKEN_COF = cof(__webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\")(proto)) == NUMBER;\nvar TRIM = 'trim' in String.prototype;\n\n// 7.1.3 ToNumber(argument)\nvar toNumber = function (argument) {\n  var it = toPrimitive(argument, false);\n  if (typeof it == 'string' && it.length > 2) {\n    it = TRIM ? it.trim() : $trim(it, 3);\n    var first = it.charCodeAt(0);\n    var third, radix, maxCode;\n    if (first === 43 || first === 45) {\n      third = it.charCodeAt(2);\n      if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix\n    } else if (first === 48) {\n      switch (it.charCodeAt(1)) {\n        case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i\n        case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i\n        default: return +it;\n      }\n      for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {\n        code = digits.charCodeAt(i);\n        // parseInt parses a string to a first unavailable symbol\n        // but ToNumber should return NaN if a string contains unavailable symbols\n        if (code < 48 || code > maxCode) return NaN;\n      } return parseInt(digits, radix);\n    }\n  } return +it;\n};\n\nif (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {\n  $Number = function Number(value) {\n    var it = arguments.length < 1 ? 0 : value;\n    var that = this;\n    return that instanceof $Number\n      // check on 1..constructor(foo) case\n      && (BROKEN_COF ? fails(function () { proto.valueOf.call(that); }) : cof(that) != NUMBER)\n        ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);\n  };\n  for (var keys = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") ? gOPN(Base) : (\n    // ES3:\n    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +\n    // ES6 (in case, if modules with ES6 Number statics required before):\n    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +\n    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'\n  ).split(','), j = 0, key; keys.length > j; j++) {\n    if (has(Base, key = keys[j]) && !has($Number, key)) {\n      dP($Number, key, gOPD(Base, key));\n    }\n  }\n  $Number.prototype = proto;\n  proto.constructor = $Number;\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(global, NUMBER, $Number);\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.epsilon.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.epsilon.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.1 Number.EPSILON\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { EPSILON: Math.pow(2, -52) });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-finite.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-finite.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.2 Number.isFinite(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar _isFinite = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").isFinite;\n\n$export($export.S, 'Number', {\n  isFinite: function isFinite(it) {\n    return typeof it == 'number' && _isFinite(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-integer.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-integer.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.3 Number.isInteger(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { isInteger: __webpack_require__(/*! ./_is-integer */ \"./node_modules/core-js/modules/_is-integer.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-nan.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-nan.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.4 Number.isNaN(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', {\n  isNaN: function isNaN(number) {\n    // eslint-disable-next-line no-self-compare\n    return number != number;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.is-safe-integer.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.is-safe-integer.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.5 Number.isSafeInteger(number)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isInteger = __webpack_require__(/*! ./_is-integer */ \"./node_modules/core-js/modules/_is-integer.js\");\nvar abs = Math.abs;\n\n$export($export.S, 'Number', {\n  isSafeInteger: function isSafeInteger(number) {\n    return isInteger(number) && abs(number) <= 0x1fffffffffffff;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.max-safe-integer.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.max-safe-integer.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.6 Number.MAX_SAFE_INTEGER\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.min-safe-integer.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.min-safe-integer.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 20.1.2.10 Number.MIN_SAFE_INTEGER\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.parse-float.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.parse-float.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseFloat = __webpack_require__(/*! ./_parse-float */ \"./node_modules/core-js/modules/_parse-float.js\");\n// 20.1.2.12 Number.parseFloat(string)\n$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', { parseFloat: $parseFloat });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.parse-int.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.parse-int.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseInt = __webpack_require__(/*! ./_parse-int */ \"./node_modules/core-js/modules/_parse-int.js\");\n// 20.1.2.13 Number.parseInt(string, radix)\n$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', { parseInt: $parseInt });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.to-fixed.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.to-fixed.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar aNumberValue = __webpack_require__(/*! ./_a-number-value */ \"./node_modules/core-js/modules/_a-number-value.js\");\nvar repeat = __webpack_require__(/*! ./_string-repeat */ \"./node_modules/core-js/modules/_string-repeat.js\");\nvar $toFixed = 1.0.toFixed;\nvar floor = Math.floor;\nvar data = [0, 0, 0, 0, 0, 0];\nvar ERROR = 'Number.toFixed: incorrect invocation!';\nvar ZERO = '0';\n\nvar multiply = function (n, c) {\n  var i = -1;\n  var c2 = c;\n  while (++i < 6) {\n    c2 += n * data[i];\n    data[i] = c2 % 1e7;\n    c2 = floor(c2 / 1e7);\n  }\n};\nvar divide = function (n) {\n  var i = 6;\n  var c = 0;\n  while (--i >= 0) {\n    c += data[i];\n    data[i] = floor(c / n);\n    c = (c % n) * 1e7;\n  }\n};\nvar numToString = function () {\n  var i = 6;\n  var s = '';\n  while (--i >= 0) {\n    if (s !== '' || i === 0 || data[i] !== 0) {\n      var t = String(data[i]);\n      s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;\n    }\n  } return s;\n};\nvar pow = function (x, n, acc) {\n  return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);\n};\nvar log = function (x) {\n  var n = 0;\n  var x2 = x;\n  while (x2 >= 4096) {\n    n += 12;\n    x2 /= 4096;\n  }\n  while (x2 >= 2) {\n    n += 1;\n    x2 /= 2;\n  } return n;\n};\n\n$export($export.P + $export.F * (!!$toFixed && (\n  0.00008.toFixed(3) !== '0.000' ||\n  0.9.toFixed(0) !== '1' ||\n  1.255.toFixed(2) !== '1.25' ||\n  1000000000000000128.0.toFixed(0) !== '1000000000000000128'\n) || !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  // V8 ~ Android 4.3-\n  $toFixed.call({});\n})), 'Number', {\n  toFixed: function toFixed(fractionDigits) {\n    var x = aNumberValue(this, ERROR);\n    var f = toInteger(fractionDigits);\n    var s = '';\n    var m = ZERO;\n    var e, z, j, k;\n    if (f < 0 || f > 20) throw RangeError(ERROR);\n    // eslint-disable-next-line no-self-compare\n    if (x != x) return 'NaN';\n    if (x <= -1e21 || x >= 1e21) return String(x);\n    if (x < 0) {\n      s = '-';\n      x = -x;\n    }\n    if (x > 1e-21) {\n      e = log(x * pow(2, 69, 1)) - 69;\n      z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);\n      z *= 0x10000000000000;\n      e = 52 - e;\n      if (e > 0) {\n        multiply(0, z);\n        j = f;\n        while (j >= 7) {\n          multiply(1e7, 0);\n          j -= 7;\n        }\n        multiply(pow(10, j, 1), 0);\n        j = e - 1;\n        while (j >= 23) {\n          divide(1 << 23);\n          j -= 23;\n        }\n        divide(1 << j);\n        multiply(1, 1);\n        divide(2);\n        m = numToString();\n      } else {\n        multiply(0, z);\n        multiply(1 << -e, 0);\n        m = numToString() + repeat.call(ZERO, f);\n      }\n    }\n    if (f > 0) {\n      k = m.length;\n      m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));\n    } else {\n      m = s + m;\n    } return m;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.number.to-precision.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.number.to-precision.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar aNumberValue = __webpack_require__(/*! ./_a-number-value */ \"./node_modules/core-js/modules/_a-number-value.js\");\nvar $toPrecision = 1.0.toPrecision;\n\n$export($export.P + $export.F * ($fails(function () {\n  // IE7-\n  return $toPrecision.call(1, undefined) !== '1';\n}) || !$fails(function () {\n  // V8 ~ Android 4.3-\n  $toPrecision.call({});\n})), 'Number', {\n  toPrecision: function toPrecision(precision) {\n    var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');\n    return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.assign.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.assign.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.1 Object.assign(target, source)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S + $export.F, 'Object', { assign: __webpack_require__(/*! ./_object-assign */ \"./node_modules/core-js/modules/_object-assign.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.create.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.create.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\n$export($export.S, 'Object', { create: __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.define-properties.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.define-properties.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n// 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)\n$export($export.S + $export.F * !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\"), 'Object', { defineProperties: __webpack_require__(/*! ./_object-dps */ \"./node_modules/core-js/modules/_object-dps.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.define-property.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.define-property.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)\n$export($export.S + $export.F * !__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\"), 'Object', { defineProperty: __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.freeze.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.freeze.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.5 Object.freeze(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").onFreeze;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('freeze', function ($freeze) {\n  return function freeze(it) {\n    return $freeze && isObject(it) ? $freeze(meta(it)) : it;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js\":\n/*!********************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js ***!\n  \\********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar $getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('getOwnPropertyDescriptor', function () {\n  return function getOwnPropertyDescriptor(it, key) {\n    return $getOwnPropertyDescriptor(toIObject(it), key);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.get-own-property-names.js\":\n/*!***************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.get-own-property-names.js ***!\n  \\***************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.7 Object.getOwnPropertyNames(O)\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('getOwnPropertyNames', function () {\n  return __webpack_require__(/*! ./_object-gopn-ext */ \"./node_modules/core-js/modules/_object-gopn-ext.js\").f;\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.get-prototype-of.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.get-prototype-of.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.9 Object.getPrototypeOf(O)\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar $getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('getPrototypeOf', function () {\n  return function getPrototypeOf(it) {\n    return $getPrototypeOf(toObject(it));\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is-extensible.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is-extensible.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.11 Object.isExtensible(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('isExtensible', function ($isExtensible) {\n  return function isExtensible(it) {\n    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is-frozen.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is-frozen.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.12 Object.isFrozen(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('isFrozen', function ($isFrozen) {\n  return function isFrozen(it) {\n    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is-sealed.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is-sealed.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.13 Object.isSealed(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('isSealed', function ($isSealed) {\n  return function isSealed(it) {\n    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.is.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.is.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.10 Object.is(value1, value2)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n$export($export.S, 'Object', { is: __webpack_require__(/*! ./_same-value */ \"./node_modules/core-js/modules/_same-value.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.keys.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.keys.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.14 Object.keys(O)\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar $keys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('keys', function () {\n  return function keys(it) {\n    return $keys(toObject(it));\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.prevent-extensions.js\":\n/*!***********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.prevent-extensions.js ***!\n  \\***********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.15 Object.preventExtensions(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").onFreeze;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('preventExtensions', function ($preventExtensions) {\n  return function preventExtensions(it) {\n    return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.seal.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.seal.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.2.17 Object.seal(O)\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").onFreeze;\n\n__webpack_require__(/*! ./_object-sap */ \"./node_modules/core-js/modules/_object-sap.js\")('seal', function ($seal) {\n  return function seal(it) {\n    return $seal && isObject(it) ? $seal(meta(it)) : it;\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.set-prototype-of.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.set-prototype-of.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 19.1.3.19 Object.setPrototypeOf(O, proto)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n$export($export.S, 'Object', { setPrototypeOf: __webpack_require__(/*! ./_set-proto */ \"./node_modules/core-js/modules/_set-proto.js\").set });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.object.to-string.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.object.to-string.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 19.1.3.6 Object.prototype.toString()\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar test = {};\ntest[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('toStringTag')] = 'z';\nif (test + '' != '[object z]') {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(Object.prototype, 'toString', function toString() {\n    return '[object ' + classof(this) + ']';\n  }, true);\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.parse-float.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.parse-float.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseFloat = __webpack_require__(/*! ./_parse-float */ \"./node_modules/core-js/modules/_parse-float.js\");\n// 18.2.4 parseFloat(string)\n$export($export.G + $export.F * (parseFloat != $parseFloat), { parseFloat: $parseFloat });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.parse-int.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.parse-int.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $parseInt = __webpack_require__(/*! ./_parse-int */ \"./node_modules/core-js/modules/_parse-int.js\");\n// 18.2.5 parseInt(string, radix)\n$export($export.G + $export.F * (parseInt != $parseInt), { parseInt: $parseInt });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.promise.js\":\n/*!*****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.promise.js ***!\n  \\*****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar LIBRARY = __webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar ctx = __webpack_require__(/*! ./_ctx */ \"./node_modules/core-js/modules/_ctx.js\");\nvar classof = __webpack_require__(/*! ./_classof */ \"./node_modules/core-js/modules/_classof.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar task = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\").set;\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar newPromiseCapabilityModule = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\nvar perform = __webpack_require__(/*! ./_perform */ \"./node_modules/core-js/modules/_perform.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\nvar promiseResolve = __webpack_require__(/*! ./_promise-resolve */ \"./node_modules/core-js/modules/_promise-resolve.js\");\nvar PROMISE = 'Promise';\nvar TypeError = global.TypeError;\nvar process = global.process;\nvar versions = process && process.versions;\nvar v8 = versions && versions.v8 || '';\nvar $Promise = global[PROMISE];\nvar isNode = classof(process) == 'process';\nvar empty = function () { /* empty */ };\nvar Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;\nvar newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;\n\nvar USE_NATIVE = !!function () {\n  try {\n    // correct subclassing with @@species support\n    var promise = $Promise.resolve(1);\n    var FakePromise = (promise.constructor = {})[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('species')] = function (exec) {\n      exec(empty, empty);\n    };\n    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test\n    return (isNode || typeof PromiseRejectionEvent == 'function')\n      && promise.then(empty) instanceof FakePromise\n      // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables\n      // https://bugs.chromium.org/p/chromium/issues/detail?id=830565\n      // we can't detect it synchronously, so just check versions\n      && v8.indexOf('6.6') !== 0\n      && userAgent.indexOf('Chrome/66') === -1;\n  } catch (e) { /* empty */ }\n}();\n\n// helpers\nvar isThenable = function (it) {\n  var then;\n  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;\n};\nvar notify = function (promise, isReject) {\n  if (promise._n) return;\n  promise._n = true;\n  var chain = promise._c;\n  microtask(function () {\n    var value = promise._v;\n    var ok = promise._s == 1;\n    var i = 0;\n    var run = function (reaction) {\n      var handler = ok ? reaction.ok : reaction.fail;\n      var resolve = reaction.resolve;\n      var reject = reaction.reject;\n      var domain = reaction.domain;\n      var result, then, exited;\n      try {\n        if (handler) {\n          if (!ok) {\n            if (promise._h == 2) onHandleUnhandled(promise);\n            promise._h = 1;\n          }\n          if (handler === true) result = value;\n          else {\n            if (domain) domain.enter();\n            result = handler(value); // may throw\n            if (domain) {\n              domain.exit();\n              exited = true;\n            }\n          }\n          if (result === reaction.promise) {\n            reject(TypeError('Promise-chain cycle'));\n          } else if (then = isThenable(result)) {\n            then.call(result, resolve, reject);\n          } else resolve(result);\n        } else reject(value);\n      } catch (e) {\n        if (domain && !exited) domain.exit();\n        reject(e);\n      }\n    };\n    while (chain.length > i) run(chain[i++]); // variable length - can't use forEach\n    promise._c = [];\n    promise._n = false;\n    if (isReject && !promise._h) onUnhandled(promise);\n  });\n};\nvar onUnhandled = function (promise) {\n  task.call(global, function () {\n    var value = promise._v;\n    var unhandled = isUnhandled(promise);\n    var result, handler, console;\n    if (unhandled) {\n      result = perform(function () {\n        if (isNode) {\n          process.emit('unhandledRejection', value, promise);\n        } else if (handler = global.onunhandledrejection) {\n          handler({ promise: promise, reason: value });\n        } else if ((console = global.console) && console.error) {\n          console.error('Unhandled promise rejection', value);\n        }\n      });\n      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should\n      promise._h = isNode || isUnhandled(promise) ? 2 : 1;\n    } promise._a = undefined;\n    if (unhandled && result.e) throw result.v;\n  });\n};\nvar isUnhandled = function (promise) {\n  return promise._h !== 1 && (promise._a || promise._c).length === 0;\n};\nvar onHandleUnhandled = function (promise) {\n  task.call(global, function () {\n    var handler;\n    if (isNode) {\n      process.emit('rejectionHandled', promise);\n    } else if (handler = global.onrejectionhandled) {\n      handler({ promise: promise, reason: promise._v });\n    }\n  });\n};\nvar $reject = function (value) {\n  var promise = this;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  promise._v = value;\n  promise._s = 2;\n  if (!promise._a) promise._a = promise._c.slice();\n  notify(promise, true);\n};\nvar $resolve = function (value) {\n  var promise = this;\n  var then;\n  if (promise._d) return;\n  promise._d = true;\n  promise = promise._w || promise; // unwrap\n  try {\n    if (promise === value) throw TypeError(\"Promise can't be resolved itself\");\n    if (then = isThenable(value)) {\n      microtask(function () {\n        var wrapper = { _w: promise, _d: false }; // wrap\n        try {\n          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));\n        } catch (e) {\n          $reject.call(wrapper, e);\n        }\n      });\n    } else {\n      promise._v = value;\n      promise._s = 1;\n      notify(promise, false);\n    }\n  } catch (e) {\n    $reject.call({ _w: promise, _d: false }, e); // wrap\n  }\n};\n\n// constructor polyfill\nif (!USE_NATIVE) {\n  // 25.4.3.1 Promise(executor)\n  $Promise = function Promise(executor) {\n    anInstance(this, $Promise, PROMISE, '_h');\n    aFunction(executor);\n    Internal.call(this);\n    try {\n      executor(ctx($resolve, this, 1), ctx($reject, this, 1));\n    } catch (err) {\n      $reject.call(this, err);\n    }\n  };\n  // eslint-disable-next-line no-unused-vars\n  Internal = function Promise(executor) {\n    this._c = [];             // <- awaiting reactions\n    this._a = undefined;      // <- checked in isUnhandled reactions\n    this._s = 0;              // <- state\n    this._d = false;          // <- done\n    this._v = undefined;      // <- value\n    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled\n    this._n = false;          // <- notify\n  };\n  Internal.prototype = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\")($Promise.prototype, {\n    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)\n    then: function then(onFulfilled, onRejected) {\n      var reaction = newPromiseCapability(speciesConstructor(this, $Promise));\n      reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;\n      reaction.fail = typeof onRejected == 'function' && onRejected;\n      reaction.domain = isNode ? process.domain : undefined;\n      this._c.push(reaction);\n      if (this._a) this._a.push(reaction);\n      if (this._s) notify(this, false);\n      return reaction.promise;\n    },\n    // 25.4.5.1 Promise.prototype.catch(onRejected)\n    'catch': function (onRejected) {\n      return this.then(undefined, onRejected);\n    }\n  });\n  OwnPromiseCapability = function () {\n    var promise = new Internal();\n    this.promise = promise;\n    this.resolve = ctx($resolve, promise, 1);\n    this.reject = ctx($reject, promise, 1);\n  };\n  newPromiseCapabilityModule.f = newPromiseCapability = function (C) {\n    return C === $Promise || C === Wrapper\n      ? new OwnPromiseCapability(C)\n      : newGenericPromiseCapability(C);\n  };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });\n__webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\")($Promise, PROMISE);\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")(PROMISE);\nWrapper = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\")[PROMISE];\n\n// statics\n$export($export.S + $export.F * !USE_NATIVE, PROMISE, {\n  // 25.4.4.5 Promise.reject(r)\n  reject: function reject(r) {\n    var capability = newPromiseCapability(this);\n    var $$reject = capability.reject;\n    $$reject(r);\n    return capability.promise;\n  }\n});\n$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {\n  // 25.4.4.6 Promise.resolve(x)\n  resolve: function resolve(x) {\n    return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);\n  }\n});\n$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(/*! ./_iter-detect */ \"./node_modules/core-js/modules/_iter-detect.js\")(function (iter) {\n  $Promise.all(iter)['catch'](empty);\n})), PROMISE, {\n  // 25.4.4.1 Promise.all(iterable)\n  all: function all(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var resolve = capability.resolve;\n    var reject = capability.reject;\n    var result = perform(function () {\n      var values = [];\n      var index = 0;\n      var remaining = 1;\n      forOf(iterable, false, function (promise) {\n        var $index = index++;\n        var alreadyCalled = false;\n        values.push(undefined);\n        remaining++;\n        C.resolve(promise).then(function (value) {\n          if (alreadyCalled) return;\n          alreadyCalled = true;\n          values[$index] = value;\n          --remaining || resolve(values);\n        }, reject);\n      });\n      --remaining || resolve(values);\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  },\n  // 25.4.4.4 Promise.race(iterable)\n  race: function race(iterable) {\n    var C = this;\n    var capability = newPromiseCapability(C);\n    var reject = capability.reject;\n    var result = perform(function () {\n      forOf(iterable, false, function (promise) {\n        C.resolve(promise).then(capability.resolve, reject);\n      });\n    });\n    if (result.e) reject(result.v);\n    return capability.promise;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.apply.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.apply.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar rApply = (__webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Reflect || {}).apply;\nvar fApply = Function.apply;\n// MS Edge argumentsList argument is optional\n$export($export.S + $export.F * !__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  rApply(function () { /* empty */ });\n}), 'Reflect', {\n  apply: function apply(target, thisArgument, argumentsList) {\n    var T = aFunction(target);\n    var L = anObject(argumentsList);\n    return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.construct.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.construct.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar bind = __webpack_require__(/*! ./_bind */ \"./node_modules/core-js/modules/_bind.js\");\nvar rConstruct = (__webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").Reflect || {}).construct;\n\n// MS Edge supports only 2 arguments and argumentsList argument is optional\n// FF Nightly sets third argument as `new.target`, but does not create `this` from it\nvar NEW_TARGET_BUG = fails(function () {\n  function F() { /* empty */ }\n  return !(rConstruct(function () { /* empty */ }, [], F) instanceof F);\n});\nvar ARGS_BUG = !fails(function () {\n  rConstruct(function () { /* empty */ });\n});\n\n$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {\n  construct: function construct(Target, args /* , newTarget */) {\n    aFunction(Target);\n    anObject(args);\n    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);\n    if (ARGS_BUG && !NEW_TARGET_BUG) return rConstruct(Target, args, newTarget);\n    if (Target == newTarget) {\n      // w/o altered newTarget, optimization for 0-4 arguments\n      switch (args.length) {\n        case 0: return new Target();\n        case 1: return new Target(args[0]);\n        case 2: return new Target(args[0], args[1]);\n        case 3: return new Target(args[0], args[1], args[2]);\n        case 4: return new Target(args[0], args[1], args[2], args[3]);\n      }\n      // w/o altered newTarget, lot of arguments case\n      var $args = [null];\n      $args.push.apply($args, args);\n      return new (bind.apply(Target, $args))();\n    }\n    // with altered newTarget, not support built-in constructors\n    var proto = newTarget.prototype;\n    var instance = create(isObject(proto) ? proto : Object.prototype);\n    var result = Function.apply.call(Target, instance, args);\n    return isObject(result) ? result : instance;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.define-property.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.define-property.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\n\n// MS Edge has broken Reflect.defineProperty - throwing instead of returning false\n$export($export.S + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  // eslint-disable-next-line no-undef\n  Reflect.defineProperty(dP.f({}, 1, { value: 1 }), 1, { value: 2 });\n}), 'Reflect', {\n  defineProperty: function defineProperty(target, propertyKey, attributes) {\n    anObject(target);\n    propertyKey = toPrimitive(propertyKey, true);\n    anObject(attributes);\n    try {\n      dP.f(target, propertyKey, attributes);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.delete-property.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.delete-property.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.4 Reflect.deleteProperty(target, propertyKey)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\n$export($export.S, 'Reflect', {\n  deleteProperty: function deleteProperty(target, propertyKey) {\n    var desc = gOPD(anObject(target), propertyKey);\n    return desc && !desc.configurable ? false : delete target[propertyKey];\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.enumerate.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.enumerate.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 26.1.5 Reflect.enumerate(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar Enumerate = function (iterated) {\n  this._t = anObject(iterated); // target\n  this._i = 0;                  // next index\n  var keys = this._k = [];      // keys\n  var key;\n  for (key in iterated) keys.push(key);\n};\n__webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\")(Enumerate, 'Object', function () {\n  var that = this;\n  var keys = that._k;\n  var key;\n  do {\n    if (that._i >= keys.length) return { value: undefined, done: true };\n  } while (!((key = keys[that._i++]) in that._t));\n  return { value: key, done: false };\n});\n\n$export($export.S, 'Reflect', {\n  enumerate: function enumerate(target) {\n    return new Enumerate(target);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js\":\n/*!*********************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js ***!\n  \\*********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\n$export($export.S, 'Reflect', {\n  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey) {\n    return gOPD.f(anObject(target), propertyKey);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.get-prototype-of.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.get-prototype-of.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.8 Reflect.getPrototypeOf(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar getProto = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\n$export($export.S, 'Reflect', {\n  getPrototypeOf: function getPrototypeOf(target) {\n    return getProto(anObject(target));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.get.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.get.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.6 Reflect.get(target, propertyKey [, receiver])\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\n\nfunction get(target, propertyKey /* , receiver */) {\n  var receiver = arguments.length < 3 ? target : arguments[2];\n  var desc, proto;\n  if (anObject(target) === receiver) return target[propertyKey];\n  if (desc = gOPD.f(target, propertyKey)) return has(desc, 'value')\n    ? desc.value\n    : desc.get !== undefined\n      ? desc.get.call(receiver)\n      : undefined;\n  if (isObject(proto = getPrototypeOf(target))) return get(proto, propertyKey, receiver);\n}\n\n$export($export.S, 'Reflect', { get: get });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.has.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.has.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.9 Reflect.has(target, propertyKey)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Reflect', {\n  has: function has(target, propertyKey) {\n    return propertyKey in target;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.is-extensible.js\":\n/*!*******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.is-extensible.js ***!\n  \\*******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.10 Reflect.isExtensible(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar $isExtensible = Object.isExtensible;\n\n$export($export.S, 'Reflect', {\n  isExtensible: function isExtensible(target) {\n    anObject(target);\n    return $isExtensible ? $isExtensible(target) : true;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.own-keys.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.own-keys.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.11 Reflect.ownKeys(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Reflect', { ownKeys: __webpack_require__(/*! ./_own-keys */ \"./node_modules/core-js/modules/_own-keys.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.prevent-extensions.js\":\n/*!************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.prevent-extensions.js ***!\n  \\************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.12 Reflect.preventExtensions(target)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar $preventExtensions = Object.preventExtensions;\n\n$export($export.S, 'Reflect', {\n  preventExtensions: function preventExtensions(target) {\n    anObject(target);\n    try {\n      if ($preventExtensions) $preventExtensions(target);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.set-prototype-of.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.set-prototype-of.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.14 Reflect.setPrototypeOf(target, proto)\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar setProto = __webpack_require__(/*! ./_set-proto */ \"./node_modules/core-js/modules/_set-proto.js\");\n\nif (setProto) $export($export.S, 'Reflect', {\n  setPrototypeOf: function setPrototypeOf(target, proto) {\n    setProto.check(target, proto);\n    try {\n      setProto.set(target, proto);\n      return true;\n    } catch (e) {\n      return false;\n    }\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.reflect.set.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.reflect.set.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\n\nfunction set(target, propertyKey, V /* , receiver */) {\n  var receiver = arguments.length < 4 ? target : arguments[3];\n  var ownDesc = gOPD.f(anObject(target), propertyKey);\n  var existingDescriptor, proto;\n  if (!ownDesc) {\n    if (isObject(proto = getPrototypeOf(target))) {\n      return set(proto, propertyKey, V, receiver);\n    }\n    ownDesc = createDesc(0);\n  }\n  if (has(ownDesc, 'value')) {\n    if (ownDesc.writable === false || !isObject(receiver)) return false;\n    if (existingDescriptor = gOPD.f(receiver, propertyKey)) {\n      if (existingDescriptor.get || existingDescriptor.set || existingDescriptor.writable === false) return false;\n      existingDescriptor.value = V;\n      dP.f(receiver, propertyKey, existingDescriptor);\n    } else dP.f(receiver, propertyKey, createDesc(0, V));\n    return true;\n  }\n  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);\n}\n\n$export($export.S, 'Reflect', { set: set });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.constructor.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.constructor.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar inheritIfRequired = __webpack_require__(/*! ./_inherit-if-required */ \"./node_modules/core-js/modules/_inherit-if-required.js\");\nvar dP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f;\nvar gOPN = __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f;\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar $flags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\nvar $RegExp = global.RegExp;\nvar Base = $RegExp;\nvar proto = $RegExp.prototype;\nvar re1 = /a/g;\nvar re2 = /a/g;\n// \"new\" creates a new object, old webkit buggy here\nvar CORRECT_NEW = new $RegExp(re1) !== re1;\n\nif (__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && (!CORRECT_NEW || __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  re2[__webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('match')] = false;\n  // RegExp constructor can alter flags and IsRegExp works correct with @@match\n  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';\n}))) {\n  $RegExp = function RegExp(p, f) {\n    var tiRE = this instanceof $RegExp;\n    var piRE = isRegExp(p);\n    var fiU = f === undefined;\n    return !tiRE && piRE && p.constructor === $RegExp && fiU ? p\n      : inheritIfRequired(CORRECT_NEW\n        ? new Base(piRE && !fiU ? p.source : p, f)\n        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)\n      , tiRE ? this : proto, $RegExp);\n  };\n  var proxy = function (key) {\n    key in $RegExp || dP($RegExp, key, {\n      configurable: true,\n      get: function () { return Base[key]; },\n      set: function (it) { Base[key] = it; }\n    });\n  };\n  for (var keys = gOPN(Base), i = 0; keys.length > i;) proxy(keys[i++]);\n  proto.constructor = $RegExp;\n  $RegExp.prototype = proto;\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(global, 'RegExp', $RegExp);\n}\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")('RegExp');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.exec.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.exec.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar regexpExec = __webpack_require__(/*! ./_regexp-exec */ \"./node_modules/core-js/modules/_regexp-exec.js\");\n__webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\")({\n  target: 'RegExp',\n  proto: true,\n  forced: regexpExec !== /./.exec\n}, {\n  exec: regexpExec\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.flags.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.flags.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// 21.2.5.3 get RegExp.prototype.flags()\nif (__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && /./g.flags != 'g') __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\").f(RegExp.prototype, 'flags', {\n  configurable: true,\n  get: __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\")\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.match.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.match.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar advanceStringIndex = __webpack_require__(/*! ./_advance-string-index */ \"./node_modules/core-js/modules/_advance-string-index.js\");\nvar regExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\n\n// @@match logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('match', 1, function (defined, MATCH, $match, maybeCallNative) {\n  return [\n    // `String.prototype.match` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.match\n    function match(regexp) {\n      var O = defined(this);\n      var fn = regexp == undefined ? undefined : regexp[MATCH];\n      return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));\n    },\n    // `RegExp.prototype[@@match]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@match\n    function (regexp) {\n      var res = maybeCallNative($match, regexp, this);\n      if (res.done) return res.value;\n      var rx = anObject(regexp);\n      var S = String(this);\n      if (!rx.global) return regExpExec(rx, S);\n      var fullUnicode = rx.unicode;\n      rx.lastIndex = 0;\n      var A = [];\n      var n = 0;\n      var result;\n      while ((result = regExpExec(rx, S)) !== null) {\n        var matchStr = String(result[0]);\n        A[n] = matchStr;\n        if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n        n++;\n      }\n      return n === 0 ? null : A;\n    }\n  ];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.replace.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.replace.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar advanceStringIndex = __webpack_require__(/*! ./_advance-string-index */ \"./node_modules/core-js/modules/_advance-string-index.js\");\nvar regExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\nvar max = Math.max;\nvar min = Math.min;\nvar floor = Math.floor;\nvar SUBSTITUTION_SYMBOLS = /\\$([$&`']|\\d\\d?|<[^>]*>)/g;\nvar SUBSTITUTION_SYMBOLS_NO_NAMED = /\\$([$&`']|\\d\\d?)/g;\n\nvar maybeToString = function (it) {\n  return it === undefined ? it : String(it);\n};\n\n// @@replace logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('replace', 2, function (defined, REPLACE, $replace, maybeCallNative) {\n  return [\n    // `String.prototype.replace` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.replace\n    function replace(searchValue, replaceValue) {\n      var O = defined(this);\n      var fn = searchValue == undefined ? undefined : searchValue[REPLACE];\n      return fn !== undefined\n        ? fn.call(searchValue, O, replaceValue)\n        : $replace.call(String(O), searchValue, replaceValue);\n    },\n    // `RegExp.prototype[@@replace]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@replace\n    function (regexp, replaceValue) {\n      var res = maybeCallNative($replace, regexp, this, replaceValue);\n      if (res.done) return res.value;\n\n      var rx = anObject(regexp);\n      var S = String(this);\n      var functionalReplace = typeof replaceValue === 'function';\n      if (!functionalReplace) replaceValue = String(replaceValue);\n      var global = rx.global;\n      if (global) {\n        var fullUnicode = rx.unicode;\n        rx.lastIndex = 0;\n      }\n      var results = [];\n      while (true) {\n        var result = regExpExec(rx, S);\n        if (result === null) break;\n        results.push(result);\n        if (!global) break;\n        var matchStr = String(result[0]);\n        if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);\n      }\n      var accumulatedResult = '';\n      var nextSourcePosition = 0;\n      for (var i = 0; i < results.length; i++) {\n        result = results[i];\n        var matched = String(result[0]);\n        var position = max(min(toInteger(result.index), S.length), 0);\n        var captures = [];\n        // NOTE: This is equivalent to\n        //   captures = result.slice(1).map(maybeToString)\n        // but for some reason `nativeSlice.call(result, 1, result.length)` (called in\n        // the slice polyfill when slicing native arrays) \"doesn't work\" in safari 9 and\n        // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.\n        for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));\n        var namedCaptures = result.groups;\n        if (functionalReplace) {\n          var replacerArgs = [matched].concat(captures, position, S);\n          if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);\n          var replacement = String(replaceValue.apply(undefined, replacerArgs));\n        } else {\n          replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);\n        }\n        if (position >= nextSourcePosition) {\n          accumulatedResult += S.slice(nextSourcePosition, position) + replacement;\n          nextSourcePosition = position + matched.length;\n        }\n      }\n      return accumulatedResult + S.slice(nextSourcePosition);\n    }\n  ];\n\n    // https://tc39.github.io/ecma262/#sec-getsubstitution\n  function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {\n    var tailPos = position + matched.length;\n    var m = captures.length;\n    var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;\n    if (namedCaptures !== undefined) {\n      namedCaptures = toObject(namedCaptures);\n      symbols = SUBSTITUTION_SYMBOLS;\n    }\n    return $replace.call(replacement, symbols, function (match, ch) {\n      var capture;\n      switch (ch.charAt(0)) {\n        case '$': return '$';\n        case '&': return matched;\n        case '`': return str.slice(0, position);\n        case \"'\": return str.slice(tailPos);\n        case '<':\n          capture = namedCaptures[ch.slice(1, -1)];\n          break;\n        default: // \\d\\d?\n          var n = +ch;\n          if (n === 0) return match;\n          if (n > m) {\n            var f = floor(n / 10);\n            if (f === 0) return match;\n            if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);\n            return match;\n          }\n          capture = captures[n - 1];\n      }\n      return capture === undefined ? '' : capture;\n    });\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.search.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.search.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar sameValue = __webpack_require__(/*! ./_same-value */ \"./node_modules/core-js/modules/_same-value.js\");\nvar regExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\n\n// @@search logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('search', 1, function (defined, SEARCH, $search, maybeCallNative) {\n  return [\n    // `String.prototype.search` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.search\n    function search(regexp) {\n      var O = defined(this);\n      var fn = regexp == undefined ? undefined : regexp[SEARCH];\n      return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));\n    },\n    // `RegExp.prototype[@@search]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@search\n    function (regexp) {\n      var res = maybeCallNative($search, regexp, this);\n      if (res.done) return res.value;\n      var rx = anObject(regexp);\n      var S = String(this);\n      var previousLastIndex = rx.lastIndex;\n      if (!sameValue(previousLastIndex, 0)) rx.lastIndex = 0;\n      var result = regExpExec(rx, S);\n      if (!sameValue(rx.lastIndex, previousLastIndex)) rx.lastIndex = previousLastIndex;\n      return result === null ? -1 : result.index;\n    }\n  ];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.split.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.split.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar advanceStringIndex = __webpack_require__(/*! ./_advance-string-index */ \"./node_modules/core-js/modules/_advance-string-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar callRegExpExec = __webpack_require__(/*! ./_regexp-exec-abstract */ \"./node_modules/core-js/modules/_regexp-exec-abstract.js\");\nvar regexpExec = __webpack_require__(/*! ./_regexp-exec */ \"./node_modules/core-js/modules/_regexp-exec.js\");\nvar fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar $min = Math.min;\nvar $push = [].push;\nvar $SPLIT = 'split';\nvar LENGTH = 'length';\nvar LAST_INDEX = 'lastIndex';\nvar MAX_UINT32 = 0xffffffff;\n\n// babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError\nvar SUPPORTS_Y = !fails(function () { RegExp(MAX_UINT32, 'y'); });\n\n// @@split logic\n__webpack_require__(/*! ./_fix-re-wks */ \"./node_modules/core-js/modules/_fix-re-wks.js\")('split', 2, function (defined, SPLIT, $split, maybeCallNative) {\n  var internalSplit;\n  if (\n    'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||\n    'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||\n    'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||\n    '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||\n    '.'[$SPLIT](/()()/)[LENGTH] > 1 ||\n    ''[$SPLIT](/.?/)[LENGTH]\n  ) {\n    // based on es5-shim implementation, need to rework it\n    internalSplit = function (separator, limit) {\n      var string = String(this);\n      if (separator === undefined && limit === 0) return [];\n      // If `separator` is not a regex, use native split\n      if (!isRegExp(separator)) return $split.call(string, separator, limit);\n      var output = [];\n      var flags = (separator.ignoreCase ? 'i' : '') +\n                  (separator.multiline ? 'm' : '') +\n                  (separator.unicode ? 'u' : '') +\n                  (separator.sticky ? 'y' : '');\n      var lastLastIndex = 0;\n      var splitLimit = limit === undefined ? MAX_UINT32 : limit >>> 0;\n      // Make `global` and avoid `lastIndex` issues by working with a copy\n      var separatorCopy = new RegExp(separator.source, flags + 'g');\n      var match, lastIndex, lastLength;\n      while (match = regexpExec.call(separatorCopy, string)) {\n        lastIndex = separatorCopy[LAST_INDEX];\n        if (lastIndex > lastLastIndex) {\n          output.push(string.slice(lastLastIndex, match.index));\n          if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));\n          lastLength = match[0][LENGTH];\n          lastLastIndex = lastIndex;\n          if (output[LENGTH] >= splitLimit) break;\n        }\n        if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop\n      }\n      if (lastLastIndex === string[LENGTH]) {\n        if (lastLength || !separatorCopy.test('')) output.push('');\n      } else output.push(string.slice(lastLastIndex));\n      return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;\n    };\n  // Chakra, V8\n  } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {\n    internalSplit = function (separator, limit) {\n      return separator === undefined && limit === 0 ? [] : $split.call(this, separator, limit);\n    };\n  } else {\n    internalSplit = $split;\n  }\n\n  return [\n    // `String.prototype.split` method\n    // https://tc39.github.io/ecma262/#sec-string.prototype.split\n    function split(separator, limit) {\n      var O = defined(this);\n      var splitter = separator == undefined ? undefined : separator[SPLIT];\n      return splitter !== undefined\n        ? splitter.call(separator, O, limit)\n        : internalSplit.call(String(O), separator, limit);\n    },\n    // `RegExp.prototype[@@split]` method\n    // https://tc39.github.io/ecma262/#sec-regexp.prototype-@@split\n    //\n    // NOTE: This cannot be properly polyfilled in engines that don't support\n    // the 'y' flag.\n    function (regexp, limit) {\n      var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== $split);\n      if (res.done) return res.value;\n\n      var rx = anObject(regexp);\n      var S = String(this);\n      var C = speciesConstructor(rx, RegExp);\n\n      var unicodeMatching = rx.unicode;\n      var flags = (rx.ignoreCase ? 'i' : '') +\n                  (rx.multiline ? 'm' : '') +\n                  (rx.unicode ? 'u' : '') +\n                  (SUPPORTS_Y ? 'y' : 'g');\n\n      // ^(? + rx + ) is needed, in combination with some S slicing, to\n      // simulate the 'y' flag.\n      var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);\n      var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;\n      if (lim === 0) return [];\n      if (S.length === 0) return callRegExpExec(splitter, S) === null ? [S] : [];\n      var p = 0;\n      var q = 0;\n      var A = [];\n      while (q < S.length) {\n        splitter.lastIndex = SUPPORTS_Y ? q : 0;\n        var z = callRegExpExec(splitter, SUPPORTS_Y ? S : S.slice(q));\n        var e;\n        if (\n          z === null ||\n          (e = $min(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p\n        ) {\n          q = advanceStringIndex(S, q, unicodeMatching);\n        } else {\n          A.push(S.slice(p, q));\n          if (A.length === lim) return A;\n          for (var i = 1; i <= z.length - 1; i++) {\n            A.push(z[i]);\n            if (A.length === lim) return A;\n          }\n          q = p = e;\n        }\n      }\n      A.push(S.slice(p));\n      return A;\n    }\n  ];\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.regexp.to-string.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.regexp.to-string.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n__webpack_require__(/*! ./es6.regexp.flags */ \"./node_modules/core-js/modules/es6.regexp.flags.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar $flags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar TO_STRING = 'toString';\nvar $toString = /./[TO_STRING];\n\nvar define = function (fn) {\n  __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\")(RegExp.prototype, TO_STRING, fn, true);\n};\n\n// 21.2.5.14 RegExp.prototype.toString()\nif (__webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () { return $toString.call({ source: 'a', flags: 'b' }) != '/a/b'; })) {\n  define(function toString() {\n    var R = anObject(this);\n    return '/'.concat(R.source, '/',\n      'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);\n  });\n// FF44- RegExp#toString has a wrong name\n} else if ($toString.name != TO_STRING) {\n  define(function toString() {\n    return $toString.call(this);\n  });\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.set.js\":\n/*!*************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.set.js ***!\n  \\*************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar strong = __webpack_require__(/*! ./_collection-strong */ \"./node_modules/core-js/modules/_collection-strong.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar SET = 'Set';\n\n// 23.2 Set Objects\nmodule.exports = __webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(SET, function (get) {\n  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.2.3.1 Set.prototype.add(value)\n  add: function add(value) {\n    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);\n  }\n}, strong);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.anchor.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.anchor.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.2 String.prototype.anchor(name)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('anchor', function (createHTML) {\n  return function anchor(name) {\n    return createHTML(this, 'a', 'name', name);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.big.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.big.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.3 String.prototype.big()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('big', function (createHTML) {\n  return function big() {\n    return createHTML(this, 'big', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.blink.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.blink.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.4 String.prototype.blink()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('blink', function (createHTML) {\n  return function blink() {\n    return createHTML(this, 'blink', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.bold.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.bold.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.5 String.prototype.bold()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('bold', function (createHTML) {\n  return function bold() {\n    return createHTML(this, 'b', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.code-point-at.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.code-point-at.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(false);\n$export($export.P, 'String', {\n  // 21.1.3.3 String.prototype.codePointAt(pos)\n  codePointAt: function codePointAt(pos) {\n    return $at(this, pos);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.ends-with.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.ends-with.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar context = __webpack_require__(/*! ./_string-context */ \"./node_modules/core-js/modules/_string-context.js\");\nvar ENDS_WITH = 'endsWith';\nvar $endsWith = ''[ENDS_WITH];\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ \"./node_modules/core-js/modules/_fails-is-regexp.js\")(ENDS_WITH), 'String', {\n  endsWith: function endsWith(searchString /* , endPosition = @length */) {\n    var that = context(this, searchString, ENDS_WITH);\n    var endPosition = arguments.length > 1 ? arguments[1] : undefined;\n    var len = toLength(that.length);\n    var end = endPosition === undefined ? len : Math.min(toLength(endPosition), len);\n    var search = String(searchString);\n    return $endsWith\n      ? $endsWith.call(that, search, end)\n      : that.slice(end - search.length, end) === search;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.fixed.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.fixed.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.6 String.prototype.fixed()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('fixed', function (createHTML) {\n  return function fixed() {\n    return createHTML(this, 'tt', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.fontcolor.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.fontcolor.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.7 String.prototype.fontcolor(color)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('fontcolor', function (createHTML) {\n  return function fontcolor(color) {\n    return createHTML(this, 'font', 'color', color);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.fontsize.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.fontsize.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.8 String.prototype.fontsize(size)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('fontsize', function (createHTML) {\n  return function fontsize(size) {\n    return createHTML(this, 'font', 'size', size);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.from-code-point.js\":\n/*!********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.from-code-point.js ***!\n  \\********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar fromCharCode = String.fromCharCode;\nvar $fromCodePoint = String.fromCodePoint;\n\n// length should be 1, old FF problem\n$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {\n  // 21.1.2.2 String.fromCodePoint(...codePoints)\n  fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars\n    var res = [];\n    var aLen = arguments.length;\n    var i = 0;\n    var code;\n    while (aLen > i) {\n      code = +arguments[i++];\n      if (toAbsoluteIndex(code, 0x10ffff) !== code) throw RangeError(code + ' is not a valid code point');\n      res.push(code < 0x10000\n        ? fromCharCode(code)\n        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)\n      );\n    } return res.join('');\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.includes.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.includes.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 21.1.3.7 String.prototype.includes(searchString, position = 0)\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar context = __webpack_require__(/*! ./_string-context */ \"./node_modules/core-js/modules/_string-context.js\");\nvar INCLUDES = 'includes';\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ \"./node_modules/core-js/modules/_fails-is-regexp.js\")(INCLUDES), 'String', {\n  includes: function includes(searchString /* , position = 0 */) {\n    return !!~context(this, searchString, INCLUDES)\n      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.italics.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.italics.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.9 String.prototype.italics()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('italics', function (createHTML) {\n  return function italics() {\n    return createHTML(this, 'i', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.iterator.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.iterator.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\n__webpack_require__(/*! ./_iter-define */ \"./node_modules/core-js/modules/_iter-define.js\")(String, 'String', function (iterated) {\n  this._t = String(iterated); // target\n  this._i = 0;                // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n  var O = this._t;\n  var index = this._i;\n  var point;\n  if (index >= O.length) return { value: undefined, done: true };\n  point = $at(O, index);\n  this._i += point.length;\n  return { value: point, done: false };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.link.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.link.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.10 String.prototype.link(url)\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('link', function (createHTML) {\n  return function link(url) {\n    return createHTML(this, 'a', 'href', url);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.raw.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.raw.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\n\n$export($export.S, 'String', {\n  // 21.1.2.4 String.raw(callSite, ...substitutions)\n  raw: function raw(callSite) {\n    var tpl = toIObject(callSite.raw);\n    var len = toLength(tpl.length);\n    var aLen = arguments.length;\n    var res = [];\n    var i = 0;\n    while (len > i) {\n      res.push(String(tpl[i++]));\n      if (i < aLen) res.push(String(arguments[i]));\n    } return res.join('');\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.repeat.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.repeat.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P, 'String', {\n  // 21.1.3.13 String.prototype.repeat(count)\n  repeat: __webpack_require__(/*! ./_string-repeat */ \"./node_modules/core-js/modules/_string-repeat.js\")\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.small.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.small.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.11 String.prototype.small()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('small', function (createHTML) {\n  return function small() {\n    return createHTML(this, 'small', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.starts-with.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.starts-with.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// 21.1.3.18 String.prototype.startsWith(searchString [, position ])\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar context = __webpack_require__(/*! ./_string-context */ \"./node_modules/core-js/modules/_string-context.js\");\nvar STARTS_WITH = 'startsWith';\nvar $startsWith = ''[STARTS_WITH];\n\n$export($export.P + $export.F * __webpack_require__(/*! ./_fails-is-regexp */ \"./node_modules/core-js/modules/_fails-is-regexp.js\")(STARTS_WITH), 'String', {\n  startsWith: function startsWith(searchString /* , position = 0 */) {\n    var that = context(this, searchString, STARTS_WITH);\n    var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length));\n    var search = String(searchString);\n    return $startsWith\n      ? $startsWith.call(that, search, index)\n      : that.slice(index, index + search.length) === search;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.strike.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.strike.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.12 String.prototype.strike()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('strike', function (createHTML) {\n  return function strike() {\n    return createHTML(this, 'strike', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.sub.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.sub.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.13 String.prototype.sub()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('sub', function (createHTML) {\n  return function sub() {\n    return createHTML(this, 'sub', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.sup.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.sup.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// B.2.3.14 String.prototype.sup()\n__webpack_require__(/*! ./_string-html */ \"./node_modules/core-js/modules/_string-html.js\")('sup', function (createHTML) {\n  return function sup() {\n    return createHTML(this, 'sup', '', '');\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.string.trim.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.string.trim.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// 21.1.3.25 String.prototype.trim()\n__webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\")('trim', function ($trim) {\n  return function trim() {\n    return $trim(this, 3);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.symbol.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.symbol.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// ECMAScript 6 symbols shim\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar has = __webpack_require__(/*! ./_has */ \"./node_modules/core-js/modules/_has.js\");\nvar DESCRIPTORS = __webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar META = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\").KEY;\nvar $fails = __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\");\nvar shared = __webpack_require__(/*! ./_shared */ \"./node_modules/core-js/modules/_shared.js\");\nvar setToStringTag = __webpack_require__(/*! ./_set-to-string-tag */ \"./node_modules/core-js/modules/_set-to-string-tag.js\");\nvar uid = __webpack_require__(/*! ./_uid */ \"./node_modules/core-js/modules/_uid.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar wksExt = __webpack_require__(/*! ./_wks-ext */ \"./node_modules/core-js/modules/_wks-ext.js\");\nvar wksDefine = __webpack_require__(/*! ./_wks-define */ \"./node_modules/core-js/modules/_wks-define.js\");\nvar enumKeys = __webpack_require__(/*! ./_enum-keys */ \"./node_modules/core-js/modules/_enum-keys.js\");\nvar isArray = __webpack_require__(/*! ./_is-array */ \"./node_modules/core-js/modules/_is-array.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar createDesc = __webpack_require__(/*! ./_property-desc */ \"./node_modules/core-js/modules/_property-desc.js\");\nvar _create = __webpack_require__(/*! ./_object-create */ \"./node_modules/core-js/modules/_object-create.js\");\nvar gOPNExt = __webpack_require__(/*! ./_object-gopn-ext */ \"./node_modules/core-js/modules/_object-gopn-ext.js\");\nvar $GOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar $DP = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\nvar $keys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar gOPD = $GOPD.f;\nvar dP = $DP.f;\nvar gOPN = gOPNExt.f;\nvar $Symbol = global.Symbol;\nvar $JSON = global.JSON;\nvar _stringify = $JSON && $JSON.stringify;\nvar PROTOTYPE = 'prototype';\nvar HIDDEN = wks('_hidden');\nvar TO_PRIMITIVE = wks('toPrimitive');\nvar isEnum = {}.propertyIsEnumerable;\nvar SymbolRegistry = shared('symbol-registry');\nvar AllSymbols = shared('symbols');\nvar OPSymbols = shared('op-symbols');\nvar ObjectProto = Object[PROTOTYPE];\nvar USE_NATIVE = typeof $Symbol == 'function';\nvar QObject = global.QObject;\n// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173\nvar setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;\n\n// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687\nvar setSymbolDesc = DESCRIPTORS && $fails(function () {\n  return _create(dP({}, 'a', {\n    get: function () { return dP(this, 'a', { value: 7 }).a; }\n  })).a != 7;\n}) ? function (it, key, D) {\n  var protoDesc = gOPD(ObjectProto, key);\n  if (protoDesc) delete ObjectProto[key];\n  dP(it, key, D);\n  if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc);\n} : dP;\n\nvar wrap = function (tag) {\n  var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);\n  sym._k = tag;\n  return sym;\n};\n\nvar isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) {\n  return typeof it == 'symbol';\n} : function (it) {\n  return it instanceof $Symbol;\n};\n\nvar $defineProperty = function defineProperty(it, key, D) {\n  if (it === ObjectProto) $defineProperty(OPSymbols, key, D);\n  anObject(it);\n  key = toPrimitive(key, true);\n  anObject(D);\n  if (has(AllSymbols, key)) {\n    if (!D.enumerable) {\n      if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {}));\n      it[HIDDEN][key] = true;\n    } else {\n      if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;\n      D = _create(D, { enumerable: createDesc(0, false) });\n    } return setSymbolDesc(it, key, D);\n  } return dP(it, key, D);\n};\nvar $defineProperties = function defineProperties(it, P) {\n  anObject(it);\n  var keys = enumKeys(P = toIObject(P));\n  var i = 0;\n  var l = keys.length;\n  var key;\n  while (l > i) $defineProperty(it, key = keys[i++], P[key]);\n  return it;\n};\nvar $create = function create(it, P) {\n  return P === undefined ? _create(it) : $defineProperties(_create(it), P);\n};\nvar $propertyIsEnumerable = function propertyIsEnumerable(key) {\n  var E = isEnum.call(this, key = toPrimitive(key, true));\n  if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false;\n  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;\n};\nvar $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) {\n  it = toIObject(it);\n  key = toPrimitive(key, true);\n  if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return;\n  var D = gOPD(it, key);\n  if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true;\n  return D;\n};\nvar $getOwnPropertyNames = function getOwnPropertyNames(it) {\n  var names = gOPN(toIObject(it));\n  var result = [];\n  var i = 0;\n  var key;\n  while (names.length > i) {\n    if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key);\n  } return result;\n};\nvar $getOwnPropertySymbols = function getOwnPropertySymbols(it) {\n  var IS_OP = it === ObjectProto;\n  var names = gOPN(IS_OP ? OPSymbols : toIObject(it));\n  var result = [];\n  var i = 0;\n  var key;\n  while (names.length > i) {\n    if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]);\n  } return result;\n};\n\n// 19.4.1.1 Symbol([description])\nif (!USE_NATIVE) {\n  $Symbol = function Symbol() {\n    if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!');\n    var tag = uid(arguments.length > 0 ? arguments[0] : undefined);\n    var $set = function (value) {\n      if (this === ObjectProto) $set.call(OPSymbols, value);\n      if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;\n      setSymbolDesc(this, tag, createDesc(1, value));\n    };\n    if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set });\n    return wrap(tag);\n  };\n  redefine($Symbol[PROTOTYPE], 'toString', function toString() {\n    return this._k;\n  });\n\n  $GOPD.f = $getOwnPropertyDescriptor;\n  $DP.f = $defineProperty;\n  __webpack_require__(/*! ./_object-gopn */ \"./node_modules/core-js/modules/_object-gopn.js\").f = gOPNExt.f = $getOwnPropertyNames;\n  __webpack_require__(/*! ./_object-pie */ \"./node_modules/core-js/modules/_object-pie.js\").f = $propertyIsEnumerable;\n  __webpack_require__(/*! ./_object-gops */ \"./node_modules/core-js/modules/_object-gops.js\").f = $getOwnPropertySymbols;\n\n  if (DESCRIPTORS && !__webpack_require__(/*! ./_library */ \"./node_modules/core-js/modules/_library.js\")) {\n    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);\n  }\n\n  wksExt.f = function (name) {\n    return wrap(wks(name));\n  };\n}\n\n$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol });\n\nfor (var es6Symbols = (\n  // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14\n  'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'\n).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]);\n\nfor (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]);\n\n$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {\n  // 19.4.2.1 Symbol.for(key)\n  'for': function (key) {\n    return has(SymbolRegistry, key += '')\n      ? SymbolRegistry[key]\n      : SymbolRegistry[key] = $Symbol(key);\n  },\n  // 19.4.2.5 Symbol.keyFor(sym)\n  keyFor: function keyFor(sym) {\n    if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!');\n    for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key;\n  },\n  useSetter: function () { setter = true; },\n  useSimple: function () { setter = false; }\n});\n\n$export($export.S + $export.F * !USE_NATIVE, 'Object', {\n  // 19.1.2.2 Object.create(O [, Properties])\n  create: $create,\n  // 19.1.2.4 Object.defineProperty(O, P, Attributes)\n  defineProperty: $defineProperty,\n  // 19.1.2.3 Object.defineProperties(O, Properties)\n  defineProperties: $defineProperties,\n  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)\n  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,\n  // 19.1.2.7 Object.getOwnPropertyNames(O)\n  getOwnPropertyNames: $getOwnPropertyNames,\n  // 19.1.2.8 Object.getOwnPropertySymbols(O)\n  getOwnPropertySymbols: $getOwnPropertySymbols\n});\n\n// 24.3.2 JSON.stringify(value [, replacer [, space]])\n$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () {\n  var S = $Symbol();\n  // MS Edge converts symbol values to JSON as {}\n  // WebKit converts symbol values to JSON as null\n  // V8 throws on boxed symbols\n  return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}';\n})), 'JSON', {\n  stringify: function stringify(it) {\n    var args = [it];\n    var i = 1;\n    var replacer, $replacer;\n    while (arguments.length > i) args.push(arguments[i++]);\n    $replacer = replacer = args[1];\n    if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined\n    if (!isArray(replacer)) replacer = function (key, value) {\n      if (typeof $replacer == 'function') value = $replacer.call(this, key, value);\n      if (!isSymbol(value)) return value;\n    };\n    args[1] = replacer;\n    return _stringify.apply($JSON, args);\n  }\n});\n\n// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)\n$Symbol[PROTOTYPE][TO_PRIMITIVE] || __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\")($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);\n// 19.4.3.5 Symbol.prototype[@@toStringTag]\nsetToStringTag($Symbol, 'Symbol');\n// 20.2.1.9 Math[@@toStringTag]\nsetToStringTag(Math, 'Math', true);\n// 24.3.3 JSON[@@toStringTag]\nsetToStringTag(global.JSON, 'JSON', true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.array-buffer.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.array-buffer.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $typed = __webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\");\nvar buffer = __webpack_require__(/*! ./_typed-buffer */ \"./node_modules/core-js/modules/_typed-buffer.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toAbsoluteIndex = __webpack_require__(/*! ./_to-absolute-index */ \"./node_modules/core-js/modules/_to-absolute-index.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar ArrayBuffer = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").ArrayBuffer;\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar $ArrayBuffer = buffer.ArrayBuffer;\nvar $DataView = buffer.DataView;\nvar $isView = $typed.ABV && ArrayBuffer.isView;\nvar $slice = $ArrayBuffer.prototype.slice;\nvar VIEW = $typed.VIEW;\nvar ARRAY_BUFFER = 'ArrayBuffer';\n\n$export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), { ArrayBuffer: $ArrayBuffer });\n\n$export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, {\n  // 24.1.3.1 ArrayBuffer.isView(arg)\n  isView: function isView(it) {\n    return $isView && $isView(it) || isObject(it) && VIEW in it;\n  }\n});\n\n$export($export.P + $export.U + $export.F * __webpack_require__(/*! ./_fails */ \"./node_modules/core-js/modules/_fails.js\")(function () {\n  return !new $ArrayBuffer(2).slice(1, undefined).byteLength;\n}), ARRAY_BUFFER, {\n  // 24.1.4.3 ArrayBuffer.prototype.slice(start, end)\n  slice: function slice(start, end) {\n    if ($slice !== undefined && end === undefined) return $slice.call(anObject(this), start); // FF fix\n    var len = anObject(this).byteLength;\n    var first = toAbsoluteIndex(start, len);\n    var fin = toAbsoluteIndex(end === undefined ? len : end, len);\n    var result = new (speciesConstructor(this, $ArrayBuffer))(toLength(fin - first));\n    var viewS = new $DataView(this);\n    var viewT = new $DataView(result);\n    var index = 0;\n    while (first < fin) {\n      viewT.setUint8(index++, viewS.getUint8(first++));\n    } return result;\n  }\n});\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")(ARRAY_BUFFER);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.data-view.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.data-view.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n$export($export.G + $export.W + $export.F * !__webpack_require__(/*! ./_typed */ \"./node_modules/core-js/modules/_typed.js\").ABV, {\n  DataView: __webpack_require__(/*! ./_typed-buffer */ \"./node_modules/core-js/modules/_typed-buffer.js\").DataView\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.float32-array.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.float32-array.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Float32', 4, function (init) {\n  return function Float32Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.float64-array.js\":\n/*!*****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.float64-array.js ***!\n  \\*****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Float64', 8, function (init) {\n  return function Float64Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.int16-array.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.int16-array.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Int16', 2, function (init) {\n  return function Int16Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.int32-array.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.int32-array.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Int32', 4, function (init) {\n  return function Int32Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.int8-array.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.int8-array.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Int8', 1, function (init) {\n  return function Int8Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint16-array.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint16-array.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint16', 2, function (init) {\n  return function Uint16Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint32-array.js\":\n/*!****************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint32-array.js ***!\n  \\****************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint32', 4, function (init) {\n  return function Uint32Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint8-array.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint8-array.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint8', 1, function (init) {\n  return function Uint8Array(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js\":\n/*!***********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js ***!\n  \\***********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_typed-array */ \"./node_modules/core-js/modules/_typed-array.js\")('Uint8', 1, function (init) {\n  return function Uint8ClampedArray(data, byteOffset, length) {\n    return init(this, data, byteOffset, length);\n  };\n}, true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.weak-map.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.weak-map.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar each = __webpack_require__(/*! ./_array-methods */ \"./node_modules/core-js/modules/_array-methods.js\")(0);\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar meta = __webpack_require__(/*! ./_meta */ \"./node_modules/core-js/modules/_meta.js\");\nvar assign = __webpack_require__(/*! ./_object-assign */ \"./node_modules/core-js/modules/_object-assign.js\");\nvar weak = __webpack_require__(/*! ./_collection-weak */ \"./node_modules/core-js/modules/_collection-weak.js\");\nvar isObject = __webpack_require__(/*! ./_is-object */ \"./node_modules/core-js/modules/_is-object.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar NATIVE_WEAK_MAP = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar IS_IE11 = !global.ActiveXObject && 'ActiveXObject' in global;\nvar WEAK_MAP = 'WeakMap';\nvar getWeak = meta.getWeak;\nvar isExtensible = Object.isExtensible;\nvar uncaughtFrozenStore = weak.ufstore;\nvar InternalMap;\n\nvar wrapper = function (get) {\n  return function WeakMap() {\n    return get(this, arguments.length > 0 ? arguments[0] : undefined);\n  };\n};\n\nvar methods = {\n  // 23.3.3.3 WeakMap.prototype.get(key)\n  get: function get(key) {\n    if (isObject(key)) {\n      var data = getWeak(key);\n      if (data === true) return uncaughtFrozenStore(validate(this, WEAK_MAP)).get(key);\n      return data ? data[this._i] : undefined;\n    }\n  },\n  // 23.3.3.5 WeakMap.prototype.set(key, value)\n  set: function set(key, value) {\n    return weak.def(validate(this, WEAK_MAP), key, value);\n  }\n};\n\n// 23.3 WeakMap Objects\nvar $WeakMap = module.exports = __webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(WEAK_MAP, wrapper, methods, weak, true, true);\n\n// IE11 WeakMap frozen keys fix\nif (NATIVE_WEAK_MAP && IS_IE11) {\n  InternalMap = weak.getConstructor(wrapper, WEAK_MAP);\n  assign(InternalMap.prototype, methods);\n  meta.NEED = true;\n  each(['delete', 'has', 'get', 'set'], function (key) {\n    var proto = $WeakMap.prototype;\n    var method = proto[key];\n    redefine(proto, key, function (a, b) {\n      // store frozen objects on internal weakmap shim\n      if (isObject(a) && !isExtensible(a)) {\n        if (!this._f) this._f = new InternalMap();\n        var result = this._f[key](a, b);\n        return key == 'set' ? this : result;\n      // store all the rest on native weakmap\n      } return method.call(this, a, b);\n    });\n  });\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es6.weak-set.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es6.weak-set.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar weak = __webpack_require__(/*! ./_collection-weak */ \"./node_modules/core-js/modules/_collection-weak.js\");\nvar validate = __webpack_require__(/*! ./_validate-collection */ \"./node_modules/core-js/modules/_validate-collection.js\");\nvar WEAK_SET = 'WeakSet';\n\n// 23.4 WeakSet Objects\n__webpack_require__(/*! ./_collection */ \"./node_modules/core-js/modules/_collection.js\")(WEAK_SET, function (get) {\n  return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };\n}, {\n  // 23.4.3.1 WeakSet.prototype.add(value)\n  add: function add(value) {\n    return weak.def(validate(this, WEAK_SET), value, true);\n  }\n}, weak, false, true);\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.array.flat-map.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.array.flat-map.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatMap\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar flattenIntoArray = __webpack_require__(/*! ./_flatten-into-array */ \"./node_modules/core-js/modules/_flatten-into-array.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar arraySpeciesCreate = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\n\n$export($export.P, 'Array', {\n  flatMap: function flatMap(callbackfn /* , thisArg */) {\n    var O = toObject(this);\n    var sourceLen, A;\n    aFunction(callbackfn);\n    sourceLen = toLength(O.length);\n    A = arraySpeciesCreate(O, 0);\n    flattenIntoArray(A, O, O, sourceLen, 0, 1, callbackfn, arguments[1]);\n    return A;\n  }\n});\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('flatMap');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.array.flatten.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.array.flatten.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/proposal-flatMap/#sec-Array.prototype.flatten\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar flattenIntoArray = __webpack_require__(/*! ./_flatten-into-array */ \"./node_modules/core-js/modules/_flatten-into-array.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar toInteger = __webpack_require__(/*! ./_to-integer */ \"./node_modules/core-js/modules/_to-integer.js\");\nvar arraySpeciesCreate = __webpack_require__(/*! ./_array-species-create */ \"./node_modules/core-js/modules/_array-species-create.js\");\n\n$export($export.P, 'Array', {\n  flatten: function flatten(/* depthArg = 1 */) {\n    var depthArg = arguments[0];\n    var O = toObject(this);\n    var sourceLen = toLength(O.length);\n    var A = arraySpeciesCreate(O, 0);\n    flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toInteger(depthArg));\n    return A;\n  }\n});\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('flatten');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.array.includes.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.array.includes.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/Array.prototype.includes\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $includes = __webpack_require__(/*! ./_array-includes */ \"./node_modules/core-js/modules/_array-includes.js\")(true);\n\n$export($export.P, 'Array', {\n  includes: function includes(el /* , fromIndex = 0 */) {\n    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);\n  }\n});\n\n__webpack_require__(/*! ./_add-to-unscopables */ \"./node_modules/core-js/modules/_add-to-unscopables.js\")('includes');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.asap.js\":\n/*!**************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.asap.js ***!\n  \\**************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar process = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\").process;\nvar isNode = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\")(process) == 'process';\n\n$export($export.G, {\n  asap: function asap(fn) {\n    var domain = isNode && process.domain;\n    microtask(domain ? domain.bind(fn) : fn);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.error.is-error.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.error.is-error.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/ljharb/proposal-is-error\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar cof = __webpack_require__(/*! ./_cof */ \"./node_modules/core-js/modules/_cof.js\");\n\n$export($export.S, 'Error', {\n  isError: function isError(it) {\n    return cof(it) === 'Error';\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.global.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.global.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-global\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.G, { global: __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.map.from.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.map.from.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-map.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('Map');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.map.of.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.map.of.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-map.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('Map');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.map.to-json.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.map.to-json.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P + $export.R, 'Map', { toJSON: __webpack_require__(/*! ./_collection-to-json */ \"./node_modules/core-js/modules/_collection-to-json.js\")('Map') });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.clamp.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.clamp.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  clamp: function clamp(x, lower, upper) {\n    return Math.min(upper, Math.max(lower, x));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.deg-per-rad.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.deg-per-rad.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { DEG_PER_RAD: Math.PI / 180 });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.degrees.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.degrees.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar RAD_PER_DEG = 180 / Math.PI;\n\n$export($export.S, 'Math', {\n  degrees: function degrees(radians) {\n    return radians * RAD_PER_DEG;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.fscale.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.fscale.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar scale = __webpack_require__(/*! ./_math-scale */ \"./node_modules/core-js/modules/_math-scale.js\");\nvar fround = __webpack_require__(/*! ./_math-fround */ \"./node_modules/core-js/modules/_math-fround.js\");\n\n$export($export.S, 'Math', {\n  fscale: function fscale(x, inLow, inHigh, outLow, outHigh) {\n    return fround(scale(x, inLow, inHigh, outLow, outHigh));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.iaddh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.iaddh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  iaddh: function iaddh(x0, x1, y0, y1) {\n    var $x0 = x0 >>> 0;\n    var $x1 = x1 >>> 0;\n    var $y0 = y0 >>> 0;\n    return $x1 + (y1 >>> 0) + (($x0 & $y0 | ($x0 | $y0) & ~($x0 + $y0 >>> 0)) >>> 31) | 0;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.imulh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.imulh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  imulh: function imulh(u, v) {\n    var UINT16 = 0xffff;\n    var $u = +u;\n    var $v = +v;\n    var u0 = $u & UINT16;\n    var v0 = $v & UINT16;\n    var u1 = $u >> 16;\n    var v1 = $v >> 16;\n    var t = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);\n    return u1 * v1 + (t >> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >> 16);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.isubh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.isubh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  isubh: function isubh(x0, x1, y0, y1) {\n    var $x0 = x0 >>> 0;\n    var $x1 = x1 >>> 0;\n    var $y0 = y0 >>> 0;\n    return $x1 - (y1 >>> 0) - ((~$x0 & $y0 | ~($x0 ^ $y0) & $x0 - $y0 >>> 0) >>> 31) | 0;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.rad-per-deg.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.rad-per-deg.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { RAD_PER_DEG: 180 / Math.PI });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.radians.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.radians.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar DEG_PER_RAD = Math.PI / 180;\n\n$export($export.S, 'Math', {\n  radians: function radians(degrees) {\n    return degrees * DEG_PER_RAD;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.scale.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.scale.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://rwaldron.github.io/proposal-math-extensions/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { scale: __webpack_require__(/*! ./_math-scale */ \"./node_modules/core-js/modules/_math-scale.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.signbit.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.signbit.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// http://jfbastien.github.io/papers/Math.signbit.html\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', { signbit: function signbit(x) {\n  // eslint-disable-next-line no-self-compare\n  return (x = +x) != x ? x : x == 0 ? 1 / x == Infinity : x > 0;\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.math.umulh.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.math.umulh.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://gist.github.com/BrendanEich/4294d5c212a6d2254703\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'Math', {\n  umulh: function umulh(u, v) {\n    var UINT16 = 0xffff;\n    var $u = +u;\n    var $v = +v;\n    var u0 = $u & UINT16;\n    var v0 = $v & UINT16;\n    var u1 = $u >>> 16;\n    var v1 = $v >>> 16;\n    var t = (u1 * v0 >>> 0) + (u0 * v0 >>> 16);\n    return u1 * v1 + (t >>> 16) + ((u0 * v1 >>> 0) + (t & UINT16) >>> 16);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.define-getter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.define-getter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar $defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\n\n// B.2.2.2 Object.prototype.__defineGetter__(P, getter)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __defineGetter__: function __defineGetter__(P, getter) {\n    $defineProperty.f(toObject(this), P, { get: aFunction(getter), enumerable: true, configurable: true });\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.define-setter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.define-setter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar $defineProperty = __webpack_require__(/*! ./_object-dp */ \"./node_modules/core-js/modules/_object-dp.js\");\n\n// B.2.2.3 Object.prototype.__defineSetter__(P, setter)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __defineSetter__: function __defineSetter__(P, setter) {\n    $defineProperty.f(toObject(this), P, { set: aFunction(setter), enumerable: true, configurable: true });\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.entries.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.entries.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-object-values-entries\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $entries = __webpack_require__(/*! ./_object-to-array */ \"./node_modules/core-js/modules/_object-to-array.js\")(true);\n\n$export($export.S, 'Object', {\n  entries: function entries(it) {\n    return $entries(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js\":\n/*!*********************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js ***!\n  \\*********************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-object-getownpropertydescriptors\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar ownKeys = __webpack_require__(/*! ./_own-keys */ \"./node_modules/core-js/modules/_own-keys.js\");\nvar toIObject = __webpack_require__(/*! ./_to-iobject */ \"./node_modules/core-js/modules/_to-iobject.js\");\nvar gOPD = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\");\nvar createProperty = __webpack_require__(/*! ./_create-property */ \"./node_modules/core-js/modules/_create-property.js\");\n\n$export($export.S, 'Object', {\n  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {\n    var O = toIObject(object);\n    var getDesc = gOPD.f;\n    var keys = ownKeys(O);\n    var result = {};\n    var i = 0;\n    var key, desc;\n    while (keys.length > i) {\n      desc = getDesc(O, key = keys[i++]);\n      if (desc !== undefined) createProperty(result, key, desc);\n    }\n    return result;\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.lookup-getter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.lookup-getter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\n\n// B.2.2.4 Object.prototype.__lookupGetter__(P)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __lookupGetter__: function __lookupGetter__(P) {\n    var O = toObject(this);\n    var K = toPrimitive(P, true);\n    var D;\n    do {\n      if (D = getOwnPropertyDescriptor(O, K)) return D.get;\n    } while (O = getPrototypeOf(O));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.lookup-setter.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.lookup-setter.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar toObject = __webpack_require__(/*! ./_to-object */ \"./node_modules/core-js/modules/_to-object.js\");\nvar toPrimitive = __webpack_require__(/*! ./_to-primitive */ \"./node_modules/core-js/modules/_to-primitive.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar getOwnPropertyDescriptor = __webpack_require__(/*! ./_object-gopd */ \"./node_modules/core-js/modules/_object-gopd.js\").f;\n\n// B.2.2.5 Object.prototype.__lookupSetter__(P)\n__webpack_require__(/*! ./_descriptors */ \"./node_modules/core-js/modules/_descriptors.js\") && $export($export.P + __webpack_require__(/*! ./_object-forced-pam */ \"./node_modules/core-js/modules/_object-forced-pam.js\"), 'Object', {\n  __lookupSetter__: function __lookupSetter__(P) {\n    var O = toObject(this);\n    var K = toPrimitive(P, true);\n    var D;\n    do {\n      if (D = getOwnPropertyDescriptor(O, K)) return D.set;\n    } while (O = getPrototypeOf(O));\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.object.values.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.object.values.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-object-values-entries\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $values = __webpack_require__(/*! ./_object-to-array */ \"./node_modules/core-js/modules/_object-to-array.js\")(false);\n\n$export($export.S, 'Object', {\n  values: function values(it) {\n    return $values(it);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.observable.js\":\n/*!********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.observable.js ***!\n  \\********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/zenparsing/es-observable\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar microtask = __webpack_require__(/*! ./_microtask */ \"./node_modules/core-js/modules/_microtask.js\")();\nvar OBSERVABLE = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\")('observable');\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar anInstance = __webpack_require__(/*! ./_an-instance */ \"./node_modules/core-js/modules/_an-instance.js\");\nvar redefineAll = __webpack_require__(/*! ./_redefine-all */ \"./node_modules/core-js/modules/_redefine-all.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar forOf = __webpack_require__(/*! ./_for-of */ \"./node_modules/core-js/modules/_for-of.js\");\nvar RETURN = forOf.RETURN;\n\nvar getMethod = function (fn) {\n  return fn == null ? undefined : aFunction(fn);\n};\n\nvar cleanupSubscription = function (subscription) {\n  var cleanup = subscription._c;\n  if (cleanup) {\n    subscription._c = undefined;\n    cleanup();\n  }\n};\n\nvar subscriptionClosed = function (subscription) {\n  return subscription._o === undefined;\n};\n\nvar closeSubscription = function (subscription) {\n  if (!subscriptionClosed(subscription)) {\n    subscription._o = undefined;\n    cleanupSubscription(subscription);\n  }\n};\n\nvar Subscription = function (observer, subscriber) {\n  anObject(observer);\n  this._c = undefined;\n  this._o = observer;\n  observer = new SubscriptionObserver(this);\n  try {\n    var cleanup = subscriber(observer);\n    var subscription = cleanup;\n    if (cleanup != null) {\n      if (typeof cleanup.unsubscribe === 'function') cleanup = function () { subscription.unsubscribe(); };\n      else aFunction(cleanup);\n      this._c = cleanup;\n    }\n  } catch (e) {\n    observer.error(e);\n    return;\n  } if (subscriptionClosed(this)) cleanupSubscription(this);\n};\n\nSubscription.prototype = redefineAll({}, {\n  unsubscribe: function unsubscribe() { closeSubscription(this); }\n});\n\nvar SubscriptionObserver = function (subscription) {\n  this._s = subscription;\n};\n\nSubscriptionObserver.prototype = redefineAll({}, {\n  next: function next(value) {\n    var subscription = this._s;\n    if (!subscriptionClosed(subscription)) {\n      var observer = subscription._o;\n      try {\n        var m = getMethod(observer.next);\n        if (m) return m.call(observer, value);\n      } catch (e) {\n        try {\n          closeSubscription(subscription);\n        } finally {\n          throw e;\n        }\n      }\n    }\n  },\n  error: function error(value) {\n    var subscription = this._s;\n    if (subscriptionClosed(subscription)) throw value;\n    var observer = subscription._o;\n    subscription._o = undefined;\n    try {\n      var m = getMethod(observer.error);\n      if (!m) throw value;\n      value = m.call(observer, value);\n    } catch (e) {\n      try {\n        cleanupSubscription(subscription);\n      } finally {\n        throw e;\n      }\n    } cleanupSubscription(subscription);\n    return value;\n  },\n  complete: function complete(value) {\n    var subscription = this._s;\n    if (!subscriptionClosed(subscription)) {\n      var observer = subscription._o;\n      subscription._o = undefined;\n      try {\n        var m = getMethod(observer.complete);\n        value = m ? m.call(observer, value) : undefined;\n      } catch (e) {\n        try {\n          cleanupSubscription(subscription);\n        } finally {\n          throw e;\n        }\n      } cleanupSubscription(subscription);\n      return value;\n    }\n  }\n});\n\nvar $Observable = function Observable(subscriber) {\n  anInstance(this, $Observable, 'Observable', '_f')._f = aFunction(subscriber);\n};\n\nredefineAll($Observable.prototype, {\n  subscribe: function subscribe(observer) {\n    return new Subscription(observer, this._f);\n  },\n  forEach: function forEach(fn) {\n    var that = this;\n    return new (core.Promise || global.Promise)(function (resolve, reject) {\n      aFunction(fn);\n      var subscription = that.subscribe({\n        next: function (value) {\n          try {\n            return fn(value);\n          } catch (e) {\n            reject(e);\n            subscription.unsubscribe();\n          }\n        },\n        error: reject,\n        complete: resolve\n      });\n    });\n  }\n});\n\nredefineAll($Observable, {\n  from: function from(x) {\n    var C = typeof this === 'function' ? this : $Observable;\n    var method = getMethod(anObject(x)[OBSERVABLE]);\n    if (method) {\n      var observable = anObject(method.call(x));\n      return observable.constructor === C ? observable : new C(function (observer) {\n        return observable.subscribe(observer);\n      });\n    }\n    return new C(function (observer) {\n      var done = false;\n      microtask(function () {\n        if (!done) {\n          try {\n            if (forOf(x, false, function (it) {\n              observer.next(it);\n              if (done) return RETURN;\n            }) === RETURN) return;\n          } catch (e) {\n            if (done) throw e;\n            observer.error(e);\n            return;\n          } observer.complete();\n        }\n      });\n      return function () { done = true; };\n    });\n  },\n  of: function of() {\n    for (var i = 0, l = arguments.length, items = new Array(l); i < l;) items[i] = arguments[i++];\n    return new (typeof this === 'function' ? this : $Observable)(function (observer) {\n      var done = false;\n      microtask(function () {\n        if (!done) {\n          for (var j = 0; j < items.length; ++j) {\n            observer.next(items[j]);\n            if (done) return;\n          } observer.complete();\n        }\n      });\n      return function () { done = true; };\n    });\n  }\n});\n\nhide($Observable.prototype, OBSERVABLE, function () { return this; });\n\n$export($export.G, { Observable: $Observable });\n\n__webpack_require__(/*! ./_set-species */ \"./node_modules/core-js/modules/_set-species.js\")('Observable');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.promise.finally.js\":\n/*!*************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.promise.finally.js ***!\n  \\*************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n// https://github.com/tc39/proposal-promise-finally\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar core = __webpack_require__(/*! ./_core */ \"./node_modules/core-js/modules/_core.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar speciesConstructor = __webpack_require__(/*! ./_species-constructor */ \"./node_modules/core-js/modules/_species-constructor.js\");\nvar promiseResolve = __webpack_require__(/*! ./_promise-resolve */ \"./node_modules/core-js/modules/_promise-resolve.js\");\n\n$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) {\n  var C = speciesConstructor(this, core.Promise || global.Promise);\n  var isFunction = typeof onFinally == 'function';\n  return this.then(\n    isFunction ? function (x) {\n      return promiseResolve(C, onFinally()).then(function () { return x; });\n    } : onFinally,\n    isFunction ? function (e) {\n      return promiseResolve(C, onFinally()).then(function () { throw e; });\n    } : onFinally\n  );\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.promise.try.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.promise.try.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/proposal-promise-try\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar newPromiseCapability = __webpack_require__(/*! ./_new-promise-capability */ \"./node_modules/core-js/modules/_new-promise-capability.js\");\nvar perform = __webpack_require__(/*! ./_perform */ \"./node_modules/core-js/modules/_perform.js\");\n\n$export($export.S, 'Promise', { 'try': function (callbackfn) {\n  var promiseCapability = newPromiseCapability.f(this);\n  var result = perform(callbackfn);\n  (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v);\n  return promiseCapability.promise;\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.define-metadata.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.define-metadata.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toMetaKey = metadata.key;\nvar ordinaryDefineOwnMetadata = metadata.set;\n\nmetadata.exp({ defineMetadata: function defineMetadata(metadataKey, metadataValue, target, targetKey) {\n  ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetaKey(targetKey));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.delete-metadata.js\":\n/*!*********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.delete-metadata.js ***!\n  \\*********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar toMetaKey = metadata.key;\nvar getOrCreateMetadataMap = metadata.map;\nvar store = metadata.store;\n\nmetadata.exp({ deleteMetadata: function deleteMetadata(metadataKey, target /* , targetKey */) {\n  var targetKey = arguments.length < 3 ? undefined : toMetaKey(arguments[2]);\n  var metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false);\n  if (metadataMap === undefined || !metadataMap['delete'](metadataKey)) return false;\n  if (metadataMap.size) return true;\n  var targetMetadata = store.get(target);\n  targetMetadata['delete'](targetKey);\n  return !!targetMetadata.size || store['delete'](target);\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js\":\n/*!***********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js ***!\n  \\***********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar Set = __webpack_require__(/*! ./es6.set */ \"./node_modules/core-js/modules/es6.set.js\");\nvar from = __webpack_require__(/*! ./_array-from-iterable */ \"./node_modules/core-js/modules/_array-from-iterable.js\");\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ordinaryOwnMetadataKeys = metadata.keys;\nvar toMetaKey = metadata.key;\n\nvar ordinaryMetadataKeys = function (O, P) {\n  var oKeys = ordinaryOwnMetadataKeys(O, P);\n  var parent = getPrototypeOf(O);\n  if (parent === null) return oKeys;\n  var pKeys = ordinaryMetadataKeys(parent, P);\n  return pKeys.length ? oKeys.length ? from(new Set(oKeys.concat(pKeys))) : pKeys : oKeys;\n};\n\nmetadata.exp({ getMetadataKeys: function getMetadataKeys(target /* , targetKey */) {\n  return ordinaryMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-metadata.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-metadata.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ordinaryHasOwnMetadata = metadata.has;\nvar ordinaryGetOwnMetadata = metadata.get;\nvar toMetaKey = metadata.key;\n\nvar ordinaryGetMetadata = function (MetadataKey, O, P) {\n  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);\n  if (hasOwn) return ordinaryGetOwnMetadata(MetadataKey, O, P);\n  var parent = getPrototypeOf(O);\n  return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined;\n};\n\nmetadata.exp({ getMetadata: function getMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryGetMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js\":\n/*!***************************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js ***!\n  \\***************************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar ordinaryOwnMetadataKeys = metadata.keys;\nvar toMetaKey = metadata.key;\n\nmetadata.exp({ getOwnMetadataKeys: function getOwnMetadataKeys(target /* , targetKey */) {\n  return ordinaryOwnMetadataKeys(anObject(target), arguments.length < 2 ? undefined : toMetaKey(arguments[1]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.get-own-metadata.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar ordinaryGetOwnMetadata = metadata.get;\nvar toMetaKey = metadata.key;\n\nmetadata.exp({ getOwnMetadata: function getOwnMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryGetOwnMetadata(metadataKey, anObject(target)\n    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.has-metadata.js\":\n/*!******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.has-metadata.js ***!\n  \\******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar getPrototypeOf = __webpack_require__(/*! ./_object-gpo */ \"./node_modules/core-js/modules/_object-gpo.js\");\nvar ordinaryHasOwnMetadata = metadata.has;\nvar toMetaKey = metadata.key;\n\nvar ordinaryHasMetadata = function (MetadataKey, O, P) {\n  var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P);\n  if (hasOwn) return true;\n  var parent = getPrototypeOf(O);\n  return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false;\n};\n\nmetadata.exp({ hasMetadata: function hasMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryHasMetadata(metadataKey, anObject(target), arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.has-own-metadata.js\":\n/*!**********************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.has-own-metadata.js ***!\n  \\**********************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar ordinaryHasOwnMetadata = metadata.has;\nvar toMetaKey = metadata.key;\n\nmetadata.exp({ hasOwnMetadata: function hasOwnMetadata(metadataKey, target /* , targetKey */) {\n  return ordinaryHasOwnMetadata(metadataKey, anObject(target)\n    , arguments.length < 3 ? undefined : toMetaKey(arguments[2]));\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.reflect.metadata.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.reflect.metadata.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $metadata = __webpack_require__(/*! ./_metadata */ \"./node_modules/core-js/modules/_metadata.js\");\nvar anObject = __webpack_require__(/*! ./_an-object */ \"./node_modules/core-js/modules/_an-object.js\");\nvar aFunction = __webpack_require__(/*! ./_a-function */ \"./node_modules/core-js/modules/_a-function.js\");\nvar toMetaKey = $metadata.key;\nvar ordinaryDefineOwnMetadata = $metadata.set;\n\n$metadata.exp({ metadata: function metadata(metadataKey, metadataValue) {\n  return function decorator(target, targetKey) {\n    ordinaryDefineOwnMetadata(\n      metadataKey, metadataValue,\n      (targetKey !== undefined ? anObject : aFunction)(target),\n      toMetaKey(targetKey)\n    );\n  };\n} });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.set.from.js\":\n/*!******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.set.from.js ***!\n  \\******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-set.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('Set');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.set.of.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.set.of.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-set.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('Set');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.set.to-json.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.set.to-json.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/DavidBruant/Map-Set.prototype.toJSON\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.P + $export.R, 'Set', { toJSON: __webpack_require__(/*! ./_collection-to-json */ \"./node_modules/core-js/modules/_collection-to-json.js\")('Set') });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.at.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.at.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/mathiasbynens/String.prototype.at\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $at = __webpack_require__(/*! ./_string-at */ \"./node_modules/core-js/modules/_string-at.js\")(true);\n\n$export($export.P, 'String', {\n  at: function at(pos) {\n    return $at(this, pos);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.match-all.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.match-all.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://tc39.github.io/String.prototype.matchAll/\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar defined = __webpack_require__(/*! ./_defined */ \"./node_modules/core-js/modules/_defined.js\");\nvar toLength = __webpack_require__(/*! ./_to-length */ \"./node_modules/core-js/modules/_to-length.js\");\nvar isRegExp = __webpack_require__(/*! ./_is-regexp */ \"./node_modules/core-js/modules/_is-regexp.js\");\nvar getFlags = __webpack_require__(/*! ./_flags */ \"./node_modules/core-js/modules/_flags.js\");\nvar RegExpProto = RegExp.prototype;\n\nvar $RegExpStringIterator = function (regexp, string) {\n  this._r = regexp;\n  this._s = string;\n};\n\n__webpack_require__(/*! ./_iter-create */ \"./node_modules/core-js/modules/_iter-create.js\")($RegExpStringIterator, 'RegExp String', function next() {\n  var match = this._r.exec(this._s);\n  return { value: match, done: match === null };\n});\n\n$export($export.P, 'String', {\n  matchAll: function matchAll(regexp) {\n    defined(this);\n    if (!isRegExp(regexp)) throw TypeError(regexp + ' is not a regexp!');\n    var S = String(this);\n    var flags = 'flags' in RegExpProto ? String(regexp.flags) : getFlags.call(regexp);\n    var rx = new RegExp(regexp.source, ~flags.indexOf('g') ? flags : 'g' + flags);\n    rx.lastIndex = toLength(regexp.lastIndex);\n    return new $RegExpStringIterator(rx, S);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.pad-end.js\":\n/*!************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.pad-end.js ***!\n  \\************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/proposal-string-pad-start-end\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $pad = __webpack_require__(/*! ./_string-pad */ \"./node_modules/core-js/modules/_string-pad.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\n\n// https://github.com/zloirock/core-js/issues/280\n$export($export.P + $export.F * /Version\\/10\\.\\d+(\\.\\d+)? Safari\\//.test(userAgent), 'String', {\n  padEnd: function padEnd(maxLength /* , fillString = ' ' */) {\n    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.pad-start.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.pad-start.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/tc39/proposal-string-pad-start-end\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $pad = __webpack_require__(/*! ./_string-pad */ \"./node_modules/core-js/modules/_string-pad.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\n\n// https://github.com/zloirock/core-js/issues/280\n$export($export.P + $export.F * /Version\\/10\\.\\d+(\\.\\d+)? Safari\\//.test(userAgent), 'String', {\n  padStart: function padStart(maxLength /* , fillString = ' ' */) {\n    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);\n  }\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.trim-left.js\":\n/*!**************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.trim-left.js ***!\n  \\**************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/sebmarkbage/ecmascript-string-left-right-trim\n__webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\")('trimLeft', function ($trim) {\n  return function trimLeft() {\n    return $trim(this, 1);\n  };\n}, 'trimStart');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.string.trim-right.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.string.trim-right.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n// https://github.com/sebmarkbage/ecmascript-string-left-right-trim\n__webpack_require__(/*! ./_string-trim */ \"./node_modules/core-js/modules/_string-trim.js\")('trimRight', function ($trim) {\n  return function trimRight() {\n    return $trim(this, 2);\n  };\n}, 'trimEnd');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.symbol.async-iterator.js\":\n/*!*******************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.symbol.async-iterator.js ***!\n  \\*******************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_wks-define */ \"./node_modules/core-js/modules/_wks-define.js\")('asyncIterator');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.symbol.observable.js\":\n/*!***************************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.symbol.observable.js ***!\n  \\***************************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./_wks-define */ \"./node_modules/core-js/modules/_wks-define.js\")('observable');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.system.global.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.system.global.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://github.com/tc39/proposal-global\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\n\n$export($export.S, 'System', { global: __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\") });\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-map.from.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-map.from.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('WeakMap');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-map.of.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-map.of.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('WeakMap');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-set.from.js\":\n/*!***********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-set.from.js ***!\n  \\***********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.from\n__webpack_require__(/*! ./_set-collection-from */ \"./node_modules/core-js/modules/_set-collection-from.js\")('WeakSet');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/es7.weak-set.of.js\":\n/*!*********************************************************!*\\\n  !*** ./node_modules/core-js/modules/es7.weak-set.of.js ***!\n  \\*********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.of\n__webpack_require__(/*! ./_set-collection-of */ \"./node_modules/core-js/modules/_set-collection-of.js\")('WeakSet');\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.dom.iterable.js\":\n/*!**********************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.dom.iterable.js ***!\n  \\**********************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $iterators = __webpack_require__(/*! ./es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\nvar getKeys = __webpack_require__(/*! ./_object-keys */ \"./node_modules/core-js/modules/_object-keys.js\");\nvar redefine = __webpack_require__(/*! ./_redefine */ \"./node_modules/core-js/modules/_redefine.js\");\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar hide = __webpack_require__(/*! ./_hide */ \"./node_modules/core-js/modules/_hide.js\");\nvar Iterators = __webpack_require__(/*! ./_iterators */ \"./node_modules/core-js/modules/_iterators.js\");\nvar wks = __webpack_require__(/*! ./_wks */ \"./node_modules/core-js/modules/_wks.js\");\nvar ITERATOR = wks('iterator');\nvar TO_STRING_TAG = wks('toStringTag');\nvar ArrayValues = Iterators.Array;\n\nvar DOMIterables = {\n  CSSRuleList: true, // TODO: Not spec compliant, should be false.\n  CSSStyleDeclaration: false,\n  CSSValueList: false,\n  ClientRectList: false,\n  DOMRectList: false,\n  DOMStringList: false,\n  DOMTokenList: true,\n  DataTransferItemList: false,\n  FileList: false,\n  HTMLAllCollection: false,\n  HTMLCollection: false,\n  HTMLFormElement: false,\n  HTMLSelectElement: false,\n  MediaList: true, // TODO: Not spec compliant, should be false.\n  MimeTypeArray: false,\n  NamedNodeMap: false,\n  NodeList: true,\n  PaintRequestList: false,\n  Plugin: false,\n  PluginArray: false,\n  SVGLengthList: false,\n  SVGNumberList: false,\n  SVGPathSegList: false,\n  SVGPointList: false,\n  SVGStringList: false,\n  SVGTransformList: false,\n  SourceBufferList: false,\n  StyleSheetList: true, // TODO: Not spec compliant, should be false.\n  TextTrackCueList: false,\n  TextTrackList: false,\n  TouchList: false\n};\n\nfor (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {\n  var NAME = collections[i];\n  var explicit = DOMIterables[NAME];\n  var Collection = global[NAME];\n  var proto = Collection && Collection.prototype;\n  var key;\n  if (proto) {\n    if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);\n    if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n    Iterators[NAME] = ArrayValues;\n    if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);\n  }\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.immediate.js\":\n/*!*******************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.immediate.js ***!\n  \\*******************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar $task = __webpack_require__(/*! ./_task */ \"./node_modules/core-js/modules/_task.js\");\n$export($export.G + $export.B, {\n  setImmediate: $task.set,\n  clearImmediate: $task.clear\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/modules/web.timers.js\":\n/*!****************************************************!*\\\n  !*** ./node_modules/core-js/modules/web.timers.js ***!\n  \\****************************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n// ie9- setTimeout & setInterval additional parameters fix\nvar global = __webpack_require__(/*! ./_global */ \"./node_modules/core-js/modules/_global.js\");\nvar $export = __webpack_require__(/*! ./_export */ \"./node_modules/core-js/modules/_export.js\");\nvar userAgent = __webpack_require__(/*! ./_user-agent */ \"./node_modules/core-js/modules/_user-agent.js\");\nvar slice = [].slice;\nvar MSIE = /MSIE .\\./.test(userAgent); // <- dirty ie9- check\nvar wrap = function (set) {\n  return function (fn, time /* , ...args */) {\n    var boundArgs = arguments.length > 2;\n    var args = boundArgs ? slice.call(arguments, 2) : false;\n    return set(boundArgs ? function () {\n      // eslint-disable-next-line no-new-func\n      (typeof fn == 'function' ? fn : Function(fn)).apply(this, args);\n    } : fn, time);\n  };\n};\n$export($export.G + $export.B + $export.F * MSIE, {\n  setTimeout: wrap(global.setTimeout),\n  setInterval: wrap(global.setInterval)\n});\n\n\n/***/ }),\n\n/***/ \"./node_modules/core-js/shim.js\":\n/*!**************************************!*\\\n  !*** ./node_modules/core-js/shim.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! ./modules/es6.symbol */ \"./node_modules/core-js/modules/es6.symbol.js\");\n__webpack_require__(/*! ./modules/es6.object.create */ \"./node_modules/core-js/modules/es6.object.create.js\");\n__webpack_require__(/*! ./modules/es6.object.define-property */ \"./node_modules/core-js/modules/es6.object.define-property.js\");\n__webpack_require__(/*! ./modules/es6.object.define-properties */ \"./node_modules/core-js/modules/es6.object.define-properties.js\");\n__webpack_require__(/*! ./modules/es6.object.get-own-property-descriptor */ \"./node_modules/core-js/modules/es6.object.get-own-property-descriptor.js\");\n__webpack_require__(/*! ./modules/es6.object.get-prototype-of */ \"./node_modules/core-js/modules/es6.object.get-prototype-of.js\");\n__webpack_require__(/*! ./modules/es6.object.keys */ \"./node_modules/core-js/modules/es6.object.keys.js\");\n__webpack_require__(/*! ./modules/es6.object.get-own-property-names */ \"./node_modules/core-js/modules/es6.object.get-own-property-names.js\");\n__webpack_require__(/*! ./modules/es6.object.freeze */ \"./node_modules/core-js/modules/es6.object.freeze.js\");\n__webpack_require__(/*! ./modules/es6.object.seal */ \"./node_modules/core-js/modules/es6.object.seal.js\");\n__webpack_require__(/*! ./modules/es6.object.prevent-extensions */ \"./node_modules/core-js/modules/es6.object.prevent-extensions.js\");\n__webpack_require__(/*! ./modules/es6.object.is-frozen */ \"./node_modules/core-js/modules/es6.object.is-frozen.js\");\n__webpack_require__(/*! ./modules/es6.object.is-sealed */ \"./node_modules/core-js/modules/es6.object.is-sealed.js\");\n__webpack_require__(/*! ./modules/es6.object.is-extensible */ \"./node_modules/core-js/modules/es6.object.is-extensible.js\");\n__webpack_require__(/*! ./modules/es6.object.assign */ \"./node_modules/core-js/modules/es6.object.assign.js\");\n__webpack_require__(/*! ./modules/es6.object.is */ \"./node_modules/core-js/modules/es6.object.is.js\");\n__webpack_require__(/*! ./modules/es6.object.set-prototype-of */ \"./node_modules/core-js/modules/es6.object.set-prototype-of.js\");\n__webpack_require__(/*! ./modules/es6.object.to-string */ \"./node_modules/core-js/modules/es6.object.to-string.js\");\n__webpack_require__(/*! ./modules/es6.function.bind */ \"./node_modules/core-js/modules/es6.function.bind.js\");\n__webpack_require__(/*! ./modules/es6.function.name */ \"./node_modules/core-js/modules/es6.function.name.js\");\n__webpack_require__(/*! ./modules/es6.function.has-instance */ \"./node_modules/core-js/modules/es6.function.has-instance.js\");\n__webpack_require__(/*! ./modules/es6.parse-int */ \"./node_modules/core-js/modules/es6.parse-int.js\");\n__webpack_require__(/*! ./modules/es6.parse-float */ \"./node_modules/core-js/modules/es6.parse-float.js\");\n__webpack_require__(/*! ./modules/es6.number.constructor */ \"./node_modules/core-js/modules/es6.number.constructor.js\");\n__webpack_require__(/*! ./modules/es6.number.to-fixed */ \"./node_modules/core-js/modules/es6.number.to-fixed.js\");\n__webpack_require__(/*! ./modules/es6.number.to-precision */ \"./node_modules/core-js/modules/es6.number.to-precision.js\");\n__webpack_require__(/*! ./modules/es6.number.epsilon */ \"./node_modules/core-js/modules/es6.number.epsilon.js\");\n__webpack_require__(/*! ./modules/es6.number.is-finite */ \"./node_modules/core-js/modules/es6.number.is-finite.js\");\n__webpack_require__(/*! ./modules/es6.number.is-integer */ \"./node_modules/core-js/modules/es6.number.is-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.is-nan */ \"./node_modules/core-js/modules/es6.number.is-nan.js\");\n__webpack_require__(/*! ./modules/es6.number.is-safe-integer */ \"./node_modules/core-js/modules/es6.number.is-safe-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.max-safe-integer */ \"./node_modules/core-js/modules/es6.number.max-safe-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.min-safe-integer */ \"./node_modules/core-js/modules/es6.number.min-safe-integer.js\");\n__webpack_require__(/*! ./modules/es6.number.parse-float */ \"./node_modules/core-js/modules/es6.number.parse-float.js\");\n__webpack_require__(/*! ./modules/es6.number.parse-int */ \"./node_modules/core-js/modules/es6.number.parse-int.js\");\n__webpack_require__(/*! ./modules/es6.math.acosh */ \"./node_modules/core-js/modules/es6.math.acosh.js\");\n__webpack_require__(/*! ./modules/es6.math.asinh */ \"./node_modules/core-js/modules/es6.math.asinh.js\");\n__webpack_require__(/*! ./modules/es6.math.atanh */ \"./node_modules/core-js/modules/es6.math.atanh.js\");\n__webpack_require__(/*! ./modules/es6.math.cbrt */ \"./node_modules/core-js/modules/es6.math.cbrt.js\");\n__webpack_require__(/*! ./modules/es6.math.clz32 */ \"./node_modules/core-js/modules/es6.math.clz32.js\");\n__webpack_require__(/*! ./modules/es6.math.cosh */ \"./node_modules/core-js/modules/es6.math.cosh.js\");\n__webpack_require__(/*! ./modules/es6.math.expm1 */ \"./node_modules/core-js/modules/es6.math.expm1.js\");\n__webpack_require__(/*! ./modules/es6.math.fround */ \"./node_modules/core-js/modules/es6.math.fround.js\");\n__webpack_require__(/*! ./modules/es6.math.hypot */ \"./node_modules/core-js/modules/es6.math.hypot.js\");\n__webpack_require__(/*! ./modules/es6.math.imul */ \"./node_modules/core-js/modules/es6.math.imul.js\");\n__webpack_require__(/*! ./modules/es6.math.log10 */ \"./node_modules/core-js/modules/es6.math.log10.js\");\n__webpack_require__(/*! ./modules/es6.math.log1p */ \"./node_modules/core-js/modules/es6.math.log1p.js\");\n__webpack_require__(/*! ./modules/es6.math.log2 */ \"./node_modules/core-js/modules/es6.math.log2.js\");\n__webpack_require__(/*! ./modules/es6.math.sign */ \"./node_modules/core-js/modules/es6.math.sign.js\");\n__webpack_require__(/*! ./modules/es6.math.sinh */ \"./node_modules/core-js/modules/es6.math.sinh.js\");\n__webpack_require__(/*! ./modules/es6.math.tanh */ \"./node_modules/core-js/modules/es6.math.tanh.js\");\n__webpack_require__(/*! ./modules/es6.math.trunc */ \"./node_modules/core-js/modules/es6.math.trunc.js\");\n__webpack_require__(/*! ./modules/es6.string.from-code-point */ \"./node_modules/core-js/modules/es6.string.from-code-point.js\");\n__webpack_require__(/*! ./modules/es6.string.raw */ \"./node_modules/core-js/modules/es6.string.raw.js\");\n__webpack_require__(/*! ./modules/es6.string.trim */ \"./node_modules/core-js/modules/es6.string.trim.js\");\n__webpack_require__(/*! ./modules/es6.string.iterator */ \"./node_modules/core-js/modules/es6.string.iterator.js\");\n__webpack_require__(/*! ./modules/es6.string.code-point-at */ \"./node_modules/core-js/modules/es6.string.code-point-at.js\");\n__webpack_require__(/*! ./modules/es6.string.ends-with */ \"./node_modules/core-js/modules/es6.string.ends-with.js\");\n__webpack_require__(/*! ./modules/es6.string.includes */ \"./node_modules/core-js/modules/es6.string.includes.js\");\n__webpack_require__(/*! ./modules/es6.string.repeat */ \"./node_modules/core-js/modules/es6.string.repeat.js\");\n__webpack_require__(/*! ./modules/es6.string.starts-with */ \"./node_modules/core-js/modules/es6.string.starts-with.js\");\n__webpack_require__(/*! ./modules/es6.string.anchor */ \"./node_modules/core-js/modules/es6.string.anchor.js\");\n__webpack_require__(/*! ./modules/es6.string.big */ \"./node_modules/core-js/modules/es6.string.big.js\");\n__webpack_require__(/*! ./modules/es6.string.blink */ \"./node_modules/core-js/modules/es6.string.blink.js\");\n__webpack_require__(/*! ./modules/es6.string.bold */ \"./node_modules/core-js/modules/es6.string.bold.js\");\n__webpack_require__(/*! ./modules/es6.string.fixed */ \"./node_modules/core-js/modules/es6.string.fixed.js\");\n__webpack_require__(/*! ./modules/es6.string.fontcolor */ \"./node_modules/core-js/modules/es6.string.fontcolor.js\");\n__webpack_require__(/*! ./modules/es6.string.fontsize */ \"./node_modules/core-js/modules/es6.string.fontsize.js\");\n__webpack_require__(/*! ./modules/es6.string.italics */ \"./node_modules/core-js/modules/es6.string.italics.js\");\n__webpack_require__(/*! ./modules/es6.string.link */ \"./node_modules/core-js/modules/es6.string.link.js\");\n__webpack_require__(/*! ./modules/es6.string.small */ \"./node_modules/core-js/modules/es6.string.small.js\");\n__webpack_require__(/*! ./modules/es6.string.strike */ \"./node_modules/core-js/modules/es6.string.strike.js\");\n__webpack_require__(/*! ./modules/es6.string.sub */ \"./node_modules/core-js/modules/es6.string.sub.js\");\n__webpack_require__(/*! ./modules/es6.string.sup */ \"./node_modules/core-js/modules/es6.string.sup.js\");\n__webpack_require__(/*! ./modules/es6.date.now */ \"./node_modules/core-js/modules/es6.date.now.js\");\n__webpack_require__(/*! ./modules/es6.date.to-json */ \"./node_modules/core-js/modules/es6.date.to-json.js\");\n__webpack_require__(/*! ./modules/es6.date.to-iso-string */ \"./node_modules/core-js/modules/es6.date.to-iso-string.js\");\n__webpack_require__(/*! ./modules/es6.date.to-string */ \"./node_modules/core-js/modules/es6.date.to-string.js\");\n__webpack_require__(/*! ./modules/es6.date.to-primitive */ \"./node_modules/core-js/modules/es6.date.to-primitive.js\");\n__webpack_require__(/*! ./modules/es6.array.is-array */ \"./node_modules/core-js/modules/es6.array.is-array.js\");\n__webpack_require__(/*! ./modules/es6.array.from */ \"./node_modules/core-js/modules/es6.array.from.js\");\n__webpack_require__(/*! ./modules/es6.array.of */ \"./node_modules/core-js/modules/es6.array.of.js\");\n__webpack_require__(/*! ./modules/es6.array.join */ \"./node_modules/core-js/modules/es6.array.join.js\");\n__webpack_require__(/*! ./modules/es6.array.slice */ \"./node_modules/core-js/modules/es6.array.slice.js\");\n__webpack_require__(/*! ./modules/es6.array.sort */ \"./node_modules/core-js/modules/es6.array.sort.js\");\n__webpack_require__(/*! ./modules/es6.array.for-each */ \"./node_modules/core-js/modules/es6.array.for-each.js\");\n__webpack_require__(/*! ./modules/es6.array.map */ \"./node_modules/core-js/modules/es6.array.map.js\");\n__webpack_require__(/*! ./modules/es6.array.filter */ \"./node_modules/core-js/modules/es6.array.filter.js\");\n__webpack_require__(/*! ./modules/es6.array.some */ \"./node_modules/core-js/modules/es6.array.some.js\");\n__webpack_require__(/*! ./modules/es6.array.every */ \"./node_modules/core-js/modules/es6.array.every.js\");\n__webpack_require__(/*! ./modules/es6.array.reduce */ \"./node_modules/core-js/modules/es6.array.reduce.js\");\n__webpack_require__(/*! ./modules/es6.array.reduce-right */ \"./node_modules/core-js/modules/es6.array.reduce-right.js\");\n__webpack_require__(/*! ./modules/es6.array.index-of */ \"./node_modules/core-js/modules/es6.array.index-of.js\");\n__webpack_require__(/*! ./modules/es6.array.last-index-of */ \"./node_modules/core-js/modules/es6.array.last-index-of.js\");\n__webpack_require__(/*! ./modules/es6.array.copy-within */ \"./node_modules/core-js/modules/es6.array.copy-within.js\");\n__webpack_require__(/*! ./modules/es6.array.fill */ \"./node_modules/core-js/modules/es6.array.fill.js\");\n__webpack_require__(/*! ./modules/es6.array.find */ \"./node_modules/core-js/modules/es6.array.find.js\");\n__webpack_require__(/*! ./modules/es6.array.find-index */ \"./node_modules/core-js/modules/es6.array.find-index.js\");\n__webpack_require__(/*! ./modules/es6.array.species */ \"./node_modules/core-js/modules/es6.array.species.js\");\n__webpack_require__(/*! ./modules/es6.array.iterator */ \"./node_modules/core-js/modules/es6.array.iterator.js\");\n__webpack_require__(/*! ./modules/es6.regexp.constructor */ \"./node_modules/core-js/modules/es6.regexp.constructor.js\");\n__webpack_require__(/*! ./modules/es6.regexp.exec */ \"./node_modules/core-js/modules/es6.regexp.exec.js\");\n__webpack_require__(/*! ./modules/es6.regexp.to-string */ \"./node_modules/core-js/modules/es6.regexp.to-string.js\");\n__webpack_require__(/*! ./modules/es6.regexp.flags */ \"./node_modules/core-js/modules/es6.regexp.flags.js\");\n__webpack_require__(/*! ./modules/es6.regexp.match */ \"./node_modules/core-js/modules/es6.regexp.match.js\");\n__webpack_require__(/*! ./modules/es6.regexp.replace */ \"./node_modules/core-js/modules/es6.regexp.replace.js\");\n__webpack_require__(/*! ./modules/es6.regexp.search */ \"./node_modules/core-js/modules/es6.regexp.search.js\");\n__webpack_require__(/*! ./modules/es6.regexp.split */ \"./node_modules/core-js/modules/es6.regexp.split.js\");\n__webpack_require__(/*! ./modules/es6.promise */ \"./node_modules/core-js/modules/es6.promise.js\");\n__webpack_require__(/*! ./modules/es6.map */ \"./node_modules/core-js/modules/es6.map.js\");\n__webpack_require__(/*! ./modules/es6.set */ \"./node_modules/core-js/modules/es6.set.js\");\n__webpack_require__(/*! ./modules/es6.weak-map */ \"./node_modules/core-js/modules/es6.weak-map.js\");\n__webpack_require__(/*! ./modules/es6.weak-set */ \"./node_modules/core-js/modules/es6.weak-set.js\");\n__webpack_require__(/*! ./modules/es6.typed.array-buffer */ \"./node_modules/core-js/modules/es6.typed.array-buffer.js\");\n__webpack_require__(/*! ./modules/es6.typed.data-view */ \"./node_modules/core-js/modules/es6.typed.data-view.js\");\n__webpack_require__(/*! ./modules/es6.typed.int8-array */ \"./node_modules/core-js/modules/es6.typed.int8-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint8-array */ \"./node_modules/core-js/modules/es6.typed.uint8-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint8-clamped-array */ \"./node_modules/core-js/modules/es6.typed.uint8-clamped-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.int16-array */ \"./node_modules/core-js/modules/es6.typed.int16-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint16-array */ \"./node_modules/core-js/modules/es6.typed.uint16-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.int32-array */ \"./node_modules/core-js/modules/es6.typed.int32-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.uint32-array */ \"./node_modules/core-js/modules/es6.typed.uint32-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.float32-array */ \"./node_modules/core-js/modules/es6.typed.float32-array.js\");\n__webpack_require__(/*! ./modules/es6.typed.float64-array */ \"./node_modules/core-js/modules/es6.typed.float64-array.js\");\n__webpack_require__(/*! ./modules/es6.reflect.apply */ \"./node_modules/core-js/modules/es6.reflect.apply.js\");\n__webpack_require__(/*! ./modules/es6.reflect.construct */ \"./node_modules/core-js/modules/es6.reflect.construct.js\");\n__webpack_require__(/*! ./modules/es6.reflect.define-property */ \"./node_modules/core-js/modules/es6.reflect.define-property.js\");\n__webpack_require__(/*! ./modules/es6.reflect.delete-property */ \"./node_modules/core-js/modules/es6.reflect.delete-property.js\");\n__webpack_require__(/*! ./modules/es6.reflect.enumerate */ \"./node_modules/core-js/modules/es6.reflect.enumerate.js\");\n__webpack_require__(/*! ./modules/es6.reflect.get */ \"./node_modules/core-js/modules/es6.reflect.get.js\");\n__webpack_require__(/*! ./modules/es6.reflect.get-own-property-descriptor */ \"./node_modules/core-js/modules/es6.reflect.get-own-property-descriptor.js\");\n__webpack_require__(/*! ./modules/es6.reflect.get-prototype-of */ \"./node_modules/core-js/modules/es6.reflect.get-prototype-of.js\");\n__webpack_require__(/*! ./modules/es6.reflect.has */ \"./node_modules/core-js/modules/es6.reflect.has.js\");\n__webpack_require__(/*! ./modules/es6.reflect.is-extensible */ \"./node_modules/core-js/modules/es6.reflect.is-extensible.js\");\n__webpack_require__(/*! ./modules/es6.reflect.own-keys */ \"./node_modules/core-js/modules/es6.reflect.own-keys.js\");\n__webpack_require__(/*! ./modules/es6.reflect.prevent-extensions */ \"./node_modules/core-js/modules/es6.reflect.prevent-extensions.js\");\n__webpack_require__(/*! ./modules/es6.reflect.set */ \"./node_modules/core-js/modules/es6.reflect.set.js\");\n__webpack_require__(/*! ./modules/es6.reflect.set-prototype-of */ \"./node_modules/core-js/modules/es6.reflect.set-prototype-of.js\");\n__webpack_require__(/*! ./modules/es7.array.includes */ \"./node_modules/core-js/modules/es7.array.includes.js\");\n__webpack_require__(/*! ./modules/es7.array.flat-map */ \"./node_modules/core-js/modules/es7.array.flat-map.js\");\n__webpack_require__(/*! ./modules/es7.array.flatten */ \"./node_modules/core-js/modules/es7.array.flatten.js\");\n__webpack_require__(/*! ./modules/es7.string.at */ \"./node_modules/core-js/modules/es7.string.at.js\");\n__webpack_require__(/*! ./modules/es7.string.pad-start */ \"./node_modules/core-js/modules/es7.string.pad-start.js\");\n__webpack_require__(/*! ./modules/es7.string.pad-end */ \"./node_modules/core-js/modules/es7.string.pad-end.js\");\n__webpack_require__(/*! ./modules/es7.string.trim-left */ \"./node_modules/core-js/modules/es7.string.trim-left.js\");\n__webpack_require__(/*! ./modules/es7.string.trim-right */ \"./node_modules/core-js/modules/es7.string.trim-right.js\");\n__webpack_require__(/*! ./modules/es7.string.match-all */ \"./node_modules/core-js/modules/es7.string.match-all.js\");\n__webpack_require__(/*! ./modules/es7.symbol.async-iterator */ \"./node_modules/core-js/modules/es7.symbol.async-iterator.js\");\n__webpack_require__(/*! ./modules/es7.symbol.observable */ \"./node_modules/core-js/modules/es7.symbol.observable.js\");\n__webpack_require__(/*! ./modules/es7.object.get-own-property-descriptors */ \"./node_modules/core-js/modules/es7.object.get-own-property-descriptors.js\");\n__webpack_require__(/*! ./modules/es7.object.values */ \"./node_modules/core-js/modules/es7.object.values.js\");\n__webpack_require__(/*! ./modules/es7.object.entries */ \"./node_modules/core-js/modules/es7.object.entries.js\");\n__webpack_require__(/*! ./modules/es7.object.define-getter */ \"./node_modules/core-js/modules/es7.object.define-getter.js\");\n__webpack_require__(/*! ./modules/es7.object.define-setter */ \"./node_modules/core-js/modules/es7.object.define-setter.js\");\n__webpack_require__(/*! ./modules/es7.object.lookup-getter */ \"./node_modules/core-js/modules/es7.object.lookup-getter.js\");\n__webpack_require__(/*! ./modules/es7.object.lookup-setter */ \"./node_modules/core-js/modules/es7.object.lookup-setter.js\");\n__webpack_require__(/*! ./modules/es7.map.to-json */ \"./node_modules/core-js/modules/es7.map.to-json.js\");\n__webpack_require__(/*! ./modules/es7.set.to-json */ \"./node_modules/core-js/modules/es7.set.to-json.js\");\n__webpack_require__(/*! ./modules/es7.map.of */ \"./node_modules/core-js/modules/es7.map.of.js\");\n__webpack_require__(/*! ./modules/es7.set.of */ \"./node_modules/core-js/modules/es7.set.of.js\");\n__webpack_require__(/*! ./modules/es7.weak-map.of */ \"./node_modules/core-js/modules/es7.weak-map.of.js\");\n__webpack_require__(/*! ./modules/es7.weak-set.of */ \"./node_modules/core-js/modules/es7.weak-set.of.js\");\n__webpack_require__(/*! ./modules/es7.map.from */ \"./node_modules/core-js/modules/es7.map.from.js\");\n__webpack_require__(/*! ./modules/es7.set.from */ \"./node_modules/core-js/modules/es7.set.from.js\");\n__webpack_require__(/*! ./modules/es7.weak-map.from */ \"./node_modules/core-js/modules/es7.weak-map.from.js\");\n__webpack_require__(/*! ./modules/es7.weak-set.from */ \"./node_modules/core-js/modules/es7.weak-set.from.js\");\n__webpack_require__(/*! ./modules/es7.global */ \"./node_modules/core-js/modules/es7.global.js\");\n__webpack_require__(/*! ./modules/es7.system.global */ \"./node_modules/core-js/modules/es7.system.global.js\");\n__webpack_require__(/*! ./modules/es7.error.is-error */ \"./node_modules/core-js/modules/es7.error.is-error.js\");\n__webpack_require__(/*! ./modules/es7.math.clamp */ \"./node_modules/core-js/modules/es7.math.clamp.js\");\n__webpack_require__(/*! ./modules/es7.math.deg-per-rad */ \"./node_modules/core-js/modules/es7.math.deg-per-rad.js\");\n__webpack_require__(/*! ./modules/es7.math.degrees */ \"./node_modules/core-js/modules/es7.math.degrees.js\");\n__webpack_require__(/*! ./modules/es7.math.fscale */ \"./node_modules/core-js/modules/es7.math.fscale.js\");\n__webpack_require__(/*! ./modules/es7.math.iaddh */ \"./node_modules/core-js/modules/es7.math.iaddh.js\");\n__webpack_require__(/*! ./modules/es7.math.isubh */ \"./node_modules/core-js/modules/es7.math.isubh.js\");\n__webpack_require__(/*! ./modules/es7.math.imulh */ \"./node_modules/core-js/modules/es7.math.imulh.js\");\n__webpack_require__(/*! ./modules/es7.math.rad-per-deg */ \"./node_modules/core-js/modules/es7.math.rad-per-deg.js\");\n__webpack_require__(/*! ./modules/es7.math.radians */ \"./node_modules/core-js/modules/es7.math.radians.js\");\n__webpack_require__(/*! ./modules/es7.math.scale */ \"./node_modules/core-js/modules/es7.math.scale.js\");\n__webpack_require__(/*! ./modules/es7.math.umulh */ \"./node_modules/core-js/modules/es7.math.umulh.js\");\n__webpack_require__(/*! ./modules/es7.math.signbit */ \"./node_modules/core-js/modules/es7.math.signbit.js\");\n__webpack_require__(/*! ./modules/es7.promise.finally */ \"./node_modules/core-js/modules/es7.promise.finally.js\");\n__webpack_require__(/*! ./modules/es7.promise.try */ \"./node_modules/core-js/modules/es7.promise.try.js\");\n__webpack_require__(/*! ./modules/es7.reflect.define-metadata */ \"./node_modules/core-js/modules/es7.reflect.define-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.delete-metadata */ \"./node_modules/core-js/modules/es7.reflect.delete-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-metadata */ \"./node_modules/core-js/modules/es7.reflect.get-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-metadata-keys */ \"./node_modules/core-js/modules/es7.reflect.get-metadata-keys.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-own-metadata */ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.get-own-metadata-keys */ \"./node_modules/core-js/modules/es7.reflect.get-own-metadata-keys.js\");\n__webpack_require__(/*! ./modules/es7.reflect.has-metadata */ \"./node_modules/core-js/modules/es7.reflect.has-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.has-own-metadata */ \"./node_modules/core-js/modules/es7.reflect.has-own-metadata.js\");\n__webpack_require__(/*! ./modules/es7.reflect.metadata */ \"./node_modules/core-js/modules/es7.reflect.metadata.js\");\n__webpack_require__(/*! ./modules/es7.asap */ \"./node_modules/core-js/modules/es7.asap.js\");\n__webpack_require__(/*! ./modules/es7.observable */ \"./node_modules/core-js/modules/es7.observable.js\");\n__webpack_require__(/*! ./modules/web.timers */ \"./node_modules/core-js/modules/web.timers.js\");\n__webpack_require__(/*! ./modules/web.immediate */ \"./node_modules/core-js/modules/web.immediate.js\");\n__webpack_require__(/*! ./modules/web.dom.iterable */ \"./node_modules/core-js/modules/web.dom.iterable.js\");\nmodule.exports = __webpack_require__(/*! ./modules/_core */ \"./node_modules/core-js/modules/_core.js\");\n\n\n/***/ }),\n\n/***/ \"./node_modules/ieee754/index.js\":\n/*!***************************************!*\\\n  !*** ./node_modules/ieee754/index.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n  var e, m\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var nBits = -7\n  var i = isLE ? (nBytes - 1) : 0\n  var d = isLE ? -1 : 1\n  var s = buffer[offset + i]\n\n  i += d\n\n  e = s & ((1 << (-nBits)) - 1)\n  s >>= (-nBits)\n  nBits += eLen\n  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  m = e & ((1 << (-nBits)) - 1)\n  e >>= (-nBits)\n  nBits += mLen\n  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n  if (e === 0) {\n    e = 1 - eBias\n  } else if (e === eMax) {\n    return m ? NaN : ((s ? -1 : 1) * Infinity)\n  } else {\n    m = m + Math.pow(2, mLen)\n    e = e - eBias\n  }\n  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n  var e, m, c\n  var eLen = (nBytes * 8) - mLen - 1\n  var eMax = (1 << eLen) - 1\n  var eBias = eMax >> 1\n  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n  var i = isLE ? 0 : (nBytes - 1)\n  var d = isLE ? 1 : -1\n  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n  value = Math.abs(value)\n\n  if (isNaN(value) || value === Infinity) {\n    m = isNaN(value) ? 1 : 0\n    e = eMax\n  } else {\n    e = Math.floor(Math.log(value) / Math.LN2)\n    if (value * (c = Math.pow(2, -e)) < 1) {\n      e--\n      c *= 2\n    }\n    if (e + eBias >= 1) {\n      value += rt / c\n    } else {\n      value += rt * Math.pow(2, 1 - eBias)\n    }\n    if (value * c >= 2) {\n      e++\n      c /= 2\n    }\n\n    if (e + eBias >= eMax) {\n      m = 0\n      e = eMax\n    } else if (e + eBias >= 1) {\n      m = ((value * c) - 1) * Math.pow(2, mLen)\n      e = e + eBias\n    } else {\n      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n      e = 0\n    }\n  }\n\n  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n  e = (e << mLen) | m\n  eLen += mLen\n  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n  buffer[offset + i - d] |= s * 128\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/bytesToUuid.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/bytesToUuid.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\nvar byteToHex = [];\nfor (var i = 0; i < 256; ++i) {\n  byteToHex[i] = (i + 0x100).toString(16).substr(1);\n}\n\nfunction bytesToUuid(buf, offset) {\n  var i = offset || 0;\n  var bth = byteToHex;\n  // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4\n  return ([bth[buf[i++]], bth[buf[i++]], \n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]], '-',\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]],\n\tbth[buf[i++]], bth[buf[i++]]]).join('');\n}\n\nmodule.exports = bytesToUuid;\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/lib/rng-browser.js\":\n/*!**********************************************!*\\\n  !*** ./node_modules/uuid/lib/rng-browser.js ***!\n  \\**********************************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\n// Unique ID creation requires a high quality random # generator.  In the\n// browser this is a little complicated due to unknown quality of Math.random()\n// and inconsistent support for the `crypto` API.  We do the best we can via\n// feature-detection\n\n// getRandomValues needs to be invoked in a context where \"this\" is a Crypto\n// implementation. Also, find the complete implementation of crypto on IE11.\nvar getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||\n                      (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));\n\nif (getRandomValues) {\n  // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto\n  var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef\n\n  module.exports = function whatwgRNG() {\n    getRandomValues(rnds8);\n    return rnds8;\n  };\n} else {\n  // Math.random()-based (RNG)\n  //\n  // If all else fails, use Math.random().  It's fast, but is of unspecified\n  // quality.\n  var rnds = new Array(16);\n\n  module.exports = function mathRNG() {\n    for (var i = 0, r; i < 16; i++) {\n      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;\n      rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;\n    }\n\n    return rnds;\n  };\n}\n\n\n/***/ }),\n\n/***/ \"./node_modules/uuid/v4.js\":\n/*!*********************************!*\\\n  !*** ./node_modules/uuid/v4.js ***!\n  \\*********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar rng = __webpack_require__(/*! ./lib/rng */ \"./node_modules/uuid/lib/rng-browser.js\");\nvar bytesToUuid = __webpack_require__(/*! ./lib/bytesToUuid */ \"./node_modules/uuid/lib/bytesToUuid.js\");\n\nfunction v4(options, buf, offset) {\n  var i = buf && offset || 0;\n\n  if (typeof(options) == 'string') {\n    buf = options === 'binary' ? new Array(16) : null;\n    options = null;\n  }\n  options = options || {};\n\n  var rnds = options.random || (options.rng || rng)();\n\n  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n  rnds[6] = (rnds[6] & 0x0f) | 0x40;\n  rnds[8] = (rnds[8] & 0x3f) | 0x80;\n\n  // Copy bytes to buffer, if provided\n  if (buf) {\n    for (var ii = 0; ii < 16; ++ii) {\n      buf[i + ii] = rnds[ii];\n    }\n  }\n\n  return buf || bytesToUuid(rnds);\n}\n\nmodule.exports = v4;\n\n\n/***/ }),\n\n/***/ \"./node_modules/webpack/buildin/global.js\":\n/*!***********************************!*\\\n  !*** (webpack)/buildin/global.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports) {\n\nvar g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n/***/ }),\n\n/***/ \"./src/AccessTokenEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/AccessTokenEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AccessTokenEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Timer = __webpack_require__(/*! ./Timer.js */ \"./src/Timer.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60; // seconds\n\nvar AccessTokenEvents = exports.AccessTokenEvents = function () {\n    function AccessTokenEvents() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$accessTokenExpir2 = _ref.accessTokenExpiringTimer,\n            accessTokenExpiringTimer = _ref$accessTokenExpir2 === undefined ? new _Timer.Timer(\"Access token expiring\") : _ref$accessTokenExpir2,\n            _ref$accessTokenExpir3 = _ref.accessTokenExpiredTimer,\n            accessTokenExpiredTimer = _ref$accessTokenExpir3 === undefined ? new _Timer.Timer(\"Access token expired\") : _ref$accessTokenExpir3;\n\n        _classCallCheck(this, AccessTokenEvents);\n\n        this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        this._accessTokenExpiring = accessTokenExpiringTimer;\n        this._accessTokenExpired = accessTokenExpiredTimer;\n    }\n\n    AccessTokenEvents.prototype.load = function load(container) {\n        // only register events if there's an access token and it has an expiration\n        if (container.access_token && container.expires_in !== undefined) {\n            var duration = container.expires_in;\n            _Log.Log.debug(\"AccessTokenEvents.load: access token present, remaining duration:\", duration);\n\n            if (duration > 0) {\n                // only register expiring if we still have time\n                var expiring = duration - this._accessTokenExpiringNotificationTime;\n                if (expiring <= 0) {\n                    expiring = 1;\n                }\n\n                _Log.Log.debug(\"AccessTokenEvents.load: registering expiring timer in:\", expiring);\n                this._accessTokenExpiring.init(expiring);\n            } else {\n                _Log.Log.debug(\"AccessTokenEvents.load: canceling existing expiring timer becase we're past expiration.\");\n                this._accessTokenExpiring.cancel();\n            }\n\n            // if it's negative, it will still fire\n            var expired = duration + 1;\n            _Log.Log.debug(\"AccessTokenEvents.load: registering expired timer in:\", expired);\n            this._accessTokenExpired.init(expired);\n        } else {\n            this._accessTokenExpiring.cancel();\n            this._accessTokenExpired.cancel();\n        }\n    };\n\n    AccessTokenEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"AccessTokenEvents.unload: canceling existing access token timers\");\n        this._accessTokenExpiring.cancel();\n        this._accessTokenExpired.cancel();\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpiring = function addAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpiring = function removeAccessTokenExpiring(cb) {\n        this._accessTokenExpiring.removeHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.addAccessTokenExpired = function addAccessTokenExpired(cb) {\n        this._accessTokenExpired.addHandler(cb);\n    };\n\n    AccessTokenEvents.prototype.removeAccessTokenExpired = function removeAccessTokenExpired(cb) {\n        this._accessTokenExpired.removeHandler(cb);\n    };\n\n    return AccessTokenEvents;\n}();\n\n/***/ }),\n\n/***/ \"./src/CheckSessionIFrame.js\":\n/*!***********************************!*\\\n  !*** ./src/CheckSessionIFrame.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CheckSessionIFrame = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultInterval = 2000;\n\nvar CheckSessionIFrame = exports.CheckSessionIFrame = function () {\n    function CheckSessionIFrame(callback, client_id, url, interval) {\n        var stopOnError = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n\n        _classCallCheck(this, CheckSessionIFrame);\n\n        this._callback = callback;\n        this._client_id = client_id;\n        this._url = url;\n        this._interval = interval || DefaultInterval;\n        this._stopOnError = stopOnError;\n\n        var idx = url.indexOf(\"/\", url.indexOf(\"//\") + 2);\n        this._frame_origin = url.substr(0, idx);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        this._frame.src = url;\n    }\n\n    CheckSessionIFrame.prototype.load = function load() {\n        var _this = this;\n\n        return new Promise(function (resolve) {\n            _this._frame.onload = function () {\n                resolve();\n            };\n\n            window.document.body.appendChild(_this._frame);\n            _this._boundMessageEvent = _this._message.bind(_this);\n            window.addEventListener(\"message\", _this._boundMessageEvent, false);\n        });\n    };\n\n    CheckSessionIFrame.prototype._message = function _message(e) {\n        if (e.origin === this._frame_origin && e.source === this._frame.contentWindow) {\n            if (e.data === \"error\") {\n                _Log.Log.error(\"CheckSessionIFrame: error message from check session op iframe\");\n                if (this._stopOnError) {\n                    this.stop();\n                }\n            } else if (e.data === \"changed\") {\n                _Log.Log.debug(\"CheckSessionIFrame: changed message from check session op iframe\");\n                this.stop();\n                this._callback();\n            } else {\n                _Log.Log.debug(\"CheckSessionIFrame: \" + e.data + \" message from check session op iframe\");\n            }\n        }\n    };\n\n    CheckSessionIFrame.prototype.start = function start(session_state) {\n        var _this2 = this;\n\n        if (this._session_state !== session_state) {\n            _Log.Log.debug(\"CheckSessionIFrame.start\");\n\n            this.stop();\n\n            this._session_state = session_state;\n\n            var send = function send() {\n                _this2._frame.contentWindow.postMessage(_this2._client_id + \" \" + _this2._session_state, _this2._frame_origin);\n            };\n\n            // trigger now\n            send();\n\n            // and setup timer\n            this._timer = window.setInterval(send, this._interval);\n        }\n    };\n\n    CheckSessionIFrame.prototype.stop = function stop() {\n        this._session_state = null;\n\n        if (this._timer) {\n            _Log.Log.debug(\"CheckSessionIFrame.stop\");\n\n            window.clearInterval(this._timer);\n            this._timer = null;\n        }\n    };\n\n    return CheckSessionIFrame;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaIFrameNavigator.js\":\n/*!***************************************!*\\\n  !*** ./src/CordovaIFrameNavigator.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaIFrameNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaIFrameNavigator = exports.CordovaIFrameNavigator = function () {\n    function CordovaIFrameNavigator() {\n        _classCallCheck(this, CordovaIFrameNavigator);\n    }\n\n    CordovaIFrameNavigator.prototype.prepare = function prepare(params) {\n        params.popupWindowFeatures = 'hidden=yes';\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaIFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupNavigator.js\":\n/*!**************************************!*\\\n  !*** ./src/CordovaPopupNavigator.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupNavigator = undefined;\n\nvar _CordovaPopupWindow = __webpack_require__(/*! ./CordovaPopupWindow.js */ \"./src/CordovaPopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar CordovaPopupNavigator = exports.CordovaPopupNavigator = function () {\n    function CordovaPopupNavigator() {\n        _classCallCheck(this, CordovaPopupNavigator);\n    }\n\n    CordovaPopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _CordovaPopupWindow.CordovaPopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    return CordovaPopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/CordovaPopupWindow.js\":\n/*!***********************************!*\\\n  !*** ./src/CordovaPopupWindow.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.CordovaPopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultPopupFeatures = 'location=no,toolbar=no,zoom=no';\nvar DefaultPopupTarget = \"_blank\";\n\nvar CordovaPopupWindow = exports.CordovaPopupWindow = function () {\n    function CordovaPopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, CordovaPopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this.features = params.popupWindowFeatures || DefaultPopupFeatures;\n        this.target = params.popupWindowTarget || DefaultPopupTarget;\n\n        this.redirect_uri = params.startUrl;\n        _Log.Log.debug(\"CordovaPopupWindow.ctor: redirect_uri: \" + this.redirect_uri);\n    }\n\n    CordovaPopupWindow.prototype._isInAppBrowserInstalled = function _isInAppBrowserInstalled(cordovaMetadata) {\n        return [\"cordova-plugin-inappbrowser\", \"cordova-plugin-inappbrowser.inappbrowser\", \"org.apache.cordova.inappbrowser\"].some(function (name) {\n            return cordovaMetadata.hasOwnProperty(name);\n        });\n    };\n\n    CordovaPopupWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            if (!window.cordova) {\n                return this._error(\"cordova is undefined\");\n            }\n\n            var cordovaMetadata = window.cordova.require(\"cordova/plugin_list\").metadata;\n            if (this._isInAppBrowserInstalled(cordovaMetadata) === false) {\n                return this._error(\"InAppBrowser plugin not found\");\n            }\n            this._popup = cordova.InAppBrowser.open(params.url, this.target, this.features);\n            if (this._popup) {\n                _Log.Log.debug(\"CordovaPopupWindow.navigate: popup successfully created\");\n\n                this._exitCallbackEvent = this._exitCallback.bind(this);\n                this._loadStartCallbackEvent = this._loadStartCallback.bind(this);\n\n                this._popup.addEventListener(\"exit\", this._exitCallbackEvent, false);\n                this._popup.addEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            } else {\n                this._error(\"Error opening popup window\");\n            }\n        }\n        return this.promise;\n    };\n\n    CordovaPopupWindow.prototype._loadStartCallback = function _loadStartCallback(event) {\n        if (event.url.indexOf(this.redirect_uri) === 0) {\n            this._success({ url: event.url });\n        }\n    };\n\n    CordovaPopupWindow.prototype._exitCallback = function _exitCallback(message) {\n        this._error(message);\n    };\n\n    CordovaPopupWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"CordovaPopupWindow: Successful response from cordova popup window\");\n        this._resolve(data);\n    };\n\n    CordovaPopupWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    CordovaPopupWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    CordovaPopupWindow.prototype._cleanup = function _cleanup() {\n        if (this._popup) {\n            _Log.Log.debug(\"CordovaPopupWindow: cleaning up popup\");\n            this._popup.removeEventListener(\"exit\", this._exitCallbackEvent, false);\n            this._popup.removeEventListener(\"loadstart\", this._loadStartCallbackEvent, false);\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    _createClass(CordovaPopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return CordovaPopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/ErrorResponse.js\":\n/*!******************************!*\\\n  !*** ./src/ErrorResponse.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.ErrorResponse = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ErrorResponse = exports.ErrorResponse = function (_Error) {\n        _inherits(ErrorResponse, _Error);\n\n        function ErrorResponse() {\n                var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n                    error = _ref.error,\n                    error_description = _ref.error_description,\n                    error_uri = _ref.error_uri,\n                    state = _ref.state,\n                    session_state = _ref.session_state;\n\n                _classCallCheck(this, ErrorResponse);\n\n                if (!error) {\n                        _Log.Log.error(\"No error passed to ErrorResponse\");\n                        throw new Error(\"error\");\n                }\n\n                var _this = _possibleConstructorReturn(this, _Error.call(this, error_description || error));\n\n                _this.name = \"ErrorResponse\";\n\n                _this.error = error;\n                _this.error_description = error_description;\n                _this.error_uri = error_uri;\n\n                _this.state = state;\n                _this.session_state = session_state;\n                return _this;\n        }\n\n        return ErrorResponse;\n}(Error);\n\n/***/ }),\n\n/***/ \"./src/Event.js\":\n/*!**********************!*\\\n  !*** ./src/Event.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Event = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar Event = exports.Event = function () {\n    function Event(name) {\n        _classCallCheck(this, Event);\n\n        this._name = name;\n        this._callbacks = [];\n    }\n\n    Event.prototype.addHandler = function addHandler(cb) {\n        this._callbacks.push(cb);\n    };\n\n    Event.prototype.removeHandler = function removeHandler(cb) {\n        var idx = this._callbacks.findIndex(function (item) {\n            return item === cb;\n        });\n        if (idx >= 0) {\n            this._callbacks.splice(idx, 1);\n        }\n    };\n\n    Event.prototype.raise = function raise() {\n        _Log.Log.debug(\"Event: Raising event: \" + this._name);\n        for (var i = 0; i < this._callbacks.length; i++) {\n            var _callbacks;\n\n            (_callbacks = this._callbacks)[i].apply(_callbacks, arguments);\n        }\n    };\n\n    return Event;\n}();\n\n/***/ }),\n\n/***/ \"./src/Global.js\":\n/*!***********************!*\\\n  !*** ./src/Global.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar timer = {\n    setInterval: function (_setInterval) {\n        function setInterval(_x, _x2) {\n            return _setInterval.apply(this, arguments);\n        }\n\n        setInterval.toString = function () {\n            return _setInterval.toString();\n        };\n\n        return setInterval;\n    }(function (cb, duration) {\n        return setInterval(cb, duration);\n    }),\n    clearInterval: function (_clearInterval) {\n        function clearInterval(_x3) {\n            return _clearInterval.apply(this, arguments);\n        }\n\n        clearInterval.toString = function () {\n            return _clearInterval.toString();\n        };\n\n        return clearInterval;\n    }(function (handle) {\n        return clearInterval(handle);\n    })\n};\n\nvar testing = false;\nvar request = null;\n\nvar Global = exports.Global = function () {\n    function Global() {\n        _classCallCheck(this, Global);\n    }\n\n    Global._testing = function _testing() {\n        testing = true;\n    };\n\n    Global.setXMLHttpRequest = function setXMLHttpRequest(newRequest) {\n        request = newRequest;\n    };\n\n    _createClass(Global, null, [{\n        key: 'location',\n        get: function get() {\n            if (!testing) {\n                return location;\n            }\n        }\n    }, {\n        key: 'localStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return localStorage;\n            }\n        }\n    }, {\n        key: 'sessionStorage',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return sessionStorage;\n            }\n        }\n    }, {\n        key: 'XMLHttpRequest',\n        get: function get() {\n            if (!testing && typeof window !== 'undefined') {\n                return request || XMLHttpRequest;\n            }\n        }\n    }, {\n        key: 'timer',\n        get: function get() {\n            if (!testing) {\n                return timer;\n            }\n        }\n    }]);\n\n    return Global;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameNavigator.js\":\n/*!********************************!*\\\n  !*** ./src/IFrameNavigator.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _IFrameWindow = __webpack_require__(/*! ./IFrameWindow.js */ \"./src/IFrameWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar IFrameNavigator = exports.IFrameNavigator = function () {\n    function IFrameNavigator() {\n        _classCallCheck(this, IFrameNavigator);\n    }\n\n    IFrameNavigator.prototype.prepare = function prepare(params) {\n        var frame = new _IFrameWindow.IFrameWindow(params);\n        return Promise.resolve(frame);\n    };\n\n    IFrameNavigator.prototype.callback = function callback(url) {\n        _Log.Log.debug(\"IFrameNavigator.callback\");\n\n        try {\n            _IFrameWindow.IFrameWindow.notifyParent(url);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return IFrameNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/IFrameWindow.js\":\n/*!*****************************!*\\\n  !*** ./src/IFrameWindow.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.IFrameWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar DefaultTimeout = 10000;\n\nvar IFrameWindow = exports.IFrameWindow = function () {\n    function IFrameWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, IFrameWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        this._boundMessageEvent = this._message.bind(this);\n        window.addEventListener(\"message\", this._boundMessageEvent, false);\n\n        this._frame = window.document.createElement(\"iframe\");\n\n        // shotgun approach\n        this._frame.style.visibility = \"hidden\";\n        this._frame.style.position = \"absolute\";\n        this._frame.style.display = \"none\";\n        this._frame.style.width = 0;\n        this._frame.style.height = 0;\n\n        window.document.body.appendChild(this._frame);\n    }\n\n    IFrameWindow.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            this._error(\"No url provided\");\n        } else {\n            var timeout = params.silentRequestTimeout || DefaultTimeout;\n            _Log.Log.debug(\"IFrameWindow.navigate: Using timeout of:\", timeout);\n            this._timer = window.setTimeout(this._timeout.bind(this), timeout);\n            this._frame.src = params.url;\n        }\n\n        return this.promise;\n    };\n\n    IFrameWindow.prototype._success = function _success(data) {\n        this._cleanup();\n\n        _Log.Log.debug(\"IFrameWindow: Successful response from frame window\");\n        this._resolve(data);\n    };\n\n    IFrameWindow.prototype._error = function _error(message) {\n        this._cleanup();\n\n        _Log.Log.error(message);\n        this._reject(new Error(message));\n    };\n\n    IFrameWindow.prototype.close = function close() {\n        this._cleanup();\n    };\n\n    IFrameWindow.prototype._cleanup = function _cleanup() {\n        if (this._frame) {\n            _Log.Log.debug(\"IFrameWindow: cleanup\");\n\n            window.removeEventListener(\"message\", this._boundMessageEvent, false);\n            window.clearTimeout(this._timer);\n            window.document.body.removeChild(this._frame);\n\n            this._timer = null;\n            this._frame = null;\n            this._boundMessageEvent = null;\n        }\n    };\n\n    IFrameWindow.prototype._timeout = function _timeout() {\n        _Log.Log.debug(\"IFrameWindow.timeout\");\n        this._error(\"Frame window timed out\");\n    };\n\n    IFrameWindow.prototype._message = function _message(e) {\n        _Log.Log.debug(\"IFrameWindow.message\");\n\n        if (this._timer && e.origin === this._origin && e.source === this._frame.contentWindow) {\n            var url = e.data;\n            if (url) {\n                this._success({ url: url });\n            } else {\n                this._error(\"Invalid response from frame\");\n            }\n        }\n    };\n\n    IFrameWindow.notifyParent = function notifyParent(url) {\n        _Log.Log.debug(\"IFrameWindow.notifyParent\");\n        if (window.frameElement) {\n            url = url || window.location.href;\n            if (url) {\n                _Log.Log.debug(\"IFrameWindow.notifyParent: posting url message to parent\");\n                window.parent.postMessage(url, location.protocol + \"//\" + location.host);\n            }\n        }\n    };\n\n    _createClass(IFrameWindow, [{\n        key: \"promise\",\n        get: function get() {\n            return this._promise;\n        }\n    }, {\n        key: \"_origin\",\n        get: function get() {\n            return location.protocol + \"//\" + location.host;\n        }\n    }]);\n\n    return IFrameWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/InMemoryWebStorage.js\":\n/*!***********************************!*\\\n  !*** ./src/InMemoryWebStorage.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.InMemoryWebStorage = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar InMemoryWebStorage = exports.InMemoryWebStorage = function () {\n    function InMemoryWebStorage() {\n        _classCallCheck(this, InMemoryWebStorage);\n\n        this._data = {};\n    }\n\n    InMemoryWebStorage.prototype.getItem = function getItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.getItem\", key);\n        return this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.setItem = function setItem(key, value) {\n        _Log.Log.debug(\"InMemoryWebStorage.setItem\", key);\n        this._data[key] = value;\n    };\n\n    InMemoryWebStorage.prototype.removeItem = function removeItem(key) {\n        _Log.Log.debug(\"InMemoryWebStorage.removeItem\", key);\n        delete this._data[key];\n    };\n\n    InMemoryWebStorage.prototype.key = function key(index) {\n        return Object.getOwnPropertyNames(this._data)[index];\n    };\n\n    _createClass(InMemoryWebStorage, [{\n        key: \"length\",\n        get: function get() {\n            return Object.getOwnPropertyNames(this._data).length;\n        }\n    }]);\n\n    return InMemoryWebStorage;\n}();\n\n/***/ }),\n\n/***/ \"./src/JoseUtil.js\":\n/*!*************************!*\\\n  !*** ./src/JoseUtil.js ***!\n  \\*************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.JoseUtil = undefined;\n\nvar _jsrsasign = __webpack_require__(/*! ./crypto/jsrsasign */ \"./src/crypto/jsrsasign.js\");\n\nvar _JoseUtilImpl = __webpack_require__(/*! ./JoseUtilImpl */ \"./src/JoseUtilImpl.js\");\n\nvar _JoseUtilImpl2 = _interopRequireDefault(_JoseUtilImpl);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar JoseUtil = exports.JoseUtil = (0, _JoseUtilImpl2.default)({ jws: _jsrsasign.jws, KeyUtil: _jsrsasign.KeyUtil, X509: _jsrsasign.X509, crypto: _jsrsasign.crypto, hextob64u: _jsrsasign.hextob64u, b64tohex: _jsrsasign.b64tohex, AllowedSigningAlgs: _jsrsasign.AllowedSigningAlgs });\n\n/***/ }),\n\n/***/ \"./src/JoseUtilImpl.js\":\n/*!*****************************!*\\\n  !*** ./src/JoseUtilImpl.js ***!\n  \\*****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.default = getJoseUtil;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nfunction getJoseUtil(_ref) {\n    var jws = _ref.jws,\n        KeyUtil = _ref.KeyUtil,\n        X509 = _ref.X509,\n        crypto = _ref.crypto,\n        hextob64u = _ref.hextob64u,\n        b64tohex = _ref.b64tohex,\n        AllowedSigningAlgs = _ref.AllowedSigningAlgs;\n\n    return function () {\n        function JoseUtil() {\n            _classCallCheck(this, JoseUtil);\n        }\n\n        JoseUtil.parseJwt = function parseJwt(jwt) {\n            _Log.Log.debug(\"JoseUtil.parseJwt\");\n            try {\n                var token = jws.JWS.parse(jwt);\n                return {\n                    header: token.headerObj,\n                    payload: token.payloadObj\n                };\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.validateJwt = function validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n            _Log.Log.debug(\"JoseUtil.validateJwt\");\n\n            try {\n                if (key.kty === \"RSA\") {\n                    if (key.e && key.n) {\n                        key = KeyUtil.getKey(key);\n                    } else if (key.x5c && key.x5c.length) {\n                        var hex = b64tohex(key.x5c[0]);\n                        key = X509.getPublicKeyFromCertHex(hex);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: RSA key missing key material\", key);\n                        return Promise.reject(new Error(\"RSA key missing key material\"));\n                    }\n                } else if (key.kty === \"EC\") {\n                    if (key.crv && key.x && key.y) {\n                        key = KeyUtil.getKey(key);\n                    } else {\n                        _Log.Log.error(\"JoseUtil.validateJwt: EC key missing key material\", key);\n                        return Promise.reject(new Error(\"EC key missing key material\"));\n                    }\n                } else {\n                    _Log.Log.error(\"JoseUtil.validateJwt: Unsupported key type\", key && key.kty);\n                    return Promise.reject(new Error( true && key.kty));\n                }\n\n                return JoseUtil._validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive);\n            } catch (e) {\n                _Log.Log.error(e && e.message || e);\n                return Promise.reject(\"JWT validation failed\");\n            }\n        };\n\n        JoseUtil.validateJwtAttributes = function validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive) {\n            if (!clockSkew) {\n                clockSkew = 0;\n            }\n\n            if (!now) {\n                now = parseInt(Date.now() / 1000);\n            }\n\n            var payload = JoseUtil.parseJwt(jwt).payload;\n\n            if (!payload.iss) {\n                _Log.Log.error(\"JoseUtil._validateJwt: issuer was not provided\");\n                return Promise.reject(new Error(\"issuer was not provided\"));\n            }\n            if (payload.iss !== issuer) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid issuer in token\", payload.iss);\n                return Promise.reject(new Error(\"Invalid issuer in token: \" + payload.iss));\n            }\n\n            if (!payload.aud) {\n                _Log.Log.error(\"JoseUtil._validateJwt: aud was not provided\");\n                return Promise.reject(new Error(\"aud was not provided\"));\n            }\n            var validAudience = payload.aud === audience || Array.isArray(payload.aud) && payload.aud.indexOf(audience) >= 0;\n            if (!validAudience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid audience in token\", payload.aud);\n                return Promise.reject(new Error(\"Invalid audience in token: \" + payload.aud));\n            }\n            if (payload.azp && payload.azp !== audience) {\n                _Log.Log.error(\"JoseUtil._validateJwt: Invalid azp in token\", payload.azp);\n                return Promise.reject(new Error(\"Invalid azp in token: \" + payload.azp));\n            }\n\n            if (!timeInsensitive) {\n                var lowerNow = now + clockSkew;\n                var upperNow = now - clockSkew;\n\n                if (!payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat was not provided\");\n                    return Promise.reject(new Error(\"iat was not provided\"));\n                }\n                if (lowerNow < payload.iat) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: iat is in the future\", payload.iat);\n                    return Promise.reject(new Error(\"iat is in the future: \" + payload.iat));\n                }\n\n                if (payload.nbf && lowerNow < payload.nbf) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: nbf is in the future\", payload.nbf);\n                    return Promise.reject(new Error(\"nbf is in the future: \" + payload.nbf));\n                }\n\n                if (!payload.exp) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp was not provided\");\n                    return Promise.reject(new Error(\"exp was not provided\"));\n                }\n                if (payload.exp < upperNow) {\n                    _Log.Log.error(\"JoseUtil._validateJwt: exp is in the past\", payload.exp);\n                    return Promise.reject(new Error(\"exp is in the past:\" + payload.exp));\n                }\n            }\n\n            return Promise.resolve(payload);\n        };\n\n        JoseUtil._validateJwt = function _validateJwt(jwt, key, issuer, audience, clockSkew, now, timeInsensitive) {\n\n            return JoseUtil.validateJwtAttributes(jwt, issuer, audience, clockSkew, now, timeInsensitive).then(function (payload) {\n                try {\n                    if (!jws.JWS.verify(jwt, key, AllowedSigningAlgs)) {\n                        _Log.Log.error(\"JoseUtil._validateJwt: signature validation failed\");\n                        return Promise.reject(new Error(\"signature validation failed\"));\n                    }\n\n                    return payload;\n                } catch (e) {\n                    _Log.Log.error(e && e.message || e);\n                    return Promise.reject(new Error(\"signature validation failed\"));\n                }\n            });\n        };\n\n        JoseUtil.hashString = function hashString(value, alg) {\n            try {\n                return crypto.Util.hashString(value, alg);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        JoseUtil.hexToBase64Url = function hexToBase64Url(value) {\n            try {\n                return hextob64u(value);\n            } catch (e) {\n                _Log.Log.error(e);\n            }\n        };\n\n        return JoseUtil;\n    }();\n}\nmodule.exports = exports[\"default\"];\n\n/***/ }),\n\n/***/ \"./src/JsonService.js\":\n/*!****************************!*\\\n  !*** ./src/JsonService.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.JsonService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar JsonService = exports.JsonService = function () {\n    function JsonService() {\n        var additionalContentTypes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var jwtHandler = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n\n        _classCallCheck(this, JsonService);\n\n        if (additionalContentTypes && Array.isArray(additionalContentTypes)) {\n            this._contentTypes = additionalContentTypes.slice();\n        } else {\n            this._contentTypes = [];\n        }\n        this._contentTypes.push('application/json');\n        if (jwtHandler) {\n            this._contentTypes.push('application/jwt');\n        }\n\n        this._XMLHttpRequest = XMLHttpRequestCtor;\n        this._jwtHandler = jwtHandler;\n    }\n\n    JsonService.prototype.getJson = function getJson(url, token) {\n        var _this = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.getJson: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.getJson, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this._XMLHttpRequest();\n            req.open('GET', url);\n\n            var allowedContentTypes = _this._contentTypes;\n            var jwtHandler = _this._jwtHandler;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.getJson: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found == \"application/jwt\") {\n                            jwtHandler(req).then(resolve, reject);\n                            return;\n                        }\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.getJson: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                } else {\n                    reject(Error(req.statusText + \" (\" + req.status + \")\"));\n                }\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.getJson: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            if (token) {\n                _Log.Log.debug(\"JsonService.getJson: token passed, setting Authorization header\");\n                req.setRequestHeader(\"Authorization\", \"Bearer \" + token);\n            }\n\n            req.send();\n        });\n    };\n\n    JsonService.prototype.postForm = function postForm(url, payload) {\n        var _this2 = this;\n\n        if (!url) {\n            _Log.Log.error(\"JsonService.postForm: No url passed\");\n            throw new Error(\"url\");\n        }\n\n        _Log.Log.debug(\"JsonService.postForm, url: \", url);\n\n        return new Promise(function (resolve, reject) {\n\n            var req = new _this2._XMLHttpRequest();\n            req.open('POST', url);\n\n            var allowedContentTypes = _this2._contentTypes;\n\n            req.onload = function () {\n                _Log.Log.debug(\"JsonService.postForm: HTTP response received, status\", req.status);\n\n                if (req.status === 200) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                resolve(JSON.parse(req.responseText));\n                                return;\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n\n                    reject(Error(\"Invalid response Content-Type: \" + contentType + \", from URL: \" + url));\n                    return;\n                }\n\n                if (req.status === 400) {\n\n                    var contentType = req.getResponseHeader(\"Content-Type\");\n                    if (contentType) {\n\n                        var found = allowedContentTypes.find(function (item) {\n                            if (contentType.startsWith(item)) {\n                                return true;\n                            }\n                        });\n\n                        if (found) {\n                            try {\n                                var payload = JSON.parse(req.responseText);\n                                if (payload && payload.error) {\n                                    _Log.Log.error(\"JsonService.postForm: Error from server: \", payload.error);\n                                    reject(new Error(payload.error));\n                                    return;\n                                }\n                            } catch (e) {\n                                _Log.Log.error(\"JsonService.postForm: Error parsing JSON response\", e.message);\n                                reject(e);\n                                return;\n                            }\n                        }\n                    }\n                }\n\n                reject(Error(req.statusText + \" (\" + req.status + \")\"));\n            };\n\n            req.onerror = function () {\n                _Log.Log.error(\"JsonService.postForm: network error\");\n                reject(Error(\"Network Error\"));\n            };\n\n            var body = \"\";\n            for (var key in payload) {\n\n                var value = payload[key];\n\n                if (value) {\n\n                    if (body.length > 0) {\n                        body += \"&\";\n                    }\n\n                    body += encodeURIComponent(key);\n                    body += \"=\";\n                    body += encodeURIComponent(value);\n                }\n            }\n\n            req.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            req.send(body);\n        });\n    };\n\n    return JsonService;\n}();\n\n/***/ }),\n\n/***/ \"./src/Log.js\":\n/*!********************!*\\\n  !*** ./src/Log.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar nopLogger = {\n    debug: function debug() {},\n    info: function info() {},\n    warn: function warn() {},\n    error: function error() {}\n};\n\nvar NONE = 0;\nvar ERROR = 1;\nvar WARN = 2;\nvar INFO = 3;\nvar DEBUG = 4;\n\nvar logger = void 0;\nvar level = void 0;\n\nvar Log = exports.Log = function () {\n    function Log() {\n        _classCallCheck(this, Log);\n    }\n\n    Log.reset = function reset() {\n        level = INFO;\n        logger = nopLogger;\n    };\n\n    Log.debug = function debug() {\n        if (level >= DEBUG) {\n            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n                args[_key] = arguments[_key];\n            }\n\n            logger.debug.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.info = function info() {\n        if (level >= INFO) {\n            for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n                args[_key2] = arguments[_key2];\n            }\n\n            logger.info.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.warn = function warn() {\n        if (level >= WARN) {\n            for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n                args[_key3] = arguments[_key3];\n            }\n\n            logger.warn.apply(logger, Array.from(args));\n        }\n    };\n\n    Log.error = function error() {\n        if (level >= ERROR) {\n            for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n                args[_key4] = arguments[_key4];\n            }\n\n            logger.error.apply(logger, Array.from(args));\n        }\n    };\n\n    _createClass(Log, null, [{\n        key: \"NONE\",\n        get: function get() {\n            return NONE;\n        }\n    }, {\n        key: \"ERROR\",\n        get: function get() {\n            return ERROR;\n        }\n    }, {\n        key: \"WARN\",\n        get: function get() {\n            return WARN;\n        }\n    }, {\n        key: \"INFO\",\n        get: function get() {\n            return INFO;\n        }\n    }, {\n        key: \"DEBUG\",\n        get: function get() {\n            return DEBUG;\n        }\n    }, {\n        key: \"level\",\n        get: function get() {\n            return level;\n        },\n        set: function set(value) {\n            if (NONE <= value && value <= DEBUG) {\n                level = value;\n            } else {\n                throw new Error(\"Invalid log level\");\n            }\n        }\n    }, {\n        key: \"logger\",\n        get: function get() {\n            return logger;\n        },\n        set: function set(value) {\n            if (!value.debug && value.info) {\n                // just to stay backwards compat. can remove in 2.0\n                value.debug = value.info;\n            }\n\n            if (value.debug && value.info && value.warn && value.error) {\n                logger = value;\n            } else {\n                throw new Error(\"Invalid logger\");\n            }\n        }\n    }]);\n\n    return Log;\n}();\n\nLog.reset();\n\n/***/ }),\n\n/***/ \"./src/MetadataService.js\":\n/*!********************************!*\\\n  !*** ./src/MetadataService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.MetadataService = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar MetadataService = exports.MetadataService = function () {\n    function MetadataService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n\n        _classCallCheck(this, MetadataService);\n\n        if (!settings) {\n            _Log.Log.error(\"MetadataService: No settings passed to MetadataService\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(['application/jwk-set+json']);\n    }\n\n    MetadataService.prototype.getMetadata = function getMetadata() {\n        var _this = this;\n\n        if (this._settings.metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: Returning metadata from settings\");\n            return Promise.resolve(this._settings.metadata);\n        }\n\n        if (!this.metadataUrl) {\n            _Log.Log.error(\"MetadataService.getMetadata: No authority or metadataUrl configured on settings\");\n            return Promise.reject(new Error(\"No authority or metadataUrl configured on settings\"));\n        }\n\n        _Log.Log.debug(\"MetadataService.getMetadata: getting metadata from\", this.metadataUrl);\n\n        return this._jsonService.getJson(this.metadataUrl).then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadata: json received\");\n            _this._settings.metadata = metadata;\n            return metadata;\n        });\n    };\n\n    MetadataService.prototype.getIssuer = function getIssuer() {\n        return this._getMetadataProperty(\"issuer\");\n    };\n\n    MetadataService.prototype.getAuthorizationEndpoint = function getAuthorizationEndpoint() {\n        return this._getMetadataProperty(\"authorization_endpoint\");\n    };\n\n    MetadataService.prototype.getUserInfoEndpoint = function getUserInfoEndpoint() {\n        return this._getMetadataProperty(\"userinfo_endpoint\");\n    };\n\n    MetadataService.prototype.getTokenEndpoint = function getTokenEndpoint() {\n        var optional = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n\n        return this._getMetadataProperty(\"token_endpoint\", optional);\n    };\n\n    MetadataService.prototype.getCheckSessionIframe = function getCheckSessionIframe() {\n        return this._getMetadataProperty(\"check_session_iframe\", true);\n    };\n\n    MetadataService.prototype.getEndSessionEndpoint = function getEndSessionEndpoint() {\n        return this._getMetadataProperty(\"end_session_endpoint\", true);\n    };\n\n    MetadataService.prototype.getRevocationEndpoint = function getRevocationEndpoint() {\n        return this._getMetadataProperty(\"revocation_endpoint\", true);\n    };\n\n    MetadataService.prototype.getKeysEndpoint = function getKeysEndpoint() {\n        return this._getMetadataProperty(\"jwks_uri\", true);\n    };\n\n    MetadataService.prototype._getMetadataProperty = function _getMetadataProperty(name) {\n        var optional = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n        _Log.Log.debug(\"MetadataService.getMetadataProperty for: \" + name);\n\n        return this.getMetadata().then(function (metadata) {\n            _Log.Log.debug(\"MetadataService.getMetadataProperty: metadata recieved\");\n\n            if (metadata[name] === undefined) {\n\n                if (optional === true) {\n                    _Log.Log.warn(\"MetadataService.getMetadataProperty: Metadata does not contain optional property \" + name);\n                    return undefined;\n                } else {\n                    _Log.Log.error(\"MetadataService.getMetadataProperty: Metadata does not contain property \" + name);\n                    throw new Error(\"Metadata does not contain property \" + name);\n                }\n            }\n\n            return metadata[name];\n        });\n    };\n\n    MetadataService.prototype.getSigningKeys = function getSigningKeys() {\n        var _this2 = this;\n\n        if (this._settings.signingKeys) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: Returning signingKeys from settings\");\n            return Promise.resolve(this._settings.signingKeys);\n        }\n\n        return this._getMetadataProperty(\"jwks_uri\").then(function (jwks_uri) {\n            _Log.Log.debug(\"MetadataService.getSigningKeys: jwks_uri received\", jwks_uri);\n\n            return _this2._jsonService.getJson(jwks_uri).then(function (keySet) {\n                _Log.Log.debug(\"MetadataService.getSigningKeys: key set received\", keySet);\n\n                if (!keySet.keys) {\n                    _Log.Log.error(\"MetadataService.getSigningKeys: Missing keys on keyset\");\n                    throw new Error(\"Missing keys on keyset\");\n                }\n\n                _this2._settings.signingKeys = keySet.keys;\n                return _this2._settings.signingKeys;\n            });\n        });\n    };\n\n    _createClass(MetadataService, [{\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                if (this._settings.metadataUrl) {\n                    this._metadataUrl = this._settings.metadataUrl;\n                } else {\n                    this._metadataUrl = this._settings.authority;\n\n                    if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                        if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                            this._metadataUrl += '/';\n                        }\n                        this._metadataUrl += OidcMetadataUrlPath;\n                    }\n                }\n            }\n\n            return this._metadataUrl;\n        }\n    }]);\n\n    return MetadataService;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClient.js\":\n/*!***************************!*\\\n  !*** ./src/OidcClient.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClient = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nvar _SigninResponse = __webpack_require__(/*! ./SigninResponse.js */ \"./src/SigninResponse.js\");\n\nvar _SignoutRequest = __webpack_require__(/*! ./SignoutRequest.js */ \"./src/SignoutRequest.js\");\n\nvar _SignoutResponse = __webpack_require__(/*! ./SignoutResponse.js */ \"./src/SignoutResponse.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcClient = exports.OidcClient = function () {\n    function OidcClient() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        _classCallCheck(this, OidcClient);\n\n        if (settings instanceof _OidcClientSettings.OidcClientSettings) {\n            this._settings = settings;\n        } else {\n            this._settings = new _OidcClientSettings.OidcClientSettings(settings);\n        }\n    }\n\n    OidcClient.prototype.createSigninRequest = function createSigninRequest() {\n        var _this = this;\n\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            redirect_uri = _ref.redirect_uri,\n            data = _ref.data,\n            state = _ref.state,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            response_mode = _ref.response_mode,\n            extraQueryParams = _ref.extraQueryParams,\n            extraTokenParams = _ref.extraTokenParams,\n            request_type = _ref.request_type,\n            skipUserInfo = _ref.skipUserInfo;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSigninRequest\");\n\n        var client_id = this._settings.client_id;\n        response_type = response_type || this._settings.response_type;\n        scope = scope || this._settings.scope;\n        redirect_uri = redirect_uri || this._settings.redirect_uri;\n\n        // id_token_hint, login_hint aren't allowed on _settings\n        prompt = prompt || this._settings.prompt;\n        display = display || this._settings.display;\n        max_age = max_age || this._settings.max_age;\n        ui_locales = ui_locales || this._settings.ui_locales;\n        acr_values = acr_values || this._settings.acr_values;\n        resource = resource || this._settings.resource;\n        response_mode = response_mode || this._settings.response_mode;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n        extraTokenParams = extraTokenParams || this._settings.extraTokenParams;\n\n        var authority = this._settings.authority;\n\n        if (_SigninRequest.SigninRequest.isCode(response_type) && response_type !== \"code\") {\n            return Promise.reject(new Error(\"OpenID Connect hybrid flow is not supported\"));\n        }\n\n        return this._metadataService.getAuthorizationEndpoint().then(function (url) {\n            _Log.Log.debug(\"OidcClient.createSigninRequest: Received authorization endpoint\", url);\n\n            var signinRequest = new _SigninRequest.SigninRequest({\n                url: url,\n                client_id: client_id,\n                redirect_uri: redirect_uri,\n                response_type: response_type,\n                scope: scope,\n                data: data || state,\n                authority: authority,\n                prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values,\n                resource: resource, request: request, request_uri: request_uri, extraQueryParams: extraQueryParams, extraTokenParams: extraTokenParams, request_type: request_type, response_mode: response_mode,\n                client_secret: _this._settings.client_secret,\n                skipUserInfo: skipUserInfo\n            });\n\n            var signinState = signinRequest.state;\n            stateStore = stateStore || _this._stateStore;\n\n            return stateStore.set(signinState.id, signinState.toStorageString()).then(function () {\n                return signinRequest;\n            });\n        });\n    };\n\n    OidcClient.prototype.readSigninResponseState = function readSigninResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSigninResponseState\");\n\n        var useQuery = this._settings.response_mode === \"query\" || !this._settings.response_mode && _SigninRequest.SigninRequest.isCode(this._settings.response_type);\n        var delimiter = useQuery ? \"?\" : \"#\";\n\n        var response = new _SigninResponse.SigninResponse(url, delimiter);\n\n        if (!response.state) {\n            _Log.Log.error(\"OidcClient.readSigninResponseState: No state in response\");\n            return Promise.reject(new Error(\"No state in response\"));\n        }\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n\n        return stateApi(response.state).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSigninResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _SigninState.SigninState.fromStorageString(storedStateString);\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSigninResponse = function processSigninResponse(url, stateStore) {\n        var _this2 = this;\n\n        _Log.Log.debug(\"OidcClient.processSigninResponse\");\n\n        return this.readSigninResponseState(url, stateStore, true).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            _Log.Log.debug(\"OidcClient.processSigninResponse: Received state from storage; validating response\");\n            return _this2._validator.validateSigninResponse(state, response);\n        });\n    };\n\n    OidcClient.prototype.createSignoutRequest = function createSignoutRequest() {\n        var _this3 = this;\n\n        var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id_token_hint = _ref3.id_token_hint,\n            data = _ref3.data,\n            state = _ref3.state,\n            post_logout_redirect_uri = _ref3.post_logout_redirect_uri,\n            extraQueryParams = _ref3.extraQueryParams,\n            request_type = _ref3.request_type;\n\n        var stateStore = arguments[1];\n\n        _Log.Log.debug(\"OidcClient.createSignoutRequest\");\n\n        post_logout_redirect_uri = post_logout_redirect_uri || this._settings.post_logout_redirect_uri;\n        extraQueryParams = extraQueryParams || this._settings.extraQueryParams;\n\n        return this._metadataService.getEndSessionEndpoint().then(function (url) {\n            if (!url) {\n                _Log.Log.error(\"OidcClient.createSignoutRequest: No end session endpoint url returned\");\n                throw new Error(\"no end session endpoint\");\n            }\n\n            _Log.Log.debug(\"OidcClient.createSignoutRequest: Received end session endpoint\", url);\n\n            var request = new _SignoutRequest.SignoutRequest({\n                url: url,\n                id_token_hint: id_token_hint,\n                post_logout_redirect_uri: post_logout_redirect_uri,\n                data: data || state,\n                extraQueryParams: extraQueryParams,\n                request_type: request_type\n            });\n\n            var signoutState = request.state;\n            if (signoutState) {\n                _Log.Log.debug(\"OidcClient.createSignoutRequest: Signout request has state to persist\");\n\n                stateStore = stateStore || _this3._stateStore;\n                stateStore.set(signoutState.id, signoutState.toStorageString());\n            }\n\n            return request;\n        });\n    };\n\n    OidcClient.prototype.readSignoutResponseState = function readSignoutResponseState(url, stateStore) {\n        var removeState = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n        _Log.Log.debug(\"OidcClient.readSignoutResponseState\");\n\n        var response = new _SignoutResponse.SignoutResponse(url);\n        if (!response.state) {\n            _Log.Log.debug(\"OidcClient.readSignoutResponseState: No state in response\");\n\n            if (response.error) {\n                _Log.Log.warn(\"OidcClient.readSignoutResponseState: Response was error: \", response.error);\n                return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n            }\n\n            return Promise.resolve({ undefined: undefined, response: response });\n        }\n\n        var stateKey = response.state;\n\n        stateStore = stateStore || this._stateStore;\n\n        var stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);\n        return stateApi(stateKey).then(function (storedStateString) {\n            if (!storedStateString) {\n                _Log.Log.error(\"OidcClient.readSignoutResponseState: No matching state found in storage\");\n                throw new Error(\"No matching state found in storage\");\n            }\n\n            var state = _State.State.fromStorageString(storedStateString);\n\n            return { state: state, response: response };\n        });\n    };\n\n    OidcClient.prototype.processSignoutResponse = function processSignoutResponse(url, stateStore) {\n        var _this4 = this;\n\n        _Log.Log.debug(\"OidcClient.processSignoutResponse\");\n\n        return this.readSignoutResponseState(url, stateStore, true).then(function (_ref4) {\n            var state = _ref4.state,\n                response = _ref4.response;\n\n            if (state) {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: Received state from storage; validating response\");\n                return _this4._validator.validateSignoutResponse(state, response);\n            } else {\n                _Log.Log.debug(\"OidcClient.processSignoutResponse: No state from storage; skipping validating response\");\n                return response;\n            }\n        });\n    };\n\n    OidcClient.prototype.clearStaleState = function clearStaleState(stateStore) {\n        _Log.Log.debug(\"OidcClient.clearStaleState\");\n\n        stateStore = stateStore || this._stateStore;\n\n        return _State.State.clearStaleState(stateStore, this.settings.staleStateAge);\n    };\n\n    _createClass(OidcClient, [{\n        key: '_stateStore',\n        get: function get() {\n            return this.settings.stateStore;\n        }\n    }, {\n        key: '_validator',\n        get: function get() {\n            return this.settings.validator;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this.settings.metadataService;\n        }\n    }, {\n        key: 'settings',\n        get: function get() {\n            return this._settings;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n    }]);\n\n    return OidcClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/OidcClientSettings.js\":\n/*!***********************************!*\\\n  !*** ./src/OidcClientSettings.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.OidcClientSettings = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _ResponseValidator = __webpack_require__(/*! ./ResponseValidator.js */ \"./src/ResponseValidator.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcMetadataUrlPath = '.well-known/openid-configuration';\n\nvar DefaultResponseType = \"id_token\";\nvar DefaultScope = \"openid\";\nvar DefaultStaleStateAge = 60 * 15; // seconds\nvar DefaultClockSkewInSeconds = 60 * 5;\n\nvar OidcClientSettings = exports.OidcClientSettings = function () {\n    function OidcClientSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            authority = _ref.authority,\n            metadataUrl = _ref.metadataUrl,\n            metadata = _ref.metadata,\n            signingKeys = _ref.signingKeys,\n            client_id = _ref.client_id,\n            client_secret = _ref.client_secret,\n            _ref$response_type = _ref.response_type,\n            response_type = _ref$response_type === undefined ? DefaultResponseType : _ref$response_type,\n            _ref$scope = _ref.scope,\n            scope = _ref$scope === undefined ? DefaultScope : _ref$scope,\n            redirect_uri = _ref.redirect_uri,\n            post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            _ref$filterProtocolCl = _ref.filterProtocolClaims,\n            filterProtocolClaims = _ref$filterProtocolCl === undefined ? true : _ref$filterProtocolCl,\n            _ref$loadUserInfo = _ref.loadUserInfo,\n            loadUserInfo = _ref$loadUserInfo === undefined ? true : _ref$loadUserInfo,\n            _ref$staleStateAge = _ref.staleStateAge,\n            staleStateAge = _ref$staleStateAge === undefined ? DefaultStaleStateAge : _ref$staleStateAge,\n            _ref$clockSkew = _ref.clockSkew,\n            clockSkew = _ref$clockSkew === undefined ? DefaultClockSkewInSeconds : _ref$clockSkew,\n            _ref$userInfoJwtIssue = _ref.userInfoJwtIssuer,\n            userInfoJwtIssuer = _ref$userInfoJwtIssue === undefined ? 'OP' : _ref$userInfoJwtIssue,\n            _ref$stateStore = _ref.stateStore,\n            stateStore = _ref$stateStore === undefined ? new _WebStorageStateStore.WebStorageStateStore() : _ref$stateStore,\n            _ref$ResponseValidato = _ref.ResponseValidatorCtor,\n            ResponseValidatorCtor = _ref$ResponseValidato === undefined ? _ResponseValidator.ResponseValidator : _ref$ResponseValidato,\n            _ref$MetadataServiceC = _ref.MetadataServiceCtor,\n            MetadataServiceCtor = _ref$MetadataServiceC === undefined ? _MetadataService.MetadataService : _ref$MetadataServiceC,\n            _ref$extraQueryParams = _ref.extraQueryParams,\n            extraQueryParams = _ref$extraQueryParams === undefined ? {} : _ref$extraQueryParams,\n            _ref$extraTokenParams = _ref.extraTokenParams,\n            extraTokenParams = _ref$extraTokenParams === undefined ? {} : _ref$extraTokenParams;\n\n        _classCallCheck(this, OidcClientSettings);\n\n        this._authority = authority;\n        this._metadataUrl = metadataUrl;\n        this._metadata = metadata;\n        this._signingKeys = signingKeys;\n\n        this._client_id = client_id;\n        this._client_secret = client_secret;\n        this._response_type = response_type;\n        this._scope = scope;\n        this._redirect_uri = redirect_uri;\n        this._post_logout_redirect_uri = post_logout_redirect_uri;\n\n        this._prompt = prompt;\n        this._display = display;\n        this._max_age = max_age;\n        this._ui_locales = ui_locales;\n        this._acr_values = acr_values;\n        this._resource = resource;\n        this._response_mode = response_mode;\n\n        this._filterProtocolClaims = !!filterProtocolClaims;\n        this._loadUserInfo = !!loadUserInfo;\n        this._staleStateAge = staleStateAge;\n        this._clockSkew = clockSkew;\n        this._userInfoJwtIssuer = userInfoJwtIssuer;\n\n        this._stateStore = stateStore;\n        this._validator = new ResponseValidatorCtor(this);\n        this._metadataService = new MetadataServiceCtor(this);\n\n        this._extraQueryParams = (typeof extraQueryParams === 'undefined' ? 'undefined' : _typeof(extraQueryParams)) === 'object' ? extraQueryParams : {};\n        this._extraTokenParams = (typeof extraTokenParams === 'undefined' ? 'undefined' : _typeof(extraTokenParams)) === 'object' ? extraTokenParams : {};\n    }\n\n    // client config\n\n\n    _createClass(OidcClientSettings, [{\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        },\n        set: function set(value) {\n            if (!this._client_id) {\n                // one-time set only\n                this._client_id = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_client_id: client_id has already been assigned.\");\n                throw new Error(\"client_id has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'response_type',\n        get: function get() {\n            return this._response_type;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'post_logout_redirect_uri',\n        get: function get() {\n            return this._post_logout_redirect_uri;\n        }\n\n        // optional protocol params\n\n    }, {\n        key: 'prompt',\n        get: function get() {\n            return this._prompt;\n        }\n    }, {\n        key: 'display',\n        get: function get() {\n            return this._display;\n        }\n    }, {\n        key: 'max_age',\n        get: function get() {\n            return this._max_age;\n        }\n    }, {\n        key: 'ui_locales',\n        get: function get() {\n            return this._ui_locales;\n        }\n    }, {\n        key: 'acr_values',\n        get: function get() {\n            return this._acr_values;\n        }\n    }, {\n        key: 'resource',\n        get: function get() {\n            return this._resource;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n\n        // metadata\n\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        },\n        set: function set(value) {\n            if (!this._authority) {\n                // one-time set only\n                this._authority = value;\n            } else {\n                _Log.Log.error(\"OidcClientSettings.set_authority: authority has already been assigned.\");\n                throw new Error(\"authority has already been assigned.\");\n            }\n        }\n    }, {\n        key: 'metadataUrl',\n        get: function get() {\n            if (!this._metadataUrl) {\n                this._metadataUrl = this.authority;\n\n                if (this._metadataUrl && this._metadataUrl.indexOf(OidcMetadataUrlPath) < 0) {\n                    if (this._metadataUrl[this._metadataUrl.length - 1] !== '/') {\n                        this._metadataUrl += '/';\n                    }\n                    this._metadataUrl += OidcMetadataUrlPath;\n                }\n            }\n\n            return this._metadataUrl;\n        }\n\n        // settable/cachable metadata values\n\n    }, {\n        key: 'metadata',\n        get: function get() {\n            return this._metadata;\n        },\n        set: function set(value) {\n            this._metadata = value;\n        }\n    }, {\n        key: 'signingKeys',\n        get: function get() {\n            return this._signingKeys;\n        },\n        set: function set(value) {\n            this._signingKeys = value;\n        }\n\n        // behavior flags\n\n    }, {\n        key: 'filterProtocolClaims',\n        get: function get() {\n            return this._filterProtocolClaims;\n        }\n    }, {\n        key: 'loadUserInfo',\n        get: function get() {\n            return this._loadUserInfo;\n        }\n    }, {\n        key: 'staleStateAge',\n        get: function get() {\n            return this._staleStateAge;\n        }\n    }, {\n        key: 'clockSkew',\n        get: function get() {\n            return this._clockSkew;\n        }\n    }, {\n        key: 'userInfoJwtIssuer',\n        get: function get() {\n            return this._userInfoJwtIssuer;\n        }\n    }, {\n        key: 'stateStore',\n        get: function get() {\n            return this._stateStore;\n        }\n    }, {\n        key: 'validator',\n        get: function get() {\n            return this._validator;\n        }\n    }, {\n        key: 'metadataService',\n        get: function get() {\n            return this._metadataService;\n        }\n\n        // extra query params\n\n    }, {\n        key: 'extraQueryParams',\n        get: function get() {\n            return this._extraQueryParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraQueryParams = value;\n            } else {\n                this._extraQueryParams = {};\n            }\n        }\n\n        // extra token params\n\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        },\n        set: function set(value) {\n            if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                this._extraTokenParams = value;\n            } else {\n                this._extraTokenParams = {};\n            }\n        }\n    }]);\n\n    return OidcClientSettings;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupNavigator.js\":\n/*!*******************************!*\\\n  !*** ./src/PopupNavigator.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupNavigator = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _PopupWindow = __webpack_require__(/*! ./PopupWindow.js */ \"./src/PopupWindow.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar PopupNavigator = exports.PopupNavigator = function () {\n    function PopupNavigator() {\n        _classCallCheck(this, PopupNavigator);\n    }\n\n    PopupNavigator.prototype.prepare = function prepare(params) {\n        var popup = new _PopupWindow.PopupWindow(params);\n        return Promise.resolve(popup);\n    };\n\n    PopupNavigator.prototype.callback = function callback(url, keepOpen, delimiter) {\n        _Log.Log.debug(\"PopupNavigator.callback\");\n\n        try {\n            _PopupWindow.PopupWindow.notifyOpener(url, keepOpen, delimiter);\n            return Promise.resolve();\n        } catch (e) {\n            return Promise.reject(e);\n        }\n    };\n\n    return PopupNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/PopupWindow.js\":\n/*!****************************!*\\\n  !*** ./src/PopupWindow.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.PopupWindow = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar CheckForPopupClosedInterval = 500;\nvar DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;';\n//const DefaultPopupFeatures = 'location=no,toolbar=no,width=500,height=500,left=100,top=100;resizable=yes';\n\nvar DefaultPopupTarget = \"_blank\";\n\nvar PopupWindow = exports.PopupWindow = function () {\n    function PopupWindow(params) {\n        var _this = this;\n\n        _classCallCheck(this, PopupWindow);\n\n        this._promise = new Promise(function (resolve, reject) {\n            _this._resolve = resolve;\n            _this._reject = reject;\n        });\n\n        var target = params.popupWindowTarget || DefaultPopupTarget;\n        var features = params.popupWindowFeatures || DefaultPopupFeatures;\n\n        this._popup = window.open('', target, features);\n        if (this._popup) {\n            _Log.Log.debug(\"PopupWindow.ctor: popup successfully created\");\n            this._checkForPopupClosedTimer = window.setInterval(this._checkForPopupClosed.bind(this), CheckForPopupClosedInterval);\n        }\n    }\n\n    PopupWindow.prototype.navigate = function navigate(params) {\n        if (!this._popup) {\n            this._error(\"PopupWindow.navigate: Error opening popup window\");\n        } else if (!params || !params.url) {\n            this._error(\"PopupWindow.navigate: no url provided\");\n            this._error(\"No url provided\");\n        } else {\n            _Log.Log.debug(\"PopupWindow.navigate: Setting URL in popup\");\n\n            this._id = params.id;\n            if (this._id) {\n                window[\"popupCallback_\" + params.id] = this._callback.bind(this);\n            }\n\n            this._popup.focus();\n            this._popup.window.location = params.url;\n        }\n\n        return this.promise;\n    };\n\n    PopupWindow.prototype._success = function _success(data) {\n        _Log.Log.debug(\"PopupWindow.callback: Successful response from popup window\");\n\n        this._cleanup();\n        this._resolve(data);\n    };\n\n    PopupWindow.prototype._error = function _error(message) {\n        _Log.Log.error(\"PopupWindow.error: \", message);\n\n        this._cleanup();\n        this._reject(new Error(message));\n    };\n\n    PopupWindow.prototype.close = function close() {\n        this._cleanup(false);\n    };\n\n    PopupWindow.prototype._cleanup = function _cleanup(keepOpen) {\n        _Log.Log.debug(\"PopupWindow.cleanup\");\n\n        window.clearInterval(this._checkForPopupClosedTimer);\n        this._checkForPopupClosedTimer = null;\n\n        delete window[\"popupCallback_\" + this._id];\n\n        if (this._popup && !keepOpen) {\n            this._popup.close();\n        }\n        this._popup = null;\n    };\n\n    PopupWindow.prototype._checkForPopupClosed = function _checkForPopupClosed() {\n        if (!this._popup || this._popup.closed) {\n            this._error(\"Popup window closed\");\n        }\n    };\n\n    PopupWindow.prototype._callback = function _callback(url, keepOpen) {\n        this._cleanup(keepOpen);\n\n        if (url) {\n            _Log.Log.debug(\"PopupWindow.callback success\");\n            this._success({ url: url });\n        } else {\n            _Log.Log.debug(\"PopupWindow.callback: Invalid response from popup\");\n            this._error(\"Invalid response from popup\");\n        }\n    };\n\n    PopupWindow.notifyOpener = function notifyOpener(url, keepOpen, delimiter) {\n        if (window.opener) {\n            url = url || window.location.href;\n            if (url) {\n                var data = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n                if (data.state) {\n                    var name = \"popupCallback_\" + data.state;\n                    var callback = window.opener[name];\n                    if (callback) {\n                        _Log.Log.debug(\"PopupWindow.notifyOpener: passing url message to opener\");\n                        callback(url, keepOpen);\n                    } else {\n                        _Log.Log.warn(\"PopupWindow.notifyOpener: no matching callback found on opener\");\n                    }\n                } else {\n                    _Log.Log.warn(\"PopupWindow.notifyOpener: no state found in response url\");\n                }\n            }\n        } else {\n            _Log.Log.warn(\"PopupWindow.notifyOpener: no window.opener. Can't complete notification.\");\n        }\n    };\n\n    _createClass(PopupWindow, [{\n        key: 'promise',\n        get: function get() {\n            return this._promise;\n        }\n    }]);\n\n    return PopupWindow;\n}();\n\n/***/ }),\n\n/***/ \"./src/RedirectNavigator.js\":\n/*!**********************************!*\\\n  !*** ./src/RedirectNavigator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.RedirectNavigator = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar RedirectNavigator = exports.RedirectNavigator = function () {\n    function RedirectNavigator() {\n        _classCallCheck(this, RedirectNavigator);\n    }\n\n    RedirectNavigator.prototype.prepare = function prepare() {\n        return Promise.resolve(this);\n    };\n\n    RedirectNavigator.prototype.navigate = function navigate(params) {\n        if (!params || !params.url) {\n            _Log.Log.error(\"RedirectNavigator.navigate: No url provided\");\n            return Promise.reject(new Error(\"No url provided\"));\n        }\n\n        if (params.useReplaceToNavigate) {\n            window.location.replace(params.url);\n        } else {\n            window.location = params.url;\n        }\n\n        return Promise.resolve();\n    };\n\n    _createClass(RedirectNavigator, [{\n        key: \"url\",\n        get: function get() {\n            return window.location.href;\n        }\n    }]);\n\n    return RedirectNavigator;\n}();\n\n/***/ }),\n\n/***/ \"./src/ResponseValidator.js\":\n/*!**********************************!*\\\n  !*** ./src/ResponseValidator.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.ResponseValidator = undefined;\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _UserInfoService = __webpack_require__(/*! ./UserInfoService.js */ \"./src/UserInfoService.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _ErrorResponse = __webpack_require__(/*! ./ErrorResponse.js */ \"./src/ErrorResponse.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar ProtocolClaims = [\"nonce\", \"at_hash\", \"iat\", \"nbf\", \"exp\", \"aud\", \"iss\", \"c_hash\"];\n\nvar ResponseValidator = exports.ResponseValidator = function () {\n    function ResponseValidator(settings) {\n        var MetadataServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _MetadataService.MetadataService;\n        var UserInfoServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _UserInfoService.UserInfoService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n\n        _classCallCheck(this, ResponseValidator);\n\n        if (!settings) {\n            _Log.Log.error(\"ResponseValidator.ctor: No settings passed to ResponseValidator\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._userInfoService = new UserInfoServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n        this._tokenClient = new TokenClientCtor(this._settings);\n    }\n\n    ResponseValidator.prototype.validateSigninResponse = function validateSigninResponse(state, response) {\n        var _this = this;\n\n        _Log.Log.debug(\"ResponseValidator.validateSigninResponse\");\n\n        return this._processSigninParams(state, response).then(function (response) {\n            _Log.Log.debug(\"ResponseValidator.validateSigninResponse: state processed\");\n            return _this._validateTokens(state, response).then(function (response) {\n                _Log.Log.debug(\"ResponseValidator.validateSigninResponse: tokens validated\");\n                return _this._processClaims(state, response).then(function (response) {\n                    _Log.Log.debug(\"ResponseValidator.validateSigninResponse: claims processed\");\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype.validateSignoutResponse = function validateSignoutResponse(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator.validateSignoutResponse: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator.validateSignoutResponse: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator.validateSignoutResponse: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processSigninParams = function _processSigninParams(state, response) {\n        if (state.id !== response.state) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: State does not match\");\n            return Promise.reject(new Error(\"State does not match\"));\n        }\n\n        if (!state.client_id) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No client_id on state\");\n            return Promise.reject(new Error(\"No client_id on state\"));\n        }\n\n        if (!state.authority) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: No authority on state\");\n            return Promise.reject(new Error(\"No authority on state\"));\n        }\n\n        // this allows the authority to be loaded from the signin state\n        if (!this._settings.authority) {\n            this._settings.authority = state.authority;\n        }\n        // ensure we're using the correct authority if the authority is not loaded from signin state\n        else if (this._settings.authority && this._settings.authority !== state.authority) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: authority mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"authority mismatch on settings vs. signin state\"));\n            }\n        // this allows the client_id to be loaded from the signin state\n        if (!this._settings.client_id) {\n            this._settings.client_id = state.client_id;\n        }\n        // ensure we're using the correct client_id if the client_id is not loaded from signin state\n        else if (this._settings.client_id && this._settings.client_id !== state.client_id) {\n                _Log.Log.error(\"ResponseValidator._processSigninParams: client_id mismatch on settings vs. signin state\");\n                return Promise.reject(new Error(\"client_id mismatch on settings vs. signin state\"));\n            }\n\n        // now that we know the state matches, take the stored data\n        // and set it into the response so callers can get their state\n        // this is important for both success & error outcomes\n        _Log.Log.debug(\"ResponseValidator._processSigninParams: state validated\");\n        response.state = state.data;\n\n        if (response.error) {\n            _Log.Log.warn(\"ResponseValidator._processSigninParams: Response was error\", response.error);\n            return Promise.reject(new _ErrorResponse.ErrorResponse(response));\n        }\n\n        if (state.nonce && !response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting id_token in response\");\n            return Promise.reject(new Error(\"No id_token in response\"));\n        }\n\n        if (!state.nonce && response.id_token) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting id_token in response\");\n            return Promise.reject(new Error(\"Unexpected id_token in response\"));\n        }\n\n        if (state.code_verifier && !response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Expecting code in response\");\n            return Promise.reject(new Error(\"No code in response\"));\n        }\n\n        if (!state.code_verifier && response.code) {\n            _Log.Log.error(\"ResponseValidator._processSigninParams: Not expecting code in response\");\n            return Promise.reject(new Error(\"Unexpected code in response\"));\n        }\n\n        if (!response.scope) {\n            // if there's no scope on the response, then assume all scopes granted (per-spec) and copy over scopes from original request\n            response.scope = state.scope;\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processClaims = function _processClaims(state, response) {\n        var _this2 = this;\n\n        if (response.isOpenIdConnect) {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is OIDC, processing claims\");\n\n            response.profile = this._filterProtocolClaims(response.profile);\n\n            if (state.skipUserInfo !== true && this._settings.loadUserInfo && response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._processClaims: loading user info\");\n\n                return this._userInfoService.getClaims(response.access_token).then(function (claims) {\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received from user info endpoint\");\n\n                    if (claims.sub !== response.profile.sub) {\n                        _Log.Log.error(\"ResponseValidator._processClaims: sub from user info endpoint does not match sub in access_token\");\n                        return Promise.reject(new Error(\"sub from user info endpoint does not match sub in access_token\"));\n                    }\n\n                    response.profile = _this2._mergeClaims(response.profile, claims);\n                    _Log.Log.debug(\"ResponseValidator._processClaims: user info claims received, updated profile:\", response.profile);\n\n                    return response;\n                });\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processClaims: not loading user info\");\n            }\n        } else {\n            _Log.Log.debug(\"ResponseValidator._processClaims: response is not OIDC, not processing claims\");\n        }\n\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._mergeClaims = function _mergeClaims(claims1, claims2) {\n        var result = Object.assign({}, claims1);\n\n        for (var name in claims2) {\n            var values = claims2[name];\n            if (!Array.isArray(values)) {\n                values = [values];\n            }\n\n            for (var i = 0; i < values.length; i++) {\n                var value = values[i];\n                if (!result[name]) {\n                    result[name] = value;\n                } else if (Array.isArray(result[name])) {\n                    if (result[name].indexOf(value) < 0) {\n                        result[name].push(value);\n                    }\n                } else if (result[name] !== value) {\n                    if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {\n                        result[name] = this._mergeClaims(result[name], value);\n                    } else {\n                        result[name] = [result[name], value];\n                    }\n                }\n            }\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._filterProtocolClaims = function _filterProtocolClaims(claims) {\n        _Log.Log.debug(\"ResponseValidator._filterProtocolClaims, incoming claims:\", claims);\n\n        var result = Object.assign({}, claims);\n\n        if (this._settings._filterProtocolClaims) {\n            ProtocolClaims.forEach(function (type) {\n                delete result[type];\n            });\n\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims filtered\", result);\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterProtocolClaims: protocol claims not filtered\");\n        }\n\n        return result;\n    };\n\n    ResponseValidator.prototype._validateTokens = function _validateTokens(state, response) {\n        if (response.code) {\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating code\");\n            return this._processCode(state, response);\n        }\n\n        if (response.id_token) {\n            if (response.access_token) {\n                _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token and access_token\");\n                return this._validateIdTokenAndAccessToken(state, response);\n            }\n\n            _Log.Log.debug(\"ResponseValidator._validateTokens: Validating id_token\");\n            return this._validateIdToken(state, response);\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateTokens: No code to process or id_token to validate\");\n        return Promise.resolve(response);\n    };\n\n    ResponseValidator.prototype._processCode = function _processCode(state, response) {\n        var _this3 = this;\n\n        var request = {\n            client_id: state.client_id,\n            client_secret: state.client_secret,\n            code: response.code,\n            redirect_uri: state.redirect_uri,\n            code_verifier: state.code_verifier\n        };\n\n        if (state.extraTokenParams && _typeof(state.extraTokenParams) === 'object') {\n            Object.assign(request, state.extraTokenParams);\n        }\n\n        return this._tokenClient.exchangeCode(request).then(function (tokenResponse) {\n\n            for (var key in tokenResponse) {\n                response[key] = tokenResponse[key];\n            }\n\n            if (response.id_token) {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, processing id_token\");\n                return _this3._validateIdTokenAttributes(state, response);\n            } else {\n                _Log.Log.debug(\"ResponseValidator._processCode: token response successful, returning response\");\n            }\n\n            return response;\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAttributes = function _validateIdTokenAttributes(state, response) {\n        var _this4 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n\n            var audience = state.client_id;\n            var clockSkewInSeconds = _this4._settings.clockSkew;\n            _Log.Log.debug(\"ResponseValidator._validateIdTokenAttributes: Validaing JWT attributes; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n            return _this4._joseUtil.validateJwtAttributes(response.id_token, issuer, audience, clockSkewInSeconds).then(function (payload) {\n\n                if (state.nonce && state.nonce !== payload.nonce) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: Invalid nonce in id_token\");\n                    return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n                }\n\n                if (!payload.sub) {\n                    _Log.Log.error(\"ResponseValidator._validateIdTokenAttributes: No sub present in id_token\");\n                    return Promise.reject(new Error(\"No sub present in id_token\"));\n                }\n\n                response.profile = payload;\n                return response;\n            });\n        });\n    };\n\n    ResponseValidator.prototype._validateIdTokenAndAccessToken = function _validateIdTokenAndAccessToken(state, response) {\n        var _this5 = this;\n\n        return this._validateIdToken(state, response).then(function (response) {\n            return _this5._validateAccessToken(response);\n        });\n    };\n\n    ResponseValidator.prototype._validateIdToken = function _validateIdToken(state, response) {\n        var _this6 = this;\n\n        if (!state.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: No nonce on state\");\n            return Promise.reject(new Error(\"No nonce on state\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header || !jwt.payload) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        if (state.nonce !== jwt.payload.nonce) {\n            _Log.Log.error(\"ResponseValidator._validateIdToken: Invalid nonce in id_token\");\n            return Promise.reject(new Error(\"Invalid nonce in id_token\"));\n        }\n\n        var kid = jwt.header.kid;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            _Log.Log.debug(\"ResponseValidator._validateIdToken: Received issuer\");\n\n            return _this6._metadataService.getSigningKeys().then(function (keys) {\n                if (!keys) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No signing keys from metadata\");\n                    return Promise.reject(new Error(\"No signing keys from metadata\"));\n                }\n\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Received signing keys\");\n                var key = void 0;\n                if (!kid) {\n                    keys = _this6._filterByAlg(keys, jwt.header.alg);\n\n                    if (keys.length > 1) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No kid found in id_token and more than one key found in metadata\");\n                        return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                    } else {\n                        // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                        // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                        key = keys[0];\n                    }\n                } else {\n                    key = keys.filter(function (key) {\n                        return key.kid === kid;\n                    })[0];\n                }\n\n                if (!key) {\n                    _Log.Log.error(\"ResponseValidator._validateIdToken: No key matching kid or alg found in signing keys\");\n                    return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                }\n\n                var audience = state.client_id;\n\n                var clockSkewInSeconds = _this6._settings.clockSkew;\n                _Log.Log.debug(\"ResponseValidator._validateIdToken: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                return _this6._joseUtil.validateJwt(response.id_token, key, issuer, audience, clockSkewInSeconds).then(function () {\n                    _Log.Log.debug(\"ResponseValidator._validateIdToken: JWT validation successful\");\n\n                    if (!jwt.payload.sub) {\n                        _Log.Log.error(\"ResponseValidator._validateIdToken: No sub present in id_token\");\n                        return Promise.reject(new Error(\"No sub present in id_token\"));\n                    }\n\n                    response.profile = jwt.payload;\n\n                    return response;\n                });\n            });\n        });\n    };\n\n    ResponseValidator.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"ResponseValidator._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"ResponseValidator._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    ResponseValidator.prototype._validateAccessToken = function _validateAccessToken(response) {\n        if (!response.profile) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No profile loaded from id_token\");\n            return Promise.reject(new Error(\"No profile loaded from id_token\"));\n        }\n\n        if (!response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No at_hash in id_token\");\n            return Promise.reject(new Error(\"No at_hash in id_token\"));\n        }\n\n        if (!response.id_token) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: No id_token\");\n            return Promise.reject(new Error(\"No id_token\"));\n        }\n\n        var jwt = this._joseUtil.parseJwt(response.id_token);\n        if (!jwt || !jwt.header) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to parse id_token\", jwt);\n            return Promise.reject(new Error(\"Failed to parse id_token\"));\n        }\n\n        var hashAlg = jwt.header.alg;\n        if (!hashAlg || hashAlg.length !== 5) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var hashBits = hashAlg.substr(2, 3);\n        if (!hashBits) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        hashBits = parseInt(hashBits);\n        if (hashBits !== 256 && hashBits !== 384 && hashBits !== 512) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Unsupported alg:\", hashAlg, hashBits);\n            return Promise.reject(new Error(\"Unsupported alg: \" + hashAlg));\n        }\n\n        var sha = \"sha\" + hashBits;\n        var hash = this._joseUtil.hashString(response.access_token, sha);\n        if (!hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: access_token hash failed:\", sha);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        var left = hash.substr(0, hash.length / 2);\n        var left_b64u = this._joseUtil.hexToBase64Url(left);\n        if (left_b64u !== response.profile.at_hash) {\n            _Log.Log.error(\"ResponseValidator._validateAccessToken: Failed to validate at_hash\", left_b64u, response.profile.at_hash);\n            return Promise.reject(new Error(\"Failed to validate at_hash\"));\n        }\n\n        _Log.Log.debug(\"ResponseValidator._validateAccessToken: success\");\n\n        return Promise.resolve(response);\n    };\n\n    return ResponseValidator;\n}();\n\n/***/ }),\n\n/***/ \"./src/SessionMonitor.js\":\n/*!*******************************!*\\\n  !*** ./src/SessionMonitor.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SessionMonitor = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _CheckSessionIFrame = __webpack_require__(/*! ./CheckSessionIFrame.js */ \"./src/CheckSessionIFrame.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar SessionMonitor = exports.SessionMonitor = function () {\n    function SessionMonitor(userManager) {\n        var _this = this;\n\n        var CheckSessionIFrameCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _CheckSessionIFrame.CheckSessionIFrame;\n        var timer = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global.timer;\n\n        _classCallCheck(this, SessionMonitor);\n\n        if (!userManager) {\n            _Log.Log.error(\"SessionMonitor.ctor: No user manager passed to SessionMonitor\");\n            throw new Error(\"userManager\");\n        }\n\n        this._userManager = userManager;\n        this._CheckSessionIFrameCtor = CheckSessionIFrameCtor;\n        this._timer = timer;\n\n        this._userManager.events.addUserLoaded(this._start.bind(this));\n        this._userManager.events.addUserUnloaded(this._stop.bind(this));\n\n        this._userManager.getUser().then(function (user) {\n            // doing this manually here since calling getUser \n            // doesn't trigger load event.\n            if (user) {\n                _this._start(user);\n            } else if (_this._settings.monitorAnonymousSession) {\n                _this._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a ctor\n                    _Log.Log.error(\"SessionMonitor ctor: error from querySessionStatus:\", err.message);\n                });\n            }\n        }).catch(function (err) {\n            // catch to suppress errors since we're in a ctor\n            _Log.Log.error(\"SessionMonitor ctor: error from getUser:\", err.message);\n        });\n    }\n\n    SessionMonitor.prototype._start = function _start(user) {\n        var _this2 = this;\n\n        var session_state = user.session_state;\n\n        if (session_state) {\n            if (user.profile) {\n                this._sub = user.profile.sub;\n                this._sid = user.profile.sid;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", sub:\", this._sub);\n            } else {\n                this._sub = undefined;\n                this._sid = undefined;\n                _Log.Log.debug(\"SessionMonitor._start: session_state:\", session_state, \", anonymous user\");\n            }\n\n            if (!this._checkSessionIFrame) {\n                this._metadataService.getCheckSessionIframe().then(function (url) {\n                    if (url) {\n                        _Log.Log.debug(\"SessionMonitor._start: Initializing check session iframe\");\n\n                        var client_id = _this2._client_id;\n                        var interval = _this2._checkSessionInterval;\n                        var stopOnError = _this2._stopCheckSessionOnError;\n\n                        _this2._checkSessionIFrame = new _this2._CheckSessionIFrameCtor(_this2._callback.bind(_this2), client_id, url, interval, stopOnError);\n                        _this2._checkSessionIFrame.load().then(function () {\n                            _this2._checkSessionIFrame.start(session_state);\n                        });\n                    } else {\n                        _Log.Log.warn(\"SessionMonitor._start: No check session iframe found in the metadata\");\n                    }\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in non-promise callback\n                    _Log.Log.error(\"SessionMonitor._start: Error from getCheckSessionIframe:\", err.message);\n                });\n            } else {\n                this._checkSessionIFrame.start(session_state);\n            }\n        }\n    };\n\n    SessionMonitor.prototype._stop = function _stop() {\n        var _this3 = this;\n\n        this._sub = undefined;\n        this._sid = undefined;\n\n        if (this._checkSessionIFrame) {\n            _Log.Log.debug(\"SessionMonitor._stop\");\n            this._checkSessionIFrame.stop();\n        }\n\n        if (this._settings.monitorAnonymousSession) {\n            // using a timer to delay re-initialization to avoid race conditions during signout\n            var timerHandle = this._timer.setInterval(function () {\n                _this3._timer.clearInterval(timerHandle);\n\n                _this3._userManager.querySessionStatus().then(function (session) {\n                    var tmpUser = {\n                        session_state: session.session_state\n                    };\n                    if (session.sub && session.sid) {\n                        tmpUser.profile = {\n                            sub: session.sub,\n                            sid: session.sid\n                        };\n                    }\n                    _this3._start(tmpUser);\n                }).catch(function (err) {\n                    // catch to suppress errors since we're in a callback\n                    _Log.Log.error(\"SessionMonitor: error from querySessionStatus:\", err.message);\n                });\n            }, 1000);\n        }\n    };\n\n    SessionMonitor.prototype._callback = function _callback() {\n        var _this4 = this;\n\n        this._userManager.querySessionStatus().then(function (session) {\n            var raiseEvent = true;\n\n            if (session) {\n                if (session.sub === _this4._sub) {\n                    raiseEvent = false;\n                    _this4._checkSessionIFrame.start(session.session_state);\n\n                    if (session.sid === _this4._sid) {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, restarting check session iframe; session_state:\", session.session_state);\n                    } else {\n                        _Log.Log.debug(\"SessionMonitor._callback: Same sub still logged in at OP, session state has changed, restarting check session iframe; session_state:\", session.session_state);\n                        _this4._userManager.events._raiseUserSessionChanged();\n                    }\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: Different subject signed into OP:\", session.sub);\n                }\n            } else {\n                _Log.Log.debug(\"SessionMonitor._callback: Subject no longer signed into OP\");\n            }\n\n            if (raiseEvent) {\n                if (_this4._sub) {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed out event\");\n                    _this4._userManager.events._raiseUserSignedOut();\n                } else {\n                    _Log.Log.debug(\"SessionMonitor._callback: SessionMonitor._callback; raising signed in event\");\n                    _this4._userManager.events._raiseUserSignedIn();\n                }\n            }\n        }).catch(function (err) {\n            if (_this4._sub) {\n                _Log.Log.debug(\"SessionMonitor._callback: Error calling queryCurrentSigninSession; raising signed out event\", err.message);\n                _this4._userManager.events._raiseUserSignedOut();\n            }\n        });\n    };\n\n    _createClass(SessionMonitor, [{\n        key: '_settings',\n        get: function get() {\n            return this._userManager.settings;\n        }\n    }, {\n        key: '_metadataService',\n        get: function get() {\n            return this._userManager.metadataService;\n        }\n    }, {\n        key: '_client_id',\n        get: function get() {\n            return this._settings.client_id;\n        }\n    }, {\n        key: '_checkSessionInterval',\n        get: function get() {\n            return this._settings.checkSessionInterval;\n        }\n    }, {\n        key: '_stopCheckSessionOnError',\n        get: function get() {\n            return this._settings.stopCheckSessionOnError;\n        }\n    }]);\n\n    return SessionMonitor;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninRequest.js\":\n/*!******************************!*\\\n  !*** ./src/SigninRequest.js ***!\n  \\******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _SigninState = __webpack_require__(/*! ./SigninState.js */ \"./src/SigninState.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninRequest = exports.SigninRequest = function () {\n    function SigninRequest(_ref) {\n        var url = _ref.url,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            response_type = _ref.response_type,\n            scope = _ref.scope,\n            authority = _ref.authority,\n            data = _ref.data,\n            prompt = _ref.prompt,\n            display = _ref.display,\n            max_age = _ref.max_age,\n            ui_locales = _ref.ui_locales,\n            id_token_hint = _ref.id_token_hint,\n            login_hint = _ref.login_hint,\n            acr_values = _ref.acr_values,\n            resource = _ref.resource,\n            response_mode = _ref.response_mode,\n            request = _ref.request,\n            request_uri = _ref.request_uri,\n            extraQueryParams = _ref.extraQueryParams,\n            request_type = _ref.request_type,\n            client_secret = _ref.client_secret,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninRequest);\n\n        if (!url) {\n            _Log.Log.error(\"SigninRequest.ctor: No url passed\");\n            throw new Error(\"url\");\n        }\n        if (!client_id) {\n            _Log.Log.error(\"SigninRequest.ctor: No client_id passed\");\n            throw new Error(\"client_id\");\n        }\n        if (!redirect_uri) {\n            _Log.Log.error(\"SigninRequest.ctor: No redirect_uri passed\");\n            throw new Error(\"redirect_uri\");\n        }\n        if (!response_type) {\n            _Log.Log.error(\"SigninRequest.ctor: No response_type passed\");\n            throw new Error(\"response_type\");\n        }\n        if (!scope) {\n            _Log.Log.error(\"SigninRequest.ctor: No scope passed\");\n            throw new Error(\"scope\");\n        }\n        if (!authority) {\n            _Log.Log.error(\"SigninRequest.ctor: No authority passed\");\n            throw new Error(\"authority\");\n        }\n\n        var oidc = SigninRequest.isOidc(response_type);\n        var code = SigninRequest.isCode(response_type);\n\n        if (!response_mode) {\n            response_mode = SigninRequest.isCode(response_type) ? \"query\" : null;\n        }\n\n        this.state = new _SigninState.SigninState({ nonce: oidc,\n            data: data, client_id: client_id, authority: authority, redirect_uri: redirect_uri,\n            code_verifier: code,\n            request_type: request_type, response_mode: response_mode,\n            client_secret: client_secret, scope: scope, extraTokenParams: extraTokenParams, skipUserInfo: skipUserInfo });\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"client_id\", client_id);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"redirect_uri\", redirect_uri);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"response_type\", response_type);\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"scope\", scope);\n\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        if (oidc) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"nonce\", this.state.nonce);\n        }\n        if (code) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge\", this.state.code_challenge);\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"code_challenge_method\", \"S256\");\n        }\n\n        var optional = { prompt: prompt, display: display, max_age: max_age, ui_locales: ui_locales, id_token_hint: id_token_hint, login_hint: login_hint, acr_values: acr_values, resource: resource, request: request, request_uri: request_uri, response_mode: response_mode };\n        for (var key in optional) {\n            if (optional[key]) {\n                url = _UrlUtility.UrlUtility.addQueryParam(url, key, optional[key]);\n            }\n        }\n\n        for (var _key in extraQueryParams) {\n            url = _UrlUtility.UrlUtility.addQueryParam(url, _key, extraQueryParams[_key]);\n        }\n\n        this.url = url;\n    }\n\n    SigninRequest.isOidc = function isOidc(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"id_token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isOAuth = function isOAuth(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"token\";\n        });\n        return !!result[0];\n    };\n\n    SigninRequest.isCode = function isCode(response_type) {\n        var result = response_type.split(/\\s+/g).filter(function (item) {\n            return item === \"code\";\n        });\n        return !!result[0];\n    };\n\n    return SigninRequest;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninResponse.js\":\n/*!*******************************!*\\\n  !*** ./src/SigninResponse.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninResponse = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar OidcScope = \"openid\";\n\nvar SigninResponse = exports.SigninResponse = function () {\n    function SigninResponse(url) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n\n        _classCallCheck(this, SigninResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, delimiter);\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.code = values.code;\n        this.state = values.state;\n        this.id_token = values.id_token;\n        this.session_state = values.session_state;\n        this.access_token = values.access_token;\n        this.token_type = values.token_type;\n        this.scope = values.scope;\n        this.profile = undefined; // will be set from ResponseValidator\n\n        this.expires_in = values.expires_in;\n    }\n\n    _createClass(SigninResponse, [{\n        key: \"expires_in\",\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: \"expired\",\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: \"scopes\",\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }, {\n        key: \"isOpenIdConnect\",\n        get: function get() {\n            return this.scopes.indexOf(OidcScope) >= 0 || !!this.id_token;\n        }\n    }]);\n\n    return SigninResponse;\n}();\n\n/***/ }),\n\n/***/ \"./src/SigninState.js\":\n/*!****************************!*\\\n  !*** ./src/SigninState.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SigninState = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _State2 = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SigninState = exports.SigninState = function (_State) {\n    _inherits(SigninState, _State);\n\n    function SigninState() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            nonce = _ref.nonce,\n            authority = _ref.authority,\n            client_id = _ref.client_id,\n            redirect_uri = _ref.redirect_uri,\n            code_verifier = _ref.code_verifier,\n            response_mode = _ref.response_mode,\n            client_secret = _ref.client_secret,\n            scope = _ref.scope,\n            extraTokenParams = _ref.extraTokenParams,\n            skipUserInfo = _ref.skipUserInfo;\n\n        _classCallCheck(this, SigninState);\n\n        var _this = _possibleConstructorReturn(this, _State.call(this, arguments[0]));\n\n        if (nonce === true) {\n            _this._nonce = (0, _random2.default)();\n        } else if (nonce) {\n            _this._nonce = nonce;\n        }\n\n        if (code_verifier === true) {\n            // random() produces 32 length\n            _this._code_verifier = (0, _random2.default)() + (0, _random2.default)() + (0, _random2.default)();\n        } else if (code_verifier) {\n            _this._code_verifier = code_verifier;\n        }\n\n        if (_this.code_verifier) {\n            var hash = _JoseUtil.JoseUtil.hashString(_this.code_verifier, \"SHA256\");\n            _this._code_challenge = _JoseUtil.JoseUtil.hexToBase64Url(hash);\n        }\n\n        _this._redirect_uri = redirect_uri;\n        _this._authority = authority;\n        _this._client_id = client_id;\n        _this._response_mode = response_mode;\n        _this._client_secret = client_secret;\n        _this._scope = scope;\n        _this._extraTokenParams = extraTokenParams;\n        _this._skipUserInfo = skipUserInfo;\n        return _this;\n    }\n\n    SigninState.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"SigninState.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type,\n            nonce: this.nonce,\n            code_verifier: this.code_verifier,\n            redirect_uri: this.redirect_uri,\n            authority: this.authority,\n            client_id: this.client_id,\n            response_mode: this.response_mode,\n            client_secret: this.client_secret,\n            scope: this.scope,\n            extraTokenParams: this.extraTokenParams,\n            skipUserInfo: this.skipUserInfo\n        });\n    };\n\n    SigninState.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"SigninState.fromStorageString\");\n        var data = JSON.parse(storageString);\n        return new SigninState(data);\n    };\n\n    _createClass(SigninState, [{\n        key: 'nonce',\n        get: function get() {\n            return this._nonce;\n        }\n    }, {\n        key: 'authority',\n        get: function get() {\n            return this._authority;\n        }\n    }, {\n        key: 'client_id',\n        get: function get() {\n            return this._client_id;\n        }\n    }, {\n        key: 'redirect_uri',\n        get: function get() {\n            return this._redirect_uri;\n        }\n    }, {\n        key: 'code_verifier',\n        get: function get() {\n            return this._code_verifier;\n        }\n    }, {\n        key: 'code_challenge',\n        get: function get() {\n            return this._code_challenge;\n        }\n    }, {\n        key: 'response_mode',\n        get: function get() {\n            return this._response_mode;\n        }\n    }, {\n        key: 'client_secret',\n        get: function get() {\n            return this._client_secret;\n        }\n    }, {\n        key: 'scope',\n        get: function get() {\n            return this._scope;\n        }\n    }, {\n        key: 'extraTokenParams',\n        get: function get() {\n            return this._extraTokenParams;\n        }\n    }, {\n        key: 'skipUserInfo',\n        get: function get() {\n            return this._skipUserInfo;\n        }\n    }]);\n\n    return SigninState;\n}(_State2.State);\n\n/***/ }),\n\n/***/ \"./src/SignoutRequest.js\":\n/*!*******************************!*\\\n  !*** ./src/SignoutRequest.js ***!\n  \\*******************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SignoutRequest = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nvar _State = __webpack_require__(/*! ./State.js */ \"./src/State.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutRequest = exports.SignoutRequest = function SignoutRequest(_ref) {\n    var url = _ref.url,\n        id_token_hint = _ref.id_token_hint,\n        post_logout_redirect_uri = _ref.post_logout_redirect_uri,\n        data = _ref.data,\n        extraQueryParams = _ref.extraQueryParams,\n        request_type = _ref.request_type;\n\n    _classCallCheck(this, SignoutRequest);\n\n    if (!url) {\n        _Log.Log.error(\"SignoutRequest.ctor: No url passed\");\n        throw new Error(\"url\");\n    }\n\n    if (id_token_hint) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"id_token_hint\", id_token_hint);\n    }\n\n    if (post_logout_redirect_uri) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, \"post_logout_redirect_uri\", post_logout_redirect_uri);\n\n        if (data) {\n            this.state = new _State.State({ data: data, request_type: request_type });\n\n            url = _UrlUtility.UrlUtility.addQueryParam(url, \"state\", this.state.id);\n        }\n    }\n\n    for (var key in extraQueryParams) {\n        url = _UrlUtility.UrlUtility.addQueryParam(url, key, extraQueryParams[key]);\n    }\n\n    this.url = url;\n};\n\n/***/ }),\n\n/***/ \"./src/SignoutResponse.js\":\n/*!********************************!*\\\n  !*** ./src/SignoutResponse.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n        value: true\n});\nexports.SignoutResponse = undefined;\n\nvar _UrlUtility = __webpack_require__(/*! ./UrlUtility.js */ \"./src/UrlUtility.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SignoutResponse = exports.SignoutResponse = function SignoutResponse(url) {\n        _classCallCheck(this, SignoutResponse);\n\n        var values = _UrlUtility.UrlUtility.parseUrlFragment(url, \"?\");\n\n        this.error = values.error;\n        this.error_description = values.error_description;\n        this.error_uri = values.error_uri;\n\n        this.state = values.state;\n};\n\n/***/ }),\n\n/***/ \"./src/SilentRenewService.js\":\n/*!***********************************!*\\\n  !*** ./src/SilentRenewService.js ***!\n  \\***********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.SilentRenewService = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar SilentRenewService = exports.SilentRenewService = function () {\n    function SilentRenewService(userManager) {\n        _classCallCheck(this, SilentRenewService);\n\n        this._userManager = userManager;\n    }\n\n    SilentRenewService.prototype.start = function start() {\n        if (!this._callback) {\n            this._callback = this._tokenExpiring.bind(this);\n            this._userManager.events.addAccessTokenExpiring(this._callback);\n\n            // this will trigger loading of the user so the expiring events can be initialized\n            this._userManager.getUser().then(function (user) {\n                // deliberate nop\n            }).catch(function (err) {\n                // catch to suppress errors since we're in a ctor\n                _Log.Log.error(\"SilentRenewService.start: Error from getUser:\", err.message);\n            });\n        }\n    };\n\n    SilentRenewService.prototype.stop = function stop() {\n        if (this._callback) {\n            this._userManager.events.removeAccessTokenExpiring(this._callback);\n            delete this._callback;\n        }\n    };\n\n    SilentRenewService.prototype._tokenExpiring = function _tokenExpiring() {\n        var _this = this;\n\n        this._userManager.signinSilent().then(function (user) {\n            _Log.Log.debug(\"SilentRenewService._tokenExpiring: Silent token renewal successful\");\n        }, function (err) {\n            _Log.Log.error(\"SilentRenewService._tokenExpiring: Error from signinSilent:\", err.message);\n            _this._userManager.events._raiseSilentRenewError(err);\n        });\n    };\n\n    return SilentRenewService;\n}();\n\n/***/ }),\n\n/***/ \"./src/State.js\":\n/*!**********************!*\\\n  !*** ./src/State.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.State = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _random = __webpack_require__(/*! ./random.js */ \"./src/random.js\");\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar State = exports.State = function () {\n    function State() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            id = _ref.id,\n            data = _ref.data,\n            created = _ref.created,\n            request_type = _ref.request_type;\n\n        _classCallCheck(this, State);\n\n        this._id = id || (0, _random2.default)();\n        this._data = data;\n\n        if (typeof created === 'number' && created > 0) {\n            this._created = created;\n        } else {\n            this._created = parseInt(Date.now() / 1000);\n        }\n        this._request_type = request_type;\n    }\n\n    State.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"State.toStorageString\");\n        return JSON.stringify({\n            id: this.id,\n            data: this.data,\n            created: this.created,\n            request_type: this.request_type\n        });\n    };\n\n    State.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"State.fromStorageString\");\n        return new State(JSON.parse(storageString));\n    };\n\n    State.clearStaleState = function clearStaleState(storage, age) {\n\n        var cutoff = Date.now() / 1000 - age;\n\n        return storage.getAllKeys().then(function (keys) {\n            _Log.Log.debug(\"State.clearStaleState: got keys\", keys);\n\n            var promises = [];\n\n            var _loop = function _loop(i) {\n                var key = keys[i];\n                p = storage.get(key).then(function (item) {\n                    var remove = false;\n\n                    if (item) {\n                        try {\n                            var state = State.fromStorageString(item);\n\n                            _Log.Log.debug(\"State.clearStaleState: got item from key: \", key, state.created);\n\n                            if (state.created <= cutoff) {\n                                remove = true;\n                            }\n                        } catch (e) {\n                            _Log.Log.error(\"State.clearStaleState: Error parsing state for key\", key, e.message);\n                            remove = true;\n                        }\n                    } else {\n                        _Log.Log.debug(\"State.clearStaleState: no item in storage for key: \", key);\n                        remove = true;\n                    }\n\n                    if (remove) {\n                        _Log.Log.debug(\"State.clearStaleState: removed item for key: \", key);\n                        return storage.remove(key);\n                    }\n                });\n\n\n                promises.push(p);\n            };\n\n            for (var i = 0; i < keys.length; i++) {\n                var p;\n\n                _loop(i);\n            }\n\n            _Log.Log.debug(\"State.clearStaleState: waiting on promise count:\", promises.length);\n            return Promise.all(promises);\n        });\n    };\n\n    _createClass(State, [{\n        key: 'id',\n        get: function get() {\n            return this._id;\n        }\n    }, {\n        key: 'data',\n        get: function get() {\n            return this._data;\n        }\n    }, {\n        key: 'created',\n        get: function get() {\n            return this._created;\n        }\n    }, {\n        key: 'request_type',\n        get: function get() {\n            return this._request_type;\n        }\n    }]);\n\n    return State;\n}();\n\n/***/ }),\n\n/***/ \"./src/Timer.js\":\n/*!**********************!*\\\n  !*** ./src/Timer.js ***!\n  \\**********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.Timer = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _Event2 = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TimerDuration = 5; // seconds\n\nvar Timer = exports.Timer = function (_Event) {\n    _inherits(Timer, _Event);\n\n    function Timer(name) {\n        var timer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.timer;\n        var nowFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;\n\n        _classCallCheck(this, Timer);\n\n        var _this = _possibleConstructorReturn(this, _Event.call(this, name));\n\n        _this._timer = timer;\n\n        if (nowFunc) {\n            _this._nowFunc = nowFunc;\n        } else {\n            _this._nowFunc = function () {\n                return Date.now() / 1000;\n            };\n        }\n        return _this;\n    }\n\n    Timer.prototype.init = function init(duration) {\n        if (duration <= 0) {\n            duration = 1;\n        }\n        duration = parseInt(duration);\n\n        var expiration = this.now + duration;\n        if (this.expiration === expiration && this._timerHandle) {\n            // no need to reinitialize to same expiration, so bail out\n            _Log.Log.debug(\"Timer.init timer \" + this._name + \" skipping initialization since already initialized for expiration:\", this.expiration);\n            return;\n        }\n\n        this.cancel();\n\n        _Log.Log.debug(\"Timer.init timer \" + this._name + \" for duration:\", duration);\n        this._expiration = expiration;\n\n        // we're using a fairly short timer and then checking the expiration in the\n        // callback to handle scenarios where the browser device sleeps, and then\n        // the timers end up getting delayed.\n        var timerDuration = TimerDuration;\n        if (duration < timerDuration) {\n            timerDuration = duration;\n        }\n        this._timerHandle = this._timer.setInterval(this._callback.bind(this), timerDuration * 1000);\n    };\n\n    Timer.prototype.cancel = function cancel() {\n        if (this._timerHandle) {\n            _Log.Log.debug(\"Timer.cancel: \", this._name);\n            this._timer.clearInterval(this._timerHandle);\n            this._timerHandle = null;\n        }\n    };\n\n    Timer.prototype._callback = function _callback() {\n        var diff = this._expiration - this.now;\n        _Log.Log.debug(\"Timer.callback; \" + this._name + \" timer expires in:\", diff);\n\n        if (this._expiration <= this.now) {\n            this.cancel();\n            _Event.prototype.raise.call(this);\n        }\n    };\n\n    _createClass(Timer, [{\n        key: 'now',\n        get: function get() {\n            return parseInt(this._nowFunc());\n        }\n    }, {\n        key: 'expiration',\n        get: function get() {\n            return this._expiration;\n        }\n    }]);\n\n    return Timer;\n}(_Event2.Event);\n\n/***/ }),\n\n/***/ \"./src/TokenClient.js\":\n/*!****************************!*\\\n  !*** ./src/TokenClient.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenClient = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar TokenClient = exports.TokenClient = function () {\n    function TokenClient(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenClient.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor();\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenClient.prototype.exchangeCode = function exchangeCode() {\n        var _this = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"authorization_code\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.redirect_uri = args.redirect_uri || this._settings.redirect_uri;\n\n        if (!args.code) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code passed\");\n            return Promise.reject(new Error(\"A code is required\"));\n        }\n        if (!args.redirect_uri) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No redirect_uri passed\");\n            return Promise.reject(new Error(\"A redirect_uri is required\"));\n        }\n        if (!args.code_verifier) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No code_verifier passed\");\n            return Promise.reject(new Error(\"A code_verifier is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeCode: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeCode: Received token endpoint\");\n\n            return _this._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeCode: response received\");\n                return response;\n            });\n        });\n    };\n\n    TokenClient.prototype.exchangeRefreshToken = function exchangeRefreshToken() {\n        var _this2 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.grant_type = args.grant_type || \"refresh_token\";\n        args.client_id = args.client_id || this._settings.client_id;\n        args.client_secret = args.client_secret || this._settings.client_secret;\n\n        if (!args.refresh_token) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No refresh_token passed\");\n            return Promise.reject(new Error(\"A refresh_token is required\"));\n        }\n        if (!args.client_id) {\n            _Log.Log.error(\"TokenClient.exchangeRefreshToken: No client_id passed\");\n            return Promise.reject(new Error(\"A client_id is required\"));\n        }\n\n        return this._metadataService.getTokenEndpoint(false).then(function (url) {\n            _Log.Log.debug(\"TokenClient.exchangeRefreshToken: Received token endpoint\");\n\n            return _this2._jsonService.postForm(url, args).then(function (response) {\n                _Log.Log.debug(\"TokenClient.exchangeRefreshToken: response received\");\n                return response;\n            });\n        });\n    };\n\n    return TokenClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/TokenRevocationClient.js\":\n/*!**************************************!*\\\n  !*** ./src/TokenRevocationClient.js ***!\n  \\**************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.TokenRevocationClient = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar AccessTokenTypeHint = \"access_token\";\nvar RefreshTokenTypeHint = \"refresh_token\";\n\nvar TokenRevocationClient = exports.TokenRevocationClient = function () {\n    function TokenRevocationClient(settings) {\n        var XMLHttpRequestCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _Global.Global.XMLHttpRequest;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n\n        _classCallCheck(this, TokenRevocationClient);\n\n        if (!settings) {\n            _Log.Log.error(\"TokenRevocationClient.ctor: No settings provided\");\n            throw new Error(\"No settings provided.\");\n        }\n\n        this._settings = settings;\n        this._XMLHttpRequestCtor = XMLHttpRequestCtor;\n        this._metadataService = new MetadataServiceCtor(this._settings);\n    }\n\n    TokenRevocationClient.prototype.revoke = function revoke(token, required) {\n        var _this = this;\n\n        var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : \"access_token\";\n\n        if (!token) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: No token provided\");\n            throw new Error(\"No token provided.\");\n        }\n\n        if (type !== AccessTokenTypeHint && type != RefreshTokenTypeHint) {\n            _Log.Log.error(\"TokenRevocationClient.revoke: Invalid token type\");\n            throw new Error(\"Invalid token type.\");\n        }\n\n        return this._metadataService.getRevocationEndpoint().then(function (url) {\n            if (!url) {\n                if (required) {\n                    _Log.Log.error(\"TokenRevocationClient.revoke: Revocation not supported\");\n                    throw new Error(\"Revocation not supported\");\n                }\n\n                // not required, so don't error and just return\n                return;\n            }\n\n            _Log.Log.debug(\"TokenRevocationClient.revoke: Revoking \" + type);\n            var client_id = _this._settings.client_id;\n            var client_secret = _this._settings.client_secret;\n            return _this._revoke(url, client_id, client_secret, token, type);\n        });\n    };\n\n    TokenRevocationClient.prototype._revoke = function _revoke(url, client_id, client_secret, token, type) {\n        var _this2 = this;\n\n        return new Promise(function (resolve, reject) {\n\n            var xhr = new _this2._XMLHttpRequestCtor();\n            xhr.open(\"POST\", url);\n\n            xhr.onload = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: HTTP response received, status\", xhr.status);\n\n                if (xhr.status === 200) {\n                    resolve();\n                } else {\n                    reject(Error(xhr.statusText + \" (\" + xhr.status + \")\"));\n                }\n            };\n            xhr.onerror = function () {\n                _Log.Log.debug(\"TokenRevocationClient.revoke: Network Error.\");\n                reject(\"Network Error\");\n            };\n\n            var body = \"client_id=\" + encodeURIComponent(client_id);\n            if (client_secret) {\n                body += \"&client_secret=\" + encodeURIComponent(client_secret);\n            }\n            body += \"&token_type_hint=\" + encodeURIComponent(type);\n            body += \"&token=\" + encodeURIComponent(token);\n\n            xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            xhr.send(body);\n        });\n    };\n\n    return TokenRevocationClient;\n}();\n\n/***/ }),\n\n/***/ \"./src/UrlUtility.js\":\n/*!***************************!*\\\n  !*** ./src/UrlUtility.js ***!\n  \\***************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UrlUtility = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UrlUtility = exports.UrlUtility = function () {\n    function UrlUtility() {\n        _classCallCheck(this, UrlUtility);\n    }\n\n    UrlUtility.addQueryParam = function addQueryParam(url, name, value) {\n        if (url.indexOf('?') < 0) {\n            url += \"?\";\n        }\n\n        if (url[url.length - 1] !== \"?\") {\n            url += \"&\";\n        }\n\n        url += encodeURIComponent(name);\n        url += \"=\";\n        url += encodeURIComponent(value);\n\n        return url;\n    };\n\n    UrlUtility.parseUrlFragment = function parseUrlFragment(value) {\n        var delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : \"#\";\n        var global = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _Global.Global;\n\n        if (typeof value !== 'string') {\n            value = global.location.href;\n        }\n\n        var idx = value.lastIndexOf(delimiter);\n        if (idx >= 0) {\n            value = value.substr(idx + 1);\n        }\n\n        if (delimiter === \"?\") {\n            // if we're doing query, then strip off hash fragment before we parse\n            idx = value.indexOf('#');\n            if (idx >= 0) {\n                value = value.substr(0, idx);\n            }\n        }\n\n        var params = {},\n            regex = /([^&=]+)=([^&]*)/g,\n            m;\n\n        var counter = 0;\n        while (m = regex.exec(value)) {\n            params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);\n            if (counter++ > 50) {\n                _Log.Log.error(\"UrlUtility.parseUrlFragment: response exceeded expected number of parameters\", value);\n                return {\n                    error: \"Response exceeded expected number of parameters\"\n                };\n            }\n        }\n\n        for (var prop in params) {\n            return params;\n        }\n\n        return {};\n    };\n\n    return UrlUtility;\n}();\n\n/***/ }),\n\n/***/ \"./src/User.js\":\n/*!*********************!*\\\n  !*** ./src/User.js ***!\n  \\*********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.User = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar User = exports.User = function () {\n    function User(_ref) {\n        var id_token = _ref.id_token,\n            session_state = _ref.session_state,\n            access_token = _ref.access_token,\n            refresh_token = _ref.refresh_token,\n            token_type = _ref.token_type,\n            scope = _ref.scope,\n            profile = _ref.profile,\n            expires_at = _ref.expires_at,\n            state = _ref.state;\n\n        _classCallCheck(this, User);\n\n        this.id_token = id_token;\n        this.session_state = session_state;\n        this.access_token = access_token;\n        this.refresh_token = refresh_token;\n        this.token_type = token_type;\n        this.scope = scope;\n        this.profile = profile;\n        this.expires_at = expires_at;\n        this.state = state;\n    }\n\n    User.prototype.toStorageString = function toStorageString() {\n        _Log.Log.debug(\"User.toStorageString\");\n        return JSON.stringify({\n            id_token: this.id_token,\n            session_state: this.session_state,\n            access_token: this.access_token,\n            refresh_token: this.refresh_token,\n            token_type: this.token_type,\n            scope: this.scope,\n            profile: this.profile,\n            expires_at: this.expires_at\n        });\n    };\n\n    User.fromStorageString = function fromStorageString(storageString) {\n        _Log.Log.debug(\"User.fromStorageString\");\n        return new User(JSON.parse(storageString));\n    };\n\n    _createClass(User, [{\n        key: 'expires_in',\n        get: function get() {\n            if (this.expires_at) {\n                var now = parseInt(Date.now() / 1000);\n                return this.expires_at - now;\n            }\n            return undefined;\n        },\n        set: function set(value) {\n            var expires_in = parseInt(value);\n            if (typeof expires_in === 'number' && expires_in > 0) {\n                var now = parseInt(Date.now() / 1000);\n                this.expires_at = now + expires_in;\n            }\n        }\n    }, {\n        key: 'expired',\n        get: function get() {\n            var expires_in = this.expires_in;\n            if (expires_in !== undefined) {\n                return expires_in <= 0;\n            }\n            return undefined;\n        }\n    }, {\n        key: 'scopes',\n        get: function get() {\n            return (this.scope || \"\").split(\" \");\n        }\n    }]);\n\n    return User;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserInfoService.js\":\n/*!********************************!*\\\n  !*** ./src/UserInfoService.js ***!\n  \\********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserInfoService = undefined;\n\nvar _JsonService = __webpack_require__(/*! ./JsonService.js */ \"./src/JsonService.js\");\n\nvar _MetadataService = __webpack_require__(/*! ./MetadataService.js */ \"./src/MetadataService.js\");\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserInfoService = exports.UserInfoService = function () {\n    function UserInfoService(settings) {\n        var JsonServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _JsonService.JsonService;\n        var MetadataServiceCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _MetadataService.MetadataService;\n        var joseUtil = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserInfoService);\n\n        if (!settings) {\n            _Log.Log.error(\"UserInfoService.ctor: No settings passed\");\n            throw new Error(\"settings\");\n        }\n\n        this._settings = settings;\n        this._jsonService = new JsonServiceCtor(undefined, undefined, this._getClaimsFromJwt.bind(this));\n        this._metadataService = new MetadataServiceCtor(this._settings);\n        this._joseUtil = joseUtil;\n    }\n\n    UserInfoService.prototype.getClaims = function getClaims(token) {\n        var _this = this;\n\n        if (!token) {\n            _Log.Log.error(\"UserInfoService.getClaims: No token passed\");\n            return Promise.reject(new Error(\"A token is required\"));\n        }\n\n        return this._metadataService.getUserInfoEndpoint().then(function (url) {\n            _Log.Log.debug(\"UserInfoService.getClaims: received userinfo url\", url);\n\n            return _this._jsonService.getJson(url, token).then(function (claims) {\n                _Log.Log.debug(\"UserInfoService.getClaims: claims received\", claims);\n                return claims;\n            });\n        });\n    };\n\n    UserInfoService.prototype._getClaimsFromJwt = function _getClaimsFromJwt(req) {\n        var _this2 = this;\n\n        try {\n            var jwt = this._joseUtil.parseJwt(req.responseText);\n            if (!jwt || !jwt.header || !jwt.payload) {\n                _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Failed to parse JWT\", jwt);\n                return Promise.reject(new Error(\"Failed to parse id_token\"));\n            }\n\n            var kid = jwt.header.kid;\n\n            var issuerPromise = void 0;\n            switch (this._settings.userInfoJwtIssuer) {\n                case 'OP':\n                    issuerPromise = this._metadataService.getIssuer();\n                    break;\n                case 'ANY':\n                    issuerPromise = Promise.resolve(jwt.payload.iss);\n                    break;\n                default:\n                    issuerPromise = Promise.resolve(this._settings.userInfoJwtIssuer);\n                    break;\n            }\n\n            return issuerPromise.then(function (issuer) {\n                _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received issuer:\" + issuer);\n\n                return _this2._metadataService.getSigningKeys().then(function (keys) {\n                    if (!keys) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No signing keys from metadata\");\n                        return Promise.reject(new Error(\"No signing keys from metadata\"));\n                    }\n\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Received signing keys\");\n                    var key = void 0;\n                    if (!kid) {\n                        keys = _this2._filterByAlg(keys, jwt.header.alg);\n\n                        if (keys.length > 1) {\n                            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No kid found in id_token and more than one key found in metadata\");\n                            return Promise.reject(new Error(\"No kid found in id_token and more than one key found in metadata\"));\n                        } else {\n                            // kid is mandatory only when there are multiple keys in the referenced JWK Set document\n                            // see http://openid.net/specs/openid-connect-core-1_0.html#Signing\n                            key = keys[0];\n                        }\n                    } else {\n                        key = keys.filter(function (key) {\n                            return key.kid === kid;\n                        })[0];\n                    }\n\n                    if (!key) {\n                        _Log.Log.error(\"UserInfoService._getClaimsFromJwt: No key matching kid or alg found in signing keys\");\n                        return Promise.reject(new Error(\"No key matching kid or alg found in signing keys\"));\n                    }\n\n                    var audience = _this2._settings.client_id;\n\n                    var clockSkewInSeconds = _this2._settings.clockSkew;\n                    _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: Validaing JWT; using clock skew (in seconds) of: \", clockSkewInSeconds);\n\n                    return _this2._joseUtil.validateJwt(req.responseText, key, issuer, audience, clockSkewInSeconds, undefined, true).then(function () {\n                        _Log.Log.debug(\"UserInfoService._getClaimsFromJwt: JWT validation successful\");\n                        return jwt.payload;\n                    });\n                });\n            });\n            return;\n        } catch (e) {\n            _Log.Log.error(\"UserInfoService._getClaimsFromJwt: Error parsing JWT response\", e.message);\n            reject(e);\n            return;\n        }\n    };\n\n    UserInfoService.prototype._filterByAlg = function _filterByAlg(keys, alg) {\n        var kty = null;\n        if (alg.startsWith(\"RS\")) {\n            kty = \"RSA\";\n        } else if (alg.startsWith(\"PS\")) {\n            kty = \"PS\";\n        } else if (alg.startsWith(\"ES\")) {\n            kty = \"EC\";\n        } else {\n            _Log.Log.debug(\"UserInfoService._filterByAlg: alg not supported: \", alg);\n            return [];\n        }\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Looking for keys that match kty: \", kty);\n\n        keys = keys.filter(function (key) {\n            return key.kty === kty;\n        });\n\n        _Log.Log.debug(\"UserInfoService._filterByAlg: Number of keys that match kty: \", kty, keys.length);\n\n        return keys;\n    };\n\n    return UserInfoService;\n}();\n\n/***/ }),\n\n/***/ \"./src/UserManager.js\":\n/*!****************************!*\\\n  !*** ./src/UserManager.js ***!\n  \\****************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManager = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClient2 = __webpack_require__(/*! ./OidcClient.js */ \"./src/OidcClient.js\");\n\nvar _UserManagerSettings = __webpack_require__(/*! ./UserManagerSettings.js */ \"./src/UserManagerSettings.js\");\n\nvar _User = __webpack_require__(/*! ./User.js */ \"./src/User.js\");\n\nvar _UserManagerEvents = __webpack_require__(/*! ./UserManagerEvents.js */ \"./src/UserManagerEvents.js\");\n\nvar _SilentRenewService = __webpack_require__(/*! ./SilentRenewService.js */ \"./src/SilentRenewService.js\");\n\nvar _SessionMonitor = __webpack_require__(/*! ./SessionMonitor.js */ \"./src/SessionMonitor.js\");\n\nvar _TokenRevocationClient = __webpack_require__(/*! ./TokenRevocationClient.js */ \"./src/TokenRevocationClient.js\");\n\nvar _TokenClient = __webpack_require__(/*! ./TokenClient.js */ \"./src/TokenClient.js\");\n\nvar _JoseUtil = __webpack_require__(/*! ./JoseUtil.js */ \"./src/JoseUtil.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManager = exports.UserManager = function (_OidcClient) {\n    _inherits(UserManager, _OidcClient);\n\n    function UserManager() {\n        var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n        var SilentRenewServiceCtor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _SilentRenewService.SilentRenewService;\n        var SessionMonitorCtor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _SessionMonitor.SessionMonitor;\n        var TokenRevocationClientCtor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _TokenRevocationClient.TokenRevocationClient;\n        var TokenClientCtor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _TokenClient.TokenClient;\n        var joseUtil = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : _JoseUtil.JoseUtil;\n\n        _classCallCheck(this, UserManager);\n\n        if (!(settings instanceof _UserManagerSettings.UserManagerSettings)) {\n            settings = new _UserManagerSettings.UserManagerSettings(settings);\n        }\n\n        var _this = _possibleConstructorReturn(this, _OidcClient.call(this, settings));\n\n        _this._events = new _UserManagerEvents.UserManagerEvents(settings);\n        _this._silentRenewService = new SilentRenewServiceCtor(_this);\n\n        // order is important for the following properties; these services depend upon the events.\n        if (_this.settings.automaticSilentRenew) {\n            _Log.Log.debug(\"UserManager.ctor: automaticSilentRenew is configured, setting up silent renew\");\n            _this.startSilentRenew();\n        }\n\n        if (_this.settings.monitorSession) {\n            _Log.Log.debug(\"UserManager.ctor: monitorSession is configured, setting up session monitor\");\n            _this._sessionMonitor = new SessionMonitorCtor(_this);\n        }\n\n        _this._tokenRevocationClient = new TokenRevocationClientCtor(_this._settings);\n        _this._tokenClient = new TokenClientCtor(_this._settings);\n        _this._joseUtil = joseUtil;\n        return _this;\n    }\n\n    UserManager.prototype.getUser = function getUser() {\n        var _this2 = this;\n\n        return this._loadUser().then(function (user) {\n            if (user) {\n                _Log.Log.info(\"UserManager.getUser: user loaded\");\n\n                _this2._events.load(user, false);\n\n                return user;\n            } else {\n                _Log.Log.info(\"UserManager.getUser: user not found in storage\");\n                return null;\n            }\n        });\n    };\n\n    UserManager.prototype.removeUser = function removeUser() {\n        var _this3 = this;\n\n        return this.storeUser(null).then(function () {\n            _Log.Log.info(\"UserManager.removeUser: user removed from storage\");\n            _this3._events.unload();\n        });\n    };\n\n    UserManager.prototype.signinRedirect = function signinRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:r\";\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signinStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signinRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signinRedirectCallback = function signinRedirectCallback(url) {\n        return this._signinEnd(url || this._redirectNavigator.url).then(function (user) {\n            if (user.profile && user.profile.sub) {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: successful, signed in sub: \", user.profile.sub);\n            } else {\n                _Log.Log.info(\"UserManager.signinRedirectCallback: no sub\");\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopup = function signinPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:p\";\n        var url = args.redirect_uri || this.settings.popup_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinPopup: No popup_redirect_uri or redirect_uri configured\");\n            return Promise.reject(new Error(\"No popup_redirect_uri or redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.display = \"popup\";\n\n        return this._signin(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopup: signinPopup successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopup: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinPopupCallback = function signinPopupCallback(url) {\n        return this._signinCallback(url, this._popupNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinPopupCallback: no sub\");\n                }\n            }\n\n            return user;\n        }).catch(function (err) {\n            _Log.Log.error( true && err.message);\n        });\n    };\n\n    UserManager.prototype.signinSilent = function signinSilent() {\n        var _this4 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\";\n        // first determine if we have a refresh token, or need to use iframe\n        return this._loadUser().then(function (user) {\n            if (user && user.refresh_token) {\n                args.refresh_token = user.refresh_token;\n                return _this4._useRefreshToken(args);\n            } else {\n                args.id_token_hint = args.id_token_hint || _this4.settings.includeIdTokenInSilentRenew && user && user.id_token;\n                if (user && _this4._settings.validateSubOnSilentRenew) {\n                    _Log.Log.debug(\"UserManager.signinSilent, subject prior to silent renew: \", user.profile.sub);\n                    args.current_sub = user.profile.sub;\n                }\n                return _this4._signinSilentIframe(args);\n            }\n        });\n    };\n\n    UserManager.prototype._useRefreshToken = function _useRefreshToken() {\n        var _this5 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        return this._tokenClient.exchangeRefreshToken(args).then(function (result) {\n            if (!result) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No response returned from token endpoint\");\n                return Promise.reject(\"No response returned from token endpoint\");\n            }\n            if (!result.access_token) {\n                _Log.Log.error(\"UserManager._useRefreshToken: No access token returned from token endpoint\");\n                return Promise.reject(\"No access token returned from token endpoint\");\n            }\n\n            return _this5._loadUser().then(function (user) {\n                if (user) {\n                    var idTokenValidation = Promise.resolve();\n                    if (result.id_token) {\n                        idTokenValidation = _this5._validateIdTokenFromTokenRefreshToken(user.profile, result.id_token);\n                    }\n\n                    return idTokenValidation.then(function () {\n                        _Log.Log.debug(\"UserManager._useRefreshToken: refresh token response success\");\n                        user.id_token = result.id_token;\n                        user.access_token = result.access_token;\n                        user.refresh_token = result.refresh_token || user.refresh_token;\n                        user.expires_in = result.expires_in;\n\n                        return _this5.storeUser(user).then(function () {\n                            _this5._events.load(user);\n                            return user;\n                        });\n                    });\n                } else {\n                    return null;\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._validateIdTokenFromTokenRefreshToken = function _validateIdTokenFromTokenRefreshToken(profile, id_token) {\n        var _this6 = this;\n\n        return this._metadataService.getIssuer().then(function (issuer) {\n            return _this6._joseUtil.validateJwtAttributes(id_token, issuer, _this6._settings.client_id, _this6._settings.clockSkew).then(function (payload) {\n                if (!payload) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: Failed to validate id_token\");\n                    return Promise.reject(new Error(\"Failed to validate id_token\"));\n                }\n                if (payload.sub !== profile.sub) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: sub in id_token does not match current sub\");\n                    return Promise.reject(new Error(\"sub in id_token does not match current sub\"));\n                }\n                if (payload.auth_time && payload.auth_time !== profile.auth_time) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: auth_time in id_token does not match original auth_time\");\n                    return Promise.reject(new Error(\"auth_time in id_token does not match original auth_time\"));\n                }\n                if (payload.azp && payload.azp !== profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp in id_token does not match original azp\");\n                    return Promise.reject(new Error(\"azp in id_token does not match original azp\"));\n                }\n                if (!payload.azp && profile.azp) {\n                    _Log.Log.error(\"UserManager._validateIdTokenFromTokenRefreshToken: azp not in id_token, but present in original id_token\");\n                    return Promise.reject(new Error(\"azp not in id_token, but present in original id_token\"));\n                }\n            });\n        });\n    };\n\n    UserManager.prototype._signinSilentIframe = function _signinSilentIframe() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.signinSilent: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = args.prompt || \"none\";\n\n        return this._signin(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilent: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilent: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinSilentCallback = function signinSilentCallback(url) {\n        return this._signinCallback(url, this._iframeNavigator).then(function (user) {\n            if (user) {\n                if (user.profile && user.profile.sub) {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: successful, signed in sub: \", user.profile.sub);\n                } else {\n                    _Log.Log.info(\"UserManager.signinSilentCallback: no sub\");\n                }\n            }\n\n            return user;\n        });\n    };\n\n    UserManager.prototype.signinCallback = function signinCallback(url) {\n        var _this7 = this;\n\n        return this.readSigninResponseState(url).then(function (_ref) {\n            var state = _ref.state,\n                response = _ref.response;\n\n            if (state.request_type === \"si:r\") {\n                return _this7.signinRedirectCallback(url);\n            }\n            if (state.request_type === \"si:p\") {\n                return _this7.signinPopupCallback(url);\n            }\n            if (state.request_type === \"si:s\") {\n                return _this7.signinSilentCallback(url);\n            }\n            return Promise.reject(new Error(\"invalid response_type in state\"));\n        });\n    };\n\n    UserManager.prototype.signoutCallback = function signoutCallback(url, keepOpen) {\n        var _this8 = this;\n\n        return this.readSignoutResponseState(url).then(function (_ref2) {\n            var state = _ref2.state,\n                response = _ref2.response;\n\n            if (state) {\n                if (state.request_type === \"so:r\") {\n                    return _this8.signoutRedirectCallback(url);\n                }\n                if (state.request_type === \"so:p\") {\n                    return _this8.signoutPopupCallback(url, keepOpen);\n                }\n                return Promise.reject(new Error(\"invalid response_type in state\"));\n            }\n            return response;\n        });\n    };\n\n    UserManager.prototype.querySessionStatus = function querySessionStatus() {\n        var _this9 = this;\n\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"si:s\"; // this acts like a signin silent\n        var url = args.redirect_uri || this.settings.silent_redirect_uri || this.settings.redirect_uri;\n        if (!url) {\n            _Log.Log.error(\"UserManager.querySessionStatus: No silent_redirect_uri configured\");\n            return Promise.reject(new Error(\"No silent_redirect_uri configured\"));\n        }\n\n        args.redirect_uri = url;\n        args.prompt = \"none\";\n        args.response_type = args.response_type || this.settings.query_status_response_type;\n        args.scope = args.scope || \"openid\";\n        args.skipUserInfo = true;\n\n        return this._signinStart(args, this._iframeNavigator, {\n            startUrl: url,\n            silentRequestTimeout: args.silentRequestTimeout || this.settings.silentRequestTimeout\n        }).then(function (navResponse) {\n            return _this9.processSigninResponse(navResponse.url).then(function (signinResponse) {\n                _Log.Log.debug(\"UserManager.querySessionStatus: got signin response\");\n\n                if (signinResponse.session_state && signinResponse.profile.sub) {\n                    _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for sub: \", signinResponse.profile.sub);\n                    return {\n                        session_state: signinResponse.session_state,\n                        sub: signinResponse.profile.sub,\n                        sid: signinResponse.profile.sid\n                    };\n                } else {\n                    _Log.Log.info(\"querySessionStatus successful, user not authenticated\");\n                }\n            }).catch(function (err) {\n                if (err.session_state && _this9.settings.monitorAnonymousSession) {\n                    if (err.message == \"login_required\" || err.message == \"consent_required\" || err.message == \"interaction_required\" || err.message == \"account_selection_required\") {\n                        _Log.Log.info(\"UserManager.querySessionStatus: querySessionStatus success for anonymous user\");\n                        return {\n                            session_state: err.session_state\n                        };\n                    }\n                }\n\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signin = function _signin(args, navigator) {\n        var _this10 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signinStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this10._signinEnd(navResponse.url, args);\n        });\n    };\n\n    UserManager.prototype._signinStart = function _signinStart(args, navigator) {\n        var _this11 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signinStart: got navigator window handle\");\n\n            return _this11.createSigninRequest(args).then(function (signinRequest) {\n                _Log.Log.debug(\"UserManager._signinStart: got signin request\");\n\n                navigatorParams.url = signinRequest.url;\n                navigatorParams.id = signinRequest.state.id;\n\n                return handle.navigate(navigatorParams);\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signinStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signinEnd = function _signinEnd(url) {\n        var _this12 = this;\n\n        var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n        return this.processSigninResponse(url).then(function (signinResponse) {\n            _Log.Log.debug(\"UserManager._signinEnd: got signin response\");\n\n            var user = new _User.User(signinResponse);\n\n            if (args.current_sub) {\n                if (args.current_sub !== user.profile.sub) {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user does not match user returned from signin. sub from signin: \", user.profile.sub);\n                    return Promise.reject(new Error(\"login_required\"));\n                } else {\n                    _Log.Log.debug(\"UserManager._signinEnd: current user matches user returned from signin\");\n                }\n            }\n\n            return _this12.storeUser(user).then(function () {\n                _Log.Log.debug(\"UserManager._signinEnd: user stored\");\n\n                _this12._events.load(user);\n\n                return user;\n            });\n        });\n    };\n\n    UserManager.prototype._signinCallback = function _signinCallback(url, navigator) {\n        _Log.Log.debug(\"UserManager._signinCallback\");\n        return navigator.callback(url);\n    };\n\n    UserManager.prototype.signoutRedirect = function signoutRedirect() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:r\";\n        var postLogoutRedirectUri = args.post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        if (postLogoutRedirectUri) {\n            args.post_logout_redirect_uri = postLogoutRedirectUri;\n        }\n        var navParams = {\n            useReplaceToNavigate: args.useReplaceToNavigate\n        };\n        return this._signoutStart(args, this._redirectNavigator, navParams).then(function () {\n            _Log.Log.info(\"UserManager.signoutRedirect: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutRedirectCallback = function signoutRedirectCallback(url) {\n        return this._signoutEnd(url || this._redirectNavigator.url).then(function (response) {\n            _Log.Log.info(\"UserManager.signoutRedirectCallback: successful\");\n            return response;\n        });\n    };\n\n    UserManager.prototype.signoutPopup = function signoutPopup() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        args = Object.assign({}, args);\n\n        args.request_type = \"so:p\";\n        var url = args.post_logout_redirect_uri || this.settings.popup_post_logout_redirect_uri || this.settings.post_logout_redirect_uri;\n        args.post_logout_redirect_uri = url;\n        args.display = \"popup\";\n        if (args.post_logout_redirect_uri) {\n            // we're putting a dummy entry in here because we\n            // need a unique id from the state for notification\n            // to the parent window, which is necessary if we\n            // plan to return back to the client after signout\n            // and so we can close the popup after signout\n            args.state = args.state || {};\n        }\n\n        return this._signout(args, this._popupNavigator, {\n            startUrl: url,\n            popupWindowFeatures: args.popupWindowFeatures || this.settings.popupWindowFeatures,\n            popupWindowTarget: args.popupWindowTarget || this.settings.popupWindowTarget\n        }).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopup: successful\");\n        });\n    };\n\n    UserManager.prototype.signoutPopupCallback = function signoutPopupCallback(url, keepOpen) {\n        if (typeof keepOpen === 'undefined' && typeof url === 'boolean') {\n            keepOpen = url;\n            url = null;\n        }\n\n        var delimiter = '?';\n        return this._popupNavigator.callback(url, keepOpen, delimiter).then(function () {\n            _Log.Log.info(\"UserManager.signoutPopupCallback: successful\");\n        });\n    };\n\n    UserManager.prototype._signout = function _signout(args, navigator) {\n        var _this13 = this;\n\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return this._signoutStart(args, navigator, navigatorParams).then(function (navResponse) {\n            return _this13._signoutEnd(navResponse.url);\n        });\n    };\n\n    UserManager.prototype._signoutStart = function _signoutStart() {\n        var args = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n        var _this14 = this;\n\n        var navigator = arguments[1];\n        var navigatorParams = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n        return navigator.prepare(navigatorParams).then(function (handle) {\n            _Log.Log.debug(\"UserManager._signoutStart: got navigator window handle\");\n\n            return _this14._loadUser().then(function (user) {\n                _Log.Log.debug(\"UserManager._signoutStart: loaded current user from storage\");\n\n                var revokePromise = _this14._settings.revokeAccessTokenOnSignout ? _this14._revokeInternal(user) : Promise.resolve();\n                return revokePromise.then(function () {\n\n                    var id_token = args.id_token_hint || user && user.id_token;\n                    if (id_token) {\n                        _Log.Log.debug(\"UserManager._signoutStart: Setting id_token into signout request\");\n                        args.id_token_hint = id_token;\n                    }\n\n                    return _this14.removeUser().then(function () {\n                        _Log.Log.debug(\"UserManager._signoutStart: user removed, creating signout request\");\n\n                        return _this14.createSignoutRequest(args).then(function (signoutRequest) {\n                            _Log.Log.debug(\"UserManager._signoutStart: got signout request\");\n\n                            navigatorParams.url = signoutRequest.url;\n                            if (signoutRequest.state) {\n                                navigatorParams.id = signoutRequest.state.id;\n                            }\n                            return handle.navigate(navigatorParams);\n                        });\n                    });\n                });\n            }).catch(function (err) {\n                if (handle.close) {\n                    _Log.Log.debug(\"UserManager._signoutStart: Error after preparing navigator, closing navigator window\");\n                    handle.close();\n                }\n                throw err;\n            });\n        });\n    };\n\n    UserManager.prototype._signoutEnd = function _signoutEnd(url) {\n        return this.processSignoutResponse(url).then(function (signoutResponse) {\n            _Log.Log.debug(\"UserManager._signoutEnd: got signout response\");\n\n            return signoutResponse;\n        });\n    };\n\n    UserManager.prototype.revokeAccessToken = function revokeAccessToken() {\n        var _this15 = this;\n\n        return this._loadUser().then(function (user) {\n            return _this15._revokeInternal(user, true).then(function (success) {\n                if (success) {\n                    _Log.Log.debug(\"UserManager.revokeAccessToken: removing token properties from user and re-storing\");\n\n                    user.access_token = null;\n                    user.refresh_token = null;\n                    user.expires_at = null;\n                    user.token_type = null;\n\n                    return _this15.storeUser(user).then(function () {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: user stored\");\n                        _this15._events.load(user);\n                    });\n                }\n            });\n        }).then(function () {\n            _Log.Log.info(\"UserManager.revokeAccessToken: access token revoked successfully\");\n        });\n    };\n\n    UserManager.prototype._revokeInternal = function _revokeInternal(user, required) {\n        var _this16 = this;\n\n        if (user) {\n            var access_token = user.access_token;\n            var refresh_token = user.refresh_token;\n\n            return this._revokeAccessTokenInternal(access_token, required).then(function (atSuccess) {\n                return _this16._revokeRefreshTokenInternal(refresh_token, required).then(function (rtSuccess) {\n                    if (!atSuccess && !rtSuccess) {\n                        _Log.Log.debug(\"UserManager.revokeAccessToken: no need to revoke due to no token(s), or JWT format\");\n                    }\n\n                    return atSuccess || rtSuccess;\n                });\n            });\n        }\n\n        return Promise.resolve(false);\n    };\n\n    UserManager.prototype._revokeAccessTokenInternal = function _revokeAccessTokenInternal(access_token, required) {\n        // check for JWT vs. reference token\n        if (!access_token || access_token.indexOf('.') >= 0) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(access_token, required).then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype._revokeRefreshTokenInternal = function _revokeRefreshTokenInternal(refresh_token, required) {\n        if (!refresh_token) {\n            return Promise.resolve(false);\n        }\n\n        return this._tokenRevocationClient.revoke(refresh_token, required, \"refresh_token\").then(function () {\n            return true;\n        });\n    };\n\n    UserManager.prototype.startSilentRenew = function startSilentRenew() {\n        this._silentRenewService.start();\n    };\n\n    UserManager.prototype.stopSilentRenew = function stopSilentRenew() {\n        this._silentRenewService.stop();\n    };\n\n    UserManager.prototype._loadUser = function _loadUser() {\n        return this._userStore.get(this._userStoreKey).then(function (storageString) {\n            if (storageString) {\n                _Log.Log.debug(\"UserManager._loadUser: user storageString loaded\");\n                return _User.User.fromStorageString(storageString);\n            }\n\n            _Log.Log.debug(\"UserManager._loadUser: no user storageString\");\n            return null;\n        });\n    };\n\n    UserManager.prototype.storeUser = function storeUser(user) {\n        if (user) {\n            _Log.Log.debug(\"UserManager.storeUser: storing user\");\n\n            var storageString = user.toStorageString();\n            return this._userStore.set(this._userStoreKey, storageString);\n        } else {\n            _Log.Log.debug(\"storeUser.storeUser: removing user\");\n            return this._userStore.remove(this._userStoreKey);\n        }\n    };\n\n    _createClass(UserManager, [{\n        key: '_redirectNavigator',\n        get: function get() {\n            return this.settings.redirectNavigator;\n        }\n    }, {\n        key: '_popupNavigator',\n        get: function get() {\n            return this.settings.popupNavigator;\n        }\n    }, {\n        key: '_iframeNavigator',\n        get: function get() {\n            return this.settings.iframeNavigator;\n        }\n    }, {\n        key: '_userStore',\n        get: function get() {\n            return this.settings.userStore;\n        }\n    }, {\n        key: 'events',\n        get: function get() {\n            return this._events;\n        }\n    }, {\n        key: '_userStoreKey',\n        get: function get() {\n            return 'user:' + this.settings.authority + ':' + this.settings.client_id;\n        }\n    }]);\n\n    return UserManager;\n}(_OidcClient2.OidcClient);\n\n/***/ }),\n\n/***/ \"./src/UserManagerEvents.js\":\n/*!**********************************!*\\\n  !*** ./src/UserManagerEvents.js ***!\n  \\**********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerEvents = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _AccessTokenEvents2 = __webpack_require__(/*! ./AccessTokenEvents.js */ \"./src/AccessTokenEvents.js\");\n\nvar _Event = __webpack_require__(/*! ./Event.js */ \"./src/Event.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar UserManagerEvents = exports.UserManagerEvents = function (_AccessTokenEvents) {\n    _inherits(UserManagerEvents, _AccessTokenEvents);\n\n    function UserManagerEvents(settings) {\n        _classCallCheck(this, UserManagerEvents);\n\n        var _this = _possibleConstructorReturn(this, _AccessTokenEvents.call(this, settings));\n\n        _this._userLoaded = new _Event.Event(\"User loaded\");\n        _this._userUnloaded = new _Event.Event(\"User unloaded\");\n        _this._silentRenewError = new _Event.Event(\"Silent renew error\");\n        _this._userSignedIn = new _Event.Event(\"User signed in\");\n        _this._userSignedOut = new _Event.Event(\"User signed out\");\n        _this._userSessionChanged = new _Event.Event(\"User session changed\");\n        return _this;\n    }\n\n    UserManagerEvents.prototype.load = function load(user) {\n        var raiseEvent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n        _Log.Log.debug(\"UserManagerEvents.load\");\n        _AccessTokenEvents.prototype.load.call(this, user);\n        if (raiseEvent) {\n            this._userLoaded.raise(user);\n        }\n    };\n\n    UserManagerEvents.prototype.unload = function unload() {\n        _Log.Log.debug(\"UserManagerEvents.unload\");\n        _AccessTokenEvents.prototype.unload.call(this);\n        this._userUnloaded.raise();\n    };\n\n    UserManagerEvents.prototype.addUserLoaded = function addUserLoaded(cb) {\n        this._userLoaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserLoaded = function removeUserLoaded(cb) {\n        this._userLoaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addUserUnloaded = function addUserUnloaded(cb) {\n        this._userUnloaded.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserUnloaded = function removeUserUnloaded(cb) {\n        this._userUnloaded.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype.addSilentRenewError = function addSilentRenewError(cb) {\n        this._silentRenewError.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeSilentRenewError = function removeSilentRenewError(cb) {\n        this._silentRenewError.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseSilentRenewError = function _raiseSilentRenewError(e) {\n        _Log.Log.debug(\"UserManagerEvents._raiseSilentRenewError\", e.message);\n        this._silentRenewError.raise(e);\n    };\n\n    UserManagerEvents.prototype.addUserSignedIn = function addUserSignedIn(cb) {\n        this._userSignedIn.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedIn = function removeUserSignedIn(cb) {\n        this._userSignedIn.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedIn = function _raiseUserSignedIn() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedIn\");\n        this._userSignedIn.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSignedOut = function addUserSignedOut(cb) {\n        this._userSignedOut.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSignedOut = function removeUserSignedOut(cb) {\n        this._userSignedOut.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSignedOut = function _raiseUserSignedOut() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSignedOut\");\n        this._userSignedOut.raise();\n    };\n\n    UserManagerEvents.prototype.addUserSessionChanged = function addUserSessionChanged(cb) {\n        this._userSessionChanged.addHandler(cb);\n    };\n\n    UserManagerEvents.prototype.removeUserSessionChanged = function removeUserSessionChanged(cb) {\n        this._userSessionChanged.removeHandler(cb);\n    };\n\n    UserManagerEvents.prototype._raiseUserSessionChanged = function _raiseUserSessionChanged() {\n        _Log.Log.debug(\"UserManagerEvents._raiseUserSessionChanged\");\n        this._userSessionChanged.raise();\n    };\n\n    return UserManagerEvents;\n}(_AccessTokenEvents2.AccessTokenEvents);\n\n/***/ }),\n\n/***/ \"./src/UserManagerSettings.js\":\n/*!************************************!*\\\n  !*** ./src/UserManagerSettings.js ***!\n  \\************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.UserManagerSettings = undefined;\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _OidcClientSettings2 = __webpack_require__(/*! ./OidcClientSettings.js */ \"./src/OidcClientSettings.js\");\n\nvar _RedirectNavigator = __webpack_require__(/*! ./RedirectNavigator.js */ \"./src/RedirectNavigator.js\");\n\nvar _PopupNavigator = __webpack_require__(/*! ./PopupNavigator.js */ \"./src/PopupNavigator.js\");\n\nvar _IFrameNavigator = __webpack_require__(/*! ./IFrameNavigator.js */ \"./src/IFrameNavigator.js\");\n\nvar _WebStorageStateStore = __webpack_require__(/*! ./WebStorageStateStore.js */ \"./src/WebStorageStateStore.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nvar _SigninRequest = __webpack_require__(/*! ./SigninRequest.js */ \"./src/SigninRequest.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar DefaultAccessTokenExpiringNotificationTime = 60;\nvar DefaultCheckSessionInterval = 2000;\n\nvar UserManagerSettings = exports.UserManagerSettings = function (_OidcClientSettings) {\n    _inherits(UserManagerSettings, _OidcClientSettings);\n\n    function UserManagerSettings() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            popup_redirect_uri = _ref.popup_redirect_uri,\n            popup_post_logout_redirect_uri = _ref.popup_post_logout_redirect_uri,\n            popupWindowFeatures = _ref.popupWindowFeatures,\n            popupWindowTarget = _ref.popupWindowTarget,\n            silent_redirect_uri = _ref.silent_redirect_uri,\n            silentRequestTimeout = _ref.silentRequestTimeout,\n            _ref$automaticSilentR = _ref.automaticSilentRenew,\n            automaticSilentRenew = _ref$automaticSilentR === undefined ? false : _ref$automaticSilentR,\n            _ref$validateSubOnSil = _ref.validateSubOnSilentRenew,\n            validateSubOnSilentRenew = _ref$validateSubOnSil === undefined ? false : _ref$validateSubOnSil,\n            _ref$includeIdTokenIn = _ref.includeIdTokenInSilentRenew,\n            includeIdTokenInSilentRenew = _ref$includeIdTokenIn === undefined ? true : _ref$includeIdTokenIn,\n            _ref$monitorSession = _ref.monitorSession,\n            monitorSession = _ref$monitorSession === undefined ? true : _ref$monitorSession,\n            _ref$monitorAnonymous = _ref.monitorAnonymousSession,\n            monitorAnonymousSession = _ref$monitorAnonymous === undefined ? false : _ref$monitorAnonymous,\n            _ref$checkSessionInte = _ref.checkSessionInterval,\n            checkSessionInterval = _ref$checkSessionInte === undefined ? DefaultCheckSessionInterval : _ref$checkSessionInte,\n            _ref$stopCheckSession = _ref.stopCheckSessionOnError,\n            stopCheckSessionOnError = _ref$stopCheckSession === undefined ? true : _ref$stopCheckSession,\n            query_status_response_type = _ref.query_status_response_type,\n            _ref$revokeAccessToke = _ref.revokeAccessTokenOnSignout,\n            revokeAccessTokenOnSignout = _ref$revokeAccessToke === undefined ? false : _ref$revokeAccessToke,\n            _ref$accessTokenExpir = _ref.accessTokenExpiringNotificationTime,\n            accessTokenExpiringNotificationTime = _ref$accessTokenExpir === undefined ? DefaultAccessTokenExpiringNotificationTime : _ref$accessTokenExpir,\n            _ref$redirectNavigato = _ref.redirectNavigator,\n            redirectNavigator = _ref$redirectNavigato === undefined ? new _RedirectNavigator.RedirectNavigator() : _ref$redirectNavigato,\n            _ref$popupNavigator = _ref.popupNavigator,\n            popupNavigator = _ref$popupNavigator === undefined ? new _PopupNavigator.PopupNavigator() : _ref$popupNavigator,\n            _ref$iframeNavigator = _ref.iframeNavigator,\n            iframeNavigator = _ref$iframeNavigator === undefined ? new _IFrameNavigator.IFrameNavigator() : _ref$iframeNavigator,\n            _ref$userStore = _ref.userStore,\n            userStore = _ref$userStore === undefined ? new _WebStorageStateStore.WebStorageStateStore({ store: _Global.Global.sessionStorage }) : _ref$userStore;\n\n        _classCallCheck(this, UserManagerSettings);\n\n        var _this = _possibleConstructorReturn(this, _OidcClientSettings.call(this, arguments[0]));\n\n        _this._popup_redirect_uri = popup_redirect_uri;\n        _this._popup_post_logout_redirect_uri = popup_post_logout_redirect_uri;\n        _this._popupWindowFeatures = popupWindowFeatures;\n        _this._popupWindowTarget = popupWindowTarget;\n\n        _this._silent_redirect_uri = silent_redirect_uri;\n        _this._silentRequestTimeout = silentRequestTimeout;\n        _this._automaticSilentRenew = automaticSilentRenew;\n        _this._validateSubOnSilentRenew = validateSubOnSilentRenew;\n        _this._includeIdTokenInSilentRenew = includeIdTokenInSilentRenew;\n        _this._accessTokenExpiringNotificationTime = accessTokenExpiringNotificationTime;\n\n        _this._monitorSession = monitorSession;\n        _this._monitorAnonymousSession = monitorAnonymousSession;\n        _this._checkSessionInterval = checkSessionInterval;\n        _this._stopCheckSessionOnError = stopCheckSessionOnError;\n        if (query_status_response_type) {\n            _this._query_status_response_type = query_status_response_type;\n        } else if (arguments[0] && arguments[0].response_type) {\n            _this._query_status_response_type = _SigninRequest.SigninRequest.isOidc(arguments[0].response_type) ? \"id_token\" : \"code\";\n        } else {\n            _this._query_status_response_type = \"id_token\";\n        }\n        _this._revokeAccessTokenOnSignout = revokeAccessTokenOnSignout;\n\n        _this._redirectNavigator = redirectNavigator;\n        _this._popupNavigator = popupNavigator;\n        _this._iframeNavigator = iframeNavigator;\n\n        _this._userStore = userStore;\n        return _this;\n    }\n\n    _createClass(UserManagerSettings, [{\n        key: 'popup_redirect_uri',\n        get: function get() {\n            return this._popup_redirect_uri;\n        }\n    }, {\n        key: 'popup_post_logout_redirect_uri',\n        get: function get() {\n            return this._popup_post_logout_redirect_uri;\n        }\n    }, {\n        key: 'popupWindowFeatures',\n        get: function get() {\n            return this._popupWindowFeatures;\n        }\n    }, {\n        key: 'popupWindowTarget',\n        get: function get() {\n            return this._popupWindowTarget;\n        }\n    }, {\n        key: 'silent_redirect_uri',\n        get: function get() {\n            return this._silent_redirect_uri;\n        }\n    }, {\n        key: 'silentRequestTimeout',\n        get: function get() {\n            return this._silentRequestTimeout;\n        }\n    }, {\n        key: 'automaticSilentRenew',\n        get: function get() {\n            return this._automaticSilentRenew;\n        }\n    }, {\n        key: 'validateSubOnSilentRenew',\n        get: function get() {\n            return this._validateSubOnSilentRenew;\n        }\n    }, {\n        key: 'includeIdTokenInSilentRenew',\n        get: function get() {\n            return this._includeIdTokenInSilentRenew;\n        }\n    }, {\n        key: 'accessTokenExpiringNotificationTime',\n        get: function get() {\n            return this._accessTokenExpiringNotificationTime;\n        }\n    }, {\n        key: 'monitorSession',\n        get: function get() {\n            return this._monitorSession;\n        }\n    }, {\n        key: 'monitorAnonymousSession',\n        get: function get() {\n            return this._monitorAnonymousSession;\n        }\n    }, {\n        key: 'checkSessionInterval',\n        get: function get() {\n            return this._checkSessionInterval;\n        }\n    }, {\n        key: 'stopCheckSessionOnError',\n        get: function get() {\n            return this._stopCheckSessionOnError;\n        }\n    }, {\n        key: 'query_status_response_type',\n        get: function get() {\n            return this._query_status_response_type;\n        }\n    }, {\n        key: 'revokeAccessTokenOnSignout',\n        get: function get() {\n            return this._revokeAccessTokenOnSignout;\n        }\n    }, {\n        key: 'redirectNavigator',\n        get: function get() {\n            return this._redirectNavigator;\n        }\n    }, {\n        key: 'popupNavigator',\n        get: function get() {\n            return this._popupNavigator;\n        }\n    }, {\n        key: 'iframeNavigator',\n        get: function get() {\n            return this._iframeNavigator;\n        }\n    }, {\n        key: 'userStore',\n        get: function get() {\n            return this._userStore;\n        }\n    }]);\n\n    return UserManagerSettings;\n}(_OidcClientSettings2.OidcClientSettings);\n\n/***/ }),\n\n/***/ \"./src/WebStorageStateStore.js\":\n/*!*************************************!*\\\n  !*** ./src/WebStorageStateStore.js ***!\n  \\*************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.WebStorageStateStore = undefined;\n\nvar _Log = __webpack_require__(/*! ./Log.js */ \"./src/Log.js\");\n\nvar _Global = __webpack_require__(/*! ./Global.js */ \"./src/Global.js\");\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } // Copyright (c) Brock Allen & Dominick Baier. All rights reserved.\n// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.\n\nvar WebStorageStateStore = exports.WebStorageStateStore = function () {\n    function WebStorageStateStore() {\n        var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n            _ref$prefix = _ref.prefix,\n            prefix = _ref$prefix === undefined ? \"oidc.\" : _ref$prefix,\n            _ref$store = _ref.store,\n            store = _ref$store === undefined ? _Global.Global.localStorage : _ref$store;\n\n        _classCallCheck(this, WebStorageStateStore);\n\n        this._store = store;\n        this._prefix = prefix;\n    }\n\n    WebStorageStateStore.prototype.set = function set(key, value) {\n        _Log.Log.debug(\"WebStorageStateStore.set\", key);\n\n        key = this._prefix + key;\n\n        this._store.setItem(key, value);\n\n        return Promise.resolve();\n    };\n\n    WebStorageStateStore.prototype.get = function get(key) {\n        _Log.Log.debug(\"WebStorageStateStore.get\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.remove = function remove(key) {\n        _Log.Log.debug(\"WebStorageStateStore.remove\", key);\n\n        key = this._prefix + key;\n\n        var item = this._store.getItem(key);\n        this._store.removeItem(key);\n\n        return Promise.resolve(item);\n    };\n\n    WebStorageStateStore.prototype.getAllKeys = function getAllKeys() {\n        _Log.Log.debug(\"WebStorageStateStore.getAllKeys\");\n\n        var keys = [];\n\n        for (var index = 0; index < this._store.length; index++) {\n            var key = this._store.key(index);\n\n            if (key.indexOf(this._prefix) === 0) {\n                keys.push(key.substr(this._prefix.length));\n            }\n        }\n\n        return Promise.resolve(keys);\n    };\n\n    return WebStorageStateStore;\n}();\n\n/***/ }),\n\n/***/ \"./src/crypto/jsrsasign.js\":\n/*!*********************************!*\\\n  !*** ./src/crypto/jsrsasign.js ***!\n  \\*********************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n    value: true\n});\nexports.AllowedSigningAlgs = exports.b64tohex = exports.hextob64u = exports.crypto = exports.X509 = exports.KeyUtil = exports.jws = undefined;\n\nvar _jsrsasign = __webpack_require__(/*! ../../jsrsasign/dist/jsrsasign.js */ \"./jsrsasign/dist/jsrsasign.js\");\n\nvar AllowedSigningAlgs = ['RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'ES256', 'ES384', 'ES512'];\n\nexports.jws = _jsrsasign.jws;\nexports.KeyUtil = _jsrsasign.KEYUTIL;\nexports.X509 = _jsrsasign.X509;\nexports.crypto = _jsrsasign.crypto;\nexports.hextob64u = _jsrsasign.hextob64u;\nexports.b64tohex = _jsrsasign.b64tohex;\nexports.AllowedSigningAlgs = AllowedSigningAlgs;\n\n/***/ }),\n\n/***/ \"./src/random.js\":\n/*!***********************!*\\\n  !*** ./src/random.js ***!\n  \\***********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = random;\n\nvar _v = __webpack_require__(/*! uuid/v4 */ \"./node_modules/uuid/v4.js\");\n\nvar _v2 = _interopRequireDefault(_v);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/**\n * Generates RFC4122 version 4 guid ()\n */\n\nfunction random() {\n  return (0, _v2.default)().replace(/-/g, '');\n}\nmodule.exports = exports['default'];\n\n/***/ }),\n\n/***/ \"./version.js\":\n/*!********************!*\\\n  !*** ./version.js ***!\n  \\********************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nvar Version = \"1.10.1\";exports.Version = Version;\n\n/***/ }),\n\n/***/ 0:\n/*!***************************************!*\\\n  !*** multi babel-polyfill ./index.js ***!\n  \\***************************************/\n/*! no static exports found */\n/***/ (function(module, exports, __webpack_require__) {\n\n__webpack_require__(/*! babel-polyfill */\"./node_modules/babel-polyfill/lib/index.js\");\nmodule.exports = __webpack_require__(/*! ./index.js */\"./index.js\");\n\n\n/***/ })\n\n/******/ });\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9PaWRjL3dlYnBhY2svYm9vdHN0cmFwIiwid2VicGFjazovL09pZGMvLi9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vanNyc2FzaWduL2Rpc3QvanNyc2FzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbGliL2luZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvYmFiZWwtcG9seWZpbGwvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vcmVnZXhwL2VzY2FwZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1mdW5jdGlvbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYS1udW1iZXItdmFsdWUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FkZC10by11bnNjb3BhYmxlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYWR2YW5jZS1zdHJpbmctaW5kZXguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLWluc3RhbmNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWNvcHktd2l0aGluLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1maWxsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1mcm9tLWl0ZXJhYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1pbmNsdWRlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktcmVkdWNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYmluZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi10by1qc29uLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXdlYWsuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvbGxlY3Rpb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NvcmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2NyZWF0ZS1wcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY3R4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kYXRlLXRvLWlzby1zdHJpbmcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RhdGUtdG8tcHJpbWl0aXZlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZWZpbmVkLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kZXNjcmlwdG9ycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZG9tLWNyZWF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1idWcta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZW51bS1rZXlzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19leHBvcnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLWlzLXJlZ2V4cC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZmFpbHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZpeC1yZS13a3MuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZsYWdzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mbGF0dGVuLWludG8tYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2Zvci1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZnVuY3Rpb24tdG8tc3RyaW5nLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWludGVnZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtcmVnZXhwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWZyb3VuZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1sb2cxcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zY2FsZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWljcm90YXNrLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19uZXctcHJvbWlzZS1jYXBhYmlsaXR5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtYXNzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZHAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1mb3JjZWQtcGFtLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4tZXh0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ29wbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1ncG8uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1rZXlzLWludGVybmFsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXBpZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXNhcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LXRvLWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vd24ta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGFyc2UtZmxvYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWludC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcGVyZm9ybS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvbWlzZS1yZXNvbHZlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wcm9wZXJ0eS1kZXNjLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS1hbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlZGVmaW5lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWdleHAtZXhlYy1hYnN0cmFjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVnZXhwLWV4ZWMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3JlcGxhY2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zYW1lLXZhbHVlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtY29sbGVjdGlvbi1mcm9tLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtY29sbGVjdGlvbi1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC1rZXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWF0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctY29udGV4dC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1wYWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1yZXBlYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy10cmltLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctd3MuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWFic29sdXRlLWluZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWJ1ZmZlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3VpZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdXNlci1hZ2VudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdmFsaWRhdGUtY29sbGVjdGlvbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWV4dC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9jb3JlLnJlZ2V4cC5lc2NhcGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmNvcHktd2l0aGluLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5ldmVyeS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZmlsdGVyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLWluZGV4LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maW5kLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5mb3ItZWFjaC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuZnJvbS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaW5kZXgtb2YuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmlzLWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuam9pbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubGFzdC1pbmRleC1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkubWFwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlLXJpZ2h0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNsaWNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zb21lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zb3J0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLm5vdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1pc28tc3RyaW5nLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLWpzb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tcHJpbWl0aXZlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLXN0cmluZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZnVuY3Rpb24uaGFzLWluc3RhbmNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYWNvc2guanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYXNpbmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguYXRhbmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguY2JydC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jbHozMi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jb3NoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmV4cG0xLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmZyb3VuZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5oeXBvdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5pbXVsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzEwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzFwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmxvZzIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguc2lnbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5zaW5oLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnRhbmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgudHJ1bmMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5jb25zdHJ1Y3Rvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmVwc2lsb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1maW5pdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1pbnRlZ2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtbmFuLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuaXMtc2FmZS1pbnRlZ2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIubWF4LXNhZmUtaW50ZWdlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLm1pbi1zYWZlLWludGVnZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnBhcnNlLWludC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnRvLWZpeGVkLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIudG8tcHJlY2lzaW9uLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuYXNzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuY3JlYXRlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5kZWZpbmUtcHJvcGVydHkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5mcmVlemUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LW5hbWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LXByb3RvdHlwZS1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLWV4dGVuc2libGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1mcm96ZW4uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1zZWFsZWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5pcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmtleXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5wcmV2ZW50LWV4dGVuc2lvbnMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3Quc2V0LXByb3RvdHlwZS1vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtZmxvYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnBhcnNlLWludC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucHJvbWlzZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5hcHBseS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5jb25zdHJ1Y3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVmaW5lLXByb3BlcnR5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmRlbGV0ZS1wcm9wZXJ0eS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5lbnVtZXJhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0Lmhhcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5pcy1leHRlbnNpYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0Lm93bi1rZXlzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnByZXZlbnQtZXh0ZW5zaW9ucy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5zZXQtcHJvdG90eXBlLW9mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLmNvbnN0cnVjdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuZXhlYy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLmZsYWdzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAubWF0Y2guanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5yZXBsYWNlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuc2VhcmNoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuc3BsaXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC50by1zdHJpbmcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnNldC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmFuY2hvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJpZy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJsaW5rLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuYm9sZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmNvZGUtcG9pbnQtYXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5lbmRzLXdpdGguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5maXhlZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRjb2xvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRzaXplLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZnJvbS1jb2RlLXBvaW50LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaW5jbHVkZXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5pdGFsaWNzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRlcmF0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5saW5rLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcucmF3LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcucmVwZWF0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc21hbGwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdGFydHMtd2l0aC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN0cmlrZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN1Yi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnN1cC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN5bWJvbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuYXJyYXktYnVmZmVyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5kYXRhLXZpZXcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0MzItYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0NjQtYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmludDE2LWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQzMi1hcnJheS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50OC1hcnJheS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDE2LWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50MzItYXJyYXkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQ4LWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi53ZWFrLW1hcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1zZXQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LmFycmF5LmZsYXQtbWFwLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hcnJheS5mbGF0dGVuLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuYXNhcC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuZXJyb3IuaXMtZXJyb3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lmdsb2JhbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWFwLmZyb20uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hcC5vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWFwLnRvLWpzb24uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguY2xhbXAuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguZGVnLXBlci1yYWQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguZGVncmVlcy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5mc2NhbGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaWFkZGguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaW11bGguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGguaXN1YmguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGgucmFkLXBlci1kZWcuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm1hdGgucmFkaWFucy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5zY2FsZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcubWF0aC5zaWduYml0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5tYXRoLnVtdWxoLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QuZGVmaW5lLWdldHRlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5lbnRyaWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9ycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXIuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5sb29rdXAtc2V0dGVyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QudmFsdWVzLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYnNlcnZhYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5wcm9taXNlLmZpbmFsbHkuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnByb21pc2UudHJ5LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlZmluZS1tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5kZWxldGUtbWV0YWRhdGEuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLWtleXMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1vd24tbWV0YWRhdGEta2V5cy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5nZXQtb3duLW1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0Lmhhcy1tZXRhZGF0YS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcucmVmbGVjdC5oYXMtb3duLW1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5yZWZsZWN0Lm1ldGFkYXRhLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zZXQuZnJvbS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc2V0Lm9mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zZXQudG8tanNvbi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLmF0LmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcubWF0Y2gtYWxsLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tbGVmdC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3RyaW5nLnRyaW0tcmlnaHQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5bWJvbC5hc3luYy1pdGVyYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcuc3ltYm9sLm9ic2VydmFibGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LndlYWstbWFwLmZyb20uanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LndlYWstbWFwLm9mLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy53ZWFrLXNldC5mcm9tLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy53ZWFrLXNldC5vZi5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuZG9tLml0ZXJhYmxlLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL3dlYi5pbW1lZGlhdGUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLnRpbWVycy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2NvcmUtanMvc2hpbS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL25vZGVfbW9kdWxlcy91dWlkL2xpYi9ieXRlc1RvVXVpZC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vbm9kZV9tb2R1bGVzL3V1aWQvbGliL3JuZy1icm93c2VyLmpzIiwid2VicGFjazovL09pZGMvLi9ub2RlX21vZHVsZXMvdXVpZC92NC5qcyIsIndlYnBhY2s6Ly9PaWRjLyh3ZWJwYWNrKS9idWlsZGluL2dsb2JhbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0FjY2Vzc1Rva2VuRXZlbnRzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvQ2hlY2tTZXNzaW9uSUZyYW1lLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvQ29yZG92YUlGcmFtZU5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0NvcmRvdmFQb3B1cE5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0NvcmRvdmFQb3B1cFdpbmRvdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0Vycm9yUmVzcG9uc2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9FdmVudC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0dsb2JhbC5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0lGcmFtZU5hdmlnYXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0lGcmFtZVdpbmRvdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0luTWVtb3J5V2ViU3RvcmFnZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL0pvc2VVdGlsLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSm9zZVV0aWxJbXBsLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvSnNvblNlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Mb2cuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9NZXRhZGF0YVNlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9PaWRjQ2xpZW50LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvT2lkY0NsaWVudFNldHRpbmdzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvUG9wdXBOYXZpZ2F0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Qb3B1cFdpbmRvdy5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1JlZGlyZWN0TmF2aWdhdG9yLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvUmVzcG9uc2VWYWxpZGF0b3IuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TZXNzaW9uTW9uaXRvci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpZ25pblJlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWduaW5SZXNwb25zZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1NpZ25pblN0YXRlLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvU2lnbm91dFJlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWdub3V0UmVzcG9uc2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TaWxlbnRSZW5ld1NlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9TdGF0ZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1RpbWVyLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVG9rZW5DbGllbnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Ub2tlblJldm9jYXRpb25DbGllbnQuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9VcmxVdGlsaXR5LmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXNlci5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VzZXJJbmZvU2VydmljZS5qcyIsIndlYnBhY2s6Ly9PaWRjLy4vc3JjL1VzZXJNYW5hZ2VyLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvVXNlck1hbmFnZXJFdmVudHMuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9Vc2VyTWFuYWdlclNldHRpbmdzLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMiLCJ3ZWJwYWNrOi8vT2lkYy8uL3NyYy9jcnlwdG8vanNyc2FzaWduLmpzIiwid2VicGFjazovL09pZGMvLi9zcmMvcmFuZG9tLmpzIiwid2VicGFjazovL09pZGMvLi92ZXJzaW9uLmpzIl0sIm5hbWVzIjpbIlZlcnNpb24iLCJMb2ciLCJPaWRjQ2xpZW50IiwiT2lkY0NsaWVudFNldHRpbmdzIiwiV2ViU3RvcmFnZVN0YXRlU3RvcmUiLCJJbk1lbW9yeVdlYlN0b3JhZ2UiLCJVc2VyTWFuYWdlciIsIkFjY2Vzc1Rva2VuRXZlbnRzIiwiTWV0YWRhdGFTZXJ2aWNlIiwiQ29yZG92YVBvcHVwTmF2aWdhdG9yIiwiQ29yZG92YUlGcmFtZU5hdmlnYXRvciIsIkNoZWNrU2Vzc2lvbklGcmFtZSIsIlRva2VuUmV2b2NhdGlvbkNsaWVudCIsIlNlc3Npb25Nb25pdG9yIiwiR2xvYmFsIiwiVXNlciIsIm5hdmlnYXRvciIsInVzZXJBZ2VudCIsIndpbmRvdyIsIllBSE9PIiwidW5kZWZpbmVkIiwibGFuZyIsImV4dGVuZCIsImciLCJoIiwiZiIsIkVycm9yIiwiZCIsInByb3RvdHlwZSIsImNvbnN0cnVjdG9yIiwic3VwZXJjbGFzcyIsIk9iamVjdCIsImIiLCJlIiwiYyIsInRlc3QiLCJqIiwiaSIsImxlbmd0aCIsImwiLCJrIiwiYSIsIkNyeXB0b0pTIiwibGliIiwiQmFzZSIsIm4iLCJwIiwibyIsIm1peEluIiwiaGFzT3duUHJvcGVydHkiLCJpbml0IiwiJHN1cGVyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJjcmVhdGUiLCJ0b1N0cmluZyIsImNsb25lIiwiV29yZEFycmF5Iiwid29yZHMiLCJzaWdCeXRlcyIsInN0cmluZ2lmeSIsImNvbmNhdCIsInQiLCJxIiwicyIsImNsYW1wIiwiciIsImNlaWwiLCJjYWxsIiwic2xpY2UiLCJyYW5kb20iLCJwdXNoIiwibSIsImVuYyIsIkhleCIsImpvaW4iLCJwYXJzZSIsInBhcnNlSW50Iiwic3Vic3RyIiwiTGF0aW4xIiwiU3RyaW5nIiwiZnJvbUNoYXJDb2RlIiwiY2hhckNvZGVBdCIsIlV0ZjgiLCJkZWNvZGVVUklDb21wb25lbnQiLCJlc2NhcGUiLCJ1bmVzY2FwZSIsImVuY29kZVVSSUNvbXBvbmVudCIsIkJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0iLCJyZXNldCIsIl9kYXRhIiwiX25EYXRhQnl0ZXMiLCJfYXBwZW5kIiwiX3Byb2Nlc3MiLCJ3IiwieCIsImJsb2NrU2l6ZSIsInYiLCJ1IiwibWF4IiwiX21pbkJ1ZmZlclNpemUiLCJtaW4iLCJfZG9Qcm9jZXNzQmxvY2siLCJzcGxpY2UiLCJIYXNoZXIiLCJjZmciLCJfZG9SZXNldCIsInVwZGF0ZSIsImZpbmFsaXplIiwiX2RvRmluYWxpemUiLCJfY3JlYXRlSGVscGVyIiwiX2NyZWF0ZUhtYWNIZWxwZXIiLCJITUFDIiwiYWxnbyIsIk1hdGgiLCJ4NjQiLCJXb3JkIiwiaGlnaCIsImxvdyIsInRvWDMyIiwiQmFzZTY0IiwiX21hcCIsImNoYXJBdCIsImluZGV4T2YiLCJzcXJ0IiwicG93IiwiU0hBMjU2IiwiX2hhc2giLCJmbG9vciIsIkhtYWNTSEEyNTYiLCJUIiwiZWEiLCJTSEE1MTIiLCJGIiwiRyIsIkgiLCJJIiwiSiIsIlgiLCJLIiwiWSIsIkwiLCJaIiwiTSIsIiQiLCJOIiwiYWEiLCJPIiwiYmEiLCJQIiwiY2EiLCJRIiwieiIsIkEiLCJ5IiwiVSIsIkIiLCJSIiwiQyIsIlMiLCJEIiwiViIsIkUiLCJXIiwiZmEiLCJkYSIsIkhtYWNTSEE1MTIiLCJTSEEzODQiLCJIbWFjU0hBMzg0IiwiYjY0bWFwIiwiYjY0cGFkIiwiaGV4MmI2NCIsInN1YnN0cmluZyIsImI2NHRvaGV4IiwiaW50MmNoYXIiLCJiNjR0b0JBIiwiQXJyYXkiLCJkYml0cyIsImNhbmFyeSIsImpfbG0iLCJCaWdJbnRlZ2VyIiwiZnJvbU51bWJlciIsImZyb21TdHJpbmciLCJuYmkiLCJhbTEiLCJhbTIiLCJhbTMiLCJhcHBOYW1lIiwiYW0iLCJEQiIsIkRNIiwiRFYiLCJCSV9GUCIsIkZWIiwiRjEiLCJGMiIsIkJJX1JNIiwiQklfUkMiLCJyciIsInZ2IiwiaW50QXQiLCJibnBDb3B5VG8iLCJibnBGcm9tSW50IiwibmJ2IiwiZnJvbUludCIsImJucEZyb21TdHJpbmciLCJmcm9tUmFkaXgiLCJaRVJPIiwic3ViVG8iLCJibnBDbGFtcCIsImJuVG9TdHJpbmciLCJuZWdhdGUiLCJ0b1JhZGl4IiwiYm5OZWdhdGUiLCJibkFicyIsImJuQ29tcGFyZVRvIiwibmJpdHMiLCJibkJpdExlbmd0aCIsImJucERMU2hpZnRUbyIsImJucERSU2hpZnRUbyIsImJucExTaGlmdFRvIiwiYm5wUlNoaWZ0VG8iLCJibnBTdWJUbyIsImJucE11bHRpcGx5VG8iLCJhYnMiLCJibnBTcXVhcmVUbyIsImJucERpdlJlbVRvIiwiY29weVRvIiwibFNoaWZ0VG8iLCJkbFNoaWZ0VG8iLCJjb21wYXJlVG8iLCJPTkUiLCJkclNoaWZ0VG8iLCJyU2hpZnRUbyIsImJuTW9kIiwiZGl2UmVtVG8iLCJDbGFzc2ljIiwiY0NvbnZlcnQiLCJtb2QiLCJjUmV2ZXJ0IiwiY1JlZHVjZSIsImNNdWxUbyIsIm11bHRpcGx5VG8iLCJyZWR1Y2UiLCJjU3FyVG8iLCJzcXVhcmVUbyIsImNvbnZlcnQiLCJyZXZlcnQiLCJtdWxUbyIsInNxclRvIiwiYm5wSW52RGlnaXQiLCJNb250Z29tZXJ5IiwibXAiLCJpbnZEaWdpdCIsIm1wbCIsIm1waCIsInVtIiwibXQyIiwibW9udENvbnZlcnQiLCJtb250UmV2ZXJ0IiwibW9udFJlZHVjZSIsIm1vbnRTcXJUbyIsIm1vbnRNdWxUbyIsImJucElzRXZlbiIsImJucEV4cCIsImJuTW9kUG93SW50IiwiaXNFdmVuIiwiZXhwIiwiYml0TGVuZ3RoIiwibW9kUG93SW50IiwiYm5DbG9uZSIsImJuSW50VmFsdWUiLCJibkJ5dGVWYWx1ZSIsImJuU2hvcnRWYWx1ZSIsImJucENodW5rU2l6ZSIsIkxOMiIsImxvZyIsImJuU2lnTnVtIiwiYm5wVG9SYWRpeCIsInNpZ251bSIsImNodW5rU2l6ZSIsImludFZhbHVlIiwiYm5wRnJvbVJhZGl4IiwiZE11bHRpcGx5IiwiZEFkZE9mZnNldCIsImJucEZyb21OdW1iZXIiLCJ0ZXN0Qml0IiwiYml0d2lzZVRvIiwic2hpZnRMZWZ0Iiwib3Bfb3IiLCJpc1Byb2JhYmxlUHJpbWUiLCJuZXh0Qnl0ZXMiLCJiblRvQnl0ZUFycmF5IiwiYm5FcXVhbHMiLCJibk1pbiIsImJuTWF4IiwiYm5wQml0d2lzZVRvIiwib3BfYW5kIiwiYm5BbmQiLCJibk9yIiwib3BfeG9yIiwiYm5Yb3IiLCJvcF9hbmRub3QiLCJibkFuZE5vdCIsImJuTm90IiwiYm5TaGlmdExlZnQiLCJiblNoaWZ0UmlnaHQiLCJsYml0IiwiYm5HZXRMb3dlc3RTZXRCaXQiLCJjYml0IiwiYm5CaXRDb3VudCIsImJuVGVzdEJpdCIsImJucENoYW5nZUJpdCIsImJuU2V0Qml0IiwiY2hhbmdlQml0IiwiYm5DbGVhckJpdCIsImJuRmxpcEJpdCIsImJucEFkZFRvIiwiYm5BZGQiLCJhZGRUbyIsImJuU3VidHJhY3QiLCJibk11bHRpcGx5IiwiYm5TcXVhcmUiLCJibkRpdmlkZSIsImJuUmVtYWluZGVyIiwiYm5EaXZpZGVBbmRSZW1haW5kZXIiLCJibnBETXVsdGlwbHkiLCJibnBEQWRkT2Zmc2V0IiwiTnVsbEV4cCIsIm5Ob3AiLCJuTXVsVG8iLCJuU3FyVG8iLCJiblBvdyIsImJucE11bHRpcGx5TG93ZXJUbyIsImJucE11bHRpcGx5VXBwZXJUbyIsIkJhcnJldHQiLCJyMiIsInEzIiwibXUiLCJkaXZpZGUiLCJiYXJyZXR0Q29udmVydCIsImJhcnJldHRSZXZlcnQiLCJiYXJyZXR0UmVkdWNlIiwibXVsdGlwbHlVcHBlclRvIiwibXVsdGlwbHlMb3dlclRvIiwiYmFycmV0dFNxclRvIiwiYmFycmV0dE11bFRvIiwiYm5Nb2RQb3ciLCJibkdDRCIsImdldExvd2VzdFNldEJpdCIsImJucE1vZEludCIsImJuTW9kSW52ZXJzZSIsInN1YnRyYWN0IiwiYWRkIiwibG93cHJpbWVzIiwibHBsaW0iLCJibklzUHJvYmFibGVQcmltZSIsIm1vZEludCIsIm1pbGxlclJhYmluIiwiYm5wTWlsbGVyUmFiaW4iLCJzaGlmdFJpZ2h0IiwibW9kUG93IiwiYnl0ZVZhbHVlIiwic2hvcnRWYWx1ZSIsInRvQnl0ZUFycmF5IiwiZXF1YWxzIiwiYW5kIiwib3IiLCJ4b3IiLCJhbmROb3QiLCJub3QiLCJiaXRDb3VudCIsInNldEJpdCIsImNsZWFyQml0IiwiZmxpcEJpdCIsIm11bHRpcGx5IiwicmVtYWluZGVyIiwiZGl2aWRlQW5kUmVtYWluZGVyIiwibW9kSW52ZXJzZSIsImdjZCIsInNxdWFyZSIsIkFyY2ZvdXIiLCJBUkM0aW5pdCIsIkFSQzRuZXh0IiwibmV4dCIsInBybmdfbmV3c3RhdGUiLCJybmdfcHNpemUiLCJybmdfc3RhdGUiLCJybmdfcG9vbCIsInJuZ19wcHRyIiwicm5nX3NlZWRfaW50Iiwicm5nX3NlZWRfdGltZSIsIkRhdGUiLCJnZXRUaW1lIiwiY3J5cHRvIiwibXNDcnlwdG8iLCJnZXRSYW5kb21WYWx1ZXMiLCJ1YSIsIlVpbnQ4QXJyYXkiLCJhcHBWZXJzaW9uIiwicm5nX2dldF9ieXRlIiwicm5nX2dldF9ieXRlcyIsIlNlY3VyZVJhbmRvbSIsInBhcnNlQmlnSW50IiwibGluZWJyayIsImJ5dGUySGV4IiwicGtjczFwYWQyIiwib2FlcF9tZ2YxX2FyciIsIm9hZXBfcGFkIiwiS0pVUiIsIk1lc3NhZ2VEaWdlc3QiLCJVdGlsIiwiZ2V0Q2Fub25pY2FsQWxnTmFtZSIsImdldEhhc2hMZW5ndGgiLCJoZXh0b3JzdHIiLCJoYXNoSGV4IiwicnN0cnRvaGV4IiwiUlNBS2V5IiwiZG1wMSIsImRtcTEiLCJjb2VmZiIsIlJTQVNldFB1YmxpYyIsImlzUHVibGljIiwiaXNQcml2YXRlIiwiUlNBRG9QdWJsaWMiLCJSU0FFbmNyeXB0IiwiZG9QdWJsaWMiLCJSU0FFbmNyeXB0T0FFUCIsInNldFB1YmxpYyIsImVuY3J5cHQiLCJlbmNyeXB0T0FFUCIsInR5cGUiLCJFQ0ZpZWxkRWxlbWVudEZwIiwiZmVGcEVxdWFscyIsImZlRnBUb0JpZ0ludGVnZXIiLCJmZUZwTmVnYXRlIiwiZmVGcEFkZCIsInRvQmlnSW50ZWdlciIsImZlRnBTdWJ0cmFjdCIsImZlRnBNdWx0aXBseSIsImZlRnBTcXVhcmUiLCJmZUZwRGl2aWRlIiwiRUNQb2ludEZwIiwiY3VydmUiLCJ6aW52IiwicG9pbnRGcEdldFgiLCJmcm9tQmlnSW50ZWdlciIsInBvaW50RnBHZXRZIiwicG9pbnRGcEVxdWFscyIsImlzSW5maW5pdHkiLCJwb2ludEZwSXNJbmZpbml0eSIsInBvaW50RnBOZWdhdGUiLCJwb2ludEZwQWRkIiwidHdpY2UiLCJnZXRJbmZpbml0eSIsInBvaW50RnBUd2ljZSIsInBvaW50RnBNdWx0aXBseSIsInBvaW50RnBNdWx0aXBseVR3byIsImdldFgiLCJnZXRZIiwibXVsdGlwbHlUd28iLCJFQ0N1cnZlRnAiLCJpbmZpbml0eSIsImN1cnZlRnBHZXRRIiwiY3VydmVGcEdldEEiLCJjdXJ2ZUZwR2V0QiIsImN1cnZlRnBFcXVhbHMiLCJjdXJ2ZUZwR2V0SW5maW5pdHkiLCJjdXJ2ZUZwRnJvbUJpZ0ludGVnZXIiLCJjdXJ2ZUZwRGVjb2RlUG9pbnRIZXgiLCJnZXRRIiwiZ2V0QSIsImdldEIiLCJkZWNvZGVQb2ludEhleCIsImdldEJ5dGVMZW5ndGgiLCJnZXRFbmNvZGVkIiwidG9CeXRlQXJyYXlVbnNpZ25lZCIsInVuc2hpZnQiLCJkZWNvZGVGcm9tIiwiZGVjb2RlRnJvbUhleCIsImFkZDJEIiwidHdpY2UyRCIsInZhbHVlT2YiLCJtdWx0aXBseTJEIiwiaXNPbkN1cnZlIiwidmFsaWRhdGUiLCJqc29uUGFyc2UiLCJSZWdFeHAiLCJtYXRjaCIsInJlcGxhY2UiLCJzaGlmdCIsImFzbjEiLCJBU04xVXRpbCIsImludGVnZXJUb0J5dGVIZXgiLCJiaWdJbnRUb01pblR3b3NDb21wbGVtZW50c0hleCIsImdldFBFTVN0cmluZ0Zyb21IZXgiLCJoZXh0b3BlbSIsIm5ld09iamVjdCIsIkRFUkJvb2xlYW4iLCJERVJJbnRlZ2VyIiwiREVSQml0U3RyaW5nIiwiREVST2N0ZXRTdHJpbmciLCJERVJOdWxsIiwiREVST2JqZWN0SWRlbnRpZmllciIsIkRFUkVudW1lcmF0ZWQiLCJERVJVVEY4U3RyaW5nIiwiREVSTnVtZXJpY1N0cmluZyIsIkRFUlByaW50YWJsZVN0cmluZyIsIkRFUlRlbGV0ZXhTdHJpbmciLCJERVJJQTVTdHJpbmciLCJERVJVVENUaW1lIiwiREVSR2VuZXJhbGl6ZWRUaW1lIiwiREVSU2VxdWVuY2UiLCJERVJTZXQiLCJERVJUYWdnZWRPYmplY3QiLCJrZXlzIiwiYXJyYXkiLCJ0YWciLCJleHBsaWNpdCIsIm9iaiIsImpzb25Ub0FTTjFIRVgiLCJnZXRFbmNvZGVkSGV4Iiwib2lkSGV4VG9JbnQiLCJvaWRJbnRUb0hleCIsInNwbGl0IiwiQVNOMU9iamVjdCIsImdldExlbmd0aEhleEZyb21WYWx1ZSIsImhWIiwiaFRMViIsImlzTW9kaWZpZWQiLCJnZXRGcmVzaFZhbHVlSGV4IiwiaEwiLCJoVCIsImdldFZhbHVlSGV4IiwiREVSQWJzdHJhY3RTdHJpbmciLCJnZXRTdHJpbmciLCJzZXRTdHJpbmciLCJ1dGY4dG9oZXgiLCJ0b0xvd2VyQ2FzZSIsInNldFN0cmluZ0hleCIsInN0ciIsImhleCIsIkRFUkFic3RyYWN0VGltZSIsImxvY2FsRGF0ZVRvVVRDIiwidXRjIiwiZ2V0VGltZXpvbmVPZmZzZXQiLCJmb3JtYXREYXRlIiwiemVyb1BhZGRpbmciLCJnZXRGdWxsWWVhciIsImdldE1vbnRoIiwiZ2V0RGF0ZSIsImdldEhvdXJzIiwiZ2V0TWludXRlcyIsImdldFNlY29uZHMiLCJnZXRNaWxsaXNlY29uZHMiLCJzdG9oZXgiLCJzZXRCeURhdGVWYWx1ZSIsIlVUQyIsInNldEJ5RGF0ZSIsIkRFUkFic3RyYWN0U3RydWN0dXJlZCIsInNldEJ5QVNOMU9iamVjdEFycmF5IiwiYXNuMUFycmF5IiwiYXBwZW5kQVNOMU9iamVjdCIsInNldEJ5QmlnSW50ZWdlciIsInNldEJ5SW50ZWdlciIsInNldFZhbHVlSGV4IiwiYmlnaW50Iiwic2V0SGV4VmFsdWVJbmNsdWRpbmdVbnVzZWRCaXRzIiwic2V0VW51c2VkQml0c0FuZEhleFZhbHVlIiwic2V0QnlCaW5hcnlTdHJpbmciLCJzZXRCeUJvb2xlYW5BcnJheSIsIm5ld0ZhbHNlQXJyYXkiLCJiaW4iLCJzZXRWYWx1ZU9pZFN0cmluZyIsInNldFZhbHVlTmFtZSIsIng1MDkiLCJPSUQiLCJuYW1lMm9pZCIsIm9pZCIsIm5hbWUiLCJkYXRlIiwid2l0aE1pbGxpcyIsIm1pbGxpcyIsInNvcnRGbGFnIiwic29ydCIsInNvcnRmbGFnIiwiaXNFeHBsaWNpdCIsImFzbjFPYmplY3QiLCJzZXRBU04xT2JqZWN0IiwiQVNOMUhFWCIsImdldExibGVuIiwiZ2V0TCIsImdldFZibGVuIiwiZ2V0VmlkeCIsImdldFYiLCJnZXRUTFYiLCJnZXROZXh0U2libGluZ0lkeCIsImdldENoaWxkSWR4IiwiZ2V0TnRoQ2hpbGRJZHgiLCJnZXRJZHhieUxpc3QiLCJnZXRUTFZieUxpc3QiLCJnZXRWYnlMaXN0IiwiaGV4dG9vaWRzdHIiLCJkdW1wIiwib21taXRfbG9uZ19vY3RldCIsImlzQVNOMUhFWCIsIm9pZDJuYW1lIiwiaGV4dG91dGY4Iiwib2lkbmFtZSIsIkpTT04iLCJ4NTA5RXh0TmFtZSIsImlzSGV4IiwiQmFzZTY0eCIsInN0b0JBIiwiQkF0b3MiLCJCQXRvaGV4Iiwic3RvYjY0Iiwic3RvYjY0dSIsImI2NHRvYjY0dSIsImI2NHV0b3MiLCJiNjR1dG9iNjQiLCJoZXh0b2I2NHUiLCJiNjR1dG9oZXgiLCJ1dGY4dG9iNjR1IiwiYjY0dXRvdXRmOCIsIkJ1ZmZlciIsInVyaWNtcHRvaGV4IiwiZW5jb2RlVVJJQ29tcG9uZW50QWxsIiwiaGV4dG91cmljbXAiLCJ1dGY4dG9iNjQiLCJiNjR0b3V0ZjgiLCJoZXh0b2I2NCIsImhleHRvYjY0bmwiLCJiNjRubHRvaGV4IiwicGVtdG9oZXgiLCJoZXh0b0FycmF5QnVmZmVyIiwiQXJyYXlCdWZmZXIiLCJEYXRhVmlldyIsInNldFVpbnQ4IiwiQXJyYXlCdWZmZXJ0b2hleCIsImJ5dGVMZW5ndGgiLCJnZXRVaW50OCIsInp1bHV0b21zZWMiLCJ6dWx1dG9zZWMiLCJ6dWx1dG9kYXRlIiwiZGF0ZXRvenVsdSIsImdldFVUQ0Z1bGxZZWFyIiwiZ2V0VVRDTW9udGgiLCJnZXRVVENEYXRlIiwiZ2V0VVRDSG91cnMiLCJnZXRVVENNaW51dGVzIiwiZ2V0VVRDU2Vjb25kcyIsImdldFVUQ01pbGxpc2Vjb25kcyIsImlwdjZ0b2hleCIsInJlcGVhdCIsImhleHRvaXB2NiIsImhleHRvaXAiLCJpcHRvaGV4IiwibmV3bGluZV90b1VuaXgiLCJuZXdsaW5lX3RvRG9zIiwiaXNJbnRlZ2VyIiwiaXNCYXNlNjQiLCJpc0Jhc2U2NFVSTCIsImlzSW50ZWdlckFycmF5IiwiaGV4dG9wb3NoZXgiLCJpbnRhcnlzdHJ0b2hleCIsIm1hcCIsInN0cmRpZmZpZHgiLCJESUdFU1RJTkZPSEVBRCIsInNoYTEiLCJzaGEyMjQiLCJzaGEyNTYiLCJzaGEzODQiLCJzaGE1MTIiLCJtZDIiLCJtZDUiLCJyaXBlbWQxNjAiLCJERUZBVUxUUFJPVklERVIiLCJobWFjbWQ1IiwiaG1hY3NoYTEiLCJobWFjc2hhMjI0IiwiaG1hY3NoYTI1NiIsImhtYWNzaGEzODQiLCJobWFjc2hhNTEyIiwiaG1hY3JpcGVtZDE2MCIsIk1ENXdpdGhSU0EiLCJTSEExd2l0aFJTQSIsIlNIQTIyNHdpdGhSU0EiLCJTSEEyNTZ3aXRoUlNBIiwiU0hBMzg0d2l0aFJTQSIsIlNIQTUxMndpdGhSU0EiLCJSSVBFTUQxNjB3aXRoUlNBIiwiTUQ1d2l0aEVDRFNBIiwiU0hBMXdpdGhFQ0RTQSIsIlNIQTIyNHdpdGhFQ0RTQSIsIlNIQTI1NndpdGhFQ0RTQSIsIlNIQTM4NHdpdGhFQ0RTQSIsIlNIQTUxMndpdGhFQ0RTQSIsIlJJUEVNRDE2MHdpdGhFQ0RTQSIsIlNIQTF3aXRoRFNBIiwiU0hBMjI0d2l0aERTQSIsIlNIQTI1NndpdGhEU0EiLCJNRDV3aXRoUlNBYW5kTUdGMSIsIlNIQTF3aXRoUlNBYW5kTUdGMSIsIlNIQTIyNHdpdGhSU0FhbmRNR0YxIiwiU0hBMjU2d2l0aFJTQWFuZE1HRjEiLCJTSEEzODR3aXRoUlNBYW5kTUdGMSIsIlNIQTUxMndpdGhSU0FhbmRNR0YxIiwiUklQRU1EMTYwd2l0aFJTQWFuZE1HRjEiLCJDUllQVE9KU01FU1NBR0VESUdFU1ROQU1FIiwiTUQ1IiwiU0hBMSIsIlNIQTIyNCIsIlJJUEVNRDE2MCIsImdldERpZ2VzdEluZm9IZXgiLCJnZXRQYWRkZWREaWdlc3RJbmZvSGV4IiwiaGFzaFN0cmluZyIsImFsZyIsImRpZ2VzdFN0cmluZyIsImRpZ2VzdEhleCIsInByb3YiLCJzaGEyNTZIZXgiLCJzaGE1MTJIZXgiLCJTRUNVUkVSQU5ET01HRU4iLCJnZXRSYW5kb21IZXhPZk5ieXRlcyIsImdldFJhbmRvbUJpZ0ludGVnZXJPZk5ieXRlcyIsImdldFJhbmRvbUhleE9mTmJpdHMiLCJnZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYml0cyIsImdldFJhbmRvbUJpZ0ludGVnZXJaZXJvVG9NYXgiLCJnZXRSYW5kb21CaWdJbnRlZ2VyTWluVG9NYXgiLCJzZXRBbGdBbmRQcm92aWRlciIsIm1kIiwidXBkYXRlU3RyaW5nIiwidXBkYXRlSGV4IiwiZGlnZXN0Iiwic2pjbCIsImhhc2giLCJjb2RlYyIsInRvQml0cyIsImZyb21CaXRzIiwiYWxnTmFtZSIsInByb3ZOYW1lIiwiSEFTSExFTkdUSCIsIk1hYyIsImFsZ1Byb3YiLCJtYWMiLCJwYXNzIiwiZG9GaW5hbCIsImRvRmluYWxTdHJpbmciLCJkb0ZpbmFsSGV4Iiwic2V0UGFzc3dvcmQiLCJ1dGY4IiwicnN0ciIsImI2NCIsImI2NHUiLCJTaWduYXR1cmUiLCJfc2V0QWxnTmFtZXMiLCJtZEFsZ05hbWUiLCJwdWJrZXlBbGdOYW1lIiwiX3plcm9QYWRkaW5nT2ZTaWduYXR1cmUiLCJLRVlVVElMIiwiZ2V0S2V5IiwicHJ2S2V5Iiwic3RhdGUiLCJwdWJLZXkiLCJzaWduIiwic0hhc2hIZXgiLCJlY3BydmhleCIsImVjY3VydmVuYW1lIiwiRUNEU0EiLCJoU2lnbiIsInNpZ25IZXgiLCJzaWduV2l0aE1lc3NhZ2VIYXNoUFNTIiwicHNzU2FsdExlbiIsInNpZ25XaXRoTWVzc2FnZUhhc2giLCJEU0EiLCJzaWduU3RyaW5nIiwidmVyaWZ5IiwiZWNwdWJoZXgiLCJ2ZXJpZnlIZXgiLCJ2ZXJpZnlXaXRoTWVzc2FnZUhhc2hQU1MiLCJ2ZXJpZnlXaXRoTWVzc2FnZUhhc2giLCJhbGdQcm92TmFtZSIsImluaXRQYXJhbXMiLCJwc3NzYWx0bGVuIiwicHJ2a2V5cGVtIiwicHJ2a2V5cGFzIiwiQ2lwaGVyIiwiZ2V0QWxnQnlLZXlBbmROYW1lIiwiZGVjcnlwdCIsImRlY3J5cHRPQUVQIiwib2lkaGV4Mm5hbWUiLCJnZXRCaWdSYW5kb20iLCJzZXROYW1lZEN1cnZlIiwiZWNwYXJhbXMiLCJFQ1BhcmFtZXRlckRCIiwiZ2V0QnlOYW1lIiwicHJ2S2V5SGV4IiwicHViS2V5SGV4IiwiY3VydmVOYW1lIiwic2V0UHJpdmF0ZUtleUhleCIsInNldFB1YmxpY0tleUhleCIsImdldFB1YmxpY0tleVhZSGV4Iiwia2V5bGVuIiwiZ2V0U2hvcnROSVNUUEN1cnZlTmFtZSIsImdlbmVyYXRlS2V5UGFpckhleCIsImJpUlNTaWdUb0FTTjFTaWciLCJmcm9tQnl0ZUFycmF5VW5zaWduZWQiLCJzZXJpYWxpemVTaWciLCJwYXJzZVNpZ0hleCIsInZlcmlmeVJhdyIsIkJpdGNvaW4iLCJpc0FycmF5IiwicGFyc2VTaWciLCJ0b0J5dGVBcnJheVNpZ25lZCIsInBhcnNlU2lnQ29tcGFjdCIsInJlYWRQS0NTNVBydktleUhleCIsImdldE5hbWUiLCJyZWFkUEtDUzhQcnZLZXlIZXgiLCJyZWFkUEtDUzhQdWJLZXlIZXgiLCJyZWFkQ2VydFB1YktleUhleCIsInBydiIsInB1YiIsInBhcnNlU2lnSGV4SW5IZXhSUyIsImFzbjFTaWdUb0NvbmNhdFNpZyIsImNvbmNhdFNpZ1RvQVNOMVNpZyIsImhleFJTU2lnVG9BU04xU2lnIiwicmVnaXN0IiwiQUVTIiwiVHJpcGxlREVTIiwiREVTIiwia2V5IiwiaXYiLCJjaXBoZXJ0ZXh0IiwicHJvYyIsImVwcm9jIiwiaXZsZW4iLCJjaXBoZXIiLCJpdnNhbHQiLCJkYXRhIiwia2V5aGV4IiwiaXZoZXgiLCJ2ZXJzaW9uIiwicGFyc2VQS0NTNVBFTSIsImdldEtleUFuZFVudXNlZEl2QnlQYXNzY29kZUFuZEl2c2FsdCIsImRlY3J5cHRLZXlCNjQiLCJnZXREZWNyeXB0ZWRLZXlIZXgiLCJnZXRFbmNyeXB0ZWRQS0NTNVBFTUZyb21QcnZLZXlIZXgiLCJ0b1VwcGVyQ2FzZSIsInBhcnNlSGV4T2ZFbmNyeXB0ZWRQS0NTOCIsImVuY3J5cHRpb25TY2hlbWVBbGciLCJlbmNyeXB0aW9uU2NoZW1lSVYiLCJwYmtkZjJTYWx0IiwicGJrZGYySXRlciIsImdldFBCS0RGMktleUhleEZyb21QYXJhbSIsIlBCS0RGMiIsImtleVNpemUiLCJpdGVyYXRpb25zIiwiX2dldFBsYWluUEtDUzhIZXhGcm9tRW5jcnlwdGVkUEtDUzhQRU0iLCJnZXRLZXlGcm9tRW5jcnlwdGVkUEtDUzhQRU0iLCJnZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhIZXgiLCJwYXJzZVBsYWluUHJpdmF0ZVBLQ1M4SGV4IiwiYWxncGFyYW0iLCJhbGdvaWQiLCJrZXlpZHgiLCJnZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhQRU0iLCJfZ2V0S2V5RnJvbVB1YmxpY1BLQ1M4SGV4IiwicGFyc2VQdWJsaWNSYXdSU0FLZXlIZXgiLCJwYXJzZVB1YmxpY1BLQ1M4SGV4IiwieHkiLCJrdHkiLCJkcCIsImRxIiwiY28iLCJxaSIsInNldFByaXZhdGVFeCIsInNldFByaXZhdGUiLCJjcnYiLCJYNTA5IiwiZ2V0UHVibGljS2V5RnJvbUNlcnRIZXgiLCJnZXRQdWJsaWNLZXlGcm9tQ2VydFBFTSIsImdlbmVyYXRlS2V5cGFpciIsImdlbmVyYXRlIiwicHJ2S2V5T2JqIiwicHViS2V5T2JqIiwiZ2V0UEVNIiwiU3ViamVjdFB1YmxpY0tleUluZm8iLCJzZXEiLCJvY3RzdHIiLCJiaXRzdHIiLCJnZXRLZXlGcm9tQ1NSUEVNIiwiZ2V0S2V5RnJvbUNTUkhleCIsInBhcnNlQ1NSSGV4IiwicDhwdWJrZXloZXgiLCJnZXRKV0tGcm9tS2V5IiwiZ2V0UG9zQXJyYXlPZkNoaWxkcmVuRnJvbUhleCIsImdldEhleFZhbHVlQXJyYXlPZkNoaWxkcmVuRnJvbUhleCIsInJlYWRQcml2YXRlS2V5RnJvbVBFTVN0cmluZyIsInJlYWRQS0NTNVB1YktleUhleCIsInJlYWRDZXJ0SGV4IiwiZ2V0UHVibGljS2V5SGV4IiwiX1JFX0hFWERFQ09OTFkiLCJjb21waWxlIiwiX3JzYXNpZ25fZ2V0SGV4UGFkZGVkRGlnZXN0SW5mb0ZvclN0cmluZyIsImRvUHJpdmF0ZSIsInBzc19tZ2YxX3N0ciIsInNpZ25QU1MiLCJfcnNhc2lnbl9nZXREZWNyeXB0U2lnbmF0dXJlQkkiLCJfcnNhc2lnbl9nZXRIZXhEaWdlc3RJbmZvRnJvbVNpZyIsIl9yc2FzaWduX2dldEFsZ05hbWVBbmRIYXNoRnJvbUhleERpc2dlc3RJbmZvIiwidmVyaWZ5UFNTIiwiU0FMVF9MRU5fSExFTiIsIlNBTFRfTEVOX01BWCIsIlNBTFRfTEVOX1JFQ09WRVIiLCJmb2Zmc2V0IiwiYUV4dEluZm8iLCJnZXRWZXJzaW9uIiwiZ2V0U2VyaWFsTnVtYmVySGV4IiwiZ2V0U2lnbmF0dXJlQWxnb3JpdGhtRmllbGQiLCJnZXRJc3N1ZXJIZXgiLCJnZXRJc3N1ZXJTdHJpbmciLCJoZXgyZG4iLCJnZXRTdWJqZWN0SGV4IiwiZ2V0U3ViamVjdFN0cmluZyIsImdldE5vdEJlZm9yZSIsImdldE5vdEFmdGVyIiwiZ2V0UHVibGljS2V5SWR4IiwiZ2V0UHVibGljS2V5Q29udGVudElkeCIsImdldFB1YmxpY0tleSIsImdldFNpZ25hdHVyZUFsZ29yaXRobU5hbWUiLCJnZXRTaWduYXR1cmVWYWx1ZUhleCIsInZlcmlmeVNpZ25hdHVyZSIsInBhcnNlRXh0IiwiY3JpdGljYWwiLCJ2aWR4IiwiZ2V0RXh0SW5mbyIsImdldEV4dEJhc2ljQ29uc3RyYWludHMiLCJjQSIsInBhdGhMZW4iLCJnZXRFeHRLZXlVc2FnZUJpbiIsImdldEV4dEtleVVzYWdlU3RyaW5nIiwiS0VZVVNBR0VfTkFNRSIsImdldEV4dFN1YmplY3RLZXlJZGVudGlmaWVyIiwiZ2V0RXh0QXV0aG9yaXR5S2V5SWRlbnRpZmllciIsImtpZCIsImdldEV4dEV4dEtleVVzYWdlTmFtZSIsImdldEV4dFN1YmplY3RBbHROYW1lIiwiZ2V0RXh0U3ViamVjdEFsdE5hbWUyIiwiZ2V0RXh0Q1JMRGlzdHJpYnV0aW9uUG9pbnRzVVJJIiwiZ2V0RXh0QUlBSW5mbyIsIm9jc3AiLCJjYWlzc3VlciIsImdldEV4dENlcnRpZmljYXRlUG9saWNpZXMiLCJpZCIsImNwcyIsInVub3RpY2UiLCJyZWFkQ2VydFBFTSIsImdldEluZm8iLCJoZXgycmRuIiwiaGV4MmF0dHJUeXBlVmFsdWUiLCJvaWQyYXR5cGUiLCJnZXRQdWJsaWNLZXlJbmZvUHJvcE9mQ2VydFBFTSIsImp3cyIsIkpXUyIsImlzU2FmZUpTT05TdHJpbmciLCJwYXJzZUpXUyIsInBhcnNlZEpXUyIsInNpZ3ZhbEgiLCJoZWFkQjY0VSIsInBheWxvYWRCNjRVIiwic2lndmFsQjY0VSIsInNpIiwic2lndmFsQkkiLCJoZWFkUyIsInBheWxvYWRTIiwicmVhZFNhZmVKU09OU3RyaW5nIiwiandzYWxnMnNpZ2FsZyIsImhBU04xU2lnIiwiaGVhZGVyT2JqIiwicGF5bG9hZE9iaiIsImhlYWRlclBQIiwicGF5bG9hZFBQIiwic2lnSGV4IiwidmVyaWZ5SldUIiwiaW5BcnJheSIsImluY2x1ZGVkQXJyYXkiLCJpc3MiLCJzdWIiLCJhdWQiLCJJbnREYXRlIiwiZ2V0Tm93IiwidmVyaWZ5QXQiLCJncmFjZVBlcmlvZCIsIm5iZiIsImlhdCIsImp0aSIsIkhTMjU2IiwiSFMzODQiLCJIUzUxMiIsIlJTMjU2IiwiUlMzODQiLCJSUzUxMiIsIkVTMjU2IiwiRVMzODQiLCJQUzI1NiIsIlBTMzg0IiwiUFM1MTIiLCJub25lIiwiZ2V0RW5jb2RlZFNpZ25hdHVyZVZhbHVlRnJvbUpXUyIsImdldEpXS3RodW1icHJpbnQiLCJnZXQiLCJnZXRadWx1IiwiaW50RGF0ZTJVVENTdHJpbmciLCJ0b1VUQ1N0cmluZyIsImludERhdGUyWnVsdSIsIkVEU0EiLCJfY3J5cHRvIiwiRGVmYXVsdEFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lIiwiYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUiLCJhY2Nlc3NUb2tlbkV4cGlyaW5nVGltZXIiLCJUaW1lciIsImFjY2Vzc1Rva2VuRXhwaXJlZFRpbWVyIiwiX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lIiwiX2FjY2Vzc1Rva2VuRXhwaXJpbmciLCJfYWNjZXNzVG9rZW5FeHBpcmVkIiwibG9hZCIsImNvbnRhaW5lciIsImFjY2Vzc190b2tlbiIsImV4cGlyZXNfaW4iLCJkdXJhdGlvbiIsImRlYnVnIiwiZXhwaXJpbmciLCJjYW5jZWwiLCJleHBpcmVkIiwidW5sb2FkIiwiYWRkQWNjZXNzVG9rZW5FeHBpcmluZyIsImNiIiwiYWRkSGFuZGxlciIsInJlbW92ZUFjY2Vzc1Rva2VuRXhwaXJpbmciLCJyZW1vdmVIYW5kbGVyIiwiYWRkQWNjZXNzVG9rZW5FeHBpcmVkIiwicmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmVkIiwiRGVmYXVsdEludGVydmFsIiwiY2FsbGJhY2siLCJjbGllbnRfaWQiLCJ1cmwiLCJpbnRlcnZhbCIsInN0b3BPbkVycm9yIiwiX2NhbGxiYWNrIiwiX2NsaWVudF9pZCIsIl91cmwiLCJfaW50ZXJ2YWwiLCJfc3RvcE9uRXJyb3IiLCJpZHgiLCJfZnJhbWVfb3JpZ2luIiwiX2ZyYW1lIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50Iiwic3R5bGUiLCJ2aXNpYmlsaXR5IiwicG9zaXRpb24iLCJkaXNwbGF5Iiwid2lkdGgiLCJoZWlnaHQiLCJzcmMiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm9ubG9hZCIsImJvZHkiLCJhcHBlbmRDaGlsZCIsIl9ib3VuZE1lc3NhZ2VFdmVudCIsIl9tZXNzYWdlIiwiYmluZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJvcmlnaW4iLCJzb3VyY2UiLCJjb250ZW50V2luZG93IiwiZXJyb3IiLCJzdG9wIiwic3RhcnQiLCJzZXNzaW9uX3N0YXRlIiwiX3Nlc3Npb25fc3RhdGUiLCJzZW5kIiwicG9zdE1lc3NhZ2UiLCJfdGltZXIiLCJzZXRJbnRlcnZhbCIsImNsZWFySW50ZXJ2YWwiLCJwcmVwYXJlIiwicGFyYW1zIiwicG9wdXBXaW5kb3dGZWF0dXJlcyIsInBvcHVwIiwiQ29yZG92YVBvcHVwV2luZG93IiwiRGVmYXVsdFBvcHVwRmVhdHVyZXMiLCJEZWZhdWx0UG9wdXBUYXJnZXQiLCJfcHJvbWlzZSIsInJlamVjdCIsIl9yZXNvbHZlIiwiX3JlamVjdCIsImZlYXR1cmVzIiwidGFyZ2V0IiwicG9wdXBXaW5kb3dUYXJnZXQiLCJyZWRpcmVjdF91cmkiLCJzdGFydFVybCIsIl9pc0luQXBwQnJvd3Nlckluc3RhbGxlZCIsImNvcmRvdmFNZXRhZGF0YSIsInNvbWUiLCJuYXZpZ2F0ZSIsIl9lcnJvciIsImNvcmRvdmEiLCJyZXF1aXJlIiwibWV0YWRhdGEiLCJfcG9wdXAiLCJJbkFwcEJyb3dzZXIiLCJvcGVuIiwiX2V4aXRDYWxsYmFja0V2ZW50IiwiX2V4aXRDYWxsYmFjayIsIl9sb2FkU3RhcnRDYWxsYmFja0V2ZW50IiwiX2xvYWRTdGFydENhbGxiYWNrIiwicHJvbWlzZSIsImV2ZW50IiwiX3N1Y2Nlc3MiLCJtZXNzYWdlIiwiX2NsZWFudXAiLCJjbG9zZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJFcnJvclJlc3BvbnNlIiwiZXJyb3JfZGVzY3JpcHRpb24iLCJlcnJvcl91cmkiLCJFdmVudCIsIl9uYW1lIiwiX2NhbGxiYWNrcyIsImZpbmRJbmRleCIsIml0ZW0iLCJyYWlzZSIsInRpbWVyIiwiaGFuZGxlIiwidGVzdGluZyIsInJlcXVlc3QiLCJfdGVzdGluZyIsInNldFhNTEh0dHBSZXF1ZXN0IiwibmV3UmVxdWVzdCIsImxvY2F0aW9uIiwibG9jYWxTdG9yYWdlIiwic2Vzc2lvblN0b3JhZ2UiLCJYTUxIdHRwUmVxdWVzdCIsIklGcmFtZU5hdmlnYXRvciIsImZyYW1lIiwiSUZyYW1lV2luZG93Iiwibm90aWZ5UGFyZW50IiwiRGVmYXVsdFRpbWVvdXQiLCJ0aW1lb3V0Iiwic2lsZW50UmVxdWVzdFRpbWVvdXQiLCJzZXRUaW1lb3V0IiwiX3RpbWVvdXQiLCJjbGVhclRpbWVvdXQiLCJyZW1vdmVDaGlsZCIsIl9vcmlnaW4iLCJmcmFtZUVsZW1lbnQiLCJocmVmIiwicGFyZW50IiwicHJvdG9jb2wiLCJob3N0IiwiZ2V0SXRlbSIsInNldEl0ZW0iLCJ2YWx1ZSIsInJlbW92ZUl0ZW0iLCJpbmRleCIsImdldE93blByb3BlcnR5TmFtZXMiLCJKb3NlVXRpbCIsIktleVV0aWwiLCJBbGxvd2VkU2lnbmluZ0FsZ3MiLCJnZXRKb3NlVXRpbCIsInBhcnNlSnd0Iiwiand0IiwidG9rZW4iLCJoZWFkZXIiLCJwYXlsb2FkIiwidmFsaWRhdGVKd3QiLCJpc3N1ZXIiLCJhdWRpZW5jZSIsImNsb2NrU2tldyIsIm5vdyIsInRpbWVJbnNlbnNpdGl2ZSIsIng1YyIsIl92YWxpZGF0ZUp3dCIsInZhbGlkYXRlSnd0QXR0cmlidXRlcyIsInZhbGlkQXVkaWVuY2UiLCJhenAiLCJsb3dlck5vdyIsInVwcGVyTm93IiwidGhlbiIsImhleFRvQmFzZTY0VXJsIiwiSnNvblNlcnZpY2UiLCJhZGRpdGlvbmFsQ29udGVudFR5cGVzIiwiWE1MSHR0cFJlcXVlc3RDdG9yIiwiand0SGFuZGxlciIsIl9jb250ZW50VHlwZXMiLCJfWE1MSHR0cFJlcXVlc3QiLCJfand0SGFuZGxlciIsImdldEpzb24iLCJyZXEiLCJhbGxvd2VkQ29udGVudFR5cGVzIiwic3RhdHVzIiwiY29udGVudFR5cGUiLCJnZXRSZXNwb25zZUhlYWRlciIsImZvdW5kIiwiZmluZCIsInN0YXJ0c1dpdGgiLCJyZXNwb25zZVRleHQiLCJzdGF0dXNUZXh0Iiwib25lcnJvciIsInNldFJlcXVlc3RIZWFkZXIiLCJwb3N0Rm9ybSIsIm5vcExvZ2dlciIsImluZm8iLCJ3YXJuIiwiTk9ORSIsIkVSUk9SIiwiV0FSTiIsIklORk8iLCJERUJVRyIsImxvZ2dlciIsImxldmVsIiwiYXJncyIsImZyb20iLCJPaWRjTWV0YWRhdGFVcmxQYXRoIiwic2V0dGluZ3MiLCJKc29uU2VydmljZUN0b3IiLCJfc2V0dGluZ3MiLCJfanNvblNlcnZpY2UiLCJnZXRNZXRhZGF0YSIsIm1ldGFkYXRhVXJsIiwiZ2V0SXNzdWVyIiwiX2dldE1ldGFkYXRhUHJvcGVydHkiLCJnZXRBdXRob3JpemF0aW9uRW5kcG9pbnQiLCJnZXRVc2VySW5mb0VuZHBvaW50IiwiZ2V0VG9rZW5FbmRwb2ludCIsIm9wdGlvbmFsIiwiZ2V0Q2hlY2tTZXNzaW9uSWZyYW1lIiwiZ2V0RW5kU2Vzc2lvbkVuZHBvaW50IiwiZ2V0UmV2b2NhdGlvbkVuZHBvaW50IiwiZ2V0S2V5c0VuZHBvaW50IiwiZ2V0U2lnbmluZ0tleXMiLCJzaWduaW5nS2V5cyIsImp3a3NfdXJpIiwia2V5U2V0IiwiX21ldGFkYXRhVXJsIiwiYXV0aG9yaXR5IiwiY3JlYXRlU2lnbmluUmVxdWVzdCIsInJlc3BvbnNlX3R5cGUiLCJzY29wZSIsInByb21wdCIsIm1heF9hZ2UiLCJ1aV9sb2NhbGVzIiwiaWRfdG9rZW5faGludCIsImxvZ2luX2hpbnQiLCJhY3JfdmFsdWVzIiwicmVzb3VyY2UiLCJyZXF1ZXN0X3VyaSIsInJlc3BvbnNlX21vZGUiLCJleHRyYVF1ZXJ5UGFyYW1zIiwiZXh0cmFUb2tlblBhcmFtcyIsInJlcXVlc3RfdHlwZSIsInNraXBVc2VySW5mbyIsInN0YXRlU3RvcmUiLCJTaWduaW5SZXF1ZXN0IiwiaXNDb2RlIiwiX21ldGFkYXRhU2VydmljZSIsInNpZ25pblJlcXVlc3QiLCJjbGllbnRfc2VjcmV0Iiwic2lnbmluU3RhdGUiLCJfc3RhdGVTdG9yZSIsInNldCIsInRvU3RvcmFnZVN0cmluZyIsInJlYWRTaWduaW5SZXNwb25zZVN0YXRlIiwicmVtb3ZlU3RhdGUiLCJ1c2VRdWVyeSIsImRlbGltaXRlciIsInJlc3BvbnNlIiwiU2lnbmluUmVzcG9uc2UiLCJzdGF0ZUFwaSIsInJlbW92ZSIsInN0b3JlZFN0YXRlU3RyaW5nIiwiU2lnbmluU3RhdGUiLCJmcm9tU3RvcmFnZVN0cmluZyIsInByb2Nlc3NTaWduaW5SZXNwb25zZSIsIl92YWxpZGF0b3IiLCJ2YWxpZGF0ZVNpZ25pblJlc3BvbnNlIiwiY3JlYXRlU2lnbm91dFJlcXVlc3QiLCJwb3N0X2xvZ291dF9yZWRpcmVjdF91cmkiLCJTaWdub3V0UmVxdWVzdCIsInNpZ25vdXRTdGF0ZSIsInJlYWRTaWdub3V0UmVzcG9uc2VTdGF0ZSIsIlNpZ25vdXRSZXNwb25zZSIsInN0YXRlS2V5IiwiU3RhdGUiLCJwcm9jZXNzU2lnbm91dFJlc3BvbnNlIiwidmFsaWRhdGVTaWdub3V0UmVzcG9uc2UiLCJjbGVhclN0YWxlU3RhdGUiLCJzdGFsZVN0YXRlQWdlIiwidmFsaWRhdG9yIiwibWV0YWRhdGFTZXJ2aWNlIiwiRGVmYXVsdFJlc3BvbnNlVHlwZSIsIkRlZmF1bHRTY29wZSIsIkRlZmF1bHRTdGFsZVN0YXRlQWdlIiwiRGVmYXVsdENsb2NrU2tld0luU2Vjb25kcyIsImZpbHRlclByb3RvY29sQ2xhaW1zIiwibG9hZFVzZXJJbmZvIiwidXNlckluZm9Kd3RJc3N1ZXIiLCJSZXNwb25zZVZhbGlkYXRvckN0b3IiLCJSZXNwb25zZVZhbGlkYXRvciIsIk1ldGFkYXRhU2VydmljZUN0b3IiLCJfYXV0aG9yaXR5IiwiX21ldGFkYXRhIiwiX3NpZ25pbmdLZXlzIiwiX2NsaWVudF9zZWNyZXQiLCJfcmVzcG9uc2VfdHlwZSIsIl9zY29wZSIsIl9yZWRpcmVjdF91cmkiLCJfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIiwiX3Byb21wdCIsIl9kaXNwbGF5IiwiX21heF9hZ2UiLCJfdWlfbG9jYWxlcyIsIl9hY3JfdmFsdWVzIiwiX3Jlc291cmNlIiwiX3Jlc3BvbnNlX21vZGUiLCJfZmlsdGVyUHJvdG9jb2xDbGFpbXMiLCJfbG9hZFVzZXJJbmZvIiwiX3N0YWxlU3RhdGVBZ2UiLCJfY2xvY2tTa2V3IiwiX3VzZXJJbmZvSnd0SXNzdWVyIiwiX2V4dHJhUXVlcnlQYXJhbXMiLCJfZXh0cmFUb2tlblBhcmFtcyIsIlBvcHVwTmF2aWdhdG9yIiwiUG9wdXBXaW5kb3ciLCJrZWVwT3BlbiIsIm5vdGlmeU9wZW5lciIsIkNoZWNrRm9yUG9wdXBDbG9zZWRJbnRlcnZhbCIsIl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIiLCJfY2hlY2tGb3JQb3B1cENsb3NlZCIsIl9pZCIsImZvY3VzIiwiY2xvc2VkIiwib3BlbmVyIiwiVXJsVXRpbGl0eSIsInBhcnNlVXJsRnJhZ21lbnQiLCJSZWRpcmVjdE5hdmlnYXRvciIsInVzZVJlcGxhY2VUb05hdmlnYXRlIiwiUHJvdG9jb2xDbGFpbXMiLCJVc2VySW5mb1NlcnZpY2VDdG9yIiwiVXNlckluZm9TZXJ2aWNlIiwiam9zZVV0aWwiLCJUb2tlbkNsaWVudEN0b3IiLCJUb2tlbkNsaWVudCIsIl91c2VySW5mb1NlcnZpY2UiLCJfam9zZVV0aWwiLCJfdG9rZW5DbGllbnQiLCJfcHJvY2Vzc1NpZ25pblBhcmFtcyIsIl92YWxpZGF0ZVRva2VucyIsIl9wcm9jZXNzQ2xhaW1zIiwibm9uY2UiLCJpZF90b2tlbiIsImNvZGVfdmVyaWZpZXIiLCJjb2RlIiwiaXNPcGVuSWRDb25uZWN0IiwicHJvZmlsZSIsImdldENsYWltcyIsImNsYWltcyIsIl9tZXJnZUNsYWltcyIsImNsYWltczEiLCJjbGFpbXMyIiwicmVzdWx0IiwiYXNzaWduIiwidmFsdWVzIiwiZm9yRWFjaCIsIl9wcm9jZXNzQ29kZSIsIl92YWxpZGF0ZUlkVG9rZW5BbmRBY2Nlc3NUb2tlbiIsIl92YWxpZGF0ZUlkVG9rZW4iLCJleGNoYW5nZUNvZGUiLCJ0b2tlblJlc3BvbnNlIiwiX3ZhbGlkYXRlSWRUb2tlbkF0dHJpYnV0ZXMiLCJjbG9ja1NrZXdJblNlY29uZHMiLCJfdmFsaWRhdGVBY2Nlc3NUb2tlbiIsIl9maWx0ZXJCeUFsZyIsImZpbHRlciIsImF0X2hhc2giLCJoYXNoQWxnIiwiaGFzaEJpdHMiLCJzaGEiLCJsZWZ0IiwibGVmdF9iNjR1IiwidXNlck1hbmFnZXIiLCJDaGVja1Nlc3Npb25JRnJhbWVDdG9yIiwiX3VzZXJNYW5hZ2VyIiwiX0NoZWNrU2Vzc2lvbklGcmFtZUN0b3IiLCJldmVudHMiLCJhZGRVc2VyTG9hZGVkIiwiX3N0YXJ0IiwiYWRkVXNlclVubG9hZGVkIiwiX3N0b3AiLCJnZXRVc2VyIiwidXNlciIsIm1vbml0b3JBbm9ueW1vdXNTZXNzaW9uIiwicXVlcnlTZXNzaW9uU3RhdHVzIiwidG1wVXNlciIsInNlc3Npb24iLCJzaWQiLCJjYXRjaCIsImVyciIsIl9zdWIiLCJfc2lkIiwiX2NoZWNrU2Vzc2lvbklGcmFtZSIsIl9jaGVja1Nlc3Npb25JbnRlcnZhbCIsIl9zdG9wQ2hlY2tTZXNzaW9uT25FcnJvciIsInRpbWVySGFuZGxlIiwicmFpc2VFdmVudCIsIl9yYWlzZVVzZXJTZXNzaW9uQ2hhbmdlZCIsIl9yYWlzZVVzZXJTaWduZWRPdXQiLCJfcmFpc2VVc2VyU2lnbmVkSW4iLCJjaGVja1Nlc3Npb25JbnRlcnZhbCIsInN0b3BDaGVja1Nlc3Npb25PbkVycm9yIiwib2lkYyIsImlzT2lkYyIsImFkZFF1ZXJ5UGFyYW0iLCJjb2RlX2NoYWxsZW5nZSIsImlzT0F1dGgiLCJPaWRjU2NvcGUiLCJ0b2tlbl90eXBlIiwiZXhwaXJlc19hdCIsInNjb3BlcyIsIl9ub25jZSIsIl9jb2RlX3ZlcmlmaWVyIiwiX2NvZGVfY2hhbGxlbmdlIiwiX3NraXBVc2VySW5mbyIsImNyZWF0ZWQiLCJzdG9yYWdlU3RyaW5nIiwiU2lsZW50UmVuZXdTZXJ2aWNlIiwiX3Rva2VuRXhwaXJpbmciLCJzaWduaW5TaWxlbnQiLCJfcmFpc2VTaWxlbnRSZW5ld0Vycm9yIiwiX2NyZWF0ZWQiLCJfcmVxdWVzdF90eXBlIiwic3RvcmFnZSIsImFnZSIsImN1dG9mZiIsImdldEFsbEtleXMiLCJwcm9taXNlcyIsImFsbCIsIlRpbWVyRHVyYXRpb24iLCJub3dGdW5jIiwiX25vd0Z1bmMiLCJleHBpcmF0aW9uIiwiX3RpbWVySGFuZGxlIiwiX2V4cGlyYXRpb24iLCJ0aW1lckR1cmF0aW9uIiwiZGlmZiIsImdyYW50X3R5cGUiLCJleGNoYW5nZVJlZnJlc2hUb2tlbiIsInJlZnJlc2hfdG9rZW4iLCJBY2Nlc3NUb2tlblR5cGVIaW50IiwiUmVmcmVzaFRva2VuVHlwZUhpbnQiLCJfWE1MSHR0cFJlcXVlc3RDdG9yIiwicmV2b2tlIiwicmVxdWlyZWQiLCJfcmV2b2tlIiwieGhyIiwiZ2xvYmFsIiwibGFzdEluZGV4T2YiLCJyZWdleCIsImNvdW50ZXIiLCJleGVjIiwicHJvcCIsIl9nZXRDbGFpbXNGcm9tSnd0IiwiaXNzdWVyUHJvbWlzZSIsIlNpbGVudFJlbmV3U2VydmljZUN0b3IiLCJTZXNzaW9uTW9uaXRvckN0b3IiLCJUb2tlblJldm9jYXRpb25DbGllbnRDdG9yIiwiVXNlck1hbmFnZXJTZXR0aW5ncyIsIl9ldmVudHMiLCJVc2VyTWFuYWdlckV2ZW50cyIsIl9zaWxlbnRSZW5ld1NlcnZpY2UiLCJhdXRvbWF0aWNTaWxlbnRSZW5ldyIsInN0YXJ0U2lsZW50UmVuZXciLCJtb25pdG9yU2Vzc2lvbiIsIl9zZXNzaW9uTW9uaXRvciIsIl90b2tlblJldm9jYXRpb25DbGllbnQiLCJfbG9hZFVzZXIiLCJyZW1vdmVVc2VyIiwic3RvcmVVc2VyIiwic2lnbmluUmVkaXJlY3QiLCJuYXZQYXJhbXMiLCJfc2lnbmluU3RhcnQiLCJfcmVkaXJlY3ROYXZpZ2F0b3IiLCJzaWduaW5SZWRpcmVjdENhbGxiYWNrIiwiX3NpZ25pbkVuZCIsInNpZ25pblBvcHVwIiwicG9wdXBfcmVkaXJlY3RfdXJpIiwiX3NpZ25pbiIsIl9wb3B1cE5hdmlnYXRvciIsInNpZ25pblBvcHVwQ2FsbGJhY2siLCJfc2lnbmluQ2FsbGJhY2siLCJfdXNlUmVmcmVzaFRva2VuIiwiaW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3IiwidmFsaWRhdGVTdWJPblNpbGVudFJlbmV3IiwiY3VycmVudF9zdWIiLCJfc2lnbmluU2lsZW50SWZyYW1lIiwiaWRUb2tlblZhbGlkYXRpb24iLCJfdmFsaWRhdGVJZFRva2VuRnJvbVRva2VuUmVmcmVzaFRva2VuIiwiYXV0aF90aW1lIiwic2lsZW50X3JlZGlyZWN0X3VyaSIsIl9pZnJhbWVOYXZpZ2F0b3IiLCJzaWduaW5TaWxlbnRDYWxsYmFjayIsInNpZ25pbkNhbGxiYWNrIiwic2lnbm91dENhbGxiYWNrIiwic2lnbm91dFJlZGlyZWN0Q2FsbGJhY2siLCJzaWdub3V0UG9wdXBDYWxsYmFjayIsInF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlIiwibmF2UmVzcG9uc2UiLCJzaWduaW5SZXNwb25zZSIsIm5hdmlnYXRvclBhcmFtcyIsInNpZ25vdXRSZWRpcmVjdCIsInBvc3RMb2dvdXRSZWRpcmVjdFVyaSIsIl9zaWdub3V0U3RhcnQiLCJfc2lnbm91dEVuZCIsInNpZ25vdXRQb3B1cCIsInBvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIl9zaWdub3V0IiwicmV2b2tlUHJvbWlzZSIsInJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0IiwiX3Jldm9rZUludGVybmFsIiwic2lnbm91dFJlcXVlc3QiLCJzaWdub3V0UmVzcG9uc2UiLCJyZXZva2VBY2Nlc3NUb2tlbiIsInN1Y2Nlc3MiLCJfcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbCIsIl9yZXZva2VSZWZyZXNoVG9rZW5JbnRlcm5hbCIsImF0U3VjY2VzcyIsInJ0U3VjY2VzcyIsInN0b3BTaWxlbnRSZW5ldyIsIl91c2VyU3RvcmUiLCJfdXNlclN0b3JlS2V5IiwicmVkaXJlY3ROYXZpZ2F0b3IiLCJwb3B1cE5hdmlnYXRvciIsImlmcmFtZU5hdmlnYXRvciIsInVzZXJTdG9yZSIsIl91c2VyTG9hZGVkIiwiX3VzZXJVbmxvYWRlZCIsIl9zaWxlbnRSZW5ld0Vycm9yIiwiX3VzZXJTaWduZWRJbiIsIl91c2VyU2lnbmVkT3V0IiwiX3VzZXJTZXNzaW9uQ2hhbmdlZCIsInJlbW92ZVVzZXJMb2FkZWQiLCJyZW1vdmVVc2VyVW5sb2FkZWQiLCJhZGRTaWxlbnRSZW5ld0Vycm9yIiwicmVtb3ZlU2lsZW50UmVuZXdFcnJvciIsImFkZFVzZXJTaWduZWRJbiIsInJlbW92ZVVzZXJTaWduZWRJbiIsImFkZFVzZXJTaWduZWRPdXQiLCJyZW1vdmVVc2VyU2lnbmVkT3V0IiwiYWRkVXNlclNlc3Npb25DaGFuZ2VkIiwicmVtb3ZlVXNlclNlc3Npb25DaGFuZ2VkIiwiRGVmYXVsdENoZWNrU2Vzc2lvbkludGVydmFsIiwic3RvcmUiLCJfcG9wdXBfcmVkaXJlY3RfdXJpIiwiX3BvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSIsIl9wb3B1cFdpbmRvd0ZlYXR1cmVzIiwiX3BvcHVwV2luZG93VGFyZ2V0IiwiX3NpbGVudF9yZWRpcmVjdF91cmkiLCJfc2lsZW50UmVxdWVzdFRpbWVvdXQiLCJfYXV0b21hdGljU2lsZW50UmVuZXciLCJfdmFsaWRhdGVTdWJPblNpbGVudFJlbmV3IiwiX2luY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyIsIl9tb25pdG9yU2Vzc2lvbiIsIl9tb25pdG9yQW5vbnltb3VzU2Vzc2lvbiIsIl9xdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZSIsIl9yZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCIsInByZWZpeCIsIl9zdG9yZSIsIl9wcmVmaXgiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrREFBMEMsZ0NBQWdDO0FBQzFFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0VBQXdELGtCQUFrQjtBQUMxRTtBQUNBLHlEQUFpRCxjQUFjO0FBQy9EOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBeUMsaUNBQWlDO0FBQzFFLHdIQUFnSCxtQkFBbUIsRUFBRTtBQUNySTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUEyQiwwQkFBMEIsRUFBRTtBQUN2RCx5Q0FBaUMsZUFBZTtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4REFBc0QsK0RBQStEOztBQUVySDtBQUNBOzs7QUFHQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDL0VBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQW5CQTtBQUNBOztrQkFvQmU7QUFDWEEsNkJBRFc7QUFFWEMsaUJBRlc7QUFHWEMsc0NBSFc7QUFJWEMsOERBSlc7QUFLWEMsb0VBTFc7QUFNWEMsOERBTlc7QUFPWEMseUNBUFc7QUFRWEMsMkRBUlc7QUFTWEMscURBVFc7QUFVWEMsdUVBVlc7QUFXWEMsMEVBWFc7QUFZWEMsOERBWlc7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QUNBLFlBQVk7QUFDWjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0EsV0FBVztBQUNYOztBQUVBO0FBQ0E7QUFDQSx3Q0FBd0MsV0FBVztBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsU0FBUztBQUNUO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQ0FBb0MsY0FBYztBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsaUNBQWlDLGtCQUFrQjtBQUNuRDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7O0FBRUE7QUFDQSxZQUFZO0FBQ1o7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSw4Q0FBOEMsUUFBUTtBQUN0RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUEsV0FBVztBQUNYO0FBQ0E7QUFDQTs7QUFFQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSw4Q0FBOEMsUUFBUTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLDhDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7OztBQy90Qlk7O0FBRVo7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyxTQUFTO0FBQzNDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBMEMsVUFBVTtBQUNwRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFWTs7QUFFWixhQUFhLG1CQUFPLENBQUMsb0RBQVc7QUFDaEMsY0FBYyxtQkFBTyxDQUFDLGdEQUFTO0FBQy9CLGNBQWMsbUJBQU8sQ0FBQyxvRUFBUzs7QUFFL0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtREFBbUQ7QUFDeEU7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixVQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsdUNBQXVDLFNBQVM7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLGlCQUFpQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFNBQVM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsRUFBRTtBQUNsRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZUFBZTtBQUN2QztBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBLHFCQUFxQixlQUFlO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixZQUFZO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EscUJBQXFCLFNBQVM7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHVEQUF1RCxPQUFPO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1REFBdUQsT0FBTztBQUM5RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFF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O0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTCxtREFBbUQ7QUFDbkQ7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTCxvQ0FBb0M7QUFDcEM7QUFDQSxLQUFLO0FBQ0wsd0VBQXdFO0FBQ3hFO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsOERBQThEO0FBQzlEO0FBQ0EsS0FBSztBQUNMLHdFQUF3RTtBQUN4RTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUgseUJBQXlCLHNCQUFzQixFQUFFLEVBQUU7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsNENBQTRDO0FBQzVDO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFdBQVc7QUFDbkI7QUFDQTtBQUNBLFFBQVEsVUFBVTtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsV0FBVztBQUNuQjtBQUNBO0FBQ0E7QUFDQSxRQUFRLFdBQVc7QUFDbkI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHlCQUF5QixtQkFBbUIsdUJBQXVCLEVBQUUsRUFBRTtBQUN2RTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixXQUFXO0FBQzVCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FB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QWtEO0FBQzFELG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsd0hBQTZDO0FBQ3JELG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsZ0hBQXlDO0FBQ2pELG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsd0dBQXFDO0FBQzdDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEdBQXNDO0FBQzlDLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsMEdBQXNDO0FBQzlDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsNEVBQXVCO0FBQy9CLG1CQUFPLENBQUMsb0VBQW1CO0FBQzNCLG1CQUFPLENBQUMsb0VBQW1CO0FBQzNCLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsZ0hBQXlDO0FBQ2pELG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsa0dBQWtDO0FBQzFDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsb0dBQW1DO0FBQzNDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsb0lBQW1EO0FBQzNELG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsd0dBQXFDO0FBQzdDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsa0hBQTBDO0FBQ2xELG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsZ0ZBQXlCO0FBQ2pDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsd0dBQXFDO0FBQzdDLG1CQUFPLENBQUMsZ0dBQWlDO0FBQ3pDLG1CQUFPLENBQUMsb0lBQW1EO0FBQzNELG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsMEVBQXNCO0FBQzlCLG1CQUFPLENBQUMsMEVBQXNCO0FBQzlCLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsOEVBQXdCO0FBQ2hDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEVBQXNCO0FBQzlCLG1CQUFPLENBQUMsd0ZBQTZCO0FBQ3JDLG1CQUFPLENBQUMsMEZBQThCO0FBQ3RDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsa0ZBQTBCO0FBQ2xDLG1CQUFPLENBQUMsc0ZBQTRCO0FBQ3BDLG1CQUFPLENBQUMsNEZBQStCO0FBQ3ZDLG1CQUFPLENBQUMsb0ZBQTJCO0FBQ25DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsNEdBQXVDO0FBQy9DLG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsZ0hBQXlDO0FBQ2pELG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsd0hBQTZDO0FBQ3JELG1CQUFPLENBQUMsc0dBQW9DO0FBQzVDLG1CQUFPLENBQUMsOEdBQXdDO0FBQ2hELG1CQUFPLENBQUMsOEZBQWdDO0FBQ3hDLG1C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QXpFLENBQTNCOztRQUdJaE4sRyxHQUFBQSxjO1FBQ0ErTSxPLEdBQUFBLGtCO1FBQ0FuUyxJLEdBQUFBLGU7UUFDQXBlLE0sR0FBQUEsaUI7UUFDQW1PLFMsR0FBQUEsb0I7UUFDQWhjLFEsR0FBQUEsbUI7UUFDQXErQixrQixHQUFBQSxrQjs7Ozs7Ozs7Ozs7Ozs7Ozs7a0JDTG9CNWtDLE07O0FBTnhCOzs7Ozs7QUFFQTs7OztBQUllLFNBQVNBLE1BQVQsR0FBa0I7QUFDL0IsU0FBTyxtQkFBUW1hLE9BQVIsQ0FBZ0IsSUFBaEIsRUFBc0IsRUFBdEIsQ0FBUDtBQUNEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNSRCxJQUFNemUsVUFBVSxRQUFoQixDLFFBQWtDQSxPLEdBQUFBLE8iLCJmaWxlIjoib2lkYy1jbGllbnQuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL3NyYy9Mb2cuanMnO1xyXG5pbXBvcnQgeyBPaWRjQ2xpZW50IH0gZnJvbSAnLi9zcmMvT2lkY0NsaWVudC5qcyc7XHJcbmltcG9ydCB7IE9pZGNDbGllbnRTZXR0aW5ncyB9IGZyb20gJy4vc3JjL09pZGNDbGllbnRTZXR0aW5ncy5qcyc7XHJcbmltcG9ydCB7IFdlYlN0b3JhZ2VTdGF0ZVN0b3JlIH0gZnJvbSAnLi9zcmMvV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMnO1xyXG5pbXBvcnQgeyBJbk1lbW9yeVdlYlN0b3JhZ2UgfSBmcm9tICcuL3NyYy9Jbk1lbW9yeVdlYlN0b3JhZ2UuanMnO1xyXG5pbXBvcnQgeyBVc2VyTWFuYWdlciB9IGZyb20gJy4vc3JjL1VzZXJNYW5hZ2VyLmpzJztcclxuaW1wb3J0IHsgQWNjZXNzVG9rZW5FdmVudHMgfSBmcm9tICcuL3NyYy9BY2Nlc3NUb2tlbkV2ZW50cy5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vc3JjL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IENvcmRvdmFQb3B1cE5hdmlnYXRvciB9IGZyb20gJy4vc3JjL0NvcmRvdmFQb3B1cE5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IENvcmRvdmFJRnJhbWVOYXZpZ2F0b3IgfSBmcm9tICcuL3NyYy9Db3Jkb3ZhSUZyYW1lTmF2aWdhdG9yLmpzJztcclxuaW1wb3J0IHsgQ2hlY2tTZXNzaW9uSUZyYW1lIH0gZnJvbSAnLi9zcmMvQ2hlY2tTZXNzaW9uSUZyYW1lLmpzJztcclxuaW1wb3J0IHsgVG9rZW5SZXZvY2F0aW9uQ2xpZW50IH0gZnJvbSAnLi9zcmMvVG9rZW5SZXZvY2F0aW9uQ2xpZW50LmpzJztcclxuaW1wb3J0IHsgU2Vzc2lvbk1vbml0b3IgfSBmcm9tICcuL3NyYy9TZXNzaW9uTW9uaXRvci5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vc3JjL0dsb2JhbC5qcyc7XHJcbmltcG9ydCB7IFVzZXIgfSBmcm9tICcuL3NyYy9Vc2VyLmpzJztcclxuXHJcbmltcG9ydCB7IFZlcnNpb24gfSBmcm9tICcuL3ZlcnNpb24uanMnO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgVmVyc2lvbixcclxuICAgIExvZyxcclxuICAgIE9pZGNDbGllbnQsXHJcbiAgICBPaWRjQ2xpZW50U2V0dGluZ3MsXHJcbiAgICBXZWJTdG9yYWdlU3RhdGVTdG9yZSxcclxuICAgIEluTWVtb3J5V2ViU3RvcmFnZSxcclxuICAgIFVzZXJNYW5hZ2VyLFxyXG4gICAgQWNjZXNzVG9rZW5FdmVudHMsXHJcbiAgICBNZXRhZGF0YVNlcnZpY2UsXHJcbiAgICBDb3Jkb3ZhUG9wdXBOYXZpZ2F0b3IsXHJcbiAgICBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yLFxyXG4gICAgQ2hlY2tTZXNzaW9uSUZyYW1lLFxyXG4gICAgVG9rZW5SZXZvY2F0aW9uQ2xpZW50LFxyXG4gICAgU2Vzc2lvbk1vbml0b3IsXHJcbiAgICBHbG9iYWwsXHJcbiAgICBVc2VyXHJcbn07XHJcbiIsIi8qXHJcbiAqIGpzcnNhc2lnbihhbGwpIDguMC4xMiAoMjAxOC0wNC0yMikgKGMpIDIwMTAtMjAxOCBLZW5qaSBVcnVzaGltYSB8IGtqdXIuZ2l0aHViLmNvbS9qc3JzYXNpZ24vbGljZW5zZVxyXG4gKi9cclxuXHJcbnZhciBuYXZpZ2F0b3IgPSB7fTtcclxubmF2aWdhdG9yLnVzZXJBZ2VudCA9IGZhbHNlO1xyXG5cclxudmFyIHdpbmRvdyA9IHt9O1xyXG5cbi8qIVxyXG5Db3B5cmlnaHQgKGMpIDIwMTEsIFlhaG9vISBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbkNvZGUgbGljZW5zZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlOlxyXG5odHRwOi8vZGV2ZWxvcGVyLnlhaG9vLmNvbS95dWkvbGljZW5zZS5odG1sXHJcbnZlcnNpb246IDIuOS4wXHJcbiovXHJcbmlmKFlBSE9PPT09dW5kZWZpbmVkKXt2YXIgWUFIT089e319WUFIT08ubGFuZz17ZXh0ZW5kOmZ1bmN0aW9uKGcsaCxmKXtpZighaHx8IWcpe3Rocm93IG5ldyBFcnJvcihcIllBSE9PLmxhbmcuZXh0ZW5kIGZhaWxlZCwgcGxlYXNlIGNoZWNrIHRoYXQgYWxsIGRlcGVuZGVuY2llcyBhcmUgaW5jbHVkZWQuXCIpfXZhciBkPWZ1bmN0aW9uKCl7fTtkLnByb3RvdHlwZT1oLnByb3RvdHlwZTtnLnByb3RvdHlwZT1uZXcgZCgpO2cucHJvdG90eXBlLmNvbnN0cnVjdG9yPWc7Zy5zdXBlcmNsYXNzPWgucHJvdG90eXBlO2lmKGgucHJvdG90eXBlLmNvbnN0cnVjdG9yPT1PYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yKXtoLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1ofWlmKGYpe3ZhciBiO2ZvcihiIGluIGYpe2cucHJvdG90eXBlW2JdPWZbYl19dmFyIGU9ZnVuY3Rpb24oKXt9LGM9W1widG9TdHJpbmdcIixcInZhbHVlT2ZcIl07dHJ5e2lmKC9NU0lFLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKXtlPWZ1bmN0aW9uKGosaSl7Zm9yKGI9MDtiPGMubGVuZ3RoO2I9YisxKXt2YXIgbD1jW2JdLGs9aVtsXTtpZih0eXBlb2Ygaz09PVwiZnVuY3Rpb25cIiYmayE9T2JqZWN0LnByb3RvdHlwZVtsXSl7altsXT1rfX19fX1jYXRjaChhKXt9ZShnLnByb3RvdHlwZSxmKX19fTtcbi8qISBDcnlwdG9KUyB2My4xLjIgY29yZS1maXguanNcclxuICogY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbiAqIChjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKiBjb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiAqIFRISVMgSVMgRklYIG9mICdjb3JlLmpzJyB0byBmaXggSG1hYyBpc3N1ZS5cclxuICogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvaXNzdWVzL2RldGFpbD9pZD04NFxyXG4gKiBodHRwczovL2NyeXB0by1qcy5nb29nbGVjb2RlLmNvbS9zdm4taGlzdG9yeS9yNjY3L2JyYW5jaGVzLzMueC9zcmMvY29yZS5qc1xyXG4gKi9cclxudmFyIENyeXB0b0pTPUNyeXB0b0pTfHwoZnVuY3Rpb24oZSxnKXt2YXIgYT17fTt2YXIgYj1hLmxpYj17fTt2YXIgaj1iLkJhc2U9KGZ1bmN0aW9uKCl7ZnVuY3Rpb24gbigpe31yZXR1cm57ZXh0ZW5kOmZ1bmN0aW9uKHApe24ucHJvdG90eXBlPXRoaXM7dmFyIG89bmV3IG4oKTtpZihwKXtvLm1peEluKHApfWlmKCFvLmhhc093blByb3BlcnR5KFwiaW5pdFwiKSl7by5pbml0PWZ1bmN0aW9uKCl7by4kc3VwZXIuaW5pdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fW8uaW5pdC5wcm90b3R5cGU9bztvLiRzdXBlcj10aGlzO3JldHVybiBvfSxjcmVhdGU6ZnVuY3Rpb24oKXt2YXIgbz10aGlzLmV4dGVuZCgpO28uaW5pdC5hcHBseShvLGFyZ3VtZW50cyk7cmV0dXJuIG99LGluaXQ6ZnVuY3Rpb24oKXt9LG1peEluOmZ1bmN0aW9uKHApe2Zvcih2YXIgbyBpbiBwKXtpZihwLmhhc093blByb3BlcnR5KG8pKXt0aGlzW29dPXBbb119fWlmKHAuaGFzT3duUHJvcGVydHkoXCJ0b1N0cmluZ1wiKSl7dGhpcy50b1N0cmluZz1wLnRvU3RyaW5nfX0sY2xvbmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pbml0LnByb3RvdHlwZS5leHRlbmQodGhpcyl9fX0oKSk7dmFyIGw9Yi5Xb3JkQXJyYXk9ai5leHRlbmQoe2luaXQ6ZnVuY3Rpb24obyxuKXtvPXRoaXMud29yZHM9b3x8W107aWYobiE9Zyl7dGhpcy5zaWdCeXRlcz1ufWVsc2V7dGhpcy5zaWdCeXRlcz1vLmxlbmd0aCo0fX0sdG9TdHJpbmc6ZnVuY3Rpb24obil7cmV0dXJuKG58fGgpLnN0cmluZ2lmeSh0aGlzKX0sY29uY2F0OmZ1bmN0aW9uKHQpe3ZhciBxPXRoaXMud29yZHM7dmFyIHA9dC53b3Jkczt2YXIgbj10aGlzLnNpZ0J5dGVzO3ZhciBzPXQuc2lnQnl0ZXM7dGhpcy5jbGFtcCgpO2lmKG4lNCl7Zm9yKHZhciByPTA7cjxzO3IrKyl7dmFyIG89KHBbcj4+PjJdPj4+KDI0LShyJTQpKjgpKSYyNTU7cVsobityKT4+PjJdfD1vPDwoMjQtKChuK3IpJTQpKjgpfX1lbHNle2Zvcih2YXIgcj0wO3I8cztyKz00KXtxWyhuK3IpPj4+Ml09cFtyPj4+Ml19fXRoaXMuc2lnQnl0ZXMrPXM7cmV0dXJuIHRoaXN9LGNsYW1wOmZ1bmN0aW9uKCl7dmFyIG89dGhpcy53b3Jkczt2YXIgbj10aGlzLnNpZ0J5dGVzO29bbj4+PjJdJj00Mjk0OTY3Mjk1PDwoMzItKG4lNCkqOCk7by5sZW5ndGg9ZS5jZWlsKG4vNCl9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIG49ai5jbG9uZS5jYWxsKHRoaXMpO24ud29yZHM9dGhpcy53b3Jkcy5zbGljZSgwKTtyZXR1cm4gbn0scmFuZG9tOmZ1bmN0aW9uKHApe3ZhciBvPVtdO2Zvcih2YXIgbj0wO248cDtuKz00KXtvLnB1c2goKGUucmFuZG9tKCkqNDI5NDk2NzI5Nil8MCl9cmV0dXJuIG5ldyBsLmluaXQobyxwKX19KTt2YXIgbT1hLmVuYz17fTt2YXIgaD1tLkhleD17c3RyaW5naWZ5OmZ1bmN0aW9uKHApe3ZhciByPXAud29yZHM7dmFyIG89cC5zaWdCeXRlczt2YXIgcT1bXTtmb3IodmFyIG49MDtuPG87bisrKXt2YXIgcz0ocltuPj4+Ml0+Pj4oMjQtKG4lNCkqOCkpJjI1NTtxLnB1c2goKHM+Pj40KS50b1N0cmluZygxNikpO3EucHVzaCgocyYxNSkudG9TdHJpbmcoMTYpKX1yZXR1cm4gcS5qb2luKFwiXCIpfSxwYXJzZTpmdW5jdGlvbihwKXt2YXIgbj1wLmxlbmd0aDt2YXIgcT1bXTtmb3IodmFyIG89MDtvPG47bys9Mil7cVtvPj4+M118PXBhcnNlSW50KHAuc3Vic3RyKG8sMiksMTYpPDwoMjQtKG8lOCkqNCl9cmV0dXJuIG5ldyBsLmluaXQocSxuLzIpfX07dmFyIGQ9bS5MYXRpbjE9e3N0cmluZ2lmeTpmdW5jdGlvbihxKXt2YXIgcj1xLndvcmRzO3ZhciBwPXEuc2lnQnl0ZXM7dmFyIG49W107Zm9yKHZhciBvPTA7bzxwO28rKyl7dmFyIHM9KHJbbz4+PjJdPj4+KDI0LShvJTQpKjgpKSYyNTU7bi5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUocykpfXJldHVybiBuLmpvaW4oXCJcIil9LHBhcnNlOmZ1bmN0aW9uKHApe3ZhciBuPXAubGVuZ3RoO3ZhciBxPVtdO2Zvcih2YXIgbz0wO288bjtvKyspe3Fbbz4+PjJdfD0ocC5jaGFyQ29kZUF0KG8pJjI1NSk8PCgyNC0obyU0KSo4KX1yZXR1cm4gbmV3IGwuaW5pdChxLG4pfX07dmFyIGM9bS5VdGY4PXtzdHJpbmdpZnk6ZnVuY3Rpb24obil7dHJ5e3JldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKGQuc3RyaW5naWZ5KG4pKSl9Y2F0Y2gobyl7dGhyb3cgbmV3IEVycm9yKFwiTWFsZm9ybWVkIFVURi04IGRhdGFcIil9fSxwYXJzZTpmdW5jdGlvbihuKXtyZXR1cm4gZC5wYXJzZSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQobikpKX19O3ZhciBpPWIuQnVmZmVyZWRCbG9ja0FsZ29yaXRobT1qLmV4dGVuZCh7cmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLl9kYXRhPW5ldyBsLmluaXQoKTt0aGlzLl9uRGF0YUJ5dGVzPTB9LF9hcHBlbmQ6ZnVuY3Rpb24obil7aWYodHlwZW9mIG49PVwic3RyaW5nXCIpe249Yy5wYXJzZShuKX10aGlzLl9kYXRhLmNvbmNhdChuKTt0aGlzLl9uRGF0YUJ5dGVzKz1uLnNpZ0J5dGVzfSxfcHJvY2VzczpmdW5jdGlvbih3KXt2YXIgcT10aGlzLl9kYXRhO3ZhciB4PXEud29yZHM7dmFyIG49cS5zaWdCeXRlczt2YXIgdD10aGlzLmJsb2NrU2l6ZTt2YXIgdj10KjQ7dmFyIHU9bi92O2lmKHcpe3U9ZS5jZWlsKHUpfWVsc2V7dT1lLm1heCgodXwwKS10aGlzLl9taW5CdWZmZXJTaXplLDApfXZhciBzPXUqdDt2YXIgcj1lLm1pbihzKjQsbik7aWYocyl7Zm9yKHZhciBwPTA7cDxzO3ArPXQpe3RoaXMuX2RvUHJvY2Vzc0Jsb2NrKHgscCl9dmFyIG89eC5zcGxpY2UoMCxzKTtxLnNpZ0J5dGVzLT1yfXJldHVybiBuZXcgbC5pbml0KG8scil9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIG49ai5jbG9uZS5jYWxsKHRoaXMpO24uX2RhdGE9dGhpcy5fZGF0YS5jbG9uZSgpO3JldHVybiBufSxfbWluQnVmZmVyU2l6ZTowfSk7dmFyIGY9Yi5IYXNoZXI9aS5leHRlbmQoe2NmZzpqLmV4dGVuZCgpLGluaXQ6ZnVuY3Rpb24obil7dGhpcy5jZmc9dGhpcy5jZmcuZXh0ZW5kKG4pO3RoaXMucmVzZXQoKX0scmVzZXQ6ZnVuY3Rpb24oKXtpLnJlc2V0LmNhbGwodGhpcyk7dGhpcy5fZG9SZXNldCgpfSx1cGRhdGU6ZnVuY3Rpb24obil7dGhpcy5fYXBwZW5kKG4pO3RoaXMuX3Byb2Nlc3MoKTtyZXR1cm4gdGhpc30sZmluYWxpemU6ZnVuY3Rpb24obil7aWYobil7dGhpcy5fYXBwZW5kKG4pfXZhciBvPXRoaXMuX2RvRmluYWxpemUoKTtyZXR1cm4gb30sYmxvY2tTaXplOjUxMi8zMixfY3JlYXRlSGVscGVyOmZ1bmN0aW9uKG4pe3JldHVybiBmdW5jdGlvbihwLG8pe3JldHVybiBuZXcgbi5pbml0KG8pLmZpbmFsaXplKHApfX0sX2NyZWF0ZUhtYWNIZWxwZXI6ZnVuY3Rpb24obil7cmV0dXJuIGZ1bmN0aW9uKHAsbyl7cmV0dXJuIG5ldyBrLkhNQUMuaW5pdChuLG8pLmZpbmFsaXplKHApfX19KTt2YXIgaz1hLmFsZ289e307cmV0dXJuIGF9KE1hdGgpKTtcbi8qXHJcbkNyeXB0b0pTIHYzLjEuMiB4NjQtY29yZS1taW4uanNcclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbihjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiovXHJcbihmdW5jdGlvbihnKXt2YXIgYT1DcnlwdG9KUyxmPWEubGliLGU9Zi5CYXNlLGg9Zi5Xb3JkQXJyYXksYT1hLng2ND17fTthLldvcmQ9ZS5leHRlbmQoe2luaXQ6ZnVuY3Rpb24oYixjKXt0aGlzLmhpZ2g9Yjt0aGlzLmxvdz1jfX0pO2EuV29yZEFycmF5PWUuZXh0ZW5kKHtpbml0OmZ1bmN0aW9uKGIsYyl7Yj10aGlzLndvcmRzPWJ8fFtdO3RoaXMuc2lnQnl0ZXM9YyE9Zz9jOjgqYi5sZW5ndGh9LHRvWDMyOmZ1bmN0aW9uKCl7Zm9yKHZhciBiPXRoaXMud29yZHMsYz1iLmxlbmd0aCxhPVtdLGQ9MDtkPGM7ZCsrKXt2YXIgZT1iW2RdO2EucHVzaChlLmhpZ2gpO2EucHVzaChlLmxvdyl9cmV0dXJuIGguY3JlYXRlKGEsdGhpcy5zaWdCeXRlcyl9LGNsb25lOmZ1bmN0aW9uKCl7Zm9yKHZhciBiPWUuY2xvbmUuY2FsbCh0aGlzKSxjPWIud29yZHM9dGhpcy53b3Jkcy5zbGljZSgwKSxhPWMubGVuZ3RoLGQ9MDtkPGE7ZCsrKWNbZF09Y1tkXS5jbG9uZSgpO3JldHVybiBifX0pfSkoKTtcclxuXG4vKlxyXG5DcnlwdG9KUyB2My4xLjIgZW5jLWJhc2U2NC5qc1xyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanNcclxuKGMpIDIwMDktMjAxMyBieSBKZWZmIE1vdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcclxuKi9cclxuKGZ1bmN0aW9uKCl7dmFyIGg9Q3J5cHRvSlMsaj1oLmxpYi5Xb3JkQXJyYXk7aC5lbmMuQmFzZTY0PXtzdHJpbmdpZnk6ZnVuY3Rpb24oYil7dmFyIGU9Yi53b3JkcyxmPWIuc2lnQnl0ZXMsYz10aGlzLl9tYXA7Yi5jbGFtcCgpO2I9W107Zm9yKHZhciBhPTA7YTxmO2ErPTMpZm9yKHZhciBkPShlW2E+Pj4yXT4+PjI0LTgqKGElNCkmMjU1KTw8MTZ8KGVbYSsxPj4+Ml0+Pj4yNC04KigoYSsxKSU0KSYyNTUpPDw4fGVbYSsyPj4+Ml0+Pj4yNC04KigoYSsyKSU0KSYyNTUsZz0wOzQ+ZyYmYSswLjc1Kmc8ZjtnKyspYi5wdXNoKGMuY2hhckF0KGQ+Pj42KigzLWcpJjYzKSk7aWYoZT1jLmNoYXJBdCg2NCkpZm9yKDtiLmxlbmd0aCU0OyliLnB1c2goZSk7cmV0dXJuIGIuam9pbihcIlwiKX0scGFyc2U6ZnVuY3Rpb24oYil7dmFyIGU9Yi5sZW5ndGgsZj10aGlzLl9tYXAsYz1mLmNoYXJBdCg2NCk7YyYmKGM9Yi5pbmRleE9mKGMpLC0xIT1jJiYoZT1jKSk7Zm9yKHZhciBjPVtdLGE9MCxkPTA7ZDxcclxuZTtkKyspaWYoZCU0KXt2YXIgZz1mLmluZGV4T2YoYi5jaGFyQXQoZC0xKSk8PDIqKGQlNCksaD1mLmluZGV4T2YoYi5jaGFyQXQoZCkpPj4+Ni0yKihkJTQpO2NbYT4+PjJdfD0oZ3xoKTw8MjQtOCooYSU0KTthKyt9cmV0dXJuIGouY3JlYXRlKGMsYSl9LF9tYXA6XCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwifX0pKCk7XHJcblxuLypcclxuQ3J5cHRvSlMgdjMuMS4yIHNoYTI1Ni1taW4uanNcclxuY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXHJcbihjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXHJcbiovXHJcbihmdW5jdGlvbihrKXtmb3IodmFyIGc9Q3J5cHRvSlMsaD1nLmxpYix2PWguV29yZEFycmF5LGo9aC5IYXNoZXIsaD1nLmFsZ28scz1bXSx0PVtdLHU9ZnVuY3Rpb24ocSl7cmV0dXJuIDQyOTQ5NjcyOTYqKHEtKHF8MCkpfDB9LGw9MixiPTA7NjQ+Yjspe3ZhciBkO2E6e2Q9bDtmb3IodmFyIHc9ay5zcXJ0KGQpLHI9MjtyPD13O3IrKylpZighKGQlcikpe2Q9ITE7YnJlYWsgYX1kPSEwfWQmJig4PmImJihzW2JdPXUoay5wb3cobCwwLjUpKSksdFtiXT11KGsucG93KGwsMS8zKSksYisrKTtsKyt9dmFyIG49W10saD1oLlNIQTI1Nj1qLmV4dGVuZCh7X2RvUmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLl9oYXNoPW5ldyB2LmluaXQocy5zbGljZSgwKSl9LF9kb1Byb2Nlc3NCbG9jazpmdW5jdGlvbihxLGgpe2Zvcih2YXIgYT10aGlzLl9oYXNoLndvcmRzLGM9YVswXSxkPWFbMV0sYj1hWzJdLGs9YVszXSxmPWFbNF0sZz1hWzVdLGo9YVs2XSxsPWFbN10sZT0wOzY0PmU7ZSsrKXtpZigxNj5lKW5bZV09XHJcbnFbaCtlXXwwO2Vsc2V7dmFyIG09bltlLTE1XSxwPW5bZS0yXTtuW2VdPSgobTw8MjV8bT4+PjcpXihtPDwxNHxtPj4+MTgpXm0+Pj4zKStuW2UtN10rKChwPDwxNXxwPj4+MTcpXihwPDwxM3xwPj4+MTkpXnA+Pj4xMCkrbltlLTE2XX1tPWwrKChmPDwyNnxmPj4+NileKGY8PDIxfGY+Pj4xMSleKGY8PDd8Zj4+PjI1KSkrKGYmZ15+ZiZqKSt0W2VdK25bZV07cD0oKGM8PDMwfGM+Pj4yKV4oYzw8MTl8Yz4+PjEzKV4oYzw8MTB8Yz4+PjIyKSkrKGMmZF5jJmJeZCZiKTtsPWo7aj1nO2c9ZjtmPWsrbXwwO2s9YjtiPWQ7ZD1jO2M9bStwfDB9YVswXT1hWzBdK2N8MDthWzFdPWFbMV0rZHwwO2FbMl09YVsyXStifDA7YVszXT1hWzNdK2t8MDthWzRdPWFbNF0rZnwwO2FbNV09YVs1XStnfDA7YVs2XT1hWzZdK2p8MDthWzddPWFbN10rbHwwfSxfZG9GaW5hbGl6ZTpmdW5jdGlvbigpe3ZhciBkPXRoaXMuX2RhdGEsYj1kLndvcmRzLGE9OCp0aGlzLl9uRGF0YUJ5dGVzLGM9OCpkLnNpZ0J5dGVzO1xyXG5iW2M+Pj41XXw9MTI4PDwyNC1jJTMyO2JbKGMrNjQ+Pj45PDw0KSsxNF09ay5mbG9vcihhLzQyOTQ5NjcyOTYpO2JbKGMrNjQ+Pj45PDw0KSsxNV09YTtkLnNpZ0J5dGVzPTQqYi5sZW5ndGg7dGhpcy5fcHJvY2VzcygpO3JldHVybiB0aGlzLl9oYXNofSxjbG9uZTpmdW5jdGlvbigpe3ZhciBiPWouY2xvbmUuY2FsbCh0aGlzKTtiLl9oYXNoPXRoaXMuX2hhc2guY2xvbmUoKTtyZXR1cm4gYn19KTtnLlNIQTI1Nj1qLl9jcmVhdGVIZWxwZXIoaCk7Zy5IbWFjU0hBMjU2PWouX2NyZWF0ZUhtYWNIZWxwZXIoaCl9KShNYXRoKTtcclxuXG4vKlxyXG5DcnlwdG9KUyB2My4xLjIgc2hhNTEyLW1pbi5qc1xyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanNcclxuKGMpIDIwMDktMjAxMyBieSBKZWZmIE1vdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcclxuKi9cclxuKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gYSgpe3JldHVybiBkLmNyZWF0ZS5hcHBseShkLGFyZ3VtZW50cyl9Zm9yKHZhciBuPUNyeXB0b0pTLHI9bi5saWIuSGFzaGVyLGU9bi54NjQsZD1lLldvcmQsVD1lLldvcmRBcnJheSxlPW4uYWxnbyxlYT1bYSgxMTE2MzUyNDA4LDM2MDk3Njc0NTgpLGEoMTg5OTQ0NzQ0MSw2MDI4OTE3MjUpLGEoMzA0OTMyMzQ3MSwzOTY0NDg0Mzk5KSxhKDM5MjEwMDk1NzMsMjE3MzI5NTU0OCksYSg5NjE5ODcxNjMsNDA4MTYyODQ3MiksYSgxNTA4OTcwOTkzLDMwNTM4MzQyNjUpLGEoMjQ1MzYzNTc0OCwyOTM3NjcxNTc5KSxhKDI4NzA3NjMyMjEsMzY2NDYwOTU2MCksYSgzNjI0MzgxMDgwLDI3MzQ4ODMzOTQpLGEoMzEwNTk4NDAxLDExNjQ5OTY1NDIpLGEoNjA3MjI1Mjc4LDEzMjM2MTA3NjQpLGEoMTQyNjg4MTk4NywzNTkwMzA0OTk0KSxhKDE5MjUwNzgzODgsNDA2ODE4MjM4MyksYSgyMTYyMDc4MjA2LDk5MTMzNjExMyksYSgyNjE0ODg4MTAzLDYzMzgwMzMxNyksXHJcbmEoMzI0ODIyMjU4MCwzNDc5Nzc0ODY4KSxhKDM4MzUzOTA0MDEsMjY2NjYxMzQ1OCksYSg0MDIyMjI0Nzc0LDk0NDcxMTEzOSksYSgyNjQzNDcwNzgsMjM0MTI2Mjc3MyksYSg2MDQ4MDc2MjgsMjAwNzgwMDkzMyksYSg3NzAyNTU5ODMsMTQ5NTk5MDkwMSksYSgxMjQ5MTUwMTIyLDE4NTY0MzEyMzUpLGEoMTU1NTA4MTY5MiwzMTc1MjE4MTMyKSxhKDE5OTYwNjQ5ODYsMjE5ODk1MDgzNyksYSgyNTU0MjIwODgyLDM5OTk3MTkzMzkpLGEoMjgyMTgzNDM0OSw3NjY3ODQwMTYpLGEoMjk1Mjk5NjgwOCwyNTY2NTk0ODc5KSxhKDMyMTAzMTM2NzEsMzIwMzMzNzk1NiksYSgzMzM2NTcxODkxLDEwMzQ0NTcwMjYpLGEoMzU4NDUyODcxMSwyNDY2OTQ4OTAxKSxhKDExMzkyNjk5MywzNzU4MzI2MzgzKSxhKDMzODI0MTg5NSwxNjg3MTc5MzYpLGEoNjY2MzA3MjA1LDExODgxNzk5NjQpLGEoNzczNTI5OTEyLDE1NDYwNDU3MzQpLGEoMTI5NDc1NzM3MiwxNTIyODA1NDg1KSxhKDEzOTYxODIyOTEsXHJcbjI2NDM4MzM4MjMpLGEoMTY5NTE4MzcwMCwyMzQzNTI3MzkwKSxhKDE5ODY2NjEwNTEsMTAxNDQ3NzQ4MCksYSgyMTc3MDI2MzUwLDEyMDY3NTkxNDIpLGEoMjQ1Njk1NjAzNywzNDQwNzc2MjcpLGEoMjczMDQ4NTkyMSwxMjkwODYzNDYwKSxhKDI4MjAzMDI0MTEsMzE1ODQ1NDI3MyksYSgzMjU5NzMwODAwLDM1MDU5NTI2NTcpLGEoMzM0NTc2NDc3MSwxMDYyMTcwMDgpLGEoMzUxNjA2NTgxNywzNjA2MDA4MzQ0KSxhKDM2MDAzNTI4MDQsMTQzMjcyNTc3NiksYSg0MDk0NTcxOTA5LDE0NjcwMzE1OTQpLGEoMjc1NDIzMzQ0LDg1MTE2OTcyMCksYSg0MzAyMjc3MzQsMzEwMDgyMzc1MiksYSg1MDY5NDg2MTYsMTM2MzI1ODE5NSksYSg2NTkwNjA1NTYsMzc1MDY4NTU5MyksYSg4ODM5OTc4NzcsMzc4NTA1MDI4MCksYSg5NTgxMzk1NzEsMzMxODMwNzQyNyksYSgxMzIyODIyMjE4LDM4MTI3MjM0MDMpLGEoMTUzNzAwMjA2MywyMDAzMDM0OTk1KSxhKDE3NDc4NzM3NzksMzYwMjAzNjg5OSksXHJcbmEoMTk1NTU2MjIyMiwxNTc1OTkwMDEyKSxhKDIwMjQxMDQ4MTUsMTEyNTU5MjkyOCksYSgyMjI3NzMwNDUyLDI3MTY5MDQzMDYpLGEoMjM2MTg1MjQyNCw0NDI3NzYwNDQpLGEoMjQyODQzNjQ3NCw1OTM2OTgzNDQpLGEoMjc1NjczNDE4NywzNzMzMTEwMjQ5KSxhKDMyMDQwMzE0NzksMjk5OTM1MTU3MyksYSgzMzI5MzI1Mjk4LDM4MTU5MjA0MjcpLGEoMzM5MTU2OTYxNCwzOTI4MzgzOTAwKSxhKDM1MTUyNjcyNzEsNTY2MjgwNzExKSxhKDM5NDAxODc2MDYsMzQ1NDA2OTUzNCksYSg0MTE4NjMwMjcxLDQwMDAyMzk5OTIpLGEoMTE2NDE4NDc0LDE5MTQxMzg1NTQpLGEoMTc0MjkyNDIxLDI3MzEwNTUyNzApLGEoMjg5MzgwMzU2LDMyMDM5OTMwMDYpLGEoNDYwMzkzMjY5LDMyMDYyMDMxNSksYSg2ODU0NzE3MzMsNTg3NDk2ODM2KSxhKDg1MjE0Mjk3MSwxMDg2NzkyODUxKSxhKDEwMTcwMzYyOTgsMzY1NTQzMTAwKSxhKDExMjYwMDA1ODAsMjYxODI5NzY3NiksYSgxMjg4MDMzNDcwLFxyXG4zNDA5ODU1MTU4KSxhKDE1MDE1MDU5NDgsNDIzNDUwOTg2NiksYSgxNjA3MTY3OTE1LDk4NzE2NzQ2OCksYSgxODE2NDAyMzE2LDEyNDYxODk1OTEpXSx2PVtdLHc9MDs4MD53O3crKyl2W3ddPWEoKTtlPWUuU0hBNTEyPXIuZXh0ZW5kKHtfZG9SZXNldDpmdW5jdGlvbigpe3RoaXMuX2hhc2g9bmV3IFQuaW5pdChbbmV3IGQuaW5pdCgxNzc5MDMzNzAzLDQwODkyMzU3MjApLG5ldyBkLmluaXQoMzE0NDEzNDI3NywyMjI3ODczNTk1KSxuZXcgZC5pbml0KDEwMTM5MDQyNDIsNDI3MTE3NTcyMyksbmV3IGQuaW5pdCgyNzczNDgwNzYyLDE1OTU3NTAxMjkpLG5ldyBkLmluaXQoMTM1OTg5MzExOSwyOTE3NTY1MTM3KSxuZXcgZC5pbml0KDI2MDA4MjI5MjQsNzI1NTExMTk5KSxuZXcgZC5pbml0KDUyODczNDYzNSw0MjE1Mzg5NTQ3KSxuZXcgZC5pbml0KDE1NDE0NTkyMjUsMzI3MDMzMjA5KV0pfSxfZG9Qcm9jZXNzQmxvY2s6ZnVuY3Rpb24oYSxkKXtmb3IodmFyIGY9dGhpcy5faGFzaC53b3JkcyxcclxuRj1mWzBdLGU9ZlsxXSxuPWZbMl0scj1mWzNdLEc9Zls0XSxIPWZbNV0sST1mWzZdLGY9Zls3XSx3PUYuaGlnaCxKPUYubG93LFg9ZS5oaWdoLEs9ZS5sb3csWT1uLmhpZ2gsTD1uLmxvdyxaPXIuaGlnaCxNPXIubG93LCQ9Ry5oaWdoLE49Ry5sb3csYWE9SC5oaWdoLE89SC5sb3csYmE9SS5oaWdoLFA9SS5sb3csY2E9Zi5oaWdoLFE9Zi5sb3csaz13LGc9Six6PVgseD1LLEE9WSx5PUwsVT1aLEI9TSxsPSQsaD1OLFI9YWEsQz1PLFM9YmEsRD1QLFY9Y2EsRT1RLG09MDs4MD5tO20rKyl7dmFyIHM9dlttXTtpZigxNj5tKXZhciBqPXMuaGlnaD1hW2QrMiptXXwwLGI9cy5sb3c9YVtkKzIqbSsxXXwwO2Vsc2V7dmFyIGo9dlttLTE1XSxiPWouaGlnaCxwPWoubG93LGo9KGI+Pj4xfHA8PDMxKV4oYj4+Pjh8cDw8MjQpXmI+Pj43LHA9KHA+Pj4xfGI8PDMxKV4ocD4+Pjh8Yjw8MjQpXihwPj4+N3xiPDwyNSksdT12W20tMl0sYj11LmhpZ2gsYz11Lmxvdyx1PShiPj4+MTl8Yzw8MTMpXihiPDxcclxuM3xjPj4+MjkpXmI+Pj42LGM9KGM+Pj4xOXxiPDwxMyleKGM8PDN8Yj4+PjI5KV4oYz4+PjZ8Yjw8MjYpLGI9dlttLTddLFc9Yi5oaWdoLHQ9dlttLTE2XSxxPXQuaGlnaCx0PXQubG93LGI9cCtiLmxvdyxqPWorVysoYj4+PjA8cD4+PjA/MTowKSxiPWIrYyxqPWordSsoYj4+PjA8Yz4+PjA/MTowKSxiPWIrdCxqPWorcSsoYj4+PjA8dD4+PjA/MTowKTtzLmhpZ2g9ajtzLmxvdz1ifXZhciBXPWwmUl5+bCZTLHQ9aCZDXn5oJkQscz1rJnpeayZBXnomQSxUPWcmeF5nJnleeCZ5LHA9KGs+Pj4yOHxnPDw0KV4oazw8MzB8Zz4+PjIpXihrPDwyNXxnPj4+NyksdT0oZz4+PjI4fGs8PDQpXihnPDwzMHxrPj4+MileKGc8PDI1fGs+Pj43KSxjPWVhW21dLGZhPWMuaGlnaCxkYT1jLmxvdyxjPUUrKChoPj4+MTR8bDw8MTgpXihoPj4+MTh8bDw8MTQpXihoPDwyM3xsPj4+OSkpLHE9VisoKGw+Pj4xNHxoPDwxOCleKGw+Pj4xOHxoPDwxNCleKGw8PDIzfGg+Pj45KSkrKGM+Pj4wPEU+Pj4wPzE6XHJcbjApLGM9Yyt0LHE9cStXKyhjPj4+MDx0Pj4+MD8xOjApLGM9YytkYSxxPXErZmErKGM+Pj4wPGRhPj4+MD8xOjApLGM9YytiLHE9cStqKyhjPj4+MDxiPj4+MD8xOjApLGI9dStULHM9cCtzKyhiPj4+MDx1Pj4+MD8xOjApLFY9UyxFPUQsUz1SLEQ9QyxSPWwsQz1oLGg9QitjfDAsbD1VK3ErKGg+Pj4wPEI+Pj4wPzE6MCl8MCxVPUEsQj15LEE9eix5PXgsej1rLHg9ZyxnPWMrYnwwLGs9cStzKyhnPj4+MDxjPj4+MD8xOjApfDB9Sj1GLmxvdz1KK2c7Ri5oaWdoPXcraysoSj4+PjA8Zz4+PjA/MTowKTtLPWUubG93PUsreDtlLmhpZ2g9WCt6KyhLPj4+MDx4Pj4+MD8xOjApO0w9bi5sb3c9TCt5O24uaGlnaD1ZK0ErKEw+Pj4wPHk+Pj4wPzE6MCk7TT1yLmxvdz1NK0I7ci5oaWdoPVorVSsoTT4+PjA8Qj4+PjA/MTowKTtOPUcubG93PU4raDtHLmhpZ2g9JCtsKyhOPj4+MDxoPj4+MD8xOjApO089SC5sb3c9TytDO0guaGlnaD1hYStSKyhPPj4+MDxDPj4+MD8xOjApO1A9SS5sb3c9UCtEO1xyXG5JLmhpZ2g9YmErUysoUD4+PjA8RD4+PjA/MTowKTtRPWYubG93PVErRTtmLmhpZ2g9Y2ErVisoUT4+PjA8RT4+PjA/MTowKX0sX2RvRmluYWxpemU6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLl9kYXRhLGQ9YS53b3JkcyxmPTgqdGhpcy5fbkRhdGFCeXRlcyxlPTgqYS5zaWdCeXRlcztkW2U+Pj41XXw9MTI4PDwyNC1lJTMyO2RbKGUrMTI4Pj4+MTA8PDUpKzMwXT1NYXRoLmZsb29yKGYvNDI5NDk2NzI5Nik7ZFsoZSsxMjg+Pj4xMDw8NSkrMzFdPWY7YS5zaWdCeXRlcz00KmQubGVuZ3RoO3RoaXMuX3Byb2Nlc3MoKTtyZXR1cm4gdGhpcy5faGFzaC50b1gzMigpfSxjbG9uZTpmdW5jdGlvbigpe3ZhciBhPXIuY2xvbmUuY2FsbCh0aGlzKTthLl9oYXNoPXRoaXMuX2hhc2guY2xvbmUoKTtyZXR1cm4gYX0sYmxvY2tTaXplOjMyfSk7bi5TSEE1MTI9ci5fY3JlYXRlSGVscGVyKGUpO24uSG1hY1NIQTUxMj1yLl9jcmVhdGVIbWFjSGVscGVyKGUpfSkoKTtcclxuXG4vKlxyXG5DcnlwdG9KUyB2My4xLjIgc2hhMzg0LW1pbi5qc1xyXG5jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanNcclxuKGMpIDIwMDktMjAxMyBieSBKZWZmIE1vdHQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbmNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qcy93aWtpL0xpY2Vuc2VcclxuKi9cclxuKGZ1bmN0aW9uKCl7dmFyIGM9Q3J5cHRvSlMsYT1jLng2NCxiPWEuV29yZCxlPWEuV29yZEFycmF5LGE9Yy5hbGdvLGQ9YS5TSEE1MTIsYT1hLlNIQTM4ND1kLmV4dGVuZCh7X2RvUmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLl9oYXNoPW5ldyBlLmluaXQoW25ldyBiLmluaXQoMzQxODA3MDM2NSwzMjM4MzcxMDMyKSxuZXcgYi5pbml0KDE2NTQyNzAyNTAsOTE0MTUwNjYzKSxuZXcgYi5pbml0KDI0Mzg1MjkzNzAsODEyNzAyOTk5KSxuZXcgYi5pbml0KDM1NTQ2MjM2MCw0MTQ0OTEyNjk3KSxuZXcgYi5pbml0KDE3MzE0MDU0MTUsNDI5MDc3NTg1NyksbmV3IGIuaW5pdCgyMzk0MTgwMjMxLDE3NTA2MDMwMjUpLG5ldyBiLmluaXQoMzY3NTAwODUyNSwxNjk0MDc2ODM5KSxuZXcgYi5pbml0KDEyMDMwNjI4MTMsMzIwNDA3NTQyOCldKX0sX2RvRmluYWxpemU6ZnVuY3Rpb24oKXt2YXIgYT1kLl9kb0ZpbmFsaXplLmNhbGwodGhpcyk7YS5zaWdCeXRlcy09MTY7cmV0dXJuIGF9fSk7Yy5TSEEzODQ9XHJcbmQuX2NyZWF0ZUhlbHBlcihhKTtjLkhtYWNTSEEzODQ9ZC5fY3JlYXRlSG1hY0hlbHBlcihhKX0pKCk7XHJcblxuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG52YXIgYjY0bWFwPVwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiO3ZhciBiNjRwYWQ9XCI9XCI7ZnVuY3Rpb24gaGV4MmI2NChkKXt2YXIgYjt2YXIgZTt2YXIgYT1cIlwiO2ZvcihiPTA7YiszPD1kLmxlbmd0aDtiKz0zKXtlPXBhcnNlSW50KGQuc3Vic3RyaW5nKGIsYiszKSwxNik7YSs9YjY0bWFwLmNoYXJBdChlPj42KStiNjRtYXAuY2hhckF0KGUmNjMpfWlmKGIrMT09ZC5sZW5ndGgpe2U9cGFyc2VJbnQoZC5zdWJzdHJpbmcoYixiKzEpLDE2KTthKz1iNjRtYXAuY2hhckF0KGU8PDIpfWVsc2V7aWYoYisyPT1kLmxlbmd0aCl7ZT1wYXJzZUludChkLnN1YnN0cmluZyhiLGIrMiksMTYpO2ErPWI2NG1hcC5jaGFyQXQoZT4+MikrYjY0bWFwLmNoYXJBdCgoZSYzKTw8NCl9fWlmKGI2NHBhZCl7d2hpbGUoKGEubGVuZ3RoJjMpPjApe2ErPWI2NHBhZH19cmV0dXJuIGF9ZnVuY3Rpb24gYjY0dG9oZXgoZil7dmFyIGQ9XCJcIjt2YXIgZTt2YXIgYj0wO3ZhciBjO3ZhciBhO2ZvcihlPTA7ZTxmLmxlbmd0aDsrK2Upe2lmKGYuY2hhckF0KGUpPT1iNjRwYWQpe2JyZWFrfWE9YjY0bWFwLmluZGV4T2YoZi5jaGFyQXQoZSkpO2lmKGE8MCl7Y29udGludWV9aWYoYj09MCl7ZCs9aW50MmNoYXIoYT4+Mik7Yz1hJjM7Yj0xfWVsc2V7aWYoYj09MSl7ZCs9aW50MmNoYXIoKGM8PDIpfChhPj40KSk7Yz1hJjE1O2I9Mn1lbHNle2lmKGI9PTIpe2QrPWludDJjaGFyKGMpO2QrPWludDJjaGFyKGE+PjIpO2M9YSYzO2I9M31lbHNle2QrPWludDJjaGFyKChjPDwyKXwoYT4+NCkpO2QrPWludDJjaGFyKGEmMTUpO2I9MH19fX1pZihiPT0xKXtkKz1pbnQyY2hhcihjPDwyKX1yZXR1cm4gZH1mdW5jdGlvbiBiNjR0b0JBKGUpe3ZhciBkPWI2NHRvaGV4KGUpO3ZhciBjO3ZhciBiPW5ldyBBcnJheSgpO2ZvcihjPTA7MipjPGQubGVuZ3RoOysrYyl7YltjXT1wYXJzZUludChkLnN1YnN0cmluZygyKmMsMipjKzIpLDE2KX1yZXR1cm4gYn07XG4vKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi9cclxuICovXHJcbnZhciBkYml0czt2YXIgY2FuYXJ5PTI0NDgzNzgxNDA5NDU5MDt2YXIgal9sbT0oKGNhbmFyeSYxNjc3NzIxNSk9PTE1NzE1MDcwKTtmdW5jdGlvbiBCaWdJbnRlZ2VyKGUsZCxmKXtpZihlIT1udWxsKXtpZihcIm51bWJlclwiPT10eXBlb2YgZSl7dGhpcy5mcm9tTnVtYmVyKGUsZCxmKX1lbHNle2lmKGQ9PW51bGwmJlwic3RyaW5nXCIhPXR5cGVvZiBlKXt0aGlzLmZyb21TdHJpbmcoZSwyNTYpfWVsc2V7dGhpcy5mcm9tU3RyaW5nKGUsZCl9fX19ZnVuY3Rpb24gbmJpKCl7cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKG51bGwpfWZ1bmN0aW9uIGFtMShmLGEsYixlLGgsZyl7d2hpbGUoLS1nPj0wKXt2YXIgZD1hKnRoaXNbZisrXStiW2VdK2g7aD1NYXRoLmZsb29yKGQvNjcxMDg4NjQpO2JbZSsrXT1kJjY3MTA4ODYzfXJldHVybiBofWZ1bmN0aW9uIGFtMihmLHEscixlLG8sYSl7dmFyIGs9cSYzMjc2NyxwPXE+PjE1O3doaWxlKC0tYT49MCl7dmFyIGQ9dGhpc1tmXSYzMjc2Nzt2YXIgZz10aGlzW2YrK10+PjE1O3ZhciBiPXAqZCtnKms7ZD1rKmQrKChiJjMyNzY3KTw8MTUpK3JbZV0rKG8mMTA3Mzc0MTgyMyk7bz0oZD4+PjMwKSsoYj4+PjE1KStwKmcrKG8+Pj4zMCk7cltlKytdPWQmMTA3Mzc0MTgyM31yZXR1cm4gb31mdW5jdGlvbiBhbTMoZixxLHIsZSxvLGEpe3ZhciBrPXEmMTYzODMscD1xPj4xNDt3aGlsZSgtLWE+PTApe3ZhciBkPXRoaXNbZl0mMTYzODM7dmFyIGc9dGhpc1tmKytdPj4xNDt2YXIgYj1wKmQrZyprO2Q9aypkKygoYiYxNjM4Myk8PDE0KStyW2VdK287bz0oZD4+MjgpKyhiPj4xNCkrcCpnO3JbZSsrXT1kJjI2ODQzNTQ1NX1yZXR1cm4gb31pZihqX2xtJiYobmF2aWdhdG9yLmFwcE5hbWU9PVwiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyXCIpKXtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbT1hbTI7ZGJpdHM9MzB9ZWxzZXtpZihqX2xtJiYobmF2aWdhdG9yLmFwcE5hbWUhPVwiTmV0c2NhcGVcIikpe0JpZ0ludGVnZXIucHJvdG90eXBlLmFtPWFtMTtkYml0cz0yNn1lbHNle0JpZ0ludGVnZXIucHJvdG90eXBlLmFtPWFtMztkYml0cz0yOH19QmlnSW50ZWdlci5wcm90b3R5cGUuREI9ZGJpdHM7QmlnSW50ZWdlci5wcm90b3R5cGUuRE09KCgxPDxkYml0cyktMSk7QmlnSW50ZWdlci5wcm90b3R5cGUuRFY9KDE8PGRiaXRzKTt2YXIgQklfRlA9NTI7QmlnSW50ZWdlci5wcm90b3R5cGUuRlY9TWF0aC5wb3coMixCSV9GUCk7QmlnSW50ZWdlci5wcm90b3R5cGUuRjE9QklfRlAtZGJpdHM7QmlnSW50ZWdlci5wcm90b3R5cGUuRjI9MipkYml0cy1CSV9GUDt2YXIgQklfUk09XCIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIjt2YXIgQklfUkM9bmV3IEFycmF5KCk7dmFyIHJyLHZ2O3JyPVwiMFwiLmNoYXJDb2RlQXQoMCk7Zm9yKHZ2PTA7dnY8PTk7Kyt2dil7QklfUkNbcnIrK109dnZ9cnI9XCJhXCIuY2hhckNvZGVBdCgwKTtmb3IodnY9MTA7dnY8MzY7Kyt2dil7QklfUkNbcnIrK109dnZ9cnI9XCJBXCIuY2hhckNvZGVBdCgwKTtmb3IodnY9MTA7dnY8MzY7Kyt2dil7QklfUkNbcnIrK109dnZ9ZnVuY3Rpb24gaW50MmNoYXIoYSl7cmV0dXJuIEJJX1JNLmNoYXJBdChhKX1mdW5jdGlvbiBpbnRBdChiLGEpe3ZhciBkPUJJX1JDW2IuY2hhckNvZGVBdChhKV07cmV0dXJuKGQ9PW51bGwpPy0xOmR9ZnVuY3Rpb24gYm5wQ29weVRvKGIpe2Zvcih2YXIgYT10aGlzLnQtMTthPj0wOy0tYSl7YlthXT10aGlzW2FdfWIudD10aGlzLnQ7Yi5zPXRoaXMuc31mdW5jdGlvbiBibnBGcm9tSW50KGEpe3RoaXMudD0xO3RoaXMucz0oYTwwKT8tMTowO2lmKGE+MCl7dGhpc1swXT1hfWVsc2V7aWYoYTwtMSl7dGhpc1swXT1hK3RoaXMuRFZ9ZWxzZXt0aGlzLnQ9MH19fWZ1bmN0aW9uIG5idihhKXt2YXIgYj1uYmkoKTtiLmZyb21JbnQoYSk7cmV0dXJuIGJ9ZnVuY3Rpb24gYm5wRnJvbVN0cmluZyhoLGMpe3ZhciBlO2lmKGM9PTE2KXtlPTR9ZWxzZXtpZihjPT04KXtlPTN9ZWxzZXtpZihjPT0yNTYpe2U9OH1lbHNle2lmKGM9PTIpe2U9MX1lbHNle2lmKGM9PTMyKXtlPTV9ZWxzZXtpZihjPT00KXtlPTJ9ZWxzZXt0aGlzLmZyb21SYWRpeChoLGMpO3JldHVybn19fX19fXRoaXMudD0wO3RoaXMucz0wO3ZhciBnPWgubGVuZ3RoLGQ9ZmFsc2UsZj0wO3doaWxlKC0tZz49MCl7dmFyIGE9KGU9PTgpP2hbZ10mMjU1OmludEF0KGgsZyk7aWYoYTwwKXtpZihoLmNoYXJBdChnKT09XCItXCIpe2Q9dHJ1ZX1jb250aW51ZX1kPWZhbHNlO2lmKGY9PTApe3RoaXNbdGhpcy50KytdPWF9ZWxzZXtpZihmK2U+dGhpcy5EQil7dGhpc1t0aGlzLnQtMV18PShhJigoMTw8KHRoaXMuREItZikpLTEpKTw8Zjt0aGlzW3RoaXMudCsrXT0oYT4+KHRoaXMuREItZikpfWVsc2V7dGhpc1t0aGlzLnQtMV18PWE8PGZ9fWYrPWU7aWYoZj49dGhpcy5EQil7Zi09dGhpcy5EQn19aWYoZT09OCYmKGhbMF0mMTI4KSE9MCl7dGhpcy5zPS0xO2lmKGY+MCl7dGhpc1t0aGlzLnQtMV18PSgoMTw8KHRoaXMuREItZikpLTEpPDxmfX10aGlzLmNsYW1wKCk7aWYoZCl7QmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyl9fWZ1bmN0aW9uIGJucENsYW1wKCl7dmFyIGE9dGhpcy5zJnRoaXMuRE07d2hpbGUodGhpcy50PjAmJnRoaXNbdGhpcy50LTFdPT1hKXstLXRoaXMudH19ZnVuY3Rpb24gYm5Ub1N0cmluZyhjKXtpZih0aGlzLnM8MCl7cmV0dXJuXCItXCIrdGhpcy5uZWdhdGUoKS50b1N0cmluZyhjKX12YXIgZTtpZihjPT0xNil7ZT00fWVsc2V7aWYoYz09OCl7ZT0zfWVsc2V7aWYoYz09Mil7ZT0xfWVsc2V7aWYoYz09MzIpe2U9NX1lbHNle2lmKGM9PTQpe2U9Mn1lbHNle3JldHVybiB0aGlzLnRvUmFkaXgoYyl9fX19fXZhciBnPSgxPDxlKS0xLGwsYT1mYWxzZSxoPVwiXCIsZj10aGlzLnQ7dmFyIGo9dGhpcy5EQi0oZip0aGlzLkRCKSVlO2lmKGYtLT4wKXtpZihqPHRoaXMuREImJihsPXRoaXNbZl0+PmopPjApe2E9dHJ1ZTtoPWludDJjaGFyKGwpfXdoaWxlKGY+PTApe2lmKGo8ZSl7bD0odGhpc1tmXSYoKDE8PGopLTEpKTw8KGUtaik7bHw9dGhpc1stLWZdPj4oais9dGhpcy5EQi1lKX1lbHNle2w9KHRoaXNbZl0+PihqLT1lKSkmZztpZihqPD0wKXtqKz10aGlzLkRCOy0tZn19aWYobD4wKXthPXRydWV9aWYoYSl7aCs9aW50MmNoYXIobCl9fX1yZXR1cm4gYT9oOlwiMFwifWZ1bmN0aW9uIGJuTmVnYXRlKCl7dmFyIGE9bmJpKCk7QmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsYSk7cmV0dXJuIGF9ZnVuY3Rpb24gYm5BYnMoKXtyZXR1cm4odGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpc31mdW5jdGlvbiBibkNvbXBhcmVUbyhiKXt2YXIgZD10aGlzLnMtYi5zO2lmKGQhPTApe3JldHVybiBkfXZhciBjPXRoaXMudDtkPWMtYi50O2lmKGQhPTApe3JldHVybih0aGlzLnM8MCk/LWQ6ZH13aGlsZSgtLWM+PTApe2lmKChkPXRoaXNbY10tYltjXSkhPTApe3JldHVybiBkfX1yZXR1cm4gMH1mdW5jdGlvbiBuYml0cyhhKXt2YXIgYz0xLGI7aWYoKGI9YT4+PjE2KSE9MCl7YT1iO2MrPTE2fWlmKChiPWE+PjgpIT0wKXthPWI7Yys9OH1pZigoYj1hPj40KSE9MCl7YT1iO2MrPTR9aWYoKGI9YT4+MikhPTApe2E9YjtjKz0yfWlmKChiPWE+PjEpIT0wKXthPWI7Yys9MX1yZXR1cm4gY31mdW5jdGlvbiBibkJpdExlbmd0aCgpe2lmKHRoaXMudDw9MCl7cmV0dXJuIDB9cmV0dXJuIHRoaXMuREIqKHRoaXMudC0xKStuYml0cyh0aGlzW3RoaXMudC0xXV4odGhpcy5zJnRoaXMuRE0pKX1mdW5jdGlvbiBibnBETFNoaWZ0VG8oYyxiKXt2YXIgYTtmb3IoYT10aGlzLnQtMTthPj0wOy0tYSl7YlthK2NdPXRoaXNbYV19Zm9yKGE9Yy0xO2E+PTA7LS1hKXtiW2FdPTB9Yi50PXRoaXMudCtjO2Iucz10aGlzLnN9ZnVuY3Rpb24gYm5wRFJTaGlmdFRvKGMsYil7Zm9yKHZhciBhPWM7YTx0aGlzLnQ7KythKXtiW2EtY109dGhpc1thXX1iLnQ9TWF0aC5tYXgodGhpcy50LWMsMCk7Yi5zPXRoaXMuc31mdW5jdGlvbiBibnBMU2hpZnRUbyhqLGUpe3ZhciBiPWoldGhpcy5EQjt2YXIgYT10aGlzLkRCLWI7dmFyIGc9KDE8PGEpLTE7dmFyIGY9TWF0aC5mbG9vcihqL3RoaXMuREIpLGg9KHRoaXMuczw8YikmdGhpcy5ETSxkO2ZvcihkPXRoaXMudC0xO2Q+PTA7LS1kKXtlW2QrZisxXT0odGhpc1tkXT4+YSl8aDtoPSh0aGlzW2RdJmcpPDxifWZvcihkPWYtMTtkPj0wOy0tZCl7ZVtkXT0wfWVbZl09aDtlLnQ9dGhpcy50K2YrMTtlLnM9dGhpcy5zO2UuY2xhbXAoKX1mdW5jdGlvbiBibnBSU2hpZnRUbyhnLGQpe2Qucz10aGlzLnM7dmFyIGU9TWF0aC5mbG9vcihnL3RoaXMuREIpO2lmKGU+PXRoaXMudCl7ZC50PTA7cmV0dXJufXZhciBiPWcldGhpcy5EQjt2YXIgYT10aGlzLkRCLWI7dmFyIGY9KDE8PGIpLTE7ZFswXT10aGlzW2VdPj5iO2Zvcih2YXIgYz1lKzE7Yzx0aGlzLnQ7KytjKXtkW2MtZS0xXXw9KHRoaXNbY10mZik8PGE7ZFtjLWVdPXRoaXNbY10+PmJ9aWYoYj4wKXtkW3RoaXMudC1lLTFdfD0odGhpcy5zJmYpPDxhfWQudD10aGlzLnQtZTtkLmNsYW1wKCl9ZnVuY3Rpb24gYm5wU3ViVG8oZCxmKXt2YXIgZT0wLGc9MCxiPU1hdGgubWluKGQudCx0aGlzLnQpO3doaWxlKGU8Yil7Zys9dGhpc1tlXS1kW2VdO2ZbZSsrXT1nJnRoaXMuRE07Zz4+PXRoaXMuREJ9aWYoZC50PHRoaXMudCl7Zy09ZC5zO3doaWxlKGU8dGhpcy50KXtnKz10aGlzW2VdO2ZbZSsrXT1nJnRoaXMuRE07Zz4+PXRoaXMuREJ9Zys9dGhpcy5zfWVsc2V7Zys9dGhpcy5zO3doaWxlKGU8ZC50KXtnLT1kW2VdO2ZbZSsrXT1nJnRoaXMuRE07Zz4+PXRoaXMuREJ9Zy09ZC5zfWYucz0oZzwwKT8tMTowO2lmKGc8LTEpe2ZbZSsrXT10aGlzLkRWK2d9ZWxzZXtpZihnPjApe2ZbZSsrXT1nfX1mLnQ9ZTtmLmNsYW1wKCl9ZnVuY3Rpb24gYm5wTXVsdGlwbHlUbyhjLGUpe3ZhciBiPXRoaXMuYWJzKCksZj1jLmFicygpO3ZhciBkPWIudDtlLnQ9ZCtmLnQ7d2hpbGUoLS1kPj0wKXtlW2RdPTB9Zm9yKGQ9MDtkPGYudDsrK2Qpe2VbZCtiLnRdPWIuYW0oMCxmW2RdLGUsZCwwLGIudCl9ZS5zPTA7ZS5jbGFtcCgpO2lmKHRoaXMucyE9Yy5zKXtCaWdJbnRlZ2VyLlpFUk8uc3ViVG8oZSxlKX19ZnVuY3Rpb24gYm5wU3F1YXJlVG8oZCl7dmFyIGE9dGhpcy5hYnMoKTt2YXIgYj1kLnQ9MiphLnQ7d2hpbGUoLS1iPj0wKXtkW2JdPTB9Zm9yKGI9MDtiPGEudC0xOysrYil7dmFyIGU9YS5hbShiLGFbYl0sZCwyKmIsMCwxKTtpZigoZFtiK2EudF0rPWEuYW0oYisxLDIqYVtiXSxkLDIqYisxLGUsYS50LWItMSkpPj1hLkRWKXtkW2IrYS50XS09YS5EVjtkW2IrYS50KzFdPTF9fWlmKGQudD4wKXtkW2QudC0xXSs9YS5hbShiLGFbYl0sZCwyKmIsMCwxKX1kLnM9MDtkLmNsYW1wKCl9ZnVuY3Rpb24gYm5wRGl2UmVtVG8obixoLGcpe3ZhciB3PW4uYWJzKCk7aWYody50PD0wKXtyZXR1cm59dmFyIGs9dGhpcy5hYnMoKTtpZihrLnQ8dy50KXtpZihoIT1udWxsKXtoLmZyb21JbnQoMCl9aWYoZyE9bnVsbCl7dGhpcy5jb3B5VG8oZyl9cmV0dXJufWlmKGc9PW51bGwpe2c9bmJpKCl9dmFyIGQ9bmJpKCksYT10aGlzLnMsbD1uLnM7dmFyIHY9dGhpcy5EQi1uYml0cyh3W3cudC0xXSk7aWYodj4wKXt3LmxTaGlmdFRvKHYsZCk7ay5sU2hpZnRUbyh2LGcpfWVsc2V7dy5jb3B5VG8oZCk7ay5jb3B5VG8oZyl9dmFyIHA9ZC50O3ZhciBiPWRbcC0xXTtpZihiPT0wKXtyZXR1cm59dmFyIG89YiooMTw8dGhpcy5GMSkrKChwPjEpP2RbcC0yXT4+dGhpcy5GMjowKTt2YXIgQT10aGlzLkZWL28sej0oMTw8dGhpcy5GMSkvbyx4PTE8PHRoaXMuRjI7dmFyIHU9Zy50LHM9dS1wLGY9KGg9PW51bGwpP25iaSgpOmg7ZC5kbFNoaWZ0VG8ocyxmKTtpZihnLmNvbXBhcmVUbyhmKT49MCl7Z1tnLnQrK109MTtnLnN1YlRvKGYsZyl9QmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHAsZik7Zi5zdWJUbyhkLGQpO3doaWxlKGQudDxwKXtkW2QudCsrXT0wfXdoaWxlKC0tcz49MCl7dmFyIGM9KGdbLS11XT09Yik/dGhpcy5ETTpNYXRoLmZsb29yKGdbdV0qQSsoZ1t1LTFdK3gpKnopO2lmKChnW3VdKz1kLmFtKDAsYyxnLHMsMCxwKSk8Yyl7ZC5kbFNoaWZ0VG8ocyxmKTtnLnN1YlRvKGYsZyk7d2hpbGUoZ1t1XTwtLWMpe2cuc3ViVG8oZixnKX19fWlmKGghPW51bGwpe2cuZHJTaGlmdFRvKHAsaCk7aWYoYSE9bCl7QmlnSW50ZWdlci5aRVJPLnN1YlRvKGgsaCl9fWcudD1wO2cuY2xhbXAoKTtpZih2PjApe2cuclNoaWZ0VG8odixnKX1pZihhPDApe0JpZ0ludGVnZXIuWkVSTy5zdWJUbyhnLGcpfX1mdW5jdGlvbiBibk1vZChiKXt2YXIgYz1uYmkoKTt0aGlzLmFicygpLmRpdlJlbVRvKGIsbnVsbCxjKTtpZih0aGlzLnM8MCYmYy5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKT4wKXtiLnN1YlRvKGMsYyl9cmV0dXJuIGN9ZnVuY3Rpb24gQ2xhc3NpYyhhKXt0aGlzLm09YX1mdW5jdGlvbiBjQ29udmVydChhKXtpZihhLnM8MHx8YS5jb21wYXJlVG8odGhpcy5tKT49MCl7cmV0dXJuIGEubW9kKHRoaXMubSl9ZWxzZXtyZXR1cm4gYX19ZnVuY3Rpb24gY1JldmVydChhKXtyZXR1cm4gYX1mdW5jdGlvbiBjUmVkdWNlKGEpe2EuZGl2UmVtVG8odGhpcy5tLG51bGwsYSl9ZnVuY3Rpb24gY011bFRvKGEsYyxiKXthLm11bHRpcGx5VG8oYyxiKTt0aGlzLnJlZHVjZShiKX1mdW5jdGlvbiBjU3FyVG8oYSxiKXthLnNxdWFyZVRvKGIpO3RoaXMucmVkdWNlKGIpfUNsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQ9Y0NvbnZlcnQ7Q2xhc3NpYy5wcm90b3R5cGUucmV2ZXJ0PWNSZXZlcnQ7Q2xhc3NpYy5wcm90b3R5cGUucmVkdWNlPWNSZWR1Y2U7Q2xhc3NpYy5wcm90b3R5cGUubXVsVG89Y011bFRvO0NsYXNzaWMucHJvdG90eXBlLnNxclRvPWNTcXJUbztmdW5jdGlvbiBibnBJbnZEaWdpdCgpe2lmKHRoaXMudDwxKXtyZXR1cm4gMH12YXIgYT10aGlzWzBdO2lmKChhJjEpPT0wKXtyZXR1cm4gMH12YXIgYj1hJjM7Yj0oYiooMi0oYSYxNSkqYikpJjE1O2I9KGIqKDItKGEmMjU1KSpiKSkmMjU1O2I9KGIqKDItKCgoYSY2NTUzNSkqYikmNjU1MzUpKSkmNjU1MzU7Yj0oYiooMi1hKmIldGhpcy5EVikpJXRoaXMuRFY7cmV0dXJuKGI+MCk/dGhpcy5EVi1iOi1ifWZ1bmN0aW9uIE1vbnRnb21lcnkoYSl7dGhpcy5tPWE7dGhpcy5tcD1hLmludkRpZ2l0KCk7dGhpcy5tcGw9dGhpcy5tcCYzMjc2Nzt0aGlzLm1waD10aGlzLm1wPj4xNTt0aGlzLnVtPSgxPDwoYS5EQi0xNSkpLTE7dGhpcy5tdDI9MiphLnR9ZnVuY3Rpb24gbW9udENvbnZlcnQoYSl7dmFyIGI9bmJpKCk7YS5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQsYik7Yi5kaXZSZW1Ubyh0aGlzLm0sbnVsbCxiKTtpZihhLnM8MCYmYi5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKT4wKXt0aGlzLm0uc3ViVG8oYixiKX1yZXR1cm4gYn1mdW5jdGlvbiBtb250UmV2ZXJ0KGEpe3ZhciBiPW5iaSgpO2EuY29weVRvKGIpO3RoaXMucmVkdWNlKGIpO3JldHVybiBifWZ1bmN0aW9uIG1vbnRSZWR1Y2UoYSl7d2hpbGUoYS50PD10aGlzLm10Mil7YVthLnQrK109MH1mb3IodmFyIGM9MDtjPHRoaXMubS50OysrYyl7dmFyIGI9YVtjXSYzMjc2Nzt2YXIgZD0oYip0aGlzLm1wbCsoKChiKnRoaXMubXBoKyhhW2NdPj4xNSkqdGhpcy5tcGwpJnRoaXMudW0pPDwxNSkpJmEuRE07Yj1jK3RoaXMubS50O2FbYl0rPXRoaXMubS5hbSgwLGQsYSxjLDAsdGhpcy5tLnQpO3doaWxlKGFbYl0+PWEuRFYpe2FbYl0tPWEuRFY7YVsrK2JdKyt9fWEuY2xhbXAoKTthLmRyU2hpZnRUbyh0aGlzLm0udCxhKTtpZihhLmNvbXBhcmVUbyh0aGlzLm0pPj0wKXthLnN1YlRvKHRoaXMubSxhKX19ZnVuY3Rpb24gbW9udFNxclRvKGEsYil7YS5zcXVhcmVUbyhiKTt0aGlzLnJlZHVjZShiKX1mdW5jdGlvbiBtb250TXVsVG8oYSxjLGIpe2EubXVsdGlwbHlUbyhjLGIpO3RoaXMucmVkdWNlKGIpfU1vbnRnb21lcnkucHJvdG90eXBlLmNvbnZlcnQ9bW9udENvbnZlcnQ7TW9udGdvbWVyeS5wcm90b3R5cGUucmV2ZXJ0PW1vbnRSZXZlcnQ7TW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlPW1vbnRSZWR1Y2U7TW9udGdvbWVyeS5wcm90b3R5cGUubXVsVG89bW9udE11bFRvO01vbnRnb21lcnkucHJvdG90eXBlLnNxclRvPW1vbnRTcXJUbztmdW5jdGlvbiBibnBJc0V2ZW4oKXtyZXR1cm4oKHRoaXMudD4wKT8odGhpc1swXSYxKTp0aGlzLnMpPT0wfWZ1bmN0aW9uIGJucEV4cChoLGope2lmKGg+NDI5NDk2NzI5NXx8aDwxKXtyZXR1cm4gQmlnSW50ZWdlci5PTkV9dmFyIGY9bmJpKCksYT1uYmkoKSxkPWouY29udmVydCh0aGlzKSxjPW5iaXRzKGgpLTE7ZC5jb3B5VG8oZik7d2hpbGUoLS1jPj0wKXtqLnNxclRvKGYsYSk7aWYoKGgmKDE8PGMpKT4wKXtqLm11bFRvKGEsZCxmKX1lbHNle3ZhciBiPWY7Zj1hO2E9Yn19cmV0dXJuIGoucmV2ZXJ0KGYpfWZ1bmN0aW9uIGJuTW9kUG93SW50KGIsYSl7dmFyIGM7aWYoYjwyNTZ8fGEuaXNFdmVuKCkpe2M9bmV3IENsYXNzaWMoYSl9ZWxzZXtjPW5ldyBNb250Z29tZXJ5KGEpfXJldHVybiB0aGlzLmV4cChiLGMpfUJpZ0ludGVnZXIucHJvdG90eXBlLmNvcHlUbz1ibnBDb3B5VG87QmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbUludD1ibnBGcm9tSW50O0JpZ0ludGVnZXIucHJvdG90eXBlLmZyb21TdHJpbmc9Ym5wRnJvbVN0cmluZztCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGFtcD1ibnBDbGFtcDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5kbFNoaWZ0VG89Ym5wRExTaGlmdFRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmRyU2hpZnRUbz1ibnBEUlNoaWZ0VG87QmlnSW50ZWdlci5wcm90b3R5cGUubFNoaWZ0VG89Ym5wTFNoaWZ0VG87QmlnSW50ZWdlci5wcm90b3R5cGUuclNoaWZ0VG89Ym5wUlNoaWZ0VG87QmlnSW50ZWdlci5wcm90b3R5cGUuc3ViVG89Ym5wU3ViVG87QmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlUbz1ibnBNdWx0aXBseVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZVRvPWJucFNxdWFyZVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmRpdlJlbVRvPWJucERpdlJlbVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmludkRpZ2l0PWJucEludkRpZ2l0O0JpZ0ludGVnZXIucHJvdG90eXBlLmlzRXZlbj1ibnBJc0V2ZW47QmlnSW50ZWdlci5wcm90b3R5cGUuZXhwPWJucEV4cDtCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZz1iblRvU3RyaW5nO0JpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZT1ibk5lZ2F0ZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnM9Ym5BYnM7QmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvPWJuQ29tcGFyZVRvO0JpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aD1ibkJpdExlbmd0aDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2Q9Ym5Nb2Q7QmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50PWJuTW9kUG93SW50O0JpZ0ludGVnZXIuWkVSTz1uYnYoMCk7QmlnSW50ZWdlci5PTkU9bmJ2KDEpO1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG5mdW5jdGlvbiBibkNsb25lKCl7dmFyIGE9bmJpKCk7dGhpcy5jb3B5VG8oYSk7cmV0dXJuIGF9ZnVuY3Rpb24gYm5JbnRWYWx1ZSgpe2lmKHRoaXMuczwwKXtpZih0aGlzLnQ9PTEpe3JldHVybiB0aGlzWzBdLXRoaXMuRFZ9ZWxzZXtpZih0aGlzLnQ9PTApe3JldHVybiAtMX19fWVsc2V7aWYodGhpcy50PT0xKXtyZXR1cm4gdGhpc1swXX1lbHNle2lmKHRoaXMudD09MCl7cmV0dXJuIDB9fX1yZXR1cm4oKHRoaXNbMV0mKCgxPDwoMzItdGhpcy5EQikpLTEpKTw8dGhpcy5EQil8dGhpc1swXX1mdW5jdGlvbiBibkJ5dGVWYWx1ZSgpe3JldHVybih0aGlzLnQ9PTApP3RoaXMuczoodGhpc1swXTw8MjQpPj4yNH1mdW5jdGlvbiBiblNob3J0VmFsdWUoKXtyZXR1cm4odGhpcy50PT0wKT90aGlzLnM6KHRoaXNbMF08PDE2KT4+MTZ9ZnVuY3Rpb24gYm5wQ2h1bmtTaXplKGEpe3JldHVybiBNYXRoLmZsb29yKE1hdGguTE4yKnRoaXMuREIvTWF0aC5sb2coYSkpfWZ1bmN0aW9uIGJuU2lnTnVtKCl7aWYodGhpcy5zPDApe3JldHVybiAtMX1lbHNle2lmKHRoaXMudDw9MHx8KHRoaXMudD09MSYmdGhpc1swXTw9MCkpe3JldHVybiAwfWVsc2V7cmV0dXJuIDF9fX1mdW5jdGlvbiBibnBUb1JhZGl4KGMpe2lmKGM9PW51bGwpe2M9MTB9aWYodGhpcy5zaWdudW0oKT09MHx8YzwyfHxjPjM2KXtyZXR1cm5cIjBcIn12YXIgZj10aGlzLmNodW5rU2l6ZShjKTt2YXIgZT1NYXRoLnBvdyhjLGYpO3ZhciBpPW5idihlKSxqPW5iaSgpLGg9bmJpKCksZz1cIlwiO3RoaXMuZGl2UmVtVG8oaSxqLGgpO3doaWxlKGouc2lnbnVtKCk+MCl7Zz0oZStoLmludFZhbHVlKCkpLnRvU3RyaW5nKGMpLnN1YnN0cigxKStnO2ouZGl2UmVtVG8oaSxqLGgpfXJldHVybiBoLmludFZhbHVlKCkudG9TdHJpbmcoYykrZ31mdW5jdGlvbiBibnBGcm9tUmFkaXgobSxoKXt0aGlzLmZyb21JbnQoMCk7aWYoaD09bnVsbCl7aD0xMH12YXIgZj10aGlzLmNodW5rU2l6ZShoKTt2YXIgZz1NYXRoLnBvdyhoLGYpLGU9ZmFsc2UsYT0wLGw9MDtmb3IodmFyIGM9MDtjPG0ubGVuZ3RoOysrYyl7dmFyIGs9aW50QXQobSxjKTtpZihrPDApe2lmKG0uY2hhckF0KGMpPT1cIi1cIiYmdGhpcy5zaWdudW0oKT09MCl7ZT10cnVlfWNvbnRpbnVlfWw9aCpsK2s7aWYoKythPj1mKXt0aGlzLmRNdWx0aXBseShnKTt0aGlzLmRBZGRPZmZzZXQobCwwKTthPTA7bD0wfX1pZihhPjApe3RoaXMuZE11bHRpcGx5KE1hdGgucG93KGgsYSkpO3RoaXMuZEFkZE9mZnNldChsLDApfWlmKGUpe0JpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpfX1mdW5jdGlvbiBibnBGcm9tTnVtYmVyKGYsZSxoKXtpZihcIm51bWJlclwiPT10eXBlb2YgZSl7aWYoZjwyKXt0aGlzLmZyb21JbnQoMSl9ZWxzZXt0aGlzLmZyb21OdW1iZXIoZixoKTtpZighdGhpcy50ZXN0Qml0KGYtMSkpe3RoaXMuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChmLTEpLG9wX29yLHRoaXMpfWlmKHRoaXMuaXNFdmVuKCkpe3RoaXMuZEFkZE9mZnNldCgxLDApfXdoaWxlKCF0aGlzLmlzUHJvYmFibGVQcmltZShlKSl7dGhpcy5kQWRkT2Zmc2V0KDIsMCk7aWYodGhpcy5iaXRMZW5ndGgoKT5mKXt0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChmLTEpLHRoaXMpfX19fWVsc2V7dmFyIGQ9bmV3IEFycmF5KCksZz1mJjc7ZC5sZW5ndGg9KGY+PjMpKzE7ZS5uZXh0Qnl0ZXMoZCk7aWYoZz4wKXtkWzBdJj0oKDE8PGcpLTEpfWVsc2V7ZFswXT0wfXRoaXMuZnJvbVN0cmluZyhkLDI1Nil9fWZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKXt2YXIgYj10aGlzLnQsYz1uZXcgQXJyYXkoKTtjWzBdPXRoaXMuczt2YXIgZT10aGlzLkRCLShiKnRoaXMuREIpJTgsZixhPTA7aWYoYi0tPjApe2lmKGU8dGhpcy5EQiYmKGY9dGhpc1tiXT4+ZSkhPSh0aGlzLnMmdGhpcy5ETSk+PmUpe2NbYSsrXT1mfCh0aGlzLnM8PCh0aGlzLkRCLWUpKX13aGlsZShiPj0wKXtpZihlPDgpe2Y9KHRoaXNbYl0mKCgxPDxlKS0xKSk8PCg4LWUpO2Z8PXRoaXNbLS1iXT4+KGUrPXRoaXMuREItOCl9ZWxzZXtmPSh0aGlzW2JdPj4oZS09OCkpJjI1NTtpZihlPD0wKXtlKz10aGlzLkRCOy0tYn19aWYoKGYmMTI4KSE9MCl7Znw9LTI1Nn1pZihhPT0wJiYodGhpcy5zJjEyOCkhPShmJjEyOCkpeysrYX1pZihhPjB8fGYhPXRoaXMucyl7Y1thKytdPWZ9fX1yZXR1cm4gY31mdW5jdGlvbiBibkVxdWFscyhiKXtyZXR1cm4odGhpcy5jb21wYXJlVG8oYik9PTApfWZ1bmN0aW9uIGJuTWluKGIpe3JldHVybih0aGlzLmNvbXBhcmVUbyhiKTwwKT90aGlzOmJ9ZnVuY3Rpb24gYm5NYXgoYil7cmV0dXJuKHRoaXMuY29tcGFyZVRvKGIpPjApP3RoaXM6Yn1mdW5jdGlvbiBibnBCaXR3aXNlVG8oYyxoLGUpe3ZhciBkLGcsYj1NYXRoLm1pbihjLnQsdGhpcy50KTtmb3IoZD0wO2Q8YjsrK2Qpe2VbZF09aCh0aGlzW2RdLGNbZF0pfWlmKGMudDx0aGlzLnQpe2c9Yy5zJnRoaXMuRE07Zm9yKGQ9YjtkPHRoaXMudDsrK2Qpe2VbZF09aCh0aGlzW2RdLGcpfWUudD10aGlzLnR9ZWxzZXtnPXRoaXMucyZ0aGlzLkRNO2ZvcihkPWI7ZDxjLnQ7KytkKXtlW2RdPWgoZyxjW2RdKX1lLnQ9Yy50fWUucz1oKHRoaXMucyxjLnMpO2UuY2xhbXAoKX1mdW5jdGlvbiBvcF9hbmQoYSxiKXtyZXR1cm4gYSZifWZ1bmN0aW9uIGJuQW5kKGIpe3ZhciBjPW5iaSgpO3RoaXMuYml0d2lzZVRvKGIsb3BfYW5kLGMpO3JldHVybiBjfWZ1bmN0aW9uIG9wX29yKGEsYil7cmV0dXJuIGF8Yn1mdW5jdGlvbiBibk9yKGIpe3ZhciBjPW5iaSgpO3RoaXMuYml0d2lzZVRvKGIsb3Bfb3IsYyk7cmV0dXJuIGN9ZnVuY3Rpb24gb3BfeG9yKGEsYil7cmV0dXJuIGFeYn1mdW5jdGlvbiBiblhvcihiKXt2YXIgYz1uYmkoKTt0aGlzLmJpdHdpc2VUbyhiLG9wX3hvcixjKTtyZXR1cm4gY31mdW5jdGlvbiBvcF9hbmRub3QoYSxiKXtyZXR1cm4gYSZ+Yn1mdW5jdGlvbiBibkFuZE5vdChiKXt2YXIgYz1uYmkoKTt0aGlzLmJpdHdpc2VUbyhiLG9wX2FuZG5vdCxjKTtyZXR1cm4gY31mdW5jdGlvbiBibk5vdCgpe3ZhciBiPW5iaSgpO2Zvcih2YXIgYT0wO2E8dGhpcy50OysrYSl7YlthXT10aGlzLkRNJn50aGlzW2FdfWIudD10aGlzLnQ7Yi5zPX50aGlzLnM7cmV0dXJuIGJ9ZnVuY3Rpb24gYm5TaGlmdExlZnQoYil7dmFyIGE9bmJpKCk7aWYoYjwwKXt0aGlzLnJTaGlmdFRvKC1iLGEpfWVsc2V7dGhpcy5sU2hpZnRUbyhiLGEpfXJldHVybiBhfWZ1bmN0aW9uIGJuU2hpZnRSaWdodChiKXt2YXIgYT1uYmkoKTtpZihiPDApe3RoaXMubFNoaWZ0VG8oLWIsYSl9ZWxzZXt0aGlzLnJTaGlmdFRvKGIsYSl9cmV0dXJuIGF9ZnVuY3Rpb24gbGJpdChhKXtpZihhPT0wKXtyZXR1cm4gLTF9dmFyIGI9MDtpZigoYSY2NTUzNSk9PTApe2E+Pj0xNjtiKz0xNn1pZigoYSYyNTUpPT0wKXthPj49ODtiKz04fWlmKChhJjE1KT09MCl7YT4+PTQ7Yis9NH1pZigoYSYzKT09MCl7YT4+PTI7Yis9Mn1pZigoYSYxKT09MCl7KytifXJldHVybiBifWZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCl7Zm9yKHZhciBhPTA7YTx0aGlzLnQ7KythKXtpZih0aGlzW2FdIT0wKXtyZXR1cm4gYSp0aGlzLkRCK2xiaXQodGhpc1thXSl9fWlmKHRoaXMuczwwKXtyZXR1cm4gdGhpcy50KnRoaXMuREJ9cmV0dXJuIC0xfWZ1bmN0aW9uIGNiaXQoYSl7dmFyIGI9MDt3aGlsZShhIT0wKXthJj1hLTE7KytifXJldHVybiBifWZ1bmN0aW9uIGJuQml0Q291bnQoKXt2YXIgYz0wLGE9dGhpcy5zJnRoaXMuRE07Zm9yKHZhciBiPTA7Yjx0aGlzLnQ7KytiKXtjKz1jYml0KHRoaXNbYl1eYSl9cmV0dXJuIGN9ZnVuY3Rpb24gYm5UZXN0Qml0KGIpe3ZhciBhPU1hdGguZmxvb3IoYi90aGlzLkRCKTtpZihhPj10aGlzLnQpe3JldHVybih0aGlzLnMhPTApfXJldHVybigodGhpc1thXSYoMTw8KGIldGhpcy5EQikpKSE9MCl9ZnVuY3Rpb24gYm5wQ2hhbmdlQml0KGMsYil7dmFyIGE9QmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGMpO3RoaXMuYml0d2lzZVRvKGEsYixhKTtyZXR1cm4gYX1mdW5jdGlvbiBiblNldEJpdChhKXtyZXR1cm4gdGhpcy5jaGFuZ2VCaXQoYSxvcF9vcil9ZnVuY3Rpb24gYm5DbGVhckJpdChhKXtyZXR1cm4gdGhpcy5jaGFuZ2VCaXQoYSxvcF9hbmRub3QpfWZ1bmN0aW9uIGJuRmxpcEJpdChhKXtyZXR1cm4gdGhpcy5jaGFuZ2VCaXQoYSxvcF94b3IpfWZ1bmN0aW9uIGJucEFkZFRvKGQsZil7dmFyIGU9MCxnPTAsYj1NYXRoLm1pbihkLnQsdGhpcy50KTt3aGlsZShlPGIpe2crPXRoaXNbZV0rZFtlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWlmKGQudDx0aGlzLnQpe2crPWQuczt3aGlsZShlPHRoaXMudCl7Zys9dGhpc1tlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWcrPXRoaXMuc31lbHNle2crPXRoaXMuczt3aGlsZShlPGQudCl7Zys9ZFtlXTtmW2UrK109ZyZ0aGlzLkRNO2c+Pj10aGlzLkRCfWcrPWQuc31mLnM9KGc8MCk/LTE6MDtpZihnPjApe2ZbZSsrXT1nfWVsc2V7aWYoZzwtMSl7ZltlKytdPXRoaXMuRFYrZ319Zi50PWU7Zi5jbGFtcCgpfWZ1bmN0aW9uIGJuQWRkKGIpe3ZhciBjPW5iaSgpO3RoaXMuYWRkVG8oYixjKTtyZXR1cm4gY31mdW5jdGlvbiBiblN1YnRyYWN0KGIpe3ZhciBjPW5iaSgpO3RoaXMuc3ViVG8oYixjKTtyZXR1cm4gY31mdW5jdGlvbiBibk11bHRpcGx5KGIpe3ZhciBjPW5iaSgpO3RoaXMubXVsdGlwbHlUbyhiLGMpO3JldHVybiBjfWZ1bmN0aW9uIGJuU3F1YXJlKCl7dmFyIGE9bmJpKCk7dGhpcy5zcXVhcmVUbyhhKTtyZXR1cm4gYX1mdW5jdGlvbiBibkRpdmlkZShiKXt2YXIgYz1uYmkoKTt0aGlzLmRpdlJlbVRvKGIsYyxudWxsKTtyZXR1cm4gY31mdW5jdGlvbiBiblJlbWFpbmRlcihiKXt2YXIgYz1uYmkoKTt0aGlzLmRpdlJlbVRvKGIsbnVsbCxjKTtyZXR1cm4gY31mdW5jdGlvbiBibkRpdmlkZUFuZFJlbWFpbmRlcihiKXt2YXIgZD1uYmkoKSxjPW5iaSgpO3RoaXMuZGl2UmVtVG8oYixkLGMpO3JldHVybiBuZXcgQXJyYXkoZCxjKX1mdW5jdGlvbiBibnBETXVsdGlwbHkoYSl7dGhpc1t0aGlzLnRdPXRoaXMuYW0oMCxhLTEsdGhpcywwLDAsdGhpcy50KTsrK3RoaXMudDt0aGlzLmNsYW1wKCl9ZnVuY3Rpb24gYm5wREFkZE9mZnNldChiLGEpe2lmKGI9PTApe3JldHVybn13aGlsZSh0aGlzLnQ8PWEpe3RoaXNbdGhpcy50KytdPTB9dGhpc1thXSs9Yjt3aGlsZSh0aGlzW2FdPj10aGlzLkRWKXt0aGlzW2FdLT10aGlzLkRWO2lmKCsrYT49dGhpcy50KXt0aGlzW3RoaXMudCsrXT0wfSsrdGhpc1thXX19ZnVuY3Rpb24gTnVsbEV4cCgpe31mdW5jdGlvbiBuTm9wKGEpe3JldHVybiBhfWZ1bmN0aW9uIG5NdWxUbyhhLGMsYil7YS5tdWx0aXBseVRvKGMsYil9ZnVuY3Rpb24gblNxclRvKGEsYil7YS5zcXVhcmVUbyhiKX1OdWxsRXhwLnByb3RvdHlwZS5jb252ZXJ0PW5Ob3A7TnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0PW5Ob3A7TnVsbEV4cC5wcm90b3R5cGUubXVsVG89bk11bFRvO051bGxFeHAucHJvdG90eXBlLnNxclRvPW5TcXJUbztmdW5jdGlvbiBiblBvdyhhKXtyZXR1cm4gdGhpcy5leHAoYSxuZXcgTnVsbEV4cCgpKX1mdW5jdGlvbiBibnBNdWx0aXBseUxvd2VyVG8oYixmLGUpe3ZhciBkPU1hdGgubWluKHRoaXMudCtiLnQsZik7ZS5zPTA7ZS50PWQ7d2hpbGUoZD4wKXtlWy0tZF09MH12YXIgYztmb3IoYz1lLnQtdGhpcy50O2Q8YzsrK2Qpe2VbZCt0aGlzLnRdPXRoaXMuYW0oMCxiW2RdLGUsZCwwLHRoaXMudCl9Zm9yKGM9TWF0aC5taW4oYi50LGYpO2Q8YzsrK2Qpe3RoaXMuYW0oMCxiW2RdLGUsZCwwLGYtZCl9ZS5jbGFtcCgpfWZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhiLGUsZCl7LS1lO3ZhciBjPWQudD10aGlzLnQrYi50LWU7ZC5zPTA7d2hpbGUoLS1jPj0wKXtkW2NdPTB9Zm9yKGM9TWF0aC5tYXgoZS10aGlzLnQsMCk7YzxiLnQ7KytjKXtkW3RoaXMudCtjLWVdPXRoaXMuYW0oZS1jLGJbY10sZCwwLDAsdGhpcy50K2MtZSl9ZC5jbGFtcCgpO2QuZHJTaGlmdFRvKDEsZCl9ZnVuY3Rpb24gQmFycmV0dChhKXt0aGlzLnIyPW5iaSgpO3RoaXMucTM9bmJpKCk7QmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIqYS50LHRoaXMucjIpO3RoaXMubXU9dGhpcy5yMi5kaXZpZGUoYSk7dGhpcy5tPWF9ZnVuY3Rpb24gYmFycmV0dENvbnZlcnQoYSl7aWYoYS5zPDB8fGEudD4yKnRoaXMubS50KXtyZXR1cm4gYS5tb2QodGhpcy5tKX1lbHNle2lmKGEuY29tcGFyZVRvKHRoaXMubSk8MCl7cmV0dXJuIGF9ZWxzZXt2YXIgYj1uYmkoKTthLmNvcHlUbyhiKTt0aGlzLnJlZHVjZShiKTtyZXR1cm4gYn19fWZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoYSl7cmV0dXJuIGF9ZnVuY3Rpb24gYmFycmV0dFJlZHVjZShhKXthLmRyU2hpZnRUbyh0aGlzLm0udC0xLHRoaXMucjIpO2lmKGEudD50aGlzLm0udCsxKXthLnQ9dGhpcy5tLnQrMTthLmNsYW1wKCl9dGhpcy5tdS5tdWx0aXBseVVwcGVyVG8odGhpcy5yMix0aGlzLm0udCsxLHRoaXMucTMpO3RoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMyx0aGlzLm0udCsxLHRoaXMucjIpO3doaWxlKGEuY29tcGFyZVRvKHRoaXMucjIpPDApe2EuZEFkZE9mZnNldCgxLHRoaXMubS50KzEpfWEuc3ViVG8odGhpcy5yMixhKTt3aGlsZShhLmNvbXBhcmVUbyh0aGlzLm0pPj0wKXthLnN1YlRvKHRoaXMubSxhKX19ZnVuY3Rpb24gYmFycmV0dFNxclRvKGEsYil7YS5zcXVhcmVUbyhiKTt0aGlzLnJlZHVjZShiKX1mdW5jdGlvbiBiYXJyZXR0TXVsVG8oYSxjLGIpe2EubXVsdGlwbHlUbyhjLGIpO3RoaXMucmVkdWNlKGIpfUJhcnJldHQucHJvdG90eXBlLmNvbnZlcnQ9YmFycmV0dENvbnZlcnQ7QmFycmV0dC5wcm90b3R5cGUucmV2ZXJ0PWJhcnJldHRSZXZlcnQ7QmFycmV0dC5wcm90b3R5cGUucmVkdWNlPWJhcnJldHRSZWR1Y2U7QmFycmV0dC5wcm90b3R5cGUubXVsVG89YmFycmV0dE11bFRvO0JhcnJldHQucHJvdG90eXBlLnNxclRvPWJhcnJldHRTcXJUbztmdW5jdGlvbiBibk1vZFBvdyhxLGYpe3ZhciBvPXEuYml0TGVuZ3RoKCksaCxiPW5idigxKSx2O2lmKG88PTApe3JldHVybiBifWVsc2V7aWYobzwxOCl7aD0xfWVsc2V7aWYobzw0OCl7aD0zfWVsc2V7aWYobzwxNDQpe2g9NH1lbHNle2lmKG88NzY4KXtoPTV9ZWxzZXtoPTZ9fX19fWlmKG88OCl7dj1uZXcgQ2xhc3NpYyhmKX1lbHNle2lmKGYuaXNFdmVuKCkpe3Y9bmV3IEJhcnJldHQoZil9ZWxzZXt2PW5ldyBNb250Z29tZXJ5KGYpfX12YXIgcD1uZXcgQXJyYXkoKSxkPTMscz1oLTEsYT0oMTw8aCktMTtwWzFdPXYuY29udmVydCh0aGlzKTtpZihoPjEpe3ZhciBBPW5iaSgpO3Yuc3FyVG8ocFsxXSxBKTt3aGlsZShkPD1hKXtwW2RdPW5iaSgpO3YubXVsVG8oQSxwW2QtMl0scFtkXSk7ZCs9Mn19dmFyIGw9cS50LTEseCx1PXRydWUsYz1uYmkoKSx5O289bmJpdHMocVtsXSktMTt3aGlsZShsPj0wKXtpZihvPj1zKXt4PShxW2xdPj4oby1zKSkmYX1lbHNle3g9KHFbbF0mKCgxPDwobysxKSktMSkpPDwocy1vKTtpZihsPjApe3h8PXFbbC0xXT4+KHRoaXMuREIrby1zKX19ZD1oO3doaWxlKCh4JjEpPT0wKXt4Pj49MTstLWR9aWYoKG8tPWQpPDApe28rPXRoaXMuREI7LS1sfWlmKHUpe3BbeF0uY29weVRvKGIpO3U9ZmFsc2V9ZWxzZXt3aGlsZShkPjEpe3Yuc3FyVG8oYixjKTt2LnNxclRvKGMsYik7ZC09Mn1pZihkPjApe3Yuc3FyVG8oYixjKX1lbHNle3k9YjtiPWM7Yz15fXYubXVsVG8oYyxwW3hdLGIpfXdoaWxlKGw+PTAmJihxW2xdJigxPDxvKSk9PTApe3Yuc3FyVG8oYixjKTt5PWI7Yj1jO2M9eTtpZigtLW88MCl7bz10aGlzLkRCLTE7LS1sfX19cmV0dXJuIHYucmV2ZXJ0KGIpfWZ1bmN0aW9uIGJuR0NEKGMpe3ZhciBiPSh0aGlzLnM8MCk/dGhpcy5uZWdhdGUoKTp0aGlzLmNsb25lKCk7dmFyIGg9KGMuczwwKT9jLm5lZ2F0ZSgpOmMuY2xvbmUoKTtpZihiLmNvbXBhcmVUbyhoKTwwKXt2YXIgZT1iO2I9aDtoPWV9dmFyIGQ9Yi5nZXRMb3dlc3RTZXRCaXQoKSxmPWguZ2V0TG93ZXN0U2V0Qml0KCk7aWYoZjwwKXtyZXR1cm4gYn1pZihkPGYpe2Y9ZH1pZihmPjApe2IuclNoaWZ0VG8oZixiKTtoLnJTaGlmdFRvKGYsaCl9d2hpbGUoYi5zaWdudW0oKT4wKXtpZigoZD1iLmdldExvd2VzdFNldEJpdCgpKT4wKXtiLnJTaGlmdFRvKGQsYil9aWYoKGQ9aC5nZXRMb3dlc3RTZXRCaXQoKSk+MCl7aC5yU2hpZnRUbyhkLGgpfWlmKGIuY29tcGFyZVRvKGgpPj0wKXtiLnN1YlRvKGgsYik7Yi5yU2hpZnRUbygxLGIpfWVsc2V7aC5zdWJUbyhiLGgpO2guclNoaWZ0VG8oMSxoKX19aWYoZj4wKXtoLmxTaGlmdFRvKGYsaCl9cmV0dXJuIGh9ZnVuY3Rpb24gYm5wTW9kSW50KGUpe2lmKGU8PTApe3JldHVybiAwfXZhciBjPXRoaXMuRFYlZSxiPSh0aGlzLnM8MCk/ZS0xOjA7aWYodGhpcy50PjApe2lmKGM9PTApe2I9dGhpc1swXSVlfWVsc2V7Zm9yKHZhciBhPXRoaXMudC0xO2E+PTA7LS1hKXtiPShjKmIrdGhpc1thXSklZX19fXJldHVybiBifWZ1bmN0aW9uIGJuTW9kSW52ZXJzZShmKXt2YXIgaj1mLmlzRXZlbigpO2lmKCh0aGlzLmlzRXZlbigpJiZqKXx8Zi5zaWdudW0oKT09MCl7cmV0dXJuIEJpZ0ludGVnZXIuWkVST312YXIgaT1mLmNsb25lKCksaD10aGlzLmNsb25lKCk7dmFyIGc9bmJ2KDEpLGU9bmJ2KDApLGw9bmJ2KDApLGs9bmJ2KDEpO3doaWxlKGkuc2lnbnVtKCkhPTApe3doaWxlKGkuaXNFdmVuKCkpe2kuclNoaWZ0VG8oMSxpKTtpZihqKXtpZighZy5pc0V2ZW4oKXx8IWUuaXNFdmVuKCkpe2cuYWRkVG8odGhpcyxnKTtlLnN1YlRvKGYsZSl9Zy5yU2hpZnRUbygxLGcpfWVsc2V7aWYoIWUuaXNFdmVuKCkpe2Uuc3ViVG8oZixlKX19ZS5yU2hpZnRUbygxLGUpfXdoaWxlKGguaXNFdmVuKCkpe2guclNoaWZ0VG8oMSxoKTtpZihqKXtpZighbC5pc0V2ZW4oKXx8IWsuaXNFdmVuKCkpe2wuYWRkVG8odGhpcyxsKTtrLnN1YlRvKGYsayl9bC5yU2hpZnRUbygxLGwpfWVsc2V7aWYoIWsuaXNFdmVuKCkpe2suc3ViVG8oZixrKX19ay5yU2hpZnRUbygxLGspfWlmKGkuY29tcGFyZVRvKGgpPj0wKXtpLnN1YlRvKGgsaSk7aWYoail7Zy5zdWJUbyhsLGcpfWUuc3ViVG8oayxlKX1lbHNle2guc3ViVG8oaSxoKTtpZihqKXtsLnN1YlRvKGcsbCl9ay5zdWJUbyhlLGspfX1pZihoLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkhPTApe3JldHVybiBCaWdJbnRlZ2VyLlpFUk99aWYoay5jb21wYXJlVG8oZik+PTApe3JldHVybiBrLnN1YnRyYWN0KGYpfWlmKGsuc2lnbnVtKCk8MCl7ay5hZGRUbyhmLGspfWVsc2V7cmV0dXJuIGt9aWYoay5zaWdudW0oKTwwKXtyZXR1cm4gay5hZGQoZil9ZWxzZXtyZXR1cm4ga319dmFyIGxvd3ByaW1lcz1bMiwzLDUsNywxMSwxMywxNywxOSwyMywyOSwzMSwzNyw0MSw0Myw0Nyw1Myw1OSw2MSw2Nyw3MSw3Myw3OSw4Myw4OSw5NywxMDEsMTAzLDEwNywxMDksMTEzLDEyNywxMzEsMTM3LDEzOSwxNDksMTUxLDE1NywxNjMsMTY3LDE3MywxNzksMTgxLDE5MSwxOTMsMTk3LDE5OSwyMTEsMjIzLDIyNywyMjksMjMzLDIzOSwyNDEsMjUxLDI1NywyNjMsMjY5LDI3MSwyNzcsMjgxLDI4MywyOTMsMzA3LDMxMSwzMTMsMzE3LDMzMSwzMzcsMzQ3LDM0OSwzNTMsMzU5LDM2NywzNzMsMzc5LDM4MywzODksMzk3LDQwMSw0MDksNDE5LDQyMSw0MzEsNDMzLDQzOSw0NDMsNDQ5LDQ1Nyw0NjEsNDYzLDQ2Nyw0NzksNDg3LDQ5MSw0OTksNTAzLDUwOSw1MjEsNTIzLDU0MSw1NDcsNTU3LDU2Myw1NjksNTcxLDU3Nyw1ODcsNTkzLDU5OSw2MDEsNjA3LDYxMyw2MTcsNjE5LDYzMSw2NDEsNjQzLDY0Nyw2NTMsNjU5LDY2MSw2NzMsNjc3LDY4Myw2OTEsNzAxLDcwOSw3MTksNzI3LDczMyw3MzksNzQzLDc1MSw3NTcsNzYxLDc2OSw3NzMsNzg3LDc5Nyw4MDksODExLDgyMSw4MjMsODI3LDgyOSw4MzksODUzLDg1Nyw4NTksODYzLDg3Nyw4ODEsODgzLDg4Nyw5MDcsOTExLDkxOSw5MjksOTM3LDk0MSw5NDcsOTUzLDk2Nyw5NzEsOTc3LDk4Myw5OTEsOTk3XTt2YXIgbHBsaW09KDE8PDI2KS9sb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXTtmdW5jdGlvbiBibklzUHJvYmFibGVQcmltZShlKXt2YXIgZCxiPXRoaXMuYWJzKCk7aWYoYi50PT0xJiZiWzBdPD1sb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXSl7Zm9yKGQ9MDtkPGxvd3ByaW1lcy5sZW5ndGg7KytkKXtpZihiWzBdPT1sb3dwcmltZXNbZF0pe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9aWYoYi5pc0V2ZW4oKSl7cmV0dXJuIGZhbHNlfWQ9MTt3aGlsZShkPGxvd3ByaW1lcy5sZW5ndGgpe3ZhciBhPWxvd3ByaW1lc1tkXSxjPWQrMTt3aGlsZShjPGxvd3ByaW1lcy5sZW5ndGgmJmE8bHBsaW0pe2EqPWxvd3ByaW1lc1tjKytdfWE9Yi5tb2RJbnQoYSk7d2hpbGUoZDxjKXtpZihhJWxvd3ByaW1lc1tkKytdPT0wKXtyZXR1cm4gZmFsc2V9fX1yZXR1cm4gYi5taWxsZXJSYWJpbihlKX1mdW5jdGlvbiBibnBNaWxsZXJSYWJpbihmKXt2YXIgZz10aGlzLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTt2YXIgYz1nLmdldExvd2VzdFNldEJpdCgpO2lmKGM8PTApe3JldHVybiBmYWxzZX12YXIgaD1nLnNoaWZ0UmlnaHQoYyk7Zj0oZisxKT4+MTtpZihmPmxvd3ByaW1lcy5sZW5ndGgpe2Y9bG93cHJpbWVzLmxlbmd0aH12YXIgYj1uYmkoKTtmb3IodmFyIGU9MDtlPGY7KytlKXtiLmZyb21JbnQobG93cHJpbWVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSpsb3dwcmltZXMubGVuZ3RoKV0pO3ZhciBsPWIubW9kUG93KGgsdGhpcyk7aWYobC5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpIT0wJiZsLmNvbXBhcmVUbyhnKSE9MCl7dmFyIGQ9MTt3aGlsZShkKys8YyYmbC5jb21wYXJlVG8oZykhPTApe2w9bC5tb2RQb3dJbnQoMix0aGlzKTtpZihsLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSk9PTApe3JldHVybiBmYWxzZX19aWYobC5jb21wYXJlVG8oZykhPTApe3JldHVybiBmYWxzZX19fXJldHVybiB0cnVlfUJpZ0ludGVnZXIucHJvdG90eXBlLmNodW5rU2l6ZT1ibnBDaHVua1NpemU7QmlnSW50ZWdlci5wcm90b3R5cGUudG9SYWRpeD1ibnBUb1JhZGl4O0JpZ0ludGVnZXIucHJvdG90eXBlLmZyb21SYWRpeD1ibnBGcm9tUmFkaXg7QmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbU51bWJlcj1ibnBGcm9tTnVtYmVyO0JpZ0ludGVnZXIucHJvdG90eXBlLmJpdHdpc2VUbz1ibnBCaXR3aXNlVG87QmlnSW50ZWdlci5wcm90b3R5cGUuY2hhbmdlQml0PWJucENoYW5nZUJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGRUbz1ibnBBZGRUbztCaWdJbnRlZ2VyLnByb3RvdHlwZS5kTXVsdGlwbHk9Ym5wRE11bHRpcGx5O0JpZ0ludGVnZXIucHJvdG90eXBlLmRBZGRPZmZzZXQ9Ym5wREFkZE9mZnNldDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseUxvd2VyVG89Ym5wTXVsdGlwbHlMb3dlclRvO0JpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VXBwZXJUbz1ibnBNdWx0aXBseVVwcGVyVG87QmlnSW50ZWdlci5wcm90b3R5cGUubW9kSW50PWJucE1vZEludDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5taWxsZXJSYWJpbj1ibnBNaWxsZXJSYWJpbjtCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbG9uZT1ibkNsb25lO0JpZ0ludGVnZXIucHJvdG90eXBlLmludFZhbHVlPWJuSW50VmFsdWU7QmlnSW50ZWdlci5wcm90b3R5cGUuYnl0ZVZhbHVlPWJuQnl0ZVZhbHVlO0JpZ0ludGVnZXIucHJvdG90eXBlLnNob3J0VmFsdWU9Ym5TaG9ydFZhbHVlO0JpZ0ludGVnZXIucHJvdG90eXBlLnNpZ251bT1iblNpZ051bTtCaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheT1iblRvQnl0ZUFycmF5O0JpZ0ludGVnZXIucHJvdG90eXBlLmVxdWFscz1ibkVxdWFscztCaWdJbnRlZ2VyLnByb3RvdHlwZS5taW49Ym5NaW47QmlnSW50ZWdlci5wcm90b3R5cGUubWF4PWJuTWF4O0JpZ0ludGVnZXIucHJvdG90eXBlLmFuZD1ibkFuZDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5vcj1ibk9yO0JpZ0ludGVnZXIucHJvdG90eXBlLnhvcj1iblhvcjtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmROb3Q9Ym5BbmROb3Q7QmlnSW50ZWdlci5wcm90b3R5cGUubm90PWJuTm90O0JpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0TGVmdD1iblNoaWZ0TGVmdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zaGlmdFJpZ2h0PWJuU2hpZnRSaWdodDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5nZXRMb3dlc3RTZXRCaXQ9Ym5HZXRMb3dlc3RTZXRCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuYml0Q291bnQ9Ym5CaXRDb3VudDtCaWdJbnRlZ2VyLnByb3RvdHlwZS50ZXN0Qml0PWJuVGVzdEJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zZXRCaXQ9Ym5TZXRCaXQ7QmlnSW50ZWdlci5wcm90b3R5cGUuY2xlYXJCaXQ9Ym5DbGVhckJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5mbGlwQml0PWJuRmxpcEJpdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5hZGQ9Ym5BZGQ7QmlnSW50ZWdlci5wcm90b3R5cGUuc3VidHJhY3Q9Ym5TdWJ0cmFjdDtCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseT1ibk11bHRpcGx5O0JpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZT1ibkRpdmlkZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5yZW1haW5kZXI9Ym5SZW1haW5kZXI7QmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlQW5kUmVtYWluZGVyPWJuRGl2aWRlQW5kUmVtYWluZGVyO0JpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvdz1ibk1vZFBvdztCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnZlcnNlPWJuTW9kSW52ZXJzZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5wb3c9Ym5Qb3c7QmlnSW50ZWdlci5wcm90b3R5cGUuZ2NkPWJuR0NEO0JpZ0ludGVnZXIucHJvdG90eXBlLmlzUHJvYmFibGVQcmltZT1ibklzUHJvYmFibGVQcmltZTtCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmU9Ym5TcXVhcmU7XG4vKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi9cclxuICovXHJcbmZ1bmN0aW9uIEFyY2ZvdXIoKXt0aGlzLmk9MDt0aGlzLmo9MDt0aGlzLlM9bmV3IEFycmF5KCl9ZnVuY3Rpb24gQVJDNGluaXQoZCl7dmFyIGMsYSxiO2ZvcihjPTA7YzwyNTY7KytjKXt0aGlzLlNbY109Y31hPTA7Zm9yKGM9MDtjPDI1NjsrK2Mpe2E9KGErdGhpcy5TW2NdK2RbYyVkLmxlbmd0aF0pJjI1NTtiPXRoaXMuU1tjXTt0aGlzLlNbY109dGhpcy5TW2FdO3RoaXMuU1thXT1ifXRoaXMuaT0wO3RoaXMuaj0wfWZ1bmN0aW9uIEFSQzRuZXh0KCl7dmFyIGE7dGhpcy5pPSh0aGlzLmkrMSkmMjU1O3RoaXMuaj0odGhpcy5qK3RoaXMuU1t0aGlzLmldKSYyNTU7YT10aGlzLlNbdGhpcy5pXTt0aGlzLlNbdGhpcy5pXT10aGlzLlNbdGhpcy5qXTt0aGlzLlNbdGhpcy5qXT1hO3JldHVybiB0aGlzLlNbKGErdGhpcy5TW3RoaXMuaV0pJjI1NV19QXJjZm91ci5wcm90b3R5cGUuaW5pdD1BUkM0aW5pdDtBcmNmb3VyLnByb3RvdHlwZS5uZXh0PUFSQzRuZXh0O2Z1bmN0aW9uIHBybmdfbmV3c3RhdGUoKXtyZXR1cm4gbmV3IEFyY2ZvdXIoKX12YXIgcm5nX3BzaXplPTI1Njtcbi8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xyXG4gKi9cclxudmFyIHJuZ19zdGF0ZTt2YXIgcm5nX3Bvb2w7dmFyIHJuZ19wcHRyO2Z1bmN0aW9uIHJuZ19zZWVkX2ludChhKXtybmdfcG9vbFtybmdfcHB0cisrXV49YSYyNTU7cm5nX3Bvb2xbcm5nX3BwdHIrK11ePShhPj44KSYyNTU7cm5nX3Bvb2xbcm5nX3BwdHIrK11ePShhPj4xNikmMjU1O3JuZ19wb29sW3JuZ19wcHRyKytdXj0oYT4+MjQpJjI1NTtpZihybmdfcHB0cj49cm5nX3BzaXplKXtybmdfcHB0ci09cm5nX3BzaXplfX1mdW5jdGlvbiBybmdfc2VlZF90aW1lKCl7cm5nX3NlZWRfaW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKX1pZihybmdfcG9vbD09bnVsbCl7cm5nX3Bvb2w9bmV3IEFycmF5KCk7cm5nX3BwdHI9MDt2YXIgdDtpZih3aW5kb3chPT11bmRlZmluZWQmJih3aW5kb3cuY3J5cHRvIT09dW5kZWZpbmVkfHx3aW5kb3cubXNDcnlwdG8hPT11bmRlZmluZWQpKXt2YXIgY3J5cHRvPXdpbmRvdy5jcnlwdG98fHdpbmRvdy5tc0NyeXB0bztpZihjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKXt2YXIgdWE9bmV3IFVpbnQ4QXJyYXkoMzIpO2NyeXB0by5nZXRSYW5kb21WYWx1ZXModWEpO2Zvcih0PTA7dDwzMjsrK3Qpe3JuZ19wb29sW3JuZ19wcHRyKytdPXVhW3RdfX1lbHNle2lmKG5hdmlnYXRvci5hcHBOYW1lPT1cIk5ldHNjYXBlXCImJm5hdmlnYXRvci5hcHBWZXJzaW9uPFwiNVwiKXt2YXIgej13aW5kb3cuY3J5cHRvLnJhbmRvbSgzMik7Zm9yKHQ9MDt0PHoubGVuZ3RoOysrdCl7cm5nX3Bvb2xbcm5nX3BwdHIrK109ei5jaGFyQ29kZUF0KHQpJjI1NX19fX13aGlsZShybmdfcHB0cjxybmdfcHNpemUpe3Q9TWF0aC5mbG9vcig2NTUzNipNYXRoLnJhbmRvbSgpKTtybmdfcG9vbFtybmdfcHB0cisrXT10Pj4+ODtybmdfcG9vbFtybmdfcHB0cisrXT10JjI1NX1ybmdfcHB0cj0wO3JuZ19zZWVkX3RpbWUoKX1mdW5jdGlvbiBybmdfZ2V0X2J5dGUoKXtpZihybmdfc3RhdGU9PW51bGwpe3JuZ19zZWVkX3RpbWUoKTtybmdfc3RhdGU9cHJuZ19uZXdzdGF0ZSgpO3JuZ19zdGF0ZS5pbml0KHJuZ19wb29sKTtmb3Iocm5nX3BwdHI9MDtybmdfcHB0cjxybmdfcG9vbC5sZW5ndGg7KytybmdfcHB0cil7cm5nX3Bvb2xbcm5nX3BwdHJdPTB9cm5nX3BwdHI9MH1yZXR1cm4gcm5nX3N0YXRlLm5leHQoKX1mdW5jdGlvbiBybmdfZ2V0X2J5dGVzKGIpe3ZhciBhO2ZvcihhPTA7YTxiLmxlbmd0aDsrK2Epe2JbYV09cm5nX2dldF9ieXRlKCl9fWZ1bmN0aW9uIFNlY3VyZVJhbmRvbSgpe31TZWN1cmVSYW5kb20ucHJvdG90eXBlLm5leHRCeXRlcz1ybmdfZ2V0X2J5dGVzO1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG5mdW5jdGlvbiBwYXJzZUJpZ0ludChiLGEpe3JldHVybiBuZXcgQmlnSW50ZWdlcihiLGEpfWZ1bmN0aW9uIGxpbmVicmsoYyxkKXt2YXIgYT1cIlwiO3ZhciBiPTA7d2hpbGUoYitkPGMubGVuZ3RoKXthKz1jLnN1YnN0cmluZyhiLGIrZCkrXCJcXG5cIjtiKz1kfXJldHVybiBhK2Muc3Vic3RyaW5nKGIsYy5sZW5ndGgpfWZ1bmN0aW9uIGJ5dGUySGV4KGEpe2lmKGE8MTYpe3JldHVyblwiMFwiK2EudG9TdHJpbmcoMTYpfWVsc2V7cmV0dXJuIGEudG9TdHJpbmcoMTYpfX1mdW5jdGlvbiBwa2NzMXBhZDIoZSxoKXtpZihoPGUubGVuZ3RoKzExKXt0aHJvd1wiTWVzc2FnZSB0b28gbG9uZyBmb3IgUlNBXCI7cmV0dXJuIG51bGx9dmFyIGc9bmV3IEFycmF5KCk7dmFyIGQ9ZS5sZW5ndGgtMTt3aGlsZShkPj0wJiZoPjApe3ZhciBmPWUuY2hhckNvZGVBdChkLS0pO2lmKGY8MTI4KXtnWy0taF09Zn1lbHNle2lmKChmPjEyNykmJihmPDIwNDgpKXtnWy0taF09KGYmNjMpfDEyODtnWy0taF09KGY+PjYpfDE5Mn1lbHNle2dbLS1oXT0oZiY2Myl8MTI4O2dbLS1oXT0oKGY+PjYpJjYzKXwxMjg7Z1stLWhdPShmPj4xMil8MjI0fX19Z1stLWhdPTA7dmFyIGI9bmV3IFNlY3VyZVJhbmRvbSgpO3ZhciBhPW5ldyBBcnJheSgpO3doaWxlKGg+Mil7YVswXT0wO3doaWxlKGFbMF09PTApe2IubmV4dEJ5dGVzKGEpfWdbLS1oXT1hWzBdfWdbLS1oXT0yO2dbLS1oXT0wO3JldHVybiBuZXcgQmlnSW50ZWdlcihnKX1mdW5jdGlvbiBvYWVwX21nZjFfYXJyKGMsYSxlKXt2YXIgYj1cIlwiLGQ9MDt3aGlsZShiLmxlbmd0aDxhKXtiKz1lKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGMuY29uY2F0KFsoZCY0Mjc4MTkwMDgwKT4+MjQsKGQmMTY3MTE2ODApPj4xNiwoZCY2NTI4MCk+PjgsZCYyNTVdKSkpO2QrPTF9cmV0dXJuIGJ9ZnVuY3Rpb24gb2FlcF9wYWQocSxhLGYsbCl7dmFyIGM9S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdDt2YXIgbz1LSlVSLmNyeXB0by5VdGlsO3ZhciBiPW51bGw7aWYoIWYpe2Y9XCJzaGExXCJ9aWYodHlwZW9mIGY9PT1cInN0cmluZ1wiKXtiPWMuZ2V0Q2Fub25pY2FsQWxnTmFtZShmKTtsPWMuZ2V0SGFzaExlbmd0aChiKTtmPWZ1bmN0aW9uKGkpe3JldHVybiBoZXh0b3JzdHIoby5oYXNoSGV4KHJzdHJ0b2hleChpKSxiKSl9fWlmKHEubGVuZ3RoKzIqbCsyPmEpe3Rocm93XCJNZXNzYWdlIHRvbyBsb25nIGZvciBSU0FcIn12YXIgaz1cIlwiLGU7Zm9yKGU9MDtlPGEtcS5sZW5ndGgtMipsLTI7ZSs9MSl7ays9XCJcXHgwMFwifXZhciBoPWYoXCJcIikraytcIlxceDAxXCIrcTt2YXIgZz1uZXcgQXJyYXkobCk7bmV3IFNlY3VyZVJhbmRvbSgpLm5leHRCeXRlcyhnKTt2YXIgaj1vYWVwX21nZjFfYXJyKGcsaC5sZW5ndGgsZik7dmFyIHA9W107Zm9yKGU9MDtlPGgubGVuZ3RoO2UrPTEpe3BbZV09aC5jaGFyQ29kZUF0KGUpXmouY2hhckNvZGVBdChlKX12YXIgbT1vYWVwX21nZjFfYXJyKHAsZy5sZW5ndGgsZik7dmFyIGQ9WzBdO2ZvcihlPTA7ZTxnLmxlbmd0aDtlKz0xKXtkW2UrMV09Z1tlXV5tLmNoYXJDb2RlQXQoZSl9cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGQuY29uY2F0KHApKX1mdW5jdGlvbiBSU0FLZXkoKXt0aGlzLm49bnVsbDt0aGlzLmU9MDt0aGlzLmQ9bnVsbDt0aGlzLnA9bnVsbDt0aGlzLnE9bnVsbDt0aGlzLmRtcDE9bnVsbDt0aGlzLmRtcTE9bnVsbDt0aGlzLmNvZWZmPW51bGx9ZnVuY3Rpb24gUlNBU2V0UHVibGljKGIsYSl7dGhpcy5pc1B1YmxpYz10cnVlO3RoaXMuaXNQcml2YXRlPWZhbHNlO2lmKHR5cGVvZiBiIT09XCJzdHJpbmdcIil7dGhpcy5uPWI7dGhpcy5lPWF9ZWxzZXtpZihiIT1udWxsJiZhIT1udWxsJiZiLmxlbmd0aD4wJiZhLmxlbmd0aD4wKXt0aGlzLm49cGFyc2VCaWdJbnQoYiwxNik7dGhpcy5lPXBhcnNlSW50KGEsMTYpfWVsc2V7dGhyb3dcIkludmFsaWQgUlNBIHB1YmxpYyBrZXlcIn19fWZ1bmN0aW9uIFJTQURvUHVibGljKGEpe3JldHVybiBhLm1vZFBvd0ludCh0aGlzLmUsdGhpcy5uKX1mdW5jdGlvbiBSU0FFbmNyeXB0KGQpe3ZhciBhPXBrY3MxcGFkMihkLCh0aGlzLm4uYml0TGVuZ3RoKCkrNyk+PjMpO2lmKGE9PW51bGwpe3JldHVybiBudWxsfXZhciBlPXRoaXMuZG9QdWJsaWMoYSk7aWYoZT09bnVsbCl7cmV0dXJuIG51bGx9dmFyIGI9ZS50b1N0cmluZygxNik7aWYoKGIubGVuZ3RoJjEpPT0wKXtyZXR1cm4gYn1lbHNle3JldHVyblwiMFwiK2J9fWZ1bmN0aW9uIFJTQUVuY3J5cHRPQUVQKGYsZSxiKXt2YXIgYT1vYWVwX3BhZChmLCh0aGlzLm4uYml0TGVuZ3RoKCkrNyk+PjMsZSxiKTtpZihhPT1udWxsKXtyZXR1cm4gbnVsbH12YXIgZz10aGlzLmRvUHVibGljKGEpO2lmKGc9PW51bGwpe3JldHVybiBudWxsfXZhciBkPWcudG9TdHJpbmcoMTYpO2lmKChkLmxlbmd0aCYxKT09MCl7cmV0dXJuIGR9ZWxzZXtyZXR1cm5cIjBcIitkfX1SU0FLZXkucHJvdG90eXBlLmRvUHVibGljPVJTQURvUHVibGljO1JTQUtleS5wcm90b3R5cGUuc2V0UHVibGljPVJTQVNldFB1YmxpYztSU0FLZXkucHJvdG90eXBlLmVuY3J5cHQ9UlNBRW5jcnlwdDtSU0FLZXkucHJvdG90eXBlLmVuY3J5cHRPQUVQPVJTQUVuY3J5cHRPQUVQO1JTQUtleS5wcm90b3R5cGUudHlwZT1cIlJTQVwiO1xuLyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vXHJcbiAqL1xyXG5mdW5jdGlvbiBFQ0ZpZWxkRWxlbWVudEZwKGIsYSl7dGhpcy54PWE7dGhpcy5xPWJ9ZnVuY3Rpb24gZmVGcEVxdWFscyhhKXtpZihhPT10aGlzKXtyZXR1cm4gdHJ1ZX1yZXR1cm4odGhpcy5xLmVxdWFscyhhLnEpJiZ0aGlzLnguZXF1YWxzKGEueCkpfWZ1bmN0aW9uIGZlRnBUb0JpZ0ludGVnZXIoKXtyZXR1cm4gdGhpcy54fWZ1bmN0aW9uIGZlRnBOZWdhdGUoKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5uZWdhdGUoKS5tb2QodGhpcy5xKSl9ZnVuY3Rpb24gZmVGcEFkZChhKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5hZGQoYS50b0JpZ0ludGVnZXIoKSkubW9kKHRoaXMucSkpfWZ1bmN0aW9uIGZlRnBTdWJ0cmFjdChhKXtyZXR1cm4gbmV3IEVDRmllbGRFbGVtZW50RnAodGhpcy5xLHRoaXMueC5zdWJ0cmFjdChhLnRvQmlnSW50ZWdlcigpKS5tb2QodGhpcy5xKSl9ZnVuY3Rpb24gZmVGcE11bHRpcGx5KGEpe3JldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsdGhpcy54Lm11bHRpcGx5KGEudG9CaWdJbnRlZ2VyKCkpLm1vZCh0aGlzLnEpKX1mdW5jdGlvbiBmZUZwU3F1YXJlKCl7cmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLnguc3F1YXJlKCkubW9kKHRoaXMucSkpfWZ1bmN0aW9uIGZlRnBEaXZpZGUoYSl7cmV0dXJuIG5ldyBFQ0ZpZWxkRWxlbWVudEZwKHRoaXMucSx0aGlzLngubXVsdGlwbHkoYS50b0JpZ0ludGVnZXIoKS5tb2RJbnZlcnNlKHRoaXMucSkpLm1vZCh0aGlzLnEpKX1FQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5lcXVhbHM9ZmVGcEVxdWFscztFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS50b0JpZ0ludGVnZXI9ZmVGcFRvQmlnSW50ZWdlcjtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5uZWdhdGU9ZmVGcE5lZ2F0ZTtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5hZGQ9ZmVGcEFkZDtFQ0ZpZWxkRWxlbWVudEZwLnByb3RvdHlwZS5zdWJ0cmFjdD1mZUZwU3VidHJhY3Q7RUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUubXVsdGlwbHk9ZmVGcE11bHRpcGx5O0VDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLnNxdWFyZT1mZUZwU3F1YXJlO0VDRmllbGRFbGVtZW50RnAucHJvdG90eXBlLmRpdmlkZT1mZUZwRGl2aWRlO2Z1bmN0aW9uIEVDUG9pbnRGcChjLGEsZCxiKXt0aGlzLmN1cnZlPWM7dGhpcy54PWE7dGhpcy55PWQ7aWYoYj09bnVsbCl7dGhpcy56PUJpZ0ludGVnZXIuT05FfWVsc2V7dGhpcy56PWJ9dGhpcy56aW52PW51bGx9ZnVuY3Rpb24gcG9pbnRGcEdldFgoKXtpZih0aGlzLnppbnY9PW51bGwpe3RoaXMuemludj10aGlzLnoubW9kSW52ZXJzZSh0aGlzLmN1cnZlLnEpfXJldHVybiB0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKHRoaXMueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnppbnYpLm1vZCh0aGlzLmN1cnZlLnEpKX1mdW5jdGlvbiBwb2ludEZwR2V0WSgpe2lmKHRoaXMuemludj09bnVsbCl7dGhpcy56aW52PXRoaXMuei5tb2RJbnZlcnNlKHRoaXMuY3VydmUucSl9cmV0dXJuIHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIodGhpcy55LnRvQmlnSW50ZWdlcigpLm11bHRpcGx5KHRoaXMuemludikubW9kKHRoaXMuY3VydmUucSkpfWZ1bmN0aW9uIHBvaW50RnBFcXVhbHMoYSl7aWYoYT09dGhpcyl7cmV0dXJuIHRydWV9aWYodGhpcy5pc0luZmluaXR5KCkpe3JldHVybiBhLmlzSW5maW5pdHkoKX1pZihhLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXMuaXNJbmZpbml0eSgpfXZhciBjLGI7Yz1hLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLnkudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkoYS56KSkubW9kKHRoaXMuY3VydmUucSk7aWYoIWMuZXF1YWxzKEJpZ0ludGVnZXIuWkVSTykpe3JldHVybiBmYWxzZX1iPWEueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueC50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShhLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTtyZXR1cm4gYi5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKX1mdW5jdGlvbiBwb2ludEZwSXNJbmZpbml0eSgpe2lmKCh0aGlzLng9PW51bGwpJiYodGhpcy55PT1udWxsKSl7cmV0dXJuIHRydWV9cmV0dXJuIHRoaXMuei5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSYmIXRoaXMueS50b0JpZ0ludGVnZXIoKS5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKX1mdW5jdGlvbiBwb2ludEZwTmVnYXRlKCl7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSx0aGlzLngsdGhpcy55Lm5lZ2F0ZSgpLHRoaXMueil9ZnVuY3Rpb24gcG9pbnRGcEFkZChsKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIGx9aWYobC5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzfXZhciBwPWwueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseSh0aGlzLnopLnN1YnRyYWN0KHRoaXMueS50b0JpZ0ludGVnZXIoKS5tdWx0aXBseShsLnopKS5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgbz1sLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkodGhpcy56KS5zdWJ0cmFjdCh0aGlzLngudG9CaWdJbnRlZ2VyKCkubXVsdGlwbHkobC56KSkubW9kKHRoaXMuY3VydmUucSk7aWYoQmlnSW50ZWdlci5aRVJPLmVxdWFscyhvKSl7aWYoQmlnSW50ZWdlci5aRVJPLmVxdWFscyhwKSl7cmV0dXJuIHRoaXMudHdpY2UoKX1yZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBqPW5ldyBCaWdJbnRlZ2VyKFwiM1wiKTt2YXIgZT10aGlzLngudG9CaWdJbnRlZ2VyKCk7dmFyIG49dGhpcy55LnRvQmlnSW50ZWdlcigpO3ZhciBjPWwueC50b0JpZ0ludGVnZXIoKTt2YXIgaz1sLnkudG9CaWdJbnRlZ2VyKCk7dmFyIG09by5zcXVhcmUoKTt2YXIgaT1tLm11bHRpcGx5KG8pO3ZhciBkPWUubXVsdGlwbHkobSk7dmFyIGc9cC5zcXVhcmUoKS5tdWx0aXBseSh0aGlzLnopO3ZhciBhPWcuc3VidHJhY3QoZC5zaGlmdExlZnQoMSkpLm11bHRpcGx5KGwueikuc3VidHJhY3QoaSkubXVsdGlwbHkobykubW9kKHRoaXMuY3VydmUucSk7dmFyIGg9ZC5tdWx0aXBseShqKS5tdWx0aXBseShwKS5zdWJ0cmFjdChuLm11bHRpcGx5KGkpKS5zdWJ0cmFjdChnLm11bHRpcGx5KHApKS5tdWx0aXBseShsLnopLmFkZChwLm11bHRpcGx5KGkpKS5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgZj1pLm11bHRpcGx5KHRoaXMueikubXVsdGlwbHkobC56KS5tb2QodGhpcy5jdXJ2ZS5xKTtyZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLmN1cnZlLHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoYSksdGhpcy5jdXJ2ZS5mcm9tQmlnSW50ZWdlcihoKSxmKX1mdW5jdGlvbiBwb2ludEZwVHdpY2UoKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXN9aWYodGhpcy55LnRvQmlnSW50ZWdlcigpLnNpZ251bSgpPT0wKXtyZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBnPW5ldyBCaWdJbnRlZ2VyKFwiM1wiKTt2YXIgYz10aGlzLngudG9CaWdJbnRlZ2VyKCk7dmFyIGg9dGhpcy55LnRvQmlnSW50ZWdlcigpO3ZhciBlPWgubXVsdGlwbHkodGhpcy56KTt2YXIgaj1lLm11bHRpcGx5KGgpLm1vZCh0aGlzLmN1cnZlLnEpO3ZhciBpPXRoaXMuY3VydmUuYS50b0JpZ0ludGVnZXIoKTt2YXIgaz1jLnNxdWFyZSgpLm11bHRpcGx5KGcpO2lmKCFCaWdJbnRlZ2VyLlpFUk8uZXF1YWxzKGkpKXtrPWsuYWRkKHRoaXMuei5zcXVhcmUoKS5tdWx0aXBseShpKSl9az1rLm1vZCh0aGlzLmN1cnZlLnEpO3ZhciBiPWsuc3F1YXJlKCkuc3VidHJhY3QoYy5zaGlmdExlZnQoMykubXVsdGlwbHkoaikpLnNoaWZ0TGVmdCgxKS5tdWx0aXBseShlKS5tb2QodGhpcy5jdXJ2ZS5xKTt2YXIgZj1rLm11bHRpcGx5KGcpLm11bHRpcGx5KGMpLnN1YnRyYWN0KGouc2hpZnRMZWZ0KDEpKS5zaGlmdExlZnQoMikubXVsdGlwbHkoaikuc3VidHJhY3Qoay5zcXVhcmUoKS5tdWx0aXBseShrKSkubW9kKHRoaXMuY3VydmUucSk7dmFyIGQ9ZS5zcXVhcmUoKS5tdWx0aXBseShlKS5zaGlmdExlZnQoMykubW9kKHRoaXMuY3VydmUucSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSx0aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKGIpLHRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoZiksZCl9ZnVuY3Rpb24gcG9pbnRGcE11bHRpcGx5KGIpe2lmKHRoaXMuaXNJbmZpbml0eSgpKXtyZXR1cm4gdGhpc31pZihiLnNpZ251bSgpPT0wKXtyZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBnPWI7dmFyIGY9Zy5tdWx0aXBseShuZXcgQmlnSW50ZWdlcihcIjNcIikpO3ZhciBsPXRoaXMubmVnYXRlKCk7dmFyIGQ9dGhpczt2YXIgYztmb3IoYz1mLmJpdExlbmd0aCgpLTI7Yz4wOy0tYyl7ZD1kLnR3aWNlKCk7dmFyIGE9Zi50ZXN0Qml0KGMpO3ZhciBqPWcudGVzdEJpdChjKTtpZihhIT1qKXtkPWQuYWRkKGE/dGhpczpsKX19cmV0dXJuIGR9ZnVuY3Rpb24gcG9pbnRGcE11bHRpcGx5VHdvKGMsYSxiKXt2YXIgZDtpZihjLmJpdExlbmd0aCgpPmIuYml0TGVuZ3RoKCkpe2Q9Yy5iaXRMZW5ndGgoKS0xfWVsc2V7ZD1iLmJpdExlbmd0aCgpLTF9dmFyIGY9dGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpO3ZhciBlPXRoaXMuYWRkKGEpO3doaWxlKGQ+PTApe2Y9Zi50d2ljZSgpO2lmKGMudGVzdEJpdChkKSl7aWYoYi50ZXN0Qml0KGQpKXtmPWYuYWRkKGUpfWVsc2V7Zj1mLmFkZCh0aGlzKX19ZWxzZXtpZihiLnRlc3RCaXQoZCkpe2Y9Zi5hZGQoYSl9fS0tZH1yZXR1cm4gZn1FQ1BvaW50RnAucHJvdG90eXBlLmdldFg9cG9pbnRGcEdldFg7RUNQb2ludEZwLnByb3RvdHlwZS5nZXRZPXBvaW50RnBHZXRZO0VDUG9pbnRGcC5wcm90b3R5cGUuZXF1YWxzPXBvaW50RnBFcXVhbHM7RUNQb2ludEZwLnByb3RvdHlwZS5pc0luZmluaXR5PXBvaW50RnBJc0luZmluaXR5O0VDUG9pbnRGcC5wcm90b3R5cGUubmVnYXRlPXBvaW50RnBOZWdhdGU7RUNQb2ludEZwLnByb3RvdHlwZS5hZGQ9cG9pbnRGcEFkZDtFQ1BvaW50RnAucHJvdG90eXBlLnR3aWNlPXBvaW50RnBUd2ljZTtFQ1BvaW50RnAucHJvdG90eXBlLm11bHRpcGx5PXBvaW50RnBNdWx0aXBseTtFQ1BvaW50RnAucHJvdG90eXBlLm11bHRpcGx5VHdvPXBvaW50RnBNdWx0aXBseVR3bztmdW5jdGlvbiBFQ0N1cnZlRnAoZSxkLGMpe3RoaXMucT1lO3RoaXMuYT10aGlzLmZyb21CaWdJbnRlZ2VyKGQpO3RoaXMuYj10aGlzLmZyb21CaWdJbnRlZ2VyKGMpO3RoaXMuaW5maW5pdHk9bmV3IEVDUG9pbnRGcCh0aGlzLG51bGwsbnVsbCl9ZnVuY3Rpb24gY3VydmVGcEdldFEoKXtyZXR1cm4gdGhpcy5xfWZ1bmN0aW9uIGN1cnZlRnBHZXRBKCl7cmV0dXJuIHRoaXMuYX1mdW5jdGlvbiBjdXJ2ZUZwR2V0Qigpe3JldHVybiB0aGlzLmJ9ZnVuY3Rpb24gY3VydmVGcEVxdWFscyhhKXtpZihhPT10aGlzKXtyZXR1cm4gdHJ1ZX1yZXR1cm4odGhpcy5xLmVxdWFscyhhLnEpJiZ0aGlzLmEuZXF1YWxzKGEuYSkmJnRoaXMuYi5lcXVhbHMoYS5iKSl9ZnVuY3Rpb24gY3VydmVGcEdldEluZmluaXR5KCl7cmV0dXJuIHRoaXMuaW5maW5pdHl9ZnVuY3Rpb24gY3VydmVGcEZyb21CaWdJbnRlZ2VyKGEpe3JldHVybiBuZXcgRUNGaWVsZEVsZW1lbnRGcCh0aGlzLnEsYSl9ZnVuY3Rpb24gY3VydmVGcERlY29kZVBvaW50SGV4KGQpe3N3aXRjaChwYXJzZUludChkLnN1YnN0cigwLDIpLDE2KSl7Y2FzZSAwOnJldHVybiB0aGlzLmluZmluaXR5O2Nhc2UgMjpjYXNlIDM6cmV0dXJuIG51bGw7Y2FzZSA0OmNhc2UgNjpjYXNlIDc6dmFyIGE9KGQubGVuZ3RoLTIpLzI7dmFyIGM9ZC5zdWJzdHIoMixhKTt2YXIgYj1kLnN1YnN0cihhKzIsYSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcyx0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKGMsMTYpKSx0aGlzLmZyb21CaWdJbnRlZ2VyKG5ldyBCaWdJbnRlZ2VyKGIsMTYpKSk7ZGVmYXVsdDpyZXR1cm4gbnVsbH19RUNDdXJ2ZUZwLnByb3RvdHlwZS5nZXRRPWN1cnZlRnBHZXRRO0VDQ3VydmVGcC5wcm90b3R5cGUuZ2V0QT1jdXJ2ZUZwR2V0QTtFQ0N1cnZlRnAucHJvdG90eXBlLmdldEI9Y3VydmVGcEdldEI7RUNDdXJ2ZUZwLnByb3RvdHlwZS5lcXVhbHM9Y3VydmVGcEVxdWFscztFQ0N1cnZlRnAucHJvdG90eXBlLmdldEluZmluaXR5PWN1cnZlRnBHZXRJbmZpbml0eTtFQ0N1cnZlRnAucHJvdG90eXBlLmZyb21CaWdJbnRlZ2VyPWN1cnZlRnBGcm9tQmlnSW50ZWdlcjtFQ0N1cnZlRnAucHJvdG90eXBlLmRlY29kZVBvaW50SGV4PWN1cnZlRnBEZWNvZGVQb2ludEhleDtcbi8qISAoYykgU3RlZmFuIFRob21hcyB8IGh0dHBzOi8vZ2l0aHViLmNvbS9iaXRjb2luanMvYml0Y29pbmpzLWxpYlxyXG4gKi9cclxuRUNGaWVsZEVsZW1lbnRGcC5wcm90b3R5cGUuZ2V0Qnl0ZUxlbmd0aD1mdW5jdGlvbigpe3JldHVybiBNYXRoLmZsb29yKCh0aGlzLnRvQmlnSW50ZWdlcigpLmJpdExlbmd0aCgpKzcpLzgpfTtFQ1BvaW50RnAucHJvdG90eXBlLmdldEVuY29kZWQ9ZnVuY3Rpb24oYyl7dmFyIGQ9ZnVuY3Rpb24oaCxmKXt2YXIgZz1oLnRvQnl0ZUFycmF5VW5zaWduZWQoKTtpZihmPGcubGVuZ3RoKXtnPWcuc2xpY2UoZy5sZW5ndGgtZil9ZWxzZXt3aGlsZShmPmcubGVuZ3RoKXtnLnVuc2hpZnQoMCl9fXJldHVybiBnfTt2YXIgYT10aGlzLmdldFgoKS50b0JpZ0ludGVnZXIoKTt2YXIgZT10aGlzLmdldFkoKS50b0JpZ0ludGVnZXIoKTt2YXIgYj1kKGEsMzIpO2lmKGMpe2lmKGUuaXNFdmVuKCkpe2IudW5zaGlmdCgyKX1lbHNle2IudW5zaGlmdCgzKX19ZWxzZXtiLnVuc2hpZnQoNCk7Yj1iLmNvbmNhdChkKGUsMzIpKX1yZXR1cm4gYn07RUNQb2ludEZwLmRlY29kZUZyb209ZnVuY3Rpb24oZyxjKXt2YXIgZj1jWzBdO3ZhciBlPWMubGVuZ3RoLTE7dmFyIGQ9Yy5zbGljZSgxLDErZS8yKTt2YXIgYj1jLnNsaWNlKDErZS8yLDErZSk7ZC51bnNoaWZ0KDApO2IudW5zaGlmdCgwKTt2YXIgYT1uZXcgQmlnSW50ZWdlcihkKTt2YXIgaD1uZXcgQmlnSW50ZWdlcihiKTtyZXR1cm4gbmV3IEVDUG9pbnRGcChnLGcuZnJvbUJpZ0ludGVnZXIoYSksZy5mcm9tQmlnSW50ZWdlcihoKSl9O0VDUG9pbnRGcC5kZWNvZGVGcm9tSGV4PWZ1bmN0aW9uKGcsYyl7dmFyIGY9Yy5zdWJzdHIoMCwyKTt2YXIgZT1jLmxlbmd0aC0yO3ZhciBkPWMuc3Vic3RyKDIsZS8yKTt2YXIgYj1jLnN1YnN0cigyK2UvMixlLzIpO3ZhciBhPW5ldyBCaWdJbnRlZ2VyKGQsMTYpO3ZhciBoPW5ldyBCaWdJbnRlZ2VyKGIsMTYpO3JldHVybiBuZXcgRUNQb2ludEZwKGcsZy5mcm9tQmlnSW50ZWdlcihhKSxnLmZyb21CaWdJbnRlZ2VyKGgpKX07RUNQb2ludEZwLnByb3RvdHlwZS5hZGQyRD1mdW5jdGlvbihjKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIGN9aWYoYy5pc0luZmluaXR5KCkpe3JldHVybiB0aGlzfWlmKHRoaXMueC5lcXVhbHMoYy54KSl7aWYodGhpcy55LmVxdWFscyhjLnkpKXtyZXR1cm4gdGhpcy50d2ljZSgpfXJldHVybiB0aGlzLmN1cnZlLmdldEluZmluaXR5KCl9dmFyIGc9Yy54LnN1YnRyYWN0KHRoaXMueCk7dmFyIGU9Yy55LnN1YnRyYWN0KHRoaXMueSk7dmFyIGE9ZS5kaXZpZGUoZyk7dmFyIGQ9YS5zcXVhcmUoKS5zdWJ0cmFjdCh0aGlzLngpLnN1YnRyYWN0KGMueCk7dmFyIGY9YS5tdWx0aXBseSh0aGlzLnguc3VidHJhY3QoZCkpLnN1YnRyYWN0KHRoaXMueSk7cmV0dXJuIG5ldyBFQ1BvaW50RnAodGhpcy5jdXJ2ZSxkLGYpfTtFQ1BvaW50RnAucHJvdG90eXBlLnR3aWNlMkQ9ZnVuY3Rpb24oKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXN9aWYodGhpcy55LnRvQmlnSW50ZWdlcigpLnNpZ251bSgpPT0wKXtyZXR1cm4gdGhpcy5jdXJ2ZS5nZXRJbmZpbml0eSgpfXZhciBiPXRoaXMuY3VydmUuZnJvbUJpZ0ludGVnZXIoQmlnSW50ZWdlci52YWx1ZU9mKDIpKTt2YXIgZT10aGlzLmN1cnZlLmZyb21CaWdJbnRlZ2VyKEJpZ0ludGVnZXIudmFsdWVPZigzKSk7dmFyIGE9dGhpcy54LnNxdWFyZSgpLm11bHRpcGx5KGUpLmFkZCh0aGlzLmN1cnZlLmEpLmRpdmlkZSh0aGlzLnkubXVsdGlwbHkoYikpO3ZhciBjPWEuc3F1YXJlKCkuc3VidHJhY3QodGhpcy54Lm11bHRpcGx5KGIpKTt2YXIgZD1hLm11bHRpcGx5KHRoaXMueC5zdWJ0cmFjdChjKSkuc3VidHJhY3QodGhpcy55KTtyZXR1cm4gbmV3IEVDUG9pbnRGcCh0aGlzLmN1cnZlLGMsZCl9O0VDUG9pbnRGcC5wcm90b3R5cGUubXVsdGlwbHkyRD1mdW5jdGlvbihiKXtpZih0aGlzLmlzSW5maW5pdHkoKSl7cmV0dXJuIHRoaXN9aWYoYi5zaWdudW0oKT09MCl7cmV0dXJuIHRoaXMuY3VydmUuZ2V0SW5maW5pdHkoKX12YXIgZz1iO3ZhciBmPWcubXVsdGlwbHkobmV3IEJpZ0ludGVnZXIoXCIzXCIpKTt2YXIgbD10aGlzLm5lZ2F0ZSgpO3ZhciBkPXRoaXM7dmFyIGM7Zm9yKGM9Zi5iaXRMZW5ndGgoKS0yO2M+MDstLWMpe2Q9ZC50d2ljZSgpO3ZhciBhPWYudGVzdEJpdChjKTt2YXIgaj1nLnRlc3RCaXQoYyk7aWYoYSE9ail7ZD1kLmFkZDJEKGE/dGhpczpsKX19cmV0dXJuIGR9O0VDUG9pbnRGcC5wcm90b3R5cGUuaXNPbkN1cnZlPWZ1bmN0aW9uKCl7dmFyIGQ9dGhpcy5nZXRYKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGk9dGhpcy5nZXRZKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGY9dGhpcy5jdXJ2ZS5nZXRBKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGM9dGhpcy5jdXJ2ZS5nZXRCKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGg9dGhpcy5jdXJ2ZS5nZXRRKCk7dmFyIGU9aS5tdWx0aXBseShpKS5tb2QoaCk7dmFyIGc9ZC5tdWx0aXBseShkKS5tdWx0aXBseShkKS5hZGQoZi5tdWx0aXBseShkKSkuYWRkKGMpLm1vZChoKTtyZXR1cm4gZS5lcXVhbHMoZyl9O0VDUG9pbnRGcC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm5cIihcIit0aGlzLmdldFgoKS50b0JpZ0ludGVnZXIoKS50b1N0cmluZygpK1wiLFwiK3RoaXMuZ2V0WSgpLnRvQmlnSW50ZWdlcigpLnRvU3RyaW5nKCkrXCIpXCJ9O0VDUG9pbnRGcC5wcm90b3R5cGUudmFsaWRhdGU9ZnVuY3Rpb24oKXt2YXIgYz10aGlzLmN1cnZlLmdldFEoKTtpZih0aGlzLmlzSW5maW5pdHkoKSl7dGhyb3cgbmV3IEVycm9yKFwiUG9pbnQgaXMgYXQgaW5maW5pdHkuXCIpfXZhciBhPXRoaXMuZ2V0WCgpLnRvQmlnSW50ZWdlcigpO3ZhciBiPXRoaXMuZ2V0WSgpLnRvQmlnSW50ZWdlcigpO2lmKGEuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKTwwfHxhLmNvbXBhcmVUbyhjLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSk+MCl7dGhyb3cgbmV3IEVycm9yKFwieCBjb29yZGluYXRlIG91dCBvZiBib3VuZHNcIil9aWYoYi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpPDB8fGIuY29tcGFyZVRvKGMuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKT4wKXt0aHJvdyBuZXcgRXJyb3IoXCJ5IGNvb3JkaW5hdGUgb3V0IG9mIGJvdW5kc1wiKX1pZighdGhpcy5pc09uQ3VydmUoKSl7dGhyb3cgbmV3IEVycm9yKFwiUG9pbnQgaXMgbm90IG9uIHRoZSBjdXJ2ZS5cIil9aWYodGhpcy5tdWx0aXBseShjKS5pc0luZmluaXR5KCkpe3Rocm93IG5ldyBFcnJvcihcIlBvaW50IGlzIG5vdCBhIHNjYWxhciBtdWx0aXBsZSBvZiBHLlwiKX1yZXR1cm4gdHJ1ZX07XG4vKiEgTWlrZSBTYW11ZWwgKGMpIDIwMDkgfCBjb2RlLmdvb2dsZS5jb20vcC9qc29uLXNhbnMtZXZhbFxyXG4gKi9cclxudmFyIGpzb25QYXJzZT0oZnVuY3Rpb24oKXt2YXIgZT1cIig/Oi0/XFxcXGIoPzowfFsxLTldWzAtOV0qKSg/OlxcXFwuWzAtOV0rKT8oPzpbZUVdWystXT9bMC05XSspP1xcXFxiKVwiO3ZhciBqPScoPzpbXlxcXFwwLVxcXFx4MDhcXFxceDBhLVxcXFx4MWZcIlxcXFxcXFxcXXxcXFxcXFxcXCg/OltcIi9cXFxcXFxcXGJmbnJ0XXx1WzAtOUEtRmEtZl17NH0pKSc7dmFyIGk9Jyg/OlwiJytqKycqXCIpJzt2YXIgZD1uZXcgUmVnRXhwKFwiKD86ZmFsc2V8dHJ1ZXxudWxsfFtcXFxce1xcXFx9XFxcXFtcXFxcXV18XCIrZStcInxcIitpK1wiKVwiLFwiZ1wiKTt2YXIgaz1uZXcgUmVnRXhwKFwiXFxcXFxcXFwoPzooW151XSl8dSguezR9KSlcIixcImdcIik7dmFyIGc9eydcIic6J1wiJyxcIi9cIjpcIi9cIixcIlxcXFxcIjpcIlxcXFxcIixiOlwiXFxiXCIsZjpcIlxcZlwiLG46XCJcXG5cIixyOlwiXFxyXCIsdDpcIlxcdFwifTtmdW5jdGlvbiBoKGwsbSxuKXtyZXR1cm4gbT9nW21dOlN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQobiwxNikpfXZhciBjPW5ldyBTdHJpbmcoXCJcIik7dmFyIGE9XCJcXFxcXCI7dmFyIGY9e1wie1wiOk9iamVjdCxcIltcIjpBcnJheX07dmFyIGI9T2JqZWN0Lmhhc093blByb3BlcnR5O3JldHVybiBmdW5jdGlvbih1LHEpe3ZhciBwPXUubWF0Y2goZCk7dmFyIHg7dmFyIHY9cFswXTt2YXIgbD1mYWxzZTtpZihcIntcIj09PXYpe3g9e319ZWxzZXtpZihcIltcIj09PXYpe3g9W119ZWxzZXt4PVtdO2w9dHJ1ZX19dmFyIHQ7dmFyIHI9W3hdO2Zvcih2YXIgbz0xLWwsbT1wLmxlbmd0aDtvPG07KytvKXt2PXBbb107dmFyIHc7c3dpdGNoKHYuY2hhckNvZGVBdCgwKSl7ZGVmYXVsdDp3PXJbMF07d1t0fHx3Lmxlbmd0aF09Kyh2KTt0PXZvaWQgMDticmVhaztjYXNlIDM0OnY9di5zdWJzdHJpbmcoMSx2Lmxlbmd0aC0xKTtpZih2LmluZGV4T2YoYSkhPT0tMSl7dj12LnJlcGxhY2UoayxoKX13PXJbMF07aWYoIXQpe2lmKHcgaW5zdGFuY2VvZiBBcnJheSl7dD13Lmxlbmd0aH1lbHNle3Q9dnx8YzticmVha319d1t0XT12O3Q9dm9pZCAwO2JyZWFrO2Nhc2UgOTE6dz1yWzBdO3IudW5zaGlmdCh3W3R8fHcubGVuZ3RoXT1bXSk7dD12b2lkIDA7YnJlYWs7Y2FzZSA5MzpyLnNoaWZ0KCk7YnJlYWs7Y2FzZSAxMDI6dz1yWzBdO3dbdHx8dy5sZW5ndGhdPWZhbHNlO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTEwOnc9clswXTt3W3R8fHcubGVuZ3RoXT1udWxsO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTE2Onc9clswXTt3W3R8fHcubGVuZ3RoXT10cnVlO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTIzOnc9clswXTtyLnVuc2hpZnQod1t0fHx3Lmxlbmd0aF09e30pO3Q9dm9pZCAwO2JyZWFrO2Nhc2UgMTI1OnIuc2hpZnQoKTticmVha319aWYobCl7aWYoci5sZW5ndGghPT0xKXt0aHJvdyBuZXcgRXJyb3IoKX14PXhbMF19ZWxzZXtpZihyLmxlbmd0aCl7dGhyb3cgbmV3IEVycm9yKCl9fWlmKHEpe3ZhciBzPWZ1bmN0aW9uKEMsQil7dmFyIEQ9Q1tCXTtpZihEJiZ0eXBlb2YgRD09PVwib2JqZWN0XCIpe3ZhciBuPW51bGw7Zm9yKHZhciB6IGluIEQpe2lmKGIuY2FsbChELHopJiZEIT09Qyl7dmFyIHk9cyhELHopO2lmKHkhPT12b2lkIDApe0Rbel09eX1lbHNle2lmKCFuKXtuPVtdfW4ucHVzaCh6KX19fWlmKG4pe2Zvcih2YXIgQT1uLmxlbmd0aDstLUE+PTA7KXtkZWxldGUgRFtuW0FdXX19fXJldHVybiBxLmNhbGwoQyxCLEQpfTt4PXMoe1wiXCI6eH0sXCJcIil9cmV0dXJuIHh9fSkoKTtcbmlmKHR5cGVvZiBLSlVSPT1cInVuZGVmaW5lZFwifHwhS0pVUil7S0pVUj17fX1pZih0eXBlb2YgS0pVUi5hc24xPT1cInVuZGVmaW5lZFwifHwhS0pVUi5hc24xKXtLSlVSLmFzbjE9e319S0pVUi5hc24xLkFTTjFVdGlsPW5ldyBmdW5jdGlvbigpe3RoaXMuaW50ZWdlclRvQnl0ZUhleD1mdW5jdGlvbihhKXt2YXIgYj1hLnRvU3RyaW5nKDE2KTtpZigoYi5sZW5ndGglMik9PTEpe2I9XCIwXCIrYn1yZXR1cm4gYn07dGhpcy5iaWdJbnRUb01pblR3b3NDb21wbGVtZW50c0hleD1mdW5jdGlvbihqKXt2YXIgZj1qLnRvU3RyaW5nKDE2KTtpZihmLnN1YnN0cigwLDEpIT1cIi1cIil7aWYoZi5sZW5ndGglMj09MSl7Zj1cIjBcIitmfWVsc2V7aWYoIWYubWF0Y2goL15bMC03XS8pKXtmPVwiMDBcIitmfX19ZWxzZXt2YXIgYT1mLnN1YnN0cigxKTt2YXIgZT1hLmxlbmd0aDtpZihlJTI9PTEpe2UrPTF9ZWxzZXtpZighZi5tYXRjaCgvXlswLTddLykpe2UrPTJ9fXZhciBnPVwiXCI7Zm9yKHZhciBkPTA7ZDxlO2QrKyl7Zys9XCJmXCJ9dmFyIGM9bmV3IEJpZ0ludGVnZXIoZywxNik7dmFyIGI9Yy54b3IoaikuYWRkKEJpZ0ludGVnZXIuT05FKTtmPWIudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14tLyxcIlwiKX1yZXR1cm4gZn07dGhpcy5nZXRQRU1TdHJpbmdGcm9tSGV4PWZ1bmN0aW9uKGEsYil7cmV0dXJuIGhleHRvcGVtKGEsYil9O3RoaXMubmV3T2JqZWN0PWZ1bmN0aW9uKGspe3ZhciBEPUtKVVIsbj1ELmFzbjEsej1uLkRFUkJvb2xlYW4sZT1uLkRFUkludGVnZXIscz1uLkRFUkJpdFN0cmluZyxoPW4uREVST2N0ZXRTdHJpbmcsdj1uLkRFUk51bGwsdz1uLkRFUk9iamVjdElkZW50aWZpZXIsbD1uLkRFUkVudW1lcmF0ZWQsZz1uLkRFUlVURjhTdHJpbmcsZj1uLkRFUk51bWVyaWNTdHJpbmcseT1uLkRFUlByaW50YWJsZVN0cmluZyx1PW4uREVSVGVsZXRleFN0cmluZyxwPW4uREVSSUE1U3RyaW5nLEM9bi5ERVJVVENUaW1lLGo9bi5ERVJHZW5lcmFsaXplZFRpbWUsbT1uLkRFUlNlcXVlbmNlLGM9bi5ERVJTZXQscj1uLkRFUlRhZ2dlZE9iamVjdCxvPW4uQVNOMVV0aWwubmV3T2JqZWN0O3ZhciB0PU9iamVjdC5rZXlzKGspO2lmKHQubGVuZ3RoIT0xKXt0aHJvd1wia2V5IG9mIHBhcmFtIHNoYWxsIGJlIG9ubHkgb25lLlwifXZhciBGPXRbMF07aWYoXCI6Ym9vbDppbnQ6Yml0c3RyOm9jdHN0cjpudWxsOm9pZDplbnVtOnV0ZjhzdHI6bnVtc3RyOnBybnN0cjp0ZWxzdHI6aWE1c3RyOnV0Y3RpbWU6Z2VudGltZTpzZXE6c2V0OnRhZzpcIi5pbmRleE9mKFwiOlwiK0YrXCI6XCIpPT0tMSl7dGhyb3dcInVuZGVmaW5lZCBrZXk6IFwiK0Z9aWYoRj09XCJib29sXCIpe3JldHVybiBuZXcgeihrW0ZdKX1pZihGPT1cImludFwiKXtyZXR1cm4gbmV3IGUoa1tGXSl9aWYoRj09XCJiaXRzdHJcIil7cmV0dXJuIG5ldyBzKGtbRl0pfWlmKEY9PVwib2N0c3RyXCIpe3JldHVybiBuZXcgaChrW0ZdKX1pZihGPT1cIm51bGxcIil7cmV0dXJuIG5ldyB2KGtbRl0pfWlmKEY9PVwib2lkXCIpe3JldHVybiBuZXcgdyhrW0ZdKX1pZihGPT1cImVudW1cIil7cmV0dXJuIG5ldyBsKGtbRl0pfWlmKEY9PVwidXRmOHN0clwiKXtyZXR1cm4gbmV3IGcoa1tGXSl9aWYoRj09XCJudW1zdHJcIil7cmV0dXJuIG5ldyBmKGtbRl0pfWlmKEY9PVwicHJuc3RyXCIpe3JldHVybiBuZXcgeShrW0ZdKX1pZihGPT1cInRlbHN0clwiKXtyZXR1cm4gbmV3IHUoa1tGXSl9aWYoRj09XCJpYTVzdHJcIil7cmV0dXJuIG5ldyBwKGtbRl0pfWlmKEY9PVwidXRjdGltZVwiKXtyZXR1cm4gbmV3IEMoa1tGXSl9aWYoRj09XCJnZW50aW1lXCIpe3JldHVybiBuZXcgaihrW0ZdKX1pZihGPT1cInNlcVwiKXt2YXIgZD1rW0ZdO3ZhciBFPVtdO2Zvcih2YXIgeD0wO3g8ZC5sZW5ndGg7eCsrKXt2YXIgQj1vKGRbeF0pO0UucHVzaChCKX1yZXR1cm4gbmV3IG0oe2FycmF5OkV9KX1pZihGPT1cInNldFwiKXt2YXIgZD1rW0ZdO3ZhciBFPVtdO2Zvcih2YXIgeD0wO3g8ZC5sZW5ndGg7eCsrKXt2YXIgQj1vKGRbeF0pO0UucHVzaChCKX1yZXR1cm4gbmV3IGMoe2FycmF5OkV9KX1pZihGPT1cInRhZ1wiKXt2YXIgQT1rW0ZdO2lmKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChBKT09PVwiW29iamVjdCBBcnJheV1cIiYmQS5sZW5ndGg9PTMpe3ZhciBxPW8oQVsyXSk7cmV0dXJuIG5ldyByKHt0YWc6QVswXSxleHBsaWNpdDpBWzFdLG9iajpxfSl9ZWxzZXt2YXIgYj17fTtpZihBLmV4cGxpY2l0IT09dW5kZWZpbmVkKXtiLmV4cGxpY2l0PUEuZXhwbGljaXR9aWYoQS50YWchPT11bmRlZmluZWQpe2IudGFnPUEudGFnfWlmKEEub2JqPT09dW5kZWZpbmVkKXt0aHJvd1wib2JqIHNoYWxsIGJlIHNwZWNpZmllZCBmb3IgJ3RhZycuXCJ9Yi5vYmo9byhBLm9iaik7cmV0dXJuIG5ldyByKGIpfX19O3RoaXMuanNvblRvQVNOMUhFWD1mdW5jdGlvbihiKXt2YXIgYT10aGlzLm5ld09iamVjdChiKTtyZXR1cm4gYS5nZXRFbmNvZGVkSGV4KCl9fTtLSlVSLmFzbjEuQVNOMVV0aWwub2lkSGV4VG9JbnQ9ZnVuY3Rpb24oYSl7dmFyIGo9XCJcIjt2YXIgaz1wYXJzZUludChhLnN1YnN0cigwLDIpLDE2KTt2YXIgZD1NYXRoLmZsb29yKGsvNDApO3ZhciBjPWslNDA7dmFyIGo9ZCtcIi5cIitjO3ZhciBlPVwiXCI7Zm9yKHZhciBmPTI7ZjxhLmxlbmd0aDtmKz0yKXt2YXIgZz1wYXJzZUludChhLnN1YnN0cihmLDIpLDE2KTt2YXIgaD0oXCIwMDAwMDAwMFwiK2cudG9TdHJpbmcoMikpLnNsaWNlKC04KTtlPWUraC5zdWJzdHIoMSw3KTtpZihoLnN1YnN0cigwLDEpPT1cIjBcIil7dmFyIGI9bmV3IEJpZ0ludGVnZXIoZSwyKTtqPWorXCIuXCIrYi50b1N0cmluZygxMCk7ZT1cIlwifX1yZXR1cm4gan07S0pVUi5hc24xLkFTTjFVdGlsLm9pZEludFRvSGV4PWZ1bmN0aW9uKGYpe3ZhciBlPWZ1bmN0aW9uKGEpe3ZhciBrPWEudG9TdHJpbmcoMTYpO2lmKGsubGVuZ3RoPT0xKXtrPVwiMFwiK2t9cmV0dXJuIGt9O3ZhciBkPWZ1bmN0aW9uKG8pe3ZhciBuPVwiXCI7dmFyIGs9bmV3IEJpZ0ludGVnZXIobywxMCk7dmFyIGE9ay50b1N0cmluZygyKTt2YXIgbD03LWEubGVuZ3RoJTc7aWYobD09Nyl7bD0wfXZhciBxPVwiXCI7Zm9yKHZhciBtPTA7bTxsO20rKyl7cSs9XCIwXCJ9YT1xK2E7Zm9yKHZhciBtPTA7bTxhLmxlbmd0aC0xO20rPTcpe3ZhciBwPWEuc3Vic3RyKG0sNyk7aWYobSE9YS5sZW5ndGgtNyl7cD1cIjFcIitwfW4rPWUocGFyc2VJbnQocCwyKSl9cmV0dXJuIG59O2lmKCFmLm1hdGNoKC9eWzAtOS5dKyQvKSl7dGhyb3dcIm1hbGZvcm1lZCBvaWQgc3RyaW5nOiBcIitmfXZhciBnPVwiXCI7dmFyIGI9Zi5zcGxpdChcIi5cIik7dmFyIGo9cGFyc2VJbnQoYlswXSkqNDArcGFyc2VJbnQoYlsxXSk7Zys9ZShqKTtiLnNwbGljZSgwLDIpO2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGg7YysrKXtnKz1kKGJbY10pfXJldHVybiBnfTtLSlVSLmFzbjEuQVNOMU9iamVjdD1mdW5jdGlvbigpe3ZhciBjPXRydWU7dmFyIGI9bnVsbDt2YXIgZD1cIjAwXCI7dmFyIGU9XCIwMFwiO3ZhciBhPVwiXCI7dGhpcy5nZXRMZW5ndGhIZXhGcm9tVmFsdWU9ZnVuY3Rpb24oKXtpZih0eXBlb2YgdGhpcy5oVj09XCJ1bmRlZmluZWRcInx8dGhpcy5oVj09bnVsbCl7dGhyb3dcInRoaXMuaFYgaXMgbnVsbCBvciB1bmRlZmluZWQuXCJ9aWYodGhpcy5oVi5sZW5ndGglMj09MSl7dGhyb3dcInZhbHVlIGhleCBtdXN0IGJlIGV2ZW4gbGVuZ3RoOiBuPVwiK2EubGVuZ3RoK1wiLHY9XCIrdGhpcy5oVn12YXIgaT10aGlzLmhWLmxlbmd0aC8yO3ZhciBoPWkudG9TdHJpbmcoMTYpO2lmKGgubGVuZ3RoJTI9PTEpe2g9XCIwXCIraH1pZihpPDEyOCl7cmV0dXJuIGh9ZWxzZXt2YXIgZz1oLmxlbmd0aC8yO2lmKGc+MTUpe3Rocm93XCJBU04uMSBsZW5ndGggdG9vIGxvbmcgdG8gcmVwcmVzZW50IGJ5IDh4OiBuID0gXCIraS50b1N0cmluZygxNil9dmFyIGY9MTI4K2c7cmV0dXJuIGYudG9TdHJpbmcoMTYpK2h9fTt0aGlzLmdldEVuY29kZWRIZXg9ZnVuY3Rpb24oKXtpZih0aGlzLmhUTFY9PW51bGx8fHRoaXMuaXNNb2RpZmllZCl7dGhpcy5oVj10aGlzLmdldEZyZXNoVmFsdWVIZXgoKTt0aGlzLmhMPXRoaXMuZ2V0TGVuZ3RoSGV4RnJvbVZhbHVlKCk7dGhpcy5oVExWPXRoaXMuaFQrdGhpcy5oTCt0aGlzLmhWO3RoaXMuaXNNb2RpZmllZD1mYWxzZX1yZXR1cm4gdGhpcy5oVExWfTt0aGlzLmdldFZhbHVlSGV4PWZ1bmN0aW9uKCl7dGhpcy5nZXRFbmNvZGVkSGV4KCk7cmV0dXJuIHRoaXMuaFZ9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVyblwiXCJ9fTtLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJpbmc9ZnVuY3Rpb24oYyl7S0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt2YXIgYj1udWxsO3ZhciBhPW51bGw7dGhpcy5nZXRTdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5zfTt0aGlzLnNldFN0cmluZz1mdW5jdGlvbihkKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLnM9ZDt0aGlzLmhWPXV0Zjh0b2hleCh0aGlzLnMpLnRvTG93ZXJDYXNlKCl9O3RoaXMuc2V0U3RyaW5nSGV4PWZ1bmN0aW9uKGQpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMucz1udWxsO3RoaXMuaFY9ZH07dGhpcy5nZXRGcmVzaFZhbHVlSGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaFZ9O2lmKHR5cGVvZiBjIT1cInVuZGVmaW5lZFwiKXtpZih0eXBlb2YgYz09XCJzdHJpbmdcIil7dGhpcy5zZXRTdHJpbmcoYyl9ZWxzZXtpZih0eXBlb2YgYy5zdHIhPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0U3RyaW5nKGMuc3RyKX1lbHNle2lmKHR5cGVvZiBjLmhleCE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRTdHJpbmdIZXgoYy5oZXgpfX19fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSQWJzdHJhY3RUaW1lPWZ1bmN0aW9uKGMpe0tKVVIuYXNuMS5ERVJBYnN0cmFjdFRpbWUuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3ZhciBiPW51bGw7dmFyIGE9bnVsbDt0aGlzLmxvY2FsRGF0ZVRvVVRDPWZ1bmN0aW9uKGYpe3V0Yz1mLmdldFRpbWUoKSsoZi5nZXRUaW1lem9uZU9mZnNldCgpKjYwMDAwKTt2YXIgZT1uZXcgRGF0ZSh1dGMpO3JldHVybiBlfTt0aGlzLmZvcm1hdERhdGU9ZnVuY3Rpb24obSxvLGUpe3ZhciBnPXRoaXMuemVyb1BhZGRpbmc7dmFyIG49dGhpcy5sb2NhbERhdGVUb1VUQyhtKTt2YXIgcD1TdHJpbmcobi5nZXRGdWxsWWVhcigpKTtpZihvPT1cInV0Y1wiKXtwPXAuc3Vic3RyKDIsMil9dmFyIGw9ZyhTdHJpbmcobi5nZXRNb250aCgpKzEpLDIpO3ZhciBxPWcoU3RyaW5nKG4uZ2V0RGF0ZSgpKSwyKTt2YXIgaD1nKFN0cmluZyhuLmdldEhvdXJzKCkpLDIpO3ZhciBpPWcoU3RyaW5nKG4uZ2V0TWludXRlcygpKSwyKTt2YXIgaj1nKFN0cmluZyhuLmdldFNlY29uZHMoKSksMik7dmFyIHI9cCtsK3EraCtpK2o7aWYoZT09PXRydWUpe3ZhciBmPW4uZ2V0TWlsbGlzZWNvbmRzKCk7aWYoZiE9MCl7dmFyIGs9ZyhTdHJpbmcoZiksMyk7az1rLnJlcGxhY2UoL1swXSskLyxcIlwiKTtyPXIrXCIuXCIra319cmV0dXJuIHIrXCJaXCJ9O3RoaXMuemVyb1BhZGRpbmc9ZnVuY3Rpb24oZSxkKXtpZihlLmxlbmd0aD49ZCl7cmV0dXJuIGV9cmV0dXJuIG5ldyBBcnJheShkLWUubGVuZ3RoKzEpLmpvaW4oXCIwXCIpK2V9O3RoaXMuZ2V0U3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuc307dGhpcy5zZXRTdHJpbmc9ZnVuY3Rpb24oZCl7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5zPWQ7dGhpcy5oVj1zdG9oZXgoZCl9O3RoaXMuc2V0QnlEYXRlVmFsdWU9ZnVuY3Rpb24oaCxqLGUsZCxmLGcpe3ZhciBpPW5ldyBEYXRlKERhdGUuVVRDKGgsai0xLGUsZCxmLGcsMCkpO3RoaXMuc2V0QnlEYXRlKGkpfTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJBYnN0cmFjdFRpbWUsS0pVUi5hc24xLkFTTjFPYmplY3QpO0tKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cnVjdHVyZWQ9ZnVuY3Rpb24oYil7S0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt2YXIgYT1udWxsO3RoaXMuc2V0QnlBU04xT2JqZWN0QXJyYXk9ZnVuY3Rpb24oYyl7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5hc24xQXJyYXk9Y307dGhpcy5hcHBlbmRBU04xT2JqZWN0PWZ1bmN0aW9uKGMpe3RoaXMuaFRMVj1udWxsO3RoaXMuaXNNb2RpZmllZD10cnVlO3RoaXMuYXNuMUFycmF5LnB1c2goYyl9O3RoaXMuYXNuMUFycmF5PW5ldyBBcnJheSgpO2lmKHR5cGVvZiBiIT1cInVuZGVmaW5lZFwiKXtpZih0eXBlb2YgYi5hcnJheSE9XCJ1bmRlZmluZWRcIil7dGhpcy5hc24xQXJyYXk9Yi5hcnJheX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJ1Y3R1cmVkLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSQm9vbGVhbj1mdW5jdGlvbigpe0tKVVIuYXNuMS5ERVJCb29sZWFuLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDFcIjt0aGlzLmhUTFY9XCIwMTAxZmZcIn07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkJvb2xlYW4sS0pVUi5hc24xLkFTTjFPYmplY3QpO0tKVVIuYXNuMS5ERVJJbnRlZ2VyPWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJJbnRlZ2VyLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDJcIjt0aGlzLnNldEJ5QmlnSW50ZWdlcj1mdW5jdGlvbihiKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPUtKVVIuYXNuMS5BU04xVXRpbC5iaWdJbnRUb01pblR3b3NDb21wbGVtZW50c0hleChiKX07dGhpcy5zZXRCeUludGVnZXI9ZnVuY3Rpb24oYyl7dmFyIGI9bmV3IEJpZ0ludGVnZXIoU3RyaW5nKGMpLDEwKTt0aGlzLnNldEJ5QmlnSW50ZWdlcihiKX07dGhpcy5zZXRWYWx1ZUhleD1mdW5jdGlvbihiKXt0aGlzLmhWPWJ9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYSE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGEuYmlnaW50IT1cInVuZGVmaW5lZFwiKXt0aGlzLnNldEJ5QmlnSW50ZWdlcihhLmJpZ2ludCl9ZWxzZXtpZih0eXBlb2YgYVtcImludFwiXSE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUludGVnZXIoYVtcImludFwiXSl9ZWxzZXtpZih0eXBlb2YgYT09XCJudW1iZXJcIil7dGhpcy5zZXRCeUludGVnZXIoYSl9ZWxzZXtpZih0eXBlb2YgYS5oZXghPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0VmFsdWVIZXgoYS5oZXgpfX19fX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJJbnRlZ2VyLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSQml0U3RyaW5nPWZ1bmN0aW9uKGIpe2lmKGIhPT11bmRlZmluZWQmJnR5cGVvZiBiLm9iaiE9PVwidW5kZWZpbmVkXCIpe3ZhciBhPUtKVVIuYXNuMS5BU04xVXRpbC5uZXdPYmplY3QoYi5vYmopO2IuaGV4PVwiMDBcIithLmdldEVuY29kZWRIZXgoKX1LSlVSLmFzbjEuREVSQml0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDNcIjt0aGlzLnNldEhleFZhbHVlSW5jbHVkaW5nVW51c2VkQml0cz1mdW5jdGlvbihjKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPWN9O3RoaXMuc2V0VW51c2VkQml0c0FuZEhleFZhbHVlPWZ1bmN0aW9uKGMsZSl7aWYoYzwwfHw3PGMpe3Rocm93XCJ1bnVzZWQgYml0cyBzaGFsbCBiZSBmcm9tIDAgdG8gNzogdSA9IFwiK2N9dmFyIGQ9XCIwXCIrYzt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPWQrZX07dGhpcy5zZXRCeUJpbmFyeVN0cmluZz1mdW5jdGlvbihlKXtlPWUucmVwbGFjZSgvMCskLyxcIlwiKTt2YXIgZj04LWUubGVuZ3RoJTg7aWYoZj09OCl7Zj0wfWZvcih2YXIgZz0wO2c8PWY7ZysrKXtlKz1cIjBcIn12YXIgaj1cIlwiO2Zvcih2YXIgZz0wO2c8ZS5sZW5ndGgtMTtnKz04KXt2YXIgZD1lLnN1YnN0cihnLDgpO3ZhciBjPXBhcnNlSW50KGQsMikudG9TdHJpbmcoMTYpO2lmKGMubGVuZ3RoPT0xKXtjPVwiMFwiK2N9ais9Y310aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLmhWPVwiMFwiK2Yran07dGhpcy5zZXRCeUJvb2xlYW5BcnJheT1mdW5jdGlvbihlKXt2YXIgZD1cIlwiO2Zvcih2YXIgYz0wO2M8ZS5sZW5ndGg7YysrKXtpZihlW2NdPT10cnVlKXtkKz1cIjFcIn1lbHNle2QrPVwiMFwifX10aGlzLnNldEJ5QmluYXJ5U3RyaW5nKGQpfTt0aGlzLm5ld0ZhbHNlQXJyYXk9ZnVuY3Rpb24oZSl7dmFyIGM9bmV3IEFycmF5KGUpO2Zvcih2YXIgZD0wO2Q8ZTtkKyspe2NbZF09ZmFsc2V9cmV0dXJuIGN9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYiE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGI9PVwic3RyaW5nXCImJmIudG9Mb3dlckNhc2UoKS5tYXRjaCgvXlswLTlhLWZdKyQvKSl7dGhpcy5zZXRIZXhWYWx1ZUluY2x1ZGluZ1VudXNlZEJpdHMoYil9ZWxzZXtpZih0eXBlb2YgYi5oZXghPVwidW5kZWZpbmVkXCIpe3RoaXMuc2V0SGV4VmFsdWVJbmNsdWRpbmdVbnVzZWRCaXRzKGIuaGV4KX1lbHNle2lmKHR5cGVvZiBiLmJpbiE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUJpbmFyeVN0cmluZyhiLmJpbil9ZWxzZXtpZih0eXBlb2YgYi5hcnJheSE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRCeUJvb2xlYW5BcnJheShiLmFycmF5KX19fX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSQml0U3RyaW5nLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVST2N0ZXRTdHJpbmc9ZnVuY3Rpb24oYil7aWYoYiE9PXVuZGVmaW5lZCYmdHlwZW9mIGIub2JqIT09XCJ1bmRlZmluZWRcIil7dmFyIGE9S0pVUi5hc24xLkFTTjFVdGlsLm5ld09iamVjdChiLm9iaik7Yi5oZXg9YS5nZXRFbmNvZGVkSGV4KCl9S0pVUi5hc24xLkRFUk9jdGV0U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGIpO3RoaXMuaFQ9XCIwNFwifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVST2N0ZXRTdHJpbmcsS0pVUi5hc24xLkRFUkFic3RyYWN0U3RyaW5nKTtLSlVSLmFzbjEuREVSTnVsbD1mdW5jdGlvbigpe0tKVVIuYXNuMS5ERVJOdWxsLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmhUPVwiMDVcIjt0aGlzLmhUTFY9XCIwNTAwXCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJOdWxsLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVST2JqZWN0SWRlbnRpZmllcj1mdW5jdGlvbihjKXt2YXIgYj1mdW5jdGlvbihkKXt2YXIgZT1kLnRvU3RyaW5nKDE2KTtpZihlLmxlbmd0aD09MSl7ZT1cIjBcIitlfXJldHVybiBlfTt2YXIgYT1mdW5jdGlvbihrKXt2YXIgaj1cIlwiO3ZhciBlPW5ldyBCaWdJbnRlZ2VyKGssMTApO3ZhciBkPWUudG9TdHJpbmcoMik7dmFyIGY9Ny1kLmxlbmd0aCU3O2lmKGY9PTcpe2Y9MH12YXIgbT1cIlwiO2Zvcih2YXIgZz0wO2c8ZjtnKyspe20rPVwiMFwifWQ9bStkO2Zvcih2YXIgZz0wO2c8ZC5sZW5ndGgtMTtnKz03KXt2YXIgbD1kLnN1YnN0cihnLDcpO2lmKGchPWQubGVuZ3RoLTcpe2w9XCIxXCIrbH1qKz1iKHBhcnNlSW50KGwsMikpfXJldHVybiBqfTtLSlVSLmFzbjEuREVST2JqZWN0SWRlbnRpZmllci5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjA2XCI7dGhpcy5zZXRWYWx1ZUhleD1mdW5jdGlvbihkKXt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZTt0aGlzLnM9bnVsbDt0aGlzLmhWPWR9O3RoaXMuc2V0VmFsdWVPaWRTdHJpbmc9ZnVuY3Rpb24oZil7aWYoIWYubWF0Y2goL15bMC05Ll0rJC8pKXt0aHJvd1wibWFsZm9ybWVkIG9pZCBzdHJpbmc6IFwiK2Z9dmFyIGc9XCJcIjt2YXIgZD1mLnNwbGl0KFwiLlwiKTt2YXIgaj1wYXJzZUludChkWzBdKSo0MCtwYXJzZUludChkWzFdKTtnKz1iKGopO2Quc3BsaWNlKDAsMik7Zm9yKHZhciBlPTA7ZTxkLmxlbmd0aDtlKyspe2crPWEoZFtlXSl9dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5zPW51bGw7dGhpcy5oVj1nfTt0aGlzLnNldFZhbHVlTmFtZT1mdW5jdGlvbihlKXt2YXIgZD1LSlVSLmFzbjEueDUwOS5PSUQubmFtZTJvaWQoZSk7aWYoZCE9PVwiXCIpe3RoaXMuc2V0VmFsdWVPaWRTdHJpbmcoZCl9ZWxzZXt0aHJvd1wiREVST2JqZWN0SWRlbnRpZmllciBvaWROYW1lIHVuZGVmaW5lZDogXCIrZX19O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZihjIT09dW5kZWZpbmVkKXtpZih0eXBlb2YgYz09PVwic3RyaW5nXCIpe2lmKGMubWF0Y2goL15bMC0yXS5bMC05Ll0rJC8pKXt0aGlzLnNldFZhbHVlT2lkU3RyaW5nKGMpfWVsc2V7dGhpcy5zZXRWYWx1ZU5hbWUoYyl9fWVsc2V7aWYoYy5vaWQhPT11bmRlZmluZWQpe3RoaXMuc2V0VmFsdWVPaWRTdHJpbmcoYy5vaWQpfWVsc2V7aWYoYy5oZXghPT11bmRlZmluZWQpe3RoaXMuc2V0VmFsdWVIZXgoYy5oZXgpfWVsc2V7aWYoYy5uYW1lIT09dW5kZWZpbmVkKXt0aGlzLnNldFZhbHVlTmFtZShjLm5hbWUpfX19fX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJPYmplY3RJZGVudGlmaWVyLEtKVVIuYXNuMS5BU04xT2JqZWN0KTtLSlVSLmFzbjEuREVSRW51bWVyYXRlZD1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSRW51bWVyYXRlZC5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5oVD1cIjBhXCI7dGhpcy5zZXRCeUJpZ0ludGVnZXI9ZnVuY3Rpb24oYil7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5oVj1LSlVSLmFzbjEuQVNOMVV0aWwuYmlnSW50VG9NaW5Ud29zQ29tcGxlbWVudHNIZXgoYil9O3RoaXMuc2V0QnlJbnRlZ2VyPWZ1bmN0aW9uKGMpe3ZhciBiPW5ldyBCaWdJbnRlZ2VyKFN0cmluZyhjKSwxMCk7dGhpcy5zZXRCeUJpZ0ludGVnZXIoYil9O3RoaXMuc2V0VmFsdWVIZXg9ZnVuY3Rpb24oYil7dGhpcy5oVj1ifTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oVn07aWYodHlwZW9mIGEhPVwidW5kZWZpbmVkXCIpe2lmKHR5cGVvZiBhW1wiaW50XCJdIT1cInVuZGVmaW5lZFwiKXt0aGlzLnNldEJ5SW50ZWdlcihhW1wiaW50XCJdKX1lbHNle2lmKHR5cGVvZiBhPT1cIm51bWJlclwiKXt0aGlzLnNldEJ5SW50ZWdlcihhKX1lbHNle2lmKHR5cGVvZiBhLmhleCE9XCJ1bmRlZmluZWRcIil7dGhpcy5zZXRWYWx1ZUhleChhLmhleCl9fX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSRW51bWVyYXRlZCxLSlVSLmFzbjEuQVNOMU9iamVjdCk7S0pVUi5hc24xLkRFUlVURjhTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlVURjhTdHJpbmcuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjBjXCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJVVEY4U3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUk51bWVyaWNTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUk51bWVyaWNTdHJpbmcuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjEyXCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJOdW1lcmljU3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUlByaW50YWJsZVN0cmluZz1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSUHJpbnRhYmxlU3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIxM1wifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSUHJpbnRhYmxlU3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUlRlbGV0ZXhTdHJpbmc9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlRlbGV0ZXhTdHJpbmcuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjE0XCJ9O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJUZWxldGV4U3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUklBNVN0cmluZz1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSSUE1U3RyaW5nLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIxNlwifTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSSUE1U3RyaW5nLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFN0cmluZyk7S0pVUi5hc24xLkRFUlVUQ1RpbWU9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlVUQ1RpbWUuc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsYSk7dGhpcy5oVD1cIjE3XCI7dGhpcy5zZXRCeURhdGU9ZnVuY3Rpb24oYil7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5kYXRlPWI7dGhpcy5zPXRoaXMuZm9ybWF0RGF0ZSh0aGlzLmRhdGUsXCJ1dGNcIik7dGhpcy5oVj1zdG9oZXgodGhpcy5zKX07dGhpcy5nZXRGcmVzaFZhbHVlSGV4PWZ1bmN0aW9uKCl7aWYodHlwZW9mIHRoaXMuZGF0ZT09XCJ1bmRlZmluZWRcIiYmdHlwZW9mIHRoaXMucz09XCJ1bmRlZmluZWRcIil7dGhpcy5kYXRlPW5ldyBEYXRlKCk7dGhpcy5zPXRoaXMuZm9ybWF0RGF0ZSh0aGlzLmRhdGUsXCJ1dGNcIik7dGhpcy5oVj1zdG9oZXgodGhpcy5zKX1yZXR1cm4gdGhpcy5oVn07aWYoYSE9PXVuZGVmaW5lZCl7aWYoYS5zdHIhPT11bmRlZmluZWQpe3RoaXMuc2V0U3RyaW5nKGEuc3RyKX1lbHNle2lmKHR5cGVvZiBhPT1cInN0cmluZ1wiJiZhLm1hdGNoKC9eWzAtOV17MTJ9WiQvKSl7dGhpcy5zZXRTdHJpbmcoYSl9ZWxzZXtpZihhLmhleCE9PXVuZGVmaW5lZCl7dGhpcy5zZXRTdHJpbmdIZXgoYS5oZXgpfWVsc2V7aWYoYS5kYXRlIT09dW5kZWZpbmVkKXt0aGlzLnNldEJ5RGF0ZShhLmRhdGUpfX19fX19O1lBSE9PLmxhbmcuZXh0ZW5kKEtKVVIuYXNuMS5ERVJVVENUaW1lLEtKVVIuYXNuMS5ERVJBYnN0cmFjdFRpbWUpO0tKVVIuYXNuMS5ERVJHZW5lcmFsaXplZFRpbWU9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUkdlbmVyYWxpemVkVGltZS5zdXBlcmNsYXNzLmNvbnN0cnVjdG9yLmNhbGwodGhpcyxhKTt0aGlzLmhUPVwiMThcIjt0aGlzLndpdGhNaWxsaXM9ZmFsc2U7dGhpcy5zZXRCeURhdGU9ZnVuY3Rpb24oYil7dGhpcy5oVExWPW51bGw7dGhpcy5pc01vZGlmaWVkPXRydWU7dGhpcy5kYXRlPWI7dGhpcy5zPXRoaXMuZm9ybWF0RGF0ZSh0aGlzLmRhdGUsXCJnZW5cIix0aGlzLndpdGhNaWxsaXMpO3RoaXMuaFY9c3RvaGV4KHRoaXMucyl9O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe2lmKHRoaXMuZGF0ZT09PXVuZGVmaW5lZCYmdGhpcy5zPT09dW5kZWZpbmVkKXt0aGlzLmRhdGU9bmV3IERhdGUoKTt0aGlzLnM9dGhpcy5mb3JtYXREYXRlKHRoaXMuZGF0ZSxcImdlblwiLHRoaXMud2l0aE1pbGxpcyk7dGhpcy5oVj1zdG9oZXgodGhpcy5zKX1yZXR1cm4gdGhpcy5oVn07aWYoYSE9PXVuZGVmaW5lZCl7aWYoYS5zdHIhPT11bmRlZmluZWQpe3RoaXMuc2V0U3RyaW5nKGEuc3RyKX1lbHNle2lmKHR5cGVvZiBhPT1cInN0cmluZ1wiJiZhLm1hdGNoKC9eWzAtOV17MTR9WiQvKSl7dGhpcy5zZXRTdHJpbmcoYSl9ZWxzZXtpZihhLmhleCE9PXVuZGVmaW5lZCl7dGhpcy5zZXRTdHJpbmdIZXgoYS5oZXgpfWVsc2V7aWYoYS5kYXRlIT09dW5kZWZpbmVkKXt0aGlzLnNldEJ5RGF0ZShhLmRhdGUpfX19fWlmKGEubWlsbGlzPT09dHJ1ZSl7dGhpcy53aXRoTWlsbGlzPXRydWV9fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUkdlbmVyYWxpemVkVGltZSxLSlVSLmFzbjEuREVSQWJzdHJhY3RUaW1lKTtLSlVSLmFzbjEuREVSU2VxdWVuY2U9ZnVuY3Rpb24oYSl7S0pVUi5hc24xLkRFUlNlcXVlbmNlLnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIzMFwiO3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3ZhciBjPVwiXCI7Zm9yKHZhciBiPTA7Yjx0aGlzLmFzbjFBcnJheS5sZW5ndGg7YisrKXt2YXIgZD10aGlzLmFzbjFBcnJheVtiXTtjKz1kLmdldEVuY29kZWRIZXgoKX10aGlzLmhWPWM7cmV0dXJuIHRoaXMuaFZ9fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSU2VxdWVuY2UsS0pVUi5hc24xLkRFUkFic3RyYWN0U3RydWN0dXJlZCk7S0pVUi5hc24xLkRFUlNldD1mdW5jdGlvbihhKXtLSlVSLmFzbjEuREVSU2V0LnN1cGVyY2xhc3MuY29uc3RydWN0b3IuY2FsbCh0aGlzLGEpO3RoaXMuaFQ9XCIzMVwiO3RoaXMuc29ydEZsYWc9dHJ1ZTt0aGlzLmdldEZyZXNoVmFsdWVIZXg9ZnVuY3Rpb24oKXt2YXIgYj1uZXcgQXJyYXkoKTtmb3IodmFyIGM9MDtjPHRoaXMuYXNuMUFycmF5Lmxlbmd0aDtjKyspe3ZhciBkPXRoaXMuYXNuMUFycmF5W2NdO2IucHVzaChkLmdldEVuY29kZWRIZXgoKSl9aWYodGhpcy5zb3J0RmxhZz09dHJ1ZSl7Yi5zb3J0KCl9dGhpcy5oVj1iLmpvaW4oXCJcIik7cmV0dXJuIHRoaXMuaFZ9O2lmKHR5cGVvZiBhIT1cInVuZGVmaW5lZFwiKXtpZih0eXBlb2YgYS5zb3J0ZmxhZyE9XCJ1bmRlZmluZWRcIiYmYS5zb3J0ZmxhZz09ZmFsc2Upe3RoaXMuc29ydEZsYWc9ZmFsc2V9fX07WUFIT08ubGFuZy5leHRlbmQoS0pVUi5hc24xLkRFUlNldCxLSlVSLmFzbjEuREVSQWJzdHJhY3RTdHJ1Y3R1cmVkKTtLSlVSLmFzbjEuREVSVGFnZ2VkT2JqZWN0PWZ1bmN0aW9uKGEpe0tKVVIuYXNuMS5ERVJUYWdnZWRPYmplY3Quc3VwZXJjbGFzcy5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3RoaXMuaFQ9XCJhMFwiO3RoaXMuaFY9XCJcIjt0aGlzLmlzRXhwbGljaXQ9dHJ1ZTt0aGlzLmFzbjFPYmplY3Q9bnVsbDt0aGlzLnNldEFTTjFPYmplY3Q9ZnVuY3Rpb24oYixjLGQpe3RoaXMuaFQ9Yzt0aGlzLmlzRXhwbGljaXQ9Yjt0aGlzLmFzbjFPYmplY3Q9ZDtpZih0aGlzLmlzRXhwbGljaXQpe3RoaXMuaFY9dGhpcy5hc24xT2JqZWN0LmdldEVuY29kZWRIZXgoKTt0aGlzLmhUTFY9bnVsbDt0aGlzLmlzTW9kaWZpZWQ9dHJ1ZX1lbHNle3RoaXMuaFY9bnVsbDt0aGlzLmhUTFY9ZC5nZXRFbmNvZGVkSGV4KCk7dGhpcy5oVExWPXRoaXMuaFRMVi5yZXBsYWNlKC9eLi4vLGMpO3RoaXMuaXNNb2RpZmllZD1mYWxzZX19O3RoaXMuZ2V0RnJlc2hWYWx1ZUhleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhWfTtpZih0eXBlb2YgYSE9XCJ1bmRlZmluZWRcIil7aWYodHlwZW9mIGEudGFnIT1cInVuZGVmaW5lZFwiKXt0aGlzLmhUPWEudGFnfWlmKHR5cGVvZiBhLmV4cGxpY2l0IT1cInVuZGVmaW5lZFwiKXt0aGlzLmlzRXhwbGljaXQ9YS5leHBsaWNpdH1pZih0eXBlb2YgYS5vYmohPVwidW5kZWZpbmVkXCIpe3RoaXMuYXNuMU9iamVjdD1hLm9iajt0aGlzLnNldEFTTjFPYmplY3QodGhpcy5pc0V4cGxpY2l0LHRoaXMuaFQsdGhpcy5hc24xT2JqZWN0KX19fTtZQUhPTy5sYW5nLmV4dGVuZChLSlVSLmFzbjEuREVSVGFnZ2VkT2JqZWN0LEtKVVIuYXNuMS5BU04xT2JqZWN0KTtcbnZhciBBU04xSEVYPW5ldyBmdW5jdGlvbigpe307QVNOMUhFWC5nZXRMYmxlbj1mdW5jdGlvbihjLGEpe2lmKGMuc3Vic3RyKGErMiwxKSE9XCI4XCIpe3JldHVybiAxfXZhciBiPXBhcnNlSW50KGMuc3Vic3RyKGErMywxKSk7aWYoYj09MCl7cmV0dXJuIC0xfWlmKDA8YiYmYjwxMCl7cmV0dXJuIGIrMX1yZXR1cm4gLTJ9O0FTTjFIRVguZ2V0TD1mdW5jdGlvbihjLGIpe3ZhciBhPUFTTjFIRVguZ2V0TGJsZW4oYyxiKTtpZihhPDEpe3JldHVyblwiXCJ9cmV0dXJuIGMuc3Vic3RyKGIrMixhKjIpfTtBU04xSEVYLmdldFZibGVuPWZ1bmN0aW9uKGQsYSl7dmFyIGMsYjtjPUFTTjFIRVguZ2V0TChkLGEpO2lmKGM9PVwiXCIpe3JldHVybiAtMX1pZihjLnN1YnN0cigwLDEpPT09XCI4XCIpe2I9bmV3IEJpZ0ludGVnZXIoYy5zdWJzdHIoMiksMTYpfWVsc2V7Yj1uZXcgQmlnSW50ZWdlcihjLDE2KX1yZXR1cm4gYi5pbnRWYWx1ZSgpfTtBU04xSEVYLmdldFZpZHg9ZnVuY3Rpb24oYyxiKXt2YXIgYT1BU04xSEVYLmdldExibGVuKGMsYik7aWYoYTwwKXtyZXR1cm4gYX1yZXR1cm4gYisoYSsxKSoyfTtBU04xSEVYLmdldFY9ZnVuY3Rpb24oZCxhKXt2YXIgYz1BU04xSEVYLmdldFZpZHgoZCxhKTt2YXIgYj1BU04xSEVYLmdldFZibGVuKGQsYSk7cmV0dXJuIGQuc3Vic3RyKGMsYioyKX07QVNOMUhFWC5nZXRUTFY9ZnVuY3Rpb24oYixhKXtyZXR1cm4gYi5zdWJzdHIoYSwyKStBU04xSEVYLmdldEwoYixhKStBU04xSEVYLmdldFYoYixhKX07QVNOMUhFWC5nZXROZXh0U2libGluZ0lkeD1mdW5jdGlvbihkLGEpe3ZhciBjPUFTTjFIRVguZ2V0VmlkeChkLGEpO3ZhciBiPUFTTjFIRVguZ2V0VmJsZW4oZCxhKTtyZXR1cm4gYytiKjJ9O0FTTjFIRVguZ2V0Q2hpbGRJZHg9ZnVuY3Rpb24oZSxmKXt2YXIgaj1BU04xSEVYO3ZhciBnPW5ldyBBcnJheSgpO3ZhciBpPWouZ2V0VmlkeChlLGYpO2lmKGUuc3Vic3RyKGYsMik9PVwiMDNcIil7Zy5wdXNoKGkrMil9ZWxzZXtnLnB1c2goaSl9dmFyIGw9ai5nZXRWYmxlbihlLGYpO3ZhciBjPWk7dmFyIGQ9MDt3aGlsZSgxKXt2YXIgYj1qLmdldE5leHRTaWJsaW5nSWR4KGUsYyk7aWYoYj09bnVsbHx8KGItaT49KGwqMikpKXticmVha31pZihkPj0yMDApe2JyZWFrfWcucHVzaChiKTtjPWI7ZCsrfXJldHVybiBnfTtBU04xSEVYLmdldE50aENoaWxkSWR4PWZ1bmN0aW9uKGQsYixlKXt2YXIgYz1BU04xSEVYLmdldENoaWxkSWR4KGQsYik7cmV0dXJuIGNbZV19O0FTTjFIRVguZ2V0SWR4YnlMaXN0PWZ1bmN0aW9uKGUsZCxjLGkpe3ZhciBnPUFTTjFIRVg7dmFyIGYsYjtpZihjLmxlbmd0aD09MCl7aWYoaSE9PXVuZGVmaW5lZCl7aWYoZS5zdWJzdHIoZCwyKSE9PWkpe3Rocm93XCJjaGVja2luZyB0YWcgZG9lc24ndCBtYXRjaDogXCIrZS5zdWJzdHIoZCwyKStcIiE9XCIraX19cmV0dXJuIGR9Zj1jLnNoaWZ0KCk7Yj1nLmdldENoaWxkSWR4KGUsZCk7cmV0dXJuIGcuZ2V0SWR4YnlMaXN0KGUsYltmXSxjLGkpfTtBU04xSEVYLmdldFRMVmJ5TGlzdD1mdW5jdGlvbihkLGMsYixmKXt2YXIgZT1BU04xSEVYO3ZhciBhPWUuZ2V0SWR4YnlMaXN0KGQsYyxiKTtpZihhPT09dW5kZWZpbmVkKXt0aHJvd1wiY2FuJ3QgZmluZCBudGhMaXN0IG9iamVjdFwifWlmKGYhPT11bmRlZmluZWQpe2lmKGQuc3Vic3RyKGEsMikhPWYpe3Rocm93XCJjaGVja2luZyB0YWcgZG9lc24ndCBtYXRjaDogXCIrZC5zdWJzdHIoYSwyKStcIiE9XCIrZn19cmV0dXJuIGUuZ2V0VExWKGQsYSl9O0FTTjFIRVguZ2V0VmJ5TGlzdD1mdW5jdGlvbihlLGMsYixnLGkpe3ZhciBmPUFTTjFIRVg7dmFyIGEsZDthPWYuZ2V0SWR4YnlMaXN0KGUsYyxiLGcpO2lmKGE9PT11bmRlZmluZWQpe3Rocm93XCJjYW4ndCBmaW5kIG50aExpc3Qgb2JqZWN0XCJ9ZD1mLmdldFYoZSxhKTtpZihpPT09dHJ1ZSl7ZD1kLnN1YnN0cigyKX1yZXR1cm4gZH07QVNOMUhFWC5oZXh0b29pZHN0cj1mdW5jdGlvbihlKXt2YXIgaD1mdW5jdGlvbihiLGEpe2lmKGIubGVuZ3RoPj1hKXtyZXR1cm4gYn1yZXR1cm4gbmV3IEFycmF5KGEtYi5sZW5ndGgrMSkuam9pbihcIjBcIikrYn07dmFyIGw9W107dmFyIG89ZS5zdWJzdHIoMCwyKTt2YXIgZj1wYXJzZUludChvLDE2KTtsWzBdPW5ldyBTdHJpbmcoTWF0aC5mbG9vcihmLzQwKSk7bFsxXT1uZXcgU3RyaW5nKGYlNDApO3ZhciBtPWUuc3Vic3RyKDIpO3ZhciBrPVtdO2Zvcih2YXIgZz0wO2c8bS5sZW5ndGgvMjtnKyspe2sucHVzaChwYXJzZUludChtLnN1YnN0cihnKjIsMiksMTYpKX12YXIgaj1bXTt2YXIgZD1cIlwiO2Zvcih2YXIgZz0wO2c8ay5sZW5ndGg7ZysrKXtpZihrW2ddJjEyOCl7ZD1kK2goKGtbZ10mMTI3KS50b1N0cmluZygyKSw3KX1lbHNle2Q9ZCtoKChrW2ddJjEyNykudG9TdHJpbmcoMiksNyk7ai5wdXNoKG5ldyBTdHJpbmcocGFyc2VJbnQoZCwyKSkpO2Q9XCJcIn19dmFyIG49bC5qb2luKFwiLlwiKTtpZihqLmxlbmd0aD4wKXtuPW4rXCIuXCIrai5qb2luKFwiLlwiKX1yZXR1cm4gbn07QVNOMUhFWC5kdW1wPWZ1bmN0aW9uKHQsYyxsLGcpe3ZhciBwPUFTTjFIRVg7dmFyIGo9cC5nZXRWO3ZhciB5PXAuZHVtcDt2YXIgdz1wLmdldENoaWxkSWR4O3ZhciBlPXQ7aWYodCBpbnN0YW5jZW9mIEtKVVIuYXNuMS5BU04xT2JqZWN0KXtlPXQuZ2V0RW5jb2RlZEhleCgpfXZhciBxPWZ1bmN0aW9uKEEsaSl7aWYoQS5sZW5ndGg8PWkqMil7cmV0dXJuIEF9ZWxzZXt2YXIgdj1BLnN1YnN0cigwLGkpK1wiLi4odG90YWwgXCIrQS5sZW5ndGgvMitcImJ5dGVzKS4uXCIrQS5zdWJzdHIoQS5sZW5ndGgtaSxpKTtyZXR1cm4gdn19O2lmKGM9PT11bmRlZmluZWQpe2M9e29tbWl0X2xvbmdfb2N0ZXQ6MzJ9fWlmKGw9PT11bmRlZmluZWQpe2w9MH1pZihnPT09dW5kZWZpbmVkKXtnPVwiXCJ9dmFyIHg9Yy5vbW1pdF9sb25nX29jdGV0O2lmKGUuc3Vic3RyKGwsMik9PVwiMDFcIil7dmFyIGg9aihlLGwpO2lmKGg9PVwiMDBcIil7cmV0dXJuIGcrXCJCT09MRUFOIEZBTFNFXFxuXCJ9ZWxzZXtyZXR1cm4gZytcIkJPT0xFQU4gVFJVRVxcblwifX1pZihlLnN1YnN0cihsLDIpPT1cIjAyXCIpe3ZhciBoPWooZSxsKTtyZXR1cm4gZytcIklOVEVHRVIgXCIrcShoLHgpK1wiXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIwM1wiKXt2YXIgaD1qKGUsbCk7cmV0dXJuIGcrXCJCSVRTVFJJTkcgXCIrcShoLHgpK1wiXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIwNFwiKXt2YXIgaD1qKGUsbCk7aWYocC5pc0FTTjFIRVgoaCkpe3ZhciBrPWcrXCJPQ1RFVFNUUklORywgZW5jYXBzdWxhdGVzXFxuXCI7az1rK3koaCxjLDAsZytcIiAgXCIpO3JldHVybiBrfWVsc2V7cmV0dXJuIGcrXCJPQ1RFVFNUUklORyBcIitxKGgseCkrXCJcXG5cIn19aWYoZS5zdWJzdHIobCwyKT09XCIwNVwiKXtyZXR1cm4gZytcIk5VTExcXG5cIn1pZihlLnN1YnN0cihsLDIpPT1cIjA2XCIpe3ZhciBtPWooZSxsKTt2YXIgYT1LSlVSLmFzbjEuQVNOMVV0aWwub2lkSGV4VG9JbnQobSk7dmFyIG89S0pVUi5hc24xLng1MDkuT0lELm9pZDJuYW1lKGEpO3ZhciBiPWEucmVwbGFjZSgvXFwuL2csXCIgXCIpO2lmKG8hPVwiXCIpe3JldHVybiBnK1wiT2JqZWN0SWRlbnRpZmllciBcIitvK1wiIChcIitiK1wiKVxcblwifWVsc2V7cmV0dXJuIGcrXCJPYmplY3RJZGVudGlmaWVyIChcIitiK1wiKVxcblwifX1pZihlLnN1YnN0cihsLDIpPT1cIjBjXCIpe3JldHVybiBnK1wiVVRGOFN0cmluZyAnXCIraGV4dG91dGY4KGooZSxsKSkrXCInXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIxM1wiKXtyZXR1cm4gZytcIlByaW50YWJsZVN0cmluZyAnXCIraGV4dG91dGY4KGooZSxsKSkrXCInXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIxNFwiKXtyZXR1cm4gZytcIlRlbGV0ZXhTdHJpbmcgJ1wiK2hleHRvdXRmOChqKGUsbCkpK1wiJ1xcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMTZcIil7cmV0dXJuIGcrXCJJQTVTdHJpbmcgJ1wiK2hleHRvdXRmOChqKGUsbCkpK1wiJ1xcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMTdcIil7cmV0dXJuIGcrXCJVVENUaW1lIFwiK2hleHRvdXRmOChqKGUsbCkpK1wiXFxuXCJ9aWYoZS5zdWJzdHIobCwyKT09XCIxOFwiKXtyZXR1cm4gZytcIkdlbmVyYWxpemVkVGltZSBcIitoZXh0b3V0ZjgoaihlLGwpKStcIlxcblwifWlmKGUuc3Vic3RyKGwsMik9PVwiMzBcIil7aWYoZS5zdWJzdHIobCw0KT09XCIzMDAwXCIpe3JldHVybiBnK1wiU0VRVUVOQ0Uge31cXG5cIn12YXIgaz1nK1wiU0VRVUVOQ0VcXG5cIjt2YXIgZD13KGUsbCk7dmFyIGY9YztpZigoZC5sZW5ndGg9PTJ8fGQubGVuZ3RoPT0zKSYmZS5zdWJzdHIoZFswXSwyKT09XCIwNlwiJiZlLnN1YnN0cihkW2QubGVuZ3RoLTFdLDIpPT1cIjA0XCIpe3ZhciBvPXAub2lkbmFtZShqKGUsZFswXSkpO3ZhciByPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoYykpO3IueDUwOUV4dE5hbWU9bztmPXJ9Zm9yKHZhciB1PTA7dTxkLmxlbmd0aDt1Kyspe2s9ayt5KGUsZixkW3VdLGcrXCIgIFwiKX1yZXR1cm4ga31pZihlLnN1YnN0cihsLDIpPT1cIjMxXCIpe3ZhciBrPWcrXCJTRVRcXG5cIjt2YXIgZD13KGUsbCk7Zm9yKHZhciB1PTA7dTxkLmxlbmd0aDt1Kyspe2s9ayt5KGUsYyxkW3VdLGcrXCIgIFwiKX1yZXR1cm4ga312YXIgej1wYXJzZUludChlLnN1YnN0cihsLDIpLDE2KTtpZigoeiYxMjgpIT0wKXt2YXIgbj16JjMxO2lmKCh6JjMyKSE9MCl7dmFyIGs9ZytcIltcIituK1wiXVxcblwiO3ZhciBkPXcoZSxsKTtmb3IodmFyIHU9MDt1PGQubGVuZ3RoO3UrKyl7az1rK3koZSxjLGRbdV0sZytcIiAgXCIpfXJldHVybiBrfWVsc2V7dmFyIGg9aihlLGwpO2lmKGguc3Vic3RyKDAsOCk9PVwiNjg3NDc0NzBcIil7aD1oZXh0b3V0ZjgoaCl9aWYoYy54NTA5RXh0TmFtZT09PVwic3ViamVjdEFsdE5hbWVcIiYmbj09Mil7aD1oZXh0b3V0ZjgoaCl9dmFyIGs9ZytcIltcIituK1wiXSBcIitoK1wiXFxuXCI7cmV0dXJuIGt9fXJldHVybiBnK1wiVU5LTk9XTihcIitlLnN1YnN0cihsLDIpK1wiKSBcIitqKGUsbCkrXCJcXG5cIn07QVNOMUhFWC5pc0FTTjFIRVg9ZnVuY3Rpb24oZSl7dmFyIGQ9QVNOMUhFWDtpZihlLmxlbmd0aCUyPT0xKXtyZXR1cm4gZmFsc2V9dmFyIGM9ZC5nZXRWYmxlbihlLDApO3ZhciBiPWUuc3Vic3RyKDAsMik7dmFyIGY9ZC5nZXRMKGUsMCk7dmFyIGE9ZS5sZW5ndGgtYi5sZW5ndGgtZi5sZW5ndGg7aWYoYT09YyoyKXtyZXR1cm4gdHJ1ZX1yZXR1cm4gZmFsc2V9O0FTTjFIRVgub2lkbmFtZT1mdW5jdGlvbihhKXt2YXIgYz1LSlVSLmFzbjE7aWYoS0pVUi5sYW5nLlN0cmluZy5pc0hleChhKSl7YT1jLkFTTjFVdGlsLm9pZEhleFRvSW50KGEpfXZhciBiPWMueDUwOS5PSUQub2lkMm5hbWUoYSk7aWYoYj09PVwiXCIpe2I9YX1yZXR1cm4gYn07XG52YXIgS0pVUjtpZih0eXBlb2YgS0pVUj09XCJ1bmRlZmluZWRcInx8IUtKVVIpe0tKVVI9e319aWYodHlwZW9mIEtKVVIubGFuZz09XCJ1bmRlZmluZWRcInx8IUtKVVIubGFuZyl7S0pVUi5sYW5nPXt9fUtKVVIubGFuZy5TdHJpbmc9ZnVuY3Rpb24oKXt9O2Z1bmN0aW9uIEJhc2U2NHgoKXt9ZnVuY3Rpb24gc3RvQkEoZCl7dmFyIGI9bmV3IEFycmF5KCk7Zm9yKHZhciBjPTA7YzxkLmxlbmd0aDtjKyspe2JbY109ZC5jaGFyQ29kZUF0KGMpfXJldHVybiBifWZ1bmN0aW9uIEJBdG9zKGIpe3ZhciBkPVwiXCI7Zm9yKHZhciBjPTA7YzxiLmxlbmd0aDtjKyspe2Q9ZCtTdHJpbmcuZnJvbUNoYXJDb2RlKGJbY10pfXJldHVybiBkfWZ1bmN0aW9uIEJBdG9oZXgoYil7dmFyIGU9XCJcIjtmb3IodmFyIGQ9MDtkPGIubGVuZ3RoO2QrKyl7dmFyIGM9YltkXS50b1N0cmluZygxNik7aWYoYy5sZW5ndGg9PTEpe2M9XCIwXCIrY31lPWUrY31yZXR1cm4gZX1mdW5jdGlvbiBzdG9oZXgoYSl7cmV0dXJuIEJBdG9oZXgoc3RvQkEoYSkpfWZ1bmN0aW9uIHN0b2I2NChhKXtyZXR1cm4gaGV4MmI2NChzdG9oZXgoYSkpfWZ1bmN0aW9uIHN0b2I2NHUoYSl7cmV0dXJuIGI2NHRvYjY0dShoZXgyYjY0KHN0b2hleChhKSkpfWZ1bmN0aW9uIGI2NHV0b3MoYSl7cmV0dXJuIEJBdG9zKGI2NHRvQkEoYjY0dXRvYjY0KGEpKSl9ZnVuY3Rpb24gYjY0dG9iNjR1KGEpe2E9YS5yZXBsYWNlKC9cXD0vZyxcIlwiKTthPWEucmVwbGFjZSgvXFwrL2csXCItXCIpO2E9YS5yZXBsYWNlKC9cXC8vZyxcIl9cIik7cmV0dXJuIGF9ZnVuY3Rpb24gYjY0dXRvYjY0KGEpe2lmKGEubGVuZ3RoJTQ9PTIpe2E9YStcIj09XCJ9ZWxzZXtpZihhLmxlbmd0aCU0PT0zKXthPWErXCI9XCJ9fWE9YS5yZXBsYWNlKC8tL2csXCIrXCIpO2E9YS5yZXBsYWNlKC9fL2csXCIvXCIpO3JldHVybiBhfWZ1bmN0aW9uIGhleHRvYjY0dShhKXtpZihhLmxlbmd0aCUyPT0xKXthPVwiMFwiK2F9cmV0dXJuIGI2NHRvYjY0dShoZXgyYjY0KGEpKX1mdW5jdGlvbiBiNjR1dG9oZXgoYSl7cmV0dXJuIGI2NHRvaGV4KGI2NHV0b2I2NChhKSl9dmFyIHV0Zjh0b2I2NHUsYjY0dXRvdXRmODtpZih0eXBlb2YgQnVmZmVyPT09XCJmdW5jdGlvblwiKXt1dGY4dG9iNjR1PWZ1bmN0aW9uKGEpe3JldHVybiBiNjR0b2I2NHUobmV3IEJ1ZmZlcihhLFwidXRmOFwiKS50b1N0cmluZyhcImJhc2U2NFwiKSl9O2I2NHV0b3V0Zjg9ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBCdWZmZXIoYjY0dXRvYjY0KGEpLFwiYmFzZTY0XCIpLnRvU3RyaW5nKFwidXRmOFwiKX19ZWxzZXt1dGY4dG9iNjR1PWZ1bmN0aW9uKGEpe3JldHVybiBoZXh0b2I2NHUodXJpY21wdG9oZXgoZW5jb2RlVVJJQ29tcG9uZW50QWxsKGEpKSl9O2I2NHV0b3V0Zjg9ZnVuY3Rpb24oYSl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChoZXh0b3VyaWNtcChiNjR1dG9oZXgoYSkpKX19ZnVuY3Rpb24gdXRmOHRvYjY0KGEpe3JldHVybiBoZXgyYjY0KHVyaWNtcHRvaGV4KGVuY29kZVVSSUNvbXBvbmVudEFsbChhKSkpfWZ1bmN0aW9uIGI2NHRvdXRmOChhKXtyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGhleHRvdXJpY21wKGI2NHRvaGV4KGEpKSl9ZnVuY3Rpb24gdXRmOHRvaGV4KGEpe3JldHVybiB1cmljbXB0b2hleChlbmNvZGVVUklDb21wb25lbnRBbGwoYSkpfWZ1bmN0aW9uIGhleHRvdXRmOChhKXtyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGhleHRvdXJpY21wKGEpKX1mdW5jdGlvbiBoZXh0b3JzdHIoYyl7dmFyIGI9XCJcIjtmb3IodmFyIGE9MDthPGMubGVuZ3RoLTE7YSs9Mil7Yis9U3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChjLnN1YnN0cihhLDIpLDE2KSl9cmV0dXJuIGJ9ZnVuY3Rpb24gcnN0cnRvaGV4KGMpe3ZhciBhPVwiXCI7Zm9yKHZhciBiPTA7YjxjLmxlbmd0aDtiKyspe2ErPShcIjBcIitjLmNoYXJDb2RlQXQoYikudG9TdHJpbmcoMTYpKS5zbGljZSgtMil9cmV0dXJuIGF9ZnVuY3Rpb24gaGV4dG9iNjQoYSl7cmV0dXJuIGhleDJiNjQoYSl9ZnVuY3Rpb24gaGV4dG9iNjRubChiKXt2YXIgYT1oZXh0b2I2NChiKTt2YXIgYz1hLnJlcGxhY2UoLyguezY0fSkvZyxcIiQxXFxyXFxuXCIpO2M9Yy5yZXBsYWNlKC9cXHJcXG4kLyxcIlwiKTtyZXR1cm4gY31mdW5jdGlvbiBiNjRubHRvaGV4KGIpe3ZhciBhPWIucmVwbGFjZSgvW14wLTlBLVphLXpcXC8rPV0qL2csXCJcIik7dmFyIGM9YjY0dG9oZXgoYSk7cmV0dXJuIGN9ZnVuY3Rpb24gaGV4dG9wZW0oYSxiKXt2YXIgYz1oZXh0b2I2NG5sKGEpO3JldHVyblwiLS0tLS1CRUdJTiBcIitiK1wiLS0tLS1cXHJcXG5cIitjK1wiXFxyXFxuLS0tLS1FTkQgXCIrYitcIi0tLS0tXFxyXFxuXCJ9ZnVuY3Rpb24gcGVtdG9oZXgoYSxiKXtpZihhLmluZGV4T2YoXCItLS0tLUJFR0lOIFwiKT09LTEpe3Rocm93XCJjYW4ndCBmaW5kIFBFTSBoZWFkZXI6IFwiK2J9aWYoYiE9PXVuZGVmaW5lZCl7YT1hLnJlcGxhY2UoXCItLS0tLUJFR0lOIFwiK2IrXCItLS0tLVwiLFwiXCIpO2E9YS5yZXBsYWNlKFwiLS0tLS1FTkQgXCIrYitcIi0tLS0tXCIsXCJcIil9ZWxzZXthPWEucmVwbGFjZSgvLS0tLS1CRUdJTiBbXi1dKy0tLS0tLyxcIlwiKTthPWEucmVwbGFjZSgvLS0tLS1FTkQgW14tXSstLS0tLS8sXCJcIil9cmV0dXJuIGI2NG5sdG9oZXgoYSl9ZnVuY3Rpb24gaGV4dG9BcnJheUJ1ZmZlcihkKXtpZihkLmxlbmd0aCUyIT0wKXt0aHJvd1wiaW5wdXQgaXMgbm90IGV2ZW4gbGVuZ3RoXCJ9aWYoZC5tYXRjaCgvXlswLTlBLUZhLWZdKyQvKT09bnVsbCl7dGhyb3dcImlucHV0IGlzIG5vdCBoZXhhZGVjaW1hbFwifXZhciBiPW5ldyBBcnJheUJ1ZmZlcihkLmxlbmd0aC8yKTt2YXIgYT1uZXcgRGF0YVZpZXcoYik7Zm9yKHZhciBjPTA7YzxkLmxlbmd0aC8yO2MrKyl7YS5zZXRVaW50OChjLHBhcnNlSW50KGQuc3Vic3RyKGMqMiwyKSwxNikpfXJldHVybiBifWZ1bmN0aW9uIEFycmF5QnVmZmVydG9oZXgoYil7dmFyIGQ9XCJcIjt2YXIgYT1uZXcgRGF0YVZpZXcoYik7Zm9yKHZhciBjPTA7YzxiLmJ5dGVMZW5ndGg7YysrKXtkKz0oXCIwMFwiK2EuZ2V0VWludDgoYykudG9TdHJpbmcoMTYpKS5zbGljZSgtMil9cmV0dXJuIGR9ZnVuY3Rpb24genVsdXRvbXNlYyhuKXt2YXIgbCxqLG0sZSxmLGksYixrO3ZhciBhLGgsZyxjO2M9bi5tYXRjaCgvXihcXGR7Mn18XFxkezR9KShcXGRcXGQpKFxcZFxcZCkoXFxkXFxkKShcXGRcXGQpKFxcZFxcZCkofFxcLlxcZCspWiQvKTtpZihjKXthPWNbMV07bD1wYXJzZUludChhKTtpZihhLmxlbmd0aD09PTIpe2lmKDUwPD1sJiZsPDEwMCl7bD0xOTAwK2x9ZWxzZXtpZigwPD1sJiZsPDUwKXtsPTIwMDArbH19fWo9cGFyc2VJbnQoY1syXSktMTttPXBhcnNlSW50KGNbM10pO2U9cGFyc2VJbnQoY1s0XSk7Zj1wYXJzZUludChjWzVdKTtpPXBhcnNlSW50KGNbNl0pO2I9MDtoPWNbN107aWYoaCE9PVwiXCIpe2c9KGguc3Vic3RyKDEpK1wiMDBcIikuc3Vic3RyKDAsMyk7Yj1wYXJzZUludChnKX1yZXR1cm4gRGF0ZS5VVEMobCxqLG0sZSxmLGksYil9dGhyb3dcInVuc3VwcG9ydGVkIHp1bHUgZm9ybWF0OiBcIitufWZ1bmN0aW9uIHp1bHV0b3NlYyhhKXt2YXIgYj16dWx1dG9tc2VjKGEpO3JldHVybiB+fihiLzEwMDApfWZ1bmN0aW9uIHp1bHV0b2RhdGUoYSl7cmV0dXJuIG5ldyBEYXRlKHp1bHV0b21zZWMoYSkpfWZ1bmN0aW9uIGRhdGV0b3p1bHUoZyxlLGYpe3ZhciBiO3ZhciBhPWcuZ2V0VVRDRnVsbFllYXIoKTtpZihlKXtpZihhPDE5NTB8fDIwNDk8YSl7dGhyb3dcIm5vdCBwcm9wZXIgeWVhciBmb3IgVVRDVGltZTogXCIrYX1iPShcIlwiK2EpLnNsaWNlKC0yKX1lbHNle2I9KFwiMDAwXCIrYSkuc2xpY2UoLTQpfWIrPShcIjBcIisoZy5nZXRVVENNb250aCgpKzEpKS5zbGljZSgtMik7Yis9KFwiMFwiK2cuZ2V0VVRDRGF0ZSgpKS5zbGljZSgtMik7Yis9KFwiMFwiK2cuZ2V0VVRDSG91cnMoKSkuc2xpY2UoLTIpO2IrPShcIjBcIitnLmdldFVUQ01pbnV0ZXMoKSkuc2xpY2UoLTIpO2IrPShcIjBcIitnLmdldFVUQ1NlY29uZHMoKSkuc2xpY2UoLTIpO2lmKGYpe3ZhciBjPWcuZ2V0VVRDTWlsbGlzZWNvbmRzKCk7aWYoYyE9PTApe2M9KFwiMDBcIitjKS5zbGljZSgtMyk7Yz1jLnJlcGxhY2UoLzArJC9nLFwiXCIpO2IrPVwiLlwiK2N9fWIrPVwiWlwiO3JldHVybiBifWZ1bmN0aW9uIHVyaWNtcHRvaGV4KGEpe3JldHVybiBhLnJlcGxhY2UoLyUvZyxcIlwiKX1mdW5jdGlvbiBoZXh0b3VyaWNtcChhKXtyZXR1cm4gYS5yZXBsYWNlKC8oLi4pL2csXCIlJDFcIil9ZnVuY3Rpb24gaXB2NnRvaGV4KGcpe3ZhciBiPVwibWFsZm9ybWVkIElQdjYgYWRkcmVzc1wiO2lmKCFnLm1hdGNoKC9eWzAtOUEtRmEtZjpdKyQvKSl7dGhyb3cgYn1nPWcudG9Mb3dlckNhc2UoKTt2YXIgZD1nLnNwbGl0KFwiOlwiKS5sZW5ndGgtMTtpZihkPDIpe3Rocm93IGJ9dmFyIGU9XCI6XCIucmVwZWF0KDctZCsyKTtnPWcucmVwbGFjZShcIjo6XCIsZSk7dmFyIGM9Zy5zcGxpdChcIjpcIik7aWYoYy5sZW5ndGghPTgpe3Rocm93IGJ9Zm9yKHZhciBmPTA7Zjw4O2YrKyl7Y1tmXT0oXCIwMDAwXCIrY1tmXSkuc2xpY2UoLTQpfXJldHVybiBjLmpvaW4oXCJcIil9ZnVuY3Rpb24gaGV4dG9pcHY2KGUpe2lmKCFlLm1hdGNoKC9eWzAtOUEtRmEtZl17MzJ9JC8pKXt0aHJvd1wibWFsZm9ybWVkIElQdjYgYWRkcmVzcyBvY3RldFwifWU9ZS50b0xvd2VyQ2FzZSgpO3ZhciBiPWUubWF0Y2goLy57MSw0fS9nKTtmb3IodmFyIGQ9MDtkPDg7ZCsrKXtiW2RdPWJbZF0ucmVwbGFjZSgvXjArLyxcIlwiKTtpZihiW2RdPT1cIlwiKXtiW2RdPVwiMFwifX1lPVwiOlwiK2Iuam9pbihcIjpcIikrXCI6XCI7dmFyIGM9ZS5tYXRjaCgvOigwOil7Mix9L2cpO2lmKGM9PT1udWxsKXtyZXR1cm4gZS5zbGljZSgxLC0xKX12YXIgZj1cIlwiO2Zvcih2YXIgZD0wO2Q8Yy5sZW5ndGg7ZCsrKXtpZihjW2RdLmxlbmd0aD5mLmxlbmd0aCl7Zj1jW2RdfX1lPWUucmVwbGFjZShmLFwiOjpcIik7cmV0dXJuIGUuc2xpY2UoMSwtMSl9ZnVuY3Rpb24gaGV4dG9pcChiKXt2YXIgZD1cIm1hbGZvcm1lZCBoZXggdmFsdWVcIjtpZighYi5tYXRjaCgvXihbMC05QS1GYS1mXVswLTlBLUZhLWZdKXsxLH0kLykpe3Rocm93IGR9aWYoYi5sZW5ndGg9PTgpe3ZhciBjO3RyeXtjPXBhcnNlSW50KGIuc3Vic3RyKDAsMiksMTYpK1wiLlwiK3BhcnNlSW50KGIuc3Vic3RyKDIsMiksMTYpK1wiLlwiK3BhcnNlSW50KGIuc3Vic3RyKDQsMiksMTYpK1wiLlwiK3BhcnNlSW50KGIuc3Vic3RyKDYsMiksMTYpO3JldHVybiBjfWNhdGNoKGEpe3Rocm93IGR9fWVsc2V7aWYoYi5sZW5ndGg9PTMyKXtyZXR1cm4gaGV4dG9pcHY2KGIpfWVsc2V7cmV0dXJuIGJ9fX1mdW5jdGlvbiBpcHRvaGV4KGYpe3ZhciBqPVwibWFsZm9ybWVkIElQIGFkZHJlc3NcIjtmPWYudG9Mb3dlckNhc2UoZik7aWYoZi5tYXRjaCgvXlswLTkuXSskLykpe3ZhciBiPWYuc3BsaXQoXCIuXCIpO2lmKGIubGVuZ3RoIT09NCl7dGhyb3cgan12YXIgZz1cIlwiO3RyeXtmb3IodmFyIGU9MDtlPDQ7ZSsrKXt2YXIgaD1wYXJzZUludChiW2VdKTtnKz0oXCIwXCIraC50b1N0cmluZygxNikpLnNsaWNlKC0yKX1yZXR1cm4gZ31jYXRjaChjKXt0aHJvdyBqfX1lbHNle2lmKGYubWF0Y2goL15bMC05YS1mOl0rJC8pJiZmLmluZGV4T2YoXCI6XCIpIT09LTEpe3JldHVybiBpcHY2dG9oZXgoZil9ZWxzZXt0aHJvdyBqfX19ZnVuY3Rpb24gZW5jb2RlVVJJQ29tcG9uZW50QWxsKGEpe3ZhciBkPWVuY29kZVVSSUNvbXBvbmVudChhKTt2YXIgYj1cIlwiO2Zvcih2YXIgYz0wO2M8ZC5sZW5ndGg7YysrKXtpZihkW2NdPT1cIiVcIil7Yj1iK2Quc3Vic3RyKGMsMyk7Yz1jKzJ9ZWxzZXtiPWIrXCIlXCIrc3RvaGV4KGRbY10pfX1yZXR1cm4gYn1mdW5jdGlvbiBuZXdsaW5lX3RvVW5peChhKXthPWEucmVwbGFjZSgvXFxyXFxuL21nLFwiXFxuXCIpO3JldHVybiBhfWZ1bmN0aW9uIG5ld2xpbmVfdG9Eb3MoYSl7YT1hLnJlcGxhY2UoL1xcclxcbi9tZyxcIlxcblwiKTthPWEucmVwbGFjZSgvXFxuL21nLFwiXFxyXFxuXCIpO3JldHVybiBhfUtKVVIubGFuZy5TdHJpbmcuaXNJbnRlZ2VyPWZ1bmN0aW9uKGEpe2lmKGEubWF0Y2goL15bMC05XSskLykpe3JldHVybiB0cnVlfWVsc2V7aWYoYS5tYXRjaCgvXi1bMC05XSskLykpe3JldHVybiB0cnVlfWVsc2V7cmV0dXJuIGZhbHNlfX19O0tKVVIubGFuZy5TdHJpbmcuaXNIZXg9ZnVuY3Rpb24oYSl7aWYoYS5sZW5ndGglMj09MCYmKGEubWF0Y2goL15bMC05YS1mXSskLyl8fGEubWF0Y2goL15bMC05QS1GXSskLykpKXtyZXR1cm4gdHJ1ZX1lbHNle3JldHVybiBmYWxzZX19O0tKVVIubGFuZy5TdHJpbmcuaXNCYXNlNjQ9ZnVuY3Rpb24oYSl7YT1hLnJlcGxhY2UoL1xccysvZyxcIlwiKTtpZihhLm1hdGNoKC9eWzAtOUEtWmEteitcXC9dKz17MCwzfSQvKSYmYS5sZW5ndGglND09MCl7cmV0dXJuIHRydWV9ZWxzZXtyZXR1cm4gZmFsc2V9fTtLSlVSLmxhbmcuU3RyaW5nLmlzQmFzZTY0VVJMPWZ1bmN0aW9uKGEpe2lmKGEubWF0Y2goL1srLz1dLykpe3JldHVybiBmYWxzZX1hPWI2NHV0b2I2NChhKTtyZXR1cm4gS0pVUi5sYW5nLlN0cmluZy5pc0Jhc2U2NChhKX07S0pVUi5sYW5nLlN0cmluZy5pc0ludGVnZXJBcnJheT1mdW5jdGlvbihhKXthPWEucmVwbGFjZSgvXFxzKy9nLFwiXCIpO2lmKGEubWF0Y2goL15cXFtbMC05LF0rXFxdJC8pKXtyZXR1cm4gdHJ1ZX1lbHNle3JldHVybiBmYWxzZX19O2Z1bmN0aW9uIGhleHRvcG9zaGV4KGEpe2lmKGEubGVuZ3RoJTI9PTEpe3JldHVyblwiMFwiK2F9aWYoYS5zdWJzdHIoMCwxKT5cIjdcIil7cmV0dXJuXCIwMFwiK2F9cmV0dXJuIGF9ZnVuY3Rpb24gaW50YXJ5c3RydG9oZXgoYil7Yj1iLnJlcGxhY2UoL15cXHMqXFxbXFxzKi8sXCJcIik7Yj1iLnJlcGxhY2UoL1xccypcXF1cXHMqJC8sXCJcIik7Yj1iLnJlcGxhY2UoL1xccyovZyxcIlwiKTt0cnl7dmFyIGM9Yi5zcGxpdCgvLC8pLm1hcChmdW5jdGlvbihnLGUsaCl7dmFyIGY9cGFyc2VJbnQoZyk7aWYoZjwwfHwyNTU8Zil7dGhyb3dcImludGVnZXIgbm90IGluIHJhbmdlIDAtMjU1XCJ9dmFyIGQ9KFwiMDBcIitmLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTIpO3JldHVybiBkfSkuam9pbihcIlwiKTtyZXR1cm4gY31jYXRjaChhKXt0aHJvd1wibWFsZm9ybWVkIGludGVnZXIgYXJyYXkgc3RyaW5nOiBcIithfX12YXIgc3RyZGlmZmlkeD1mdW5jdGlvbihjLGEpe3ZhciBkPWMubGVuZ3RoO2lmKGMubGVuZ3RoPmEubGVuZ3RoKXtkPWEubGVuZ3RofWZvcih2YXIgYj0wO2I8ZDtiKyspe2lmKGMuY2hhckNvZGVBdChiKSE9YS5jaGFyQ29kZUF0KGIpKXtyZXR1cm4gYn19aWYoYy5sZW5ndGghPWEubGVuZ3RoKXtyZXR1cm4gZH1yZXR1cm4gLTF9O1xuaWYodHlwZW9mIEtKVVI9PVwidW5kZWZpbmVkXCJ8fCFLSlVSKXtLSlVSPXt9fWlmKHR5cGVvZiBLSlVSLmNyeXB0bz09XCJ1bmRlZmluZWRcInx8IUtKVVIuY3J5cHRvKXtLSlVSLmNyeXB0bz17fX1LSlVSLmNyeXB0by5VdGlsPW5ldyBmdW5jdGlvbigpe3RoaXMuRElHRVNUSU5GT0hFQUQ9e3NoYTE6XCIzMDIxMzAwOTA2MDUyYjBlMDMwMjFhMDUwMDA0MTRcIixzaGEyMjQ6XCIzMDJkMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDQwNTAwMDQxY1wiLHNoYTI1NjpcIjMwMzEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMTA1MDAwNDIwXCIsc2hhMzg0OlwiMzA0MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAyMDUwMDA0MzBcIixzaGE1MTI6XCIzMDUxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDMwNTAwMDQ0MFwiLG1kMjpcIjMwMjAzMDBjMDYwODJhODY0ODg2ZjcwZDAyMDIwNTAwMDQxMFwiLG1kNTpcIjMwMjAzMDBjMDYwODJhODY0ODg2ZjcwZDAyMDUwNTAwMDQxMFwiLHJpcGVtZDE2MDpcIjMwMjEzMDA5MDYwNTJiMjQwMzAyMDEwNTAwMDQxNFwiLH07dGhpcy5ERUZBVUxUUFJPVklERVI9e21kNTpcImNyeXB0b2pzXCIsc2hhMTpcImNyeXB0b2pzXCIsc2hhMjI0OlwiY3J5cHRvanNcIixzaGEyNTY6XCJjcnlwdG9qc1wiLHNoYTM4NDpcImNyeXB0b2pzXCIsc2hhNTEyOlwiY3J5cHRvanNcIixyaXBlbWQxNjA6XCJjcnlwdG9qc1wiLGhtYWNtZDU6XCJjcnlwdG9qc1wiLGhtYWNzaGExOlwiY3J5cHRvanNcIixobWFjc2hhMjI0OlwiY3J5cHRvanNcIixobWFjc2hhMjU2OlwiY3J5cHRvanNcIixobWFjc2hhMzg0OlwiY3J5cHRvanNcIixobWFjc2hhNTEyOlwiY3J5cHRvanNcIixobWFjcmlwZW1kMTYwOlwiY3J5cHRvanNcIixNRDV3aXRoUlNBOlwiY3J5cHRvanMvanNyc2FcIixTSEExd2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMjI0d2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMjU2d2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMzg0d2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBNTEyd2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsUklQRU1EMTYwd2l0aFJTQTpcImNyeXB0b2pzL2pzcnNhXCIsTUQ1d2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEExd2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEEyMjR3aXRoRUNEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTI1NndpdGhFQ0RTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMzg0d2l0aEVDRFNBOlwiY3J5cHRvanMvanNyc2FcIixTSEE1MTJ3aXRoRUNEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFJJUEVNRDE2MHdpdGhFQ0RTQTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMXdpdGhEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTIyNHdpdGhEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTI1NndpdGhEU0E6XCJjcnlwdG9qcy9qc3JzYVwiLE1ENXdpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixTSEExd2l0aFJTQWFuZE1HRjE6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTIyNHdpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixTSEEyNTZ3aXRoUlNBYW5kTUdGMTpcImNyeXB0b2pzL2pzcnNhXCIsU0hBMzg0d2l0aFJTQWFuZE1HRjE6XCJjcnlwdG9qcy9qc3JzYVwiLFNIQTUxMndpdGhSU0FhbmRNR0YxOlwiY3J5cHRvanMvanNyc2FcIixSSVBFTUQxNjB3aXRoUlNBYW5kTUdGMTpcImNyeXB0b2pzL2pzcnNhXCIsfTt0aGlzLkNSWVBUT0pTTUVTU0FHRURJR0VTVE5BTUU9e21kNTpDcnlwdG9KUy5hbGdvLk1ENSxzaGExOkNyeXB0b0pTLmFsZ28uU0hBMSxzaGEyMjQ6Q3J5cHRvSlMuYWxnby5TSEEyMjQsc2hhMjU2OkNyeXB0b0pTLmFsZ28uU0hBMjU2LHNoYTM4NDpDcnlwdG9KUy5hbGdvLlNIQTM4NCxzaGE1MTI6Q3J5cHRvSlMuYWxnby5TSEE1MTIscmlwZW1kMTYwOkNyeXB0b0pTLmFsZ28uUklQRU1EMTYwfTt0aGlzLmdldERpZ2VzdEluZm9IZXg9ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgdGhpcy5ESUdFU1RJTkZPSEVBRFtiXT09XCJ1bmRlZmluZWRcIil7dGhyb3dcImFsZyBub3Qgc3VwcG9ydGVkIGluIFV0aWwuRElHRVNUSU5GT0hFQUQ6IFwiK2J9cmV0dXJuIHRoaXMuRElHRVNUSU5GT0hFQURbYl0rYX07dGhpcy5nZXRQYWRkZWREaWdlc3RJbmZvSGV4PWZ1bmN0aW9uKGgsYSxqKXt2YXIgYz10aGlzLmdldERpZ2VzdEluZm9IZXgoaCxhKTt2YXIgZD1qLzQ7aWYoYy5sZW5ndGgrMjI+ZCl7dGhyb3dcImtleSBpcyB0b28gc2hvcnQgZm9yIFNpZ0FsZzoga2V5bGVuPVwiK2orXCIsXCIrYX12YXIgYj1cIjAwMDFcIjt2YXIgaz1cIjAwXCIrYzt2YXIgZz1cIlwiO3ZhciBsPWQtYi5sZW5ndGgtay5sZW5ndGg7Zm9yKHZhciBmPTA7ZjxsO2YrPTIpe2crPVwiZmZcIn12YXIgZT1iK2craztyZXR1cm4gZX07dGhpcy5oYXNoU3RyaW5nPWZ1bmN0aW9uKGEsYyl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpjfSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTt0aGlzLmhhc2hIZXg9ZnVuY3Rpb24oYixjKXt2YXIgYT1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOmN9KTtyZXR1cm4gYS5kaWdlc3RIZXgoYil9O3RoaXMuc2hhMT1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwic2hhMVwiLHByb3Y6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTt0aGlzLnNoYTI1Nj1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwic2hhMjU2XCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RTdHJpbmcoYSl9O3RoaXMuc2hhMjU2SGV4PWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0KHthbGc6XCJzaGEyNTZcIixwcm92OlwiY3J5cHRvanNcIn0pO3JldHVybiBiLmRpZ2VzdEhleChhKX07dGhpcy5zaGE1MTI9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzpcInNoYTUxMlwiLHByb3Y6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGIuZGlnZXN0U3RyaW5nKGEpfTt0aGlzLnNoYTUxMkhleD1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwic2hhNTEyXCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RIZXgoYSl9fTtLSlVSLmNyeXB0by5VdGlsLm1kNT1mdW5jdGlvbihhKXt2YXIgYj1uZXcgS0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdCh7YWxnOlwibWQ1XCIscHJvdjpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gYi5kaWdlc3RTdHJpbmcoYSl9O0tKVVIuY3J5cHRvLlV0aWwucmlwZW1kMTYwPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0KHthbGc6XCJyaXBlbWQxNjBcIixwcm92OlwiY3J5cHRvanNcIn0pO3JldHVybiBiLmRpZ2VzdFN0cmluZyhhKX07S0pVUi5jcnlwdG8uVXRpbC5TRUNVUkVSQU5ET01HRU49bmV3IFNlY3VyZVJhbmRvbSgpO0tKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tSGV4T2ZOYnl0ZXM9ZnVuY3Rpb24oYil7dmFyIGE9bmV3IEFycmF5KGIpO0tKVVIuY3J5cHRvLlV0aWwuU0VDVVJFUkFORE9NR0VOLm5leHRCeXRlcyhhKTtyZXR1cm4gQkF0b2hleChhKX07S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYnl0ZXM9ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKEtKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tSGV4T2ZOYnl0ZXMoYSksMTYpfTtLSlVSLmNyeXB0by5VdGlsLmdldFJhbmRvbUhleE9mTmJpdHM9ZnVuY3Rpb24oZCl7dmFyIGM9ZCU4O3ZhciBhPShkLWMpLzg7dmFyIGI9bmV3IEFycmF5KGErMSk7S0pVUi5jcnlwdG8uVXRpbC5TRUNVUkVSQU5ET01HRU4ubmV4dEJ5dGVzKGIpO2JbMF09KCgoMjU1PDxjKSYyNTUpXjI1NSkmYlswXTtyZXR1cm4gQkF0b2hleChiKX07S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYml0cz1mdW5jdGlvbihhKXtyZXR1cm4gbmV3IEJpZ0ludGVnZXIoS0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21IZXhPZk5iaXRzKGEpLDE2KX07S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyWmVyb1RvTWF4PWZ1bmN0aW9uKGIpe3ZhciBhPWIuYml0TGVuZ3RoKCk7d2hpbGUoMSl7dmFyIGM9S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyT2ZOYml0cyhhKTtpZihiLmNvbXBhcmVUbyhjKSE9LTEpe3JldHVybiBjfX19O0tKVVIuY3J5cHRvLlV0aWwuZ2V0UmFuZG9tQmlnSW50ZWdlck1pblRvTWF4PWZ1bmN0aW9uKGUsYil7dmFyIGM9ZS5jb21wYXJlVG8oYik7aWYoYz09MSl7dGhyb3dcImJpTWluIGlzIGdyZWF0ZXIgdGhhbiBiaU1heFwifWlmKGM9PTApe3JldHVybiBlfXZhciBhPWIuc3VidHJhY3QoZSk7dmFyIGQ9S0pVUi5jcnlwdG8uVXRpbC5nZXRSYW5kb21CaWdJbnRlZ2VyWmVyb1RvTWF4KGEpO3JldHVybiBkLmFkZChlKX07S0pVUi5jcnlwdG8uTWVzc2FnZURpZ2VzdD1mdW5jdGlvbihjKXt2YXIgYj1udWxsO3ZhciBhPW51bGw7dmFyIGQ9bnVsbDt0aGlzLnNldEFsZ0FuZFByb3ZpZGVyPWZ1bmN0aW9uKGcsZil7Zz1LSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0LmdldENhbm9uaWNhbEFsZ05hbWUoZyk7aWYoZyE9PW51bGwmJmY9PT11bmRlZmluZWQpe2Y9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJbZ119aWYoXCI6bWQ1OnNoYTE6c2hhMjI0OnNoYTI1NjpzaGEzODQ6c2hhNTEyOnJpcGVtZDE2MDpcIi5pbmRleE9mKGcpIT0tMSYmZj09XCJjcnlwdG9qc1wiKXt0cnl7dGhpcy5tZD1LSlVSLmNyeXB0by5VdGlsLkNSWVBUT0pTTUVTU0FHRURJR0VTVE5BTUVbZ10uY3JlYXRlKCl9Y2F0Y2goZSl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGFsZz1cIitnK1wiL1wiK2V9dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24oaCl7dGhpcy5tZC51cGRhdGUoaCl9O3RoaXMudXBkYXRlSGV4PWZ1bmN0aW9uKGgpe3ZhciBpPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoaCk7dGhpcy5tZC51cGRhdGUoaSl9O3RoaXMuZGlnZXN0PWZ1bmN0aW9uKCl7dmFyIGg9dGhpcy5tZC5maW5hbGl6ZSgpO3JldHVybiBoLnRvU3RyaW5nKENyeXB0b0pTLmVuYy5IZXgpfTt0aGlzLmRpZ2VzdFN0cmluZz1mdW5jdGlvbihoKXt0aGlzLnVwZGF0ZVN0cmluZyhoKTtyZXR1cm4gdGhpcy5kaWdlc3QoKX07dGhpcy5kaWdlc3RIZXg9ZnVuY3Rpb24oaCl7dGhpcy51cGRhdGVIZXgoaCk7cmV0dXJuIHRoaXMuZGlnZXN0KCl9fWlmKFwiOnNoYTI1NjpcIi5pbmRleE9mKGcpIT0tMSYmZj09XCJzamNsXCIpe3RyeXt0aGlzLm1kPW5ldyBzamNsLmhhc2guc2hhMjU2KCl9Y2F0Y2goZSl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGFsZz1cIitnK1wiL1wiK2V9dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24oaCl7dGhpcy5tZC51cGRhdGUoaCl9O3RoaXMudXBkYXRlSGV4PWZ1bmN0aW9uKGkpe3ZhciBoPXNqY2wuY29kZWMuaGV4LnRvQml0cyhpKTt0aGlzLm1kLnVwZGF0ZShoKX07dGhpcy5kaWdlc3Q9ZnVuY3Rpb24oKXt2YXIgaD10aGlzLm1kLmZpbmFsaXplKCk7cmV0dXJuIHNqY2wuY29kZWMuaGV4LmZyb21CaXRzKGgpfTt0aGlzLmRpZ2VzdFN0cmluZz1mdW5jdGlvbihoKXt0aGlzLnVwZGF0ZVN0cmluZyhoKTtyZXR1cm4gdGhpcy5kaWdlc3QoKX07dGhpcy5kaWdlc3RIZXg9ZnVuY3Rpb24oaCl7dGhpcy51cGRhdGVIZXgoaCk7cmV0dXJuIHRoaXMuZGlnZXN0KCl9fX07dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24oZSl7dGhyb3dcInVwZGF0ZVN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnTmFtZStcIi9cIit0aGlzLnByb3ZOYW1lfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihlKXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdOYW1lK1wiL1wiK3RoaXMucHJvdk5hbWV9O3RoaXMuZGlnZXN0PWZ1bmN0aW9uKCl7dGhyb3dcImRpZ2VzdCgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnTmFtZStcIi9cIit0aGlzLnByb3ZOYW1lfTt0aGlzLmRpZ2VzdFN0cmluZz1mdW5jdGlvbihlKXt0aHJvd1wiZGlnZXN0U3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdOYW1lK1wiL1wiK3RoaXMucHJvdk5hbWV9O3RoaXMuZGlnZXN0SGV4PWZ1bmN0aW9uKGUpe3Rocm93XCJkaWdlc3RIZXgoaGV4KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmFsZ05hbWUrXCIvXCIrdGhpcy5wcm92TmFtZX07aWYoYyE9PXVuZGVmaW5lZCl7aWYoYy5hbGchPT11bmRlZmluZWQpe3RoaXMuYWxnTmFtZT1jLmFsZztpZihjLnByb3Y9PT11bmRlZmluZWQpe3RoaXMucHJvdk5hbWU9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJbdGhpcy5hbGdOYW1lXX10aGlzLnNldEFsZ0FuZFByb3ZpZGVyKHRoaXMuYWxnTmFtZSx0aGlzLnByb3ZOYW1lKX19fTtLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0LmdldENhbm9uaWNhbEFsZ05hbWU9ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PT1cInN0cmluZ1wiKXthPWEudG9Mb3dlckNhc2UoKTthPWEucmVwbGFjZSgvLS8sXCJcIil9cmV0dXJuIGF9O0tKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3QuZ2V0SGFzaExlbmd0aD1mdW5jdGlvbihjKXt2YXIgYj1LSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0O3ZhciBhPWIuZ2V0Q2Fub25pY2FsQWxnTmFtZShjKTtpZihiLkhBU0hMRU5HVEhbYV09PT11bmRlZmluZWQpe3Rocm93XCJub3Qgc3VwcG9ydGVkIGFsZ29yaXRobTogXCIrY31yZXR1cm4gYi5IQVNITEVOR1RIW2FdfTtLSlVSLmNyeXB0by5NZXNzYWdlRGlnZXN0LkhBU0hMRU5HVEg9e21kNToxNixzaGExOjIwLHNoYTIyNDoyOCxzaGEyNTY6MzIsc2hhMzg0OjQ4LHNoYTUxMjo2NCxyaXBlbWQxNjA6MjB9O0tKVVIuY3J5cHRvLk1hYz1mdW5jdGlvbihkKXt2YXIgZj1udWxsO3ZhciBjPW51bGw7dmFyIGE9bnVsbDt2YXIgZT1udWxsO3ZhciBiPW51bGw7dGhpcy5zZXRBbGdBbmRQcm92aWRlcj1mdW5jdGlvbihrLGkpe2s9ay50b0xvd2VyQ2FzZSgpO2lmKGs9PW51bGwpe2s9XCJobWFjc2hhMVwifWs9ay50b0xvd2VyQ2FzZSgpO2lmKGsuc3Vic3RyKDAsNCkhPVwiaG1hY1wiKXt0aHJvd1wic2V0QWxnQW5kUHJvdmlkZXIgdW5zdXBwb3J0ZWQgSE1BQyBhbGc6IFwiK2t9aWYoaT09PXVuZGVmaW5lZCl7aT1LSlVSLmNyeXB0by5VdGlsLkRFRkFVTFRQUk9WSURFUltrXX10aGlzLmFsZ1Byb3Y9aytcIi9cIitpO3ZhciBnPWsuc3Vic3RyKDQpO2lmKFwiOm1kNTpzaGExOnNoYTIyNDpzaGEyNTY6c2hhMzg0OnNoYTUxMjpyaXBlbWQxNjA6XCIuaW5kZXhPZihnKSE9LTEmJmk9PVwiY3J5cHRvanNcIil7dHJ5e3ZhciBqPUtKVVIuY3J5cHRvLlV0aWwuQ1JZUFRPSlNNRVNTQUdFRElHRVNUTkFNRVtnXTt0aGlzLm1hYz1DcnlwdG9KUy5hbGdvLkhNQUMuY3JlYXRlKGosdGhpcy5wYXNzKX1jYXRjaChoKXt0aHJvd1wic2V0QWxnQW5kUHJvdmlkZXIgaGFzaCBhbGcgc2V0IGZhaWwgaGFzaEFsZz1cIitnK1wiL1wiK2h9dGhpcy51cGRhdGVTdHJpbmc9ZnVuY3Rpb24obCl7dGhpcy5tYWMudXBkYXRlKGwpfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihsKXt2YXIgbT1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGwpO3RoaXMubWFjLnVwZGF0ZShtKX07dGhpcy5kb0ZpbmFsPWZ1bmN0aW9uKCl7dmFyIGw9dGhpcy5tYWMuZmluYWxpemUoKTtyZXR1cm4gbC50b1N0cmluZyhDcnlwdG9KUy5lbmMuSGV4KX07dGhpcy5kb0ZpbmFsU3RyaW5nPWZ1bmN0aW9uKGwpe3RoaXMudXBkYXRlU3RyaW5nKGwpO3JldHVybiB0aGlzLmRvRmluYWwoKX07dGhpcy5kb0ZpbmFsSGV4PWZ1bmN0aW9uKGwpe3RoaXMudXBkYXRlSGV4KGwpO3JldHVybiB0aGlzLmRvRmluYWwoKX19fTt0aGlzLnVwZGF0ZVN0cmluZz1mdW5jdGlvbihnKXt0aHJvd1widXBkYXRlU3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdQcm92fTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihnKXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdQcm92fTt0aGlzLmRvRmluYWw9ZnVuY3Rpb24oKXt0aHJvd1wiZGlnZXN0KCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5hbGdQcm92fTt0aGlzLmRvRmluYWxTdHJpbmc9ZnVuY3Rpb24oZyl7dGhyb3dcImRpZ2VzdFN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuYWxnUHJvdn07dGhpcy5kb0ZpbmFsSGV4PWZ1bmN0aW9uKGcpe3Rocm93XCJkaWdlc3RIZXgoaGV4KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmFsZ1Byb3Z9O3RoaXMuc2V0UGFzc3dvcmQ9ZnVuY3Rpb24oaCl7aWYodHlwZW9mIGg9PVwic3RyaW5nXCIpe3ZhciBnPWg7aWYoaC5sZW5ndGglMj09MXx8IWgubWF0Y2goL15bMC05QS1GYS1mXSskLykpe2c9cnN0cnRvaGV4KGgpfXRoaXMucGFzcz1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGcpO3JldHVybn1pZih0eXBlb2YgaCE9XCJvYmplY3RcIil7dGhyb3dcIktKVVIuY3J5cHRvLk1hYyB1bnN1cHBvcnRlZCBwYXNzd29yZCB0eXBlOiBcIitofXZhciBnPW51bGw7aWYoaC5oZXghPT11bmRlZmluZWQpe2lmKGguaGV4Lmxlbmd0aCUyIT0wfHwhaC5oZXgubWF0Y2goL15bMC05QS1GYS1mXSskLykpe3Rocm93XCJNYWM6IHdyb25nIGhleCBwYXNzd29yZDogXCIraC5oZXh9Zz1oLmhleH1pZihoLnV0ZjghPT11bmRlZmluZWQpe2c9dXRmOHRvaGV4KGgudXRmOCl9aWYoaC5yc3RyIT09dW5kZWZpbmVkKXtnPXJzdHJ0b2hleChoLnJzdHIpfWlmKGguYjY0IT09dW5kZWZpbmVkKXtnPWI2NHRvaGV4KGguYjY0KX1pZihoLmI2NHUhPT11bmRlZmluZWQpe2c9YjY0dXRvaGV4KGguYjY0dSl9aWYoZz09bnVsbCl7dGhyb3dcIktKVVIuY3J5cHRvLk1hYyB1bnN1cHBvcnRlZCBwYXNzd29yZCB0eXBlOiBcIitofXRoaXMucGFzcz1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKGcpfTtpZihkIT09dW5kZWZpbmVkKXtpZihkLnBhc3MhPT11bmRlZmluZWQpe3RoaXMuc2V0UGFzc3dvcmQoZC5wYXNzKX1pZihkLmFsZyE9PXVuZGVmaW5lZCl7dGhpcy5hbGdOYW1lPWQuYWxnO2lmKGQucHJvdj09PXVuZGVmaW5lZCl7dGhpcy5wcm92TmFtZT1LSlVSLmNyeXB0by5VdGlsLkRFRkFVTFRQUk9WSURFUlt0aGlzLmFsZ05hbWVdfXRoaXMuc2V0QWxnQW5kUHJvdmlkZXIodGhpcy5hbGdOYW1lLHRoaXMucHJvdk5hbWUpfX19O0tKVVIuY3J5cHRvLlNpZ25hdHVyZT1mdW5jdGlvbihvKXt2YXIgcT1udWxsO3ZhciBuPW51bGw7dmFyIHI9bnVsbDt2YXIgYz1udWxsO3ZhciBsPW51bGw7dmFyIGQ9bnVsbDt2YXIgaz1udWxsO3ZhciBoPW51bGw7dmFyIHA9bnVsbDt2YXIgZT1udWxsO3ZhciBiPS0xO3ZhciBnPW51bGw7dmFyIGo9bnVsbDt2YXIgYT1udWxsO3ZhciBpPW51bGw7dmFyIGY9bnVsbDt0aGlzLl9zZXRBbGdOYW1lcz1mdW5jdGlvbigpe3ZhciBzPXRoaXMuYWxnTmFtZS5tYXRjaCgvXiguKyl3aXRoKC4rKSQvKTtpZihzKXt0aGlzLm1kQWxnTmFtZT1zWzFdLnRvTG93ZXJDYXNlKCk7dGhpcy5wdWJrZXlBbGdOYW1lPXNbMl0udG9Mb3dlckNhc2UoKX19O3RoaXMuX3plcm9QYWRkaW5nT2ZTaWduYXR1cmU9ZnVuY3Rpb24oeCx3KXt2YXIgdj1cIlwiO3ZhciB0PXcvNC14Lmxlbmd0aDtmb3IodmFyIHU9MDt1PHQ7dSsrKXt2PXYrXCIwXCJ9cmV0dXJuIHYreH07dGhpcy5zZXRBbGdBbmRQcm92aWRlcj1mdW5jdGlvbih1LHQpe3RoaXMuX3NldEFsZ05hbWVzKCk7aWYodCE9XCJjcnlwdG9qcy9qc3JzYVwiKXt0aHJvd1wicHJvdmlkZXIgbm90IHN1cHBvcnRlZDogXCIrdH1pZihcIjptZDU6c2hhMTpzaGEyMjQ6c2hhMjU2OnNoYTM4NDpzaGE1MTI6cmlwZW1kMTYwOlwiLmluZGV4T2YodGhpcy5tZEFsZ05hbWUpIT0tMSl7dHJ5e3RoaXMubWQ9bmV3IEtKVVIuY3J5cHRvLk1lc3NhZ2VEaWdlc3Qoe2FsZzp0aGlzLm1kQWxnTmFtZX0pfWNhdGNoKHMpe3Rocm93XCJzZXRBbGdBbmRQcm92aWRlciBoYXNoIGFsZyBzZXQgZmFpbCBhbGc9XCIrdGhpcy5tZEFsZ05hbWUrXCIvXCIrc310aGlzLmluaXQ9ZnVuY3Rpb24odyx4KXt2YXIgeT1udWxsO3RyeXtpZih4PT09dW5kZWZpbmVkKXt5PUtFWVVUSUwuZ2V0S2V5KHcpfWVsc2V7eT1LRVlVVElMLmdldEtleSh3LHgpfX1jYXRjaCh2KXt0aHJvd1wiaW5pdCBmYWlsZWQ6XCIrdn1pZih5LmlzUHJpdmF0ZT09PXRydWUpe3RoaXMucHJ2S2V5PXk7dGhpcy5zdGF0ZT1cIlNJR05cIn1lbHNle2lmKHkuaXNQdWJsaWM9PT10cnVlKXt0aGlzLnB1YktleT15O3RoaXMuc3RhdGU9XCJWRVJJRllcIn1lbHNle3Rocm93XCJpbml0IGZhaWxlZC46XCIreX19fTt0aGlzLnVwZGF0ZVN0cmluZz1mdW5jdGlvbih2KXt0aGlzLm1kLnVwZGF0ZVN0cmluZyh2KX07dGhpcy51cGRhdGVIZXg9ZnVuY3Rpb24odil7dGhpcy5tZC51cGRhdGVIZXgodil9O3RoaXMuc2lnbj1mdW5jdGlvbigpe3RoaXMuc0hhc2hIZXg9dGhpcy5tZC5kaWdlc3QoKTtpZih0eXBlb2YgdGhpcy5lY3BydmhleCE9XCJ1bmRlZmluZWRcIiYmdHlwZW9mIHRoaXMuZWNjdXJ2ZW5hbWUhPVwidW5kZWZpbmVkXCIpe3ZhciB2PW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6dGhpcy5lY2N1cnZlbmFtZX0pO3RoaXMuaFNpZ249di5zaWduSGV4KHRoaXMuc0hhc2hIZXgsdGhpcy5lY3BydmhleCl9ZWxzZXtpZih0aGlzLnBydktleSBpbnN0YW5jZW9mIFJTQUtleSYmdGhpcy5wdWJrZXlBbGdOYW1lPT09XCJyc2FhbmRtZ2YxXCIpe3RoaXMuaFNpZ249dGhpcy5wcnZLZXkuc2lnbldpdGhNZXNzYWdlSGFzaFBTUyh0aGlzLnNIYXNoSGV4LHRoaXMubWRBbGdOYW1lLHRoaXMucHNzU2FsdExlbil9ZWxzZXtpZih0aGlzLnBydktleSBpbnN0YW5jZW9mIFJTQUtleSYmdGhpcy5wdWJrZXlBbGdOYW1lPT09XCJyc2FcIil7dGhpcy5oU2lnbj10aGlzLnBydktleS5zaWduV2l0aE1lc3NhZ2VIYXNoKHRoaXMuc0hhc2hIZXgsdGhpcy5tZEFsZ05hbWUpfWVsc2V7aWYodGhpcy5wcnZLZXkgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5FQ0RTQSl7dGhpcy5oU2lnbj10aGlzLnBydktleS5zaWduV2l0aE1lc3NhZ2VIYXNoKHRoaXMuc0hhc2hIZXgpfWVsc2V7aWYodGhpcy5wcnZLZXkgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5EU0Epe3RoaXMuaFNpZ249dGhpcy5wcnZLZXkuc2lnbldpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4KX1lbHNle3Rocm93XCJTaWduYXR1cmU6IHVuc3VwcG9ydGVkIHByaXZhdGUga2V5IGFsZzogXCIrdGhpcy5wdWJrZXlBbGdOYW1lfX19fX1yZXR1cm4gdGhpcy5oU2lnbn07dGhpcy5zaWduU3RyaW5nPWZ1bmN0aW9uKHYpe3RoaXMudXBkYXRlU3RyaW5nKHYpO3JldHVybiB0aGlzLnNpZ24oKX07dGhpcy5zaWduSGV4PWZ1bmN0aW9uKHYpe3RoaXMudXBkYXRlSGV4KHYpO3JldHVybiB0aGlzLnNpZ24oKX07dGhpcy52ZXJpZnk9ZnVuY3Rpb24odil7dGhpcy5zSGFzaEhleD10aGlzLm1kLmRpZ2VzdCgpO2lmKHR5cGVvZiB0aGlzLmVjcHViaGV4IT1cInVuZGVmaW5lZFwiJiZ0eXBlb2YgdGhpcy5lY2N1cnZlbmFtZSE9XCJ1bmRlZmluZWRcIil7dmFyIHc9bmV3IEtKVVIuY3J5cHRvLkVDRFNBKHtjdXJ2ZTp0aGlzLmVjY3VydmVuYW1lfSk7cmV0dXJuIHcudmVyaWZ5SGV4KHRoaXMuc0hhc2hIZXgsdix0aGlzLmVjcHViaGV4KX1lbHNle2lmKHRoaXMucHViS2V5IGluc3RhbmNlb2YgUlNBS2V5JiZ0aGlzLnB1YmtleUFsZ05hbWU9PT1cInJzYWFuZG1nZjFcIil7cmV0dXJuIHRoaXMucHViS2V5LnZlcmlmeVdpdGhNZXNzYWdlSGFzaFBTUyh0aGlzLnNIYXNoSGV4LHYsdGhpcy5tZEFsZ05hbWUsdGhpcy5wc3NTYWx0TGVuKX1lbHNle2lmKHRoaXMucHViS2V5IGluc3RhbmNlb2YgUlNBS2V5JiZ0aGlzLnB1YmtleUFsZ05hbWU9PT1cInJzYVwiKXtyZXR1cm4gdGhpcy5wdWJLZXkudmVyaWZ5V2l0aE1lc3NhZ2VIYXNoKHRoaXMuc0hhc2hIZXgsdil9ZWxzZXtpZihLSlVSLmNyeXB0by5FQ0RTQSE9PXVuZGVmaW5lZCYmdGhpcy5wdWJLZXkgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5FQ0RTQSl7cmV0dXJuIHRoaXMucHViS2V5LnZlcmlmeVdpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4LHYpfWVsc2V7aWYoS0pVUi5jcnlwdG8uRFNBIT09dW5kZWZpbmVkJiZ0aGlzLnB1YktleSBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkRTQSl7cmV0dXJuIHRoaXMucHViS2V5LnZlcmlmeVdpdGhNZXNzYWdlSGFzaCh0aGlzLnNIYXNoSGV4LHYpfWVsc2V7dGhyb3dcIlNpZ25hdHVyZTogdW5zdXBwb3J0ZWQgcHVibGljIGtleSBhbGc6IFwiK3RoaXMucHVia2V5QWxnTmFtZX19fX19fX19O3RoaXMuaW5pdD1mdW5jdGlvbihzLHQpe3Rocm93XCJpbml0KGtleSwgcGFzcykgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnVwZGF0ZVN0cmluZz1mdW5jdGlvbihzKXt0aHJvd1widXBkYXRlU3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnVwZGF0ZUhleD1mdW5jdGlvbihzKXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnNpZ249ZnVuY3Rpb24oKXt0aHJvd1wic2lnbigpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy5zaWduU3RyaW5nPWZ1bmN0aW9uKHMpe3Rocm93XCJkaWdlc3RTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMuYWxnUHJvdk5hbWV9O3RoaXMuc2lnbkhleD1mdW5jdGlvbihzKXt0aHJvd1wiZGlnZXN0SGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLmFsZ1Byb3ZOYW1lfTt0aGlzLnZlcmlmeT1mdW5jdGlvbihzKXt0aHJvd1widmVyaWZ5KGhTaWdWYWwpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy5hbGdQcm92TmFtZX07dGhpcy5pbml0UGFyYW1zPW87aWYobyE9PXVuZGVmaW5lZCl7aWYoby5hbGchPT11bmRlZmluZWQpe3RoaXMuYWxnTmFtZT1vLmFsZztpZihvLnByb3Y9PT11bmRlZmluZWQpe3RoaXMucHJvdk5hbWU9S0pVUi5jcnlwdG8uVXRpbC5ERUZBVUxUUFJPVklERVJbdGhpcy5hbGdOYW1lXX1lbHNle3RoaXMucHJvdk5hbWU9by5wcm92fXRoaXMuYWxnUHJvdk5hbWU9dGhpcy5hbGdOYW1lK1wiOlwiK3RoaXMucHJvdk5hbWU7dGhpcy5zZXRBbGdBbmRQcm92aWRlcih0aGlzLmFsZ05hbWUsdGhpcy5wcm92TmFtZSk7dGhpcy5fc2V0QWxnTmFtZXMoKX1pZihvLnBzc3NhbHRsZW4hPT11bmRlZmluZWQpe3RoaXMucHNzU2FsdExlbj1vLnBzc3NhbHRsZW59aWYoby5wcnZrZXlwZW0hPT11bmRlZmluZWQpe2lmKG8ucHJ2a2V5cGFzIT09dW5kZWZpbmVkKXt0aHJvd1wiYm90aCBwcnZrZXlwZW0gYW5kIHBydmtleXBhcyBwYXJhbWV0ZXJzIG5vdCBzdXBwb3J0ZWRcIn1lbHNle3RyeXt2YXIgcT1LRVlVVElMLmdldEtleShvLnBydmtleXBlbSk7dGhpcy5pbml0KHEpfWNhdGNoKG0pe3Rocm93XCJmYXRhbCBlcnJvciB0byBsb2FkIHBlbSBwcml2YXRlIGtleTogXCIrbX19fX19O0tKVVIuY3J5cHRvLkNpcGhlcj1mdW5jdGlvbihhKXt9O0tKVVIuY3J5cHRvLkNpcGhlci5lbmNyeXB0PWZ1bmN0aW9uKGUsZixkKXtpZihmIGluc3RhbmNlb2YgUlNBS2V5JiZmLmlzUHVibGljKXt2YXIgYz1LSlVSLmNyeXB0by5DaXBoZXIuZ2V0QWxnQnlLZXlBbmROYW1lKGYsZCk7aWYoYz09PVwiUlNBXCIpe3JldHVybiBmLmVuY3J5cHQoZSl9aWYoYz09PVwiUlNBT0FFUFwiKXtyZXR1cm4gZi5lbmNyeXB0T0FFUChlLFwic2hhMVwiKX12YXIgYj1jLm1hdGNoKC9eUlNBT0FFUChcXGQrKSQvKTtpZihiIT09bnVsbCl7cmV0dXJuIGYuZW5jcnlwdE9BRVAoZSxcInNoYVwiK2JbMV0pfXRocm93XCJDaXBoZXIuZW5jcnlwdDogdW5zdXBwb3J0ZWQgYWxnb3JpdGhtIGZvciBSU0FLZXk6IFwiK2R9ZWxzZXt0aHJvd1wiQ2lwaGVyLmVuY3J5cHQ6IHVuc3VwcG9ydGVkIGtleSBvciBhbGdvcml0aG1cIn19O0tKVVIuY3J5cHRvLkNpcGhlci5kZWNyeXB0PWZ1bmN0aW9uKGUsZixkKXtpZihmIGluc3RhbmNlb2YgUlNBS2V5JiZmLmlzUHJpdmF0ZSl7dmFyIGM9S0pVUi5jcnlwdG8uQ2lwaGVyLmdldEFsZ0J5S2V5QW5kTmFtZShmLGQpO2lmKGM9PT1cIlJTQVwiKXtyZXR1cm4gZi5kZWNyeXB0KGUpfWlmKGM9PT1cIlJTQU9BRVBcIil7cmV0dXJuIGYuZGVjcnlwdE9BRVAoZSxcInNoYTFcIil9dmFyIGI9Yy5tYXRjaCgvXlJTQU9BRVAoXFxkKykkLyk7aWYoYiE9PW51bGwpe3JldHVybiBmLmRlY3J5cHRPQUVQKGUsXCJzaGFcIitiWzFdKX10aHJvd1wiQ2lwaGVyLmRlY3J5cHQ6IHVuc3VwcG9ydGVkIGFsZ29yaXRobSBmb3IgUlNBS2V5OiBcIitkfWVsc2V7dGhyb3dcIkNpcGhlci5kZWNyeXB0OiB1bnN1cHBvcnRlZCBrZXkgb3IgYWxnb3JpdGhtXCJ9fTtLSlVSLmNyeXB0by5DaXBoZXIuZ2V0QWxnQnlLZXlBbmROYW1lPWZ1bmN0aW9uKGIsYSl7aWYoYiBpbnN0YW5jZW9mIFJTQUtleSl7aWYoXCI6UlNBOlJTQU9BRVA6UlNBT0FFUDIyNDpSU0FPQUVQMjU2OlJTQU9BRVAzODQ6UlNBT0FFUDUxMjpcIi5pbmRleE9mKGEpIT0tMSl7cmV0dXJuIGF9aWYoYT09PW51bGx8fGE9PT11bmRlZmluZWQpe3JldHVyblwiUlNBXCJ9dGhyb3dcImdldEFsZ0J5S2V5QW5kTmFtZTogbm90IHN1cHBvcnRlZCBhbGdvcml0aG0gbmFtZSBmb3IgUlNBS2V5OiBcIithfXRocm93XCJnZXRBbGdCeUtleUFuZE5hbWU6IG5vdCBzdXBwb3J0ZWQgYWxnb3JpdGhtIG5hbWU6IFwiK2F9O0tKVVIuY3J5cHRvLk9JRD1uZXcgZnVuY3Rpb24oKXt0aGlzLm9pZGhleDJuYW1lPXtcIjJhODY0ODg2ZjcwZDAxMDEwMVwiOlwicnNhRW5jcnlwdGlvblwiLFwiMmE4NjQ4Y2UzZDAyMDFcIjpcImVjUHVibGljS2V5XCIsXCIyYTg2NDhjZTM4MDQwMVwiOlwiZHNhXCIsXCIyYTg2NDhjZTNkMDMwMTA3XCI6XCJzZWNwMjU2cjFcIixcIjJiODEwNDAwMWZcIjpcInNlY3AxOTJrMVwiLFwiMmI4MTA0MDAyMVwiOlwic2VjcDIyNHIxXCIsXCIyYjgxMDQwMDBhXCI6XCJzZWNwMjU2azFcIixcIjJiODEwNDAwMjNcIjpcInNlY3A1MjFyMVwiLFwiMmI4MTA0MDAyMlwiOlwic2VjcDM4NHIxXCIsXCIyYTg2NDhjZTM4MDQwM1wiOlwiU0hBMXdpdGhEU0FcIixcIjYwODY0ODAxNjUwMzA0MDMwMVwiOlwiU0hBMjI0d2l0aERTQVwiLFwiNjA4NjQ4MDE2NTAzMDQwMzAyXCI6XCJTSEEyNTZ3aXRoRFNBXCIsfX07XG5pZih0eXBlb2YgS0pVUj09XCJ1bmRlZmluZWRcInx8IUtKVVIpe0tKVVI9e319aWYodHlwZW9mIEtKVVIuY3J5cHRvPT1cInVuZGVmaW5lZFwifHwhS0pVUi5jcnlwdG8pe0tKVVIuY3J5cHRvPXt9fUtKVVIuY3J5cHRvLkVDRFNBPWZ1bmN0aW9uKGgpe3ZhciBlPVwic2VjcDI1NnIxXCI7dmFyIGc9bnVsbDt2YXIgYj1udWxsO3ZhciBmPW51bGw7dmFyIGE9bmV3IFNlY3VyZVJhbmRvbSgpO3ZhciBkPW51bGw7dGhpcy50eXBlPVwiRUNcIjt0aGlzLmlzUHJpdmF0ZT1mYWxzZTt0aGlzLmlzUHVibGljPWZhbHNlO2Z1bmN0aW9uIGMocyxvLHIsbil7dmFyIGo9TWF0aC5tYXgoby5iaXRMZW5ndGgoKSxuLmJpdExlbmd0aCgpKTt2YXIgdD1zLmFkZDJEKHIpO3ZhciBxPXMuY3VydmUuZ2V0SW5maW5pdHkoKTtmb3IodmFyIHA9ai0xO3A+PTA7LS1wKXtxPXEudHdpY2UyRCgpO3Euej1CaWdJbnRlZ2VyLk9ORTtpZihvLnRlc3RCaXQocCkpe2lmKG4udGVzdEJpdChwKSl7cT1xLmFkZDJEKHQpfWVsc2V7cT1xLmFkZDJEKHMpfX1lbHNle2lmKG4udGVzdEJpdChwKSl7cT1xLmFkZDJEKHIpfX19cmV0dXJuIHF9dGhpcy5nZXRCaWdSYW5kb209ZnVuY3Rpb24oaSl7cmV0dXJuIG5ldyBCaWdJbnRlZ2VyKGkuYml0TGVuZ3RoKCksYSkubW9kKGkuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKS5hZGQoQmlnSW50ZWdlci5PTkUpfTt0aGlzLnNldE5hbWVkQ3VydmU9ZnVuY3Rpb24oaSl7dGhpcy5lY3BhcmFtcz1LSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLmdldEJ5TmFtZShpKTt0aGlzLnBydktleUhleD1udWxsO3RoaXMucHViS2V5SGV4PW51bGw7dGhpcy5jdXJ2ZU5hbWU9aX07dGhpcy5zZXRQcml2YXRlS2V5SGV4PWZ1bmN0aW9uKGkpe3RoaXMuaXNQcml2YXRlPXRydWU7dGhpcy5wcnZLZXlIZXg9aX07dGhpcy5zZXRQdWJsaWNLZXlIZXg9ZnVuY3Rpb24oaSl7dGhpcy5pc1B1YmxpYz10cnVlO3RoaXMucHViS2V5SGV4PWl9O3RoaXMuZ2V0UHVibGljS2V5WFlIZXg9ZnVuY3Rpb24oKXt2YXIgaz10aGlzLnB1YktleUhleDtpZihrLnN1YnN0cigwLDIpIT09XCIwNFwiKXt0aHJvd1widGhpcyBtZXRob2Qgc3VwcG9ydHMgdW5jb21wcmVzc2VkIGZvcm1hdCgwNCkgb25seVwifXZhciBqPXRoaXMuZWNwYXJhbXMua2V5bGVuLzQ7aWYoay5sZW5ndGghPT0yK2oqMil7dGhyb3dcIm1hbGZvcm1lZCBwdWJsaWMga2V5IGhleCBsZW5ndGhcIn12YXIgaT17fTtpLng9ay5zdWJzdHIoMixqKTtpLnk9ay5zdWJzdHIoMitqKTtyZXR1cm4gaX07dGhpcy5nZXRTaG9ydE5JU1RQQ3VydmVOYW1lPWZ1bmN0aW9uKCl7dmFyIGk9dGhpcy5jdXJ2ZU5hbWU7aWYoaT09PVwic2VjcDI1NnIxXCJ8fGk9PT1cIk5JU1QgUC0yNTZcInx8aT09PVwiUC0yNTZcInx8aT09PVwicHJpbWUyNTZ2MVwiKXtyZXR1cm5cIlAtMjU2XCJ9aWYoaT09PVwic2VjcDM4NHIxXCJ8fGk9PT1cIk5JU1QgUC0zODRcInx8aT09PVwiUC0zODRcIil7cmV0dXJuXCJQLTM4NFwifXJldHVybiBudWxsfTt0aGlzLmdlbmVyYXRlS2V5UGFpckhleD1mdW5jdGlvbigpe3ZhciBrPXRoaXMuZWNwYXJhbXMubjt2YXIgbj10aGlzLmdldEJpZ1JhbmRvbShrKTt2YXIgbD10aGlzLmVjcGFyYW1zLkcubXVsdGlwbHkobik7dmFyIHE9bC5nZXRYKCkudG9CaWdJbnRlZ2VyKCk7dmFyIG89bC5nZXRZKCkudG9CaWdJbnRlZ2VyKCk7dmFyIGk9dGhpcy5lY3BhcmFtcy5rZXlsZW4vNDt2YXIgbT0oXCIwMDAwMDAwMDAwXCIrbi50b1N0cmluZygxNikpLnNsaWNlKC1pKTt2YXIgcj0oXCIwMDAwMDAwMDAwXCIrcS50b1N0cmluZygxNikpLnNsaWNlKC1pKTt2YXIgcD0oXCIwMDAwMDAwMDAwXCIrby50b1N0cmluZygxNikpLnNsaWNlKC1pKTt2YXIgaj1cIjA0XCIrcitwO3RoaXMuc2V0UHJpdmF0ZUtleUhleChtKTt0aGlzLnNldFB1YmxpY0tleUhleChqKTtyZXR1cm57ZWNwcnZoZXg6bSxlY3B1YmhleDpqfX07dGhpcy5zaWduV2l0aE1lc3NhZ2VIYXNoPWZ1bmN0aW9uKGkpe3JldHVybiB0aGlzLnNpZ25IZXgoaSx0aGlzLnBydktleUhleCl9O3RoaXMuc2lnbkhleD1mdW5jdGlvbihvLGope3ZhciB0PW5ldyBCaWdJbnRlZ2VyKGosMTYpO3ZhciBsPXRoaXMuZWNwYXJhbXMubjt2YXIgcT1uZXcgQmlnSW50ZWdlcihvLDE2KTtkb3t2YXIgbT10aGlzLmdldEJpZ1JhbmRvbShsKTt2YXIgdT10aGlzLmVjcGFyYW1zLkc7dmFyIHA9dS5tdWx0aXBseShtKTt2YXIgaT1wLmdldFgoKS50b0JpZ0ludGVnZXIoKS5tb2QobCl9d2hpbGUoaS5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKTw9MCk7dmFyIHY9bS5tb2RJbnZlcnNlKGwpLm11bHRpcGx5KHEuYWRkKHQubXVsdGlwbHkoaSkpKS5tb2QobCk7cmV0dXJuIEtKVVIuY3J5cHRvLkVDRFNBLmJpUlNTaWdUb0FTTjFTaWcoaSx2KX07dGhpcy5zaWduPWZ1bmN0aW9uKG0sdSl7dmFyIHE9dTt2YXIgaj10aGlzLmVjcGFyYW1zLm47dmFyIHA9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobSk7ZG97dmFyIGw9dGhpcy5nZXRCaWdSYW5kb20oaik7dmFyIHQ9dGhpcy5lY3BhcmFtcy5HO3ZhciBvPXQubXVsdGlwbHkobCk7dmFyIGk9by5nZXRYKCkudG9CaWdJbnRlZ2VyKCkubW9kKGopfXdoaWxlKGkuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTyk8PTApO3ZhciB2PWwubW9kSW52ZXJzZShqKS5tdWx0aXBseShwLmFkZChxLm11bHRpcGx5KGkpKSkubW9kKGopO3JldHVybiB0aGlzLnNlcmlhbGl6ZVNpZyhpLHYpfTt0aGlzLnZlcmlmeVdpdGhNZXNzYWdlSGFzaD1mdW5jdGlvbihqLGkpe3JldHVybiB0aGlzLnZlcmlmeUhleChqLGksdGhpcy5wdWJLZXlIZXgpfTt0aGlzLnZlcmlmeUhleD1mdW5jdGlvbihtLGkscCl7dmFyIGwsajt2YXIgbz1LSlVSLmNyeXB0by5FQ0RTQS5wYXJzZVNpZ0hleChpKTtsPW8ucjtqPW8uczt2YXIgaztrPUVDUG9pbnRGcC5kZWNvZGVGcm9tSGV4KHRoaXMuZWNwYXJhbXMuY3VydmUscCk7dmFyIG49bmV3IEJpZ0ludGVnZXIobSwxNik7cmV0dXJuIHRoaXMudmVyaWZ5UmF3KG4sbCxqLGspfTt0aGlzLnZlcmlmeT1mdW5jdGlvbihvLHAsail7dmFyIGwsaTtpZihCaXRjb2luLlV0aWwuaXNBcnJheShwKSl7dmFyIG49dGhpcy5wYXJzZVNpZyhwKTtsPW4ucjtpPW4uc31lbHNle2lmKFwib2JqZWN0XCI9PT10eXBlb2YgcCYmcC5yJiZwLnMpe2w9cC5yO2k9cC5zfWVsc2V7dGhyb3dcIkludmFsaWQgdmFsdWUgZm9yIHNpZ25hdHVyZVwifX12YXIgaztpZihqIGluc3RhbmNlb2YgRUNQb2ludEZwKXtrPWp9ZWxzZXtpZihCaXRjb2luLlV0aWwuaXNBcnJheShqKSl7az1FQ1BvaW50RnAuZGVjb2RlRnJvbSh0aGlzLmVjcGFyYW1zLmN1cnZlLGopfWVsc2V7dGhyb3dcIkludmFsaWQgZm9ybWF0IGZvciBwdWJrZXkgdmFsdWUsIG11c3QgYmUgYnl0ZSBhcnJheSBvciBFQ1BvaW50RnBcIn19dmFyIG09QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobyk7cmV0dXJuIHRoaXMudmVyaWZ5UmF3KG0sbCxpLGspfTt0aGlzLnZlcmlmeVJhdz1mdW5jdGlvbihvLGksdyxtKXt2YXIgbD10aGlzLmVjcGFyYW1zLm47dmFyIHU9dGhpcy5lY3BhcmFtcy5HO2lmKGkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKTwwfHxpLmNvbXBhcmVUbyhsKT49MCl7cmV0dXJuIGZhbHNlfWlmKHcuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKTwwfHx3LmNvbXBhcmVUbyhsKT49MCl7cmV0dXJuIGZhbHNlfXZhciBwPXcubW9kSW52ZXJzZShsKTt2YXIgaz1vLm11bHRpcGx5KHApLm1vZChsKTt2YXIgaj1pLm11bHRpcGx5KHApLm1vZChsKTt2YXIgcT11Lm11bHRpcGx5KGspLmFkZChtLm11bHRpcGx5KGopKTt2YXIgdD1xLmdldFgoKS50b0JpZ0ludGVnZXIoKS5tb2QobCk7cmV0dXJuIHQuZXF1YWxzKGkpfTt0aGlzLnNlcmlhbGl6ZVNpZz1mdW5jdGlvbihrLGope3ZhciBsPWsudG9CeXRlQXJyYXlTaWduZWQoKTt2YXIgaT1qLnRvQnl0ZUFycmF5U2lnbmVkKCk7dmFyIG09W107bS5wdXNoKDIpO20ucHVzaChsLmxlbmd0aCk7bT1tLmNvbmNhdChsKTttLnB1c2goMik7bS5wdXNoKGkubGVuZ3RoKTttPW0uY29uY2F0KGkpO20udW5zaGlmdChtLmxlbmd0aCk7bS51bnNoaWZ0KDQ4KTtyZXR1cm4gbX07dGhpcy5wYXJzZVNpZz1mdW5jdGlvbihuKXt2YXIgbTtpZihuWzBdIT00OCl7dGhyb3cgbmV3IEVycm9yKFwiU2lnbmF0dXJlIG5vdCBhIHZhbGlkIERFUlNlcXVlbmNlXCIpfW09MjtpZihuW21dIT0yKXt0aHJvdyBuZXcgRXJyb3IoXCJGaXJzdCBlbGVtZW50IGluIHNpZ25hdHVyZSBtdXN0IGJlIGEgREVSSW50ZWdlclwiKX12YXIgbD1uLnNsaWNlKG0rMixtKzIrblttKzFdKTttKz0yK25bbSsxXTtpZihuW21dIT0yKXt0aHJvdyBuZXcgRXJyb3IoXCJTZWNvbmQgZWxlbWVudCBpbiBzaWduYXR1cmUgbXVzdCBiZSBhIERFUkludGVnZXJcIil9dmFyIGk9bi5zbGljZShtKzIsbSsyK25bbSsxXSk7bSs9MituW20rMV07dmFyIGs9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobCk7dmFyIGo9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQoaSk7cmV0dXJue3I6ayxzOmp9fTt0aGlzLnBhcnNlU2lnQ29tcGFjdD1mdW5jdGlvbihtKXtpZihtLmxlbmd0aCE9PTY1KXt0aHJvd1wiU2lnbmF0dXJlIGhhcyB0aGUgd3JvbmcgbGVuZ3RoXCJ9dmFyIGo9bVswXS0yNztpZihqPDB8fGo+Nyl7dGhyb3dcIkludmFsaWQgc2lnbmF0dXJlIHR5cGVcIn12YXIgbz10aGlzLmVjcGFyYW1zLm47dmFyIGw9QmlnSW50ZWdlci5mcm9tQnl0ZUFycmF5VW5zaWduZWQobS5zbGljZSgxLDMzKSkubW9kKG8pO3ZhciBrPUJpZ0ludGVnZXIuZnJvbUJ5dGVBcnJheVVuc2lnbmVkKG0uc2xpY2UoMzMsNjUpKS5tb2Qobyk7cmV0dXJue3I6bCxzOmssaTpqfX07dGhpcy5yZWFkUEtDUzVQcnZLZXlIZXg9ZnVuY3Rpb24obCl7dmFyIG49QVNOMUhFWDt2YXIgbT1LSlVSLmNyeXB0by5FQ0RTQS5nZXROYW1lO3ZhciBwPW4uZ2V0VmJ5TGlzdDtpZihuLmlzQVNOMUhFWChsKT09PWZhbHNlKXt0aHJvd1wibm90IEFTTi4xIGhleCBzdHJpbmdcIn12YXIgaSxrLG87dHJ5e2k9cChsLDAsWzIsMF0sXCIwNlwiKTtrPXAobCwwLFsxXSxcIjA0XCIpO3RyeXtvPXAobCwwLFszLDBdLFwiMDNcIikuc3Vic3RyKDIpfWNhdGNoKGope319Y2F0Y2goail7dGhyb3dcIm1hbGZvcm1lZCBQS0NTIzEvNSBwbGFpbiBFQ0MgcHJpdmF0ZSBrZXlcIn10aGlzLmN1cnZlTmFtZT1tKGkpO2lmKHRoaXMuY3VydmVOYW1lPT09dW5kZWZpbmVkKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZVwifXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7dGhpcy5zZXRQdWJsaWNLZXlIZXgobyk7dGhpcy5zZXRQcml2YXRlS2V5SGV4KGspO3RoaXMuaXNQdWJsaWM9ZmFsc2V9O3RoaXMucmVhZFBLQ1M4UHJ2S2V5SGV4PWZ1bmN0aW9uKGwpe3ZhciBxPUFTTjFIRVg7dmFyIGk9S0pVUi5jcnlwdG8uRUNEU0EuZ2V0TmFtZTt2YXIgbj1xLmdldFZieUxpc3Q7aWYocS5pc0FTTjFIRVgobCk9PT1mYWxzZSl7dGhyb3dcIm5vdCBBU04uMSBoZXggc3RyaW5nXCJ9dmFyIGoscCxtLGs7dHJ5e2o9bihsLDAsWzEsMF0sXCIwNlwiKTtwPW4obCwwLFsxLDFdLFwiMDZcIik7bT1uKGwsMCxbMiwwLDFdLFwiMDRcIik7dHJ5e2s9bihsLDAsWzIsMCwyLDBdLFwiMDNcIikuc3Vic3RyKDIpfWNhdGNoKG8pe319Y2F0Y2gobyl7dGhyb3dcIm1hbGZvcm1lZCBQS0NTIzggcGxhaW4gRUNDIHByaXZhdGUga2V5XCJ9dGhpcy5jdXJ2ZU5hbWU9aShwKTtpZih0aGlzLmN1cnZlTmFtZT09PXVuZGVmaW5lZCl7dGhyb3dcInVuc3VwcG9ydGVkIGN1cnZlIG5hbWVcIn10aGlzLnNldE5hbWVkQ3VydmUodGhpcy5jdXJ2ZU5hbWUpO3RoaXMuc2V0UHVibGljS2V5SGV4KGspO3RoaXMuc2V0UHJpdmF0ZUtleUhleChtKTt0aGlzLmlzUHVibGljPWZhbHNlfTt0aGlzLnJlYWRQS0NTOFB1YktleUhleD1mdW5jdGlvbihsKXt2YXIgbj1BU04xSEVYO3ZhciBtPUtKVVIuY3J5cHRvLkVDRFNBLmdldE5hbWU7dmFyIHA9bi5nZXRWYnlMaXN0O2lmKG4uaXNBU04xSEVYKGwpPT09ZmFsc2Upe3Rocm93XCJub3QgQVNOLjEgaGV4IHN0cmluZ1wifXZhciBrLGksbzt0cnl7az1wKGwsMCxbMCwwXSxcIjA2XCIpO2k9cChsLDAsWzAsMV0sXCIwNlwiKTtvPXAobCwwLFsxXSxcIjAzXCIpLnN1YnN0cigyKX1jYXRjaChqKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1MjOCBFQ0MgcHVibGljIGtleVwifXRoaXMuY3VydmVOYW1lPW0oaSk7aWYodGhpcy5jdXJ2ZU5hbWU9PT1udWxsKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZVwifXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7dGhpcy5zZXRQdWJsaWNLZXlIZXgobyl9O3RoaXMucmVhZENlcnRQdWJLZXlIZXg9ZnVuY3Rpb24oayxwKXtpZihwIT09NSl7cD02fXZhciBtPUFTTjFIRVg7dmFyIGw9S0pVUi5jcnlwdG8uRUNEU0EuZ2V0TmFtZTt2YXIgbz1tLmdldFZieUxpc3Q7aWYobS5pc0FTTjFIRVgoayk9PT1mYWxzZSl7dGhyb3dcIm5vdCBBU04uMSBoZXggc3RyaW5nXCJ9dmFyIGksbjt0cnl7aT1vKGssMCxbMCxwLDAsMV0sXCIwNlwiKTtuPW8oaywwLFswLHAsMV0sXCIwM1wiKS5zdWJzdHIoMil9Y2F0Y2goail7dGhyb3dcIm1hbGZvcm1lZCBYLjUwOSBjZXJ0aWZpY2F0ZSBFQ0MgcHVibGljIGtleVwifXRoaXMuY3VydmVOYW1lPWwoaSk7aWYodGhpcy5jdXJ2ZU5hbWU9PT1udWxsKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZVwifXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7dGhpcy5zZXRQdWJsaWNLZXlIZXgobil9O2lmKGghPT11bmRlZmluZWQpe2lmKGguY3VydmUhPT11bmRlZmluZWQpe3RoaXMuY3VydmVOYW1lPWguY3VydmV9fWlmKHRoaXMuY3VydmVOYW1lPT09dW5kZWZpbmVkKXt0aGlzLmN1cnZlTmFtZT1lfXRoaXMuc2V0TmFtZWRDdXJ2ZSh0aGlzLmN1cnZlTmFtZSk7aWYoaCE9PXVuZGVmaW5lZCl7aWYoaC5wcnYhPT11bmRlZmluZWQpe3RoaXMuc2V0UHJpdmF0ZUtleUhleChoLnBydil9aWYoaC5wdWIhPT11bmRlZmluZWQpe3RoaXMuc2V0UHVibGljS2V5SGV4KGgucHViKX19fTtLSlVSLmNyeXB0by5FQ0RTQS5wYXJzZVNpZ0hleD1mdW5jdGlvbihhKXt2YXIgYj1LSlVSLmNyeXB0by5FQ0RTQS5wYXJzZVNpZ0hleEluSGV4UlMoYSk7dmFyIGQ9bmV3IEJpZ0ludGVnZXIoYi5yLDE2KTt2YXIgYz1uZXcgQmlnSW50ZWdlcihiLnMsMTYpO3JldHVybntyOmQsczpjfX07S0pVUi5jcnlwdG8uRUNEU0EucGFyc2VTaWdIZXhJbkhleFJTPWZ1bmN0aW9uKGYpe3ZhciBqPUFTTjFIRVg7dmFyIGk9ai5nZXRDaGlsZElkeDt2YXIgZz1qLmdldFY7aWYoZi5zdWJzdHIoMCwyKSE9XCIzMFwiKXt0aHJvd1wic2lnbmF0dXJlIGlzIG5vdCBhIEFTTi4xIHNlcXVlbmNlXCJ9dmFyIGg9aShmLDApO2lmKGgubGVuZ3RoIT0yKXt0aHJvd1wibnVtYmVyIG9mIHNpZ25hdHVyZSBBU04uMSBzZXF1ZW5jZSBlbGVtZW50cyBzZWVtIHdyb25nXCJ9dmFyIGU9aFswXTt2YXIgZD1oWzFdO2lmKGYuc3Vic3RyKGUsMikhPVwiMDJcIil7dGhyb3dcIjFzdCBpdGVtIG9mIHNlcXVlbmUgb2Ygc2lnbmF0dXJlIGlzIG5vdCBBU04uMSBpbnRlZ2VyXCJ9aWYoZi5zdWJzdHIoZCwyKSE9XCIwMlwiKXt0aHJvd1wiMm5kIGl0ZW0gb2Ygc2VxdWVuZSBvZiBzaWduYXR1cmUgaXMgbm90IEFTTi4xIGludGVnZXJcIn12YXIgYz1nKGYsZSk7dmFyIGI9ZyhmLGQpO3JldHVybntyOmMsczpifX07S0pVUi5jcnlwdG8uRUNEU0EuYXNuMVNpZ1RvQ29uY2F0U2lnPWZ1bmN0aW9uKGMpe3ZhciBkPUtKVVIuY3J5cHRvLkVDRFNBLnBhcnNlU2lnSGV4SW5IZXhSUyhjKTt2YXIgYj1kLnI7dmFyIGE9ZC5zO2lmKGIuc3Vic3RyKDAsMik9PVwiMDBcIiYmKGIubGVuZ3RoJTMyKT09Mil7Yj1iLnN1YnN0cigyKX1pZihhLnN1YnN0cigwLDIpPT1cIjAwXCImJihhLmxlbmd0aCUzMik9PTIpe2E9YS5zdWJzdHIoMil9aWYoKGIubGVuZ3RoJTMyKT09MzApe2I9XCIwMFwiK2J9aWYoKGEubGVuZ3RoJTMyKT09MzApe2E9XCIwMFwiK2F9aWYoYi5sZW5ndGglMzIhPTApe3Rocm93XCJ1bmtub3duIEVDRFNBIHNpZyByIGxlbmd0aCBlcnJvclwifWlmKGEubGVuZ3RoJTMyIT0wKXt0aHJvd1widW5rbm93biBFQ0RTQSBzaWcgcyBsZW5ndGggZXJyb3JcIn1yZXR1cm4gYithfTtLSlVSLmNyeXB0by5FQ0RTQS5jb25jYXRTaWdUb0FTTjFTaWc9ZnVuY3Rpb24oYSl7aWYoKCgoYS5sZW5ndGgvMikqOCklKDE2KjgpKSE9MCl7dGhyb3dcInVua25vd24gRUNEU0EgY29uY2F0aW5hdGVkIHItcyBzaWcgIGxlbmd0aCBlcnJvclwifXZhciBjPWEuc3Vic3RyKDAsYS5sZW5ndGgvMik7dmFyIGI9YS5zdWJzdHIoYS5sZW5ndGgvMik7cmV0dXJuIEtKVVIuY3J5cHRvLkVDRFNBLmhleFJTU2lnVG9BU04xU2lnKGMsYil9O0tKVVIuY3J5cHRvLkVDRFNBLmhleFJTU2lnVG9BU04xU2lnPWZ1bmN0aW9uKGIsYSl7dmFyIGQ9bmV3IEJpZ0ludGVnZXIoYiwxNik7dmFyIGM9bmV3IEJpZ0ludGVnZXIoYSwxNik7cmV0dXJuIEtKVVIuY3J5cHRvLkVDRFNBLmJpUlNTaWdUb0FTTjFTaWcoZCxjKX07S0pVUi5jcnlwdG8uRUNEU0EuYmlSU1NpZ1RvQVNOMVNpZz1mdW5jdGlvbihmLGQpe3ZhciBjPUtKVVIuYXNuMTt2YXIgYj1uZXcgYy5ERVJJbnRlZ2VyKHtiaWdpbnQ6Zn0pO3ZhciBhPW5ldyBjLkRFUkludGVnZXIoe2JpZ2ludDpkfSk7dmFyIGU9bmV3IGMuREVSU2VxdWVuY2Uoe2FycmF5OltiLGFdfSk7cmV0dXJuIGUuZ2V0RW5jb2RlZEhleCgpfTtLSlVSLmNyeXB0by5FQ0RTQS5nZXROYW1lPWZ1bmN0aW9uKGEpe2lmKGE9PT1cIjJhODY0OGNlM2QwMzAxMDdcIil7cmV0dXJuXCJzZWNwMjU2cjFcIn1pZihhPT09XCIyYjgxMDQwMDBhXCIpe3JldHVyblwic2VjcDI1NmsxXCJ9aWYoYT09PVwiMmI4MTA0MDAyMlwiKXtyZXR1cm5cInNlY3AzODRyMVwifWlmKFwifHNlY3AyNTZyMXxOSVNUIFAtMjU2fFAtMjU2fHByaW1lMjU2djF8XCIuaW5kZXhPZihhKSE9PS0xKXtyZXR1cm5cInNlY3AyNTZyMVwifWlmKFwifHNlY3AyNTZrMXxcIi5pbmRleE9mKGEpIT09LTEpe3JldHVyblwic2VjcDI1NmsxXCJ9aWYoXCJ8c2VjcDM4NHIxfE5JU1QgUC0zODR8UC0zODR8XCIuaW5kZXhPZihhKSE9PS0xKXtyZXR1cm5cInNlY3AzODRyMVwifXJldHVybiBudWxsfTtcbmlmKHR5cGVvZiBLSlVSPT1cInVuZGVmaW5lZFwifHwhS0pVUil7S0pVUj17fX1pZih0eXBlb2YgS0pVUi5jcnlwdG89PVwidW5kZWZpbmVkXCJ8fCFLSlVSLmNyeXB0byl7S0pVUi5jcnlwdG89e319S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQj1uZXcgZnVuY3Rpb24oKXt2YXIgYj17fTt2YXIgYz17fTtmdW5jdGlvbiBhKGQpe3JldHVybiBuZXcgQmlnSW50ZWdlcihkLDE2KX10aGlzLmdldEJ5TmFtZT1mdW5jdGlvbihlKXt2YXIgZD1lO2lmKHR5cGVvZiBjW2RdIT1cInVuZGVmaW5lZFwiKXtkPWNbZV19aWYodHlwZW9mIGJbZF0hPVwidW5kZWZpbmVkXCIpe3JldHVybiBiW2RdfXRocm93XCJ1bnJlZ2lzdGVyZWQgRUMgY3VydmUgbmFtZTogXCIrZH07dGhpcy5yZWdpc3Q9ZnVuY3Rpb24oQSxsLG8sZyxtLGUsaixmLGssdSxkLHgpe2JbQV09e307dmFyIHM9YShvKTt2YXIgej1hKGcpO3ZhciB5PWEobSk7dmFyIHQ9YShlKTt2YXIgdz1hKGopO3ZhciByPW5ldyBFQ0N1cnZlRnAocyx6LHkpO3ZhciBxPXIuZGVjb2RlUG9pbnRIZXgoXCIwNFwiK2Yrayk7YltBXVtcIm5hbWVcIl09QTtiW0FdW1wia2V5bGVuXCJdPWw7YltBXVtcImN1cnZlXCJdPXI7YltBXVtcIkdcIl09cTtiW0FdW1wiblwiXT10O2JbQV1bXCJoXCJdPXc7YltBXVtcIm9pZFwiXT1kO2JbQV1bXCJpbmZvXCJdPXg7Zm9yKHZhciB2PTA7djx1Lmxlbmd0aDt2Kyspe2NbdVt2XV09QX19fTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AxMjhyMVwiLDEyOCxcIkZGRkZGRkZERkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGXCIsXCJGRkZGRkZGREZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQ1wiLFwiRTg3NTc5QzExMDc5RjQzREQ4MjQ5OTNDMkNFRTVFRDNcIixcIkZGRkZGRkZFMDAwMDAwMDA3NUEzMEQxQjkwMzhBMTE1XCIsXCIxXCIsXCIxNjFGRjc1MjhCODk5QjJEMEMyODYwN0NBNTJDNUI4NlwiLFwiQ0Y1QUM4Mzk1QkFGRUIxM0MwMkRBMjkyRERFRDdBODNcIixbXSxcIlwiLFwic2VjcDEyOHIxIDogU0VDRyBjdXJ2ZSBvdmVyIGEgMTI4IGJpdCBwcmltZSBmaWVsZFwiKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AxNjBrMVwiLDE2MCxcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkFDNzNcIixcIjBcIixcIjdcIixcIjAxMDAwMDAwMDAwMDAwMDAwMDAwMDFCOEZBMTZERkFCOUFDQTE2QjZCM1wiLFwiMVwiLFwiM0I0QzM4MkNFMzdBQTE5MkE0MDE5RTc2MzAzNkY0RjVERDREN0VCQlwiLFwiOTM4Q0Y5MzUzMThGRENFRDZCQzI4Mjg2NTMxNzMzQzNGMDNDNEZFRVwiLFtdLFwiXCIsXCJzZWNwMTYwazEgOiBTRUNHIGN1cnZlIG92ZXIgYSAxNjAgYml0IHByaW1lIGZpZWxkXCIpO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDE2MHIxXCIsMTYwLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY3RkZGRkZGRlwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY3RkZGRkZGQ1wiLFwiMUM5N0JFRkM1NEJEN0E4QjY1QUNGODlGODFENEQ0QURDNTY1RkE0NVwiLFwiMDEwMDAwMDAwMDAwMDAwMDAwMDAwMUY0QzhGOTI3QUVEM0NBNzUyMjU3XCIsXCIxXCIsXCI0QTk2QjU2ODhFRjU3MzI4NDY2NDY5ODk2OEMzOEJCOTEzQ0JGQzgyXCIsXCIyM0E2Mjg1NTMxNjg5NDdENTlEQ0M5MTIwNDIzNTEzNzdBQzVGQjMyXCIsW10sXCJcIixcInNlY3AxNjByMSA6IFNFQ0cgY3VydmUgb3ZlciBhIDE2MCBiaXQgcHJpbWUgZmllbGRcIik7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMTkyazFcIiwxOTIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkVFMzdcIixcIjBcIixcIjNcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRTI2RjJGQzE3MEY2OTQ2NkE3NERFRkQ4RFwiLFwiMVwiLFwiREI0RkYxMEVDMDU3RTlBRTI2QjA3RDAyODBCN0Y0MzQxREE1RDFCMUVBRTA2QzdEXCIsXCI5QjJGMkY2RDlDNTYyOEE3ODQ0MTYzRDAxNUJFODYzNDQwODJBQTg4RDk1RTJGOURcIixbXSk7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMTkycjFcIiwxOTIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGRkZGRkZGRkZcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkZGRkZGRkZGQ1wiLFwiNjQyMTA1MTlFNTlDODBFNzBGQTdFOUFCNzIyNDMwNDlGRUI4REVFQ0MxNDZCOUIxXCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkY5OURFRjgzNjE0NkJDOUIxQjREMjI4MzFcIixcIjFcIixcIjE4OERBODBFQjAzMDkwRjY3Q0JGMjBFQjQzQTE4ODAwRjRGRjBBRkQ4MkZGMTAxMlwiLFwiMDcxOTJCOTVGRkM4REE3ODYzMTAxMUVENkIyNENERDU3M0Y5NzdBMTFFNzk0ODExXCIsW10pO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDIyNHIxXCIsMjI0LFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkYwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFXCIsXCJCNDA1MEE4NTBDMDRCM0FCRjU0MTMyNTY1MDQ0QjBCN0Q3QkZEOEJBMjcwQjM5NDMyMzU1RkZCNFwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRjE2QTJFMEI4RjAzRTEzREQyOTQ1NUM1QzJBM0RcIixcIjFcIixcIkI3MEUwQ0JENkJCNEJGN0YzMjEzOTBCOTRBMDNDMUQzNTZDMjExMjIzNDMyODBENjExNUMxRDIxXCIsXCJCRDM3NjM4OEI1RjcyM0ZCNEMyMkRGRTZDRDQzNzVBMDVBMDc0NzY0NDRENTgxOTk4NTAwN0UzNFwiLFtdKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3AyNTZrMVwiLDI1NixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZDMkZcIixcIjBcIixcIjdcIixcIkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFQkFBRURDRTZBRjQ4QTAzQkJGRDI1RThDRDAzNjQxNDFcIixcIjFcIixcIjc5QkU2NjdFRjlEQ0JCQUM1NUEwNjI5NUNFODcwQjA3MDI5QkZDREIyRENFMjhEOTU5RjI4MTVCMTZGODE3OThcIixcIjQ4M0FEQTc3MjZBM0M0NjU1REE0RkJGQzBFMTEwOEE4RkQxN0I0NDhBNjg1NTQxOTlDNDdEMDhGRkIxMEQ0QjhcIixbXSk7S0pVUi5jcnlwdG8uRUNQYXJhbWV0ZXJEQi5yZWdpc3QoXCJzZWNwMjU2cjFcIiwyNTYsXCJGRkZGRkZGRjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGXCIsXCJGRkZGRkZGRjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZDXCIsXCI1QUM2MzVEOEFBM0E5M0U3QjNFQkJENTU3Njk4ODZCQzY1MUQwNkIwQ0M1M0IwRjYzQkNFM0MzRTI3RDI2MDRCXCIsXCJGRkZGRkZGRjAwMDAwMDAwRkZGRkZGRkZGRkZGRkZGRkJDRTZGQUFEQTcxNzlFODRGM0I5Q0FDMkZDNjMyNTUxXCIsXCIxXCIsXCI2QjE3RDFGMkUxMkM0MjQ3RjhCQ0U2RTU2M0E0NDBGMjc3MDM3RDgxMkRFQjMzQTBGNEExMzk0NUQ4OThDMjk2XCIsXCI0RkUzNDJFMkZFMUE3RjlCOEVFN0VCNEE3QzBGOUUxNjJCQ0UzMzU3NkIzMTVFQ0VDQkI2NDA2ODM3QkY1MUY1XCIsW1wiTklTVCBQLTI1NlwiLFwiUC0yNTZcIixcInByaW1lMjU2djFcIl0pO0tKVVIuY3J5cHRvLkVDUGFyYW1ldGVyREIucmVnaXN0KFwic2VjcDM4NHIxXCIsMzg0LFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRUZGRkZGRkZGMDAwMDAwMDAwMDAwMDAwMEZGRkZGRkZGXCIsXCJGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFRkZGRkZGRkYwMDAwMDAwMDAwMDAwMDAwRkZGRkZGRkNcIixcIkIzMzEyRkE3RTIzRUU3RTQ5ODhFMDU2QkUzRjgyRDE5MTgxRDlDNkVGRTgxNDExMjAzMTQwODhGNTAxMzg3NUFDNjU2Mzk4RDhBMkVEMTlEMkE4NUM4RUREM0VDMkFFRlwiLFwiRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQzc2MzREODFGNDM3MkRERjU4MUEwREIyNDhCMEE3N0FFQ0VDMTk2QUNDQzUyOTczXCIsXCIxXCIsXCJBQTg3Q0EyMkJFOEIwNTM3OEVCMUM3MUVGMzIwQUQ3NDZFMUQzQjYyOEJBNzlCOTg1OUY3NDFFMDgyNTQyQTM4NTUwMkYyNURCRjU1Mjk2QzNBNTQ1RTM4NzI3NjBBQjdcIixcIjM2MTdkZTRhOTYyNjJjNmY1ZDllOThiZjkyOTJkYzI5ZjhmNDFkYmQyODlhMTQ3Y2U5ZGEzMTEzYjVmMGI4YzAwYTYwYjFjZTFkN2U4MTlkN2E0MzFkN2M5MGVhMGU1ZlwiLFtcIk5JU1QgUC0zODRcIixcIlAtMzg0XCJdKTtLSlVSLmNyeXB0by5FQ1BhcmFtZXRlckRCLnJlZ2lzdChcInNlY3A1MjFyMVwiLDUyMSxcIjFGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGXCIsXCIxRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQ1wiLFwiMDUxOTUzRUI5NjE4RTFDOUExRjkyOUEyMUEwQjY4NTQwRUVBMkRBNzI1Qjk5QjMxNUYzQjhCNDg5OTE4RUYxMDlFMTU2MTkzOTUxRUM3RTkzN0IxNjUyQzBCRDNCQjFCRjA3MzU3M0RGODgzRDJDMzRGMUVGNDUxRkQ0NkI1MDNGMDBcIixcIjFGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkE1MTg2ODc4M0JGMkY5NjZCN0ZDQzAxNDhGNzA5QTVEMDNCQjVDOUI4ODk5QzQ3QUVCQjZGQjcxRTkxMzg2NDA5XCIsXCIxXCIsXCJDNjg1OEUwNkI3MDQwNEU5Q0Q5RTNFQ0I2NjIzOTVCNDQyOUM2NDgxMzkwNTNGQjUyMUY4MjhBRjYwNkI0RDNEQkFBMTRCNUU3N0VGRTc1OTI4RkUxREMxMjdBMkZGQThERTMzNDhCM0MxODU2QTQyOUJGOTdFN0UzMUMyRTVCRDY2XCIsXCIwMTE4MzkyOTZhNzg5YTNiYzAwNDVjOGE1ZmI0MmM3ZDFiZDk5OGY1NDQ0OTU3OWI0NDY4MTdhZmJkMTcyNzNlNjYyYzk3ZWU3Mjk5NWVmNDI2NDBjNTUwYjkwMTNmYWQwNzYxMzUzYzcwODZhMjcyYzI0MDg4YmU5NDc2OWZkMTY2NTBcIixbXCJOSVNUIFAtNTIxXCIsXCJQLTUyMVwiXSk7XG52YXIgS0VZVVRJTD1mdW5jdGlvbigpe3ZhciBkPWZ1bmN0aW9uKHAscixxKXtyZXR1cm4gayhDcnlwdG9KUy5BRVMscCxyLHEpfTt2YXIgZT1mdW5jdGlvbihwLHIscSl7cmV0dXJuIGsoQ3J5cHRvSlMuVHJpcGxlREVTLHAscixxKX07dmFyIGE9ZnVuY3Rpb24ocCxyLHEpe3JldHVybiBrKENyeXB0b0pTLkRFUyxwLHIscSl9O3ZhciBrPWZ1bmN0aW9uKHMseCx1LHEpe3ZhciByPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoeCk7dmFyIHc9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh1KTt2YXIgcD1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHEpO3ZhciB0PXt9O3Qua2V5PXc7dC5pdj1wO3QuY2lwaGVydGV4dD1yO3ZhciB2PXMuZGVjcnlwdCh0LHcse2l2OnB9KTtyZXR1cm4gQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkodil9O3ZhciBsPWZ1bmN0aW9uKHAscixxKXtyZXR1cm4gZyhDcnlwdG9KUy5BRVMscCxyLHEpfTt2YXIgbz1mdW5jdGlvbihwLHIscSl7cmV0dXJuIGcoQ3J5cHRvSlMuVHJpcGxlREVTLHAscixxKX07dmFyIGY9ZnVuY3Rpb24ocCxyLHEpe3JldHVybiBnKENyeXB0b0pTLkRFUyxwLHIscSl9O3ZhciBnPWZ1bmN0aW9uKHQseSx2LHEpe3ZhciBzPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoeSk7dmFyIHg9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh2KTt2YXIgcD1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHEpO3ZhciB3PXQuZW5jcnlwdChzLHgse2l2OnB9KTt2YXIgcj1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHcudG9TdHJpbmcoKSk7dmFyIHU9Q3J5cHRvSlMuZW5jLkJhc2U2NC5zdHJpbmdpZnkocik7cmV0dXJuIHV9O3ZhciBpPXtcIkFFUy0yNTYtQ0JDXCI6e3Byb2M6ZCxlcHJvYzpsLGtleWxlbjozMixpdmxlbjoxNn0sXCJBRVMtMTkyLUNCQ1wiOntwcm9jOmQsZXByb2M6bCxrZXlsZW46MjQsaXZsZW46MTZ9LFwiQUVTLTEyOC1DQkNcIjp7cHJvYzpkLGVwcm9jOmwsa2V5bGVuOjE2LGl2bGVuOjE2fSxcIkRFUy1FREUzLUNCQ1wiOntwcm9jOmUsZXByb2M6byxrZXlsZW46MjQsaXZsZW46OH0sXCJERVMtQ0JDXCI6e3Byb2M6YSxlcHJvYzpmLGtleWxlbjo4LGl2bGVuOjh9fTt2YXIgYz1mdW5jdGlvbihwKXtyZXR1cm4gaVtwXVtcInByb2NcIl19O3ZhciBtPWZ1bmN0aW9uKHApe3ZhciByPUNyeXB0b0pTLmxpYi5Xb3JkQXJyYXkucmFuZG9tKHApO3ZhciBxPUNyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHIpO3JldHVybiBxfTt2YXIgbj1mdW5jdGlvbih2KXt2YXIgdz17fTt2YXIgcT12Lm1hdGNoKG5ldyBSZWdFeHAoXCJERUstSW5mbzogKFteLF0rKSwoWzAtOUEtRmEtZl0rKVwiLFwibVwiKSk7aWYocSl7dy5jaXBoZXI9cVsxXTt3Lml2c2FsdD1xWzJdfXZhciBwPXYubWF0Y2gobmV3IFJlZ0V4cChcIi0tLS0tQkVHSU4gKFtBLVpdKykgUFJJVkFURSBLRVktLS0tLVwiKSk7aWYocCl7dy50eXBlPXBbMV19dmFyIHU9LTE7dmFyIHg9MDtpZih2LmluZGV4T2YoXCJcXHJcXG5cXHJcXG5cIikhPS0xKXt1PXYuaW5kZXhPZihcIlxcclxcblxcclxcblwiKTt4PTJ9aWYodi5pbmRleE9mKFwiXFxuXFxuXCIpIT0tMSl7dT12LmluZGV4T2YoXCJcXG5cXG5cIik7eD0xfXZhciB0PXYuaW5kZXhPZihcIi0tLS0tRU5EXCIpO2lmKHUhPS0xJiZ0IT0tMSl7dmFyIHI9di5zdWJzdHJpbmcodSt4KjIsdC14KTtyPXIucmVwbGFjZSgvXFxzKy9nLFwiXCIpO3cuZGF0YT1yfXJldHVybiB3fTt2YXIgaj1mdW5jdGlvbihxLHkscCl7dmFyIHY9cC5zdWJzdHJpbmcoMCwxNik7dmFyIHQ9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh2KTt2YXIgcj1DcnlwdG9KUy5lbmMuVXRmOC5wYXJzZSh5KTt2YXIgdT1pW3FdW1wia2V5bGVuXCJdK2lbcV1bXCJpdmxlblwiXTt2YXIgeD1cIlwiO3ZhciB3PW51bGw7Zm9yKDs7KXt2YXIgcz1DcnlwdG9KUy5hbGdvLk1ENS5jcmVhdGUoKTtpZih3IT1udWxsKXtzLnVwZGF0ZSh3KX1zLnVwZGF0ZShyKTtzLnVwZGF0ZSh0KTt3PXMuZmluYWxpemUoKTt4PXgrQ3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkodyk7aWYoeC5sZW5ndGg+PXUqMil7YnJlYWt9fXZhciB6PXt9O3oua2V5aGV4PXguc3Vic3RyKDAsaVtxXVtcImtleWxlblwiXSoyKTt6Lml2aGV4PXguc3Vic3RyKGlbcV1bXCJrZXlsZW5cIl0qMixpW3FdW1wiaXZsZW5cIl0qMik7cmV0dXJuIHp9O3ZhciBiPWZ1bmN0aW9uKHAsdixyLHcpe3ZhciBzPUNyeXB0b0pTLmVuYy5CYXNlNjQucGFyc2UocCk7dmFyIHE9Q3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkocyk7dmFyIHU9aVt2XVtcInByb2NcIl07dmFyIHQ9dShxLHIsdyk7cmV0dXJuIHR9O3ZhciBoPWZ1bmN0aW9uKHAscyxxLHUpe3ZhciByPWlbc11bXCJlcHJvY1wiXTt2YXIgdD1yKHAscSx1KTtyZXR1cm4gdH07cmV0dXJue3ZlcnNpb246XCIxLjAuMFwiLHBhcnNlUEtDUzVQRU06ZnVuY3Rpb24ocCl7cmV0dXJuIG4ocCl9LGdldEtleUFuZFVudXNlZEl2QnlQYXNzY29kZUFuZEl2c2FsdDpmdW5jdGlvbihxLHAscil7cmV0dXJuIGoocSxwLHIpfSxkZWNyeXB0S2V5QjY0OmZ1bmN0aW9uKHAscixxLHMpe3JldHVybiBiKHAscixxLHMpfSxnZXREZWNyeXB0ZWRLZXlIZXg6ZnVuY3Rpb24oeSx4KXt2YXIgcT1uKHkpO3ZhciB0PXEudHlwZTt2YXIgcj1xLmNpcGhlcjt2YXIgcD1xLml2c2FsdDt2YXIgcz1xLmRhdGE7dmFyIHc9aihyLHgscCk7dmFyIHY9dy5rZXloZXg7dmFyIHU9YihzLHIsdixwKTtyZXR1cm4gdX0sZ2V0RW5jcnlwdGVkUEtDUzVQRU1Gcm9tUHJ2S2V5SGV4OmZ1bmN0aW9uKHgscyxBLHQscil7dmFyIHA9XCJcIjtpZih0eXBlb2YgdD09XCJ1bmRlZmluZWRcInx8dD09bnVsbCl7dD1cIkFFUy0yNTYtQ0JDXCJ9aWYodHlwZW9mIGlbdF09PVwidW5kZWZpbmVkXCIpe3Rocm93XCJLRVlVVElMIHVuc3VwcG9ydGVkIGFsZ29yaXRobTogXCIrdH1pZih0eXBlb2Ygcj09XCJ1bmRlZmluZWRcInx8cj09bnVsbCl7dmFyIHY9aVt0XVtcIml2bGVuXCJdO3ZhciB1PW0odik7cj11LnRvVXBwZXJDYXNlKCl9dmFyIHo9aih0LEEscik7dmFyIHk9ei5rZXloZXg7dmFyIHc9aChzLHQseSxyKTt2YXIgcT13LnJlcGxhY2UoLyguezY0fSkvZyxcIiQxXFxyXFxuXCIpO3ZhciBwPVwiLS0tLS1CRUdJTiBcIit4K1wiIFBSSVZBVEUgS0VZLS0tLS1cXHJcXG5cIjtwKz1cIlByb2MtVHlwZTogNCxFTkNSWVBURURcXHJcXG5cIjtwKz1cIkRFSy1JbmZvOiBcIit0K1wiLFwiK3IrXCJcXHJcXG5cIjtwKz1cIlxcclxcblwiO3ArPXE7cCs9XCJcXHJcXG4tLS0tLUVORCBcIit4K1wiIFBSSVZBVEUgS0VZLS0tLS1cXHJcXG5cIjtyZXR1cm4gcH0scGFyc2VIZXhPZkVuY3J5cHRlZFBLQ1M4OmZ1bmN0aW9uKHkpe3ZhciBCPUFTTjFIRVg7dmFyIHo9Qi5nZXRDaGlsZElkeDt2YXIgdz1CLmdldFY7dmFyIHQ9e307dmFyIHI9eih5LDApO2lmKHIubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIGZvcm1hdDogU0VRVUVOQ0UoMCkuaXRlbXMgIT0gMjogXCIrci5sZW5ndGh9dC5jaXBoZXJ0ZXh0PXcoeSxyWzFdKTt2YXIgQT16KHksclswXSk7aWYoQS5sZW5ndGghPTIpe3Rocm93XCJtYWxmb3JtZWQgZm9ybWF0OiBTRVFVRU5DRSgwLjApLml0ZW1zICE9IDI6IFwiK0EubGVuZ3RofWlmKHcoeSxBWzBdKSE9XCIyYTg2NDg4NmY3MGQwMTA1MGRcIil7dGhyb3dcInRoaXMgb25seSBzdXBwb3J0cyBwa2NzNVBCRVMyXCJ9dmFyIHA9eih5LEFbMV0pO2lmKEEubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIGZvcm1hdDogU0VRVUVOQ0UoMC4wLjEpLml0ZW1zICE9IDI6IFwiK3AubGVuZ3RofXZhciBxPXooeSxwWzFdKTtpZihxLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQ6IFNFUVVFTkNFKDAuMC4xLjEpLml0ZW1zICE9IDI6IFwiK3EubGVuZ3RofWlmKHcoeSxxWzBdKSE9XCIyYTg2NDg4NmY3MGQwMzA3XCIpe3Rocm93XCJ0aGlzIG9ubHkgc3VwcG9ydHMgVHJpcGxlREVTXCJ9dC5lbmNyeXB0aW9uU2NoZW1lQWxnPVwiVHJpcGxlREVTXCI7dC5lbmNyeXB0aW9uU2NoZW1lSVY9dyh5LHFbMV0pO3ZhciBzPXooeSxwWzBdKTtpZihzLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQ6IFNFUVVFTkNFKDAuMC4xLjApLml0ZW1zICE9IDI6IFwiK3MubGVuZ3RofWlmKHcoeSxzWzBdKSE9XCIyYTg2NDg4NmY3MGQwMTA1MGNcIil7dGhyb3dcInRoaXMgb25seSBzdXBwb3J0cyBwa2NzNVBCS0RGMlwifXZhciB4PXooeSxzWzFdKTtpZih4Lmxlbmd0aDwyKXt0aHJvd1wibWFsZm9ybWVkIGZvcm1hdDogU0VRVUVOQ0UoMC4wLjEuMC4xKS5pdGVtcyA8IDI6IFwiK3gubGVuZ3RofXQucGJrZGYyU2FsdD13KHkseFswXSk7dmFyIHU9dyh5LHhbMV0pO3RyeXt0LnBia2RmMkl0ZXI9cGFyc2VJbnQodSwxNil9Y2F0Y2godil7dGhyb3dcIm1hbGZvcm1lZCBmb3JtYXQgcGJrZGYySXRlcjogXCIrdX1yZXR1cm4gdH0sZ2V0UEJLREYyS2V5SGV4RnJvbVBhcmFtOmZ1bmN0aW9uKHUscCl7dmFyIHQ9Q3J5cHRvSlMuZW5jLkhleC5wYXJzZSh1LnBia2RmMlNhbHQpO3ZhciBxPXUucGJrZGYySXRlcjt2YXIgcz1DcnlwdG9KUy5QQktERjIocCx0LHtrZXlTaXplOjE5Mi8zMixpdGVyYXRpb25zOnF9KTt2YXIgcj1DcnlwdG9KUy5lbmMuSGV4LnN0cmluZ2lmeShzKTtyZXR1cm4gcn0sX2dldFBsYWluUEtDUzhIZXhGcm9tRW5jcnlwdGVkUEtDUzhQRU06ZnVuY3Rpb24oeCx5KXt2YXIgcj1wZW10b2hleCh4LFwiRU5DUllQVEVEIFBSSVZBVEUgS0VZXCIpO3ZhciBwPXRoaXMucGFyc2VIZXhPZkVuY3J5cHRlZFBLQ1M4KHIpO3ZhciB1PUtFWVVUSUwuZ2V0UEJLREYyS2V5SGV4RnJvbVBhcmFtKHAseSk7dmFyIHY9e307di5jaXBoZXJ0ZXh0PUNyeXB0b0pTLmVuYy5IZXgucGFyc2UocC5jaXBoZXJ0ZXh0KTt2YXIgdD1DcnlwdG9KUy5lbmMuSGV4LnBhcnNlKHUpO3ZhciBzPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UocC5lbmNyeXB0aW9uU2NoZW1lSVYpO3ZhciB3PUNyeXB0b0pTLlRyaXBsZURFUy5kZWNyeXB0KHYsdCx7aXY6c30pO3ZhciBxPUNyeXB0b0pTLmVuYy5IZXguc3RyaW5naWZ5KHcpO3JldHVybiBxfSxnZXRLZXlGcm9tRW5jcnlwdGVkUEtDUzhQRU06ZnVuY3Rpb24ocyxxKXt2YXIgcD10aGlzLl9nZXRQbGFpblBLQ1M4SGV4RnJvbUVuY3J5cHRlZFBLQ1M4UEVNKHMscSk7dmFyIHI9dGhpcy5nZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhIZXgocCk7cmV0dXJuIHJ9LHBhcnNlUGxhaW5Qcml2YXRlUEtDUzhIZXg6ZnVuY3Rpb24ocyl7dmFyIHY9QVNOMUhFWDt2YXIgdT12LmdldENoaWxkSWR4O3ZhciB0PXYuZ2V0Vjt2YXIgcT17fTtxLmFsZ3BhcmFtPW51bGw7aWYocy5zdWJzdHIoMCwyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIHBsYWluIFBLQ1M4IHByaXZhdGUga2V5KGNvZGU6MDAxKVwifXZhciByPXUocywwKTtpZihyLmxlbmd0aCE9Myl7dGhyb3dcIm1hbGZvcm1lZCBwbGFpbiBQS0NTOCBwcml2YXRlIGtleShjb2RlOjAwMilcIn1pZihzLnN1YnN0cihyWzFdLDIpIT1cIjMwXCIpe3Rocm93XCJtYWxmb3JtZWQgUEtDUzggcHJpdmF0ZSBrZXkoY29kZTowMDMpXCJ9dmFyIHA9dShzLHJbMV0pO2lmKHAubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHByaXZhdGUga2V5KGNvZGU6MDA0KVwifWlmKHMuc3Vic3RyKHBbMF0sMikhPVwiMDZcIil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwcml2YXRlIGtleShjb2RlOjAwNSlcIn1xLmFsZ29pZD10KHMscFswXSk7aWYocy5zdWJzdHIocFsxXSwyKT09XCIwNlwiKXtxLmFsZ3BhcmFtPXQocyxwWzFdKX1pZihzLnN1YnN0cihyWzJdLDIpIT1cIjA0XCIpe3Rocm93XCJtYWxmb3JtZWQgUEtDUzggcHJpdmF0ZSBrZXkoY29kZTowMDYpXCJ9cS5rZXlpZHg9di5nZXRWaWR4KHMsclsyXSk7cmV0dXJuIHF9LGdldEtleUZyb21QbGFpblByaXZhdGVQS0NTOFBFTTpmdW5jdGlvbihxKXt2YXIgcD1wZW10b2hleChxLFwiUFJJVkFURSBLRVlcIik7dmFyIHI9dGhpcy5nZXRLZXlGcm9tUGxhaW5Qcml2YXRlUEtDUzhIZXgocCk7cmV0dXJuIHJ9LGdldEtleUZyb21QbGFpblByaXZhdGVQS0NTOEhleDpmdW5jdGlvbihwKXt2YXIgcT10aGlzLnBhcnNlUGxhaW5Qcml2YXRlUEtDUzhIZXgocCk7dmFyIHI7aWYocS5hbGdvaWQ9PVwiMmE4NjQ4ODZmNzBkMDEwMTAxXCIpe3I9bmV3IFJTQUtleSgpfWVsc2V7aWYocS5hbGdvaWQ9PVwiMmE4NjQ4Y2UzODA0MDFcIil7cj1uZXcgS0pVUi5jcnlwdG8uRFNBKCl9ZWxzZXtpZihxLmFsZ29pZD09XCIyYTg2NDhjZTNkMDIwMVwiKXtyPW5ldyBLSlVSLmNyeXB0by5FQ0RTQSgpfWVsc2V7dGhyb3dcInVuc3VwcG9ydGVkIHByaXZhdGUga2V5IGFsZ29yaXRobVwifX19ci5yZWFkUEtDUzhQcnZLZXlIZXgocCk7cmV0dXJuIHJ9LF9nZXRLZXlGcm9tUHVibGljUEtDUzhIZXg6ZnVuY3Rpb24ocSl7dmFyIHA7dmFyIHI9QVNOMUhFWC5nZXRWYnlMaXN0KHEsMCxbMCwwXSxcIjA2XCIpO2lmKHI9PT1cIjJhODY0ODg2ZjcwZDAxMDEwMVwiKXtwPW5ldyBSU0FLZXkoKX1lbHNle2lmKHI9PT1cIjJhODY0OGNlMzgwNDAxXCIpe3A9bmV3IEtKVVIuY3J5cHRvLkRTQSgpfWVsc2V7aWYocj09PVwiMmE4NjQ4Y2UzZDAyMDFcIil7cD1uZXcgS0pVUi5jcnlwdG8uRUNEU0EoKX1lbHNle3Rocm93XCJ1bnN1cHBvcnRlZCBQS0NTIzggcHVibGljIGtleSBoZXhcIn19fXAucmVhZFBLQ1M4UHViS2V5SGV4KHEpO3JldHVybiBwfSxwYXJzZVB1YmxpY1Jhd1JTQUtleUhleDpmdW5jdGlvbihyKXt2YXIgdT1BU04xSEVYO3ZhciB0PXUuZ2V0Q2hpbGRJZHg7dmFyIHM9dS5nZXRWO3ZhciBwPXt9O2lmKHIuc3Vic3RyKDAsMikhPVwiMzBcIil7dGhyb3dcIm1hbGZvcm1lZCBSU0Ega2V5KGNvZGU6MDAxKVwifXZhciBxPXQociwwKTtpZihxLmxlbmd0aCE9Mil7dGhyb3dcIm1hbGZvcm1lZCBSU0Ega2V5KGNvZGU6MDAyKVwifWlmKHIuc3Vic3RyKHFbMF0sMikhPVwiMDJcIil7dGhyb3dcIm1hbGZvcm1lZCBSU0Ega2V5KGNvZGU6MDAzKVwifXAubj1zKHIscVswXSk7aWYoci5zdWJzdHIocVsxXSwyKSE9XCIwMlwiKXt0aHJvd1wibWFsZm9ybWVkIFJTQSBrZXkoY29kZTowMDQpXCJ9cC5lPXMocixxWzFdKTtyZXR1cm4gcH0scGFyc2VQdWJsaWNQS0NTOEhleDpmdW5jdGlvbih0KXt2YXIgdj1BU04xSEVYO3ZhciB1PXYuZ2V0Q2hpbGRJZHg7dmFyIHM9di5nZXRWO3ZhciBxPXt9O3EuYWxncGFyYW09bnVsbDt2YXIgcj11KHQsMCk7aWYoci5sZW5ndGghPTIpe3Rocm93XCJvdXRlciBERVJTZXF1ZW5jZSBzaGFsbCBoYXZlIDIgZWxlbWVudHM6IFwiK3IubGVuZ3RofXZhciB3PXJbMF07aWYodC5zdWJzdHIodywyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHB1YmxpYyBrZXkoY29kZTowMDEpXCJ9dmFyIHA9dSh0LHcpO2lmKHAubGVuZ3RoIT0yKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHB1YmxpYyBrZXkoY29kZTowMDIpXCJ9aWYodC5zdWJzdHIocFswXSwyKSE9XCIwNlwiKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1M4IHB1YmxpYyBrZXkoY29kZTowMDMpXCJ9cS5hbGdvaWQ9cyh0LHBbMF0pO2lmKHQuc3Vic3RyKHBbMV0sMik9PVwiMDZcIil7cS5hbGdwYXJhbT1zKHQscFsxXSl9ZWxzZXtpZih0LnN1YnN0cihwWzFdLDIpPT1cIjMwXCIpe3EuYWxncGFyYW09e307cS5hbGdwYXJhbS5wPXYuZ2V0VmJ5TGlzdCh0LHBbMV0sWzBdLFwiMDJcIik7cS5hbGdwYXJhbS5xPXYuZ2V0VmJ5TGlzdCh0LHBbMV0sWzFdLFwiMDJcIik7cS5hbGdwYXJhbS5nPXYuZ2V0VmJ5TGlzdCh0LHBbMV0sWzJdLFwiMDJcIil9fWlmKHQuc3Vic3RyKHJbMV0sMikhPVwiMDNcIil7dGhyb3dcIm1hbGZvcm1lZCBQS0NTOCBwdWJsaWMga2V5KGNvZGU6MDA0KVwifXEua2V5PXModCxyWzFdKS5zdWJzdHIoMik7cmV0dXJuIHF9LH19KCk7S0VZVVRJTC5nZXRLZXk9ZnVuY3Rpb24obCxrLG4pe3ZhciBHPUFTTjFIRVgsTD1HLmdldENoaWxkSWR4LHY9Ry5nZXRWLGQ9Ry5nZXRWYnlMaXN0LGM9S0pVUi5jcnlwdG8saT1jLkVDRFNBLEM9Yy5EU0Esdz1SU0FLZXksTT1wZW10b2hleCxGPUtFWVVUSUw7aWYodHlwZW9mIHchPVwidW5kZWZpbmVkXCImJmwgaW5zdGFuY2VvZiB3KXtyZXR1cm4gbH1pZih0eXBlb2YgaSE9XCJ1bmRlZmluZWRcIiYmbCBpbnN0YW5jZW9mIGkpe3JldHVybiBsfWlmKHR5cGVvZiBDIT1cInVuZGVmaW5lZFwiJiZsIGluc3RhbmNlb2YgQyl7cmV0dXJuIGx9aWYobC5jdXJ2ZSE9PXVuZGVmaW5lZCYmbC54eSE9PXVuZGVmaW5lZCYmbC5kPT09dW5kZWZpbmVkKXtyZXR1cm4gbmV3IGkoe3B1YjpsLnh5LGN1cnZlOmwuY3VydmV9KX1pZihsLmN1cnZlIT09dW5kZWZpbmVkJiZsLmQhPT11bmRlZmluZWQpe3JldHVybiBuZXcgaSh7cHJ2OmwuZCxjdXJ2ZTpsLmN1cnZlfSl9aWYobC5rdHk9PT11bmRlZmluZWQmJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQ9PT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQdWJsaWMobC5uLGwuZSk7cmV0dXJuIFB9aWYobC5rdHk9PT11bmRlZmluZWQmJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQhPT11bmRlZmluZWQmJmwucCE9PXVuZGVmaW5lZCYmbC5xIT09dW5kZWZpbmVkJiZsLmRwIT09dW5kZWZpbmVkJiZsLmRxIT09dW5kZWZpbmVkJiZsLmNvIT09dW5kZWZpbmVkJiZsLnFpPT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgdygpO1Auc2V0UHJpdmF0ZUV4KGwubixsLmUsbC5kLGwucCxsLnEsbC5kcCxsLmRxLGwuY28pO3JldHVybiBQfWlmKGwua3R5PT09dW5kZWZpbmVkJiZsLm4hPT11bmRlZmluZWQmJmwuZSE9PXVuZGVmaW5lZCYmbC5kIT09dW5kZWZpbmVkJiZsLnA9PT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQcml2YXRlKGwubixsLmUsbC5kKTtyZXR1cm4gUH1pZihsLnAhPT11bmRlZmluZWQmJmwucSE9PXVuZGVmaW5lZCYmbC5nIT09dW5kZWZpbmVkJiZsLnkhPT11bmRlZmluZWQmJmwueD09PXVuZGVmaW5lZCl7dmFyIFA9bmV3IEMoKTtQLnNldFB1YmxpYyhsLnAsbC5xLGwuZyxsLnkpO3JldHVybiBQfWlmKGwucCE9PXVuZGVmaW5lZCYmbC5xIT09dW5kZWZpbmVkJiZsLmchPT11bmRlZmluZWQmJmwueSE9PXVuZGVmaW5lZCYmbC54IT09dW5kZWZpbmVkKXt2YXIgUD1uZXcgQygpO1Auc2V0UHJpdmF0ZShsLnAsbC5xLGwuZyxsLnksbC54KTtyZXR1cm4gUH1pZihsLmt0eT09PVwiUlNBXCImJmwubiE9PXVuZGVmaW5lZCYmbC5lIT09dW5kZWZpbmVkJiZsLmQ9PT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQdWJsaWMoYjY0dXRvaGV4KGwubiksYjY0dXRvaGV4KGwuZSkpO3JldHVybiBQfWlmKGwua3R5PT09XCJSU0FcIiYmbC5uIT09dW5kZWZpbmVkJiZsLmUhPT11bmRlZmluZWQmJmwuZCE9PXVuZGVmaW5lZCYmbC5wIT09dW5kZWZpbmVkJiZsLnEhPT11bmRlZmluZWQmJmwuZHAhPT11bmRlZmluZWQmJmwuZHEhPT11bmRlZmluZWQmJmwucWkhPT11bmRlZmluZWQpe3ZhciBQPW5ldyB3KCk7UC5zZXRQcml2YXRlRXgoYjY0dXRvaGV4KGwubiksYjY0dXRvaGV4KGwuZSksYjY0dXRvaGV4KGwuZCksYjY0dXRvaGV4KGwucCksYjY0dXRvaGV4KGwucSksYjY0dXRvaGV4KGwuZHApLGI2NHV0b2hleChsLmRxKSxiNjR1dG9oZXgobC5xaSkpO3JldHVybiBQfWlmKGwua3R5PT09XCJSU0FcIiYmbC5uIT09dW5kZWZpbmVkJiZsLmUhPT11bmRlZmluZWQmJmwuZCE9PXVuZGVmaW5lZCl7dmFyIFA9bmV3IHcoKTtQLnNldFByaXZhdGUoYjY0dXRvaGV4KGwubiksYjY0dXRvaGV4KGwuZSksYjY0dXRvaGV4KGwuZCkpO3JldHVybiBQfWlmKGwua3R5PT09XCJFQ1wiJiZsLmNydiE9PXVuZGVmaW5lZCYmbC54IT09dW5kZWZpbmVkJiZsLnkhPT11bmRlZmluZWQmJmwuZD09PXVuZGVmaW5lZCl7dmFyIGo9bmV3IGkoe2N1cnZlOmwuY3J2fSk7dmFyIHQ9ai5lY3BhcmFtcy5rZXlsZW4vNDt2YXIgQj0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueCkpLnNsaWNlKC10KTt2YXIgej0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueSkpLnNsaWNlKC10KTt2YXIgdT1cIjA0XCIrQit6O2ouc2V0UHVibGljS2V5SGV4KHUpO3JldHVybiBqfWlmKGwua3R5PT09XCJFQ1wiJiZsLmNydiE9PXVuZGVmaW5lZCYmbC54IT09dW5kZWZpbmVkJiZsLnkhPT11bmRlZmluZWQmJmwuZCE9PXVuZGVmaW5lZCl7dmFyIGo9bmV3IGkoe2N1cnZlOmwuY3J2fSk7dmFyIHQ9ai5lY3BhcmFtcy5rZXlsZW4vNDt2YXIgQj0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueCkpLnNsaWNlKC10KTt2YXIgej0oXCIwMDAwMDAwMDAwXCIrYjY0dXRvaGV4KGwueSkpLnNsaWNlKC10KTt2YXIgdT1cIjA0XCIrQit6O3ZhciBiPShcIjAwMDAwMDAwMDBcIitiNjR1dG9oZXgobC5kKSkuc2xpY2UoLXQpO2ouc2V0UHVibGljS2V5SGV4KHUpO2ouc2V0UHJpdmF0ZUtleUhleChiKTtyZXR1cm4gan1pZihuPT09XCJwa2NzNXBydlwiKXt2YXIgSj1sLEc9QVNOMUhFWCxOLFA7Tj1MKEosMCk7aWYoTi5sZW5ndGg9PT05KXtQPW5ldyB3KCk7UC5yZWFkUEtDUzVQcnZLZXlIZXgoSil9ZWxzZXtpZihOLmxlbmd0aD09PTYpe1A9bmV3IEMoKTtQLnJlYWRQS0NTNVBydktleUhleChKKX1lbHNle2lmKE4ubGVuZ3RoPjImJkouc3Vic3RyKE5bMV0sMik9PT1cIjA0XCIpe1A9bmV3IGkoKTtQLnJlYWRQS0NTNVBydktleUhleChKKX1lbHNle3Rocm93XCJ1bnN1cHBvcnRlZCBQS0NTIzEvNSBoZXhhZGVjaW1hbCBrZXlcIn19fXJldHVybiBQfWlmKG49PT1cInBrY3M4cHJ2XCIpe3ZhciBQPUYuZ2V0S2V5RnJvbVBsYWluUHJpdmF0ZVBLQ1M4SGV4KGwpO3JldHVybiBQfWlmKG49PT1cInBrY3M4cHViXCIpe3JldHVybiBGLl9nZXRLZXlGcm9tUHVibGljUEtDUzhIZXgobCl9aWYobj09PVwieDUwOXB1YlwiKXtyZXR1cm4gWDUwOS5nZXRQdWJsaWNLZXlGcm9tQ2VydEhleChsKX1pZihsLmluZGV4T2YoXCItRU5EIENFUlRJRklDQVRFLVwiLDApIT0tMXx8bC5pbmRleE9mKFwiLUVORCBYNTA5IENFUlRJRklDQVRFLVwiLDApIT0tMXx8bC5pbmRleE9mKFwiLUVORCBUUlVTVEVEIENFUlRJRklDQVRFLVwiLDApIT0tMSl7cmV0dXJuIFg1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRQRU0obCl9aWYobC5pbmRleE9mKFwiLUVORCBQVUJMSUMgS0VZLVwiKSE9LTEpe3ZhciBPPXBlbXRvaGV4KGwsXCJQVUJMSUMgS0VZXCIpO3JldHVybiBGLl9nZXRLZXlGcm9tUHVibGljUEtDUzhIZXgoTyl9aWYobC5pbmRleE9mKFwiLUVORCBSU0EgUFJJVkFURSBLRVktXCIpIT0tMSYmbC5pbmRleE9mKFwiNCxFTkNSWVBURURcIik9PS0xKXt2YXIgbT1NKGwsXCJSU0EgUFJJVkFURSBLRVlcIik7cmV0dXJuIEYuZ2V0S2V5KG0sbnVsbCxcInBrY3M1cHJ2XCIpfWlmKGwuaW5kZXhPZihcIi1FTkQgRFNBIFBSSVZBVEUgS0VZLVwiKSE9LTEmJmwuaW5kZXhPZihcIjQsRU5DUllQVEVEXCIpPT0tMSl7dmFyIEk9TShsLFwiRFNBIFBSSVZBVEUgS0VZXCIpO3ZhciBFPWQoSSwwLFsxXSxcIjAyXCIpO3ZhciBEPWQoSSwwLFsyXSxcIjAyXCIpO3ZhciBLPWQoSSwwLFszXSxcIjAyXCIpO3ZhciByPWQoSSwwLFs0XSxcIjAyXCIpO3ZhciBzPWQoSSwwLFs1XSxcIjAyXCIpO3ZhciBQPW5ldyBDKCk7UC5zZXRQcml2YXRlKG5ldyBCaWdJbnRlZ2VyKEUsMTYpLG5ldyBCaWdJbnRlZ2VyKEQsMTYpLG5ldyBCaWdJbnRlZ2VyKEssMTYpLG5ldyBCaWdJbnRlZ2VyKHIsMTYpLG5ldyBCaWdJbnRlZ2VyKHMsMTYpKTtyZXR1cm4gUH1pZihsLmluZGV4T2YoXCItRU5EIFBSSVZBVEUgS0VZLVwiKSE9LTEpe3JldHVybiBGLmdldEtleUZyb21QbGFpblByaXZhdGVQS0NTOFBFTShsKX1pZihsLmluZGV4T2YoXCItRU5EIFJTQSBQUklWQVRFIEtFWS1cIikhPS0xJiZsLmluZGV4T2YoXCI0LEVOQ1JZUFRFRFwiKSE9LTEpe3ZhciBvPUYuZ2V0RGVjcnlwdGVkS2V5SGV4KGwsayk7dmFyIEg9bmV3IFJTQUtleSgpO0gucmVhZFBLQ1M1UHJ2S2V5SGV4KG8pO3JldHVybiBIfWlmKGwuaW5kZXhPZihcIi1FTkQgRUMgUFJJVkFURSBLRVktXCIpIT0tMSYmbC5pbmRleE9mKFwiNCxFTkNSWVBURURcIikhPS0xKXt2YXIgST1GLmdldERlY3J5cHRlZEtleUhleChsLGspO3ZhciBQPWQoSSwwLFsxXSxcIjA0XCIpO3ZhciBmPWQoSSwwLFsyLDBdLFwiMDZcIik7dmFyIEE9ZChJLDAsWzMsMF0sXCIwM1wiKS5zdWJzdHIoMik7dmFyIGU9XCJcIjtpZihLSlVSLmNyeXB0by5PSUQub2lkaGV4Mm5hbWVbZl0hPT11bmRlZmluZWQpe2U9S0pVUi5jcnlwdG8uT0lELm9pZGhleDJuYW1lW2ZdfWVsc2V7dGhyb3dcInVuZGVmaW5lZCBPSUQoaGV4KSBpbiBLSlVSLmNyeXB0by5PSUQ6IFwiK2Z9dmFyIGo9bmV3IGkoe2N1cnZlOmV9KTtqLnNldFB1YmxpY0tleUhleChBKTtqLnNldFByaXZhdGVLZXlIZXgoUCk7ai5pc1B1YmxpYz1mYWxzZTtyZXR1cm4gan1pZihsLmluZGV4T2YoXCItRU5EIERTQSBQUklWQVRFIEtFWS1cIikhPS0xJiZsLmluZGV4T2YoXCI0LEVOQ1JZUFRFRFwiKSE9LTEpe3ZhciBJPUYuZ2V0RGVjcnlwdGVkS2V5SGV4KGwsayk7dmFyIEU9ZChJLDAsWzFdLFwiMDJcIik7dmFyIEQ9ZChJLDAsWzJdLFwiMDJcIik7dmFyIEs9ZChJLDAsWzNdLFwiMDJcIik7dmFyIHI9ZChJLDAsWzRdLFwiMDJcIik7dmFyIHM9ZChJLDAsWzVdLFwiMDJcIik7dmFyIFA9bmV3IEMoKTtQLnNldFByaXZhdGUobmV3IEJpZ0ludGVnZXIoRSwxNiksbmV3IEJpZ0ludGVnZXIoRCwxNiksbmV3IEJpZ0ludGVnZXIoSywxNiksbmV3IEJpZ0ludGVnZXIociwxNiksbmV3IEJpZ0ludGVnZXIocywxNikpO3JldHVybiBQfWlmKGwuaW5kZXhPZihcIi1FTkQgRU5DUllQVEVEIFBSSVZBVEUgS0VZLVwiKSE9LTEpe3JldHVybiBGLmdldEtleUZyb21FbmNyeXB0ZWRQS0NTOFBFTShsLGspfXRocm93XCJub3Qgc3VwcG9ydGVkIGFyZ3VtZW50XCJ9O0tFWVVUSUwuZ2VuZXJhdGVLZXlwYWlyPWZ1bmN0aW9uKGEsYyl7aWYoYT09XCJSU0FcIil7dmFyIGI9Yzt2YXIgaD1uZXcgUlNBS2V5KCk7aC5nZW5lcmF0ZShiLFwiMTAwMDFcIik7aC5pc1ByaXZhdGU9dHJ1ZTtoLmlzUHVibGljPXRydWU7dmFyIGY9bmV3IFJTQUtleSgpO3ZhciBlPWgubi50b1N0cmluZygxNik7dmFyIGk9aC5lLnRvU3RyaW5nKDE2KTtmLnNldFB1YmxpYyhlLGkpO2YuaXNQcml2YXRlPWZhbHNlO2YuaXNQdWJsaWM9dHJ1ZTt2YXIgaz17fTtrLnBydktleU9iaj1oO2sucHViS2V5T2JqPWY7cmV0dXJuIGt9ZWxzZXtpZihhPT1cIkVDXCIpe3ZhciBkPWM7dmFyIGc9bmV3IEtKVVIuY3J5cHRvLkVDRFNBKHtjdXJ2ZTpkfSk7dmFyIGo9Zy5nZW5lcmF0ZUtleVBhaXJIZXgoKTt2YXIgaD1uZXcgS0pVUi5jcnlwdG8uRUNEU0Eoe2N1cnZlOmR9KTtoLnNldFB1YmxpY0tleUhleChqLmVjcHViaGV4KTtoLnNldFByaXZhdGVLZXlIZXgoai5lY3BydmhleCk7aC5pc1ByaXZhdGU9dHJ1ZTtoLmlzUHVibGljPWZhbHNlO3ZhciBmPW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6ZH0pO2Yuc2V0UHVibGljS2V5SGV4KGouZWNwdWJoZXgpO2YuaXNQcml2YXRlPWZhbHNlO2YuaXNQdWJsaWM9dHJ1ZTt2YXIgaz17fTtrLnBydktleU9iaj1oO2sucHViS2V5T2JqPWY7cmV0dXJuIGt9ZWxzZXt0aHJvd1widW5rbm93biBhbGdvcml0aG06IFwiK2F9fX07S0VZVVRJTC5nZXRQRU09ZnVuY3Rpb24oYixELHksbSxxLGope3ZhciBGPUtKVVIsaz1GLmFzbjEsej1rLkRFUk9iamVjdElkZW50aWZpZXIsZj1rLkRFUkludGVnZXIsbD1rLkFTTjFVdGlsLm5ld09iamVjdCxhPWsueDUwOSxDPWEuU3ViamVjdFB1YmxpY0tleUluZm8sZT1GLmNyeXB0byx1PWUuRFNBLHI9ZS5FQ0RTQSxuPVJTQUtleTtmdW5jdGlvbiBBKHMpe3ZhciBHPWwoe3NlcTpbe1wiaW50XCI6MH0se1wiaW50XCI6e2JpZ2ludDpzLm59fSx7XCJpbnRcIjpzLmV9LHtcImludFwiOntiaWdpbnQ6cy5kfX0se1wiaW50XCI6e2JpZ2ludDpzLnB9fSx7XCJpbnRcIjp7YmlnaW50OnMucX19LHtcImludFwiOntiaWdpbnQ6cy5kbXAxfX0se1wiaW50XCI6e2JpZ2ludDpzLmRtcTF9fSx7XCJpbnRcIjp7YmlnaW50OnMuY29lZmZ9fV19KTtyZXR1cm4gR31mdW5jdGlvbiBCKEcpe3ZhciBzPWwoe3NlcTpbe1wiaW50XCI6MX0se29jdHN0cjp7aGV4OkcucHJ2S2V5SGV4fX0se3RhZzpbXCJhMFwiLHRydWUse29pZDp7bmFtZTpHLmN1cnZlTmFtZX19XX0se3RhZzpbXCJhMVwiLHRydWUse2JpdHN0cjp7aGV4OlwiMDBcIitHLnB1YktleUhleH19XX1dfSk7cmV0dXJuIHN9ZnVuY3Rpb24geChzKXt2YXIgRz1sKHtzZXE6W3tcImludFwiOjB9LHtcImludFwiOntiaWdpbnQ6cy5wfX0se1wiaW50XCI6e2JpZ2ludDpzLnF9fSx7XCJpbnRcIjp7YmlnaW50OnMuZ319LHtcImludFwiOntiaWdpbnQ6cy55fX0se1wiaW50XCI6e2JpZ2ludDpzLnh9fV19KTtyZXR1cm4gR31pZigoKG4hPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiBuKXx8KHUhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiB1KXx8KHIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByKSkmJmIuaXNQdWJsaWM9PXRydWUmJihEPT09dW5kZWZpbmVkfHxEPT1cIlBLQ1M4UFVCXCIpKXt2YXIgRT1uZXcgQyhiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtyZXR1cm4gaGV4dG9wZW0odyxcIlBVQkxJQyBLRVlcIil9aWYoRD09XCJQS0NTMVBSVlwiJiZuIT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgbiYmKHk9PT11bmRlZmluZWR8fHk9PW51bGwpJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIEU9QShiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtyZXR1cm4gaGV4dG9wZW0odyxcIlJTQSBQUklWQVRFIEtFWVwiKX1pZihEPT1cIlBLQ1MxUFJWXCImJnIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByJiYoeT09PXVuZGVmaW5lZHx8eT09bnVsbCkmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgaT1uZXcgeih7bmFtZTpiLmN1cnZlTmFtZX0pO3ZhciB2PWkuZ2V0RW5jb2RlZEhleCgpO3ZhciBoPUIoYik7dmFyIHQ9aC5nZXRFbmNvZGVkSGV4KCk7dmFyIHA9XCJcIjtwKz1oZXh0b3BlbSh2LFwiRUMgUEFSQU1FVEVSU1wiKTtwKz1oZXh0b3BlbSh0LFwiRUMgUFJJVkFURSBLRVlcIik7cmV0dXJuIHB9aWYoRD09XCJQS0NTMVBSVlwiJiZ1IT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgdSYmKHk9PT11bmRlZmluZWR8fHk9PW51bGwpJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIEU9eChiKTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtyZXR1cm4gaGV4dG9wZW0odyxcIkRTQSBQUklWQVRFIEtFWVwiKX1pZihEPT1cIlBLQ1M1UFJWXCImJm4hPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiBuJiYoeSE9PXVuZGVmaW5lZCYmeSE9bnVsbCkmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgRT1BKGIpO3ZhciB3PUUuZ2V0RW5jb2RlZEhleCgpO2lmKG09PT11bmRlZmluZWQpe209XCJERVMtRURFMy1DQkNcIn1yZXR1cm4gdGhpcy5nZXRFbmNyeXB0ZWRQS0NTNVBFTUZyb21QcnZLZXlIZXgoXCJSU0FcIix3LHksbSxqKX1pZihEPT1cIlBLQ1M1UFJWXCImJnIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByJiYoeSE9PXVuZGVmaW5lZCYmeSE9bnVsbCkmJmIuaXNQcml2YXRlPT10cnVlKXt2YXIgRT1CKGIpO3ZhciB3PUUuZ2V0RW5jb2RlZEhleCgpO2lmKG09PT11bmRlZmluZWQpe209XCJERVMtRURFMy1DQkNcIn1yZXR1cm4gdGhpcy5nZXRFbmNyeXB0ZWRQS0NTNVBFTUZyb21QcnZLZXlIZXgoXCJFQ1wiLHcseSxtLGopfWlmKEQ9PVwiUEtDUzVQUlZcIiYmdSE9PXVuZGVmaW5lZCYmYiBpbnN0YW5jZW9mIHUmJih5IT09dW5kZWZpbmVkJiZ5IT1udWxsKSYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBFPXgoYik7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7aWYobT09PXVuZGVmaW5lZCl7bT1cIkRFUy1FREUzLUNCQ1wifXJldHVybiB0aGlzLmdldEVuY3J5cHRlZFBLQ1M1UEVNRnJvbVBydktleUhleChcIkRTQVwiLHcseSxtLGopfXZhciBvPWZ1bmN0aW9uKEcscyl7dmFyIEk9YyhHLHMpO3ZhciBIPW5ldyBsKHtzZXE6W3tzZXE6W3tvaWQ6e25hbWU6XCJwa2NzNVBCRVMyXCJ9fSx7c2VxOlt7c2VxOlt7b2lkOntuYW1lOlwicGtjczVQQktERjJcIn19LHtzZXE6W3tvY3RzdHI6e2hleDpJLnBia2RmMlNhbHR9fSx7XCJpbnRcIjpJLnBia2RmMkl0ZXJ9XX1dfSx7c2VxOlt7b2lkOntuYW1lOlwiZGVzLUVERTMtQ0JDXCJ9fSx7b2N0c3RyOntoZXg6SS5lbmNyeXB0aW9uU2NoZW1lSVZ9fV19XX1dfSx7b2N0c3RyOntoZXg6SS5jaXBoZXJ0ZXh0fX1dfSk7cmV0dXJuIEguZ2V0RW5jb2RlZEhleCgpfTt2YXIgYz1mdW5jdGlvbihOLE8pe3ZhciBIPTEwMDt2YXIgTT1DcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSg4KTt2YXIgTD1cIkRFUy1FREUzLUNCQ1wiO3ZhciBzPUNyeXB0b0pTLmxpYi5Xb3JkQXJyYXkucmFuZG9tKDgpO3ZhciBJPUNyeXB0b0pTLlBCS0RGMihPLE0se2tleVNpemU6MTkyLzMyLGl0ZXJhdGlvbnM6SH0pO3ZhciBKPUNyeXB0b0pTLmVuYy5IZXgucGFyc2UoTik7dmFyIEs9Q3J5cHRvSlMuVHJpcGxlREVTLmVuY3J5cHQoSixJLHtpdjpzfSkrXCJcIjt2YXIgRz17fTtHLmNpcGhlcnRleHQ9SztHLnBia2RmMlNhbHQ9Q3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkoTSk7Ry5wYmtkZjJJdGVyPUg7Ry5lbmNyeXB0aW9uU2NoZW1lQWxnPUw7Ry5lbmNyeXB0aW9uU2NoZW1lSVY9Q3J5cHRvSlMuZW5jLkhleC5zdHJpbmdpZnkocyk7cmV0dXJuIEd9O2lmKEQ9PVwiUEtDUzhQUlZcIiYmbiE9dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgbiYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBnPUEoYik7dmFyIGQ9Zy5nZXRFbmNvZGVkSGV4KCk7dmFyIEU9bCh7c2VxOlt7XCJpbnRcIjowfSx7c2VxOlt7b2lkOntuYW1lOlwicnNhRW5jcnlwdGlvblwifX0se1wibnVsbFwiOnRydWV9XX0se29jdHN0cjp7aGV4OmR9fV19KTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtpZih5PT09dW5kZWZpbmVkfHx5PT1udWxsKXtyZXR1cm4gaGV4dG9wZW0odyxcIlBSSVZBVEUgS0VZXCIpfWVsc2V7dmFyIHQ9byh3LHkpO3JldHVybiBoZXh0b3BlbSh0LFwiRU5DUllQVEVEIFBSSVZBVEUgS0VZXCIpfX1pZihEPT1cIlBLQ1M4UFJWXCImJnIhPT11bmRlZmluZWQmJmIgaW5zdGFuY2VvZiByJiZiLmlzUHJpdmF0ZT09dHJ1ZSl7dmFyIGc9bmV3IGwoe3NlcTpbe1wiaW50XCI6MX0se29jdHN0cjp7aGV4OmIucHJ2S2V5SGV4fX0se3RhZzpbXCJhMVwiLHRydWUse2JpdHN0cjp7aGV4OlwiMDBcIitiLnB1YktleUhleH19XX1dfSk7dmFyIGQ9Zy5nZXRFbmNvZGVkSGV4KCk7dmFyIEU9bCh7c2VxOlt7XCJpbnRcIjowfSx7c2VxOlt7b2lkOntuYW1lOlwiZWNQdWJsaWNLZXlcIn19LHtvaWQ6e25hbWU6Yi5jdXJ2ZU5hbWV9fV19LHtvY3RzdHI6e2hleDpkfX1dfSk7dmFyIHc9RS5nZXRFbmNvZGVkSGV4KCk7aWYoeT09PXVuZGVmaW5lZHx8eT09bnVsbCl7cmV0dXJuIGhleHRvcGVtKHcsXCJQUklWQVRFIEtFWVwiKX1lbHNle3ZhciB0PW8odyx5KTtyZXR1cm4gaGV4dG9wZW0odCxcIkVOQ1JZUFRFRCBQUklWQVRFIEtFWVwiKX19aWYoRD09XCJQS0NTOFBSVlwiJiZ1IT09dW5kZWZpbmVkJiZiIGluc3RhbmNlb2YgdSYmYi5pc1ByaXZhdGU9PXRydWUpe3ZhciBnPW5ldyBmKHtiaWdpbnQ6Yi54fSk7dmFyIGQ9Zy5nZXRFbmNvZGVkSGV4KCk7dmFyIEU9bCh7c2VxOlt7XCJpbnRcIjowfSx7c2VxOlt7b2lkOntuYW1lOlwiZHNhXCJ9fSx7c2VxOlt7XCJpbnRcIjp7YmlnaW50OmIucH19LHtcImludFwiOntiaWdpbnQ6Yi5xfX0se1wiaW50XCI6e2JpZ2ludDpiLmd9fV19XX0se29jdHN0cjp7aGV4OmR9fV19KTt2YXIgdz1FLmdldEVuY29kZWRIZXgoKTtpZih5PT09dW5kZWZpbmVkfHx5PT1udWxsKXtyZXR1cm4gaGV4dG9wZW0odyxcIlBSSVZBVEUgS0VZXCIpfWVsc2V7dmFyIHQ9byh3LHkpO3JldHVybiBoZXh0b3BlbSh0LFwiRU5DUllQVEVEIFBSSVZBVEUgS0VZXCIpfX10aHJvd1widW5zdXBwb3J0ZWQgb2JqZWN0IG5vciBmb3JtYXRcIn07S0VZVVRJTC5nZXRLZXlGcm9tQ1NSUEVNPWZ1bmN0aW9uKGIpe3ZhciBhPXBlbXRvaGV4KGIsXCJDRVJUSUZJQ0FURSBSRVFVRVNUXCIpO3ZhciBjPUtFWVVUSUwuZ2V0S2V5RnJvbUNTUkhleChhKTtyZXR1cm4gY307S0VZVVRJTC5nZXRLZXlGcm9tQ1NSSGV4PWZ1bmN0aW9uKGEpe3ZhciBjPUtFWVVUSUwucGFyc2VDU1JIZXgoYSk7dmFyIGI9S0VZVVRJTC5nZXRLZXkoYy5wOHB1YmtleWhleCxudWxsLFwicGtjczhwdWJcIik7cmV0dXJuIGJ9O0tFWVVUSUwucGFyc2VDU1JIZXg9ZnVuY3Rpb24oZCl7dmFyIGk9QVNOMUhFWDt2YXIgZj1pLmdldENoaWxkSWR4O3ZhciBjPWkuZ2V0VExWO3ZhciBiPXt9O3ZhciBnPWQ7aWYoZy5zdWJzdHIoMCwyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIENTUihjb2RlOjAwMSlcIn12YXIgZT1mKGcsMCk7aWYoZS5sZW5ndGg8MSl7dGhyb3dcIm1hbGZvcm1lZCBDU1IoY29kZTowMDIpXCJ9aWYoZy5zdWJzdHIoZVswXSwyKSE9XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIENTUihjb2RlOjAwMylcIn12YXIgYT1mKGcsZVswXSk7aWYoYS5sZW5ndGg8Myl7dGhyb3dcIm1hbGZvcm1lZCBDU1IoY29kZTowMDQpXCJ9Yi5wOHB1YmtleWhleD1jKGcsYVsyXSk7cmV0dXJuIGJ9O0tFWVVUSUwuZ2V0SldLRnJvbUtleT1mdW5jdGlvbihkKXt2YXIgYj17fTtpZihkIGluc3RhbmNlb2YgUlNBS2V5JiZkLmlzUHJpdmF0ZSl7Yi5rdHk9XCJSU0FcIjtiLm49aGV4dG9iNjR1KGQubi50b1N0cmluZygxNikpO2IuZT1oZXh0b2I2NHUoZC5lLnRvU3RyaW5nKDE2KSk7Yi5kPWhleHRvYjY0dShkLmQudG9TdHJpbmcoMTYpKTtiLnA9aGV4dG9iNjR1KGQucC50b1N0cmluZygxNikpO2IucT1oZXh0b2I2NHUoZC5xLnRvU3RyaW5nKDE2KSk7Yi5kcD1oZXh0b2I2NHUoZC5kbXAxLnRvU3RyaW5nKDE2KSk7Yi5kcT1oZXh0b2I2NHUoZC5kbXExLnRvU3RyaW5nKDE2KSk7Yi5xaT1oZXh0b2I2NHUoZC5jb2VmZi50b1N0cmluZygxNikpO3JldHVybiBifWVsc2V7aWYoZCBpbnN0YW5jZW9mIFJTQUtleSYmZC5pc1B1YmxpYyl7Yi5rdHk9XCJSU0FcIjtiLm49aGV4dG9iNjR1KGQubi50b1N0cmluZygxNikpO2IuZT1oZXh0b2I2NHUoZC5lLnRvU3RyaW5nKDE2KSk7cmV0dXJuIGJ9ZWxzZXtpZihkIGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRUNEU0EmJmQuaXNQcml2YXRlKXt2YXIgYT1kLmdldFNob3J0TklTVFBDdXJ2ZU5hbWUoKTtpZihhIT09XCJQLTI1NlwiJiZhIT09XCJQLTM4NFwiKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZSBmb3IgSldUOiBcIithfXZhciBjPWQuZ2V0UHVibGljS2V5WFlIZXgoKTtiLmt0eT1cIkVDXCI7Yi5jcnY9YTtiLng9aGV4dG9iNjR1KGMueCk7Yi55PWhleHRvYjY0dShjLnkpO2IuZD1oZXh0b2I2NHUoZC5wcnZLZXlIZXgpO3JldHVybiBifWVsc2V7aWYoZCBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkVDRFNBJiZkLmlzUHVibGljKXt2YXIgYT1kLmdldFNob3J0TklTVFBDdXJ2ZU5hbWUoKTtpZihhIT09XCJQLTI1NlwiJiZhIT09XCJQLTM4NFwiKXt0aHJvd1widW5zdXBwb3J0ZWQgY3VydmUgbmFtZSBmb3IgSldUOiBcIithfXZhciBjPWQuZ2V0UHVibGljS2V5WFlIZXgoKTtiLmt0eT1cIkVDXCI7Yi5jcnY9YTtiLng9aGV4dG9iNjR1KGMueCk7Yi55PWhleHRvYjY0dShjLnkpO3JldHVybiBifX19fXRocm93XCJub3Qgc3VwcG9ydGVkIGtleSBvYmplY3RcIn07XG5SU0FLZXkuZ2V0UG9zQXJyYXlPZkNoaWxkcmVuRnJvbUhleD1mdW5jdGlvbihhKXtyZXR1cm4gQVNOMUhFWC5nZXRDaGlsZElkeChhLDApfTtSU0FLZXkuZ2V0SGV4VmFsdWVBcnJheU9mQ2hpbGRyZW5Gcm9tSGV4PWZ1bmN0aW9uKGYpe3ZhciBuPUFTTjFIRVg7dmFyIGk9bi5nZXRWO3ZhciBrPVJTQUtleS5nZXRQb3NBcnJheU9mQ2hpbGRyZW5Gcm9tSGV4KGYpO3ZhciBlPWkoZixrWzBdKTt2YXIgaj1pKGYsa1sxXSk7dmFyIGI9aShmLGtbMl0pO3ZhciBjPWkoZixrWzNdKTt2YXIgaD1pKGYsa1s0XSk7dmFyIGc9aShmLGtbNV0pO3ZhciBtPWkoZixrWzZdKTt2YXIgbD1pKGYsa1s3XSk7dmFyIGQ9aShmLGtbOF0pO3ZhciBrPW5ldyBBcnJheSgpO2sucHVzaChlLGosYixjLGgsZyxtLGwsZCk7cmV0dXJuIGt9O1JTQUtleS5wcm90b3R5cGUucmVhZFByaXZhdGVLZXlGcm9tUEVNU3RyaW5nPWZ1bmN0aW9uKGQpe3ZhciBjPXBlbXRvaGV4KGQpO3ZhciBiPVJTQUtleS5nZXRIZXhWYWx1ZUFycmF5T2ZDaGlsZHJlbkZyb21IZXgoYyk7dGhpcy5zZXRQcml2YXRlRXgoYlsxXSxiWzJdLGJbM10sYls0XSxiWzVdLGJbNl0sYls3XSxiWzhdKX07UlNBS2V5LnByb3RvdHlwZS5yZWFkUEtDUzVQcnZLZXlIZXg9ZnVuY3Rpb24oYyl7dmFyIGI9UlNBS2V5LmdldEhleFZhbHVlQXJyYXlPZkNoaWxkcmVuRnJvbUhleChjKTt0aGlzLnNldFByaXZhdGVFeChiWzFdLGJbMl0sYlszXSxiWzRdLGJbNV0sYls2XSxiWzddLGJbOF0pfTtSU0FLZXkucHJvdG90eXBlLnJlYWRQS0NTOFBydktleUhleD1mdW5jdGlvbihlKXt2YXIgYyxqLGwsYixhLGYsZCxrO3ZhciBtPUFTTjFIRVg7dmFyIGc9bS5nZXRWYnlMaXN0O2lmKG0uaXNBU04xSEVYKGUpPT09ZmFsc2Upe3Rocm93XCJub3QgQVNOLjEgaGV4IHN0cmluZ1wifXRyeXtjPWcoZSwwLFsyLDAsMV0sXCIwMlwiKTtqPWcoZSwwLFsyLDAsMl0sXCIwMlwiKTtsPWcoZSwwLFsyLDAsM10sXCIwMlwiKTtiPWcoZSwwLFsyLDAsNF0sXCIwMlwiKTthPWcoZSwwLFsyLDAsNV0sXCIwMlwiKTtmPWcoZSwwLFsyLDAsNl0sXCIwMlwiKTtkPWcoZSwwLFsyLDAsN10sXCIwMlwiKTtrPWcoZSwwLFsyLDAsOF0sXCIwMlwiKX1jYXRjaChpKXt0aHJvd1wibWFsZm9ybWVkIFBLQ1MjOCBwbGFpbiBSU0EgcHJpdmF0ZSBrZXlcIn10aGlzLnNldFByaXZhdGVFeChjLGosbCxiLGEsZixkLGspfTtSU0FLZXkucHJvdG90eXBlLnJlYWRQS0NTNVB1YktleUhleD1mdW5jdGlvbihjKXt2YXIgZT1BU04xSEVYO3ZhciBiPWUuZ2V0VjtpZihlLmlzQVNOMUhFWChjKT09PWZhbHNlKXt0aHJvd1wia2V5SGV4IGlzIG5vdCBBU04uMSBoZXggc3RyaW5nXCJ9dmFyIGE9ZS5nZXRDaGlsZElkeChjLDApO2lmKGEubGVuZ3RoIT09Mnx8Yy5zdWJzdHIoYVswXSwyKSE9PVwiMDJcInx8Yy5zdWJzdHIoYVsxXSwyKSE9PVwiMDJcIil7dGhyb3dcIndyb25nIGhleCBmb3IgUEtDUyM1IHB1YmxpYyBrZXlcIn12YXIgZj1iKGMsYVswXSk7dmFyIGQ9YihjLGFbMV0pO3RoaXMuc2V0UHVibGljKGYsZCl9O1JTQUtleS5wcm90b3R5cGUucmVhZFBLQ1M4UHViS2V5SGV4PWZ1bmN0aW9uKGIpe3ZhciBjPUFTTjFIRVg7aWYoYy5pc0FTTjFIRVgoYik9PT1mYWxzZSl7dGhyb3dcIm5vdCBBU04uMSBoZXggc3RyaW5nXCJ9aWYoYy5nZXRUTFZieUxpc3QoYiwwLFswLDBdKSE9PVwiMDYwOTJhODY0ODg2ZjcwZDAxMDEwMVwiKXt0aHJvd1wibm90IFBLQ1M4IFJTQSBwdWJsaWMga2V5XCJ9dmFyIGE9Yy5nZXRUTFZieUxpc3QoYiwwLFsxLDBdKTt0aGlzLnJlYWRQS0NTNVB1YktleUhleChhKX07UlNBS2V5LnByb3RvdHlwZS5yZWFkQ2VydFB1YktleUhleD1mdW5jdGlvbihiLGQpe3ZhciBhLGM7YT1uZXcgWDUwOSgpO2EucmVhZENlcnRIZXgoYik7Yz1hLmdldFB1YmxpY0tleUhleCgpO3RoaXMucmVhZFBLQ1M4UHViS2V5SGV4KGMpfTtcbnZhciBfUkVfSEVYREVDT05MWT1uZXcgUmVnRXhwKFwiXCIpO19SRV9IRVhERUNPTkxZLmNvbXBpbGUoXCJbXjAtOWEtZl1cIixcImdpXCIpO2Z1bmN0aW9uIF9yc2FzaWduX2dldEhleFBhZGRlZERpZ2VzdEluZm9Gb3JTdHJpbmcoZCxlLGEpe3ZhciBiPWZ1bmN0aW9uKGYpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hTdHJpbmcoZixhKX07dmFyIGM9YihkKTtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5nZXRQYWRkZWREaWdlc3RJbmZvSGV4KGMsYSxlKX1mdW5jdGlvbiBfemVyb1BhZGRpbmdPZlNpZ25hdHVyZShlLGQpe3ZhciBjPVwiXCI7dmFyIGE9ZC80LWUubGVuZ3RoO2Zvcih2YXIgYj0wO2I8YTtiKyspe2M9YytcIjBcIn1yZXR1cm4gYytlfVJTQUtleS5wcm90b3R5cGUuc2lnbj1mdW5jdGlvbihkLGEpe3ZhciBiPWZ1bmN0aW9uKGUpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hTdHJpbmcoZSxhKX07dmFyIGM9YihkKTtyZXR1cm4gdGhpcy5zaWduV2l0aE1lc3NhZ2VIYXNoKGMsYSl9O1JTQUtleS5wcm90b3R5cGUuc2lnbldpdGhNZXNzYWdlSGFzaD1mdW5jdGlvbihlLGMpe3ZhciBmPUtKVVIuY3J5cHRvLlV0aWwuZ2V0UGFkZGVkRGlnZXN0SW5mb0hleChlLGMsdGhpcy5uLmJpdExlbmd0aCgpKTt2YXIgYj1wYXJzZUJpZ0ludChmLDE2KTt2YXIgZD10aGlzLmRvUHJpdmF0ZShiKTt2YXIgYT1kLnRvU3RyaW5nKDE2KTtyZXR1cm4gX3plcm9QYWRkaW5nT2ZTaWduYXR1cmUoYSx0aGlzLm4uYml0TGVuZ3RoKCkpfTtmdW5jdGlvbiBwc3NfbWdmMV9zdHIoYyxhLGUpe3ZhciBiPVwiXCIsZD0wO3doaWxlKGIubGVuZ3RoPGEpe2IrPWhleHRvcnN0cihlKHJzdHJ0b2hleChjK1N0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLFsoZCY0Mjc4MTkwMDgwKT4+MjQsKGQmMTY3MTE2ODApPj4xNiwoZCY2NTI4MCk+PjgsZCYyNTVdKSkpKTtkKz0xfXJldHVybiBifVJTQUtleS5wcm90b3R5cGUuc2lnblBTUz1mdW5jdGlvbihlLGEsZCl7dmFyIGM9ZnVuY3Rpb24oZil7cmV0dXJuIEtKVVIuY3J5cHRvLlV0aWwuaGFzaEhleChmLGEpfTt2YXIgYj1jKHJzdHJ0b2hleChlKSk7aWYoZD09PXVuZGVmaW5lZCl7ZD0tMX1yZXR1cm4gdGhpcy5zaWduV2l0aE1lc3NhZ2VIYXNoUFNTKGIsYSxkKX07UlNBS2V5LnByb3RvdHlwZS5zaWduV2l0aE1lc3NhZ2VIYXNoUFNTPWZ1bmN0aW9uKGwsYSxrKXt2YXIgYj1oZXh0b3JzdHIobCk7dmFyIGc9Yi5sZW5ndGg7dmFyIG09dGhpcy5uLmJpdExlbmd0aCgpLTE7dmFyIGM9TWF0aC5jZWlsKG0vOCk7dmFyIGQ7dmFyIG89ZnVuY3Rpb24oaSl7cmV0dXJuIEtKVVIuY3J5cHRvLlV0aWwuaGFzaEhleChpLGEpfTtpZihrPT09LTF8fGs9PT11bmRlZmluZWQpe2s9Z31lbHNle2lmKGs9PT0tMil7az1jLWctMn1lbHNle2lmKGs8LTIpe3Rocm93XCJpbnZhbGlkIHNhbHQgbGVuZ3RoXCJ9fX1pZihjPChnK2srMikpe3Rocm93XCJkYXRhIHRvbyBsb25nXCJ9dmFyIGY9XCJcIjtpZihrPjApe2Y9bmV3IEFycmF5KGspO25ldyBTZWN1cmVSYW5kb20oKS5uZXh0Qnl0ZXMoZik7Zj1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxmKX12YXIgbj1oZXh0b3JzdHIobyhyc3RydG9oZXgoXCJcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXCIrYitmKSkpO3ZhciBqPVtdO2ZvcihkPTA7ZDxjLWstZy0yO2QrPTEpe2pbZF09MH12YXIgZT1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxqKStcIlxceDAxXCIrZjt2YXIgaD1wc3NfbWdmMV9zdHIobixlLmxlbmd0aCxvKTt2YXIgcT1bXTtmb3IoZD0wO2Q8ZS5sZW5ndGg7ZCs9MSl7cVtkXT1lLmNoYXJDb2RlQXQoZCleaC5jaGFyQ29kZUF0KGQpfXZhciBwPSg2NTI4MD4+KDgqYy1tKSkmMjU1O3FbMF0mPX5wO2ZvcihkPTA7ZDxnO2QrKyl7cS5wdXNoKG4uY2hhckNvZGVBdChkKSl9cS5wdXNoKDE4OCk7cmV0dXJuIF96ZXJvUGFkZGluZ09mU2lnbmF0dXJlKHRoaXMuZG9Qcml2YXRlKG5ldyBCaWdJbnRlZ2VyKHEpKS50b1N0cmluZygxNiksdGhpcy5uLmJpdExlbmd0aCgpKX07ZnVuY3Rpb24gX3JzYXNpZ25fZ2V0RGVjcnlwdFNpZ25hdHVyZUJJKGEsZCxjKXt2YXIgYj1uZXcgUlNBS2V5KCk7Yi5zZXRQdWJsaWMoZCxjKTt2YXIgZT1iLmRvUHVibGljKGEpO3JldHVybiBlfWZ1bmN0aW9uIF9yc2FzaWduX2dldEhleERpZ2VzdEluZm9Gcm9tU2lnKGEsYyxiKXt2YXIgZT1fcnNhc2lnbl9nZXREZWNyeXB0U2lnbmF0dXJlQkkoYSxjLGIpO3ZhciBkPWUudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sXCJcIik7cmV0dXJuIGR9ZnVuY3Rpb24gX3JzYXNpZ25fZ2V0QWxnTmFtZUFuZEhhc2hGcm9tSGV4RGlzZ2VzdEluZm8oZil7Zm9yKHZhciBlIGluIEtKVVIuY3J5cHRvLlV0aWwuRElHRVNUSU5GT0hFQUQpe3ZhciBkPUtKVVIuY3J5cHRvLlV0aWwuRElHRVNUSU5GT0hFQURbZV07dmFyIGI9ZC5sZW5ndGg7aWYoZi5zdWJzdHJpbmcoMCxiKT09ZCl7dmFyIGM9W2UsZi5zdWJzdHJpbmcoYildO3JldHVybiBjfX1yZXR1cm5bXX1SU0FLZXkucHJvdG90eXBlLnZlcmlmeT1mdW5jdGlvbihmLGope2o9ai5yZXBsYWNlKF9SRV9IRVhERUNPTkxZLFwiXCIpO2o9ai5yZXBsYWNlKC9bIFxcbl0rL2csXCJcIik7dmFyIGI9cGFyc2VCaWdJbnQoaiwxNik7aWYoYi5iaXRMZW5ndGgoKT50aGlzLm4uYml0TGVuZ3RoKCkpe3JldHVybiAwfXZhciBpPXRoaXMuZG9QdWJsaWMoYik7dmFyIGU9aS50b1N0cmluZygxNikucmVwbGFjZSgvXjFmKzAwLyxcIlwiKTt2YXIgZz1fcnNhc2lnbl9nZXRBbGdOYW1lQW5kSGFzaEZyb21IZXhEaXNnZXN0SW5mbyhlKTtpZihnLmxlbmd0aD09MCl7cmV0dXJuIGZhbHNlfXZhciBkPWdbMF07dmFyIGg9Z1sxXTt2YXIgYT1mdW5jdGlvbihrKXtyZXR1cm4gS0pVUi5jcnlwdG8uVXRpbC5oYXNoU3RyaW5nKGssZCl9O3ZhciBjPWEoZik7cmV0dXJuKGg9PWMpfTtSU0FLZXkucHJvdG90eXBlLnZlcmlmeVdpdGhNZXNzYWdlSGFzaD1mdW5jdGlvbihlLGEpe2E9YS5yZXBsYWNlKF9SRV9IRVhERUNPTkxZLFwiXCIpO2E9YS5yZXBsYWNlKC9bIFxcbl0rL2csXCJcIik7dmFyIGI9cGFyc2VCaWdJbnQoYSwxNik7aWYoYi5iaXRMZW5ndGgoKT50aGlzLm4uYml0TGVuZ3RoKCkpe3JldHVybiAwfXZhciBoPXRoaXMuZG9QdWJsaWMoYik7dmFyIGc9aC50b1N0cmluZygxNikucmVwbGFjZSgvXjFmKzAwLyxcIlwiKTt2YXIgYz1fcnNhc2lnbl9nZXRBbGdOYW1lQW5kSGFzaEZyb21IZXhEaXNnZXN0SW5mbyhnKTtpZihjLmxlbmd0aD09MCl7cmV0dXJuIGZhbHNlfXZhciBkPWNbMF07dmFyIGY9Y1sxXTtyZXR1cm4oZj09ZSl9O1JTQUtleS5wcm90b3R5cGUudmVyaWZ5UFNTPWZ1bmN0aW9uKGMsYixhLGYpe3ZhciBlPWZ1bmN0aW9uKGcpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hIZXgoZyxhKX07dmFyIGQ9ZShyc3RydG9oZXgoYykpO2lmKGY9PT11bmRlZmluZWQpe2Y9LTF9cmV0dXJuIHRoaXMudmVyaWZ5V2l0aE1lc3NhZ2VIYXNoUFNTKGQsYixhLGYpfTtSU0FLZXkucHJvdG90eXBlLnZlcmlmeVdpdGhNZXNzYWdlSGFzaFBTUz1mdW5jdGlvbihmLHMsbCxjKXt2YXIgaz1uZXcgQmlnSW50ZWdlcihzLDE2KTtpZihrLmJpdExlbmd0aCgpPnRoaXMubi5iaXRMZW5ndGgoKSl7cmV0dXJuIGZhbHNlfXZhciByPWZ1bmN0aW9uKGkpe3JldHVybiBLSlVSLmNyeXB0by5VdGlsLmhhc2hIZXgoaSxsKX07dmFyIGo9aGV4dG9yc3RyKGYpO3ZhciBoPWoubGVuZ3RoO3ZhciBnPXRoaXMubi5iaXRMZW5ndGgoKS0xO3ZhciBtPU1hdGguY2VpbChnLzgpO3ZhciBxO2lmKGM9PT0tMXx8Yz09PXVuZGVmaW5lZCl7Yz1ofWVsc2V7aWYoYz09PS0yKXtjPW0taC0yfWVsc2V7aWYoYzwtMil7dGhyb3dcImludmFsaWQgc2FsdCBsZW5ndGhcIn19fWlmKG08KGgrYysyKSl7dGhyb3dcImRhdGEgdG9vIGxvbmdcIn12YXIgYT10aGlzLmRvUHVibGljKGspLnRvQnl0ZUFycmF5KCk7Zm9yKHE9MDtxPGEubGVuZ3RoO3ErPTEpe2FbcV0mPTI1NX13aGlsZShhLmxlbmd0aDxtKXthLnVuc2hpZnQoMCl9aWYoYVttLTFdIT09MTg4KXt0aHJvd1wiZW5jb2RlZCBtZXNzYWdlIGRvZXMgbm90IGVuZCBpbiAweGJjXCJ9YT1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxhKTt2YXIgZD1hLnN1YnN0cigwLG0taC0xKTt2YXIgZT1hLnN1YnN0cihkLmxlbmd0aCxoKTt2YXIgcD0oNjUyODA+Pig4Km0tZykpJjI1NTtpZigoZC5jaGFyQ29kZUF0KDApJnApIT09MCl7dGhyb3dcImJpdHMgYmV5b25kIGtleXNpemUgbm90IHplcm9cIn12YXIgbj1wc3NfbWdmMV9zdHIoZSxkLmxlbmd0aCxyKTt2YXIgbz1bXTtmb3IocT0wO3E8ZC5sZW5ndGg7cSs9MSl7b1txXT1kLmNoYXJDb2RlQXQocSlebi5jaGFyQ29kZUF0KHEpfW9bMF0mPX5wO3ZhciBiPW0taC1jLTI7Zm9yKHE9MDtxPGI7cSs9MSl7aWYob1txXSE9PTApe3Rocm93XCJsZWZ0bW9zdCBvY3RldHMgbm90IHplcm9cIn19aWYob1tiXSE9PTEpe3Rocm93XCIweDAxIG1hcmtlciBub3QgZm91bmRcIn1yZXR1cm4gZT09PWhleHRvcnN0cihyKHJzdHJ0b2hleChcIlxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcXHgwMFxceDAwXFx4MDBcIitqK1N0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLG8uc2xpY2UoLWMpKSkpKX07UlNBS2V5LlNBTFRfTEVOX0hMRU49LTE7UlNBS2V5LlNBTFRfTEVOX01BWD0tMjtSU0FLZXkuU0FMVF9MRU5fUkVDT1ZFUj0tMjtcbmZ1bmN0aW9uIFg1MDkoKXt2YXIgaz1BU04xSEVYLGo9ay5nZXRDaGlsZElkeCxoPWsuZ2V0VixiPWsuZ2V0VExWLGY9ay5nZXRWYnlMaXN0LGM9ay5nZXRUTFZieUxpc3QsZz1rLmdldElkeGJ5TGlzdCxkPWsuZ2V0VmlkeCxpPWsub2lkbmFtZSxhPVg1MDksZT1wZW10b2hleDt0aGlzLmhleD1udWxsO3RoaXMudmVyc2lvbj0wO3RoaXMuZm9mZnNldD0wO3RoaXMuYUV4dEluZm89bnVsbDt0aGlzLmdldFZlcnNpb249ZnVuY3Rpb24oKXtpZih0aGlzLmhleD09PW51bGx8fHRoaXMudmVyc2lvbiE9PTApe3JldHVybiB0aGlzLnZlcnNpb259aWYoYyh0aGlzLmhleCwwLFswLDBdKSE9PVwiYTAwMzAyMDEwMlwiKXt0aGlzLnZlcnNpb249MTt0aGlzLmZvZmZzZXQ9LTE7cmV0dXJuIDF9dGhpcy52ZXJzaW9uPTM7cmV0dXJuIDN9O3RoaXMuZ2V0U2VyaWFsTnVtYmVySGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGYodGhpcy5oZXgsMCxbMCwxK3RoaXMuZm9mZnNldF0sXCIwMlwiKX07dGhpcy5nZXRTaWduYXR1cmVBbGdvcml0aG1GaWVsZD1mdW5jdGlvbigpe3JldHVybiBpKGYodGhpcy5oZXgsMCxbMCwyK3RoaXMuZm9mZnNldCwwXSxcIjA2XCIpKX07dGhpcy5nZXRJc3N1ZXJIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gYyh0aGlzLmhleCwwLFswLDMrdGhpcy5mb2Zmc2V0XSxcIjMwXCIpfTt0aGlzLmdldElzc3VlclN0cmluZz1mdW5jdGlvbigpe3JldHVybiBhLmhleDJkbih0aGlzLmdldElzc3VlckhleCgpKX07dGhpcy5nZXRTdWJqZWN0SGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGModGhpcy5oZXgsMCxbMCw1K3RoaXMuZm9mZnNldF0sXCIzMFwiKX07dGhpcy5nZXRTdWJqZWN0U3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIGEuaGV4MmRuKHRoaXMuZ2V0U3ViamVjdEhleCgpKX07dGhpcy5nZXROb3RCZWZvcmU9ZnVuY3Rpb24oKXt2YXIgbD1mKHRoaXMuaGV4LDAsWzAsNCt0aGlzLmZvZmZzZXQsMF0pO2w9bC5yZXBsYWNlKC8oLi4pL2csXCIlJDFcIik7bD1kZWNvZGVVUklDb21wb25lbnQobCk7cmV0dXJuIGx9O3RoaXMuZ2V0Tm90QWZ0ZXI9ZnVuY3Rpb24oKXt2YXIgbD1mKHRoaXMuaGV4LDAsWzAsNCt0aGlzLmZvZmZzZXQsMV0pO2w9bC5yZXBsYWNlKC8oLi4pL2csXCIlJDFcIik7bD1kZWNvZGVVUklDb21wb25lbnQobCk7cmV0dXJuIGx9O3RoaXMuZ2V0UHVibGljS2V5SGV4PWZ1bmN0aW9uKCl7cmV0dXJuIGsuZ2V0VExWYnlMaXN0KHRoaXMuaGV4LDAsWzAsNit0aGlzLmZvZmZzZXRdLFwiMzBcIil9O3RoaXMuZ2V0UHVibGljS2V5SWR4PWZ1bmN0aW9uKCl7cmV0dXJuIGcodGhpcy5oZXgsMCxbMCw2K3RoaXMuZm9mZnNldF0sXCIzMFwiKX07dGhpcy5nZXRQdWJsaWNLZXlDb250ZW50SWR4PWZ1bmN0aW9uKCl7dmFyIGw9dGhpcy5nZXRQdWJsaWNLZXlJZHgoKTtyZXR1cm4gZyh0aGlzLmhleCxsLFsxLDBdLFwiMzBcIil9O3RoaXMuZ2V0UHVibGljS2V5PWZ1bmN0aW9uKCl7cmV0dXJuIEtFWVVUSUwuZ2V0S2V5KHRoaXMuZ2V0UHVibGljS2V5SGV4KCksbnVsbCxcInBrY3M4cHViXCIpfTt0aGlzLmdldFNpZ25hdHVyZUFsZ29yaXRobU5hbWU9ZnVuY3Rpb24oKXtyZXR1cm4gaShmKHRoaXMuaGV4LDAsWzEsMF0sXCIwNlwiKSl9O3RoaXMuZ2V0U2lnbmF0dXJlVmFsdWVIZXg9ZnVuY3Rpb24oKXtyZXR1cm4gZih0aGlzLmhleCwwLFsyXSxcIjAzXCIsdHJ1ZSl9O3RoaXMudmVyaWZ5U2lnbmF0dXJlPWZ1bmN0aW9uKG4pe3ZhciBvPXRoaXMuZ2V0U2lnbmF0dXJlQWxnb3JpdGhtTmFtZSgpO3ZhciBsPXRoaXMuZ2V0U2lnbmF0dXJlVmFsdWVIZXgoKTt2YXIgbT1jKHRoaXMuaGV4LDAsWzBdLFwiMzBcIik7dmFyIHA9bmV3IEtKVVIuY3J5cHRvLlNpZ25hdHVyZSh7YWxnOm99KTtwLmluaXQobik7cC51cGRhdGVIZXgobSk7cmV0dXJuIHAudmVyaWZ5KGwpfTt0aGlzLnBhcnNlRXh0PWZ1bmN0aW9uKCl7aWYodGhpcy52ZXJzaW9uIT09Myl7cmV0dXJuIC0xfXZhciBwPWcodGhpcy5oZXgsMCxbMCw3LDBdLFwiMzBcIik7dmFyIG09aih0aGlzLmhleCxwKTt0aGlzLmFFeHRJbmZvPW5ldyBBcnJheSgpO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXt2YXIgcT17fTtxLmNyaXRpY2FsPWZhbHNlO3ZhciBsPWoodGhpcy5oZXgsbVtuXSk7dmFyIHI9MDtpZihsLmxlbmd0aD09PTMpe3EuY3JpdGljYWw9dHJ1ZTtyPTF9cS5vaWQ9ay5oZXh0b29pZHN0cihmKHRoaXMuaGV4LG1bbl0sWzBdLFwiMDZcIikpO3ZhciBvPWcodGhpcy5oZXgsbVtuXSxbMStyXSk7cS52aWR4PWQodGhpcy5oZXgsbyk7dGhpcy5hRXh0SW5mby5wdXNoKHEpfX07dGhpcy5nZXRFeHRJbmZvPWZ1bmN0aW9uKG4pe3ZhciBsPXRoaXMuYUV4dEluZm87dmFyIG89bjtpZighbi5tYXRjaCgvXlswLTkuXSskLykpe289S0pVUi5hc24xLng1MDkuT0lELm5hbWUyb2lkKG4pfWlmKG89PT1cIlwiKXtyZXR1cm4gdW5kZWZpbmVkfWZvcih2YXIgbT0wO208bC5sZW5ndGg7bSsrKXtpZihsW21dLm9pZD09PW8pe3JldHVybiBsW21dfX1yZXR1cm4gdW5kZWZpbmVkfTt0aGlzLmdldEV4dEJhc2ljQ29uc3RyYWludHM9ZnVuY3Rpb24oKXt2YXIgbj10aGlzLmdldEV4dEluZm8oXCJiYXNpY0NvbnN0cmFpbnRzXCIpO2lmKG49PT11bmRlZmluZWQpe3JldHVybiBufXZhciBsPWgodGhpcy5oZXgsbi52aWR4KTtpZihsPT09XCJcIil7cmV0dXJue319aWYobD09PVwiMDEwMWZmXCIpe3JldHVybntjQTp0cnVlfX1pZihsLnN1YnN0cigwLDgpPT09XCIwMTAxZmYwMlwiKXt2YXIgbz1oKGwsNik7dmFyIG09cGFyc2VJbnQobywxNik7cmV0dXJue2NBOnRydWUscGF0aExlbjptfX10aHJvd1wiYmFzaWNDb25zdHJhaW50cyBwYXJzZSBlcnJvclwifTt0aGlzLmdldEV4dEtleVVzYWdlQmluPWZ1bmN0aW9uKCl7dmFyIG89dGhpcy5nZXRFeHRJbmZvKFwia2V5VXNhZ2VcIik7aWYobz09PXVuZGVmaW5lZCl7cmV0dXJuXCJcIn12YXIgbT1oKHRoaXMuaGV4LG8udmlkeCk7aWYobS5sZW5ndGglMiE9MHx8bS5sZW5ndGg8PTIpe3Rocm93XCJtYWxmb3JtZWQga2V5IHVzYWdlIHZhbHVlXCJ9dmFyIGw9cGFyc2VJbnQobS5zdWJzdHIoMCwyKSk7dmFyIG49cGFyc2VJbnQobS5zdWJzdHIoMiksMTYpLnRvU3RyaW5nKDIpO3JldHVybiBuLnN1YnN0cigwLG4ubGVuZ3RoLWwpfTt0aGlzLmdldEV4dEtleVVzYWdlU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIG49dGhpcy5nZXRFeHRLZXlVc2FnZUJpbigpO3ZhciBsPW5ldyBBcnJheSgpO2Zvcih2YXIgbT0wO208bi5sZW5ndGg7bSsrKXtpZihuLnN1YnN0cihtLDEpPT1cIjFcIil7bC5wdXNoKFg1MDkuS0VZVVNBR0VfTkFNRVttXSl9fXJldHVybiBsLmpvaW4oXCIsXCIpfTt0aGlzLmdldEV4dFN1YmplY3RLZXlJZGVudGlmaWVyPWZ1bmN0aW9uKCl7dmFyIGw9dGhpcy5nZXRFeHRJbmZvKFwic3ViamVjdEtleUlkZW50aWZpZXJcIik7aWYobD09PXVuZGVmaW5lZCl7cmV0dXJuIGx9cmV0dXJuIGgodGhpcy5oZXgsbC52aWR4KX07dGhpcy5nZXRFeHRBdXRob3JpdHlLZXlJZGVudGlmaWVyPWZ1bmN0aW9uKCl7dmFyIHA9dGhpcy5nZXRFeHRJbmZvKFwiYXV0aG9yaXR5S2V5SWRlbnRpZmllclwiKTtpZihwPT09dW5kZWZpbmVkKXtyZXR1cm4gcH12YXIgbD17fTt2YXIgbz1iKHRoaXMuaGV4LHAudmlkeCk7dmFyIG09aihvLDApO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXtpZihvLnN1YnN0cihtW25dLDIpPT09XCI4MFwiKXtsLmtpZD1oKG8sbVtuXSl9fXJldHVybiBsfTt0aGlzLmdldEV4dEV4dEtleVVzYWdlTmFtZT1mdW5jdGlvbigpe3ZhciBwPXRoaXMuZ2V0RXh0SW5mbyhcImV4dEtleVVzYWdlXCIpO2lmKHA9PT11bmRlZmluZWQpe3JldHVybiBwfXZhciBsPW5ldyBBcnJheSgpO3ZhciBvPWIodGhpcy5oZXgscC52aWR4KTtpZihvPT09XCJcIil7cmV0dXJuIGx9dmFyIG09aihvLDApO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXtsLnB1c2goaShoKG8sbVtuXSkpKX1yZXR1cm4gbH07dGhpcy5nZXRFeHRTdWJqZWN0QWx0TmFtZT1mdW5jdGlvbigpe3ZhciBtPXRoaXMuZ2V0RXh0U3ViamVjdEFsdE5hbWUyKCk7dmFyIGw9bmV3IEFycmF5KCk7Zm9yKHZhciBuPTA7bjxtLmxlbmd0aDtuKyspe2lmKG1bbl1bMF09PT1cIkROU1wiKXtsLnB1c2gobVtuXVsxXSl9fXJldHVybiBsfTt0aGlzLmdldEV4dFN1YmplY3RBbHROYW1lMj1mdW5jdGlvbigpe3ZhciBwLHMscjt2YXIgcT10aGlzLmdldEV4dEluZm8oXCJzdWJqZWN0QWx0TmFtZVwiKTtpZihxPT09dW5kZWZpbmVkKXtyZXR1cm4gcX12YXIgbD1uZXcgQXJyYXkoKTt2YXIgbz1iKHRoaXMuaGV4LHEudmlkeCk7dmFyIG09aihvLDApO2Zvcih2YXIgbj0wO248bS5sZW5ndGg7bisrKXtyPW8uc3Vic3RyKG1bbl0sMik7cD1oKG8sbVtuXSk7aWYocj09PVwiODFcIil7cz1oZXh0b3V0ZjgocCk7bC5wdXNoKFtcIk1BSUxcIixzXSl9aWYocj09PVwiODJcIil7cz1oZXh0b3V0ZjgocCk7bC5wdXNoKFtcIkROU1wiLHNdKX1pZihyPT09XCI4NFwiKXtzPVg1MDkuaGV4MmRuKHAsMCk7bC5wdXNoKFtcIkROXCIsc10pfWlmKHI9PT1cIjg2XCIpe3M9aGV4dG91dGY4KHApO2wucHVzaChbXCJVUklcIixzXSl9aWYocj09PVwiODdcIil7cz1oZXh0b2lwKHApO2wucHVzaChbXCJJUFwiLHNdKX19cmV0dXJuIGx9O3RoaXMuZ2V0RXh0Q1JMRGlzdHJpYnV0aW9uUG9pbnRzVVJJPWZ1bmN0aW9uKCl7dmFyIHE9dGhpcy5nZXRFeHRJbmZvKFwiY1JMRGlzdHJpYnV0aW9uUG9pbnRzXCIpO2lmKHE9PT11bmRlZmluZWQpe3JldHVybiBxfXZhciBsPW5ldyBBcnJheSgpO3ZhciBtPWoodGhpcy5oZXgscS52aWR4KTtmb3IodmFyIG89MDtvPG0ubGVuZ3RoO28rKyl7dHJ5e3ZhciByPWYodGhpcy5oZXgsbVtvXSxbMCwwLDBdLFwiODZcIik7dmFyIHA9aGV4dG91dGY4KHIpO2wucHVzaChwKX1jYXRjaChuKXt9fXJldHVybiBsfTt0aGlzLmdldEV4dEFJQUluZm89ZnVuY3Rpb24oKXt2YXIgcD10aGlzLmdldEV4dEluZm8oXCJhdXRob3JpdHlJbmZvQWNjZXNzXCIpO2lmKHA9PT11bmRlZmluZWQpe3JldHVybiBwfXZhciBsPXtvY3NwOltdLGNhaXNzdWVyOltdfTt2YXIgbT1qKHRoaXMuaGV4LHAudmlkeCk7Zm9yKHZhciBuPTA7bjxtLmxlbmd0aDtuKyspe3ZhciBxPWYodGhpcy5oZXgsbVtuXSxbMF0sXCIwNlwiKTt2YXIgbz1mKHRoaXMuaGV4LG1bbl0sWzFdLFwiODZcIik7aWYocT09PVwiMmIwNjAxMDUwNTA3MzAwMVwiKXtsLm9jc3AucHVzaChoZXh0b3V0ZjgobykpfWlmKHE9PT1cIjJiMDYwMTA1MDUwNzMwMDJcIil7bC5jYWlzc3Vlci5wdXNoKGhleHRvdXRmOChvKSl9fXJldHVybiBsfTt0aGlzLmdldEV4dENlcnRpZmljYXRlUG9saWNpZXM9ZnVuY3Rpb24oKXt2YXIgbz10aGlzLmdldEV4dEluZm8oXCJjZXJ0aWZpY2F0ZVBvbGljaWVzXCIpO2lmKG89PT11bmRlZmluZWQpe3JldHVybiBvfXZhciBsPWIodGhpcy5oZXgsby52aWR4KTt2YXIgdT1bXTt2YXIgcz1qKGwsMCk7Zm9yKHZhciByPTA7cjxzLmxlbmd0aDtyKyspe3ZhciB0PXt9O3ZhciBuPWoobCxzW3JdKTt0LmlkPWkoaChsLG5bMF0pKTtpZihuLmxlbmd0aD09PTIpe3ZhciBtPWoobCxuWzFdKTtmb3IodmFyIHE9MDtxPG0ubGVuZ3RoO3ErKyl7dmFyIHA9ZihsLG1bcV0sWzBdLFwiMDZcIik7aWYocD09PVwiMmIwNjAxMDUwNTA3MDIwMVwiKXt0LmNwcz1oZXh0b3V0ZjgoZihsLG1bcV0sWzFdKSl9ZWxzZXtpZihwPT09XCIyYjA2MDEwNTA1MDcwMjAyXCIpe3QudW5vdGljZT1oZXh0b3V0ZjgoZihsLG1bcV0sWzEsMF0pKX19fX11LnB1c2godCl9cmV0dXJuIHV9O3RoaXMucmVhZENlcnRQRU09ZnVuY3Rpb24obCl7dGhpcy5yZWFkQ2VydEhleChlKGwpKX07dGhpcy5yZWFkQ2VydEhleD1mdW5jdGlvbihsKXt0aGlzLmhleD1sO3RoaXMuZ2V0VmVyc2lvbigpO3RyeXtnKHRoaXMuaGV4LDAsWzAsN10sXCJhM1wiKTt0aGlzLnBhcnNlRXh0KCl9Y2F0Y2gobSl7fX07dGhpcy5nZXRJbmZvPWZ1bmN0aW9uKCl7dmFyIG09WDUwOTt2YXIgQix1LHo7Qj1cIkJhc2ljIEZpZWxkc1xcblwiO0IrPVwiICBzZXJpYWwgbnVtYmVyOiBcIit0aGlzLmdldFNlcmlhbE51bWJlckhleCgpK1wiXFxuXCI7Qis9XCIgIHNpZ25hdHVyZSBhbGdvcml0aG06IFwiK3RoaXMuZ2V0U2lnbmF0dXJlQWxnb3JpdGhtRmllbGQoKStcIlxcblwiO0IrPVwiICBpc3N1ZXI6IFwiK3RoaXMuZ2V0SXNzdWVyU3RyaW5nKCkrXCJcXG5cIjtCKz1cIiAgbm90QmVmb3JlOiBcIit0aGlzLmdldE5vdEJlZm9yZSgpK1wiXFxuXCI7Qis9XCIgIG5vdEFmdGVyOiBcIit0aGlzLmdldE5vdEFmdGVyKCkrXCJcXG5cIjtCKz1cIiAgc3ViamVjdDogXCIrdGhpcy5nZXRTdWJqZWN0U3RyaW5nKCkrXCJcXG5cIjtCKz1cIiAgc3ViamVjdCBwdWJsaWMga2V5IGluZm86IFxcblwiO3U9dGhpcy5nZXRQdWJsaWNLZXkoKTtCKz1cIiAgICBrZXkgYWxnb3JpdGhtOiBcIit1LnR5cGUrXCJcXG5cIjtpZih1LnR5cGU9PT1cIlJTQVwiKXtCKz1cIiAgICBuPVwiK2hleHRvcG9zaGV4KHUubi50b1N0cmluZygxNikpLnN1YnN0cigwLDE2KStcIi4uLlxcblwiO0IrPVwiICAgIGU9XCIraGV4dG9wb3NoZXgodS5lLnRvU3RyaW5nKDE2KSkrXCJcXG5cIn16PXRoaXMuYUV4dEluZm87aWYoeiE9PXVuZGVmaW5lZCYmeiE9PW51bGwpe0IrPVwiWDUwOXYzIEV4dGVuc2lvbnM6XFxuXCI7Zm9yKHZhciByPTA7cjx6Lmxlbmd0aDtyKyspe3ZhciBuPXpbcl07dmFyIEE9S0pVUi5hc24xLng1MDkuT0lELm9pZDJuYW1lKG4ub2lkKTtpZihBPT09XCJcIil7QT1uLm9pZH12YXIgeD1cIlwiO2lmKG4uY3JpdGljYWw9PT10cnVlKXt4PVwiQ1JJVElDQUxcIn1CKz1cIiAgXCIrQStcIiBcIit4K1wiOlxcblwiO2lmKEE9PT1cImJhc2ljQ29uc3RyYWludHNcIil7dmFyIHY9dGhpcy5nZXRFeHRCYXNpY0NvbnN0cmFpbnRzKCk7aWYodi5jQT09PXVuZGVmaW5lZCl7Qis9XCIgICAge31cXG5cIn1lbHNle0IrPVwiICAgIGNBPXRydWVcIjtpZih2LnBhdGhMZW4hPT11bmRlZmluZWQpe0IrPVwiLCBwYXRoTGVuPVwiK3YucGF0aExlbn1CKz1cIlxcblwifX1lbHNle2lmKEE9PT1cImtleVVzYWdlXCIpe0IrPVwiICAgIFwiK3RoaXMuZ2V0RXh0S2V5VXNhZ2VTdHJpbmcoKStcIlxcblwifWVsc2V7aWYoQT09PVwic3ViamVjdEtleUlkZW50aWZpZXJcIil7Qis9XCIgICAgXCIrdGhpcy5nZXRFeHRTdWJqZWN0S2V5SWRlbnRpZmllcigpK1wiXFxuXCJ9ZWxzZXtpZihBPT09XCJhdXRob3JpdHlLZXlJZGVudGlmaWVyXCIpe3ZhciBsPXRoaXMuZ2V0RXh0QXV0aG9yaXR5S2V5SWRlbnRpZmllcigpO2lmKGwua2lkIT09dW5kZWZpbmVkKXtCKz1cIiAgICBraWQ9XCIrbC5raWQrXCJcXG5cIn19ZWxzZXtpZihBPT09XCJleHRLZXlVc2FnZVwiKXt2YXIgdz10aGlzLmdldEV4dEV4dEtleVVzYWdlTmFtZSgpO0IrPVwiICAgIFwiK3cuam9pbihcIiwgXCIpK1wiXFxuXCJ9ZWxzZXtpZihBPT09XCJzdWJqZWN0QWx0TmFtZVwiKXt2YXIgdD10aGlzLmdldEV4dFN1YmplY3RBbHROYW1lMigpO0IrPVwiICAgIFwiK3QrXCJcXG5cIn1lbHNle2lmKEE9PT1cImNSTERpc3RyaWJ1dGlvblBvaW50c1wiKXt2YXIgeT10aGlzLmdldEV4dENSTERpc3RyaWJ1dGlvblBvaW50c1VSSSgpO0IrPVwiICAgIFwiK3krXCJcXG5cIn1lbHNle2lmKEE9PT1cImF1dGhvcml0eUluZm9BY2Nlc3NcIil7dmFyIHA9dGhpcy5nZXRFeHRBSUFJbmZvKCk7aWYocC5vY3NwIT09dW5kZWZpbmVkKXtCKz1cIiAgICBvY3NwOiBcIitwLm9jc3Auam9pbihcIixcIikrXCJcXG5cIn1pZihwLmNhaXNzdWVyIT09dW5kZWZpbmVkKXtCKz1cIiAgICBjYWlzc3VlcjogXCIrcC5jYWlzc3Vlci5qb2luKFwiLFwiKStcIlxcblwifX1lbHNle2lmKEE9PT1cImNlcnRpZmljYXRlUG9saWNpZXNcIil7dmFyIG89dGhpcy5nZXRFeHRDZXJ0aWZpY2F0ZVBvbGljaWVzKCk7Zm9yKHZhciBxPTA7cTxvLmxlbmd0aDtxKyspe2lmKG9bcV0uaWQhPT11bmRlZmluZWQpe0IrPVwiICAgIHBvbGljeSBvaWQ6IFwiK29bcV0uaWQrXCJcXG5cIn1pZihvW3FdLmNwcyE9PXVuZGVmaW5lZCl7Qis9XCIgICAgY3BzOiBcIitvW3FdLmNwcytcIlxcblwifX19fX19fX19fX19fUIrPVwic2lnbmF0dXJlIGFsZ29yaXRobTogXCIrdGhpcy5nZXRTaWduYXR1cmVBbGdvcml0aG1OYW1lKCkrXCJcXG5cIjtCKz1cInNpZ25hdHVyZTogXCIrdGhpcy5nZXRTaWduYXR1cmVWYWx1ZUhleCgpLnN1YnN0cigwLDE2KStcIi4uLlxcblwiO3JldHVybiBCfX1YNTA5LmhleDJkbj1mdW5jdGlvbihmLGIpe2lmKGI9PT11bmRlZmluZWQpe2I9MH1pZihmLnN1YnN0cihiLDIpIT09XCIzMFwiKXt0aHJvd1wibWFsZm9ybWVkIEROXCJ9dmFyIGM9bmV3IEFycmF5KCk7dmFyIGQ9QVNOMUhFWC5nZXRDaGlsZElkeChmLGIpO2Zvcih2YXIgZT0wO2U8ZC5sZW5ndGg7ZSsrKXtjLnB1c2goWDUwOS5oZXgycmRuKGYsZFtlXSkpfWM9Yy5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEucmVwbGFjZShcIi9cIixcIlxcXFwvXCIpfSk7cmV0dXJuXCIvXCIrYy5qb2luKFwiL1wiKX07WDUwOS5oZXgycmRuPWZ1bmN0aW9uKGYsYil7aWYoYj09PXVuZGVmaW5lZCl7Yj0wfWlmKGYuc3Vic3RyKGIsMikhPT1cIjMxXCIpe3Rocm93XCJtYWxmb3JtZWQgUkROXCJ9dmFyIGM9bmV3IEFycmF5KCk7dmFyIGQ9QVNOMUhFWC5nZXRDaGlsZElkeChmLGIpO2Zvcih2YXIgZT0wO2U8ZC5sZW5ndGg7ZSsrKXtjLnB1c2goWDUwOS5oZXgyYXR0clR5cGVWYWx1ZShmLGRbZV0pKX1jPWMubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBhLnJlcGxhY2UoXCIrXCIsXCJcXFxcK1wiKX0pO3JldHVybiBjLmpvaW4oXCIrXCIpfTtYNTA5LmhleDJhdHRyVHlwZVZhbHVlPWZ1bmN0aW9uKGQsaSl7dmFyIGo9QVNOMUhFWDt2YXIgaD1qLmdldFY7aWYoaT09PXVuZGVmaW5lZCl7aT0wfWlmKGQuc3Vic3RyKGksMikhPT1cIjMwXCIpe3Rocm93XCJtYWxmb3JtZWQgYXR0cmlidXRlIHR5cGUgYW5kIHZhbHVlXCJ9dmFyIGc9ai5nZXRDaGlsZElkeChkLGkpO2lmKGcubGVuZ3RoIT09Mnx8ZC5zdWJzdHIoZ1swXSwyKSE9PVwiMDZcIil7XCJtYWxmb3JtZWQgYXR0cmlidXRlIHR5cGUgYW5kIHZhbHVlXCJ9dmFyIGI9aChkLGdbMF0pO3ZhciBmPUtKVVIuYXNuMS5BU04xVXRpbC5vaWRIZXhUb0ludChiKTt2YXIgZT1LSlVSLmFzbjEueDUwOS5PSUQub2lkMmF0eXBlKGYpO3ZhciBhPWgoZCxnWzFdKTt2YXIgYz1oZXh0b3JzdHIoYSk7cmV0dXJuIGUrXCI9XCIrY307WDUwOS5nZXRQdWJsaWNLZXlGcm9tQ2VydEhleD1mdW5jdGlvbihiKXt2YXIgYT1uZXcgWDUwOSgpO2EucmVhZENlcnRIZXgoYik7cmV0dXJuIGEuZ2V0UHVibGljS2V5KCl9O1g1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRQRU09ZnVuY3Rpb24oYil7dmFyIGE9bmV3IFg1MDkoKTthLnJlYWRDZXJ0UEVNKGIpO3JldHVybiBhLmdldFB1YmxpY0tleSgpfTtYNTA5LmdldFB1YmxpY0tleUluZm9Qcm9wT2ZDZXJ0UEVNPWZ1bmN0aW9uKGMpe3ZhciBlPUFTTjFIRVg7dmFyIGc9ZS5nZXRWYnlMaXN0O3ZhciBiPXt9O3ZhciBhLGYsZDtiLmFsZ3BhcmFtPW51bGw7YT1uZXcgWDUwOSgpO2EucmVhZENlcnRQRU0oYyk7Zj1hLmdldFB1YmxpY0tleUhleCgpO2Iua2V5aGV4PWcoZiwwLFsxXSxcIjAzXCIpLnN1YnN0cigyKTtiLmFsZ29pZD1nKGYsMCxbMCwwXSxcIjA2XCIpO2lmKGIuYWxnb2lkPT09XCIyYTg2NDhjZTNkMDIwMVwiKXtiLmFsZ3BhcmFtPWcoZiwwLFswLDFdLFwiMDZcIil9cmV0dXJuIGJ9O1g1MDkuS0VZVVNBR0VfTkFNRT1bXCJkaWdpdGFsU2lnbmF0dXJlXCIsXCJub25SZXB1ZGlhdGlvblwiLFwia2V5RW5jaXBoZXJtZW50XCIsXCJkYXRhRW5jaXBoZXJtZW50XCIsXCJrZXlBZ3JlZW1lbnRcIixcImtleUNlcnRTaWduXCIsXCJjUkxTaWduXCIsXCJlbmNpcGhlck9ubHlcIixcImRlY2lwaGVyT25seVwiXTtcbmlmKHR5cGVvZiBLSlVSPT1cInVuZGVmaW5lZFwifHwhS0pVUil7S0pVUj17fX1pZih0eXBlb2YgS0pVUi5qd3M9PVwidW5kZWZpbmVkXCJ8fCFLSlVSLmp3cyl7S0pVUi5qd3M9e319S0pVUi5qd3MuSldTPWZ1bmN0aW9uKCl7dmFyIGI9S0pVUixhPWIuandzLkpXUyxjPWEuaXNTYWZlSlNPTlN0cmluZzt0aGlzLnBhcnNlSldTPWZ1bmN0aW9uKGcsail7aWYoKHRoaXMucGFyc2VkSldTIT09dW5kZWZpbmVkKSYmKGp8fCh0aGlzLnBhcnNlZEpXUy5zaWd2YWxIIT09dW5kZWZpbmVkKSkpe3JldHVybn12YXIgaT1nLm1hdGNoKC9eKFteLl0rKVxcLihbXi5dKylcXC4oW14uXSspJC8pO2lmKGk9PW51bGwpe3Rocm93XCJKV1Mgc2lnbmF0dXJlIGlzIG5vdCBhIGZvcm0gb2YgJ0hlYWQuUGF5bG9hZC5TaWdWYWx1ZScuXCJ9dmFyIGs9aVsxXTt2YXIgZT1pWzJdO3ZhciBsPWlbM107dmFyIG49aytcIi5cIitlO3RoaXMucGFyc2VkSldTPXt9O3RoaXMucGFyc2VkSldTLmhlYWRCNjRVPWs7dGhpcy5wYXJzZWRKV1MucGF5bG9hZEI2NFU9ZTt0aGlzLnBhcnNlZEpXUy5zaWd2YWxCNjRVPWw7dGhpcy5wYXJzZWRKV1Muc2k9bjtpZighail7dmFyIGg9YjY0dXRvaGV4KGwpO3ZhciBmPXBhcnNlQmlnSW50KGgsMTYpO3RoaXMucGFyc2VkSldTLnNpZ3ZhbEg9aDt0aGlzLnBhcnNlZEpXUy5zaWd2YWxCST1mfXZhciBkPWI2NHV0b3V0Zjgoayk7dmFyIG09YjY0dXRvdXRmOChlKTt0aGlzLnBhcnNlZEpXUy5oZWFkUz1kO3RoaXMucGFyc2VkSldTLnBheWxvYWRTPW07aWYoIWMoZCx0aGlzLnBhcnNlZEpXUyxcImhlYWRQXCIpKXt0aHJvd1wibWFsZm9ybWVkIEpTT04gc3RyaW5nIGZvciBKV1MgSGVhZDogXCIrZH19fTtLSlVSLmp3cy5KV1Muc2lnbj1mdW5jdGlvbihpLHYseSx6LGEpe3ZhciB3PUtKVVIsbT13Lmp3cyxxPW0uSldTLGc9cS5yZWFkU2FmZUpTT05TdHJpbmcscD1xLmlzU2FmZUpTT05TdHJpbmcsZD13LmNyeXB0byxrPWQuRUNEU0Esbz1kLk1hYyxjPWQuU2lnbmF0dXJlLHQ9SlNPTjt2YXIgcyxqLG47aWYodHlwZW9mIHYhPVwic3RyaW5nXCImJnR5cGVvZiB2IT1cIm9iamVjdFwiKXt0aHJvd1wic3BIZWFkZXIgbXVzdCBiZSBKU09OIHN0cmluZyBvciBvYmplY3Q6IFwiK3Z9aWYodHlwZW9mIHY9PVwib2JqZWN0XCIpe2o9djtzPXQuc3RyaW5naWZ5KGopfWlmKHR5cGVvZiB2PT1cInN0cmluZ1wiKXtzPXY7aWYoIXAocykpe3Rocm93XCJKV1MgSGVhZCBpcyBub3Qgc2FmZSBKU09OIHN0cmluZzogXCIrc31qPWcocyl9bj15O2lmKHR5cGVvZiB5PT1cIm9iamVjdFwiKXtuPXQuc3RyaW5naWZ5KHkpfWlmKChpPT1cIlwifHxpPT1udWxsKSYmai5hbGchPT11bmRlZmluZWQpe2k9ai5hbGd9aWYoKGkhPVwiXCImJmkhPW51bGwpJiZqLmFsZz09PXVuZGVmaW5lZCl7ai5hbGc9aTtzPXQuc3RyaW5naWZ5KGopfWlmKGkhPT1qLmFsZyl7dGhyb3dcImFsZyBhbmQgc0hlYWRlci5hbGcgZG9lc24ndCBtYXRjaDogXCIraStcIiE9XCIrai5hbGd9dmFyIHI9bnVsbDtpZihxLmp3c2FsZzJzaWdhbGdbaV09PT11bmRlZmluZWQpe3Rocm93XCJ1bnN1cHBvcnRlZCBhbGcgbmFtZTogXCIraX1lbHNle3I9cS5qd3NhbGcyc2lnYWxnW2ldfXZhciBlPXV0Zjh0b2I2NHUocyk7dmFyIGw9dXRmOHRvYjY0dShuKTt2YXIgYj1lK1wiLlwiK2w7dmFyIHg9XCJcIjtpZihyLnN1YnN0cigwLDQpPT1cIkhtYWNcIil7aWYoej09PXVuZGVmaW5lZCl7dGhyb3dcIm1hYyBrZXkgc2hhbGwgYmUgc3BlY2lmaWVkIGZvciBIUyogYWxnXCJ9dmFyIGg9bmV3IG8oe2FsZzpyLHByb3Y6XCJjcnlwdG9qc1wiLHBhc3M6en0pO2gudXBkYXRlU3RyaW5nKGIpO3g9aC5kb0ZpbmFsKCl9ZWxzZXtpZihyLmluZGV4T2YoXCJ3aXRoRUNEU0FcIikhPS0xKXt2YXIgZj1uZXcgYyh7YWxnOnJ9KTtmLmluaXQoeixhKTtmLnVwZGF0ZVN0cmluZyhiKTtoQVNOMVNpZz1mLnNpZ24oKTt4PUtKVVIuY3J5cHRvLkVDRFNBLmFzbjFTaWdUb0NvbmNhdFNpZyhoQVNOMVNpZyl9ZWxzZXtpZihyIT1cIm5vbmVcIil7dmFyIGY9bmV3IGMoe2FsZzpyfSk7Zi5pbml0KHosYSk7Zi51cGRhdGVTdHJpbmcoYik7eD1mLnNpZ24oKX19fXZhciB1PWhleHRvYjY0dSh4KTtyZXR1cm4gYitcIi5cIit1fTtLSlVSLmp3cy5KV1MudmVyaWZ5PWZ1bmN0aW9uKHcsQixuKXt2YXIgeD1LSlVSLHE9eC5qd3MsdD1xLkpXUyxpPXQucmVhZFNhZmVKU09OU3RyaW5nLGU9eC5jcnlwdG8scD1lLkVDRFNBLHM9ZS5NYWMsZD1lLlNpZ25hdHVyZSxtO2lmKHR5cGVvZiBSU0FLZXkhPT11bmRlZmluZWQpe209UlNBS2V5fXZhciB5PXcuc3BsaXQoXCIuXCIpO2lmKHkubGVuZ3RoIT09Myl7cmV0dXJuIGZhbHNlfXZhciBmPXlbMF07dmFyIHI9eVsxXTt2YXIgYz1mK1wiLlwiK3I7dmFyIEE9YjY0dXRvaGV4KHlbMl0pO3ZhciBsPWkoYjY0dXRvdXRmOCh5WzBdKSk7dmFyIGs9bnVsbDt2YXIgej1udWxsO2lmKGwuYWxnPT09dW5kZWZpbmVkKXt0aHJvd1wiYWxnb3JpdGhtIG5vdCBzcGVjaWZpZWQgaW4gaGVhZGVyXCJ9ZWxzZXtrPWwuYWxnO3o9ay5zdWJzdHIoMCwyKX1pZihuIT1udWxsJiZPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobik9PT1cIltvYmplY3QgQXJyYXldXCImJm4ubGVuZ3RoPjApe3ZhciBiPVwiOlwiK24uam9pbihcIjpcIikrXCI6XCI7aWYoYi5pbmRleE9mKFwiOlwiK2srXCI6XCIpPT0tMSl7dGhyb3dcImFsZ29yaXRobSAnXCIraytcIicgbm90IGFjY2VwdGVkIGluIHRoZSBsaXN0XCJ9fWlmKGshPVwibm9uZVwiJiZCPT09bnVsbCl7dGhyb3dcImtleSBzaGFsbCBiZSBzcGVjaWZpZWQgdG8gdmVyaWZ5LlwifWlmKHR5cGVvZiBCPT1cInN0cmluZ1wiJiZCLmluZGV4T2YoXCItLS0tLUJFR0lOIFwiKSE9LTEpe0I9S0VZVVRJTC5nZXRLZXkoQil9aWYoej09XCJSU1wifHx6PT1cIlBTXCIpe2lmKCEoQiBpbnN0YW5jZW9mIG0pKXt0aHJvd1wia2V5IHNoYWxsIGJlIGEgUlNBS2V5IG9iaiBmb3IgUlMqIGFuZCBQUyogYWxnc1wifX1pZih6PT1cIkVTXCIpe2lmKCEoQiBpbnN0YW5jZW9mIHApKXt0aHJvd1wia2V5IHNoYWxsIGJlIGEgRUNEU0Egb2JqIGZvciBFUyogYWxnc1wifX1pZihrPT1cIm5vbmVcIil7fXZhciB1PW51bGw7aWYodC5qd3NhbGcyc2lnYWxnW2wuYWxnXT09PXVuZGVmaW5lZCl7dGhyb3dcInVuc3VwcG9ydGVkIGFsZyBuYW1lOiBcIitrfWVsc2V7dT10Lmp3c2FsZzJzaWdhbGdba119aWYodT09XCJub25lXCIpe3Rocm93XCJub3Qgc3VwcG9ydGVkXCJ9ZWxzZXtpZih1LnN1YnN0cigwLDQpPT1cIkhtYWNcIil7dmFyIG89bnVsbDtpZihCPT09dW5kZWZpbmVkKXt0aHJvd1wiaGV4YWRlY2ltYWwga2V5IHNoYWxsIGJlIHNwZWNpZmllZCBmb3IgSE1BQ1wifXZhciBqPW5ldyBzKHthbGc6dSxwYXNzOkJ9KTtqLnVwZGF0ZVN0cmluZyhjKTtvPWouZG9GaW5hbCgpO3JldHVybiBBPT1vfWVsc2V7aWYodS5pbmRleE9mKFwid2l0aEVDRFNBXCIpIT0tMSl7dmFyIGg9bnVsbDt0cnl7aD1wLmNvbmNhdFNpZ1RvQVNOMVNpZyhBKX1jYXRjaCh2KXtyZXR1cm4gZmFsc2V9dmFyIGc9bmV3IGQoe2FsZzp1fSk7Zy5pbml0KEIpO2cudXBkYXRlU3RyaW5nKGMpO3JldHVybiBnLnZlcmlmeShoKX1lbHNle3ZhciBnPW5ldyBkKHthbGc6dX0pO2cuaW5pdChCKTtnLnVwZGF0ZVN0cmluZyhjKTtyZXR1cm4gZy52ZXJpZnkoQSl9fX19O0tKVVIuandzLkpXUy5wYXJzZT1mdW5jdGlvbihnKXt2YXIgYz1nLnNwbGl0KFwiLlwiKTt2YXIgYj17fTt2YXIgZixlLGQ7aWYoYy5sZW5ndGghPTImJmMubGVuZ3RoIT0zKXt0aHJvd1wibWFsZm9ybWVkIHNKV1M6IHdyb25nIG51bWJlciBvZiAnLicgc3BsaXR0ZWQgZWxlbWVudHNcIn1mPWNbMF07ZT1jWzFdO2lmKGMubGVuZ3RoPT0zKXtkPWNbMl19Yi5oZWFkZXJPYmo9S0pVUi5qd3MuSldTLnJlYWRTYWZlSlNPTlN0cmluZyhiNjR1dG91dGY4KGYpKTtiLnBheWxvYWRPYmo9S0pVUi5qd3MuSldTLnJlYWRTYWZlSlNPTlN0cmluZyhiNjR1dG91dGY4KGUpKTtiLmhlYWRlclBQPUpTT04uc3RyaW5naWZ5KGIuaGVhZGVyT2JqLG51bGwsXCIgIFwiKTtpZihiLnBheWxvYWRPYmo9PW51bGwpe2IucGF5bG9hZFBQPWI2NHV0b3V0ZjgoZSl9ZWxzZXtiLnBheWxvYWRQUD1KU09OLnN0cmluZ2lmeShiLnBheWxvYWRPYmosbnVsbCxcIiAgXCIpfWlmKGQhPT11bmRlZmluZWQpe2Iuc2lnSGV4PWI2NHV0b2hleChkKX1yZXR1cm4gYn07S0pVUi5qd3MuSldTLnZlcmlmeUpXVD1mdW5jdGlvbihlLGwscil7dmFyIGQ9S0pVUixqPWQuandzLG89ai5KV1Msbj1vLnJlYWRTYWZlSlNPTlN0cmluZyxwPW8uaW5BcnJheSxmPW8uaW5jbHVkZWRBcnJheTt2YXIgaz1lLnNwbGl0KFwiLlwiKTt2YXIgYz1rWzBdO3ZhciBpPWtbMV07dmFyIHE9YytcIi5cIitpO3ZhciBtPWI2NHV0b2hleChrWzJdKTt2YXIgaD1uKGI2NHV0b3V0ZjgoYykpO3ZhciBnPW4oYjY0dXRvdXRmOChpKSk7aWYoaC5hbGc9PT11bmRlZmluZWQpe3JldHVybiBmYWxzZX1pZihyLmFsZz09PXVuZGVmaW5lZCl7dGhyb3dcImFjY2VwdEZpZWxkLmFsZyBzaGFsbCBiZSBzcGVjaWZpZWRcIn1pZighcChoLmFsZyxyLmFsZykpe3JldHVybiBmYWxzZX1pZihnLmlzcyE9PXVuZGVmaW5lZCYmdHlwZW9mIHIuaXNzPT09XCJvYmplY3RcIil7aWYoIXAoZy5pc3Msci5pc3MpKXtyZXR1cm4gZmFsc2V9fWlmKGcuc3ViIT09dW5kZWZpbmVkJiZ0eXBlb2Ygci5zdWI9PT1cIm9iamVjdFwiKXtpZighcChnLnN1YixyLnN1Yikpe3JldHVybiBmYWxzZX19aWYoZy5hdWQhPT11bmRlZmluZWQmJnR5cGVvZiByLmF1ZD09PVwib2JqZWN0XCIpe2lmKHR5cGVvZiBnLmF1ZD09XCJzdHJpbmdcIil7aWYoIXAoZy5hdWQsci5hdWQpKXtyZXR1cm4gZmFsc2V9fWVsc2V7aWYodHlwZW9mIGcuYXVkPT1cIm9iamVjdFwiKXtpZighZihnLmF1ZCxyLmF1ZCkpe3JldHVybiBmYWxzZX19fX12YXIgYj1qLkludERhdGUuZ2V0Tm93KCk7aWYoci52ZXJpZnlBdCE9PXVuZGVmaW5lZCYmdHlwZW9mIHIudmVyaWZ5QXQ9PT1cIm51bWJlclwiKXtiPXIudmVyaWZ5QXR9aWYoci5ncmFjZVBlcmlvZD09PXVuZGVmaW5lZHx8dHlwZW9mIHIuZ3JhY2VQZXJpb2QhPT1cIm51bWJlclwiKXtyLmdyYWNlUGVyaW9kPTB9aWYoZy5leHAhPT11bmRlZmluZWQmJnR5cGVvZiBnLmV4cD09XCJudW1iZXJcIil7aWYoZy5leHArci5ncmFjZVBlcmlvZDxiKXtyZXR1cm4gZmFsc2V9fWlmKGcubmJmIT09dW5kZWZpbmVkJiZ0eXBlb2YgZy5uYmY9PVwibnVtYmVyXCIpe2lmKGI8Zy5uYmYtci5ncmFjZVBlcmlvZCl7cmV0dXJuIGZhbHNlfX1pZihnLmlhdCE9PXVuZGVmaW5lZCYmdHlwZW9mIGcuaWF0PT1cIm51bWJlclwiKXtpZihiPGcuaWF0LXIuZ3JhY2VQZXJpb2Qpe3JldHVybiBmYWxzZX19aWYoZy5qdGkhPT11bmRlZmluZWQmJnIuanRpIT09dW5kZWZpbmVkKXtpZihnLmp0aSE9PXIuanRpKXtyZXR1cm4gZmFsc2V9fWlmKCFvLnZlcmlmeShlLGwsci5hbGcpKXtyZXR1cm4gZmFsc2V9cmV0dXJuIHRydWV9O0tKVVIuandzLkpXUy5pbmNsdWRlZEFycmF5PWZ1bmN0aW9uKGIsYSl7dmFyIGM9S0pVUi5qd3MuSldTLmluQXJyYXk7aWYoYj09PW51bGwpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYiE9PVwib2JqZWN0XCIpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYi5sZW5ndGghPT1cIm51bWJlclwiKXtyZXR1cm4gZmFsc2V9Zm9yKHZhciBkPTA7ZDxiLmxlbmd0aDtkKyspe2lmKCFjKGJbZF0sYSkpe3JldHVybiBmYWxzZX19cmV0dXJuIHRydWV9O0tKVVIuandzLkpXUy5pbkFycmF5PWZ1bmN0aW9uKGQsYil7aWYoYj09PW51bGwpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYiE9PVwib2JqZWN0XCIpe3JldHVybiBmYWxzZX1pZih0eXBlb2YgYi5sZW5ndGghPT1cIm51bWJlclwiKXtyZXR1cm4gZmFsc2V9Zm9yKHZhciBjPTA7YzxiLmxlbmd0aDtjKyspe2lmKGJbY109PWQpe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9O0tKVVIuandzLkpXUy5qd3NhbGcyc2lnYWxnPXtIUzI1NjpcIkhtYWNTSEEyNTZcIixIUzM4NDpcIkhtYWNTSEEzODRcIixIUzUxMjpcIkhtYWNTSEE1MTJcIixSUzI1NjpcIlNIQTI1NndpdGhSU0FcIixSUzM4NDpcIlNIQTM4NHdpdGhSU0FcIixSUzUxMjpcIlNIQTUxMndpdGhSU0FcIixFUzI1NjpcIlNIQTI1NndpdGhFQ0RTQVwiLEVTMzg0OlwiU0hBMzg0d2l0aEVDRFNBXCIsUFMyNTY6XCJTSEEyNTZ3aXRoUlNBYW5kTUdGMVwiLFBTMzg0OlwiU0hBMzg0d2l0aFJTQWFuZE1HRjFcIixQUzUxMjpcIlNIQTUxMndpdGhSU0FhbmRNR0YxXCIsbm9uZTpcIm5vbmVcIix9O0tKVVIuandzLkpXUy5pc1NhZmVKU09OU3RyaW5nPWZ1bmN0aW9uKGMsYixkKXt2YXIgZT1udWxsO3RyeXtlPWpzb25QYXJzZShjKTtpZih0eXBlb2YgZSE9XCJvYmplY3RcIil7cmV0dXJuIDB9aWYoZS5jb25zdHJ1Y3Rvcj09PUFycmF5KXtyZXR1cm4gMH1pZihiKXtiW2RdPWV9cmV0dXJuIDF9Y2F0Y2goYSl7cmV0dXJuIDB9fTtLSlVSLmp3cy5KV1MucmVhZFNhZmVKU09OU3RyaW5nPWZ1bmN0aW9uKGIpe3ZhciBjPW51bGw7dHJ5e2M9anNvblBhcnNlKGIpO2lmKHR5cGVvZiBjIT1cIm9iamVjdFwiKXtyZXR1cm4gbnVsbH1pZihjLmNvbnN0cnVjdG9yPT09QXJyYXkpe3JldHVybiBudWxsfXJldHVybiBjfWNhdGNoKGEpe3JldHVybiBudWxsfX07S0pVUi5qd3MuSldTLmdldEVuY29kZWRTaWduYXR1cmVWYWx1ZUZyb21KV1M9ZnVuY3Rpb24oYil7dmFyIGE9Yi5tYXRjaCgvXlteLl0rXFwuW14uXStcXC4oW14uXSspJC8pO2lmKGE9PW51bGwpe3Rocm93XCJKV1Mgc2lnbmF0dXJlIGlzIG5vdCBhIGZvcm0gb2YgJ0hlYWQuUGF5bG9hZC5TaWdWYWx1ZScuXCJ9cmV0dXJuIGFbMV19O0tKVVIuandzLkpXUy5nZXRKV0t0aHVtYnByaW50PWZ1bmN0aW9uKGQpe2lmKGQua3R5IT09XCJSU0FcIiYmZC5rdHkhPT1cIkVDXCImJmQua3R5IT09XCJvY3RcIil7dGhyb3dcInVuc3VwcG9ydGVkIGFsZ29yaXRobSBmb3IgSldLIFRodW1wcmludFwifXZhciBhPVwie1wiO2lmKGQua3R5PT09XCJSU0FcIil7aWYodHlwZW9mIGQubiE9XCJzdHJpbmdcInx8dHlwZW9mIGQuZSE9XCJzdHJpbmdcIil7dGhyb3dcIndyb25nIG4gYW5kIGUgdmFsdWUgZm9yIFJTQSBrZXlcIn1hKz0nXCJlXCI6XCInK2QuZSsnXCIsJzthKz0nXCJrdHlcIjpcIicrZC5rdHkrJ1wiLCc7YSs9J1wiblwiOlwiJytkLm4rJ1wifSd9ZWxzZXtpZihkLmt0eT09PVwiRUNcIil7aWYodHlwZW9mIGQuY3J2IT1cInN0cmluZ1wifHx0eXBlb2YgZC54IT1cInN0cmluZ1wifHx0eXBlb2YgZC55IT1cInN0cmluZ1wiKXt0aHJvd1wid3JvbmcgY3J2LCB4IGFuZCB5IHZhbHVlIGZvciBFQyBrZXlcIn1hKz0nXCJjcnZcIjpcIicrZC5jcnYrJ1wiLCc7YSs9J1wia3R5XCI6XCInK2Qua3R5KydcIiwnO2ErPSdcInhcIjpcIicrZC54KydcIiwnO2ErPSdcInlcIjpcIicrZC55KydcIn0nfWVsc2V7aWYoZC5rdHk9PT1cIm9jdFwiKXtpZih0eXBlb2YgZC5rIT1cInN0cmluZ1wiKXt0aHJvd1wid3JvbmcgayB2YWx1ZSBmb3Igb2N0KHN5bW1ldHJpYykga2V5XCJ9YSs9J1wia3R5XCI6XCInK2Qua3R5KydcIiwnO2ErPSdcImtcIjpcIicrZC5rKydcIn0nfX19dmFyIGI9cnN0cnRvaGV4KGEpO3ZhciBjPUtKVVIuY3J5cHRvLlV0aWwuaGFzaEhleChiLFwic2hhMjU2XCIpO3ZhciBlPWhleHRvYjY0dShjKTtyZXR1cm4gZX07S0pVUi5qd3MuSW50RGF0ZT17fTtLSlVSLmp3cy5JbnREYXRlLmdldD1mdW5jdGlvbihjKXt2YXIgYj1LSlVSLmp3cy5JbnREYXRlLGQ9Yi5nZXROb3csYT1iLmdldFp1bHU7aWYoYz09XCJub3dcIil7cmV0dXJuIGQoKX1lbHNle2lmKGM9PVwibm93ICsgMWhvdXJcIil7cmV0dXJuIGQoKSs2MCo2MH1lbHNle2lmKGM9PVwibm93ICsgMWRheVwiKXtyZXR1cm4gZCgpKzYwKjYwKjI0fWVsc2V7aWYoYz09XCJub3cgKyAxbW9udGhcIil7cmV0dXJuIGQoKSs2MCo2MCoyNCozMH1lbHNle2lmKGM9PVwibm93ICsgMXllYXJcIil7cmV0dXJuIGQoKSs2MCo2MCoyNCozNjV9ZWxzZXtpZihjLm1hdGNoKC9aJC8pKXtyZXR1cm4gYShjKX1lbHNle2lmKGMubWF0Y2goL15bMC05XSskLykpe3JldHVybiBwYXJzZUludChjKX19fX19fX10aHJvd1widW5zdXBwb3J0ZWQgZm9ybWF0OiBcIitjfTtLSlVSLmp3cy5JbnREYXRlLmdldFp1bHU9ZnVuY3Rpb24oYSl7cmV0dXJuIHp1bHV0b3NlYyhhKX07S0pVUi5qd3MuSW50RGF0ZS5nZXROb3c9ZnVuY3Rpb24oKXt2YXIgYT1+fihuZXcgRGF0ZSgpLzEwMDApO3JldHVybiBhfTtLSlVSLmp3cy5JbnREYXRlLmludERhdGUyVVRDU3RyaW5nPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyBEYXRlKGEqMTAwMCk7cmV0dXJuIGIudG9VVENTdHJpbmcoKX07S0pVUi5qd3MuSW50RGF0ZS5pbnREYXRlMlp1bHU9ZnVuY3Rpb24oZSl7dmFyIGk9bmV3IERhdGUoZSoxMDAwKSxoPShcIjAwMDBcIitpLmdldFVUQ0Z1bGxZZWFyKCkpLnNsaWNlKC00KSxnPShcIjAwXCIrKGkuZ2V0VVRDTW9udGgoKSsxKSkuc2xpY2UoLTIpLGI9KFwiMDBcIitpLmdldFVUQ0RhdGUoKSkuc2xpY2UoLTIpLGE9KFwiMDBcIitpLmdldFVUQ0hvdXJzKCkpLnNsaWNlKC0yKSxjPShcIjAwXCIraS5nZXRVVENNaW51dGVzKCkpLnNsaWNlKC0yKSxmPShcIjAwXCIraS5nZXRVVENTZWNvbmRzKCkpLnNsaWNlKC0yKTtyZXR1cm4gaCtnK2IrYStjK2YrXCJaXCJ9O1xuZXhwb3J0IHsgU2VjdXJlUmFuZG9tIH07XHJcbmV4cG9ydCB7IHJuZ19zZWVkX3RpbWUgfTtcclxuXHJcbmV4cG9ydCB7IEJpZ0ludGVnZXIgfTtcclxuZXhwb3J0IHsgUlNBS2V5IH07XHJcbmV4cG9ydCBjb25zdCB7IEVEU0EgfSA9IEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBEU0EgfSA9IEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBTaWduYXR1cmUgfSA9IEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgY29uc3QgeyBNZXNzYWdlRGlnZXN0IH0gPSAgS0pVUi5jcnlwdG87XHJcbmV4cG9ydCBjb25zdCB7IE1hYyB9ID0gS0pVUi5jcnlwdG87XHJcbmV4cG9ydCBjb25zdCB7IENpcGhlciB9ID0gIEtKVVIuY3J5cHRvO1xyXG5leHBvcnQgeyBLRVlVVElMIH07XHJcbmV4cG9ydCB7IEFTTjFIRVggfTtcclxuZXhwb3J0IHsgWDUwOSB9O1xyXG5leHBvcnQgeyBDcnlwdG9KUyB9O1xyXG5cclxuLy8gZXh0L2Jhc2U2NC5qc1xyXG5leHBvcnQgeyBiNjR0b2hleCB9O1xyXG5leHBvcnQgeyBiNjR0b0JBIH07XHJcblxyXG4vLyBiYXNlNjR4LmpzXHJcbmV4cG9ydCB7IHN0b0JBIH07XHJcbmV4cG9ydCB7IEJBdG9zIH07XHJcbmV4cG9ydCB7IEJBdG9oZXggfTtcclxuZXhwb3J0IHsgc3RvaGV4IH07XHJcbmV4cG9ydCB7IHN0b2I2NCB9O1xyXG5leHBvcnQgeyBzdG9iNjR1IH07XHJcbmV4cG9ydCB7IGI2NHV0b3MgfTtcclxuZXhwb3J0IHsgYjY0dG9iNjR1IH07XHJcbmV4cG9ydCB7IGI2NHV0b2I2NCB9O1xyXG5leHBvcnQgeyBoZXgyYjY0IH07XHJcbmV4cG9ydCB7IGhleHRvYjY0dSB9O1xyXG5leHBvcnQgeyBiNjR1dG9oZXggfTtcclxuZXhwb3J0IHsgdXRmOHRvYjY0dSB9O1xyXG5leHBvcnQgeyBiNjR1dG91dGY4IH07XHJcbmV4cG9ydCB7IHV0Zjh0b2I2NCB9O1xyXG5leHBvcnQgeyBiNjR0b3V0ZjggfTtcclxuZXhwb3J0IHsgdXRmOHRvaGV4IH07XHJcbmV4cG9ydCB7IGhleHRvdXRmOCB9O1xyXG5leHBvcnQgeyBoZXh0b3JzdHIgfTtcclxuZXhwb3J0IHsgcnN0cnRvaGV4IH07XHJcbmV4cG9ydCB7IGhleHRvYjY0IH07XHJcbmV4cG9ydCB7IGhleHRvYjY0bmwgfTtcclxuZXhwb3J0IHsgYjY0bmx0b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b3BlbSB9O1xyXG5leHBvcnQgeyBwZW10b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b0FycmF5QnVmZmVyIH07XHJcbmV4cG9ydCB7IEFycmF5QnVmZmVydG9oZXggfTtcclxuZXhwb3J0IHsgenVsdXRvbXNlYyB9O1xyXG5leHBvcnQgeyB6dWx1dG9zZWMgfTtcclxuZXhwb3J0IHsgenVsdXRvZGF0ZSB9O1xyXG5leHBvcnQgeyBkYXRldG96dWx1IH07XHJcbmV4cG9ydCB7IHVyaWNtcHRvaGV4IH07XHJcbmV4cG9ydCB7IGhleHRvdXJpY21wIH07XHJcbmV4cG9ydCB7IGlwdjZ0b2hleCB9O1xyXG5leHBvcnQgeyBoZXh0b2lwdjYgfTtcclxuZXhwb3J0IHsgaGV4dG9pcCB9O1xyXG5leHBvcnQgeyBpcHRvaGV4IH07XHJcbmV4cG9ydCB7IGVuY29kZVVSSUNvbXBvbmVudEFsbCB9O1xyXG5leHBvcnQgeyBuZXdsaW5lX3RvVW5peCB9O1xyXG5leHBvcnQgeyBuZXdsaW5lX3RvRG9zIH07XHJcbmV4cG9ydCB7IGhleHRvcG9zaGV4IH07XHJcbmV4cG9ydCB7IGludGFyeXN0cnRvaGV4IH07XHJcbmV4cG9ydCB7IHN0cmRpZmZpZHggfTtcclxuXHJcbi8vIG5hbWUgc3BhY2VzXHJcbmV4cG9ydCB7IEtKVVIgfTtcclxuY29uc3QgX2NyeXB0byA9ICBLSlVSLmNyeXB0bztcclxuZXhwb3J0IHsgX2NyeXB0byBhcyBjcnlwdG8gfTtcclxuZXhwb3J0IGNvbnN0IHsgYXNuMSB9ID0gS0pVUjtcclxuZXhwb3J0IGNvbnN0IHsgandzIH0gPSBLSlVSO1xyXG5leHBvcnQgY29uc3QgeyBsYW5nIH0gPSBLSlVSO1xyXG5cclxuXHJcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9zaGltXCIpO1xuXG5yZXF1aXJlKFwicmVnZW5lcmF0b3ItcnVudGltZS9ydW50aW1lXCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9yZWdleHAvZXNjYXBlXCIpO1xuXG5pZiAoZ2xvYmFsLl9iYWJlbFBvbHlmaWxsKSB7XG4gIHRocm93IG5ldyBFcnJvcihcIm9ubHkgb25lIGluc3RhbmNlIG9mIGJhYmVsLXBvbHlmaWxsIGlzIGFsbG93ZWRcIik7XG59XG5nbG9iYWwuX2JhYmVsUG9seWZpbGwgPSB0cnVlO1xuXG52YXIgREVGSU5FX1BST1BFUlRZID0gXCJkZWZpbmVQcm9wZXJ0eVwiO1xuZnVuY3Rpb24gZGVmaW5lKE8sIGtleSwgdmFsdWUpIHtcbiAgT1trZXldIHx8IE9iamVjdFtERUZJTkVfUFJPUEVSVFldKE8sIGtleSwge1xuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfSk7XG59XG5cbmRlZmluZShTdHJpbmcucHJvdG90eXBlLCBcInBhZExlZnRcIiwgXCJcIi5wYWRTdGFydCk7XG5kZWZpbmUoU3RyaW5nLnByb3RvdHlwZSwgXCJwYWRSaWdodFwiLCBcIlwiLnBhZEVuZCk7XG5cblwicG9wLHJldmVyc2Usc2hpZnQsa2V5cyx2YWx1ZXMsZW50cmllcyxpbmRleE9mLGV2ZXJ5LHNvbWUsZm9yRWFjaCxtYXAsZmlsdGVyLGZpbmQsZmluZEluZGV4LGluY2x1ZGVzLGpvaW4sc2xpY2UsY29uY2F0LHB1c2gsc3BsaWNlLHVuc2hpZnQsc29ydCxsYXN0SW5kZXhPZixyZWR1Y2UscmVkdWNlUmlnaHQsY29weVdpdGhpbixmaWxsXCIuc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICBbXVtrZXldICYmIGRlZmluZShBcnJheSwga2V5LCBGdW5jdGlvbi5jYWxsLmJpbmQoW11ba2V5XSkpO1xufSk7IiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogaHR0cHM6Ly9yYXcuZ2l0aHViLmNvbS9mYWNlYm9vay9yZWdlbmVyYXRvci9tYXN0ZXIvTElDRU5TRSBmaWxlLiBBblxuICogYWRkaXRpb25hbCBncmFudCBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluXG4gKiB0aGUgc2FtZSBkaXJlY3RvcnkuXG4gKi9cblxuIShmdW5jdGlvbihnbG9iYWwpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgdmFyIE9wID0gT2JqZWN0LnByb3RvdHlwZTtcbiAgdmFyIGhhc093biA9IE9wLmhhc093blByb3BlcnR5O1xuICB2YXIgdW5kZWZpbmVkOyAvLyBNb3JlIGNvbXByZXNzaWJsZSB0aGFuIHZvaWQgMC5cbiAgdmFyICRTeW1ib2wgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgPyBTeW1ib2wgOiB7fTtcbiAgdmFyIGl0ZXJhdG9yU3ltYm9sID0gJFN5bWJvbC5pdGVyYXRvciB8fCBcIkBAaXRlcmF0b3JcIjtcbiAgdmFyIGFzeW5jSXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLmFzeW5jSXRlcmF0b3IgfHwgXCJAQGFzeW5jSXRlcmF0b3JcIjtcbiAgdmFyIHRvU3RyaW5nVGFnU3ltYm9sID0gJFN5bWJvbC50b1N0cmluZ1RhZyB8fCBcIkBAdG9TdHJpbmdUYWdcIjtcblxuICB2YXIgaW5Nb2R1bGUgPSB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiO1xuICB2YXIgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWU7XG4gIGlmIChydW50aW1lKSB7XG4gICAgaWYgKGluTW9kdWxlKSB7XG4gICAgICAvLyBJZiByZWdlbmVyYXRvclJ1bnRpbWUgaXMgZGVmaW5lZCBnbG9iYWxseSBhbmQgd2UncmUgaW4gYSBtb2R1bGUsXG4gICAgICAvLyBtYWtlIHRoZSBleHBvcnRzIG9iamVjdCBpZGVudGljYWwgdG8gcmVnZW5lcmF0b3JSdW50aW1lLlxuICAgICAgbW9kdWxlLmV4cG9ydHMgPSBydW50aW1lO1xuICAgIH1cbiAgICAvLyBEb24ndCBib3RoZXIgZXZhbHVhdGluZyB0aGUgcmVzdCBvZiB0aGlzIGZpbGUgaWYgdGhlIHJ1bnRpbWUgd2FzXG4gICAgLy8gYWxyZWFkeSBkZWZpbmVkIGdsb2JhbGx5LlxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIERlZmluZSB0aGUgcnVudGltZSBnbG9iYWxseSAoYXMgZXhwZWN0ZWQgYnkgZ2VuZXJhdGVkIGNvZGUpIGFzIGVpdGhlclxuICAvLyBtb2R1bGUuZXhwb3J0cyAoaWYgd2UncmUgaW4gYSBtb2R1bGUpIG9yIGEgbmV3LCBlbXB0eSBvYmplY3QuXG4gIHJ1bnRpbWUgPSBnbG9iYWwucmVnZW5lcmF0b3JSdW50aW1lID0gaW5Nb2R1bGUgPyBtb2R1bGUuZXhwb3J0cyA6IHt9O1xuXG4gIGZ1bmN0aW9uIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBJZiBvdXRlckZuIHByb3ZpZGVkIGFuZCBvdXRlckZuLnByb3RvdHlwZSBpcyBhIEdlbmVyYXRvciwgdGhlbiBvdXRlckZuLnByb3RvdHlwZSBpbnN0YW5jZW9mIEdlbmVyYXRvci5cbiAgICB2YXIgcHJvdG9HZW5lcmF0b3IgPSBvdXRlckZuICYmIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yID8gb3V0ZXJGbiA6IEdlbmVyYXRvcjtcbiAgICB2YXIgZ2VuZXJhdG9yID0gT2JqZWN0LmNyZWF0ZShwcm90b0dlbmVyYXRvci5wcm90b3R5cGUpO1xuICAgIHZhciBjb250ZXh0ID0gbmV3IENvbnRleHQodHJ5TG9jc0xpc3QgfHwgW10pO1xuXG4gICAgLy8gVGhlIC5faW52b2tlIG1ldGhvZCB1bmlmaWVzIHRoZSBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcy5cbiAgICBnZW5lcmF0b3IuX2ludm9rZSA9IG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gZ2VuZXJhdG9yO1xuICB9XG4gIHJ1bnRpbWUud3JhcCA9IHdyYXA7XG5cbiAgLy8gVHJ5L2NhdGNoIGhlbHBlciB0byBtaW5pbWl6ZSBkZW9wdGltaXphdGlvbnMuIFJldHVybnMgYSBjb21wbGV0aW9uXG4gIC8vIHJlY29yZCBsaWtlIGNvbnRleHQudHJ5RW50cmllc1tpXS5jb21wbGV0aW9uLiBUaGlzIGludGVyZmFjZSBjb3VsZFxuICAvLyBoYXZlIGJlZW4gKGFuZCB3YXMgcHJldmlvdXNseSkgZGVzaWduZWQgdG8gdGFrZSBhIGNsb3N1cmUgdG8gYmVcbiAgLy8gaW52b2tlZCB3aXRob3V0IGFyZ3VtZW50cywgYnV0IGluIGFsbCB0aGUgY2FzZXMgd2UgY2FyZSBhYm91dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYW4gZXhpc3RpbmcgbWV0aG9kIHdlIHdhbnQgdG8gY2FsbCwgc28gdGhlcmUncyBubyBuZWVkXG4gIC8vIHRvIGNyZWF0ZSBhIG5ldyBmdW5jdGlvbiBvYmplY3QuIFdlIGNhbiBldmVuIGdldCBhd2F5IHdpdGggYXNzdW1pbmdcbiAgLy8gdGhlIG1ldGhvZCB0YWtlcyBleGFjdGx5IG9uZSBhcmd1bWVudCwgc2luY2UgdGhhdCBoYXBwZW5zIHRvIGJlIHRydWVcbiAgLy8gaW4gZXZlcnkgY2FzZSwgc28gd2UgZG9uJ3QgaGF2ZSB0byB0b3VjaCB0aGUgYXJndW1lbnRzIG9iamVjdC4gVGhlXG4gIC8vIG9ubHkgYWRkaXRpb25hbCBhbGxvY2F0aW9uIHJlcXVpcmVkIGlzIHRoZSBjb21wbGV0aW9uIHJlY29yZCwgd2hpY2hcbiAgLy8gaGFzIGEgc3RhYmxlIHNoYXBlIGFuZCBzbyBob3BlZnVsbHkgc2hvdWxkIGJlIGNoZWFwIHRvIGFsbG9jYXRlLlxuICBmdW5jdGlvbiB0cnlDYXRjaChmbiwgb2JqLCBhcmcpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJub3JtYWxcIiwgYXJnOiBmbi5jYWxsKG9iaiwgYXJnKSB9O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0aHJvd1wiLCBhcmc6IGVyciB9O1xuICAgIH1cbiAgfVxuXG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0ID0gXCJzdXNwZW5kZWRTdGFydFwiO1xuICB2YXIgR2VuU3RhdGVTdXNwZW5kZWRZaWVsZCA9IFwic3VzcGVuZGVkWWllbGRcIjtcbiAgdmFyIEdlblN0YXRlRXhlY3V0aW5nID0gXCJleGVjdXRpbmdcIjtcbiAgdmFyIEdlblN0YXRlQ29tcGxldGVkID0gXCJjb21wbGV0ZWRcIjtcblxuICAvLyBSZXR1cm5pbmcgdGhpcyBvYmplY3QgZnJvbSB0aGUgaW5uZXJGbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzXG4gIC8vIGJyZWFraW5nIG91dCBvZiB0aGUgZGlzcGF0Y2ggc3dpdGNoIHN0YXRlbWVudC5cbiAgdmFyIENvbnRpbnVlU2VudGluZWwgPSB7fTtcblxuICAvLyBEdW1teSBjb25zdHJ1Y3RvciBmdW5jdGlvbnMgdGhhdCB3ZSB1c2UgYXMgdGhlIC5jb25zdHJ1Y3RvciBhbmRcbiAgLy8gLmNvbnN0cnVjdG9yLnByb3RvdHlwZSBwcm9wZXJ0aWVzIGZvciBmdW5jdGlvbnMgdGhhdCByZXR1cm4gR2VuZXJhdG9yXG4gIC8vIG9iamVjdHMuIEZvciBmdWxsIHNwZWMgY29tcGxpYW5jZSwgeW91IG1heSB3aXNoIHRvIGNvbmZpZ3VyZSB5b3VyXG4gIC8vIG1pbmlmaWVyIG5vdCB0byBtYW5nbGUgdGhlIG5hbWVzIG9mIHRoZXNlIHR3byBmdW5jdGlvbnMuXG4gIGZ1bmN0aW9uIEdlbmVyYXRvcigpIHt9XG4gIGZ1bmN0aW9uIEdlbmVyYXRvckZ1bmN0aW9uKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUoKSB7fVxuXG4gIC8vIFRoaXMgaXMgYSBwb2x5ZmlsbCBmb3IgJUl0ZXJhdG9yUHJvdG90eXBlJSBmb3IgZW52aXJvbm1lbnRzIHRoYXRcbiAgLy8gZG9uJ3QgbmF0aXZlbHkgc3VwcG9ydCBpdC5cbiAgdmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG4gIEl0ZXJhdG9yUHJvdG90eXBlW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICB2YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7XG4gIHZhciBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvICYmIGdldFByb3RvKGdldFByb3RvKHZhbHVlcyhbXSkpKTtcbiAgaWYgKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICYmXG4gICAgICBOYXRpdmVJdGVyYXRvclByb3RvdHlwZSAhPT0gT3AgJiZcbiAgICAgIGhhc093bi5jYWxsKE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlLCBpdGVyYXRvclN5bWJvbCkpIHtcbiAgICAvLyBUaGlzIGVudmlyb25tZW50IGhhcyBhIG5hdGl2ZSAlSXRlcmF0b3JQcm90b3R5cGUlOyB1c2UgaXQgaW5zdGVhZFxuICAgIC8vIG9mIHRoZSBwb2x5ZmlsbC5cbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlO1xuICB9XG5cbiAgdmFyIEdwID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUucHJvdG90eXBlID1cbiAgICBHZW5lcmF0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShJdGVyYXRvclByb3RvdHlwZSk7XG4gIEdlbmVyYXRvckZ1bmN0aW9uLnByb3RvdHlwZSA9IEdwLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlLmNvbnN0cnVjdG9yID0gR2VuZXJhdG9yRnVuY3Rpb247XG4gIEdlbmVyYXRvckZ1bmN0aW9uUHJvdG90eXBlW3RvU3RyaW5nVGFnU3ltYm9sXSA9XG4gICAgR2VuZXJhdG9yRnVuY3Rpb24uZGlzcGxheU5hbWUgPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG5cbiAgLy8gSGVscGVyIGZvciBkZWZpbmluZyB0aGUgLm5leHQsIC50aHJvdywgYW5kIC5yZXR1cm4gbWV0aG9kcyBvZiB0aGVcbiAgLy8gSXRlcmF0b3IgaW50ZXJmYWNlIGluIHRlcm1zIG9mIGEgc2luZ2xlIC5faW52b2tlIG1ldGhvZC5cbiAgZnVuY3Rpb24gZGVmaW5lSXRlcmF0b3JNZXRob2RzKHByb3RvdHlwZSkge1xuICAgIFtcIm5leHRcIiwgXCJ0aHJvd1wiLCBcInJldHVyblwiXS5mb3JFYWNoKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgcHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbihhcmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ludm9rZShtZXRob2QsIGFyZyk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcnVudGltZS5pc0dlbmVyYXRvckZ1bmN0aW9uID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgdmFyIGN0b3IgPSB0eXBlb2YgZ2VuRnVuID09PSBcImZ1bmN0aW9uXCIgJiYgZ2VuRnVuLmNvbnN0cnVjdG9yO1xuICAgIHJldHVybiBjdG9yXG4gICAgICA/IGN0b3IgPT09IEdlbmVyYXRvckZ1bmN0aW9uIHx8XG4gICAgICAgIC8vIEZvciB0aGUgbmF0aXZlIEdlbmVyYXRvckZ1bmN0aW9uIGNvbnN0cnVjdG9yLCB0aGUgYmVzdCB3ZSBjYW5cbiAgICAgICAgLy8gZG8gaXMgdG8gY2hlY2sgaXRzIC5uYW1lIHByb3BlcnR5LlxuICAgICAgICAoY3Rvci5kaXNwbGF5TmFtZSB8fCBjdG9yLm5hbWUpID09PSBcIkdlbmVyYXRvckZ1bmN0aW9uXCJcbiAgICAgIDogZmFsc2U7XG4gIH07XG5cbiAgcnVudGltZS5tYXJrID0gZnVuY3Rpb24oZ2VuRnVuKSB7XG4gICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGdlbkZ1biwgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBnZW5GdW4uX19wcm90b19fID0gR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGU7XG4gICAgICBpZiAoISh0b1N0cmluZ1RhZ1N5bWJvbCBpbiBnZW5GdW4pKSB7XG4gICAgICAgIGdlbkZ1blt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvckZ1bmN0aW9uXCI7XG4gICAgICB9XG4gICAgfVxuICAgIGdlbkZ1bi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEdwKTtcbiAgICByZXR1cm4gZ2VuRnVuO1xuICB9O1xuXG4gIC8vIFdpdGhpbiB0aGUgYm9keSBvZiBhbnkgYXN5bmMgZnVuY3Rpb24sIGBhd2FpdCB4YCBpcyB0cmFuc2Zvcm1lZCB0b1xuICAvLyBgeWllbGQgcmVnZW5lcmF0b3JSdW50aW1lLmF3cmFwKHgpYCwgc28gdGhhdCB0aGUgcnVudGltZSBjYW4gdGVzdFxuICAvLyBgaGFzT3duLmNhbGwodmFsdWUsIFwiX19hd2FpdFwiKWAgdG8gZGV0ZXJtaW5lIGlmIHRoZSB5aWVsZGVkIHZhbHVlIGlzXG4gIC8vIG1lYW50IHRvIGJlIGF3YWl0ZWQuXG4gIHJ1bnRpbWUuYXdyYXAgPSBmdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4geyBfX2F3YWl0OiBhcmcgfTtcbiAgfTtcblxuICBmdW5jdGlvbiBBc3luY0l0ZXJhdG9yKGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGludm9rZShtZXRob2QsIGFyZywgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2goZ2VuZXJhdG9yW21ldGhvZF0sIGdlbmVyYXRvciwgYXJnKTtcbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHJlamVjdChyZWNvcmQuYXJnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciByZXN1bHQgPSByZWNvcmQuYXJnO1xuICAgICAgICB2YXIgdmFsdWUgPSByZXN1bHQudmFsdWU7XG4gICAgICAgIGlmICh2YWx1ZSAmJlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZS5fX2F3YWl0KS50aGVuKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJuZXh0XCIsIHZhbHVlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0sIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgICAgaW52b2tlKFwidGhyb3dcIiwgZXJyLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkudGhlbihmdW5jdGlvbih1bndyYXBwZWQpIHtcbiAgICAgICAgICAvLyBXaGVuIGEgeWllbGRlZCBQcm9taXNlIGlzIHJlc29sdmVkLCBpdHMgZmluYWwgdmFsdWUgYmVjb21lc1xuICAgICAgICAgIC8vIHRoZSAudmFsdWUgb2YgdGhlIFByb21pc2U8e3ZhbHVlLGRvbmV9PiByZXN1bHQgZm9yIHRoZVxuICAgICAgICAgIC8vIGN1cnJlbnQgaXRlcmF0aW9uLiBJZiB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCwgaG93ZXZlciwgdGhlXG4gICAgICAgICAgLy8gcmVzdWx0IGZvciB0aGlzIGl0ZXJhdGlvbiB3aWxsIGJlIHJlamVjdGVkIHdpdGggdGhlIHNhbWVcbiAgICAgICAgICAvLyByZWFzb24uIE5vdGUgdGhhdCByZWplY3Rpb25zIG9mIHlpZWxkZWQgUHJvbWlzZXMgYXJlIG5vdFxuICAgICAgICAgIC8vIHRocm93biBiYWNrIGludG8gdGhlIGdlbmVyYXRvciBmdW5jdGlvbiwgYXMgaXMgdGhlIGNhc2VcbiAgICAgICAgICAvLyB3aGVuIGFuIGF3YWl0ZWQgUHJvbWlzZSBpcyByZWplY3RlZC4gVGhpcyBkaWZmZXJlbmNlIGluXG4gICAgICAgICAgLy8gYmVoYXZpb3IgYmV0d2VlbiB5aWVsZCBhbmQgYXdhaXQgaXMgaW1wb3J0YW50LCBiZWNhdXNlIGl0XG4gICAgICAgICAgLy8gYWxsb3dzIHRoZSBjb25zdW1lciB0byBkZWNpZGUgd2hhdCB0byBkbyB3aXRoIHRoZSB5aWVsZGVkXG4gICAgICAgICAgLy8gcmVqZWN0aW9uIChzd2FsbG93IGl0IGFuZCBjb250aW51ZSwgbWFudWFsbHkgLnRocm93IGl0IGJhY2tcbiAgICAgICAgICAvLyBpbnRvIHRoZSBnZW5lcmF0b3IsIGFiYW5kb24gaXRlcmF0aW9uLCB3aGF0ZXZlcikuIFdpdGhcbiAgICAgICAgICAvLyBhd2FpdCwgYnkgY29udHJhc3QsIHRoZXJlIGlzIG5vIG9wcG9ydHVuaXR5IHRvIGV4YW1pbmUgdGhlXG4gICAgICAgICAgLy8gcmVqZWN0aW9uIHJlYXNvbiBvdXRzaWRlIHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24sIHNvIHRoZVxuICAgICAgICAgIC8vIG9ubHkgb3B0aW9uIGlzIHRvIHRocm93IGl0IGZyb20gdGhlIGF3YWl0IGV4cHJlc3Npb24sIGFuZFxuICAgICAgICAgIC8vIGxldCB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGhhbmRsZSB0aGUgZXhjZXB0aW9uLlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IHVud3JhcHBlZDtcbiAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0sIHJlamVjdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBnbG9iYWwucHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBnbG9iYWwucHJvY2Vzcy5kb21haW4pIHtcbiAgICAgIGludm9rZSA9IGdsb2JhbC5wcm9jZXNzLmRvbWFpbi5iaW5kKGludm9rZSk7XG4gICAgfVxuXG4gICAgdmFyIHByZXZpb3VzUHJvbWlzZTtcblxuICAgIGZ1bmN0aW9uIGVucXVldWUobWV0aG9kLCBhcmcpIHtcbiAgICAgIGZ1bmN0aW9uIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByZXZpb3VzUHJvbWlzZSA9XG4gICAgICAgIC8vIElmIGVucXVldWUgaGFzIGJlZW4gY2FsbGVkIGJlZm9yZSwgdGhlbiB3ZSB3YW50IHRvIHdhaXQgdW50aWxcbiAgICAgICAgLy8gYWxsIHByZXZpb3VzIFByb21pc2VzIGhhdmUgYmVlbiByZXNvbHZlZCBiZWZvcmUgY2FsbGluZyBpbnZva2UsXG4gICAgICAgIC8vIHNvIHRoYXQgcmVzdWx0cyBhcmUgYWx3YXlzIGRlbGl2ZXJlZCBpbiB0aGUgY29ycmVjdCBvcmRlci4gSWZcbiAgICAgICAgLy8gZW5xdWV1ZSBoYXMgbm90IGJlZW4gY2FsbGVkIGJlZm9yZSwgdGhlbiBpdCBpcyBpbXBvcnRhbnQgdG9cbiAgICAgICAgLy8gY2FsbCBpbnZva2UgaW1tZWRpYXRlbHksIHdpdGhvdXQgd2FpdGluZyBvbiBhIGNhbGxiYWNrIHRvIGZpcmUsXG4gICAgICAgIC8vIHNvIHRoYXQgdGhlIGFzeW5jIGdlbmVyYXRvciBmdW5jdGlvbiBoYXMgdGhlIG9wcG9ydHVuaXR5IHRvIGRvXG4gICAgICAgIC8vIGFueSBuZWNlc3Nhcnkgc2V0dXAgaW4gYSBwcmVkaWN0YWJsZSB3YXkuIFRoaXMgcHJlZGljdGFiaWxpdHlcbiAgICAgICAgLy8gaXMgd2h5IHRoZSBQcm9taXNlIGNvbnN0cnVjdG9yIHN5bmNocm9ub3VzbHkgaW52b2tlcyBpdHNcbiAgICAgICAgLy8gZXhlY3V0b3IgY2FsbGJhY2ssIGFuZCB3aHkgYXN5bmMgZnVuY3Rpb25zIHN5bmNocm9ub3VzbHlcbiAgICAgICAgLy8gZXhlY3V0ZSBjb2RlIGJlZm9yZSB0aGUgZmlyc3QgYXdhaXQuIFNpbmNlIHdlIGltcGxlbWVudCBzaW1wbGVcbiAgICAgICAgLy8gYXN5bmMgZnVuY3Rpb25zIGluIHRlcm1zIG9mIGFzeW5jIGdlbmVyYXRvcnMsIGl0IGlzIGVzcGVjaWFsbHlcbiAgICAgICAgLy8gaW1wb3J0YW50IHRvIGdldCB0aGlzIHJpZ2h0LCBldmVuIHRob3VnaCBpdCByZXF1aXJlcyBjYXJlLlxuICAgICAgICBwcmV2aW91c1Byb21pc2UgPyBwcmV2aW91c1Byb21pc2UudGhlbihcbiAgICAgICAgICBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZyxcbiAgICAgICAgICAvLyBBdm9pZCBwcm9wYWdhdGluZyBmYWlsdXJlcyB0byBQcm9taXNlcyByZXR1cm5lZCBieSBsYXRlclxuICAgICAgICAgIC8vIGludm9jYXRpb25zIG9mIHRoZSBpdGVyYXRvci5cbiAgICAgICAgICBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZ1xuICAgICAgICApIDogY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcoKTtcbiAgICB9XG5cbiAgICAvLyBEZWZpbmUgdGhlIHVuaWZpZWQgaGVscGVyIG1ldGhvZCB0aGF0IGlzIHVzZWQgdG8gaW1wbGVtZW50IC5uZXh0LFxuICAgIC8vIC50aHJvdywgYW5kIC5yZXR1cm4gKHNlZSBkZWZpbmVJdGVyYXRvck1ldGhvZHMpLlxuICAgIHRoaXMuX2ludm9rZSA9IGVucXVldWU7XG4gIH1cblxuICBkZWZpbmVJdGVyYXRvck1ldGhvZHMoQXN5bmNJdGVyYXRvci5wcm90b3R5cGUpO1xuICBBc3luY0l0ZXJhdG9yLnByb3RvdHlwZVthc3luY0l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgcnVudGltZS5Bc3luY0l0ZXJhdG9yID0gQXN5bmNJdGVyYXRvcjtcblxuICAvLyBOb3RlIHRoYXQgc2ltcGxlIGFzeW5jIGZ1bmN0aW9ucyBhcmUgaW1wbGVtZW50ZWQgb24gdG9wIG9mXG4gIC8vIEFzeW5jSXRlcmF0b3Igb2JqZWN0czsgdGhleSBqdXN0IHJldHVybiBhIFByb21pc2UgZm9yIHRoZSB2YWx1ZSBvZlxuICAvLyB0aGUgZmluYWwgcmVzdWx0IHByb2R1Y2VkIGJ5IHRoZSBpdGVyYXRvci5cbiAgcnVudGltZS5hc3luYyA9IGZ1bmN0aW9uKGlubmVyRm4sIG91dGVyRm4sIHNlbGYsIHRyeUxvY3NMaXN0KSB7XG4gICAgdmFyIGl0ZXIgPSBuZXcgQXN5bmNJdGVyYXRvcihcbiAgICAgIHdyYXAoaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpXG4gICAgKTtcblxuICAgIHJldHVybiBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24ob3V0ZXJGbilcbiAgICAgID8gaXRlciAvLyBJZiBvdXRlckZuIGlzIGEgZ2VuZXJhdG9yLCByZXR1cm4gdGhlIGZ1bGwgaXRlcmF0b3IuXG4gICAgICA6IGl0ZXIubmV4dCgpLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdC5kb25lID8gcmVzdWx0LnZhbHVlIDogaXRlci5uZXh0KCk7XG4gICAgICAgIH0pO1xuICB9O1xuXG4gIGZ1bmN0aW9uIG1ha2VJbnZva2VNZXRob2QoaW5uZXJGbiwgc2VsZiwgY29udGV4dCkge1xuICAgIHZhciBzdGF0ZSA9IEdlblN0YXRlU3VzcGVuZGVkU3RhcnQ7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnKSB7XG4gICAgICBpZiAoc3RhdGUgPT09IEdlblN0YXRlRXhlY3V0aW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IHJ1bm5pbmdcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVDb21wbGV0ZWQpIHtcbiAgICAgICAgaWYgKG1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgdGhyb3cgYXJnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQmUgZm9yZ2l2aW5nLCBwZXIgMjUuMy4zLjMuMyBvZiB0aGUgc3BlYzpcbiAgICAgICAgLy8gaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLWdlbmVyYXRvcnJlc3VtZVxuICAgICAgICByZXR1cm4gZG9uZVJlc3VsdCgpO1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IG1ldGhvZDtcbiAgICAgIGNvbnRleHQuYXJnID0gYXJnO1xuXG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICB2YXIgZGVsZWdhdGUgPSBjb250ZXh0LmRlbGVnYXRlO1xuICAgICAgICBpZiAoZGVsZWdhdGUpIHtcbiAgICAgICAgICB2YXIgZGVsZWdhdGVSZXN1bHQgPSBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KTtcbiAgICAgICAgICBpZiAoZGVsZWdhdGVSZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCA9PT0gQ29udGludWVTZW50aW5lbCkgY29udGludWU7XG4gICAgICAgICAgICByZXR1cm4gZGVsZWdhdGVSZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcIm5leHRcIikge1xuICAgICAgICAgIC8vIFNldHRpbmcgY29udGV4dC5fc2VudCBmb3IgbGVnYWN5IHN1cHBvcnQgb2YgQmFiZWwnc1xuICAgICAgICAgIC8vIGZ1bmN0aW9uLnNlbnQgaW1wbGVtZW50YXRpb24uXG4gICAgICAgICAgY29udGV4dC5zZW50ID0gY29udGV4dC5fc2VudCA9IGNvbnRleHQuYXJnO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydCkge1xuICAgICAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUNvbXBsZXRlZDtcbiAgICAgICAgICAgIHRocm93IGNvbnRleHQuYXJnO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2hFeGNlcHRpb24oY29udGV4dC5hcmcpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5tZXRob2QgPT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgICBjb250ZXh0LmFicnVwdChcInJldHVyblwiLCBjb250ZXh0LmFyZyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZSA9IEdlblN0YXRlRXhlY3V0aW5nO1xuXG4gICAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcIm5vcm1hbFwiKSB7XG4gICAgICAgICAgLy8gSWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biBmcm9tIGlubmVyRm4sIHdlIGxlYXZlIHN0YXRlID09PVxuICAgICAgICAgIC8vIEdlblN0YXRlRXhlY3V0aW5nIGFuZCBsb29wIGJhY2sgZm9yIGFub3RoZXIgaW52b2NhdGlvbi5cbiAgICAgICAgICBzdGF0ZSA9IGNvbnRleHQuZG9uZVxuICAgICAgICAgICAgPyBHZW5TdGF0ZUNvbXBsZXRlZFxuICAgICAgICAgICAgOiBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkO1xuXG4gICAgICAgICAgaWYgKHJlY29yZC5hcmcgPT09IENvbnRpbnVlU2VudGluZWwpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogcmVjb3JkLmFyZyxcbiAgICAgICAgICAgIGRvbmU6IGNvbnRleHQuZG9uZVxuICAgICAgICAgIH07XG5cbiAgICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUNvbXBsZXRlZDtcbiAgICAgICAgICAvLyBEaXNwYXRjaCB0aGUgZXhjZXB0aW9uIGJ5IGxvb3BpbmcgYmFjayBhcm91bmQgdG8gdGhlXG4gICAgICAgICAgLy8gY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZykgY2FsbCBhYm92ZS5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gQ2FsbCBkZWxlZ2F0ZS5pdGVyYXRvcltjb250ZXh0Lm1ldGhvZF0oY29udGV4dC5hcmcpIGFuZCBoYW5kbGUgdGhlXG4gIC8vIHJlc3VsdCwgZWl0aGVyIGJ5IHJldHVybmluZyBhIHsgdmFsdWUsIGRvbmUgfSByZXN1bHQgZnJvbSB0aGVcbiAgLy8gZGVsZWdhdGUgaXRlcmF0b3IsIG9yIGJ5IG1vZGlmeWluZyBjb250ZXh0Lm1ldGhvZCBhbmQgY29udGV4dC5hcmcsXG4gIC8vIHNldHRpbmcgY29udGV4dC5kZWxlZ2F0ZSB0byBudWxsLCBhbmQgcmV0dXJuaW5nIHRoZSBDb250aW51ZVNlbnRpbmVsLlxuICBmdW5jdGlvbiBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KSB7XG4gICAgdmFyIG1ldGhvZCA9IGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXTtcbiAgICBpZiAobWV0aG9kID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIEEgLnRocm93IG9yIC5yZXR1cm4gd2hlbiB0aGUgZGVsZWdhdGUgaXRlcmF0b3IgaGFzIG5vIC50aHJvd1xuICAgICAgLy8gbWV0aG9kIGFsd2F5cyB0ZXJtaW5hdGVzIHRoZSB5aWVsZCogbG9vcC5cbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuXG4gICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICBpZiAoZGVsZWdhdGUuaXRlcmF0b3IucmV0dXJuKSB7XG4gICAgICAgICAgLy8gSWYgdGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGhhcyBhIHJldHVybiBtZXRob2QsIGdpdmUgaXQgYVxuICAgICAgICAgIC8vIGNoYW5jZSB0byBjbGVhbiB1cC5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwicmV0dXJuXCI7XG4gICAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgbWF5YmVJbnZva2VEZWxlZ2F0ZShkZWxlZ2F0ZSwgY29udGV4dCk7XG5cbiAgICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgLy8gSWYgbWF5YmVJbnZva2VEZWxlZ2F0ZShjb250ZXh0KSBjaGFuZ2VkIGNvbnRleHQubWV0aG9kIGZyb21cbiAgICAgICAgICAgIC8vIFwicmV0dXJuXCIgdG8gXCJ0aHJvd1wiLCBsZXQgdGhhdCBvdmVycmlkZSB0aGUgVHlwZUVycm9yIGJlbG93LlxuICAgICAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICAgIGNvbnRleHQuYXJnID0gbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICBcIlRoZSBpdGVyYXRvciBkb2VzIG5vdCBwcm92aWRlIGEgJ3Rocm93JyBtZXRob2RcIik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChtZXRob2QsIGRlbGVnYXRlLml0ZXJhdG9yLCBjb250ZXh0LmFyZyk7XG5cbiAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICBjb250ZXh0LmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIHZhciBpbmZvID0gcmVjb3JkLmFyZztcblxuICAgIGlmICghIGluZm8pIHtcbiAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgY29udGV4dC5hcmcgPSBuZXcgVHlwZUVycm9yKFwiaXRlcmF0b3IgcmVzdWx0IGlzIG5vdCBhbiBvYmplY3RcIik7XG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cblxuICAgIGlmIChpbmZvLmRvbmUpIHtcbiAgICAgIC8vIEFzc2lnbiB0aGUgcmVzdWx0IG9mIHRoZSBmaW5pc2hlZCBkZWxlZ2F0ZSB0byB0aGUgdGVtcG9yYXJ5XG4gICAgICAvLyB2YXJpYWJsZSBzcGVjaWZpZWQgYnkgZGVsZWdhdGUucmVzdWx0TmFtZSAoc2VlIGRlbGVnYXRlWWllbGQpLlxuICAgICAgY29udGV4dFtkZWxlZ2F0ZS5yZXN1bHROYW1lXSA9IGluZm8udmFsdWU7XG5cbiAgICAgIC8vIFJlc3VtZSBleGVjdXRpb24gYXQgdGhlIGRlc2lyZWQgbG9jYXRpb24gKHNlZSBkZWxlZ2F0ZVlpZWxkKS5cbiAgICAgIGNvbnRleHQubmV4dCA9IGRlbGVnYXRlLm5leHRMb2M7XG5cbiAgICAgIC8vIElmIGNvbnRleHQubWV0aG9kIHdhcyBcInRocm93XCIgYnV0IHRoZSBkZWxlZ2F0ZSBoYW5kbGVkIHRoZVxuICAgICAgLy8gZXhjZXB0aW9uLCBsZXQgdGhlIG91dGVyIGdlbmVyYXRvciBwcm9jZWVkIG5vcm1hbGx5LiBJZlxuICAgICAgLy8gY29udGV4dC5tZXRob2Qgd2FzIFwibmV4dFwiLCBmb3JnZXQgY29udGV4dC5hcmcgc2luY2UgaXQgaGFzIGJlZW5cbiAgICAgIC8vIFwiY29uc3VtZWRcIiBieSB0aGUgZGVsZWdhdGUgaXRlcmF0b3IuIElmIGNvbnRleHQubWV0aG9kIHdhc1xuICAgICAgLy8gXCJyZXR1cm5cIiwgYWxsb3cgdGhlIG9yaWdpbmFsIC5yZXR1cm4gY2FsbCB0byBjb250aW51ZSBpbiB0aGVcbiAgICAgIC8vIG91dGVyIGdlbmVyYXRvci5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCAhPT0gXCJyZXR1cm5cIikge1xuICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZS15aWVsZCB0aGUgcmVzdWx0IHJldHVybmVkIGJ5IHRoZSBkZWxlZ2F0ZSBtZXRob2QuXG4gICAgICByZXR1cm4gaW5mbztcbiAgICB9XG5cbiAgICAvLyBUaGUgZGVsZWdhdGUgaXRlcmF0b3IgaXMgZmluaXNoZWQsIHNvIGZvcmdldCBpdCBhbmQgY29udGludWUgd2l0aFxuICAgIC8vIHRoZSBvdXRlciBnZW5lcmF0b3IuXG4gICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gIH1cblxuICAvLyBEZWZpbmUgR2VuZXJhdG9yLnByb3RvdHlwZS57bmV4dCx0aHJvdyxyZXR1cm59IGluIHRlcm1zIG9mIHRoZVxuICAvLyB1bmlmaWVkIC5faW52b2tlIGhlbHBlciBtZXRob2QuXG4gIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhHcCk7XG5cbiAgR3BbdG9TdHJpbmdUYWdTeW1ib2xdID0gXCJHZW5lcmF0b3JcIjtcblxuICAvLyBBIEdlbmVyYXRvciBzaG91bGQgYWx3YXlzIHJldHVybiBpdHNlbGYgYXMgdGhlIGl0ZXJhdG9yIG9iamVjdCB3aGVuIHRoZVxuICAvLyBAQGl0ZXJhdG9yIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBpdC4gU29tZSBicm93c2VycycgaW1wbGVtZW50YXRpb25zIG9mIHRoZVxuICAvLyBpdGVyYXRvciBwcm90b3R5cGUgY2hhaW4gaW5jb3JyZWN0bHkgaW1wbGVtZW50IHRoaXMsIGNhdXNpbmcgdGhlIEdlbmVyYXRvclxuICAvLyBvYmplY3QgdG8gbm90IGJlIHJldHVybmVkIGZyb20gdGhpcyBjYWxsLiBUaGlzIGVuc3VyZXMgdGhhdCBkb2Vzbid0IGhhcHBlbi5cbiAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9yZWdlbmVyYXRvci9pc3N1ZXMvMjc0IGZvciBtb3JlIGRldGFpbHMuXG4gIEdwW2l0ZXJhdG9yU3ltYm9sXSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEdwLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIFwiW29iamVjdCBHZW5lcmF0b3JdXCI7XG4gIH07XG5cbiAgZnVuY3Rpb24gcHVzaFRyeUVudHJ5KGxvY3MpIHtcbiAgICB2YXIgZW50cnkgPSB7IHRyeUxvYzogbG9jc1swXSB9O1xuXG4gICAgaWYgKDEgaW4gbG9jcykge1xuICAgICAgZW50cnkuY2F0Y2hMb2MgPSBsb2NzWzFdO1xuICAgIH1cblxuICAgIGlmICgyIGluIGxvY3MpIHtcbiAgICAgIGVudHJ5LmZpbmFsbHlMb2MgPSBsb2NzWzJdO1xuICAgICAgZW50cnkuYWZ0ZXJMb2MgPSBsb2NzWzNdO1xuICAgIH1cblxuICAgIHRoaXMudHJ5RW50cmllcy5wdXNoKGVudHJ5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0VHJ5RW50cnkoZW50cnkpIHtcbiAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbiB8fCB7fTtcbiAgICByZWNvcmQudHlwZSA9IFwibm9ybWFsXCI7XG4gICAgZGVsZXRlIHJlY29yZC5hcmc7XG4gICAgZW50cnkuY29tcGxldGlvbiA9IHJlY29yZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIENvbnRleHQodHJ5TG9jc0xpc3QpIHtcbiAgICAvLyBUaGUgcm9vdCBlbnRyeSBvYmplY3QgKGVmZmVjdGl2ZWx5IGEgdHJ5IHN0YXRlbWVudCB3aXRob3V0IGEgY2F0Y2hcbiAgICAvLyBvciBhIGZpbmFsbHkgYmxvY2spIGdpdmVzIHVzIGEgcGxhY2UgdG8gc3RvcmUgdmFsdWVzIHRocm93biBmcm9tXG4gICAgLy8gbG9jYXRpb25zIHdoZXJlIHRoZXJlIGlzIG5vIGVuY2xvc2luZyB0cnkgc3RhdGVtZW50LlxuICAgIHRoaXMudHJ5RW50cmllcyA9IFt7IHRyeUxvYzogXCJyb290XCIgfV07XG4gICAgdHJ5TG9jc0xpc3QuZm9yRWFjaChwdXNoVHJ5RW50cnksIHRoaXMpO1xuICAgIHRoaXMucmVzZXQodHJ1ZSk7XG4gIH1cblxuICBydW50aW1lLmtleXMgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGtleXMucHVzaChrZXkpO1xuICAgIH1cbiAgICBrZXlzLnJldmVyc2UoKTtcblxuICAgIC8vIFJhdGhlciB0aGFuIHJldHVybmluZyBhbiBvYmplY3Qgd2l0aCBhIG5leHQgbWV0aG9kLCB3ZSBrZWVwXG4gICAgLy8gdGhpbmdzIHNpbXBsZSBhbmQgcmV0dXJuIHRoZSBuZXh0IGZ1bmN0aW9uIGl0c2VsZi5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgIHdoaWxlIChrZXlzLmxlbmd0aCkge1xuICAgICAgICB2YXIga2V5ID0ga2V5cy5wb3AoKTtcbiAgICAgICAgaWYgKGtleSBpbiBvYmplY3QpIHtcbiAgICAgICAgICBuZXh0LnZhbHVlID0ga2V5O1xuICAgICAgICAgIG5leHQuZG9uZSA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRvIGF2b2lkIGNyZWF0aW5nIGFuIGFkZGl0aW9uYWwgb2JqZWN0LCB3ZSBqdXN0IGhhbmcgdGhlIC52YWx1ZVxuICAgICAgLy8gYW5kIC5kb25lIHByb3BlcnRpZXMgb2ZmIHRoZSBuZXh0IGZ1bmN0aW9uIG9iamVjdCBpdHNlbGYuIFRoaXNcbiAgICAgIC8vIGFsc28gZW5zdXJlcyB0aGF0IHRoZSBtaW5pZmllciB3aWxsIG5vdCBhbm9ueW1pemUgdGhlIGZ1bmN0aW9uLlxuICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcbiAgICAgIHJldHVybiBuZXh0O1xuICAgIH07XG4gIH07XG5cbiAgZnVuY3Rpb24gdmFsdWVzKGl0ZXJhYmxlKSB7XG4gICAgaWYgKGl0ZXJhYmxlKSB7XG4gICAgICB2YXIgaXRlcmF0b3JNZXRob2QgPSBpdGVyYWJsZVtpdGVyYXRvclN5bWJvbF07XG4gICAgICBpZiAoaXRlcmF0b3JNZXRob2QpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yTWV0aG9kLmNhbGwoaXRlcmFibGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGl0ZXJhYmxlLm5leHQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gaXRlcmFibGU7XG4gICAgICB9XG5cbiAgICAgIGlmICghaXNOYU4oaXRlcmFibGUubGVuZ3RoKSkge1xuICAgICAgICB2YXIgaSA9IC0xLCBuZXh0ID0gZnVuY3Rpb24gbmV4dCgpIHtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgaXRlcmFibGUubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duLmNhbGwoaXRlcmFibGUsIGkpKSB7XG4gICAgICAgICAgICAgIG5leHQudmFsdWUgPSBpdGVyYWJsZVtpXTtcbiAgICAgICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIG5leHQudmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgbmV4dC5kb25lID0gdHJ1ZTtcblxuICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBuZXh0Lm5leHQgPSBuZXh0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiBhbiBpdGVyYXRvciB3aXRoIG5vIHZhbHVlcy5cbiAgICByZXR1cm4geyBuZXh0OiBkb25lUmVzdWx0IH07XG4gIH1cbiAgcnVudGltZS52YWx1ZXMgPSB2YWx1ZXM7XG5cbiAgZnVuY3Rpb24gZG9uZVJlc3VsdCgpIHtcbiAgICByZXR1cm4geyB2YWx1ZTogdW5kZWZpbmVkLCBkb25lOiB0cnVlIH07XG4gIH1cblxuICBDb250ZXh0LnByb3RvdHlwZSA9IHtcbiAgICBjb25zdHJ1Y3RvcjogQ29udGV4dCxcblxuICAgIHJlc2V0OiBmdW5jdGlvbihza2lwVGVtcFJlc2V0KSB7XG4gICAgICB0aGlzLnByZXYgPSAwO1xuICAgICAgdGhpcy5uZXh0ID0gMDtcbiAgICAgIC8vIFJlc2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAvLyBmdW5jdGlvbi5zZW50IGltcGxlbWVudGF0aW9uLlxuICAgICAgdGhpcy5zZW50ID0gdGhpcy5fc2VudCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuZG9uZSA9IGZhbHNlO1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIHRoaXMubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcblxuICAgICAgdGhpcy50cnlFbnRyaWVzLmZvckVhY2gocmVzZXRUcnlFbnRyeSk7XG5cbiAgICAgIGlmICghc2tpcFRlbXBSZXNldCkge1xuICAgICAgICBmb3IgKHZhciBuYW1lIGluIHRoaXMpIHtcbiAgICAgICAgICAvLyBOb3Qgc3VyZSBhYm91dCB0aGUgb3B0aW1hbCBvcmRlciBvZiB0aGVzZSBjb25kaXRpb25zOlxuICAgICAgICAgIGlmIChuYW1lLmNoYXJBdCgwKSA9PT0gXCJ0XCIgJiZcbiAgICAgICAgICAgICAgaGFzT3duLmNhbGwodGhpcywgbmFtZSkgJiZcbiAgICAgICAgICAgICAgIWlzTmFOKCtuYW1lLnNsaWNlKDEpKSkge1xuICAgICAgICAgICAgdGhpc1tuYW1lXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmRvbmUgPSB0cnVlO1xuXG4gICAgICB2YXIgcm9vdEVudHJ5ID0gdGhpcy50cnlFbnRyaWVzWzBdO1xuICAgICAgdmFyIHJvb3RSZWNvcmQgPSByb290RW50cnkuY29tcGxldGlvbjtcbiAgICAgIGlmIChyb290UmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByb290UmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMucnZhbDtcbiAgICB9LFxuXG4gICAgZGlzcGF0Y2hFeGNlcHRpb246IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuICAgICAgaWYgKHRoaXMuZG9uZSkge1xuICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcztcbiAgICAgIGZ1bmN0aW9uIGhhbmRsZShsb2MsIGNhdWdodCkge1xuICAgICAgICByZWNvcmQudHlwZSA9IFwidGhyb3dcIjtcbiAgICAgICAgcmVjb3JkLmFyZyA9IGV4Y2VwdGlvbjtcbiAgICAgICAgY29udGV4dC5uZXh0ID0gbG9jO1xuXG4gICAgICAgIGlmIChjYXVnaHQpIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGlzcGF0Y2hlZCBleGNlcHRpb24gd2FzIGNhdWdodCBieSBhIGNhdGNoIGJsb2NrLFxuICAgICAgICAgIC8vIHRoZW4gbGV0IHRoYXQgY2F0Y2ggYmxvY2sgaGFuZGxlIHRoZSBleGNlcHRpb24gbm9ybWFsbHkuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAhISBjYXVnaHQ7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSBcInJvb3RcIikge1xuICAgICAgICAgIC8vIEV4Y2VwdGlvbiB0aHJvd24gb3V0c2lkZSBvZiBhbnkgdHJ5IGJsb2NrIHRoYXQgY291bGQgaGFuZGxlXG4gICAgICAgICAgLy8gaXQsIHNvIHNldCB0aGUgY29tcGxldGlvbiB2YWx1ZSBvZiB0aGUgZW50aXJlIGZ1bmN0aW9uIHRvXG4gICAgICAgICAgLy8gdGhyb3cgdGhlIGV4Y2VwdGlvbi5cbiAgICAgICAgICByZXR1cm4gaGFuZGxlKFwiZW5kXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYpIHtcbiAgICAgICAgICB2YXIgaGFzQ2F0Y2ggPSBoYXNPd24uY2FsbChlbnRyeSwgXCJjYXRjaExvY1wiKTtcbiAgICAgICAgICB2YXIgaGFzRmluYWxseSA9IGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIik7XG5cbiAgICAgICAgICBpZiAoaGFzQ2F0Y2ggJiYgaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmNhdGNoTG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuY2F0Y2hMb2MsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0NhdGNoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGhhc0ZpbmFsbHkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuZmluYWxseUxvYyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJ5IHN0YXRlbWVudCB3aXRob3V0IGNhdGNoIG9yIGZpbmFsbHlcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIGFicnVwdDogZnVuY3Rpb24odHlwZSwgYXJnKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA8PSB0aGlzLnByZXYgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKGVudHJ5LCBcImZpbmFsbHlMb2NcIikgJiZcbiAgICAgICAgICAgIHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB2YXIgZmluYWxseUVudHJ5ID0gZW50cnk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSAmJlxuICAgICAgICAgICh0eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICAgdHlwZSA9PT0gXCJjb250aW51ZVwiKSAmJlxuICAgICAgICAgIGZpbmFsbHlFbnRyeS50cnlMb2MgPD0gYXJnICYmXG4gICAgICAgICAgYXJnIDw9IGZpbmFsbHlFbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgIC8vIElnbm9yZSB0aGUgZmluYWxseSBlbnRyeSBpZiBjb250cm9sIGlzIG5vdCBqdW1waW5nIHRvIGFcbiAgICAgICAgLy8gbG9jYXRpb24gb3V0c2lkZSB0aGUgdHJ5L2NhdGNoIGJsb2NrLlxuICAgICAgICBmaW5hbGx5RW50cnkgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVjb3JkID0gZmluYWxseUVudHJ5ID8gZmluYWxseUVudHJ5LmNvbXBsZXRpb24gOiB7fTtcbiAgICAgIHJlY29yZC50eXBlID0gdHlwZTtcbiAgICAgIHJlY29yZC5hcmcgPSBhcmc7XG5cbiAgICAgIGlmIChmaW5hbGx5RW50cnkpIHtcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgdGhpcy5uZXh0ID0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2M7XG4gICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZShyZWNvcmQpO1xuICAgIH0sXG5cbiAgICBjb21wbGV0ZTogZnVuY3Rpb24ocmVjb3JkLCBhZnRlckxvYykge1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgdGhyb3cgcmVjb3JkLmFyZztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcImJyZWFrXCIgfHxcbiAgICAgICAgICByZWNvcmQudHlwZSA9PT0gXCJjb250aW51ZVwiKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IHJlY29yZC5hcmc7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInJldHVyblwiKSB7XG4gICAgICAgIHRoaXMucnZhbCA9IHRoaXMuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgdGhpcy5tZXRob2QgPSBcInJldHVyblwiO1xuICAgICAgICB0aGlzLm5leHQgPSBcImVuZFwiO1xuICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJub3JtYWxcIiAmJiBhZnRlckxvYykge1xuICAgICAgICB0aGlzLm5leHQgPSBhZnRlckxvYztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfSxcblxuICAgIGZpbmlzaDogZnVuY3Rpb24oZmluYWxseUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS5maW5hbGx5TG9jID09PSBmaW5hbGx5TG9jKSB7XG4gICAgICAgICAgdGhpcy5jb21wbGV0ZShlbnRyeS5jb21wbGV0aW9uLCBlbnRyeS5hZnRlckxvYyk7XG4gICAgICAgICAgcmVzZXRUcnlFbnRyeShlbnRyeSk7XG4gICAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgXCJjYXRjaFwiOiBmdW5jdGlvbih0cnlMb2MpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jID09PSB0cnlMb2MpIHtcbiAgICAgICAgICB2YXIgcmVjb3JkID0gZW50cnkuY29tcGxldGlvbjtcbiAgICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgICAgdmFyIHRocm93biA9IHJlY29yZC5hcmc7XG4gICAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRocm93bjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUgY29udGV4dC5jYXRjaCBtZXRob2QgbXVzdCBvbmx5IGJlIGNhbGxlZCB3aXRoIGEgbG9jYXRpb25cbiAgICAgIC8vIGFyZ3VtZW50IHRoYXQgY29ycmVzcG9uZHMgdG8gYSBrbm93biBjYXRjaCBibG9jay5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlsbGVnYWwgY2F0Y2ggYXR0ZW1wdFwiKTtcbiAgICB9LFxuXG4gICAgZGVsZWdhdGVZaWVsZDogZnVuY3Rpb24oaXRlcmFibGUsIHJlc3VsdE5hbWUsIG5leHRMb2MpIHtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSB7XG4gICAgICAgIGl0ZXJhdG9yOiB2YWx1ZXMoaXRlcmFibGUpLFxuICAgICAgICByZXN1bHROYW1lOiByZXN1bHROYW1lLFxuICAgICAgICBuZXh0TG9jOiBuZXh0TG9jXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgIC8vIERlbGliZXJhdGVseSBmb3JnZXQgdGhlIGxhc3Qgc2VudCB2YWx1ZSBzbyB0aGF0IHdlIGRvbid0XG4gICAgICAgIC8vIGFjY2lkZW50YWxseSBwYXNzIGl0IG9uIHRvIHRoZSBkZWxlZ2F0ZS5cbiAgICAgICAgdGhpcy5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH1cbiAgfTtcbn0pKFxuICAvLyBBbW9uZyB0aGUgdmFyaW91cyB0cmlja3MgZm9yIG9idGFpbmluZyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsXG4gIC8vIG9iamVjdCwgdGhpcyBzZWVtcyB0byBiZSB0aGUgbW9zdCByZWxpYWJsZSB0ZWNobmlxdWUgdGhhdCBkb2VzIG5vdFxuICAvLyB1c2UgaW5kaXJlY3QgZXZhbCAod2hpY2ggdmlvbGF0ZXMgQ29udGVudCBTZWN1cml0eSBQb2xpY3kpLlxuICB0eXBlb2YgZ2xvYmFsID09PSBcIm9iamVjdFwiID8gZ2xvYmFsIDpcbiAgdHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIiA/IHdpbmRvdyA6XG4gIHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IHRoaXNcbik7XG4iLCIndXNlIHN0cmljdCdcblxuZXhwb3J0cy5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuZXhwb3J0cy50b0J5dGVBcnJheSA9IHRvQnl0ZUFycmF5XG5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5XG5cbnZhciBsb29rdXAgPSBbXVxudmFyIHJldkxvb2t1cCA9IFtdXG52YXIgQXJyID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnID8gVWludDhBcnJheSA6IEFycmF5XG5cbnZhciBjb2RlID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nXG5mb3IgKHZhciBpID0gMCwgbGVuID0gY29kZS5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICBsb29rdXBbaV0gPSBjb2RlW2ldXG4gIHJldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldID0gaVxufVxuXG4vLyBTdXBwb3J0IGRlY29kaW5nIFVSTC1zYWZlIGJhc2U2NCBzdHJpbmdzLCBhcyBOb2RlLmpzIGRvZXMuXG4vLyBTZWU6IGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Jhc2U2NCNVUkxfYXBwbGljYXRpb25zXG5yZXZMb29rdXBbJy0nLmNoYXJDb2RlQXQoMCldID0gNjJcbnJldkxvb2t1cFsnXycuY2hhckNvZGVBdCgwKV0gPSA2M1xuXG5mdW5jdGlvbiBnZXRMZW5zIChiNjQpIHtcbiAgdmFyIGxlbiA9IGI2NC5sZW5ndGhcblxuICBpZiAobGVuICUgNCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuICB9XG5cbiAgLy8gVHJpbSBvZmYgZXh0cmEgYnl0ZXMgYWZ0ZXIgcGxhY2Vob2xkZXIgYnl0ZXMgYXJlIGZvdW5kXG4gIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2JlYXRnYW1taXQvYmFzZTY0LWpzL2lzc3Vlcy80MlxuICB2YXIgdmFsaWRMZW4gPSBiNjQuaW5kZXhPZignPScpXG4gIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuXG5cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IHZhbGlkTGVuID09PSBsZW5cbiAgICA/IDBcbiAgICA6IDQgLSAodmFsaWRMZW4gJSA0KVxuXG4gIHJldHVybiBbdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbl1cbn1cblxuLy8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5mdW5jdGlvbiBieXRlTGVuZ3RoIChiNjQpIHtcbiAgdmFyIGxlbnMgPSBnZXRMZW5zKGI2NClcbiAgdmFyIHZhbGlkTGVuID0gbGVuc1swXVxuICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXVxuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gX2J5dGVMZW5ndGggKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikge1xuICByZXR1cm4gKCh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCkgLSBwbGFjZUhvbGRlcnNMZW5cbn1cblxuZnVuY3Rpb24gdG9CeXRlQXJyYXkgKGI2NCkge1xuICB2YXIgdG1wXG4gIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpXG4gIHZhciB2YWxpZExlbiA9IGxlbnNbMF1cbiAgdmFyIHBsYWNlSG9sZGVyc0xlbiA9IGxlbnNbMV1cblxuICB2YXIgYXJyID0gbmV3IEFycihfYnl0ZUxlbmd0aChiNjQsIHZhbGlkTGVuLCBwbGFjZUhvbGRlcnNMZW4pKVxuXG4gIHZhciBjdXJCeXRlID0gMFxuXG4gIC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcbiAgdmFyIGxlbiA9IHBsYWNlSG9sZGVyc0xlbiA+IDBcbiAgICA/IHZhbGlkTGVuIC0gNFxuICAgIDogdmFsaWRMZW5cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgdG1wID1cbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSldIDw8IDE4KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPDwgMTIpIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDIpXSA8PCA2KSB8XG4gICAgICByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDMpXVxuICAgIGFycltjdXJCeXRlKytdID0gKHRtcCA+PiAxNikgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSAodG1wID4+IDgpICYgMHhGRlxuICAgIGFycltjdXJCeXRlKytdID0gdG1wICYgMHhGRlxuICB9XG5cbiAgaWYgKHBsYWNlSG9sZGVyc0xlbiA9PT0gMikge1xuICAgIHRtcCA9XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXSA8PCAyKSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAxKV0gPj4gNClcbiAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDB4RkZcbiAgfVxuXG4gIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICB0bXAgPVxuICAgICAgKHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV0gPDwgMTApIHxcbiAgICAgIChyZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaSArIDEpXSA8PCA0KSB8XG4gICAgICAocmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkgKyAyKV0gPj4gMilcbiAgICBhcnJbY3VyQnl0ZSsrXSA9ICh0bXAgPj4gOCkgJiAweEZGXG4gICAgYXJyW2N1ckJ5dGUrK10gPSB0bXAgJiAweEZGXG4gIH1cblxuICByZXR1cm4gYXJyXG59XG5cbmZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG4gIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArXG4gICAgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gK1xuICAgIGxvb2t1cFtudW0gJiAweDNGXVxufVxuXG5mdW5jdGlvbiBlbmNvZGVDaHVuayAodWludDgsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHRtcFxuICB2YXIgb3V0cHV0ID0gW11cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpICs9IDMpIHtcbiAgICB0bXAgPVxuICAgICAgKCh1aW50OFtpXSA8PCAxNikgJiAweEZGMDAwMCkgK1xuICAgICAgKCh1aW50OFtpICsgMV0gPDwgOCkgJiAweEZGMDApICtcbiAgICAgICh1aW50OFtpICsgMl0gJiAweEZGKVxuICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKVxuICB9XG4gIHJldHVybiBvdXRwdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSAodWludDgpIHtcbiAgdmFyIHRtcFxuICB2YXIgbGVuID0gdWludDgubGVuZ3RoXG4gIHZhciBleHRyYUJ5dGVzID0gbGVuICUgMyAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuICB2YXIgcGFydHMgPSBbXVxuICB2YXIgbWF4Q2h1bmtMZW5ndGggPSAxNjM4MyAvLyBtdXN0IGJlIG11bHRpcGxlIG9mIDNcblxuICAvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG4gIGZvciAodmFyIGkgPSAwLCBsZW4yID0gbGVuIC0gZXh0cmFCeXRlczsgaSA8IGxlbjI7IGkgKz0gbWF4Q2h1bmtMZW5ndGgpIHtcbiAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKFxuICAgICAgdWludDgsIGksIChpICsgbWF4Q2h1bmtMZW5ndGgpID4gbGVuMiA/IGxlbjIgOiAoaSArIG1heENodW5rTGVuZ3RoKVxuICAgICkpXG4gIH1cblxuICAvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG4gIGlmIChleHRyYUJ5dGVzID09PSAxKSB7XG4gICAgdG1wID0gdWludDhbbGVuIC0gMV1cbiAgICBwYXJ0cy5wdXNoKFxuICAgICAgbG9va3VwW3RtcCA+PiAyXSArXG4gICAgICBsb29rdXBbKHRtcCA8PCA0KSAmIDB4M0ZdICtcbiAgICAgICc9PSdcbiAgICApXG4gIH0gZWxzZSBpZiAoZXh0cmFCeXRlcyA9PT0gMikge1xuICAgIHRtcCA9ICh1aW50OFtsZW4gLSAyXSA8PCA4KSArIHVpbnQ4W2xlbiAtIDFdXG4gICAgcGFydHMucHVzaChcbiAgICAgIGxvb2t1cFt0bXAgPj4gMTBdICtcbiAgICAgIGxvb2t1cFsodG1wID4+IDQpICYgMHgzRl0gK1xuICAgICAgbG9va3VwWyh0bXAgPDwgMikgJiAweDNGXSArXG4gICAgICAnPSdcbiAgICApXG4gIH1cblxuICByZXR1cm4gcGFydHMuam9pbignJylcbn1cbiIsIi8qIVxuICogVGhlIGJ1ZmZlciBtb2R1bGUgZnJvbSBub2RlLmpzLCBmb3IgdGhlIGJyb3dzZXIuXG4gKlxuICogQGF1dGhvciAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBAbGljZW5zZSAgTUlUXG4gKi9cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG5cbid1c2Ugc3RyaWN0J1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5cbi8qKlxuICogSWYgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKG1vc3QgY29tcGF0aWJsZSwgZXZlbiBJRTYpXG4gKlxuICogQnJvd3NlcnMgdGhhdCBzdXBwb3J0IHR5cGVkIGFycmF5cyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLCBDaHJvbWUgNyssIFNhZmFyaSA1LjErLFxuICogT3BlcmEgMTEuNissIGlPUyA0LjIrLlxuICpcbiAqIER1ZSB0byB2YXJpb3VzIGJyb3dzZXIgYnVncywgc29tZXRpbWVzIHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24gd2lsbCBiZSB1c2VkIGV2ZW5cbiAqIHdoZW4gdGhlIGJyb3dzZXIgc3VwcG9ydHMgdHlwZWQgYXJyYXlzLlxuICpcbiAqIE5vdGU6XG4gKlxuICogICAtIEZpcmVmb3ggNC0yOSBsYWNrcyBzdXBwb3J0IGZvciBhZGRpbmcgbmV3IHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcyxcbiAqICAgICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgIC0gQ2hyb21lIDktMTAgaXMgbWlzc2luZyB0aGUgYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbi5cbiAqXG4gKiAgIC0gSUUxMCBoYXMgYSBicm9rZW4gYFR5cGVkQXJyYXkucHJvdG90eXBlLnN1YmFycmF5YCBmdW5jdGlvbiB3aGljaCByZXR1cm5zIGFycmF5cyBvZlxuICogICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuXG4gKiBXZSBkZXRlY3QgdGhlc2UgYnVnZ3kgYnJvd3NlcnMgYW5kIHNldCBgQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlRgIHRvIGBmYWxzZWAgc28gdGhleVxuICogZ2V0IHRoZSBPYmplY3QgaW1wbGVtZW50YXRpb24sIHdoaWNoIGlzIHNsb3dlciBidXQgYmVoYXZlcyBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gZ2xvYmFsLlRZUEVEX0FSUkFZX1NVUFBPUlQgIT09IHVuZGVmaW5lZFxuICA/IGdsb2JhbC5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gIDogdHlwZWRBcnJheVN1cHBvcnQoKVxuXG4vKlxuICogRXhwb3J0IGtNYXhMZW5ndGggYWZ0ZXIgdHlwZWQgYXJyYXkgc3VwcG9ydCBpcyBkZXRlcm1pbmVkLlxuICovXG5leHBvcnRzLmtNYXhMZW5ndGggPSBrTWF4TGVuZ3RoKClcblxuZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQgKCkge1xuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5fX3Byb3RvX18gPSB7X19wcm90b19fOiBVaW50OEFycmF5LnByb3RvdHlwZSwgZm9vOiBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9fVxuICAgIHJldHVybiBhcnIuZm9vKCkgPT09IDQyICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIGFyci5zdWJhcnJheSgxLCAxKS5ieXRlTGVuZ3RoID09PSAwIC8vIGllMTAgaGFzIGJyb2tlbiBgc3ViYXJyYXlgXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5mdW5jdGlvbiBrTWF4TGVuZ3RoICgpIHtcbiAgcmV0dXJuIEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUXG4gICAgPyAweDdmZmZmZmZmXG4gICAgOiAweDNmZmZmZmZmXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlciAodGhhdCwgbGVuZ3RoKSB7XG4gIGlmIChrTWF4TGVuZ3RoKCkgPCBsZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW52YWxpZCB0eXBlZCBhcnJheSBsZW5ndGgnKVxuICB9XG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBuZXcgVWludDhBcnJheShsZW5ndGgpXG4gICAgdGhhdC5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIGlmICh0aGF0ID09PSBudWxsKSB7XG4gICAgICB0aGF0ID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gICAgfVxuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICByZXR1cm4gdGhhdFxufVxuXG4vKipcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgaGF2ZSB0aGVpclxuICogcHJvdG90eXBlIGNoYW5nZWQgdG8gYEJ1ZmZlci5wcm90b3R5cGVgLiBGdXJ0aGVybW9yZSwgYEJ1ZmZlcmAgaXMgYSBzdWJjbGFzcyBvZlxuICogYFVpbnQ4QXJyYXlgLCBzbyB0aGUgcmV0dXJuZWQgaW5zdGFuY2VzIHdpbGwgaGF2ZSBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgbWV0aG9kc1xuICogYW5kIHRoZSBgVWludDhBcnJheWAgbWV0aG9kcy4gU3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXRcbiAqIHJldHVybnMgYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogVGhlIGBVaW50OEFycmF5YCBwcm90b3R5cGUgcmVtYWlucyB1bm1vZGlmaWVkLlxuICovXG5cbmZ1bmN0aW9uIEJ1ZmZlciAoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiAhKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICAvLyBDb21tb24gY2FzZS5cbiAgaWYgKHR5cGVvZiBhcmcgPT09ICdudW1iZXInKSB7XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZ09yT2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnSWYgZW5jb2RpbmcgaXMgc3BlY2lmaWVkIHRoZW4gdGhlIGZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcnXG4gICAgICApXG4gICAgfVxuICAgIHJldHVybiBhbGxvY1Vuc2FmZSh0aGlzLCBhcmcpXG4gIH1cbiAgcmV0dXJuIGZyb20odGhpcywgYXJnLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG59XG5cbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTIgLy8gbm90IHVzZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvblxuXG4vLyBUT0RPOiBMZWdhY3ksIG5vdCBuZWVkZWQgYW55bW9yZS4gUmVtb3ZlIGluIG5leHQgbWFqb3IgdmVyc2lvbi5cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLl9fcHJvdG9fXyA9IEJ1ZmZlci5wcm90b3R5cGVcbiAgcmV0dXJuIGFyclxufVxuXG5mdW5jdGlvbiBmcm9tICh0aGF0LCB2YWx1ZSwgZW5jb2RpbmdPck9mZnNldCwgbGVuZ3RoKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IG11c3Qgbm90IGJlIGEgbnVtYmVyJylcbiAgfVxuXG4gIGlmICh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpXG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmcm9tU3RyaW5nKHRoYXQsIHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0KVxuICB9XG5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhhdCwgdmFsdWUpXG59XG5cbi8qKlxuICogRnVuY3Rpb25hbGx5IGVxdWl2YWxlbnQgdG8gQnVmZmVyKGFyZywgZW5jb2RpbmcpIGJ1dCB0aHJvd3MgYSBUeXBlRXJyb3JcbiAqIGlmIHZhbHVlIGlzIGEgbnVtYmVyLlxuICogQnVmZmVyLmZyb20oc3RyWywgZW5jb2RpbmddKVxuICogQnVmZmVyLmZyb20oYXJyYXkpXG4gKiBCdWZmZXIuZnJvbShidWZmZXIpXG4gKiBCdWZmZXIuZnJvbShhcnJheUJ1ZmZlclssIGJ5dGVPZmZzZXRbLCBsZW5ndGhdXSlcbiAqKi9cbkJ1ZmZlci5mcm9tID0gZnVuY3Rpb24gKHZhbHVlLCBlbmNvZGluZ09yT2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGZyb20obnVsbCwgdmFsdWUsIGVuY29kaW5nT3JPZmZzZXQsIGxlbmd0aClcbn1cblxuaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gIEJ1ZmZlci5wcm90b3R5cGUuX19wcm90b19fID0gVWludDhBcnJheS5wcm90b3R5cGVcbiAgQnVmZmVyLl9fcHJvdG9fXyA9IFVpbnQ4QXJyYXlcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC5zcGVjaWVzICYmXG4gICAgICBCdWZmZXJbU3ltYm9sLnNwZWNpZXNdID09PSBCdWZmZXIpIHtcbiAgICAvLyBGaXggc3ViYXJyYXkoKSBpbiBFUzIwMTYuIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9idWZmZXIvcHVsbC85N1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdWZmZXIsIFN5bWJvbC5zcGVjaWVzLCB7XG4gICAgICB2YWx1ZTogbnVsbCxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzZXJ0U2l6ZSAoc2l6ZSkge1xuICBpZiAodHlwZW9mIHNpemUgIT09ICdudW1iZXInKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpXG4gIH0gZWxzZSBpZiAoc2l6ZSA8IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKVxuICB9XG59XG5cbmZ1bmN0aW9uIGFsbG9jICh0aGF0LCBzaXplLCBmaWxsLCBlbmNvZGluZykge1xuICBhc3NlcnRTaXplKHNpemUpXG4gIGlmIChzaXplIDw9IDApIHtcbiAgICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG4gIH1cbiAgaWYgKGZpbGwgIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9ubHkgcGF5IGF0dGVudGlvbiB0byBlbmNvZGluZyBpZiBpdCdzIGEgc3RyaW5nLiBUaGlzXG4gICAgLy8gcHJldmVudHMgYWNjaWRlbnRhbGx5IHNlbmRpbmcgaW4gYSBudW1iZXIgdGhhdCB3b3VsZFxuICAgIC8vIGJlIGludGVycHJldHRlZCBhcyBhIHN0YXJ0IG9mZnNldC5cbiAgICByZXR1cm4gdHlwZW9mIGVuY29kaW5nID09PSAnc3RyaW5nJ1xuICAgICAgPyBjcmVhdGVCdWZmZXIodGhhdCwgc2l6ZSkuZmlsbChmaWxsLCBlbmNvZGluZylcbiAgICAgIDogY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpLmZpbGwoZmlsbClcbiAgfVxuICByZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUpXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBmaWxsZWQgQnVmZmVyIGluc3RhbmNlLlxuICogYWxsb2Moc2l6ZVssIGZpbGxbLCBlbmNvZGluZ11dKVxuICoqL1xuQnVmZmVyLmFsbG9jID0gZnVuY3Rpb24gKHNpemUsIGZpbGwsIGVuY29kaW5nKSB7XG4gIHJldHVybiBhbGxvYyhudWxsLCBzaXplLCBmaWxsLCBlbmNvZGluZylcbn1cblxuZnVuY3Rpb24gYWxsb2NVbnNhZmUgKHRoYXQsIHNpemUpIHtcbiAgYXNzZXJ0U2l6ZShzaXplKVxuICB0aGF0ID0gY3JlYXRlQnVmZmVyKHRoYXQsIHNpemUgPCAwID8gMCA6IGNoZWNrZWQoc2l6ZSkgfCAwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaXplOyArK2kpIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8qKlxuICogRXF1aXZhbGVudCB0byBCdWZmZXIobnVtKSwgYnkgZGVmYXVsdCBjcmVhdGVzIGEgbm9uLXplcm8tZmlsbGVkIEJ1ZmZlciBpbnN0YW5jZS5cbiAqICovXG5CdWZmZXIuYWxsb2NVbnNhZmUgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cbi8qKlxuICogRXF1aXZhbGVudCB0byBTbG93QnVmZmVyKG51bSksIGJ5IGRlZmF1bHQgY3JlYXRlcyBhIG5vbi16ZXJvLWZpbGxlZCBCdWZmZXIgaW5zdGFuY2UuXG4gKi9cbkJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3cgPSBmdW5jdGlvbiAoc2l6ZSkge1xuICByZXR1cm4gYWxsb2NVbnNhZmUobnVsbCwgc2l6ZSlcbn1cblxuZnVuY3Rpb24gZnJvbVN0cmluZyAodGhhdCwgc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIGVuY29kaW5nICE9PSAnc3RyaW5nJyB8fCBlbmNvZGluZyA9PT0gJycpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICB9XG5cbiAgaWYgKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImVuY29kaW5nXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBlbmNvZGluZycpXG4gIH1cblxuICB2YXIgbGVuZ3RoID0gYnl0ZUxlbmd0aChzdHJpbmcsIGVuY29kaW5nKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG5cbiAgdmFyIGFjdHVhbCA9IHRoYXQud3JpdGUoc3RyaW5nLCBlbmNvZGluZylcblxuICBpZiAoYWN0dWFsICE9PSBsZW5ndGgpIHtcbiAgICAvLyBXcml0aW5nIGEgaGV4IHN0cmluZywgZm9yIGV4YW1wbGUsIHRoYXQgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzIHdpbGxcbiAgICAvLyBjYXVzZSBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXJzdCBpbnZhbGlkIGNoYXJhY3RlciB0byBiZSBpZ25vcmVkLiAoZS5nLlxuICAgIC8vICdhYnh4Y2QnIHdpbGwgYmUgdHJlYXRlZCBhcyAnYWInKVxuICAgIHRoYXQgPSB0aGF0LnNsaWNlKDAsIGFjdHVhbClcbiAgfVxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGggPCAwID8gMCA6IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIgKHRoYXQsIGFycmF5LCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgYXJyYXkuYnl0ZUxlbmd0aCAvLyB0aGlzIHRocm93cyBpZiBgYXJyYXlgIGlzIG5vdCBhIHZhbGlkIEFycmF5QnVmZmVyXG5cbiAgaWYgKGJ5dGVPZmZzZXQgPCAwIHx8IGFycmF5LmJ5dGVMZW5ndGggPCBieXRlT2Zmc2V0KSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1xcJ29mZnNldFxcJyBpcyBvdXQgb2YgYm91bmRzJylcbiAgfVxuXG4gIGlmIChhcnJheS5ieXRlTGVuZ3RoIDwgYnl0ZU9mZnNldCArIChsZW5ndGggfHwgMCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignXFwnbGVuZ3RoXFwnIGlzIG91dCBvZiBib3VuZHMnKVxuICB9XG5cbiAgaWYgKGJ5dGVPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBsZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkpXG4gIH0gZWxzZSBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBhcnJheSA9IG5ldyBVaW50OEFycmF5KGFycmF5LCBieXRlT2Zmc2V0KVxuICB9IGVsc2Uge1xuICAgIGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXksIGJ5dGVPZmZzZXQsIGxlbmd0aClcbiAgfVxuXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFJldHVybiBhbiBhdWdtZW50ZWQgYFVpbnQ4QXJyYXlgIGluc3RhbmNlLCBmb3IgYmVzdCBwZXJmb3JtYW5jZVxuICAgIHRoYXQgPSBhcnJheVxuICAgIHRoYXQuX19wcm90b19fID0gQnVmZmVyLnByb3RvdHlwZVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbUFycmF5TGlrZSh0aGF0LCBhcnJheSlcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmopIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmopKSB7XG4gICAgdmFyIGxlbiA9IGNoZWNrZWQob2JqLmxlbmd0aCkgfCAwXG4gICAgdGhhdCA9IGNyZWF0ZUJ1ZmZlcih0aGF0LCBsZW4pXG5cbiAgICBpZiAodGhhdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGF0XG4gICAgfVxuXG4gICAgb2JqLmNvcHkodGhhdCwgMCwgMCwgbGVuKVxuICAgIHJldHVybiB0aGF0XG4gIH1cblxuICBpZiAob2JqKSB7XG4gICAgaWYgKCh0eXBlb2YgQXJyYXlCdWZmZXIgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgIG9iai5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgfHwgJ2xlbmd0aCcgaW4gb2JqKSB7XG4gICAgICBpZiAodHlwZW9mIG9iai5sZW5ndGggIT09ICdudW1iZXInIHx8IGlzbmFuKG9iai5sZW5ndGgpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVCdWZmZXIodGhhdCwgMClcbiAgICAgIH1cbiAgICAgIHJldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsIG9iailcbiAgICB9XG5cbiAgICBpZiAob2JqLnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkob2JqLmRhdGEpKSB7XG4gICAgICByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmouZGF0YSlcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCdGaXJzdCBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nLCBCdWZmZXIsIEFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuJylcbn1cblxuZnVuY3Rpb24gY2hlY2tlZCAobGVuZ3RoKSB7XG4gIC8vIE5vdGU6IGNhbm5vdCB1c2UgYGxlbmd0aCA8IGtNYXhMZW5ndGgoKWAgaGVyZSBiZWNhdXNlIHRoYXQgZmFpbHMgd2hlblxuICAvLyBsZW5ndGggaXMgTmFOICh3aGljaCBpcyBvdGhlcndpc2UgY29lcmNlZCB0byB6ZXJvLilcbiAgaWYgKGxlbmd0aCA+PSBrTWF4TGVuZ3RoKCkpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aCgpLnRvU3RyaW5nKDE2KSArICcgYnl0ZXMnKVxuICB9XG4gIHJldHVybiBsZW5ndGggfCAwXG59XG5cbmZ1bmN0aW9uIFNsb3dCdWZmZXIgKGxlbmd0aCkge1xuICBpZiAoK2xlbmd0aCAhPSBsZW5ndGgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBlcWVxZXFcbiAgICBsZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlciAoYikge1xuICByZXR1cm4gISEoYiAhPSBudWxsICYmIGIuX2lzQnVmZmVyKVxufVxuXG5CdWZmZXIuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnMnKVxuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiAwXG5cbiAgdmFyIHggPSBhLmxlbmd0aFxuICB2YXIgeSA9IGIubGVuZ3RoXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkge1xuICAgICAgeCA9IGFbaV1cbiAgICAgIHkgPSBiW2ldXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdsYXRpbjEnOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wibGlzdFwiIGFyZ3VtZW50IG11c3QgYmUgYW4gQXJyYXkgb2YgQnVmZmVycycpXG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDApXG4gIH1cblxuICB2YXIgaVxuICBpZiAobGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICBsZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxlbmd0aCArPSBsaXN0W2ldLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBCdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKVxuICB2YXIgcG9zID0gMFxuICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7ICsraSkge1xuICAgIHZhciBidWYgPSBsaXN0W2ldXG4gICAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJylcbiAgICB9XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpXG4gICAgcG9zICs9IGJ1Zi5sZW5ndGhcbiAgfVxuICByZXR1cm4gYnVmZmVyXG59XG5cbmZ1bmN0aW9uIGJ5dGVMZW5ndGggKHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdHJpbmcpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5sZW5ndGhcbiAgfVxuICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgQXJyYXlCdWZmZXIuaXNWaWV3ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAoQXJyYXlCdWZmZXIuaXNWaWV3KHN0cmluZykgfHwgc3RyaW5nIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgcmV0dXJuIHN0cmluZy5ieXRlTGVuZ3RoXG4gIH1cbiAgaWYgKHR5cGVvZiBzdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgc3RyaW5nID0gJycgKyBzdHJpbmdcbiAgfVxuXG4gIHZhciBsZW4gPSBzdHJpbmcubGVuZ3RoXG4gIGlmIChsZW4gPT09IDApIHJldHVybiAwXG5cbiAgLy8gVXNlIGEgZm9yIGxvb3AgdG8gYXZvaWQgcmVjdXJzaW9uXG4gIHZhciBsb3dlcmVkQ2FzZSA9IGZhbHNlXG4gIGZvciAoOzspIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICBjYXNlICdsYXRpbjEnOlxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGxlblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gbGVuICogMlxuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGxlbiA+Pj4gMVxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cmluZykubGVuZ3RoIC8vIGFzc3VtZSB1dGY4XG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGhcblxuZnVuY3Rpb24gc2xvd1RvU3RyaW5nIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuXG4gIC8vIE5vIG5lZWQgdG8gdmVyaWZ5IHRoYXQgXCJ0aGlzLmxlbmd0aCA8PSBNQVhfVUlOVDMyXCIgc2luY2UgaXQncyBhIHJlYWQtb25seVxuICAvLyBwcm9wZXJ0eSBvZiBhIHR5cGVkIGFycmF5LlxuXG4gIC8vIFRoaXMgYmVoYXZlcyBuZWl0aGVyIGxpa2UgU3RyaW5nIG5vciBVaW50OEFycmF5IGluIHRoYXQgd2Ugc2V0IHN0YXJ0L2VuZFxuICAvLyB0byB0aGVpciB1cHBlci9sb3dlciBib3VuZHMgaWYgdGhlIHZhbHVlIHBhc3NlZCBpcyBvdXQgb2YgcmFuZ2UuXG4gIC8vIHVuZGVmaW5lZCBpcyBoYW5kbGVkIHNwZWNpYWxseSBhcyBwZXIgRUNNQS0yNjIgNnRoIEVkaXRpb24sXG4gIC8vIFNlY3Rpb24gMTMuMy4zLjcgUnVudGltZSBTZW1hbnRpY3M6IEtleWVkQmluZGluZ0luaXRpYWxpemF0aW9uLlxuICBpZiAoc3RhcnQgPT09IHVuZGVmaW5lZCB8fCBzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IDBcbiAgfVxuICAvLyBSZXR1cm4gZWFybHkgaWYgc3RhcnQgPiB0aGlzLmxlbmd0aC4gRG9uZSBoZXJlIHRvIHByZXZlbnQgcG90ZW50aWFsIHVpbnQzMlxuICAvLyBjb2VyY2lvbiBmYWlsIGJlbG93LlxuICBpZiAoc3RhcnQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGhcbiAgfVxuXG4gIGlmIChlbmQgPD0gMCkge1xuICAgIHJldHVybiAnJ1xuICB9XG5cbiAgLy8gRm9yY2UgY29lcnNpb24gdG8gdWludDMyLiBUaGlzIHdpbGwgYWxzbyBjb2VyY2UgZmFsc2V5L05hTiB2YWx1ZXMgdG8gMC5cbiAgZW5kID4+Pj0gMFxuICBzdGFydCA+Pj49IDBcblxuICBpZiAoZW5kIDw9IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBpZiAoIWVuY29kaW5nKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnbGF0aW4xJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAgIHJldHVybiBsYXRpbjFTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndWNzMic6XG4gICAgICBjYXNlICd1Y3MtMic6XG4gICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgICAgcmV0dXJuIHV0ZjE2bGVTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAobG93ZXJlZENhc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZylcbiAgICAgICAgZW5jb2RpbmcgPSAoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cblxuLy8gVGhlIHByb3BlcnR5IGlzIHVzZWQgYnkgYEJ1ZmZlci5pc0J1ZmZlcmAgYW5kIGBpcy1idWZmZXJgIChpbiBTYWZhcmkgNS03KSB0byBkZXRlY3Rcbi8vIEJ1ZmZlciBpbnN0YW5jZXMuXG5CdWZmZXIucHJvdG90eXBlLl9pc0J1ZmZlciA9IHRydWVcblxuZnVuY3Rpb24gc3dhcCAoYiwgbiwgbSkge1xuICB2YXIgaSA9IGJbbl1cbiAgYltuXSA9IGJbbV1cbiAgYlttXSA9IGlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zd2FwMTYgPSBmdW5jdGlvbiBzd2FwMTYgKCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgaWYgKGxlbiAlIDIgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignQnVmZmVyIHNpemUgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDE2LWJpdHMnKVxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHtcbiAgICBzd2FwKHRoaXMsIGksIGkgKyAxKVxuICB9XG4gIHJldHVybiB0aGlzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc3dhcDMyID0gZnVuY3Rpb24gc3dhcDMyICgpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoXG4gIGlmIChsZW4gJSA0ICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0J1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzJylcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7XG4gICAgc3dhcCh0aGlzLCBpLCBpICsgMylcbiAgICBzd2FwKHRoaXMsIGkgKyAxLCBpICsgMilcbiAgfVxuICByZXR1cm4gdGhpc1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnN3YXA2NCA9IGZ1bmN0aW9uIHN3YXA2NCAoKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBpZiAobGVuICUgOCAhPT0gMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0cycpXG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gOCkge1xuICAgIHN3YXAodGhpcywgaSwgaSArIDcpXG4gICAgc3dhcCh0aGlzLCBpICsgMSwgaSArIDYpXG4gICAgc3dhcCh0aGlzLCBpICsgMiwgaSArIDUpXG4gICAgc3dhcCh0aGlzLCBpICsgMywgaSArIDQpXG4gIH1cbiAgcmV0dXJuIHRoaXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nICgpIHtcbiAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoIHwgMFxuICBpZiAobGVuZ3RoID09PSAwKSByZXR1cm4gJydcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHJldHVybiB1dGY4U2xpY2UodGhpcywgMCwgbGVuZ3RoKVxuICByZXR1cm4gc2xvd1RvU3RyaW5nLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiBlcXVhbHMgKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICBpZiAodGhpcyA9PT0gYikgcmV0dXJuIHRydWVcbiAgcmV0dXJuIEJ1ZmZlci5jb21wYXJlKHRoaXMsIGIpID09PSAwXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uIGluc3BlY3QgKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KSBzdHIgKz0gJyAuLi4gJ1xuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgc3RyICsgJz4nXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuY29tcGFyZSA9IGZ1bmN0aW9uIGNvbXBhcmUgKHRhcmdldCwgc3RhcnQsIGVuZCwgdGhpc1N0YXJ0LCB0aGlzRW5kKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKHRhcmdldCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgfVxuXG4gIGlmIChzdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RhcnQgPSAwXG4gIH1cbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZW5kID0gdGFyZ2V0ID8gdGFyZ2V0Lmxlbmd0aCA6IDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzU3RhcnQgPSAwXG4gIH1cbiAgaWYgKHRoaXNFbmQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXNFbmQgPSB0aGlzLmxlbmd0aFxuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBlbmQgPiB0YXJnZXQubGVuZ3RoIHx8IHRoaXNTdGFydCA8IDAgfHwgdGhpc0VuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ291dCBvZiByYW5nZSBpbmRleCcpXG4gIH1cblxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQgJiYgc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuICBpZiAodGhpc1N0YXJ0ID49IHRoaXNFbmQpIHtcbiAgICByZXR1cm4gLTFcbiAgfVxuICBpZiAoc3RhcnQgPj0gZW5kKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIHN0YXJ0ID4+Pj0gMFxuICBlbmQgPj4+PSAwXG4gIHRoaXNTdGFydCA+Pj49IDBcbiAgdGhpc0VuZCA+Pj49IDBcblxuICBpZiAodGhpcyA9PT0gdGFyZ2V0KSByZXR1cm4gMFxuXG4gIHZhciB4ID0gdGhpc0VuZCAtIHRoaXNTdGFydFxuICB2YXIgeSA9IGVuZCAtIHN0YXJ0XG4gIHZhciBsZW4gPSBNYXRoLm1pbih4LCB5KVxuXG4gIHZhciB0aGlzQ29weSA9IHRoaXMuc2xpY2UodGhpc1N0YXJ0LCB0aGlzRW5kKVxuICB2YXIgdGFyZ2V0Q29weSA9IHRhcmdldC5zbGljZShzdGFydCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAodGhpc0NvcHlbaV0gIT09IHRhcmdldENvcHlbaV0pIHtcbiAgICAgIHggPSB0aGlzQ29weVtpXVxuICAgICAgeSA9IHRhcmdldENvcHlbaV1cbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKHggPCB5KSByZXR1cm4gLTFcbiAgaWYgKHkgPCB4KSByZXR1cm4gMVxuICByZXR1cm4gMFxufVxuXG4vLyBGaW5kcyBlaXRoZXIgdGhlIGZpcnN0IGluZGV4IG9mIGB2YWxgIGluIGBidWZmZXJgIGF0IG9mZnNldCA+PSBgYnl0ZU9mZnNldGAsXG4vLyBPUiB0aGUgbGFzdCBpbmRleCBvZiBgdmFsYCBpbiBgYnVmZmVyYCBhdCBvZmZzZXQgPD0gYGJ5dGVPZmZzZXRgLlxuLy9cbi8vIEFyZ3VtZW50czpcbi8vIC0gYnVmZmVyIC0gYSBCdWZmZXIgdG8gc2VhcmNoXG4vLyAtIHZhbCAtIGEgc3RyaW5nLCBCdWZmZXIsIG9yIG51bWJlclxuLy8gLSBieXRlT2Zmc2V0IC0gYW4gaW5kZXggaW50byBgYnVmZmVyYDsgd2lsbCBiZSBjbGFtcGVkIHRvIGFuIGludDMyXG4vLyAtIGVuY29kaW5nIC0gYW4gb3B0aW9uYWwgZW5jb2RpbmcsIHJlbGV2YW50IGlzIHZhbCBpcyBhIHN0cmluZ1xuLy8gLSBkaXIgLSB0cnVlIGZvciBpbmRleE9mLCBmYWxzZSBmb3IgbGFzdEluZGV4T2ZcbmZ1bmN0aW9uIGJpZGlyZWN0aW9uYWxJbmRleE9mIChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcsIGRpcikge1xuICAvLyBFbXB0eSBidWZmZXIgbWVhbnMgbm8gbWF0Y2hcbiAgaWYgKGJ1ZmZlci5sZW5ndGggPT09IDApIHJldHVybiAtMVxuXG4gIC8vIE5vcm1hbGl6ZSBieXRlT2Zmc2V0XG4gIGlmICh0eXBlb2YgYnl0ZU9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICBlbmNvZGluZyA9IGJ5dGVPZmZzZXRcbiAgICBieXRlT2Zmc2V0ID0gMFxuICB9IGVsc2UgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSB7XG4gICAgYnl0ZU9mZnNldCA9IDB4N2ZmZmZmZmZcbiAgfSBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIHtcbiAgICBieXRlT2Zmc2V0ID0gLTB4ODAwMDAwMDBcbiAgfVxuICBieXRlT2Zmc2V0ID0gK2J5dGVPZmZzZXQgIC8vIENvZXJjZSB0byBOdW1iZXIuXG4gIGlmIChpc05hTihieXRlT2Zmc2V0KSkge1xuICAgIC8vIGJ5dGVPZmZzZXQ6IGl0IGl0J3MgdW5kZWZpbmVkLCBudWxsLCBOYU4sIFwiZm9vXCIsIGV0Yywgc2VhcmNoIHdob2xlIGJ1ZmZlclxuICAgIGJ5dGVPZmZzZXQgPSBkaXIgPyAwIDogKGJ1ZmZlci5sZW5ndGggLSAxKVxuICB9XG5cbiAgLy8gTm9ybWFsaXplIGJ5dGVPZmZzZXQ6IG5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gYnVmZmVyLmxlbmd0aCArIGJ5dGVPZmZzZXRcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkge1xuICAgIGlmIChkaXIpIHJldHVybiAtMVxuICAgIGVsc2UgYnl0ZU9mZnNldCA9IGJ1ZmZlci5sZW5ndGggLSAxXG4gIH0gZWxzZSBpZiAoYnl0ZU9mZnNldCA8IDApIHtcbiAgICBpZiAoZGlyKSBieXRlT2Zmc2V0ID0gMFxuICAgIGVsc2UgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBOb3JtYWxpemUgdmFsXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIHZhbCA9IEJ1ZmZlci5mcm9tKHZhbCwgZW5jb2RpbmcpXG4gIH1cblxuICAvLyBGaW5hbGx5LCBzZWFyY2ggZWl0aGVyIGluZGV4T2YgKGlmIGRpciBpcyB0cnVlKSBvciBsYXN0SW5kZXhPZlxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICAvLyBTcGVjaWFsIGNhc2U6IGxvb2tpbmcgZm9yIGVtcHR5IHN0cmluZy9idWZmZXIgYWx3YXlzIGZhaWxzXG4gICAgaWYgKHZhbC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH1cbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKVxuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSB7XG4gICAgdmFsID0gdmFsICYgMHhGRiAvLyBTZWFyY2ggZm9yIGEgYnl0ZSB2YWx1ZSBbMC0yNTVdXG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUICYmXG4gICAgICAgIHR5cGVvZiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoZGlyKSB7XG4gICAgICAgIHJldHVybiBVaW50OEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoYnVmZmVyLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsIHZhbCwgYnl0ZU9mZnNldClcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFycmF5SW5kZXhPZihidWZmZXIsIFsgdmFsIF0sIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBkaXIpXG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKCd2YWwgbXVzdCBiZSBzdHJpbmcsIG51bWJlciBvciBCdWZmZXInKVxufVxuXG5mdW5jdGlvbiBhcnJheUluZGV4T2YgKGFyciwgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgZGlyKSB7XG4gIHZhciBpbmRleFNpemUgPSAxXG4gIHZhciBhcnJMZW5ndGggPSBhcnIubGVuZ3RoXG4gIHZhciB2YWxMZW5ndGggPSB2YWwubGVuZ3RoXG5cbiAgaWYgKGVuY29kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgIGlmIChlbmNvZGluZyA9PT0gJ3VjczInIHx8IGVuY29kaW5nID09PSAndWNzLTInIHx8XG4gICAgICAgIGVuY29kaW5nID09PSAndXRmMTZsZScgfHwgZW5jb2RpbmcgPT09ICd1dGYtMTZsZScpIHtcbiAgICAgIGlmIChhcnIubGVuZ3RoIDwgMiB8fCB2YWwubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH1cbiAgICAgIGluZGV4U2l6ZSA9IDJcbiAgICAgIGFyckxlbmd0aCAvPSAyXG4gICAgICB2YWxMZW5ndGggLz0gMlxuICAgICAgYnl0ZU9mZnNldCAvPSAyXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZCAoYnVmLCBpKSB7XG4gICAgaWYgKGluZGV4U2l6ZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIGJ1ZltpXVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpICogaW5kZXhTaXplKVxuICAgIH1cbiAgfVxuXG4gIHZhciBpXG4gIGlmIChkaXIpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yIChpID0gYnl0ZU9mZnNldDsgaSA8IGFyckxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmVhZChhcnIsIGkpID09PSByZWFkKHZhbCwgZm91bmRJbmRleCA9PT0gLTEgPyAwIDogaSAtIGZvdW5kSW5kZXgpKSB7XG4gICAgICAgIGlmIChmb3VuZEluZGV4ID09PSAtMSkgZm91bmRJbmRleCA9IGlcbiAgICAgICAgaWYgKGkgLSBmb3VuZEluZGV4ICsgMSA9PT0gdmFsTGVuZ3RoKSByZXR1cm4gZm91bmRJbmRleCAqIGluZGV4U2l6ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZvdW5kSW5kZXggIT09IC0xKSBpIC09IGkgLSBmb3VuZEluZGV4XG4gICAgICAgIGZvdW5kSW5kZXggPSAtMVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoYnl0ZU9mZnNldCArIHZhbExlbmd0aCA+IGFyckxlbmd0aCkgYnl0ZU9mZnNldCA9IGFyckxlbmd0aCAtIHZhbExlbmd0aFxuICAgIGZvciAoaSA9IGJ5dGVPZmZzZXQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICB2YXIgZm91bmQgPSB0cnVlXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHZhbExlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChyZWFkKGFyciwgaSArIGopICE9PSByZWFkKHZhbCwgaikpIHtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gaVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluY2x1ZGVzID0gZnVuY3Rpb24gaW5jbHVkZXMgKHZhbCwgYnl0ZU9mZnNldCwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSAhPT0gLTFcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZiAodmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZykge1xuICByZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcywgdmFsLCBieXRlT2Zmc2V0LCBlbmNvZGluZywgdHJ1ZSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uIGxhc3RJbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nKSB7XG4gIHJldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLCB2YWwsIGJ5dGVPZmZzZXQsIGVuY29kaW5nLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgcmV0dXJuIGlcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBwYXJzZWRcbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiB1dGY4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGxhdGluMVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGFzY2lpV3JpdGUoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiBiYXNlNjRXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gdWNzMldyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIodXRmMTZsZVRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIHdyaXRlIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nKVxuICBpZiAob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBlbmNvZGluZyA9ICd1dGY4J1xuICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoXG4gICAgb2Zmc2V0ID0gMFxuICAvLyBCdWZmZXIjd3JpdGUoc3RyaW5nLCBlbmNvZGluZylcbiAgfSBlbHNlIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIG9mZnNldFssIGxlbmd0aF1bLCBlbmNvZGluZ10pXG4gIH0gZWxzZSBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgICBpZiAoaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgbGVuZ3RoID0gbGVuZ3RoIHwgMFxuICAgICAgaWYgKGVuY29kaW5nID09PSB1bmRlZmluZWQpIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoXG4gICAgICBsZW5ndGggPSB1bmRlZmluZWRcbiAgICB9XG4gIC8vIGxlZ2FjeSB3cml0ZShzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aCkgLSByZW1vdmUgaW4gdjAuMTNcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWQnXG4gICAgKVxuICB9XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmIChsZW5ndGggPT09IHVuZGVmaW5lZCB8fCBsZW5ndGggPiByZW1haW5pbmcpIGxlbmd0aCA9IHJlbWFpbmluZ1xuXG4gIGlmICgoc3RyaW5nLmxlbmd0aCA+IDAgJiYgKGxlbmd0aCA8IDAgfHwgb2Zmc2V0IDwgMCkpIHx8IG9mZnNldCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJylcbiAgfVxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG5cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2hleCc6XG4gICAgICAgIHJldHVybiBoZXhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1dGY4JzpcbiAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgcmV0dXJuIHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIHJldHVybiBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gbGF0aW4xV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgLy8gV2FybmluZzogbWF4TGVuZ3RoIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgaW4gYmFzZTY0V3JpdGVcbiAgICAgICAgcmV0dXJuIGJhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1Y3MyV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKCcnICsgZW5jb2RpbmcpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnQnVmZmVyJyxcbiAgICBkYXRhOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnIgfHwgdGhpcywgMClcbiAgfVxufVxuXG5mdW5jdGlvbiBiYXNlNjRTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGlmIChzdGFydCA9PT0gMCAmJiBlbmQgPT09IGJ1Zi5sZW5ndGgpIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYuc2xpY2Uoc3RhcnQsIGVuZCkpXG4gIH1cbn1cblxuZnVuY3Rpb24gdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuICB2YXIgcmVzID0gW11cblxuICB2YXIgaSA9IHN0YXJ0XG4gIHdoaWxlIChpIDwgZW5kKSB7XG4gICAgdmFyIGZpcnN0Qnl0ZSA9IGJ1ZltpXVxuICAgIHZhciBjb2RlUG9pbnQgPSBudWxsXG4gICAgdmFyIGJ5dGVzUGVyU2VxdWVuY2UgPSAoZmlyc3RCeXRlID4gMHhFRikgPyA0XG4gICAgICA6IChmaXJzdEJ5dGUgPiAweERGKSA/IDNcbiAgICAgIDogKGZpcnN0Qnl0ZSA+IDB4QkYpID8gMlxuICAgICAgOiAxXG5cbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPD0gZW5kKSB7XG4gICAgICB2YXIgc2Vjb25kQnl0ZSwgdGhpcmRCeXRlLCBmb3VydGhCeXRlLCB0ZW1wQ29kZVBvaW50XG5cbiAgICAgIHN3aXRjaCAoYnl0ZXNQZXJTZXF1ZW5jZSkge1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGZpcnN0Qnl0ZSA8IDB4ODApIHtcbiAgICAgICAgICAgIGNvZGVQb2ludCA9IGZpcnN0Qnl0ZVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweDFGKSA8PCAweDYgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0YpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgICAgICB0ZW1wQ29kZVBvaW50ID0gKGZpcnN0Qnl0ZSAmIDB4RikgPDwgMHhDIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAodGhpcmRCeXRlICYgMHgzRilcbiAgICAgICAgICAgIGlmICh0ZW1wQ29kZVBvaW50ID4gMHg3RkYgJiYgKHRlbXBDb2RlUG9pbnQgPCAweEQ4MDAgfHwgdGVtcENvZGVQb2ludCA+IDB4REZGRikpIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgc2Vjb25kQnl0ZSA9IGJ1ZltpICsgMV1cbiAgICAgICAgICB0aGlyZEJ5dGUgPSBidWZbaSArIDJdXG4gICAgICAgICAgZm91cnRoQnl0ZSA9IGJ1ZltpICsgM11cbiAgICAgICAgICBpZiAoKHNlY29uZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCAmJiAodGhpcmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKGZvdXJ0aEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4MTIgfCAoc2Vjb25kQnl0ZSAmIDB4M0YpIDw8IDB4QyB8ICh0aGlyZEJ5dGUgJiAweDNGKSA8PCAweDYgfCAoZm91cnRoQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4RkZGRiAmJiB0ZW1wQ29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgICAgICAgICAgY29kZVBvaW50ID0gdGVtcENvZGVQb2ludFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY29kZVBvaW50ID09PSBudWxsKSB7XG4gICAgICAvLyB3ZSBkaWQgbm90IGdlbmVyYXRlIGEgdmFsaWQgY29kZVBvaW50IHNvIGluc2VydCBhXG4gICAgICAvLyByZXBsYWNlbWVudCBjaGFyIChVK0ZGRkQpIGFuZCBhZHZhbmNlIG9ubHkgMSBieXRlXG4gICAgICBjb2RlUG9pbnQgPSAweEZGRkRcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPiAweEZGRkYpIHtcbiAgICAgIC8vIGVuY29kZSB0byB1dGYxNiAoc3Vycm9nYXRlIHBhaXIgZGFuY2UpXG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMFxuICAgICAgcmVzLnB1c2goY29kZVBvaW50ID4+PiAxMCAmIDB4M0ZGIHwgMHhEODAwKVxuICAgICAgY29kZVBvaW50ID0gMHhEQzAwIHwgY29kZVBvaW50ICYgMHgzRkZcbiAgICB9XG5cbiAgICByZXMucHVzaChjb2RlUG9pbnQpXG4gICAgaSArPSBieXRlc1BlclNlcXVlbmNlXG4gIH1cblxuICByZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcylcbn1cblxuLy8gQmFzZWQgb24gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjI3NDcyNzIvNjgwNzQyLCB0aGUgYnJvd3NlciB3aXRoXG4vLyB0aGUgbG93ZXN0IGxpbWl0IGlzIENocm9tZSwgd2l0aCAweDEwMDAwIGFyZ3MuXG4vLyBXZSBnbyAxIG1hZ25pdHVkZSBsZXNzLCBmb3Igc2FmZXR5XG52YXIgTUFYX0FSR1VNRU5UU19MRU5HVEggPSAweDEwMDBcblxuZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5IChjb2RlUG9pbnRzKSB7XG4gIHZhciBsZW4gPSBjb2RlUG9pbnRzLmxlbmd0aFxuICBpZiAobGVuIDw9IE1BWF9BUkdVTUVOVFNfTEVOR1RIKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjb2RlUG9pbnRzKSAvLyBhdm9pZCBleHRyYSBzbGljZSgpXG4gIH1cblxuICAvLyBEZWNvZGUgaW4gY2h1bmtzIHRvIGF2b2lkIFwiY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkXCIuXG4gIHZhciByZXMgPSAnJ1xuICB2YXIgaSA9IDBcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShcbiAgICAgIFN0cmluZyxcbiAgICAgIGNvZGVQb2ludHMuc2xpY2UoaSwgaSArPSBNQVhfQVJHVU1FTlRTX0xFTkdUSClcbiAgICApXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7ICsraSkge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBsYXRpbjFTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIHNsaWNlIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW5cbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgfSBlbHNlIGlmIChzdGFydCA+IGxlbikge1xuICAgIHN0YXJ0ID0gbGVuXG4gIH1cblxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCArPSBsZW5cbiAgICBpZiAoZW5kIDwgMCkgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIHZhciBuZXdCdWZcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgbmV3QnVmID0gdGhpcy5zdWJhcnJheShzdGFydCwgZW5kKVxuICAgIG5ld0J1Zi5fX3Byb3RvX18gPSBCdWZmZXIucHJvdG90eXBlXG4gIH0gZWxzZSB7XG4gICAgdmFyIHNsaWNlTGVuID0gZW5kIC0gc3RhcnRcbiAgICBuZXdCdWYgPSBuZXcgQnVmZmVyKHNsaWNlTGVuLCB1bmRlZmluZWQpXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzbGljZUxlbjsgKytpKSB7XG4gICAgICBuZXdCdWZbaV0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3QnVmXG59XG5cbi8qXG4gKiBOZWVkIHRvIG1ha2Ugc3VyZSB0aGF0IGJ1ZmZlciBpc24ndCB0cnlpbmcgdG8gd3JpdGUgb3V0IG9mIGJvdW5kcy5cbiAqL1xuZnVuY3Rpb24gY2hlY2tPZmZzZXQgKG9mZnNldCwgZXh0LCBsZW5ndGgpIHtcbiAgaWYgKChvZmZzZXQgJSAxKSAhPT0gMCB8fCBvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RyeWluZyB0byBhY2Nlc3MgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEUgPSBmdW5jdGlvbiByZWFkVUludExFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50QkUgPSBmdW5jdGlvbiByZWFkVUludEJFIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuICB9XG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWJ5dGVMZW5ndGhdICogbXVsXG4gIH1cblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gcmVhZFVJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbiByZWFkVUludDE2TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRVSW50MzJMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAoKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpKSArXG4gICAgICAodGhpc1tvZmZzZXQgKyAzXSAqIDB4MTAwMDAwMClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbiByZWFkVUludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSAqIDB4MTAwMDAwMCkgK1xuICAgICgodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICB0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRMRSA9IGZ1bmN0aW9uIHJlYWRJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnRCRSA9IGZ1bmN0aW9uIHJlYWRJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aFxuICB2YXIgbXVsID0gMVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAtLWldXG4gIHdoaWxlIChpID4gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIC0taV0gKiBtdWxcbiAgfVxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKSB2YWwgLT0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpXG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gcmVhZEludDggKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAxLCB0aGlzLmxlbmd0aClcbiAgaWYgKCEodGhpc1tvZmZzZXRdICYgMHg4MCkpIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIHJlYWRJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxuICByZXR1cm4gKHZhbCAmIDB4ODAwMCkgPyB2YWwgfCAweEZGRkYwMDAwIDogdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbiByZWFkSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXQgKyAxXSB8ICh0aGlzW29mZnNldF0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24gcmVhZEludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gcmVhZEludDMyQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCAyNCkgfFxuICAgICh0aGlzW29mZnNldCArIDFdIDw8IDE2KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICh0aGlzW29mZnNldCArIDNdKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24gcmVhZEZsb2F0TEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDIzLCA0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24gcmVhZEZsb2F0QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiByZWFkRG91YmxlTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIHRydWUsIDUyLCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uIHJlYWREb3VibGVCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDgsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsIG9mZnNldCwgZmFsc2UsIDUyLCA4KVxufVxuXG5mdW5jdGlvbiBjaGVja0ludCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiYnVmZmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1widmFsdWVcIiBhcmd1bWVudCBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gd3JpdGVVSW50TEUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFID0gZnVuY3Rpb24gd3JpdGVVSW50QkUgKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbWF4Qnl0ZXMgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCkgLSAxXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbWF4Qnl0ZXMsIDApXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgJiAweEZGXG4gIH1cblxuICByZXR1cm4gb2Zmc2V0ICsgYnl0ZUxlbmd0aFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbiB3cml0ZVVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyArK2kpIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uIHdyaXRlVUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHhmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MzIgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmZmZmZiArIHZhbHVlICsgMVxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGJ1Zi5sZW5ndGggLSBvZmZzZXQsIDQpOyBpIDwgajsgKytpKSB7XG4gICAgYnVmW29mZnNldCArIGldID0gKHZhbHVlID4+PiAobGl0dGxlRW5kaWFuID8gaSA6IDMgLSBpKSAqIDgpICYgMHhmZlxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uIHdyaXRlVUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDI0KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDE2KVxuICAgIHRoaXNbb2Zmc2V0ICsgMl0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludExFID0gZnVuY3Rpb24gd3JpdGVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IDBcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHN1YiA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpIC0gMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSAwXG4gIHRoaXNbb2Zmc2V0ICsgaV0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKC0taSA+PSAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgaWYgKHZhbHVlIDwgMCAmJiBzdWIgPT09IDAgJiYgdGhpc1tvZmZzZXQgKyBpICsgMV0gIT09IDApIHtcbiAgICAgIHN1YiA9IDFcbiAgICB9XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiB3cml0ZUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlICYgMHhmZilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiB3cml0ZUludDE2QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSAmIDB4ZmYpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiB3cml0ZUludDMyTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSAmIDB4ZmYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSAodmFsdWUgJiAweGZmKVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmIChvZmZzZXQgKyBleHQgPiBidWYubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5kZXggb3V0IG9mIHJhbmdlJylcbiAgaWYgKG9mZnNldCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdJbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5mdW5jdGlvbiB3cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDQsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uIHdyaXRlRmxvYXRMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24gd3JpdGVGbG9hdEJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSUVFRTc1NChidWYsIHZhbHVlLCBvZmZzZXQsIDgsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uIHdyaXRlRG91YmxlTEUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gY29weSAodGFyZ2V0LCB0YXJnZXRTdGFydCwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0U3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkgdGFyZ2V0U3RhcnQgPSB0YXJnZXQubGVuZ3RoXG4gIGlmICghdGFyZ2V0U3RhcnQpIHRhcmdldFN0YXJ0ID0gMFxuICBpZiAoZW5kID4gMCAmJiBlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwXG4gIGlmICh0YXJnZXQubGVuZ3RoID09PSAwIHx8IHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldFN0YXJ0IDwgMCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgfVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpXG4gIGlmIChlbmQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRTdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuICB2YXIgaVxuXG4gIGlmICh0aGlzID09PSB0YXJnZXQgJiYgc3RhcnQgPCB0YXJnZXRTdGFydCAmJiB0YXJnZXRTdGFydCA8IGVuZCkge1xuICAgIC8vIGRlc2NlbmRpbmcgY29weSBmcm9tIGVuZFxuICAgIGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB0YXJnZXRbaSArIHRhcmdldFN0YXJ0XSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfSBlbHNlIGlmIChsZW4gPCAxMDAwIHx8ICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIGFzY2VuZGluZyBjb3B5IGZyb20gc3RhcnRcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIFVpbnQ4QXJyYXkucHJvdG90eXBlLnNldC5jYWxsKFxuICAgICAgdGFyZ2V0LFxuICAgICAgdGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLFxuICAgICAgdGFyZ2V0U3RhcnRcbiAgICApXG4gIH1cblxuICByZXR1cm4gbGVuXG59XG5cbi8vIFVzYWdlOlxuLy8gICAgYnVmZmVyLmZpbGwobnVtYmVyWywgb2Zmc2V0WywgZW5kXV0pXG4vLyAgICBidWZmZXIuZmlsbChidWZmZXJbLCBvZmZzZXRbLCBlbmRdXSlcbi8vICAgIGJ1ZmZlci5maWxsKHN0cmluZ1ssIG9mZnNldFssIGVuZF1dWywgZW5jb2RpbmddKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCAodmFsLCBzdGFydCwgZW5kLCBlbmNvZGluZykge1xuICAvLyBIYW5kbGUgc3RyaW5nIGNhc2VzOlxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIHN0YXJ0ID09PSAnc3RyaW5nJykge1xuICAgICAgZW5jb2RpbmcgPSBzdGFydFxuICAgICAgc3RhcnQgPSAwXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVuZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGVuY29kaW5nID0gZW5kXG4gICAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICAgIH1cbiAgICBpZiAodmFsLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIGNvZGUgPSB2YWwuY2hhckNvZGVBdCgwKVxuICAgICAgaWYgKGNvZGUgPCAyNTYpIHtcbiAgICAgICAgdmFsID0gY29kZVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZW5jb2RpbmcgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2YgZW5jb2RpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdlbmNvZGluZyBtdXN0IGJlIGEgc3RyaW5nJylcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ3N0cmluZycgJiYgIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIHZhbCA9IHZhbCAmIDI1NVxuICB9XG5cbiAgLy8gSW52YWxpZCByYW5nZXMgYXJlIG5vdCBzZXQgdG8gYSBkZWZhdWx0LCBzbyBjYW4gcmFuZ2UgY2hlY2sgZWFybHkuXG4gIGlmIChzdGFydCA8IDAgfHwgdGhpcy5sZW5ndGggPCBzdGFydCB8fCB0aGlzLmxlbmd0aCA8IGVuZCkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdPdXQgb2YgcmFuZ2UgaW5kZXgnKVxuICB9XG5cbiAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gdGhpcy5sZW5ndGggOiBlbmQgPj4+IDBcblxuICBpZiAoIXZhbCkgdmFsID0gMFxuXG4gIHZhciBpXG4gIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykge1xuICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIHRoaXNbaV0gPSB2YWxcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gQnVmZmVyLmlzQnVmZmVyKHZhbClcbiAgICAgID8gdmFsXG4gICAgICA6IHV0ZjhUb0J5dGVzKG5ldyBCdWZmZXIodmFsLCBlbmNvZGluZykudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gMDsgaSA8IGVuZCAtIHN0YXJ0OyArK2kpIHtcbiAgICAgIHRoaXNbaSArIHN0YXJ0XSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy8gPT09PT09PT09PT09PT09PVxuXG52YXIgSU5WQUxJRF9CQVNFNjRfUkUgPSAvW14rXFwvMC05QS1aYS16LV9dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cmluZywgdW5pdHMpIHtcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgY29kZVBvaW50XG4gIHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoXG4gIHZhciBsZWFkU3Vycm9nYXRlID0gbnVsbFxuICB2YXIgYnl0ZXMgPSBbXVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBjb2RlUG9pbnQgPSBzdHJpbmcuY2hhckNvZGVBdChpKVxuXG4gICAgLy8gaXMgc3Vycm9nYXRlIGNvbXBvbmVudFxuICAgIGlmIChjb2RlUG9pbnQgPiAweEQ3RkYgJiYgY29kZVBvaW50IDwgMHhFMDAwKSB7XG4gICAgICAvLyBsYXN0IGNoYXIgd2FzIGEgbGVhZFxuICAgICAgaWYgKCFsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAgIC8vIG5vIGxlYWQgeWV0XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPiAweERCRkYpIHtcbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHRyYWlsXG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfSBlbHNlIGlmIChpICsgMSA9PT0gbGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdW5wYWlyZWQgbGVhZFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBsZWFkXG4gICAgICAgIGxlYWRTdXJyb2dhdGUgPSBjb2RlUG9pbnRcblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyAyIGxlYWRzIGluIGEgcm93XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIHZhbGlkIHN1cnJvZ2F0ZSBwYWlyXG4gICAgICBjb2RlUG9pbnQgPSAobGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCkgKyAweDEwMDAwXG4gICAgfSBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICAvLyB2YWxpZCBibXAgY2hhciwgYnV0IGxhc3QgY2hhciB3YXMgYSBsZWFkXG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICB9XG5cbiAgICBsZWFkU3Vycm9nYXRlID0gbnVsbFxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9IGVsc2UgaWYgKGNvZGVQb2ludCA8IDB4ODAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgfCAweEMwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAzKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDIHwgMHhFMCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHgxMTAwMDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gNCkgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4MTIgfCAweEYwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHhDICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweDYgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ICYgMHgzRiB8IDB4ODBcbiAgICAgIClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvZGUgcG9pbnQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBieXRlc1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYpXG4gIH1cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiB1dGYxNmxlVG9CeXRlcyAoc3RyLCB1bml0cykge1xuICB2YXIgYywgaGksIGxvXG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuXG4gICAgYyA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaGkgPSBjID4+IDhcbiAgICBsbyA9IGMgJSAyNTZcbiAgICBieXRlQXJyYXkucHVzaChsbylcbiAgICBieXRlQXJyYXkucHVzaChoaSlcbiAgfVxuXG4gIHJldHVybiBieXRlQXJyYXlcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyAoc3RyKSB7XG4gIHJldHVybiBiYXNlNjQudG9CeXRlQXJyYXkoYmFzZTY0Y2xlYW4oc3RyKSlcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlciAoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpIGJyZWFrXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gaXNuYW4gKHZhbCkge1xuICByZXR1cm4gdmFsICE9PSB2YWwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbn1cbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9jb3JlLnJlZ2V4cC5lc2NhcGUnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLlJlZ0V4cC5lc2NhcGU7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCJ2YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgbXNnKSB7XG4gIGlmICh0eXBlb2YgaXQgIT0gJ251bWJlcicgJiYgY29mKGl0KSAhPSAnTnVtYmVyJykgdGhyb3cgVHlwZUVycm9yKG1zZyk7XG4gIHJldHVybiAraXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMxIEFycmF5LnByb3RvdHlwZVtAQHVuc2NvcGFibGVzXVxudmFyIFVOU0NPUEFCTEVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3Vuc2NvcGFibGVzJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcbmlmIChBcnJheVByb3RvW1VOU0NPUEFCTEVTXSA9PSB1bmRlZmluZWQpIHJlcXVpcmUoJy4vX2hpZGUnKShBcnJheVByb3RvLCBVTlNDT1BBQkxFUywge30pO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdW2tleV0gPSB0cnVlO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKHRydWUpO1xuXG4gLy8gYEFkdmFuY2VTdHJpbmdJbmRleGAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1hZHZhbmNlc3RyaW5naW5kZXhcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFMsIGluZGV4LCB1bmljb2RlKSB7XG4gIHJldHVybiBpbmRleCArICh1bmljb2RlID8gYXQoUywgaW5kZXgpLmxlbmd0aCA6IDEpO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpIHtcbiAgaWYgKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkgdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMgQXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCwgZW5kID0gdGhpcy5sZW5ndGgpXG4ndXNlIHN0cmljdCc7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gW10uY29weVdpdGhpbiB8fCBmdW5jdGlvbiBjb3B5V2l0aGluKHRhcmdldCAvKiA9IDAgKi8sIHN0YXJ0IC8qID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgdG8gPSB0b0Fic29sdXRlSW5kZXgodGFyZ2V0LCBsZW4pO1xuICB2YXIgZnJvbSA9IHRvQWJzb2x1dGVJbmRleChzdGFydCwgbGVuKTtcbiAgdmFyIGVuZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgY291bnQgPSBNYXRoLm1pbigoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pKSAtIGZyb20sIGxlbiAtIHRvKTtcbiAgdmFyIGluYyA9IDE7XG4gIGlmIChmcm9tIDwgdG8gJiYgdG8gPCBmcm9tICsgY291bnQpIHtcbiAgICBpbmMgPSAtMTtcbiAgICBmcm9tICs9IGNvdW50IC0gMTtcbiAgICB0byArPSBjb3VudCAtIDE7XG4gIH1cbiAgd2hpbGUgKGNvdW50LS0gPiAwKSB7XG4gICAgaWYgKGZyb20gaW4gTykgT1t0b10gPSBPW2Zyb21dO1xuICAgIGVsc2UgZGVsZXRlIE9bdG9dO1xuICAgIHRvICs9IGluYztcbiAgICBmcm9tICs9IGluYztcbiAgfSByZXR1cm4gTztcbn07XG4iLCIvLyAyMi4xLjMuNiBBcnJheS5wcm90b3R5cGUuZmlsbCh2YWx1ZSwgc3RhcnQgPSAwLCBlbmQgPSB0aGlzLmxlbmd0aClcbid1c2Ugc3RyaWN0JztcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmlsbCh2YWx1ZSAvKiAsIHN0YXJ0ID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IHRvQWJzb2x1dGVJbmRleChhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgbGVuZ3RoKTtcbiAgdmFyIGVuZCA9IGFMZW4gPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgZW5kUG9zID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW5ndGgpO1xuICB3aGlsZSAoZW5kUG9zID4gaW5kZXgpIE9baW5kZXgrK10gPSB2YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXIsIElURVJBVE9SKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yT2YoaXRlciwgZmFsc2UsIHJlc3VsdC5wdXNoLCByZXN1bHQsIElURVJBVE9SKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG4iLCIvLyBmYWxzZSAtPiBBcnJheSNpbmRleE9mXG4vLyB0cnVlICAtPiBBcnJheSNpbmNsdWRlc1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChJU19JTkNMVURFUykge1xuICByZXR1cm4gZnVuY3Rpb24gKCR0aGlzLCBlbCwgZnJvbUluZGV4KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoJHRoaXMpO1xuICAgIHZhciBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgdmFyIGluZGV4ID0gdG9BYnNvbHV0ZUluZGV4KGZyb21JbmRleCwgbGVuZ3RoKTtcbiAgICB2YXIgdmFsdWU7XG4gICAgLy8gQXJyYXkjaW5jbHVkZXMgdXNlcyBTYW1lVmFsdWVaZXJvIGVxdWFsaXR5IGFsZ29yaXRobVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICBpZiAoSVNfSU5DTFVERVMgJiYgZWwgIT0gZWwpIHdoaWxlIChsZW5ndGggPiBpbmRleCkge1xuICAgICAgdmFsdWUgPSBPW2luZGV4KytdO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgICAgaWYgKHZhbHVlICE9IHZhbHVlKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBBcnJheSNpbmRleE9mIGlnbm9yZXMgaG9sZXMsIEFycmF5I2luY2x1ZGVzIC0gbm90XG4gICAgfSBlbHNlIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoSVNfSU5DTFVERVMgfHwgaW5kZXggaW4gTykge1xuICAgICAgaWYgKE9baW5kZXhdID09PSBlbCkgcmV0dXJuIElTX0lOQ0xVREVTIHx8IGluZGV4IHx8IDA7XG4gICAgfSByZXR1cm4gIUlTX0lOQ0xVREVTICYmIC0xO1xuICB9O1xufTtcbiIsIi8vIDAgLT4gQXJyYXkjZm9yRWFjaFxuLy8gMSAtPiBBcnJheSNtYXBcbi8vIDIgLT4gQXJyYXkjZmlsdGVyXG4vLyAzIC0+IEFycmF5I3NvbWVcbi8vIDQgLT4gQXJyYXkjZXZlcnlcbi8vIDUgLT4gQXJyYXkjZmluZFxuLy8gNiAtPiBBcnJheSNmaW5kSW5kZXhcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBhc2MgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoVFlQRSwgJGNyZWF0ZSkge1xuICB2YXIgSVNfTUFQID0gVFlQRSA9PSAxO1xuICB2YXIgSVNfRklMVEVSID0gVFlQRSA9PSAyO1xuICB2YXIgSVNfU09NRSA9IFRZUEUgPT0gMztcbiAgdmFyIElTX0VWRVJZID0gVFlQRSA9PSA0O1xuICB2YXIgSVNfRklORF9JTkRFWCA9IFRZUEUgPT0gNjtcbiAgdmFyIE5PX0hPTEVTID0gVFlQRSA9PSA1IHx8IElTX0ZJTkRfSU5ERVg7XG4gIHZhciBjcmVhdGUgPSAkY3JlYXRlIHx8IGFzYztcbiAgcmV0dXJuIGZ1bmN0aW9uICgkdGhpcywgY2FsbGJhY2tmbiwgdGhhdCkge1xuICAgIHZhciBPID0gdG9PYmplY3QoJHRoaXMpO1xuICAgIHZhciBzZWxmID0gSU9iamVjdChPKTtcbiAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCB0aGF0LCAzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoc2VsZi5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIHJlc3VsdCA9IElTX01BUCA/IGNyZWF0ZSgkdGhpcywgbGVuZ3RoKSA6IElTX0ZJTFRFUiA/IGNyZWF0ZSgkdGhpcywgMCkgOiB1bmRlZmluZWQ7XG4gICAgdmFyIHZhbCwgcmVzO1xuICAgIGZvciAoO2xlbmd0aCA+IGluZGV4OyBpbmRleCsrKSBpZiAoTk9fSE9MRVMgfHwgaW5kZXggaW4gc2VsZikge1xuICAgICAgdmFsID0gc2VsZltpbmRleF07XG4gICAgICByZXMgPSBmKHZhbCwgaW5kZXgsIE8pO1xuICAgICAgaWYgKFRZUEUpIHtcbiAgICAgICAgaWYgKElTX01BUCkgcmVzdWx0W2luZGV4XSA9IHJlczsgICAvLyBtYXBcbiAgICAgICAgZWxzZSBpZiAocmVzKSBzd2l0Y2ggKFRZUEUpIHtcbiAgICAgICAgICBjYXNlIDM6IHJldHVybiB0cnVlOyAgICAgICAgICAgICAvLyBzb21lXG4gICAgICAgICAgY2FzZSA1OiByZXR1cm4gdmFsOyAgICAgICAgICAgICAgLy8gZmluZFxuICAgICAgICAgIGNhc2UgNjogcmV0dXJuIGluZGV4OyAgICAgICAgICAgIC8vIGZpbmRJbmRleFxuICAgICAgICAgIGNhc2UgMjogcmVzdWx0LnB1c2godmFsKTsgICAgICAgIC8vIGZpbHRlclxuICAgICAgICB9IGVsc2UgaWYgKElTX0VWRVJZKSByZXR1cm4gZmFsc2U7IC8vIGV2ZXJ5XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBJU19GSU5EX0lOREVYID8gLTEgOiBJU19TT01FIHx8IElTX0VWRVJZID8gSVNfRVZFUlkgOiByZXN1bHQ7XG4gIH07XG59O1xuIiwidmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgY2FsbGJhY2tmbiwgYUxlbiwgbWVtbywgaXNSaWdodCkge1xuICBhRnVuY3Rpb24oY2FsbGJhY2tmbik7XG4gIHZhciBPID0gdG9PYmplY3QodGhhdCk7XG4gIHZhciBzZWxmID0gSU9iamVjdChPKTtcbiAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgdmFyIGluZGV4ID0gaXNSaWdodCA/IGxlbmd0aCAtIDEgOiAwO1xuICB2YXIgaSA9IGlzUmlnaHQgPyAtMSA6IDE7XG4gIGlmIChhTGVuIDwgMikgZm9yICg7Oykge1xuICAgIGlmIChpbmRleCBpbiBzZWxmKSB7XG4gICAgICBtZW1vID0gc2VsZltpbmRleF07XG4gICAgICBpbmRleCArPSBpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGluZGV4ICs9IGk7XG4gICAgaWYgKGlzUmlnaHQgPyBpbmRleCA8IDAgOiBsZW5ndGggPD0gaW5kZXgpIHtcbiAgICAgIHRocm93IFR5cGVFcnJvcignUmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgIH1cbiAgfVxuICBmb3IgKDtpc1JpZ2h0ID8gaW5kZXggPj0gMCA6IGxlbmd0aCA+IGluZGV4OyBpbmRleCArPSBpKSBpZiAoaW5kZXggaW4gc2VsZikge1xuICAgIG1lbW8gPSBjYWxsYmFja2ZuKG1lbW8sIHNlbGZbaW5kZXhdLCBpbmRleCwgTyk7XG4gIH1cbiAgcmV0dXJuIG1lbW87XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9yaWdpbmFsKSB7XG4gIHZhciBDO1xuICBpZiAoaXNBcnJheShvcmlnaW5hbCkpIHtcbiAgICBDID0gb3JpZ2luYWwuY29uc3RydWN0b3I7XG4gICAgLy8gY3Jvc3MtcmVhbG0gZmFsbGJhY2tcbiAgICBpZiAodHlwZW9mIEMgPT0gJ2Z1bmN0aW9uJyAmJiAoQyA9PT0gQXJyYXkgfHwgaXNBcnJheShDLnByb3RvdHlwZSkpKSBDID0gdW5kZWZpbmVkO1xuICAgIGlmIChpc09iamVjdChDKSkge1xuICAgICAgQyA9IENbU1BFQ0lFU107XG4gICAgICBpZiAoQyA9PT0gbnVsbCkgQyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gcmV0dXJuIEMgPT09IHVuZGVmaW5lZCA/IEFycmF5IDogQztcbn07XG4iLCIvLyA5LjQuMi4zIEFycmF5U3BlY2llc0NyZWF0ZShvcmlnaW5hbEFycmF5LCBsZW5ndGgpXG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcmlnaW5hbCwgbGVuZ3RoKSB7XG4gIHJldHVybiBuZXcgKHNwZWNpZXNDb25zdHJ1Y3RvcihvcmlnaW5hbCkpKGxlbmd0aCk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGFycmF5U2xpY2UgPSBbXS5zbGljZTtcbnZhciBmYWN0b3JpZXMgPSB7fTtcblxudmFyIGNvbnN0cnVjdCA9IGZ1bmN0aW9uIChGLCBsZW4sIGFyZ3MpIHtcbiAgaWYgKCEobGVuIGluIGZhY3RvcmllcykpIHtcbiAgICBmb3IgKHZhciBuID0gW10sIGkgPSAwOyBpIDwgbGVuOyBpKyspIG5baV0gPSAnYVsnICsgaSArICddJztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICBmYWN0b3JpZXNbbGVuXSA9IEZ1bmN0aW9uKCdGLGEnLCAncmV0dXJuIG5ldyBGKCcgKyBuLmpvaW4oJywnKSArICcpJyk7XG4gIH0gcmV0dXJuIGZhY3Rvcmllc1tsZW5dKEYsIGFyZ3MpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdW5jdGlvbi5iaW5kIHx8IGZ1bmN0aW9uIGJpbmQodGhhdCAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgdmFyIGZuID0gYUZ1bmN0aW9uKHRoaXMpO1xuICB2YXIgcGFydEFyZ3MgPSBhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgdmFyIGJvdW5kID0gZnVuY3Rpb24gKC8qIGFyZ3MuLi4gKi8pIHtcbiAgICB2YXIgYXJncyA9IHBhcnRBcmdzLmNvbmNhdChhcnJheVNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBib3VuZCA/IGNvbnN0cnVjdChmbiwgYXJncy5sZW5ndGgsIGFyZ3MpIDogaW52b2tlKGZuLCBhcmdzLCB0aGF0KTtcbiAgfTtcbiAgaWYgKGlzT2JqZWN0KGZuLnByb3RvdHlwZSkpIGJvdW5kLnByb3RvdHlwZSA9IGZuLnByb3RvdHlwZTtcbiAgcmV0dXJuIGJvdW5kO1xufTtcbiIsIi8vIGdldHRpbmcgdGFnIGZyb20gMTkuMS4zLjYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZygpXG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgVEFHID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvU3RyaW5nVGFnJyk7XG4vLyBFUzMgd3JvbmcgaGVyZVxudmFyIEFSRyA9IGNvZihmdW5jdGlvbiAoKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSkgPT0gJ0FyZ3VtZW50cyc7XG5cbi8vIGZhbGxiYWNrIGZvciBJRTExIFNjcmlwdCBBY2Nlc3MgRGVuaWVkIGVycm9yXG52YXIgdHJ5R2V0ID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gaXRba2V5XTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgTywgVCwgQjtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyAnVW5kZWZpbmVkJyA6IGl0ID09PSBudWxsID8gJ051bGwnXG4gICAgLy8gQEB0b1N0cmluZ1RhZyBjYXNlXG4gICAgOiB0eXBlb2YgKFQgPSB0cnlHZXQoTyA9IE9iamVjdChpdCksIFRBRykpID09ICdzdHJpbmcnID8gVFxuICAgIC8vIGJ1aWx0aW5UYWcgY2FzZVxuICAgIDogQVJHID8gY29mKE8pXG4gICAgLy8gRVMzIGFyZ3VtZW50cyBmYWxsYmFja1xuICAgIDogKEIgPSBjb2YoTykpID09ICdPYmplY3QnICYmIHR5cGVvZiBPLmNhbGxlZSA9PSAnZnVuY3Rpb24nID8gJ0FyZ3VtZW50cycgOiBCO1xufTtcbiIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbChpdCkuc2xpY2UoOCwgLTEpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciAkaXRlckRlZmluZSA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJyk7XG52YXIgc3RlcCA9IHJlcXVpcmUoJy4vX2l0ZXItc3RlcCcpO1xudmFyIHNldFNwZWNpZXMgPSByZXF1aXJlKCcuL19zZXQtc3BlY2llcycpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBmYXN0S2V5ID0gcmVxdWlyZSgnLi9fbWV0YScpLmZhc3RLZXk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgU0laRSA9IERFU0NSSVBUT1JTID8gJ19zJyA6ICdzaXplJztcblxudmFyIGdldEVudHJ5ID0gZnVuY3Rpb24gKHRoYXQsIGtleSkge1xuICAvLyBmYXN0IGNhc2VcbiAgdmFyIGluZGV4ID0gZmFzdEtleShrZXkpO1xuICB2YXIgZW50cnk7XG4gIGlmIChpbmRleCAhPT0gJ0YnKSByZXR1cm4gdGhhdC5faVtpbmRleF07XG4gIC8vIGZyb3plbiBvYmplY3QgY2FzZVxuICBmb3IgKGVudHJ5ID0gdGhhdC5fZjsgZW50cnk7IGVudHJ5ID0gZW50cnkubikge1xuICAgIGlmIChlbnRyeS5rID09IGtleSkgcmV0dXJuIGVudHJ5O1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q29uc3RydWN0b3I6IGZ1bmN0aW9uICh3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKSB7XG4gICAgdmFyIEMgPSB3cmFwcGVyKGZ1bmN0aW9uICh0aGF0LCBpdGVyYWJsZSkge1xuICAgICAgYW5JbnN0YW5jZSh0aGF0LCBDLCBOQU1FLCAnX2knKTtcbiAgICAgIHRoYXQuX3QgPSBOQU1FOyAgICAgICAgIC8vIGNvbGxlY3Rpb24gdHlwZVxuICAgICAgdGhhdC5faSA9IGNyZWF0ZShudWxsKTsgLy8gaW5kZXhcbiAgICAgIHRoYXQuX2YgPSB1bmRlZmluZWQ7ICAgIC8vIGZpcnN0IGVudHJ5XG4gICAgICB0aGF0Ll9sID0gdW5kZWZpbmVkOyAgICAvLyBsYXN0IGVudHJ5XG4gICAgICB0aGF0W1NJWkVdID0gMDsgICAgICAgICAvLyBzaXplXG4gICAgICBpZiAoaXRlcmFibGUgIT0gdW5kZWZpbmVkKSBmb3JPZihpdGVyYWJsZSwgSVNfTUFQLCB0aGF0W0FEREVSXSwgdGhhdCk7XG4gICAgfSk7XG4gICAgcmVkZWZpbmVBbGwoQy5wcm90b3R5cGUsIHtcbiAgICAgIC8vIDIzLjEuMy4xIE1hcC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgLy8gMjMuMi4zLjIgU2V0LnByb3RvdHlwZS5jbGVhcigpXG4gICAgICBjbGVhcjogZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgICAgIGZvciAodmFyIHRoYXQgPSB2YWxpZGF0ZSh0aGlzLCBOQU1FKSwgZGF0YSA9IHRoYXQuX2ksIGVudHJ5ID0gdGhhdC5fZjsgZW50cnk7IGVudHJ5ID0gZW50cnkubikge1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmIChlbnRyeS5wKSBlbnRyeS5wID0gZW50cnkucC5uID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGRlbGV0ZSBkYXRhW2VudHJ5LmldO1xuICAgICAgICB9XG4gICAgICAgIHRoYXQuX2YgPSB0aGF0Ll9sID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGF0W1NJWkVdID0gMDtcbiAgICAgIH0sXG4gICAgICAvLyAyMy4xLjMuMyBNYXAucHJvdG90eXBlLmRlbGV0ZShrZXkpXG4gICAgICAvLyAyMy4yLjMuNCBTZXQucHJvdG90eXBlLmRlbGV0ZSh2YWx1ZSlcbiAgICAgICdkZWxldGUnOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciB0aGF0ID0gdmFsaWRhdGUodGhpcywgTkFNRSk7XG4gICAgICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSk7XG4gICAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICAgIHZhciBuZXh0ID0gZW50cnkubjtcbiAgICAgICAgICB2YXIgcHJldiA9IGVudHJ5LnA7XG4gICAgICAgICAgZGVsZXRlIHRoYXQuX2lbZW50cnkuaV07XG4gICAgICAgICAgZW50cnkuciA9IHRydWU7XG4gICAgICAgICAgaWYgKHByZXYpIHByZXYubiA9IG5leHQ7XG4gICAgICAgICAgaWYgKG5leHQpIG5leHQucCA9IHByZXY7XG4gICAgICAgICAgaWYgKHRoYXQuX2YgPT0gZW50cnkpIHRoYXQuX2YgPSBuZXh0O1xuICAgICAgICAgIGlmICh0aGF0Ll9sID09IGVudHJ5KSB0aGF0Ll9sID0gcHJldjtcbiAgICAgICAgICB0aGF0W1NJWkVdLS07XG4gICAgICAgIH0gcmV0dXJuICEhZW50cnk7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMi4zLjYgU2V0LnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4sIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gICAgICAvLyAyMy4xLjMuNSBNYXAucHJvdG90eXBlLmZvckVhY2goY2FsbGJhY2tmbiwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbiAgICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbiAvKiAsIHRoYXQgPSB1bmRlZmluZWQgKi8pIHtcbiAgICAgICAgdmFsaWRhdGUodGhpcywgTkFNRSk7XG4gICAgICAgIHZhciBmID0gY3R4KGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCAzKTtcbiAgICAgICAgdmFyIGVudHJ5O1xuICAgICAgICB3aGlsZSAoZW50cnkgPSBlbnRyeSA/IGVudHJ5Lm4gOiB0aGlzLl9mKSB7XG4gICAgICAgICAgZihlbnRyeS52LCBlbnRyeS5rLCB0aGlzKTtcbiAgICAgICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcbiAgICAgICAgICB3aGlsZSAoZW50cnkgJiYgZW50cnkucikgZW50cnkgPSBlbnRyeS5wO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjcgTWFwLnByb3RvdHlwZS5oYXMoa2V5KVxuICAgICAgLy8gMjMuMi4zLjcgU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXG4gICAgICBoYXM6IGZ1bmN0aW9uIGhhcyhrZXkpIHtcbiAgICAgICAgcmV0dXJuICEhZ2V0RW50cnkodmFsaWRhdGUodGhpcywgTkFNRSksIGtleSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKERFU0NSSVBUT1JTKSBkUChDLnByb3RvdHlwZSwgJ3NpemUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRlKHRoaXMsIE5BTUUpW1NJWkVdO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBDO1xuICB9LFxuICBkZWY6IGZ1bmN0aW9uICh0aGF0LCBrZXksIHZhbHVlKSB7XG4gICAgdmFyIGVudHJ5ID0gZ2V0RW50cnkodGhhdCwga2V5KTtcbiAgICB2YXIgcHJldiwgaW5kZXg7XG4gICAgLy8gY2hhbmdlIGV4aXN0aW5nIGVudHJ5XG4gICAgaWYgKGVudHJ5KSB7XG4gICAgICBlbnRyeS52ID0gdmFsdWU7XG4gICAgLy8gY3JlYXRlIG5ldyBlbnRyeVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGF0Ll9sID0gZW50cnkgPSB7XG4gICAgICAgIGk6IGluZGV4ID0gZmFzdEtleShrZXksIHRydWUpLCAvLyA8LSBpbmRleFxuICAgICAgICBrOiBrZXksICAgICAgICAgICAgICAgICAgICAgICAgLy8gPC0ga2V5XG4gICAgICAgIHY6IHZhbHVlLCAgICAgICAgICAgICAgICAgICAgICAvLyA8LSB2YWx1ZVxuICAgICAgICBwOiBwcmV2ID0gdGhhdC5fbCwgICAgICAgICAgICAgLy8gPC0gcHJldmlvdXMgZW50cnlcbiAgICAgICAgbjogdW5kZWZpbmVkLCAgICAgICAgICAgICAgICAgIC8vIDwtIG5leHQgZW50cnlcbiAgICAgICAgcjogZmFsc2UgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIHJlbW92ZWRcbiAgICAgIH07XG4gICAgICBpZiAoIXRoYXQuX2YpIHRoYXQuX2YgPSBlbnRyeTtcbiAgICAgIGlmIChwcmV2KSBwcmV2Lm4gPSBlbnRyeTtcbiAgICAgIHRoYXRbU0laRV0rKztcbiAgICAgIC8vIGFkZCB0byBpbmRleFxuICAgICAgaWYgKGluZGV4ICE9PSAnRicpIHRoYXQuX2lbaW5kZXhdID0gZW50cnk7XG4gICAgfSByZXR1cm4gdGhhdDtcbiAgfSxcbiAgZ2V0RW50cnk6IGdldEVudHJ5LFxuICBzZXRTdHJvbmc6IGZ1bmN0aW9uIChDLCBOQU1FLCBJU19NQVApIHtcbiAgICAvLyBhZGQgLmtleXMsIC52YWx1ZXMsIC5lbnRyaWVzLCBbQEBpdGVyYXRvcl1cbiAgICAvLyAyMy4xLjMuNCwgMjMuMS4zLjgsIDIzLjEuMy4xMSwgMjMuMS4zLjEyLCAyMy4yLjMuNSwgMjMuMi4zLjgsIDIzLjIuMy4xMCwgMjMuMi4zLjExXG4gICAgJGl0ZXJEZWZpbmUoQywgTkFNRSwgZnVuY3Rpb24gKGl0ZXJhdGVkLCBraW5kKSB7XG4gICAgICB0aGlzLl90ID0gdmFsaWRhdGUoaXRlcmF0ZWQsIE5BTUUpOyAvLyB0YXJnZXRcbiAgICAgIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAgICAgIC8vIGtpbmRcbiAgICAgIHRoaXMuX2wgPSB1bmRlZmluZWQ7ICAgICAgICAgICAgICAgIC8vIHByZXZpb3VzXG4gICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgdmFyIGtpbmQgPSB0aGF0Ll9rO1xuICAgICAgdmFyIGVudHJ5ID0gdGhhdC5fbDtcbiAgICAgIC8vIHJldmVydCB0byB0aGUgbGFzdCBleGlzdGluZyBlbnRyeVxuICAgICAgd2hpbGUgKGVudHJ5ICYmIGVudHJ5LnIpIGVudHJ5ID0gZW50cnkucDtcbiAgICAgIC8vIGdldCBuZXh0IGVudHJ5XG4gICAgICBpZiAoIXRoYXQuX3QgfHwgISh0aGF0Ll9sID0gZW50cnkgPSBlbnRyeSA/IGVudHJ5Lm4gOiB0aGF0Ll90Ll9mKSkge1xuICAgICAgICAvLyBvciBmaW5pc2ggdGhlIGl0ZXJhdGlvblxuICAgICAgICB0aGF0Ll90ID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gc3RlcCgxKTtcbiAgICAgIH1cbiAgICAgIC8vIHJldHVybiBzdGVwIGJ5IGtpbmRcbiAgICAgIGlmIChraW5kID09ICdrZXlzJykgcmV0dXJuIHN0ZXAoMCwgZW50cnkuayk7XG4gICAgICBpZiAoa2luZCA9PSAndmFsdWVzJykgcmV0dXJuIHN0ZXAoMCwgZW50cnkudik7XG4gICAgICByZXR1cm4gc3RlcCgwLCBbZW50cnkuaywgZW50cnkudl0pO1xuICAgIH0sIElTX01BUCA/ICdlbnRyaWVzJyA6ICd2YWx1ZXMnLCAhSVNfTUFQLCB0cnVlKTtcblxuICAgIC8vIGFkZCBbQEBzcGVjaWVzXSwgMjMuMS4yLjIsIDIzLjIuMi4yXG4gICAgc2V0U3BlY2llcyhOQU1FKTtcbiAgfVxufTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9EYXZpZEJydWFudC9NYXAtU2V0LnByb3RvdHlwZS50b0pTT05cbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIGZyb20gPSByZXF1aXJlKCcuL19hcnJheS1mcm9tLWl0ZXJhYmxlJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChOQU1FKSB7XG4gIHJldHVybiBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgaWYgKGNsYXNzb2YodGhpcykgIT0gTkFNRSkgdGhyb3cgVHlwZUVycm9yKE5BTUUgKyBcIiN0b0pTT04gaXNuJ3QgZ2VuZXJpY1wiKTtcbiAgICByZXR1cm4gZnJvbSh0aGlzKTtcbiAgfTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbnZhciBnZXRXZWFrID0gcmVxdWlyZSgnLi9fbWV0YScpLmdldFdlYWs7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgY3JlYXRlQXJyYXlNZXRob2QgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJyk7XG52YXIgJGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIGFycmF5RmluZCA9IGNyZWF0ZUFycmF5TWV0aG9kKDUpO1xudmFyIGFycmF5RmluZEluZGV4ID0gY3JlYXRlQXJyYXlNZXRob2QoNik7XG52YXIgaWQgPSAwO1xuXG4vLyBmYWxsYmFjayBmb3IgdW5jYXVnaHQgZnJvemVuIGtleXNcbnZhciB1bmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24gKHRoYXQpIHtcbiAgcmV0dXJuIHRoYXQuX2wgfHwgKHRoYXQuX2wgPSBuZXcgVW5jYXVnaHRGcm96ZW5TdG9yZSgpKTtcbn07XG52YXIgVW5jYXVnaHRGcm96ZW5TdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5hID0gW107XG59O1xudmFyIGZpbmRVbmNhdWdodEZyb3plbiA9IGZ1bmN0aW9uIChzdG9yZSwga2V5KSB7XG4gIHJldHVybiBhcnJheUZpbmQoc3RvcmUuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgcmV0dXJuIGl0WzBdID09PSBrZXk7XG4gIH0pO1xufTtcblVuY2F1Z2h0RnJvemVuU3RvcmUucHJvdG90eXBlID0ge1xuICBnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIHJldHVybiBlbnRyeVsxXTtcbiAgfSxcbiAgaGFzOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuICEhZmluZFVuY2F1Z2h0RnJvemVuKHRoaXMsIGtleSk7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIGVudHJ5WzFdID0gdmFsdWU7XG4gICAgZWxzZSB0aGlzLmEucHVzaChba2V5LCB2YWx1ZV0pO1xuICB9LFxuICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBpbmRleCA9IGFycmF5RmluZEluZGV4KHRoaXMuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgICB9KTtcbiAgICBpZiAofmluZGV4KSB0aGlzLmEuc3BsaWNlKGluZGV4LCAxKTtcbiAgICByZXR1cm4gISF+aW5kZXg7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDb25zdHJ1Y3RvcjogZnVuY3Rpb24gKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpIHtcbiAgICB2YXIgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGl0ZXJhYmxlKSB7XG4gICAgICBhbkluc3RhbmNlKHRoYXQsIEMsIE5BTUUsICdfaScpO1xuICAgICAgdGhhdC5fdCA9IE5BTUU7ICAgICAgLy8gY29sbGVjdGlvbiB0eXBlXG4gICAgICB0aGF0Ll9pID0gaWQrKzsgICAgICAvLyBjb2xsZWN0aW9uIGlkXG4gICAgICB0aGF0Ll9sID0gdW5kZWZpbmVkOyAvLyBsZWFrIHN0b3JlIGZvciB1bmNhdWdodCBmcm96ZW4gb2JqZWN0c1xuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4zLjMuMiBXZWFrTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuNC4zLjMgV2Vha1NldC5wcm90b3R5cGUuZGVsZXRlKHZhbHVlKVxuICAgICAgJ2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpWydkZWxldGUnXShrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpICYmIGRlbGV0ZSBkYXRhW3RoaXMuX2ldO1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjMuMy40IFdlYWtNYXAucHJvdG90eXBlLmhhcyhrZXkpXG4gICAgICAvLyAyMy40LjMuNCBXZWFrU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXG4gICAgICBoYXM6IGZ1bmN0aW9uIGhhcyhrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpLmhhcyhrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBDO1xuICB9LFxuICBkZWY6IGZ1bmN0aW9uICh0aGF0LCBrZXksIHZhbHVlKSB7XG4gICAgdmFyIGRhdGEgPSBnZXRXZWFrKGFuT2JqZWN0KGtleSksIHRydWUpO1xuICAgIGlmIChkYXRhID09PSB0cnVlKSB1bmNhdWdodEZyb3plblN0b3JlKHRoYXQpLnNldChrZXksIHZhbHVlKTtcbiAgICBlbHNlIGRhdGFbdGhhdC5faV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhhdDtcbiAgfSxcbiAgdWZzdG9yZTogdW5jYXVnaHRGcm96ZW5TdG9yZVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgbWV0YSA9IHJlcXVpcmUoJy4vX21ldGEnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyICRpdGVyRGV0ZWN0ID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE5BTUUsIHdyYXBwZXIsIG1ldGhvZHMsIGNvbW1vbiwgSVNfTUFQLCBJU19XRUFLKSB7XG4gIHZhciBCYXNlID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgQyA9IEJhc2U7XG4gIHZhciBBRERFUiA9IElTX01BUCA/ICdzZXQnIDogJ2FkZCc7XG4gIHZhciBwcm90byA9IEMgJiYgQy5wcm90b3R5cGU7XG4gIHZhciBPID0ge307XG4gIHZhciBmaXhNZXRob2QgPSBmdW5jdGlvbiAoS0VZKSB7XG4gICAgdmFyIGZuID0gcHJvdG9bS0VZXTtcbiAgICByZWRlZmluZShwcm90bywgS0VZLFxuICAgICAgS0VZID09ICdkZWxldGUnID8gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdoYXMnID8gZnVuY3Rpb24gaGFzKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdnZXQnID8gZnVuY3Rpb24gZ2V0KGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gdW5kZWZpbmVkIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnYWRkJyA/IGZ1bmN0aW9uIGFkZChhKSB7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTsgcmV0dXJuIHRoaXM7IH1cbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYikgeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSwgYik7IHJldHVybiB0aGlzOyB9XG4gICAgKTtcbiAgfTtcbiAgaWYgKHR5cGVvZiBDICE9ICdmdW5jdGlvbicgfHwgIShJU19XRUFLIHx8IHByb3RvLmZvckVhY2ggJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgQygpLmVudHJpZXMoKS5uZXh0KCk7XG4gIH0pKSkge1xuICAgIC8vIGNyZWF0ZSBjb2xsZWN0aW9uIGNvbnN0cnVjdG9yXG4gICAgQyA9IGNvbW1vbi5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gICAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcbiAgICB2YXIgSEFTTlRfQ0hBSU5JTkcgPSBpbnN0YW5jZVtBRERFUl0oSVNfV0VBSyA/IHt9IDogLTAsIDEpICE9IGluc3RhbmNlO1xuICAgIC8vIFY4IH4gIENocm9taXVtIDQwLSB3ZWFrLWNvbGxlY3Rpb25zIHRocm93cyBvbiBwcmltaXRpdmVzLCBidXQgc2hvdWxkIHJldHVybiBmYWxzZVxuICAgIHZhciBUSFJPV1NfT05fUFJJTUlUSVZFUyA9IGZhaWxzKGZ1bmN0aW9uICgpIHsgaW5zdGFuY2UuaGFzKDEpOyB9KTtcbiAgICAvLyBtb3N0IGVhcmx5IGltcGxlbWVudGF0aW9ucyBkb2Vzbid0IHN1cHBvcnRzIGl0ZXJhYmxlcywgbW9zdCBtb2Rlcm4gLSBub3QgY2xvc2UgaXQgY29ycmVjdGx5XG4gICAgdmFyIEFDQ0VQVF9JVEVSQUJMRVMgPSAkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikgeyBuZXcgQyhpdGVyKTsgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXG4gICAgdmFyIEJVR0dZX1pFUk8gPSAhSVNfV0VBSyAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBWOCB+IENocm9taXVtIDQyLSBmYWlscyBvbmx5IHdpdGggNSsgZWxlbWVudHNcbiAgICAgIHZhciAkaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgICAgdmFyIGluZGV4ID0gNTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSAkaW5zdGFuY2VbQURERVJdKGluZGV4LCBpbmRleCk7XG4gICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xuICAgIH0pO1xuICAgIGlmICghQUNDRVBUX0lURVJBQkxFUykge1xuICAgICAgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRhcmdldCwgaXRlcmFibGUpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0YXJnZXQsIEMsIE5BTUUpO1xuICAgICAgICB2YXIgdGhhdCA9IGluaGVyaXRJZlJlcXVpcmVkKG5ldyBCYXNlKCksIHRhcmdldCwgQyk7XG4gICAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICAgICAgcmV0dXJuIHRoYXQ7XG4gICAgICB9KTtcbiAgICAgIEMucHJvdG90eXBlID0gcHJvdG87XG4gICAgICBwcm90by5jb25zdHJ1Y3RvciA9IEM7XG4gICAgfVxuICAgIGlmIChUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKSB7XG4gICAgICBmaXhNZXRob2QoJ2RlbGV0ZScpO1xuICAgICAgZml4TWV0aG9kKCdoYXMnKTtcbiAgICAgIElTX01BUCAmJiBmaXhNZXRob2QoJ2dldCcpO1xuICAgIH1cbiAgICBpZiAoQlVHR1lfWkVSTyB8fCBIQVNOVF9DSEFJTklORykgZml4TWV0aG9kKEFEREVSKTtcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxuICAgIGlmIChJU19XRUFLICYmIHByb3RvLmNsZWFyKSBkZWxldGUgcHJvdG8uY2xlYXI7XG4gIH1cblxuICBzZXRUb1N0cmluZ1RhZyhDLCBOQU1FKTtcblxuICBPW05BTUVdID0gQztcbiAgJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAoQyAhPSBCYXNlKSwgTyk7XG5cbiAgaWYgKCFJU19XRUFLKSBjb21tb24uc2V0U3Ryb25nKEMsIE5BTUUsIElTX01BUCk7XG5cbiAgcmV0dXJuIEM7XG59O1xuIiwidmFyIGNvcmUgPSBtb2R1bGUuZXhwb3J0cyA9IHsgdmVyc2lvbjogJzIuNi40JyB9O1xuaWYgKHR5cGVvZiBfX2UgPT0gJ251bWJlcicpIF9fZSA9IGNvcmU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIGluZGV4LCB2YWx1ZSkge1xuICBpZiAoaW5kZXggaW4gb2JqZWN0KSAkZGVmaW5lUHJvcGVydHkuZihvYmplY3QsIGluZGV4LCBjcmVhdGVEZXNjKDAsIHZhbHVlKSk7XG4gIGVsc2Ugb2JqZWN0W2luZGV4XSA9IHZhbHVlO1xufTtcbiIsIi8vIG9wdGlvbmFsIC8gc2ltcGxlIGNvbnRleHQgYmluZGluZ1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCB0aGF0LCBsZW5ndGgpIHtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYgKHRoYXQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZuO1xuICBzd2l0Y2ggKGxlbmd0aCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uIChhKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhKTtcbiAgICB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uIChhLCBiLCBjKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiLCBjKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbiAoLyogLi4uYXJncyAqLykge1xuICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIwLjMuNC4zNiAvIDE1LjkuNS40MyBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZygpXG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGdldFRpbWUgPSBEYXRlLnByb3RvdHlwZS5nZXRUaW1lO1xudmFyICR0b0lTT1N0cmluZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nO1xuXG52YXIgbHogPSBmdW5jdGlvbiAobnVtKSB7XG4gIHJldHVybiBudW0gPiA5ID8gbnVtIDogJzAnICsgbnVtO1xufTtcblxuLy8gUGhhbnRvbUpTIC8gb2xkIFdlYktpdCBoYXMgYSBicm9rZW4gaW1wbGVtZW50YXRpb25zXG5tb2R1bGUuZXhwb3J0cyA9IChmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAkdG9JU09TdHJpbmcuY2FsbChuZXcgRGF0ZSgtNWUxMyAtIDEpKSAhPSAnMDM4NS0wNy0yNVQwNzowNjozOS45OTlaJztcbn0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICR0b0lTT1N0cmluZy5jYWxsKG5ldyBEYXRlKE5hTikpO1xufSkpID8gZnVuY3Rpb24gdG9JU09TdHJpbmcoKSB7XG4gIGlmICghaXNGaW5pdGUoZ2V0VGltZS5jYWxsKHRoaXMpKSkgdGhyb3cgUmFuZ2VFcnJvcignSW52YWxpZCB0aW1lIHZhbHVlJyk7XG4gIHZhciBkID0gdGhpcztcbiAgdmFyIHkgPSBkLmdldFVUQ0Z1bGxZZWFyKCk7XG4gIHZhciBtID0gZC5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgdmFyIHMgPSB5IDwgMCA/ICctJyA6IHkgPiA5OTk5ID8gJysnIDogJyc7XG4gIHJldHVybiBzICsgKCcwMDAwMCcgKyBNYXRoLmFicyh5KSkuc2xpY2UocyA/IC02IDogLTQpICtcbiAgICAnLScgKyBseihkLmdldFVUQ01vbnRoKCkgKyAxKSArICctJyArIGx6KGQuZ2V0VVRDRGF0ZSgpKSArXG4gICAgJ1QnICsgbHooZC5nZXRVVENIb3VycygpKSArICc6JyArIGx6KGQuZ2V0VVRDTWludXRlcygpKSArXG4gICAgJzonICsgbHooZC5nZXRVVENTZWNvbmRzKCkpICsgJy4nICsgKG0gPiA5OSA/IG0gOiAnMCcgKyBseihtKSkgKyAnWic7XG59IDogJHRvSVNPU3RyaW5nO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBOVU1CRVIgPSAnbnVtYmVyJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaGludCkge1xuICBpZiAoaGludCAhPT0gJ3N0cmluZycgJiYgaGludCAhPT0gTlVNQkVSICYmIGhpbnQgIT09ICdkZWZhdWx0JykgdGhyb3cgVHlwZUVycm9yKCdJbmNvcnJlY3QgaGludCcpO1xuICByZXR1cm4gdG9QcmltaXRpdmUoYW5PYmplY3QodGhpcyksIGhpbnQgIT0gTlVNQkVSKTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xuLy8gdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgaXMgJ29iamVjdCcgaW4gb2xkIElFXG52YXIgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXMgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwiLy8gYWxsIGVudW1lcmFibGUgb2JqZWN0IGtleXMsIGluY2x1ZGVzIHN5bWJvbHNcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgcmVzdWx0ID0gZ2V0S2V5cyhpdCk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICBpZiAoZ2V0U3ltYm9scykge1xuICAgIHZhciBzeW1ib2xzID0gZ2V0U3ltYm9scyhpdCk7XG4gICAgdmFyIGlzRW51bSA9IHBJRS5mO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChzeW1ib2xzLmxlbmd0aCA+IGkpIGlmIChpc0VudW0uY2FsbChpdCwga2V5ID0gc3ltYm9sc1tpKytdKSkgcmVzdWx0LnB1c2goa2V5KTtcbiAgfSByZXR1cm4gcmVzdWx0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCBzb3VyY2UpIHtcbiAgdmFyIElTX0ZPUkNFRCA9IHR5cGUgJiAkZXhwb3J0LkY7XG4gIHZhciBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HO1xuICB2YXIgSVNfU1RBVElDID0gdHlwZSAmICRleHBvcnQuUztcbiAgdmFyIElTX1BST1RPID0gdHlwZSAmICRleHBvcnQuUDtcbiAgdmFyIElTX0JJTkQgPSB0eXBlICYgJGV4cG9ydC5CO1xuICB2YXIgdGFyZ2V0ID0gSVNfR0xPQkFMID8gZ2xvYmFsIDogSVNfU1RBVElDID8gZ2xvYmFsW25hbWVdIHx8IChnbG9iYWxbbmFtZV0gPSB7fSkgOiAoZ2xvYmFsW25hbWVdIHx8IHt9KVtQUk9UT1RZUEVdO1xuICB2YXIgZXhwb3J0cyA9IElTX0dMT0JBTCA/IGNvcmUgOiBjb3JlW25hbWVdIHx8IChjb3JlW25hbWVdID0ge30pO1xuICB2YXIgZXhwUHJvdG8gPSBleHBvcnRzW1BST1RPVFlQRV0gfHwgKGV4cG9ydHNbUFJPVE9UWVBFXSA9IHt9KTtcbiAgdmFyIGtleSwgb3duLCBvdXQsIGV4cDtcbiAgaWYgKElTX0dMT0JBTCkgc291cmNlID0gbmFtZTtcbiAgZm9yIChrZXkgaW4gc291cmNlKSB7XG4gICAgLy8gY29udGFpbnMgaW4gbmF0aXZlXG4gICAgb3duID0gIUlTX0ZPUkNFRCAmJiB0YXJnZXQgJiYgdGFyZ2V0W2tleV0gIT09IHVuZGVmaW5lZDtcbiAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuICAgIG91dCA9IChvd24gPyB0YXJnZXQgOiBzb3VyY2UpW2tleV07XG4gICAgLy8gYmluZCB0aW1lcnMgdG8gZ2xvYmFsIGZvciBjYWxsIGZyb20gZXhwb3J0IGNvbnRleHRcbiAgICBleHAgPSBJU19CSU5EICYmIG93biA/IGN0eChvdXQsIGdsb2JhbCkgOiBJU19QUk9UTyAmJiB0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicgPyBjdHgoRnVuY3Rpb24uY2FsbCwgb3V0KSA6IG91dDtcbiAgICAvLyBleHRlbmQgZ2xvYmFsXG4gICAgaWYgKHRhcmdldCkgcmVkZWZpbmUodGFyZ2V0LCBrZXksIG91dCwgdHlwZSAmICRleHBvcnQuVSk7XG4gICAgLy8gZXhwb3J0XG4gICAgaWYgKGV4cG9ydHNba2V5XSAhPSBvdXQpIGhpZGUoZXhwb3J0cywga2V5LCBleHApO1xuICAgIGlmIChJU19QUk9UTyAmJiBleHBQcm90b1trZXldICE9IG91dCkgZXhwUHJvdG9ba2V5XSA9IG91dDtcbiAgfVxufTtcbmdsb2JhbC5jb3JlID0gY29yZTtcbi8vIHR5cGUgYml0bWFwXG4kZXhwb3J0LkYgPSAxOyAgIC8vIGZvcmNlZFxuJGV4cG9ydC5HID0gMjsgICAvLyBnbG9iYWxcbiRleHBvcnQuUyA9IDQ7ICAgLy8gc3RhdGljXG4kZXhwb3J0LlAgPSA4OyAgIC8vIHByb3RvXG4kZXhwb3J0LkIgPSAxNjsgIC8vIGJpbmRcbiRleHBvcnQuVyA9IDMyOyAgLy8gd3JhcFxuJGV4cG9ydC5VID0gNjQ7ICAvLyBzYWZlXG4kZXhwb3J0LlIgPSAxMjg7IC8vIHJlYWwgcHJvdG8gbWV0aG9kIGZvciBgbGlicmFyeWBcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDtcbiIsInZhciBNQVRDSCA9IHJlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciByZSA9IC8uLztcbiAgdHJ5IHtcbiAgICAnLy4vJ1tLRVldKHJlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRyeSB7XG4gICAgICByZVtNQVRDSF0gPSBmYWxzZTtcbiAgICAgIHJldHVybiAhJy8uLydbS0VZXShyZSk7XG4gICAgfSBjYXRjaCAoZikgeyAvKiBlbXB0eSAqLyB9XG4gIH0gcmV0dXJuIHRydWU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYykge1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xucmVxdWlyZSgnLi9lczYucmVnZXhwLmV4ZWMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciByZWdleHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMnKTtcblxudmFyIFNQRUNJRVMgPSB3a3MoJ3NwZWNpZXMnKTtcblxudmFyIFJFUExBQ0VfU1VQUE9SVFNfTkFNRURfR1JPVVBTID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gI3JlcGxhY2UgbmVlZHMgYnVpbHQtaW4gc3VwcG9ydCBmb3IgbmFtZWQgZ3JvdXBzLlxuICAvLyAjbWF0Y2ggd29ya3MgZmluZSBiZWNhdXNlIGl0IGp1c3QgcmV0dXJuIHRoZSBleGVjIHJlc3VsdHMsIGV2ZW4gaWYgaXQgaGFzXG4gIC8vIGEgXCJncm9wc1wiIHByb3BlcnR5LlxuICB2YXIgcmUgPSAvLi87XG4gIHJlLmV4ZWMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgIHJlc3VsdC5ncm91cHMgPSB7IGE6ICc3JyB9O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIHJldHVybiAnJy5yZXBsYWNlKHJlLCAnJDxhPicpICE9PSAnNyc7XG59KTtcblxudmFyIFNQTElUX1dPUktTX1dJVEhfT1ZFUldSSVRURU5fRVhFQyA9IChmdW5jdGlvbiAoKSB7XG4gIC8vIENocm9tZSA1MSBoYXMgYSBidWdneSBcInNwbGl0XCIgaW1wbGVtZW50YXRpb24gd2hlbiBSZWdFeHAjZXhlYyAhPT0gbmF0aXZlRXhlY1xuICB2YXIgcmUgPSAvKD86KS87XG4gIHZhciBvcmlnaW5hbEV4ZWMgPSByZS5leGVjO1xuICByZS5leGVjID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gb3JpZ2luYWxFeGVjLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07XG4gIHZhciByZXN1bHQgPSAnYWInLnNwbGl0KHJlKTtcbiAgcmV0dXJuIHJlc3VsdC5sZW5ndGggPT09IDIgJiYgcmVzdWx0WzBdID09PSAnYScgJiYgcmVzdWx0WzFdID09PSAnYic7XG59KSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChLRVksIGxlbmd0aCwgZXhlYykge1xuICB2YXIgU1lNQk9MID0gd2tzKEtFWSk7XG5cbiAgdmFyIERFTEVHQVRFU19UT19TWU1CT0wgPSAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIFN0cmluZyBtZXRob2RzIGNhbGwgc3ltYm9sLW5hbWVkIFJlZ0VwIG1ldGhvZHNcbiAgICB2YXIgTyA9IHt9O1xuICAgIE9bU1lNQk9MXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH07XG4gICAgcmV0dXJuICcnW0tFWV0oTykgIT0gNztcbiAgfSk7XG5cbiAgdmFyIERFTEVHQVRFU19UT19FWEVDID0gREVMRUdBVEVTX1RPX1NZTUJPTCA/ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgLy8gU3ltYm9sLW5hbWVkIFJlZ0V4cCBtZXRob2RzIGNhbGwgLmV4ZWNcbiAgICB2YXIgZXhlY0NhbGxlZCA9IGZhbHNlO1xuICAgIHZhciByZSA9IC9hLztcbiAgICByZS5leGVjID0gZnVuY3Rpb24gKCkgeyBleGVjQ2FsbGVkID0gdHJ1ZTsgcmV0dXJuIG51bGw7IH07XG4gICAgaWYgKEtFWSA9PT0gJ3NwbGl0Jykge1xuICAgICAgLy8gUmVnRXhwW0BAc3BsaXRdIGRvZXNuJ3QgY2FsbCB0aGUgcmVnZXgncyBleGVjIG1ldGhvZCwgYnV0IGZpcnN0IGNyZWF0ZXNcbiAgICAgIC8vIGEgbmV3IG9uZS4gV2UgbmVlZCB0byByZXR1cm4gdGhlIHBhdGNoZWQgcmVnZXggd2hlbiBjcmVhdGluZyB0aGUgbmV3IG9uZS5cbiAgICAgIHJlLmNvbnN0cnVjdG9yID0ge307XG4gICAgICByZS5jb25zdHJ1Y3RvcltTUEVDSUVTXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJlOyB9O1xuICAgIH1cbiAgICByZVtTWU1CT0xdKCcnKTtcbiAgICByZXR1cm4gIWV4ZWNDYWxsZWQ7XG4gIH0pIDogdW5kZWZpbmVkO1xuXG4gIGlmIChcbiAgICAhREVMRUdBVEVTX1RPX1NZTUJPTCB8fFxuICAgICFERUxFR0FURVNfVE9fRVhFQyB8fFxuICAgIChLRVkgPT09ICdyZXBsYWNlJyAmJiAhUkVQTEFDRV9TVVBQT1JUU19OQU1FRF9HUk9VUFMpIHx8XG4gICAgKEtFWSA9PT0gJ3NwbGl0JyAmJiAhU1BMSVRfV09SS1NfV0lUSF9PVkVSV1JJVFRFTl9FWEVDKVxuICApIHtcbiAgICB2YXIgbmF0aXZlUmVnRXhwTWV0aG9kID0gLy4vW1NZTUJPTF07XG4gICAgdmFyIGZucyA9IGV4ZWMoXG4gICAgICBkZWZpbmVkLFxuICAgICAgU1lNQk9MLFxuICAgICAgJydbS0VZXSxcbiAgICAgIGZ1bmN0aW9uIG1heWJlQ2FsbE5hdGl2ZShuYXRpdmVNZXRob2QsIHJlZ2V4cCwgc3RyLCBhcmcyLCBmb3JjZVN0cmluZ01ldGhvZCkge1xuICAgICAgICBpZiAocmVnZXhwLmV4ZWMgPT09IHJlZ2V4cEV4ZWMpIHtcbiAgICAgICAgICBpZiAoREVMRUdBVEVTX1RPX1NZTUJPTCAmJiAhZm9yY2VTdHJpbmdNZXRob2QpIHtcbiAgICAgICAgICAgIC8vIFRoZSBuYXRpdmUgU3RyaW5nIG1ldGhvZCBhbHJlYWR5IGRlbGVnYXRlcyB0byBAQG1ldGhvZCAodGhpc1xuICAgICAgICAgICAgLy8gcG9seWZpbGxlZCBmdW5jdGlvbiksIGxlYXNpbmcgdG8gaW5maW5pdGUgcmVjdXJzaW9uLlxuICAgICAgICAgICAgLy8gV2UgYXZvaWQgaXQgYnkgZGlyZWN0bHkgY2FsbGluZyB0aGUgbmF0aXZlIEBAbWV0aG9kIG1ldGhvZC5cbiAgICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiBuYXRpdmVSZWdFeHBNZXRob2QuY2FsbChyZWdleHAsIHN0ciwgYXJnMikgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IG5hdGl2ZU1ldGhvZC5jYWxsKHN0ciwgcmVnZXhwLCBhcmcyKSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IGRvbmU6IGZhbHNlIH07XG4gICAgICB9XG4gICAgKTtcbiAgICB2YXIgc3RyZm4gPSBmbnNbMF07XG4gICAgdmFyIHJ4Zm4gPSBmbnNbMV07XG5cbiAgICByZWRlZmluZShTdHJpbmcucHJvdG90eXBlLCBLRVksIHN0cmZuKTtcbiAgICBoaWRlKFJlZ0V4cC5wcm90b3R5cGUsIFNZTUJPTCwgbGVuZ3RoID09IDJcbiAgICAgIC8vIDIxLjIuNS44IFJlZ0V4cC5wcm90b3R5cGVbQEByZXBsYWNlXShzdHJpbmcsIHJlcGxhY2VWYWx1ZSlcbiAgICAgIC8vIDIxLjIuNS4xMSBSZWdFeHAucHJvdG90eXBlW0BAc3BsaXRdKHN0cmluZywgbGltaXQpXG4gICAgICA/IGZ1bmN0aW9uIChzdHJpbmcsIGFyZykgeyByZXR1cm4gcnhmbi5jYWxsKHN0cmluZywgdGhpcywgYXJnKTsgfVxuICAgICAgLy8gMjEuMi41LjYgUmVnRXhwLnByb3RvdHlwZVtAQG1hdGNoXShzdHJpbmcpXG4gICAgICAvLyAyMS4yLjUuOSBSZWdFeHAucHJvdG90eXBlW0BAc2VhcmNoXShzdHJpbmcpXG4gICAgICA6IGZ1bmN0aW9uIChzdHJpbmcpIHsgcmV0dXJuIHJ4Zm4uY2FsbChzdHJpbmcsIHRoaXMpOyB9XG4gICAgKTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIxLjIuNS4zIGdldCBSZWdFeHAucHJvdG90eXBlLmZsYWdzXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdGhhdCA9IGFuT2JqZWN0KHRoaXMpO1xuICB2YXIgcmVzdWx0ID0gJyc7XG4gIGlmICh0aGF0Lmdsb2JhbCkgcmVzdWx0ICs9ICdnJztcbiAgaWYgKHRoYXQuaWdub3JlQ2FzZSkgcmVzdWx0ICs9ICdpJztcbiAgaWYgKHRoYXQubXVsdGlsaW5lKSByZXN1bHQgKz0gJ20nO1xuICBpZiAodGhhdC51bmljb2RlKSByZXN1bHQgKz0gJ3UnO1xuICBpZiAodGhhdC5zdGlja3kpIHJlc3VsdCArPSAneSc7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1mbGF0TWFwLyNzZWMtRmxhdHRlbkludG9BcnJheVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuL19pcy1hcnJheScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBJU19DT05DQVRfU1BSRUFEQUJMRSA9IHJlcXVpcmUoJy4vX3drcycpKCdpc0NvbmNhdFNwcmVhZGFibGUnKTtcblxuZnVuY3Rpb24gZmxhdHRlbkludG9BcnJheSh0YXJnZXQsIG9yaWdpbmFsLCBzb3VyY2UsIHNvdXJjZUxlbiwgc3RhcnQsIGRlcHRoLCBtYXBwZXIsIHRoaXNBcmcpIHtcbiAgdmFyIHRhcmdldEluZGV4ID0gc3RhcnQ7XG4gIHZhciBzb3VyY2VJbmRleCA9IDA7XG4gIHZhciBtYXBGbiA9IG1hcHBlciA/IGN0eChtYXBwZXIsIHRoaXNBcmcsIDMpIDogZmFsc2U7XG4gIHZhciBlbGVtZW50LCBzcHJlYWRhYmxlO1xuXG4gIHdoaWxlIChzb3VyY2VJbmRleCA8IHNvdXJjZUxlbikge1xuICAgIGlmIChzb3VyY2VJbmRleCBpbiBzb3VyY2UpIHtcbiAgICAgIGVsZW1lbnQgPSBtYXBGbiA/IG1hcEZuKHNvdXJjZVtzb3VyY2VJbmRleF0sIHNvdXJjZUluZGV4LCBvcmlnaW5hbCkgOiBzb3VyY2Vbc291cmNlSW5kZXhdO1xuXG4gICAgICBzcHJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBpZiAoaXNPYmplY3QoZWxlbWVudCkpIHtcbiAgICAgICAgc3ByZWFkYWJsZSA9IGVsZW1lbnRbSVNfQ09OQ0FUX1NQUkVBREFCTEVdO1xuICAgICAgICBzcHJlYWRhYmxlID0gc3ByZWFkYWJsZSAhPT0gdW5kZWZpbmVkID8gISFzcHJlYWRhYmxlIDogaXNBcnJheShlbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNwcmVhZGFibGUgJiYgZGVwdGggPiAwKSB7XG4gICAgICAgIHRhcmdldEluZGV4ID0gZmxhdHRlbkludG9BcnJheSh0YXJnZXQsIG9yaWdpbmFsLCBlbGVtZW50LCB0b0xlbmd0aChlbGVtZW50Lmxlbmd0aCksIHRhcmdldEluZGV4LCBkZXB0aCAtIDEpIC0gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0YXJnZXRJbmRleCA+PSAweDFmZmZmZmZmZmZmZmZmKSB0aHJvdyBUeXBlRXJyb3IoKTtcbiAgICAgICAgdGFyZ2V0W3RhcmdldEluZGV4XSA9IGVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIHRhcmdldEluZGV4Kys7XG4gICAgfVxuICAgIHNvdXJjZUluZGV4Kys7XG4gIH1cbiAgcmV0dXJuIHRhcmdldEluZGV4O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZsYXR0ZW5JbnRvQXJyYXk7XG4iLCJ2YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2FsbCA9IHJlcXVpcmUoJy4vX2l0ZXItY2FsbCcpO1xudmFyIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBnZXRJdGVyRm4gPSByZXF1aXJlKCcuL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZCcpO1xudmFyIEJSRUFLID0ge307XG52YXIgUkVUVVJOID0ge307XG52YXIgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXJhYmxlLCBlbnRyaWVzLCBmbiwgdGhhdCwgSVRFUkFUT1IpIHtcbiAgdmFyIGl0ZXJGbiA9IElURVJBVE9SID8gZnVuY3Rpb24gKCkgeyByZXR1cm4gaXRlcmFibGU7IH0gOiBnZXRJdGVyRm4oaXRlcmFibGUpO1xuICB2YXIgZiA9IGN0eChmbiwgdGhhdCwgZW50cmllcyA/IDIgOiAxKTtcbiAgdmFyIGluZGV4ID0gMDtcbiAgdmFyIGxlbmd0aCwgc3RlcCwgaXRlcmF0b3IsIHJlc3VsdDtcbiAgaWYgKHR5cGVvZiBpdGVyRm4gIT0gJ2Z1bmN0aW9uJykgdGhyb3cgVHlwZUVycm9yKGl0ZXJhYmxlICsgJyBpcyBub3QgaXRlcmFibGUhJyk7XG4gIC8vIGZhc3QgY2FzZSBmb3IgYXJyYXlzIHdpdGggZGVmYXVsdCBpdGVyYXRvclxuICBpZiAoaXNBcnJheUl0ZXIoaXRlckZuKSkgZm9yIChsZW5ndGggPSB0b0xlbmd0aChpdGVyYWJsZS5sZW5ndGgpOyBsZW5ndGggPiBpbmRleDsgaW5kZXgrKykge1xuICAgIHJlc3VsdCA9IGVudHJpZXMgPyBmKGFuT2JqZWN0KHN0ZXAgPSBpdGVyYWJsZVtpbmRleF0pWzBdLCBzdGVwWzFdKSA6IGYoaXRlcmFibGVbaW5kZXhdKTtcbiAgICBpZiAocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTikgcmV0dXJuIHJlc3VsdDtcbiAgfSBlbHNlIGZvciAoaXRlcmF0b3IgPSBpdGVyRm4uY2FsbChpdGVyYWJsZSk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTspIHtcbiAgICByZXN1bHQgPSBjYWxsKGl0ZXJhdG9yLCBmLCBzdGVwLnZhbHVlLCBlbnRyaWVzKTtcbiAgICBpZiAocmVzdWx0ID09PSBCUkVBSyB8fCByZXN1bHQgPT09IFJFVFVSTikgcmV0dXJuIHJlc3VsdDtcbiAgfVxufTtcbmV4cG9ydHMuQlJFQUsgPSBCUkVBSztcbmV4cG9ydHMuUkVUVVJOID0gUkVUVVJOO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgnbmF0aXZlLWZ1bmN0aW9uLXRvLXN0cmluZycsIEZ1bmN0aW9uLnRvU3RyaW5nKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy84NiNpc3N1ZWNvbW1lbnQtMTE1NzU5MDI4XG52YXIgZ2xvYmFsID0gbW9kdWxlLmV4cG9ydHMgPSB0eXBlb2Ygd2luZG93ICE9ICd1bmRlZmluZWQnICYmIHdpbmRvdy5NYXRoID09IE1hdGhcbiAgPyB3aW5kb3cgOiB0eXBlb2Ygc2VsZiAhPSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT0gTWF0aCA/IHNlbGZcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXG4gIDogRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbmlmICh0eXBlb2YgX19nID09ICdudW1iZXInKSBfX2cgPSBnbG9iYWw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsInZhciBoYXNPd25Qcm9wZXJ0eSA9IHt9Lmhhc093blByb3BlcnR5O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIGtleSkge1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChpdCwga2V5KTtcbn07XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICByZXR1cm4gZFAuZihvYmplY3QsIGtleSwgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xufSA6IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG4iLCJ2YXIgZG9jdW1lbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5kb2N1bWVudDtcbm1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuIiwibW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpKCdkaXYnKSwgJ2EnLCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gNzsgfSB9KS5hICE9IDc7XG59KTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fc2V0LXByb3RvJykuc2V0O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgdGFyZ2V0LCBDKSB7XG4gIHZhciBTID0gdGFyZ2V0LmNvbnN0cnVjdG9yO1xuICB2YXIgUDtcbiAgaWYgKFMgIT09IEMgJiYgdHlwZW9mIFMgPT0gJ2Z1bmN0aW9uJyAmJiAoUCA9IFMucHJvdG90eXBlKSAhPT0gQy5wcm90b3R5cGUgJiYgaXNPYmplY3QoUCkgJiYgc2V0UHJvdG90eXBlT2YpIHtcbiAgICBzZXRQcm90b3R5cGVPZih0aGF0LCBQKTtcbiAgfSByZXR1cm4gdGhhdDtcbn07XG4iLCIvLyBmYXN0IGFwcGx5LCBodHRwOi8vanNwZXJmLmxua2l0LmNvbS9mYXN0LWFwcGx5LzVcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCBhcmdzLCB0aGF0KSB7XG4gIHZhciB1biA9IHRoYXQgPT09IHVuZGVmaW5lZDtcbiAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgIGNhc2UgMDogcmV0dXJuIHVuID8gZm4oKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0KTtcbiAgICBjYXNlIDE6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0pO1xuICAgIGNhc2UgMjogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgY2FzZSAzOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICBjYXNlIDQ6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICB9IHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmdzKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QoJ3onKS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgwKSA/IE9iamVjdCA6IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gY29mKGl0KSA9PSAnU3RyaW5nJyA/IGl0LnNwbGl0KCcnKSA6IE9iamVjdChpdCk7XG59O1xuIiwiLy8gY2hlY2sgb24gZGVmYXVsdCBBcnJheSBpdGVyYXRvclxudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ICE9PSB1bmRlZmluZWQgJiYgKEl0ZXJhdG9ycy5BcnJheSA9PT0gaXQgfHwgQXJyYXlQcm90b1tJVEVSQVRPUl0gPT09IGl0KTtcbn07XG4iLCIvLyA3LjIuMiBJc0FycmF5KGFyZ3VtZW50KVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xubW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gIHJldHVybiBjb2YoYXJnKSA9PSAnQXJyYXknO1xufTtcbiIsIi8vIDIwLjEuMi4zIE51bWJlci5pc0ludGVnZXIobnVtYmVyKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0ludGVnZXIoaXQpIHtcbiAgcmV0dXJuICFpc09iamVjdChpdCkgJiYgaXNGaW5pdGUoaXQpICYmIGZsb29yKGl0KSA9PT0gaXQ7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIHR5cGVvZiBpdCA9PT0gJ29iamVjdCcgPyBpdCAhPT0gbnVsbCA6IHR5cGVvZiBpdCA9PT0gJ2Z1bmN0aW9uJztcbn07XG4iLCIvLyA3LjIuOCBJc1JlZ0V4cChhcmd1bWVudClcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xudmFyIE1BVENIID0gcmVxdWlyZSgnLi9fd2tzJykoJ21hdGNoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgaXNSZWdFeHA7XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgKChpc1JlZ0V4cCA9IGl0W01BVENIXSkgIT09IHVuZGVmaW5lZCA/ICEhaXNSZWdFeHAgOiBjb2YoaXQpID09ICdSZWdFeHAnKTtcbn07XG4iLCIvLyBjYWxsIHNvbWV0aGluZyBvbiBpdGVyYXRvciBzdGVwIHdpdGggc2FmZSBjbG9zaW5nIG9uIGVycm9yXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0ZXJhdG9yLCBmbiwgdmFsdWUsIGVudHJpZXMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZW50cmllcyA/IGZuKGFuT2JqZWN0KHZhbHVlKVswXSwgdmFsdWVbMV0pIDogZm4odmFsdWUpO1xuICAvLyA3LjQuNiBJdGVyYXRvckNsb3NlKGl0ZXJhdG9yLCBjb21wbGV0aW9uKVxuICB9IGNhdGNoIChlKSB7XG4gICAgdmFyIHJldCA9IGl0ZXJhdG9yWydyZXR1cm4nXTtcbiAgICBpZiAocmV0ICE9PSB1bmRlZmluZWQpIGFuT2JqZWN0KHJldC5jYWxsKGl0ZXJhdG9yKSk7XG4gICAgdGhyb3cgZTtcbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBjcmVhdGUgPSByZXF1aXJlKCcuL19vYmplY3QtY3JlYXRlJyk7XG52YXIgZGVzY3JpcHRvciA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcblxuLy8gMjUuMS4yLjEuMSAlSXRlcmF0b3JQcm90b3R5cGUlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2hpZGUnKShJdGVyYXRvclByb3RvdHlwZSwgcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyksIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCkge1xuICBDb25zdHJ1Y3Rvci5wcm90b3R5cGUgPSBjcmVhdGUoSXRlcmF0b3JQcm90b3R5cGUsIHsgbmV4dDogZGVzY3JpcHRvcigxLCBuZXh0KSB9KTtcbiAgc2V0VG9TdHJpbmdUYWcoQ29uc3RydWN0b3IsIE5BTUUgKyAnIEl0ZXJhdG9yJyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xudmFyICRpdGVyQ3JlYXRlID0gcmVxdWlyZSgnLi9faXRlci1jcmVhdGUnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBCVUdHWSA9ICEoW10ua2V5cyAmJiAnbmV4dCcgaW4gW10ua2V5cygpKTsgLy8gU2FmYXJpIGhhcyBidWdneSBpdGVyYXRvcnMgdy9vIGBuZXh0YFxudmFyIEZGX0lURVJBVE9SID0gJ0BAaXRlcmF0b3InO1xudmFyIEtFWVMgPSAna2V5cyc7XG52YXIgVkFMVUVTID0gJ3ZhbHVlcyc7XG5cbnZhciByZXR1cm5UaGlzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQmFzZSwgTkFNRSwgQ29uc3RydWN0b3IsIG5leHQsIERFRkFVTFQsIElTX1NFVCwgRk9SQ0VEKSB7XG4gICRpdGVyQ3JlYXRlKENvbnN0cnVjdG9yLCBOQU1FLCBuZXh0KTtcbiAgdmFyIGdldE1ldGhvZCA9IGZ1bmN0aW9uIChraW5kKSB7XG4gICAgaWYgKCFCVUdHWSAmJiBraW5kIGluIHByb3RvKSByZXR1cm4gcHJvdG9ba2luZF07XG4gICAgc3dpdGNoIChraW5kKSB7XG4gICAgICBjYXNlIEtFWVM6IHJldHVybiBmdW5jdGlvbiBrZXlzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgICAgY2FzZSBWQUxVRVM6IHJldHVybiBmdW5jdGlvbiB2YWx1ZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gICAgfSByZXR1cm4gZnVuY3Rpb24gZW50cmllcygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgfTtcbiAgdmFyIFRBRyA9IE5BTUUgKyAnIEl0ZXJhdG9yJztcbiAgdmFyIERFRl9WQUxVRVMgPSBERUZBVUxUID09IFZBTFVFUztcbiAgdmFyIFZBTFVFU19CVUcgPSBmYWxzZTtcbiAgdmFyIHByb3RvID0gQmFzZS5wcm90b3R5cGU7XG4gIHZhciAkbmF0aXZlID0gcHJvdG9bSVRFUkFUT1JdIHx8IHByb3RvW0ZGX0lURVJBVE9SXSB8fCBERUZBVUxUICYmIHByb3RvW0RFRkFVTFRdO1xuICB2YXIgJGRlZmF1bHQgPSAkbmF0aXZlIHx8IGdldE1ldGhvZChERUZBVUxUKTtcbiAgdmFyICRlbnRyaWVzID0gREVGQVVMVCA/ICFERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoJ2VudHJpZXMnKSA6IHVuZGVmaW5lZDtcbiAgdmFyICRhbnlOYXRpdmUgPSBOQU1FID09ICdBcnJheScgPyBwcm90by5lbnRyaWVzIHx8ICRuYXRpdmUgOiAkbmF0aXZlO1xuICB2YXIgbWV0aG9kcywga2V5LCBJdGVyYXRvclByb3RvdHlwZTtcbiAgLy8gRml4IG5hdGl2ZVxuICBpZiAoJGFueU5hdGl2ZSkge1xuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG90eXBlT2YoJGFueU5hdGl2ZS5jYWxsKG5ldyBCYXNlKCkpKTtcbiAgICBpZiAoSXRlcmF0b3JQcm90b3R5cGUgIT09IE9iamVjdC5wcm90b3R5cGUgJiYgSXRlcmF0b3JQcm90b3R5cGUubmV4dCkge1xuICAgICAgLy8gU2V0IEBAdG9TdHJpbmdUYWcgdG8gbmF0aXZlIGl0ZXJhdG9yc1xuICAgICAgc2V0VG9TdHJpbmdUYWcoSXRlcmF0b3JQcm90b3R5cGUsIFRBRywgdHJ1ZSk7XG4gICAgICAvLyBmaXggZm9yIHNvbWUgb2xkIGVuZ2luZXNcbiAgICAgIGlmICghTElCUkFSWSAmJiB0eXBlb2YgSXRlcmF0b3JQcm90b3R5cGVbSVRFUkFUT1JdICE9ICdmdW5jdGlvbicpIGhpZGUoSXRlcmF0b3JQcm90b3R5cGUsIElURVJBVE9SLCByZXR1cm5UaGlzKTtcbiAgICB9XG4gIH1cbiAgLy8gZml4IEFycmF5I3t2YWx1ZXMsIEBAaXRlcmF0b3J9Lm5hbWUgaW4gVjggLyBGRlxuICBpZiAoREVGX1ZBTFVFUyAmJiAkbmF0aXZlICYmICRuYXRpdmUubmFtZSAhPT0gVkFMVUVTKSB7XG4gICAgVkFMVUVTX0JVRyA9IHRydWU7XG4gICAgJGRlZmF1bHQgPSBmdW5jdGlvbiB2YWx1ZXMoKSB7IHJldHVybiAkbmF0aXZlLmNhbGwodGhpcyk7IH07XG4gIH1cbiAgLy8gRGVmaW5lIGl0ZXJhdG9yXG4gIGlmICgoIUxJQlJBUlkgfHwgRk9SQ0VEKSAmJiAoQlVHR1kgfHwgVkFMVUVTX0JVRyB8fCAhcHJvdG9bSVRFUkFUT1JdKSkge1xuICAgIGhpZGUocHJvdG8sIElURVJBVE9SLCAkZGVmYXVsdCk7XG4gIH1cbiAgLy8gUGx1ZyBmb3IgbGlicmFyeVxuICBJdGVyYXRvcnNbTkFNRV0gPSAkZGVmYXVsdDtcbiAgSXRlcmF0b3JzW1RBR10gPSByZXR1cm5UaGlzO1xuICBpZiAoREVGQVVMVCkge1xuICAgIG1ldGhvZHMgPSB7XG4gICAgICB2YWx1ZXM6IERFRl9WQUxVRVMgPyAkZGVmYXVsdCA6IGdldE1ldGhvZChWQUxVRVMpLFxuICAgICAga2V5czogSVNfU0VUID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoS0VZUyksXG4gICAgICBlbnRyaWVzOiAkZW50cmllc1xuICAgIH07XG4gICAgaWYgKEZPUkNFRCkgZm9yIChrZXkgaW4gbWV0aG9kcykge1xuICAgICAgaWYgKCEoa2V5IGluIHByb3RvKSkgcmVkZWZpbmUocHJvdG8sIGtleSwgbWV0aG9kc1trZXldKTtcbiAgICB9IGVsc2UgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoQlVHR1kgfHwgVkFMVUVTX0JVRyksIE5BTUUsIG1ldGhvZHMpO1xuICB9XG4gIHJldHVybiBtZXRob2RzO1xufTtcbiIsInZhciBJVEVSQVRPUiA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpO1xudmFyIFNBRkVfQ0xPU0lORyA9IGZhbHNlO1xuXG50cnkge1xuICB2YXIgcml0ZXIgPSBbN11bSVRFUkFUT1JdKCk7XG4gIHJpdGVyWydyZXR1cm4nXSA9IGZ1bmN0aW9uICgpIHsgU0FGRV9DTE9TSU5HID0gdHJ1ZTsgfTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRocm93LWxpdGVyYWxcbiAgQXJyYXkuZnJvbShyaXRlciwgZnVuY3Rpb24gKCkgeyB0aHJvdyAyOyB9KTtcbn0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChleGVjLCBza2lwQ2xvc2luZykge1xuICBpZiAoIXNraXBDbG9zaW5nICYmICFTQUZFX0NMT1NJTkcpIHJldHVybiBmYWxzZTtcbiAgdmFyIHNhZmUgPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICB2YXIgYXJyID0gWzddO1xuICAgIHZhciBpdGVyID0gYXJyW0lURVJBVE9SXSgpO1xuICAgIGl0ZXIubmV4dCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHsgZG9uZTogc2FmZSA9IHRydWUgfTsgfTtcbiAgICBhcnJbSVRFUkFUT1JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gaXRlcjsgfTtcbiAgICBleGVjKGFycik7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gc2FmZTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChkb25lLCB2YWx1ZSkge1xuICByZXR1cm4geyB2YWx1ZTogdmFsdWUsIGRvbmU6ICEhZG9uZSB9O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge307XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZhbHNlO1xuIiwiLy8gMjAuMi4yLjE0IE1hdGguZXhwbTEoeClcbnZhciAkZXhwbTEgPSBNYXRoLmV4cG0xO1xubW9kdWxlLmV4cG9ydHMgPSAoISRleHBtMVxuICAvLyBPbGQgRkYgYnVnXG4gIHx8ICRleHBtMSgxMCkgPiAyMjAyNS40NjU3OTQ4MDY3MTkgfHwgJGV4cG0xKDEwKSA8IDIyMDI1LjQ2NTc5NDgwNjcxNjUxNjhcbiAgLy8gVG9yIEJyb3dzZXIgYnVnXG4gIHx8ICRleHBtMSgtMmUtMTcpICE9IC0yZS0xN1xuKSA/IGZ1bmN0aW9uIGV4cG0xKHgpIHtcbiAgcmV0dXJuICh4ID0gK3gpID09IDAgPyB4IDogeCA+IC0xZS02ICYmIHggPCAxZS02ID8geCArIHggKiB4IC8gMiA6IE1hdGguZXhwKHgpIC0gMTtcbn0gOiAkZXhwbTE7XG4iLCIvLyAyMC4yLjIuMTYgTWF0aC5mcm91bmQoeClcbnZhciBzaWduID0gcmVxdWlyZSgnLi9fbWF0aC1zaWduJyk7XG52YXIgcG93ID0gTWF0aC5wb3c7XG52YXIgRVBTSUxPTiA9IHBvdygyLCAtNTIpO1xudmFyIEVQU0lMT04zMiA9IHBvdygyLCAtMjMpO1xudmFyIE1BWDMyID0gcG93KDIsIDEyNykgKiAoMiAtIEVQU0lMT04zMik7XG52YXIgTUlOMzIgPSBwb3coMiwgLTEyNik7XG5cbnZhciByb3VuZFRpZXNUb0V2ZW4gPSBmdW5jdGlvbiAobikge1xuICByZXR1cm4gbiArIDEgLyBFUFNJTE9OIC0gMSAvIEVQU0lMT047XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguZnJvdW5kIHx8IGZ1bmN0aW9uIGZyb3VuZCh4KSB7XG4gIHZhciAkYWJzID0gTWF0aC5hYnMoeCk7XG4gIHZhciAkc2lnbiA9IHNpZ24oeCk7XG4gIHZhciBhLCByZXN1bHQ7XG4gIGlmICgkYWJzIDwgTUlOMzIpIHJldHVybiAkc2lnbiAqIHJvdW5kVGllc1RvRXZlbigkYWJzIC8gTUlOMzIgLyBFUFNJTE9OMzIpICogTUlOMzIgKiBFUFNJTE9OMzI7XG4gIGEgPSAoMSArIEVQU0lMT04zMiAvIEVQU0lMT04pICogJGFicztcbiAgcmVzdWx0ID0gYSAtIChhIC0gJGFicyk7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgaWYgKHJlc3VsdCA+IE1BWDMyIHx8IHJlc3VsdCAhPSByZXN1bHQpIHJldHVybiAkc2lnbiAqIEluZmluaXR5O1xuICByZXR1cm4gJHNpZ24gKiByZXN1bHQ7XG59O1xuIiwiLy8gMjAuMi4yLjIwIE1hdGgubG9nMXAoeClcbm1vZHVsZS5leHBvcnRzID0gTWF0aC5sb2cxcCB8fCBmdW5jdGlvbiBsb2cxcCh4KSB7XG4gIHJldHVybiAoeCA9ICt4KSA+IC0xZS04ICYmIHggPCAxZS04ID8geCAtIHggKiB4IC8gMiA6IE1hdGgubG9nKDEgKyB4KTtcbn07XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguc2NhbGUgfHwgZnVuY3Rpb24gc2NhbGUoeCwgaW5Mb3csIGluSGlnaCwgb3V0TG93LCBvdXRIaWdoKSB7XG4gIGlmIChcbiAgICBhcmd1bWVudHMubGVuZ3RoID09PSAwXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCB4ICE9IHhcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICAgIHx8IGluTG93ICE9IGluTG93XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCBpbkhpZ2ggIT0gaW5IaWdoXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCBvdXRMb3cgIT0gb3V0TG93XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgICB8fCBvdXRIaWdoICE9IG91dEhpZ2hcbiAgKSByZXR1cm4gTmFOO1xuICBpZiAoeCA9PT0gSW5maW5pdHkgfHwgeCA9PT0gLUluZmluaXR5KSByZXR1cm4geDtcbiAgcmV0dXJuICh4IC0gaW5Mb3cpICogKG91dEhpZ2ggLSBvdXRMb3cpIC8gKGluSGlnaCAtIGluTG93KSArIG91dExvdztcbn07XG4iLCIvLyAyMC4yLjIuMjggTWF0aC5zaWduKHgpXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGguc2lnbiB8fCBmdW5jdGlvbiBzaWduKHgpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICByZXR1cm4gKHggPSAreCkgPT0gMCB8fCB4ICE9IHggPyB4IDogeCA8IDAgPyAtMSA6IDE7XG59O1xuIiwidmFyIE1FVEEgPSByZXF1aXJlKCcuL191aWQnKSgnbWV0YScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgc2V0RGVzYyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgaWQgPSAwO1xudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGUgfHwgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG52YXIgRlJFRVpFID0gIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gaXNFeHRlbnNpYmxlKE9iamVjdC5wcmV2ZW50RXh0ZW5zaW9ucyh7fSkpO1xufSk7XG52YXIgc2V0TWV0YSA9IGZ1bmN0aW9uIChpdCkge1xuICBzZXREZXNjKGl0LCBNRVRBLCB7IHZhbHVlOiB7XG4gICAgaTogJ08nICsgKytpZCwgLy8gb2JqZWN0IElEXG4gICAgdzoge30gICAgICAgICAgLy8gd2VhayBjb2xsZWN0aW9ucyBJRHNcbiAgfSB9KTtcbn07XG52YXIgZmFzdEtleSA9IGZ1bmN0aW9uIChpdCwgY3JlYXRlKSB7XG4gIC8vIHJldHVybiBwcmltaXRpdmUgd2l0aCBwcmVmaXhcbiAgaWYgKCFpc09iamVjdChpdCkpIHJldHVybiB0eXBlb2YgaXQgPT0gJ3N5bWJvbCcgPyBpdCA6ICh0eXBlb2YgaXQgPT0gJ3N0cmluZycgPyAnUycgOiAnUCcpICsgaXQ7XG4gIGlmICghaGFzKGl0LCBNRVRBKSkge1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYgKCFpc0V4dGVuc2libGUoaXQpKSByZXR1cm4gJ0YnO1xuICAgIC8vIG5vdCBuZWNlc3NhcnkgdG8gYWRkIG1ldGFkYXRhXG4gICAgaWYgKCFjcmVhdGUpIHJldHVybiAnRSc7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIG9iamVjdCBJRFxuICB9IHJldHVybiBpdFtNRVRBXS5pO1xufTtcbnZhciBnZXRXZWFrID0gZnVuY3Rpb24gKGl0LCBjcmVhdGUpIHtcbiAgaWYgKCFoYXMoaXQsIE1FVEEpKSB7XG4gICAgLy8gY2FuJ3Qgc2V0IG1ldGFkYXRhIHRvIHVuY2F1Z2h0IGZyb3plbiBvYmplY3RcbiAgICBpZiAoIWlzRXh0ZW5zaWJsZShpdCkpIHJldHVybiB0cnVlO1xuICAgIC8vIG5vdCBuZWNlc3NhcnkgdG8gYWRkIG1ldGFkYXRhXG4gICAgaWYgKCFjcmVhdGUpIHJldHVybiBmYWxzZTtcbiAgICAvLyBhZGQgbWlzc2luZyBtZXRhZGF0YVxuICAgIHNldE1ldGEoaXQpO1xuICAvLyByZXR1cm4gaGFzaCB3ZWFrIGNvbGxlY3Rpb25zIElEc1xuICB9IHJldHVybiBpdFtNRVRBXS53O1xufTtcbi8vIGFkZCBtZXRhZGF0YSBvbiBmcmVlemUtZmFtaWx5IG1ldGhvZHMgY2FsbGluZ1xudmFyIG9uRnJlZXplID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmIChGUkVFWkUgJiYgbWV0YS5ORUVEICYmIGlzRXh0ZW5zaWJsZShpdCkgJiYgIWhhcyhpdCwgTUVUQSkpIHNldE1ldGEoaXQpO1xuICByZXR1cm4gaXQ7XG59O1xudmFyIG1ldGEgPSBtb2R1bGUuZXhwb3J0cyA9IHtcbiAgS0VZOiBNRVRBLFxuICBORUVEOiBmYWxzZSxcbiAgZmFzdEtleTogZmFzdEtleSxcbiAgZ2V0V2VhazogZ2V0V2VhayxcbiAgb25GcmVlemU6IG9uRnJlZXplXG59O1xuIiwidmFyIE1hcCA9IHJlcXVpcmUoJy4vZXM2Lm1hcCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBzaGFyZWQgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgnbWV0YWRhdGEnKTtcbnZhciBzdG9yZSA9IHNoYXJlZC5zdG9yZSB8fCAoc2hhcmVkLnN0b3JlID0gbmV3IChyZXF1aXJlKCcuL2VzNi53ZWFrLW1hcCcpKSgpKTtcblxudmFyIGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAgPSBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRLZXksIGNyZWF0ZSkge1xuICB2YXIgdGFyZ2V0TWV0YWRhdGEgPSBzdG9yZS5nZXQodGFyZ2V0KTtcbiAgaWYgKCF0YXJnZXRNZXRhZGF0YSkge1xuICAgIGlmICghY3JlYXRlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHN0b3JlLnNldCh0YXJnZXQsIHRhcmdldE1ldGFkYXRhID0gbmV3IE1hcCgpKTtcbiAgfVxuICB2YXIga2V5TWV0YWRhdGEgPSB0YXJnZXRNZXRhZGF0YS5nZXQodGFyZ2V0S2V5KTtcbiAgaWYgKCFrZXlNZXRhZGF0YSkge1xuICAgIGlmICghY3JlYXRlKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHRhcmdldE1ldGFkYXRhLnNldCh0YXJnZXRLZXksIGtleU1ldGFkYXRhID0gbmV3IE1hcCgpKTtcbiAgfSByZXR1cm4ga2V5TWV0YWRhdGE7XG59O1xudmFyIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBmdW5jdGlvbiAoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgdmFyIG1ldGFkYXRhTWFwID0gZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCBmYWxzZSk7XG4gIHJldHVybiBtZXRhZGF0YU1hcCA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBtZXRhZGF0YU1hcC5oYXMoTWV0YWRhdGFLZXkpO1xufTtcbnZhciBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gZnVuY3Rpb24gKE1ldGFkYXRhS2V5LCBPLCBQKSB7XG4gIHZhciBtZXRhZGF0YU1hcCA9IGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoTywgUCwgZmFsc2UpO1xuICByZXR1cm4gbWV0YWRhdGFNYXAgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IG1ldGFkYXRhTWFwLmdldChNZXRhZGF0YUtleSk7XG59O1xudmFyIG9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEgPSBmdW5jdGlvbiAoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUsIE8sIFApIHtcbiAgZ2V0T3JDcmVhdGVNZXRhZGF0YU1hcChPLCBQLCB0cnVlKS5zZXQoTWV0YWRhdGFLZXksIE1ldGFkYXRhVmFsdWUpO1xufTtcbnZhciBvcmRpbmFyeU93bk1ldGFkYXRhS2V5cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHRhcmdldEtleSkge1xuICB2YXIgbWV0YWRhdGFNYXAgPSBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwKHRhcmdldCwgdGFyZ2V0S2V5LCBmYWxzZSk7XG4gIHZhciBrZXlzID0gW107XG4gIGlmIChtZXRhZGF0YU1hcCkgbWV0YWRhdGFNYXAuZm9yRWFjaChmdW5jdGlvbiAoXywga2V5KSB7IGtleXMucHVzaChrZXkpOyB9KTtcbiAgcmV0dXJuIGtleXM7XG59O1xudmFyIHRvTWV0YUtleSA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgaXQgPT0gJ3N5bWJvbCcgPyBpdCA6IFN0cmluZyhpdCk7XG59O1xudmFyIGV4cCA9IGZ1bmN0aW9uIChPKSB7XG4gICRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIE8pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHN0b3JlOiBzdG9yZSxcbiAgbWFwOiBnZXRPckNyZWF0ZU1ldGFkYXRhTWFwLFxuICBoYXM6IG9yZGluYXJ5SGFzT3duTWV0YWRhdGEsXG4gIGdldDogb3JkaW5hcnlHZXRPd25NZXRhZGF0YSxcbiAgc2V0OiBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhLFxuICBrZXlzOiBvcmRpbmFyeU93bk1ldGFkYXRhS2V5cyxcbiAga2V5OiB0b01ldGFLZXksXG4gIGV4cDogZXhwXG59O1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIG1hY3JvdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgT2JzZXJ2ZXIgPSBnbG9iYWwuTXV0YXRpb25PYnNlcnZlciB8fCBnbG9iYWwuV2ViS2l0TXV0YXRpb25PYnNlcnZlcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgUHJvbWlzZSA9IGdsb2JhbC5Qcm9taXNlO1xudmFyIGlzTm9kZSA9IHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBoZWFkLCBsYXN0LCBub3RpZnk7XG5cbiAgdmFyIGZsdXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwYXJlbnQsIGZuO1xuICAgIGlmIChpc05vZGUgJiYgKHBhcmVudCA9IHByb2Nlc3MuZG9tYWluKSkgcGFyZW50LmV4aXQoKTtcbiAgICB3aGlsZSAoaGVhZCkge1xuICAgICAgZm4gPSBoZWFkLmZuO1xuICAgICAgaGVhZCA9IGhlYWQubmV4dDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZuKCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChoZWFkKSBub3RpZnkoKTtcbiAgICAgICAgZWxzZSBsYXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH0gbGFzdCA9IHVuZGVmaW5lZDtcbiAgICBpZiAocGFyZW50KSBwYXJlbnQuZW50ZXIoKTtcbiAgfTtcblxuICAvLyBOb2RlLmpzXG4gIGlmIChpc05vZGUpIHtcbiAgICBub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBwcm9jZXNzLm5leHRUaWNrKGZsdXNoKTtcbiAgICB9O1xuICAvLyBicm93c2VycyB3aXRoIE11dGF0aW9uT2JzZXJ2ZXIsIGV4Y2VwdCBpT1MgU2FmYXJpIC0gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzMzOVxuICB9IGVsc2UgaWYgKE9ic2VydmVyICYmICEoZ2xvYmFsLm5hdmlnYXRvciAmJiBnbG9iYWwubmF2aWdhdG9yLnN0YW5kYWxvbmUpKSB7XG4gICAgdmFyIHRvZ2dsZSA9IHRydWU7XG4gICAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gICAgbmV3IE9ic2VydmVyKGZsdXNoKS5vYnNlcnZlKG5vZGUsIHsgY2hhcmFjdGVyRGF0YTogdHJ1ZSB9KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICBub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBub2RlLmRhdGEgPSB0b2dnbGUgPSAhdG9nZ2xlO1xuICAgIH07XG4gIC8vIGVudmlyb25tZW50cyB3aXRoIG1heWJlIG5vbi1jb21wbGV0ZWx5IGNvcnJlY3QsIGJ1dCBleGlzdGVudCBQcm9taXNlXG4gIH0gZWxzZSBpZiAoUHJvbWlzZSAmJiBQcm9taXNlLnJlc29sdmUpIHtcbiAgICAvLyBQcm9taXNlLnJlc29sdmUgd2l0aG91dCBhbiBhcmd1bWVudCB0aHJvd3MgYW4gZXJyb3IgaW4gTEcgV2ViT1MgMlxuICAgIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKHVuZGVmaW5lZCk7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcHJvbWlzZS50aGVuKGZsdXNoKTtcbiAgICB9O1xuICAvLyBmb3Igb3RoZXIgZW52aXJvbm1lbnRzIC0gbWFjcm90YXNrIGJhc2VkIG9uOlxuICAvLyAtIHNldEltbWVkaWF0ZVxuICAvLyAtIE1lc3NhZ2VDaGFubmVsXG4gIC8vIC0gd2luZG93LnBvc3RNZXNzYWdcbiAgLy8gLSBvbnJlYWR5c3RhdGVjaGFuZ2VcbiAgLy8gLSBzZXRUaW1lb3V0XG4gIH0gZWxzZSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgLy8gc3RyYW5nZSBJRSArIHdlYnBhY2sgZGV2IHNlcnZlciBidWcgLSB1c2UgLmNhbGwoZ2xvYmFsKVxuICAgICAgbWFjcm90YXNrLmNhbGwoZ2xvYmFsLCBmbHVzaCk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoZm4pIHtcbiAgICB2YXIgdGFzayA9IHsgZm46IGZuLCBuZXh0OiB1bmRlZmluZWQgfTtcbiAgICBpZiAobGFzdCkgbGFzdC5uZXh0ID0gdGFzaztcbiAgICBpZiAoIWhlYWQpIHtcbiAgICAgIGhlYWQgPSB0YXNrO1xuICAgICAgbm90aWZ5KCk7XG4gICAgfSBsYXN0ID0gdGFzaztcbiAgfTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyNS40LjEuNSBOZXdQcm9taXNlQ2FwYWJpbGl0eShDKVxudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcblxuZnVuY3Rpb24gUHJvbWlzZUNhcGFiaWxpdHkoQykge1xuICB2YXIgcmVzb2x2ZSwgcmVqZWN0O1xuICB0aGlzLnByb21pc2UgPSBuZXcgQyhmdW5jdGlvbiAoJCRyZXNvbHZlLCAkJHJlamVjdCkge1xuICAgIGlmIChyZXNvbHZlICE9PSB1bmRlZmluZWQgfHwgcmVqZWN0ICE9PSB1bmRlZmluZWQpIHRocm93IFR5cGVFcnJvcignQmFkIFByb21pc2UgY29uc3RydWN0b3InKTtcbiAgICByZXNvbHZlID0gJCRyZXNvbHZlO1xuICAgIHJlamVjdCA9ICQkcmVqZWN0O1xuICB9KTtcbiAgdGhpcy5yZXNvbHZlID0gYUZ1bmN0aW9uKHJlc29sdmUpO1xuICB0aGlzLnJlamVjdCA9IGFGdW5jdGlvbihyZWplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gKEMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlQ2FwYWJpbGl0eShDKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyAxOS4xLjIuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlLCAuLi4pXG52YXIgZ2V0S2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzJyk7XG52YXIgZ09QUyA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJyk7XG52YXIgcElFID0gcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciAkYXNzaWduID0gT2JqZWN0LmFzc2lnbjtcblxuLy8gc2hvdWxkIHdvcmsgd2l0aCBzeW1ib2xzIGFuZCBzaG91bGQgaGF2ZSBkZXRlcm1pbmlzdGljIHByb3BlcnR5IG9yZGVyIChWOCBidWcpXG5tb2R1bGUuZXhwb3J0cyA9ICEkYXNzaWduIHx8IHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICB2YXIgQSA9IHt9O1xuICB2YXIgQiA9IHt9O1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgdmFyIFMgPSBTeW1ib2woKTtcbiAgdmFyIEsgPSAnYWJjZGVmZ2hpamtsbW5vcHFyc3QnO1xuICBBW1NdID0gNztcbiAgSy5zcGxpdCgnJykuZm9yRWFjaChmdW5jdGlvbiAoaykgeyBCW2tdID0gazsgfSk7XG4gIHJldHVybiAkYXNzaWduKHt9LCBBKVtTXSAhPSA3IHx8IE9iamVjdC5rZXlzKCRhc3NpZ24oe30sIEIpKS5qb2luKCcnKSAhPSBLO1xufSkgPyBmdW5jdGlvbiBhc3NpZ24odGFyZ2V0LCBzb3VyY2UpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICB2YXIgVCA9IHRvT2JqZWN0KHRhcmdldCk7XG4gIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgdmFyIGluZGV4ID0gMTtcbiAgdmFyIGdldFN5bWJvbHMgPSBnT1BTLmY7XG4gIHZhciBpc0VudW0gPSBwSUUuZjtcbiAgd2hpbGUgKGFMZW4gPiBpbmRleCkge1xuICAgIHZhciBTID0gSU9iamVjdChhcmd1bWVudHNbaW5kZXgrK10pO1xuICAgIHZhciBrZXlzID0gZ2V0U3ltYm9scyA/IGdldEtleXMoUykuY29uY2F0KGdldFN5bWJvbHMoUykpIDogZ2V0S2V5cyhTKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGogPSAwO1xuICAgIHZhciBrZXk7XG4gICAgd2hpbGUgKGxlbmd0aCA+IGopIGlmIChpc0VudW0uY2FsbChTLCBrZXkgPSBrZXlzW2orK10pKSBUW2tleV0gPSBTW2tleV07XG4gIH0gcmV0dXJuIFQ7XG59IDogJGFzc2lnbjtcbiIsIi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgZFBzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwcycpO1xudmFyIGVudW1CdWdLZXlzID0gcmVxdWlyZSgnLi9fZW51bS1idWcta2V5cycpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xudmFyIEVtcHR5ID0gZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9O1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG4vLyBDcmVhdGUgb2JqZWN0IHdpdGggZmFrZSBgbnVsbGAgcHJvdG90eXBlOiB1c2UgaWZyYW1lIE9iamVjdCB3aXRoIGNsZWFyZWQgcHJvdG90eXBlXG52YXIgY3JlYXRlRGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gVGhyYXNoLCB3YXN0ZSBhbmQgc29kb215OiBJRSBHQyBidWdcbiAgdmFyIGlmcmFtZSA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnaWZyYW1lJyk7XG4gIHZhciBpID0gZW51bUJ1Z0tleXMubGVuZ3RoO1xuICB2YXIgbHQgPSAnPCc7XG4gIHZhciBndCA9ICc+JztcbiAgdmFyIGlmcmFtZURvY3VtZW50O1xuICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgcmVxdWlyZSgnLi9faHRtbCcpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG4gIGlmcmFtZS5zcmMgPSAnamF2YXNjcmlwdDonOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNjcmlwdC11cmxcbiAgLy8gY3JlYXRlRGljdCA9IGlmcmFtZS5jb250ZW50V2luZG93Lk9iamVjdDtcbiAgLy8gaHRtbC5yZW1vdmVDaGlsZChpZnJhbWUpO1xuICBpZnJhbWVEb2N1bWVudCA9IGlmcmFtZS5jb250ZW50V2luZG93LmRvY3VtZW50O1xuICBpZnJhbWVEb2N1bWVudC5vcGVuKCk7XG4gIGlmcmFtZURvY3VtZW50LndyaXRlKGx0ICsgJ3NjcmlwdCcgKyBndCArICdkb2N1bWVudC5GPU9iamVjdCcgKyBsdCArICcvc2NyaXB0JyArIGd0KTtcbiAgaWZyYW1lRG9jdW1lbnQuY2xvc2UoKTtcbiAgY3JlYXRlRGljdCA9IGlmcmFtZURvY3VtZW50LkY7XG4gIHdoaWxlIChpLS0pIGRlbGV0ZSBjcmVhdGVEaWN0W1BST1RPVFlQRV1bZW51bUJ1Z0tleXNbaV1dO1xuICByZXR1cm4gY3JlYXRlRGljdCgpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuY3JlYXRlIHx8IGZ1bmN0aW9uIGNyZWF0ZShPLCBQcm9wZXJ0aWVzKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChPICE9PSBudWxsKSB7XG4gICAgRW1wdHlbUFJPVE9UWVBFXSA9IGFuT2JqZWN0KE8pO1xuICAgIHJlc3VsdCA9IG5ldyBFbXB0eSgpO1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBudWxsO1xuICAgIC8vIGFkZCBcIl9fcHJvdG9fX1wiIGZvciBPYmplY3QuZ2V0UHJvdG90eXBlT2YgcG9seWZpbGxcbiAgICByZXN1bHRbSUVfUFJPVE9dID0gTztcbiAgfSBlbHNlIHJlc3VsdCA9IGNyZWF0ZURpY3QoKTtcbiAgcmV0dXJuIFByb3BlcnRpZXMgPT09IHVuZGVmaW5lZCA/IHJlc3VsdCA6IGRQcyhyZXN1bHQsIFByb3BlcnRpZXMpO1xufTtcbiIsInZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGRQID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xuXG5leHBvcnRzLmYgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnR5IDogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcykge1xuICBhbk9iamVjdChPKTtcbiAgUCA9IHRvUHJpbWl0aXZlKFAsIHRydWUpO1xuICBhbk9iamVjdChBdHRyaWJ1dGVzKTtcbiAgaWYgKElFOF9ET01fREVGSU5FKSB0cnkge1xuICAgIHJldHVybiBkUChPLCBQLCBBdHRyaWJ1dGVzKTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG4gIGlmICgnZ2V0JyBpbiBBdHRyaWJ1dGVzIHx8ICdzZXQnIGluIEF0dHJpYnV0ZXMpIHRocm93IFR5cGVFcnJvcignQWNjZXNzb3JzIG5vdCBzdXBwb3J0ZWQhJyk7XG4gIGlmICgndmFsdWUnIGluIEF0dHJpYnV0ZXMpIE9bUF0gPSBBdHRyaWJ1dGVzLnZhbHVlO1xuICByZXR1cm4gTztcbn07XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcykge1xuICBhbk9iamVjdChPKTtcbiAgdmFyIGtleXMgPSBnZXRLZXlzKFByb3BlcnRpZXMpO1xuICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gIHZhciBpID0gMDtcbiAgdmFyIFA7XG4gIHdoaWxlIChsZW5ndGggPiBpKSBkUC5mKE8sIFAgPSBrZXlzW2krK10sIFByb3BlcnRpZXNbUF0pO1xuICByZXR1cm4gTztcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyBGb3JjZWQgcmVwbGFjZW1lbnQgcHJvdG90eXBlIGFjY2Vzc29ycyBtZXRob2RzXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKSB8fCAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHZhciBLID0gTWF0aC5yYW5kb20oKTtcbiAgLy8gSW4gRkYgdGhyb3dzIG9ubHkgZGVmaW5lIG1ldGhvZHNcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmLCBuby11c2VsZXNzLWNhbGxcbiAgX19kZWZpbmVTZXR0ZXJfXy5jYWxsKG51bGwsIEssIGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSk7XG4gIGRlbGV0ZSByZXF1aXJlKCcuL19nbG9iYWwnKVtLXTtcbn0pO1xuIiwidmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKTtcbnZhciBnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGdPUEQgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCkge1xuICBPID0gdG9JT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZ09QRChPLCBQKTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG4gIGlmIChoYXMoTywgUCkpIHJldHVybiBjcmVhdGVEZXNjKCFwSUUuZi5jYWxsKE8sIFApLCBPW1BdKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxudmFyIHdpbmRvd05hbWVzID0gdHlwZW9mIHdpbmRvdyA9PSAnb2JqZWN0JyAmJiB3aW5kb3cgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXNcbiAgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh3aW5kb3cpIDogW107XG5cbnZhciBnZXRXaW5kb3dOYW1lcyA9IGZ1bmN0aW9uIChpdCkge1xuICB0cnkge1xuICAgIHJldHVybiBnT1BOKGl0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCkge1xuICByZXR1cm4gd2luZG93TmFtZXMgJiYgdG9TdHJpbmcuY2FsbChpdCkgPT0gJ1tvYmplY3QgV2luZG93XScgPyBnZXRXaW5kb3dOYW1lcyhpdCkgOiBnT1BOKHRvSU9iamVjdChpdCkpO1xufTtcbiIsIi8vIDE5LjEuMi43IC8gMTUuMi4zLjQgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbnZhciAka2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJyk7XG52YXIgaGlkZGVuS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKS5jb25jYXQoJ2xlbmd0aCcsICdwcm90b3R5cGUnKTtcblxuZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgfHwgZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhPKSB7XG4gIHJldHVybiAka2V5cyhPLCBoaWRkZW5LZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xuIiwiLy8gMTkuMS4yLjkgLyAxNS4yLjMuMiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTylcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xudmFyIE9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24gKE8pIHtcbiAgTyA9IHRvT2JqZWN0KE8pO1xuICBpZiAoaGFzKE8sIElFX1BST1RPKSkgcmV0dXJuIE9bSUVfUFJPVE9dO1xuICBpZiAodHlwZW9mIE8uY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBPIGluc3RhbmNlb2YgTy5jb25zdHJ1Y3Rvcikge1xuICAgIHJldHVybiBPLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgfSByZXR1cm4gTyBpbnN0YW5jZW9mIE9iamVjdCA/IE9iamVjdFByb3RvIDogbnVsbDtcbn07XG4iLCJ2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGFycmF5SW5kZXhPZiA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykoZmFsc2UpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWVzKSB7XG4gIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gIHZhciBpID0gMDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBPKSBpZiAoa2V5ICE9IElFX1BST1RPKSBoYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSBpZiAoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKSB7XG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8vIDE5LjEuMi4xNCAvIDE1LjIuMy4xNCBPYmplY3Qua2V5cyhPKVxudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMtaW50ZXJuYWwnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzKE8pIHtcbiAgcmV0dXJuICRrZXlzKE8sIGVudW1CdWdLZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiIsIi8vIG1vc3QgT2JqZWN0IG1ldGhvZHMgYnkgRVM2IHNob3VsZCBhY2NlcHQgcHJpbWl0aXZlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSwgZXhlYykge1xuICB2YXIgZm4gPSAoY29yZS5PYmplY3QgfHwge30pW0tFWV0gfHwgT2JqZWN0W0tFWV07XG4gIHZhciBleHAgPSB7fTtcbiAgZXhwW0tFWV0gPSBleGVjKGZuKTtcbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7IGZuKDEpOyB9KSwgJ09iamVjdCcsIGV4cCk7XG59O1xuIiwidmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBpc0VudW0gPSByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGlzRW50cmllcykge1xuICByZXR1cm4gZnVuY3Rpb24gKGl0KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoaXQpO1xuICAgIHZhciBrZXlzID0gZ2V0S2V5cyhPKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBpKSBpZiAoaXNFbnVtLmNhbGwoTywga2V5ID0ga2V5c1tpKytdKSkge1xuICAgICAgcmVzdWx0LnB1c2goaXNFbnRyaWVzID8gW2tleSwgT1trZXldXSA6IE9ba2V5XSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9O1xufTtcbiIsIi8vIGFsbCBvYmplY3Qga2V5cywgaW5jbHVkZXMgbm9uLWVudW1lcmFibGUgYW5kIHN5bWJvbHNcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIFJlZmxlY3QgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0O1xubW9kdWxlLmV4cG9ydHMgPSBSZWZsZWN0ICYmIFJlZmxlY3Qub3duS2V5cyB8fCBmdW5jdGlvbiBvd25LZXlzKGl0KSB7XG4gIHZhciBrZXlzID0gZ09QTi5mKGFuT2JqZWN0KGl0KSk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICByZXR1cm4gZ2V0U3ltYm9scyA/IGtleXMuY29uY2F0KGdldFN5bWJvbHMoaXQpKSA6IGtleXM7XG59O1xuIiwidmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykucGFyc2VGbG9hdDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcblxubW9kdWxlLmV4cG9ydHMgPSAxIC8gJHBhcnNlRmxvYXQocmVxdWlyZSgnLi9fc3RyaW5nLXdzJykgKyAnLTAnKSAhPT0gLUluZmluaXR5ID8gZnVuY3Rpb24gcGFyc2VGbG9hdChzdHIpIHtcbiAgdmFyIHN0cmluZyA9ICR0cmltKFN0cmluZyhzdHIpLCAzKTtcbiAgdmFyIHJlc3VsdCA9ICRwYXJzZUZsb2F0KHN0cmluZyk7XG4gIHJldHVybiByZXN1bHQgPT09IDAgJiYgc3RyaW5nLmNoYXJBdCgwKSA9PSAnLScgPyAtMCA6IHJlc3VsdDtcbn0gOiAkcGFyc2VGbG9hdDtcbiIsInZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wYXJzZUludDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciB3cyA9IHJlcXVpcmUoJy4vX3N0cmluZy13cycpO1xudmFyIGhleCA9IC9eWy0rXT8wW3hYXS87XG5cbm1vZHVsZS5leHBvcnRzID0gJHBhcnNlSW50KHdzICsgJzA4JykgIT09IDggfHwgJHBhcnNlSW50KHdzICsgJzB4MTYnKSAhPT0gMjIgPyBmdW5jdGlvbiBwYXJzZUludChzdHIsIHJhZGl4KSB7XG4gIHZhciBzdHJpbmcgPSAkdHJpbShTdHJpbmcoc3RyKSwgMyk7XG4gIHJldHVybiAkcGFyc2VJbnQoc3RyaW5nLCAocmFkaXggPj4+IDApIHx8IChoZXgudGVzdChzdHJpbmcpID8gMTYgOiAxMCkpO1xufSA6ICRwYXJzZUludDtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4geyBlOiBmYWxzZSwgdjogZXhlYygpIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4geyBlOiB0cnVlLCB2OiBlIH07XG4gIH1cbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5ID0gcmVxdWlyZSgnLi9fbmV3LXByb21pc2UtY2FwYWJpbGl0eScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDLCB4KSB7XG4gIGFuT2JqZWN0KEMpO1xuICBpZiAoaXNPYmplY3QoeCkgJiYgeC5jb25zdHJ1Y3RvciA9PT0gQykgcmV0dXJuIHg7XG4gIHZhciBwcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5LmYoQyk7XG4gIHZhciByZXNvbHZlID0gcHJvbWlzZUNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgcmVzb2x2ZSh4KTtcbiAgcmV0dXJuIHByb21pc2VDYXBhYmlsaXR5LnByb21pc2U7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYml0bWFwLCB2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIGVudW1lcmFibGU6ICEoYml0bWFwICYgMSksXG4gICAgY29uZmlndXJhYmxlOiAhKGJpdG1hcCAmIDIpLFxuICAgIHdyaXRhYmxlOiAhKGJpdG1hcCAmIDQpLFxuICAgIHZhbHVlOiB2YWx1ZVxuICB9O1xufTtcbiIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHNyYywgc2FmZSkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSByZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0sIHNhZmUpO1xuICByZXR1cm4gdGFyZ2V0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIFNSQyA9IHJlcXVpcmUoJy4vX3VpZCcpKCdzcmMnKTtcbnZhciAkdG9TdHJpbmcgPSByZXF1aXJlKCcuL19mdW5jdGlvbi10by1zdHJpbmcnKTtcbnZhciBUT19TVFJJTkcgPSAndG9TdHJpbmcnO1xudmFyIFRQTCA9ICgnJyArICR0b1N0cmluZykuc3BsaXQoVE9fU1RSSU5HKTtcblxucmVxdWlyZSgnLi9fY29yZScpLmluc3BlY3RTb3VyY2UgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuICR0b1N0cmluZy5jYWxsKGl0KTtcbn07XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChPLCBrZXksIHZhbCwgc2FmZSkge1xuICB2YXIgaXNGdW5jdGlvbiA9IHR5cGVvZiB2YWwgPT0gJ2Z1bmN0aW9uJztcbiAgaWYgKGlzRnVuY3Rpb24pIGhhcyh2YWwsICduYW1lJykgfHwgaGlkZSh2YWwsICduYW1lJywga2V5KTtcbiAgaWYgKE9ba2V5XSA9PT0gdmFsKSByZXR1cm47XG4gIGlmIChpc0Z1bmN0aW9uKSBoYXModmFsLCBTUkMpIHx8IGhpZGUodmFsLCBTUkMsIE9ba2V5XSA/ICcnICsgT1trZXldIDogVFBMLmpvaW4oU3RyaW5nKGtleSkpKTtcbiAgaWYgKE8gPT09IGdsb2JhbCkge1xuICAgIE9ba2V5XSA9IHZhbDtcbiAgfSBlbHNlIGlmICghc2FmZSkge1xuICAgIGRlbGV0ZSBPW2tleV07XG4gICAgaGlkZShPLCBrZXksIHZhbCk7XG4gIH0gZWxzZSBpZiAoT1trZXldKSB7XG4gICAgT1trZXldID0gdmFsO1xuICB9IGVsc2Uge1xuICAgIGhpZGUoTywga2V5LCB2YWwpO1xuICB9XG4vLyBhZGQgZmFrZSBGdW5jdGlvbiN0b1N0cmluZyBmb3IgY29ycmVjdCB3b3JrIHdyYXBwZWQgbWV0aG9kcyAvIGNvbnN0cnVjdG9ycyB3aXRoIG1ldGhvZHMgbGlrZSBMb0Rhc2ggaXNOYXRpdmVcbn0pKEZ1bmN0aW9uLnByb3RvdHlwZSwgVE9fU1RSSU5HLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgcmV0dXJuIHR5cGVvZiB0aGlzID09ICdmdW5jdGlvbicgJiYgdGhpc1tTUkNdIHx8ICR0b1N0cmluZy5jYWxsKHRoaXMpO1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xudmFyIGJ1aWx0aW5FeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjO1xuXG4gLy8gYFJlZ0V4cEV4ZWNgIGFic3RyYWN0IG9wZXJhdGlvblxuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcmVnZXhwZXhlY1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoUiwgUykge1xuICB2YXIgZXhlYyA9IFIuZXhlYztcbiAgaWYgKHR5cGVvZiBleGVjID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdmFyIHJlc3VsdCA9IGV4ZWMuY2FsbChSLCBTKTtcbiAgICBpZiAodHlwZW9mIHJlc3VsdCAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlZ0V4cCBleGVjIG1ldGhvZCByZXR1cm5lZCBzb21ldGhpbmcgb3RoZXIgdGhhbiBhbiBPYmplY3Qgb3IgbnVsbCcpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGlmIChjbGFzc29mKFIpICE9PSAnUmVnRXhwJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1JlZ0V4cCNleGVjIGNhbGxlZCBvbiBpbmNvbXBhdGlibGUgcmVjZWl2ZXInKTtcbiAgfVxuICByZXR1cm4gYnVpbHRpbkV4ZWMuY2FsbChSLCBTKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZWdleHBGbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG5cbnZhciBuYXRpdmVFeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjO1xuLy8gVGhpcyBhbHdheXMgcmVmZXJzIHRvIHRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24sIGJlY2F1c2UgdGhlXG4vLyBTdHJpbmcjcmVwbGFjZSBwb2x5ZmlsbCB1c2VzIC4vZml4LXJlZ2V4cC13ZWxsLWtub3duLXN5bWJvbC1sb2dpYy5qcyxcbi8vIHdoaWNoIGxvYWRzIHRoaXMgZmlsZSBiZWZvcmUgcGF0Y2hpbmcgdGhlIG1ldGhvZC5cbnZhciBuYXRpdmVSZXBsYWNlID0gU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlO1xuXG52YXIgcGF0Y2hlZEV4ZWMgPSBuYXRpdmVFeGVjO1xuXG52YXIgTEFTVF9JTkRFWCA9ICdsYXN0SW5kZXgnO1xuXG52YXIgVVBEQVRFU19MQVNUX0lOREVYX1dST05HID0gKGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJlMSA9IC9hLyxcbiAgICAgIHJlMiA9IC9iKi9nO1xuICBuYXRpdmVFeGVjLmNhbGwocmUxLCAnYScpO1xuICBuYXRpdmVFeGVjLmNhbGwocmUyLCAnYScpO1xuICByZXR1cm4gcmUxW0xBU1RfSU5ERVhdICE9PSAwIHx8IHJlMltMQVNUX0lOREVYXSAhPT0gMDtcbn0pKCk7XG5cbi8vIG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwLCBjb3BpZWQgZnJvbSBlczUtc2hpbSdzIFN0cmluZyNzcGxpdCBwYXRjaC5cbnZhciBOUENHX0lOQ0xVREVEID0gLygpPz8vLmV4ZWMoJycpWzFdICE9PSB1bmRlZmluZWQ7XG5cbnZhciBQQVRDSCA9IFVQREFURVNfTEFTVF9JTkRFWF9XUk9ORyB8fCBOUENHX0lOQ0xVREVEO1xuXG5pZiAoUEFUQ0gpIHtcbiAgcGF0Y2hlZEV4ZWMgPSBmdW5jdGlvbiBleGVjKHN0cikge1xuICAgIHZhciByZSA9IHRoaXM7XG4gICAgdmFyIGxhc3RJbmRleCwgcmVDb3B5LCBtYXRjaCwgaTtcblxuICAgIGlmIChOUENHX0lOQ0xVREVEKSB7XG4gICAgICByZUNvcHkgPSBuZXcgUmVnRXhwKCdeJyArIHJlLnNvdXJjZSArICckKD8hXFxcXHMpJywgcmVnZXhwRmxhZ3MuY2FsbChyZSkpO1xuICAgIH1cbiAgICBpZiAoVVBEQVRFU19MQVNUX0lOREVYX1dST05HKSBsYXN0SW5kZXggPSByZVtMQVNUX0lOREVYXTtcblxuICAgIG1hdGNoID0gbmF0aXZlRXhlYy5jYWxsKHJlLCBzdHIpO1xuXG4gICAgaWYgKFVQREFURVNfTEFTVF9JTkRFWF9XUk9ORyAmJiBtYXRjaCkge1xuICAgICAgcmVbTEFTVF9JTkRFWF0gPSByZS5nbG9iYWwgPyBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aCA6IGxhc3RJbmRleDtcbiAgICB9XG4gICAgaWYgKE5QQ0dfSU5DTFVERUQgJiYgbWF0Y2ggJiYgbWF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgLy8gRml4IGJyb3dzZXJzIHdob3NlIGBleGVjYCBtZXRob2RzIGRvbid0IGNvbnNpc3RlbnRseSByZXR1cm4gYHVuZGVmaW5lZGBcbiAgICAgIC8vIGZvciBOUENHLCBsaWtlIElFOC4gTk9URTogVGhpcyBkb2Vzbicgd29yayBmb3IgLyguPyk/L1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3AtZnVuY1xuICAgICAgbmF0aXZlUmVwbGFjZS5jYWxsKG1hdGNoWzBdLCByZUNvcHksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGggLSAyOyBpKyspIHtcbiAgICAgICAgICBpZiAoYXJndW1lbnRzW2ldID09PSB1bmRlZmluZWQpIG1hdGNoW2ldID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWF0Y2g7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcGF0Y2hlZEV4ZWM7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChyZWdFeHAsIHJlcGxhY2UpIHtcbiAgdmFyIHJlcGxhY2VyID0gcmVwbGFjZSA9PT0gT2JqZWN0KHJlcGxhY2UpID8gZnVuY3Rpb24gKHBhcnQpIHtcbiAgICByZXR1cm4gcmVwbGFjZVtwYXJ0XTtcbiAgfSA6IHJlcGxhY2U7XG4gIHJldHVybiBmdW5jdGlvbiAoaXQpIHtcbiAgICByZXR1cm4gU3RyaW5nKGl0KS5yZXBsYWNlKHJlZ0V4cCwgcmVwbGFjZXIpO1xuICB9O1xufTtcbiIsIi8vIDcuMi45IFNhbWVWYWx1ZSh4LCB5KVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuaXMgfHwgZnVuY3Rpb24gaXMoeCwgeSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIHJldHVybiB4ID09PSB5ID8geCAhPT0gMCB8fCAxIC8geCA9PT0gMSAvIHkgOiB4ICE9IHggJiYgeSAhPSB5O1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS9cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKENPTExFQ1RJT04pIHtcbiAgJGV4cG9ydCgkZXhwb3J0LlMsIENPTExFQ1RJT04sIHsgZnJvbTogZnVuY3Rpb24gZnJvbShzb3VyY2UgLyogLCBtYXBGbiwgdGhpc0FyZyAqLykge1xuICAgIHZhciBtYXBGbiA9IGFyZ3VtZW50c1sxXTtcbiAgICB2YXIgbWFwcGluZywgQSwgbiwgY2I7XG4gICAgYUZ1bmN0aW9uKHRoaXMpO1xuICAgIG1hcHBpbmcgPSBtYXBGbiAhPT0gdW5kZWZpbmVkO1xuICAgIGlmIChtYXBwaW5nKSBhRnVuY3Rpb24obWFwRm4pO1xuICAgIGlmIChzb3VyY2UgPT0gdW5kZWZpbmVkKSByZXR1cm4gbmV3IHRoaXMoKTtcbiAgICBBID0gW107XG4gICAgaWYgKG1hcHBpbmcpIHtcbiAgICAgIG4gPSAwO1xuICAgICAgY2IgPSBjdHgobWFwRm4sIGFyZ3VtZW50c1syXSwgMik7XG4gICAgICBmb3JPZihzb3VyY2UsIGZhbHNlLCBmdW5jdGlvbiAobmV4dEl0ZW0pIHtcbiAgICAgICAgQS5wdXNoKGNiKG5leHRJdGVtLCBuKyspKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPZihzb3VyY2UsIGZhbHNlLCBBLnB1c2gsIEEpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IHRoaXMoQSk7XG4gIH0gfSk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ09MTEVDVElPTikge1xuICAkZXhwb3J0KCRleHBvcnQuUywgQ09MTEVDVElPTiwgeyBvZjogZnVuY3Rpb24gb2YoKSB7XG4gICAgdmFyIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIEEgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIEFbbGVuZ3RoXSA9IGFyZ3VtZW50c1tsZW5ndGhdO1xuICAgIHJldHVybiBuZXcgdGhpcyhBKTtcbiAgfSB9KTtcbn07XG4iLCIvLyBXb3JrcyB3aXRoIF9fcHJvdG9fXyBvbmx5LiBPbGQgdjggY2FuJ3Qgd29yayB3aXRoIG51bGwgcHJvdG8gb2JqZWN0cy5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXByb3RvICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGNoZWNrID0gZnVuY3Rpb24gKE8sIHByb3RvKSB7XG4gIGFuT2JqZWN0KE8pO1xuICBpZiAoIWlzT2JqZWN0KHByb3RvKSAmJiBwcm90byAhPT0gbnVsbCkgdGhyb3cgVHlwZUVycm9yKHByb3RvICsgXCI6IGNhbid0IHNldCBhcyBwcm90b3R5cGUhXCIpO1xufTtcbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXQ6IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCAoJ19fcHJvdG9fXycgaW4ge30gPyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgZnVuY3Rpb24gKHRlc3QsIGJ1Z2d5LCBzZXQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHNldCA9IHJlcXVpcmUoJy4vX2N0eCcpKEZ1bmN0aW9uLmNhbGwsIHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJykuZihPYmplY3QucHJvdG90eXBlLCAnX19wcm90b19fJykuc2V0LCAyKTtcbiAgICAgICAgc2V0KHRlc3QsIFtdKTtcbiAgICAgICAgYnVnZ3kgPSAhKHRlc3QgaW5zdGFuY2VvZiBBcnJheSk7XG4gICAgICB9IGNhdGNoIChlKSB7IGJ1Z2d5ID0gdHJ1ZTsgfVxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHNldFByb3RvdHlwZU9mKE8sIHByb3RvKSB7XG4gICAgICAgIGNoZWNrKE8sIHByb3RvKTtcbiAgICAgICAgaWYgKGJ1Z2d5KSBPLl9fcHJvdG9fXyA9IHByb3RvO1xuICAgICAgICBlbHNlIHNldChPLCBwcm90byk7XG4gICAgICAgIHJldHVybiBPO1xuICAgICAgfTtcbiAgICB9KHt9LCBmYWxzZSkgOiB1bmRlZmluZWQpLFxuICBjaGVjazogY2hlY2tcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgU1BFQ0lFUyA9IHJlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSkge1xuICB2YXIgQyA9IGdsb2JhbFtLRVldO1xuICBpZiAoREVTQ1JJUFRPUlMgJiYgQyAmJiAhQ1tTUEVDSUVTXSkgZFAuZihDLCBTUEVDSUVTLCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfVxuICB9KTtcbn07XG4iLCJ2YXIgZGVmID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBUQUcgPSByZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQsIHRhZywgc3RhdCkge1xuICBpZiAoaXQgJiYgIWhhcyhpdCA9IHN0YXQgPyBpdCA6IGl0LnByb3RvdHlwZSwgVEFHKSkgZGVmKGl0LCBUQUcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnIH0pO1xufTtcbiIsInZhciBzaGFyZWQgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgna2V5cycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIHJldHVybiBzaGFyZWRba2V5XSB8fCAoc2hhcmVkW2tleV0gPSB1aWQoa2V5KSk7XG59O1xuIiwidmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgU0hBUkVEID0gJ19fY29yZS1qc19zaGFyZWRfXyc7XG52YXIgc3RvcmUgPSBnbG9iYWxbU0hBUkVEXSB8fCAoZ2xvYmFsW1NIQVJFRF0gPSB7fSk7XG5cbihtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIHJldHVybiBzdG9yZVtrZXldIHx8IChzdG9yZVtrZXldID0gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoge30pO1xufSkoJ3ZlcnNpb25zJywgW10pLnB1c2goe1xuICB2ZXJzaW9uOiBjb3JlLnZlcnNpb24sXG4gIG1vZGU6IHJlcXVpcmUoJy4vX2xpYnJhcnknKSA/ICdwdXJlJyA6ICdnbG9iYWwnLFxuICBjb3B5cmlnaHQ6ICfCqSAyMDE5IERlbmlzIFB1c2hrYXJldiAoemxvaXJvY2sucnUpJ1xufSk7XG4iLCIvLyA3LjMuMjAgU3BlY2llc0NvbnN0cnVjdG9yKE8sIGRlZmF1bHRDb25zdHJ1Y3RvcilcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE8sIEQpIHtcbiAgdmFyIEMgPSBhbk9iamVjdChPKS5jb25zdHJ1Y3RvcjtcbiAgdmFyIFM7XG4gIHJldHVybiBDID09PSB1bmRlZmluZWQgfHwgKFMgPSBhbk9iamVjdChDKVtTUEVDSUVTXSkgPT0gdW5kZWZpbmVkID8gRCA6IGFGdW5jdGlvbihTKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChtZXRob2QsIGFyZykge1xuICByZXR1cm4gISFtZXRob2QgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2VsZXNzLWNhbGxcbiAgICBhcmcgPyBtZXRob2QuY2FsbChudWxsLCBmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0sIDEpIDogbWV0aG9kLmNhbGwobnVsbCk7XG4gIH0pO1xufTtcbiIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbi8vIHRydWUgIC0+IFN0cmluZyNhdFxuLy8gZmFsc2UgLT4gU3RyaW5nI2NvZGVQb2ludEF0XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChUT19TVFJJTkcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0aGF0LCBwb3MpIHtcbiAgICB2YXIgcyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbiAgICB2YXIgaSA9IHRvSW50ZWdlcihwb3MpO1xuICAgIHZhciBsID0gcy5sZW5ndGg7XG4gICAgdmFyIGEsIGI7XG4gICAgaWYgKGkgPCAwIHx8IGkgPj0gbCkgcmV0dXJuIFRPX1NUUklORyA/ICcnIDogdW5kZWZpbmVkO1xuICAgIGEgPSBzLmNoYXJDb2RlQXQoaSk7XG4gICAgcmV0dXJuIGEgPCAweGQ4MDAgfHwgYSA+IDB4ZGJmZiB8fCBpICsgMSA9PT0gbCB8fCAoYiA9IHMuY2hhckNvZGVBdChpICsgMSkpIDwgMHhkYzAwIHx8IGIgPiAweGRmZmZcbiAgICAgID8gVE9fU1RSSU5HID8gcy5jaGFyQXQoaSkgOiBhXG4gICAgICA6IFRPX1NUUklORyA/IHMuc2xpY2UoaSwgaSArIDIpIDogKGEgLSAweGQ4MDAgPDwgMTApICsgKGIgLSAweGRjMDApICsgMHgxMDAwMDtcbiAgfTtcbn07XG4iLCIvLyBoZWxwZXIgZm9yIFN0cmluZyN7c3RhcnRzV2l0aCwgZW5kc1dpdGgsIGluY2x1ZGVzfVxudmFyIGlzUmVnRXhwID0gcmVxdWlyZSgnLi9faXMtcmVnZXhwJyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgc2VhcmNoU3RyaW5nLCBOQU1FKSB7XG4gIGlmIChpc1JlZ0V4cChzZWFyY2hTdHJpbmcpKSB0aHJvdyBUeXBlRXJyb3IoJ1N0cmluZyMnICsgTkFNRSArIFwiIGRvZXNuJ3QgYWNjZXB0IHJlZ2V4IVwiKTtcbiAgcmV0dXJuIFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbn07XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIHF1b3QgPSAvXCIvZztcbi8vIEIuMi4zLjIuMSBDcmVhdGVIVE1MKHN0cmluZywgdGFnLCBhdHRyaWJ1dGUsIHZhbHVlKVxudmFyIGNyZWF0ZUhUTUwgPSBmdW5jdGlvbiAoc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgdmFyIFMgPSBTdHJpbmcoZGVmaW5lZChzdHJpbmcpKTtcbiAgdmFyIHAxID0gJzwnICsgdGFnO1xuICBpZiAoYXR0cmlidXRlICE9PSAnJykgcDEgKz0gJyAnICsgYXR0cmlidXRlICsgJz1cIicgKyBTdHJpbmcodmFsdWUpLnJlcGxhY2UocXVvdCwgJyZxdW90OycpICsgJ1wiJztcbiAgcmV0dXJuIHAxICsgJz4nICsgUyArICc8LycgKyB0YWcgKyAnPic7XG59O1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTkFNRSwgZXhlYykge1xuICB2YXIgTyA9IHt9O1xuICBPW05BTUVdID0gZXhlYyhjcmVhdGVIVE1MKTtcbiAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRlc3QgPSAnJ1tOQU1FXSgnXCInKTtcbiAgICByZXR1cm4gdGVzdCAhPT0gdGVzdC50b0xvd2VyQ2FzZSgpIHx8IHRlc3Quc3BsaXQoJ1wiJykubGVuZ3RoID4gMztcbiAgfSksICdTdHJpbmcnLCBPKTtcbn07XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgcmVwZWF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoYXQsIG1heExlbmd0aCwgZmlsbFN0cmluZywgbGVmdCkge1xuICB2YXIgUyA9IFN0cmluZyhkZWZpbmVkKHRoYXQpKTtcbiAgdmFyIHN0cmluZ0xlbmd0aCA9IFMubGVuZ3RoO1xuICB2YXIgZmlsbFN0ciA9IGZpbGxTdHJpbmcgPT09IHVuZGVmaW5lZCA/ICcgJyA6IFN0cmluZyhmaWxsU3RyaW5nKTtcbiAgdmFyIGludE1heExlbmd0aCA9IHRvTGVuZ3RoKG1heExlbmd0aCk7XG4gIGlmIChpbnRNYXhMZW5ndGggPD0gc3RyaW5nTGVuZ3RoIHx8IGZpbGxTdHIgPT0gJycpIHJldHVybiBTO1xuICB2YXIgZmlsbExlbiA9IGludE1heExlbmd0aCAtIHN0cmluZ0xlbmd0aDtcbiAgdmFyIHN0cmluZ0ZpbGxlciA9IHJlcGVhdC5jYWxsKGZpbGxTdHIsIE1hdGguY2VpbChmaWxsTGVuIC8gZmlsbFN0ci5sZW5ndGgpKTtcbiAgaWYgKHN0cmluZ0ZpbGxlci5sZW5ndGggPiBmaWxsTGVuKSBzdHJpbmdGaWxsZXIgPSBzdHJpbmdGaWxsZXIuc2xpY2UoMCwgZmlsbExlbik7XG4gIHJldHVybiBsZWZ0ID8gc3RyaW5nRmlsbGVyICsgUyA6IFMgKyBzdHJpbmdGaWxsZXI7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHJlcGVhdChjb3VudCkge1xuICB2YXIgc3RyID0gU3RyaW5nKGRlZmluZWQodGhpcykpO1xuICB2YXIgcmVzID0gJyc7XG4gIHZhciBuID0gdG9JbnRlZ2VyKGNvdW50KTtcbiAgaWYgKG4gPCAwIHx8IG4gPT0gSW5maW5pdHkpIHRocm93IFJhbmdlRXJyb3IoXCJDb3VudCBjYW4ndCBiZSBuZWdhdGl2ZVwiKTtcbiAgZm9yICg7biA+IDA7IChuID4+Pj0gMSkgJiYgKHN0ciArPSBzdHIpKSBpZiAobiAmIDEpIHJlcyArPSBzdHI7XG4gIHJldHVybiByZXM7XG59O1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBzcGFjZXMgPSByZXF1aXJlKCcuL19zdHJpbmctd3MnKTtcbnZhciBzcGFjZSA9ICdbJyArIHNwYWNlcyArICddJztcbnZhciBub24gPSAnXFx1MjAwYlxcdTAwODUnO1xudmFyIGx0cmltID0gUmVnRXhwKCdeJyArIHNwYWNlICsgc3BhY2UgKyAnKicpO1xudmFyIHJ0cmltID0gUmVnRXhwKHNwYWNlICsgc3BhY2UgKyAnKiQnKTtcblxudmFyIGV4cG9ydGVyID0gZnVuY3Rpb24gKEtFWSwgZXhlYywgQUxJQVMpIHtcbiAgdmFyIGV4cCA9IHt9O1xuICB2YXIgRk9SQ0UgPSBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhc3BhY2VzW0tFWV0oKSB8fCBub25bS0VZXSgpICE9IG5vbjtcbiAgfSk7XG4gIHZhciBmbiA9IGV4cFtLRVldID0gRk9SQ0UgPyBleGVjKHRyaW0pIDogc3BhY2VzW0tFWV07XG4gIGlmIChBTElBUykgZXhwW0FMSUFTXSA9IGZuO1xuICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIEZPUkNFLCAnU3RyaW5nJywgZXhwKTtcbn07XG5cbi8vIDEgLT4gU3RyaW5nI3RyaW1MZWZ0XG4vLyAyIC0+IFN0cmluZyN0cmltUmlnaHRcbi8vIDMgLT4gU3RyaW5nI3RyaW1cbnZhciB0cmltID0gZXhwb3J0ZXIudHJpbSA9IGZ1bmN0aW9uIChzdHJpbmcsIFRZUEUpIHtcbiAgc3RyaW5nID0gU3RyaW5nKGRlZmluZWQoc3RyaW5nKSk7XG4gIGlmIChUWVBFICYgMSkgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UobHRyaW0sICcnKTtcbiAgaWYgKFRZUEUgJiAyKSBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShydHJpbSwgJycpO1xuICByZXR1cm4gc3RyaW5nO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRlcjtcbiIsIm1vZHVsZS5leHBvcnRzID0gJ1xceDA5XFx4MEFcXHgwQlxceDBDXFx4MERcXHgyMFxceEEwXFx1MTY4MFxcdTE4MEVcXHUyMDAwXFx1MjAwMVxcdTIwMDJcXHUyMDAzJyArXG4gICdcXHUyMDA0XFx1MjAwNVxcdTIwMDZcXHUyMDA3XFx1MjAwOFxcdTIwMDlcXHUyMDBBXFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1MjAyOFxcdTIwMjlcXHVGRUZGJztcbiIsInZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBpbnZva2UgPSByZXF1aXJlKCcuL19pbnZva2UnKTtcbnZhciBodG1sID0gcmVxdWlyZSgnLi9faHRtbCcpO1xudmFyIGNlbCA9IHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKTtcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgc2V0VGFzayA9IGdsb2JhbC5zZXRJbW1lZGlhdGU7XG52YXIgY2xlYXJUYXNrID0gZ2xvYmFsLmNsZWFySW1tZWRpYXRlO1xudmFyIE1lc3NhZ2VDaGFubmVsID0gZ2xvYmFsLk1lc3NhZ2VDaGFubmVsO1xudmFyIERpc3BhdGNoID0gZ2xvYmFsLkRpc3BhdGNoO1xudmFyIGNvdW50ZXIgPSAwO1xudmFyIHF1ZXVlID0ge307XG52YXIgT05SRUFEWVNUQVRFQ0hBTkdFID0gJ29ucmVhZHlzdGF0ZWNoYW5nZSc7XG52YXIgZGVmZXIsIGNoYW5uZWwsIHBvcnQ7XG52YXIgcnVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaWQgPSArdGhpcztcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvdHlwZS1idWlsdGluc1xuICBpZiAocXVldWUuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgdmFyIGZuID0gcXVldWVbaWRdO1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gICAgZm4oKTtcbiAgfVxufTtcbnZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudCkge1xuICBydW4uY2FsbChldmVudC5kYXRhKTtcbn07XG4vLyBOb2RlLmpzIDAuOSsgJiBJRTEwKyBoYXMgc2V0SW1tZWRpYXRlLCBvdGhlcndpc2U6XG5pZiAoIXNldFRhc2sgfHwgIWNsZWFyVGFzaykge1xuICBzZXRUYXNrID0gZnVuY3Rpb24gc2V0SW1tZWRpYXRlKGZuKSB7XG4gICAgdmFyIGFyZ3MgPSBbXTtcbiAgICB2YXIgaSA9IDE7XG4gICAgd2hpbGUgKGFyZ3VtZW50cy5sZW5ndGggPiBpKSBhcmdzLnB1c2goYXJndW1lbnRzW2krK10pO1xuICAgIHF1ZXVlWysrY291bnRlcl0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcbiAgICAgIGludm9rZSh0eXBlb2YgZm4gPT0gJ2Z1bmN0aW9uJyA/IGZuIDogRnVuY3Rpb24oZm4pLCBhcmdzKTtcbiAgICB9O1xuICAgIGRlZmVyKGNvdW50ZXIpO1xuICAgIHJldHVybiBjb3VudGVyO1xuICB9O1xuICBjbGVhclRhc2sgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCkge1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gIH07XG4gIC8vIE5vZGUuanMgMC44LVxuICBpZiAocmVxdWlyZSgnLi9fY29mJykocHJvY2VzcykgPT0gJ3Byb2Nlc3MnKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBTcGhlcmUgKEpTIGdhbWUgZW5naW5lKSBEaXNwYXRjaCBBUElcbiAgfSBlbHNlIGlmIChEaXNwYXRjaCAmJiBEaXNwYXRjaC5ub3cpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgRGlzcGF0Y2gubm93KGN0eChydW4sIGlkLCAxKSk7XG4gICAgfTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBNZXNzYWdlQ2hhbm5lbCwgaW5jbHVkZXMgV2ViV29ya2Vyc1xuICB9IGVsc2UgaWYgKE1lc3NhZ2VDaGFubmVsKSB7XG4gICAgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHBvcnQgPSBjaGFubmVsLnBvcnQyO1xuICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gbGlzdGVuZXI7XG4gICAgZGVmZXIgPSBjdHgocG9ydC5wb3N0TWVzc2FnZSwgcG9ydCwgMSk7XG4gIC8vIEJyb3dzZXJzIHdpdGggcG9zdE1lc3NhZ2UsIHNraXAgV2ViV29ya2Vyc1xuICAvLyBJRTggaGFzIHBvc3RNZXNzYWdlLCBidXQgaXQncyBzeW5jICYgdHlwZW9mIGl0cyBwb3N0TWVzc2FnZSBpcyAnb2JqZWN0J1xuICB9IGVsc2UgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyICYmIHR5cGVvZiBwb3N0TWVzc2FnZSA9PSAnZnVuY3Rpb24nICYmICFnbG9iYWwuaW1wb3J0U2NyaXB0cykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBnbG9iYWwucG9zdE1lc3NhZ2UoaWQgKyAnJywgJyonKTtcbiAgICB9O1xuICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIsIGZhbHNlKTtcbiAgLy8gSUU4LVxuICB9IGVsc2UgaWYgKE9OUkVBRFlTVEFURUNIQU5HRSBpbiBjZWwoJ3NjcmlwdCcpKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoY2VsKCdzY3JpcHQnKSlbT05SRUFEWVNUQVRFQ0hBTkdFXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaHRtbC5yZW1vdmVDaGlsZCh0aGlzKTtcbiAgICAgICAgcnVuLmNhbGwoaWQpO1xuICAgICAgfTtcbiAgICB9O1xuICAvLyBSZXN0IG9sZCBicm93c2Vyc1xuICB9IGVsc2Uge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBzZXRUaW1lb3V0KGN0eChydW4sIGlkLCAxKSwgMCk7XG4gICAgfTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogc2V0VGFzayxcbiAgY2xlYXI6IGNsZWFyVGFza1xufTtcbiIsInZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgbWluID0gTWF0aC5taW47XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpbmRleCwgbGVuZ3RoKSB7XG4gIGluZGV4ID0gdG9JbnRlZ2VyKGluZGV4KTtcbiAgcmV0dXJuIGluZGV4IDwgMCA/IG1heChpbmRleCArIGxlbmd0aCwgMCkgOiBtaW4oaW5kZXgsIGxlbmd0aCk7XG59O1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtdG9pbmRleFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09PSB1bmRlZmluZWQpIHJldHVybiAwO1xuICB2YXIgbnVtYmVyID0gdG9JbnRlZ2VyKGl0KTtcbiAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKG51bWJlcik7XG4gIGlmIChudW1iZXIgIT09IGxlbmd0aCkgdGhyb3cgUmFuZ2VFcnJvcignV3JvbmcgbGVuZ3RoIScpO1xuICByZXR1cm4gbGVuZ3RoO1xufTtcbiIsIi8vIDcuMS40IFRvSW50ZWdlclxudmFyIGNlaWwgPSBNYXRoLmNlaWw7XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGlzTmFOKGl0ID0gK2l0KSA/IDAgOiAoaXQgPiAwID8gZmxvb3IgOiBjZWlsKShpdCk7XG59O1xuIiwiLy8gdG8gaW5kZXhlZCBvYmplY3QsIHRvT2JqZWN0IHdpdGggZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBzdHJpbmdzXG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcbiIsIi8vIDcuMS4xNSBUb0xlbmd0aFxudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCA+IDAgPyBtaW4odG9JbnRlZ2VyKGl0KSwgMHgxZmZmZmZmZmZmZmZmZikgOiAwOyAvLyBwb3coMiwgNTMpIC0gMSA9PSA5MDA3MTk5MjU0NzQwOTkxXG59O1xuIiwiLy8gNy4xLjEzIFRvT2JqZWN0KGFyZ3VtZW50KVxudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gT2JqZWN0KGRlZmluZWQoaXQpKTtcbn07XG4iLCIvLyA3LjEuMSBUb1ByaW1pdGl2ZShpbnB1dCBbLCBQcmVmZXJyZWRUeXBlXSlcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuLy8gaW5zdGVhZCBvZiB0aGUgRVM2IHNwZWMgdmVyc2lvbiwgd2UgZGlkbid0IGltcGxlbWVudCBAQHRvUHJpbWl0aXZlIGNhc2Vcbi8vIGFuZCB0aGUgc2Vjb25kIGFyZ3VtZW50IC0gZmxhZyAtIHByZWZlcnJlZCB0eXBlIGlzIGEgc3RyaW5nXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgUykge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkgcmV0dXJuIGl0O1xuICB2YXIgZm4sIHZhbDtcbiAgaWYgKFMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIGlmICh0eXBlb2YgKGZuID0gaXQudmFsdWVPZikgPT0gJ2Z1bmN0aW9uJyAmJiAhaXNPYmplY3QodmFsID0gZm4uY2FsbChpdCkpKSByZXR1cm4gdmFsO1xuICBpZiAoIVMgJiYgdHlwZW9mIChmbiA9IGl0LnRvU3RyaW5nKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIHRocm93IFR5cGVFcnJvcihcIkNhbid0IGNvbnZlcnQgb2JqZWN0IHRvIHByaW1pdGl2ZSB2YWx1ZVwiKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5pZiAocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSkge1xuICB2YXIgTElCUkFSWSA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKTtcbiAgdmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xuICB2YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xuICB2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuICB2YXIgJHR5cGVkID0gcmVxdWlyZSgnLi9fdHlwZWQnKTtcbiAgdmFyICRidWZmZXIgPSByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKTtcbiAgdmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xuICB2YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG4gIHZhciBwcm9wZXJ0eURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG4gIHZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xuICB2YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbiAgdmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbiAgdmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG4gIHZhciB0b0luZGV4ID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbiAgdmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG4gIHZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuICB2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG4gIHZhciBjbGFzc29mID0gcmVxdWlyZSgnLi9fY2xhc3NvZicpO1xuICB2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbiAgdmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG4gIHZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbiAgdmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbiAgdmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xuICB2YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbiAgdmFyIGdldEl0ZXJGbiA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJyk7XG4gIHZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbiAgdmFyIHdrcyA9IHJlcXVpcmUoJy4vX3drcycpO1xuICB2YXIgY3JlYXRlQXJyYXlNZXRob2QgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJyk7XG4gIHZhciBjcmVhdGVBcnJheUluY2x1ZGVzID0gcmVxdWlyZSgnLi9fYXJyYXktaW5jbHVkZXMnKTtcbiAgdmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKTtcbiAgdmFyIEFycmF5SXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbiAgdmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xuICB2YXIgJGl0ZXJEZXRlY3QgPSByZXF1aXJlKCcuL19pdGVyLWRldGVjdCcpO1xuICB2YXIgc2V0U3BlY2llcyA9IHJlcXVpcmUoJy4vX3NldC1zcGVjaWVzJyk7XG4gIHZhciBhcnJheUZpbGwgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJyk7XG4gIHZhciBhcnJheUNvcHlXaXRoaW4gPSByZXF1aXJlKCcuL19hcnJheS1jb3B5LXdpdGhpbicpO1xuICB2YXIgJERQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG4gIHZhciAkR09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG4gIHZhciBkUCA9ICREUC5mO1xuICB2YXIgZ09QRCA9ICRHT1BELmY7XG4gIHZhciBSYW5nZUVycm9yID0gZ2xvYmFsLlJhbmdlRXJyb3I7XG4gIHZhciBUeXBlRXJyb3IgPSBnbG9iYWwuVHlwZUVycm9yO1xuICB2YXIgVWludDhBcnJheSA9IGdsb2JhbC5VaW50OEFycmF5O1xuICB2YXIgQVJSQVlfQlVGRkVSID0gJ0FycmF5QnVmZmVyJztcbiAgdmFyIFNIQVJFRF9CVUZGRVIgPSAnU2hhcmVkJyArIEFSUkFZX0JVRkZFUjtcbiAgdmFyIEJZVEVTX1BFUl9FTEVNRU5UID0gJ0JZVEVTX1BFUl9FTEVNRU5UJztcbiAgdmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuICB2YXIgQXJyYXlQcm90byA9IEFycmF5W1BST1RPVFlQRV07XG4gIHZhciAkQXJyYXlCdWZmZXIgPSAkYnVmZmVyLkFycmF5QnVmZmVyO1xuICB2YXIgJERhdGFWaWV3ID0gJGJ1ZmZlci5EYXRhVmlldztcbiAgdmFyIGFycmF5Rm9yRWFjaCA9IGNyZWF0ZUFycmF5TWV0aG9kKDApO1xuICB2YXIgYXJyYXlGaWx0ZXIgPSBjcmVhdGVBcnJheU1ldGhvZCgyKTtcbiAgdmFyIGFycmF5U29tZSA9IGNyZWF0ZUFycmF5TWV0aG9kKDMpO1xuICB2YXIgYXJyYXlFdmVyeSA9IGNyZWF0ZUFycmF5TWV0aG9kKDQpO1xuICB2YXIgYXJyYXlGaW5kID0gY3JlYXRlQXJyYXlNZXRob2QoNSk7XG4gIHZhciBhcnJheUZpbmRJbmRleCA9IGNyZWF0ZUFycmF5TWV0aG9kKDYpO1xuICB2YXIgYXJyYXlJbmNsdWRlcyA9IGNyZWF0ZUFycmF5SW5jbHVkZXModHJ1ZSk7XG4gIHZhciBhcnJheUluZGV4T2YgPSBjcmVhdGVBcnJheUluY2x1ZGVzKGZhbHNlKTtcbiAgdmFyIGFycmF5VmFsdWVzID0gQXJyYXlJdGVyYXRvcnMudmFsdWVzO1xuICB2YXIgYXJyYXlLZXlzID0gQXJyYXlJdGVyYXRvcnMua2V5cztcbiAgdmFyIGFycmF5RW50cmllcyA9IEFycmF5SXRlcmF0b3JzLmVudHJpZXM7XG4gIHZhciBhcnJheUxhc3RJbmRleE9mID0gQXJyYXlQcm90by5sYXN0SW5kZXhPZjtcbiAgdmFyIGFycmF5UmVkdWNlID0gQXJyYXlQcm90by5yZWR1Y2U7XG4gIHZhciBhcnJheVJlZHVjZVJpZ2h0ID0gQXJyYXlQcm90by5yZWR1Y2VSaWdodDtcbiAgdmFyIGFycmF5Sm9pbiA9IEFycmF5UHJvdG8uam9pbjtcbiAgdmFyIGFycmF5U29ydCA9IEFycmF5UHJvdG8uc29ydDtcbiAgdmFyIGFycmF5U2xpY2UgPSBBcnJheVByb3RvLnNsaWNlO1xuICB2YXIgYXJyYXlUb1N0cmluZyA9IEFycmF5UHJvdG8udG9TdHJpbmc7XG4gIHZhciBhcnJheVRvTG9jYWxlU3RyaW5nID0gQXJyYXlQcm90by50b0xvY2FsZVN0cmluZztcbiAgdmFyIElURVJBVE9SID0gd2tzKCdpdGVyYXRvcicpO1xuICB2YXIgVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xuICB2YXIgVFlQRURfQ09OU1RSVUNUT1IgPSB1aWQoJ3R5cGVkX2NvbnN0cnVjdG9yJyk7XG4gIHZhciBERUZfQ09OU1RSVUNUT1IgPSB1aWQoJ2RlZl9jb25zdHJ1Y3RvcicpO1xuICB2YXIgQUxMX0NPTlNUUlVDVE9SUyA9ICR0eXBlZC5DT05TVFI7XG4gIHZhciBUWVBFRF9BUlJBWSA9ICR0eXBlZC5UWVBFRDtcbiAgdmFyIFZJRVcgPSAkdHlwZWQuVklFVztcbiAgdmFyIFdST05HX0xFTkdUSCA9ICdXcm9uZyBsZW5ndGghJztcblxuICB2YXIgJG1hcCA9IGNyZWF0ZUFycmF5TWV0aG9kKDEsIGZ1bmN0aW9uIChPLCBsZW5ndGgpIHtcbiAgICByZXR1cm4gYWxsb2NhdGUoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxlbmd0aCk7XG4gIH0pO1xuXG4gIHZhciBMSVRUTEVfRU5ESUFOID0gZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlZlxuICAgIHJldHVybiBuZXcgVWludDhBcnJheShuZXcgVWludDE2QXJyYXkoWzFdKS5idWZmZXIpWzBdID09PSAxO1xuICB9KTtcblxuICB2YXIgRk9SQ0VEX1NFVCA9ICEhVWludDhBcnJheSAmJiAhIVVpbnQ4QXJyYXlbUFJPVE9UWVBFXS5zZXQgJiYgZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIG5ldyBVaW50OEFycmF5KDEpLnNldCh7fSk7XG4gIH0pO1xuXG4gIHZhciB0b09mZnNldCA9IGZ1bmN0aW9uIChpdCwgQllURVMpIHtcbiAgICB2YXIgb2Zmc2V0ID0gdG9JbnRlZ2VyKGl0KTtcbiAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgJSBCWVRFUykgdGhyb3cgUmFuZ2VFcnJvcignV3Jvbmcgb2Zmc2V0IScpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH07XG5cbiAgdmFyIHZhbGlkYXRlID0gZnVuY3Rpb24gKGl0KSB7XG4gICAgaWYgKGlzT2JqZWN0KGl0KSAmJiBUWVBFRF9BUlJBWSBpbiBpdCkgcmV0dXJuIGl0O1xuICAgIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgdHlwZWQgYXJyYXkhJyk7XG4gIH07XG5cbiAgdmFyIGFsbG9jYXRlID0gZnVuY3Rpb24gKEMsIGxlbmd0aCkge1xuICAgIGlmICghKGlzT2JqZWN0KEMpICYmIFRZUEVEX0NPTlNUUlVDVE9SIGluIEMpKSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ0l0IGlzIG5vdCBhIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9yIScpO1xuICAgIH0gcmV0dXJuIG5ldyBDKGxlbmd0aCk7XG4gIH07XG5cbiAgdmFyIHNwZWNpZXNGcm9tTGlzdCA9IGZ1bmN0aW9uIChPLCBsaXN0KSB7XG4gICAgcmV0dXJuIGZyb21MaXN0KHNwZWNpZXNDb25zdHJ1Y3RvcihPLCBPW0RFRl9DT05TVFJVQ1RPUl0pLCBsaXN0KTtcbiAgfTtcblxuICB2YXIgZnJvbUxpc3QgPSBmdW5jdGlvbiAoQywgbGlzdCkge1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgdmFyIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICAgIHZhciByZXN1bHQgPSBhbGxvY2F0ZShDLCBsZW5ndGgpO1xuICAgIHdoaWxlIChsZW5ndGggPiBpbmRleCkgcmVzdWx0W2luZGV4XSA9IGxpc3RbaW5kZXgrK107XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgYWRkR2V0dGVyID0gZnVuY3Rpb24gKGl0LCBrZXksIGludGVybmFsKSB7XG4gICAgZFAoaXQsIGtleSwgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMuX2RbaW50ZXJuYWxdOyB9IH0pO1xuICB9O1xuXG4gIHZhciAkZnJvbSA9IGZ1bmN0aW9uIGZyb20oc291cmNlIC8qICwgbWFwZm4sIHRoaXNBcmcgKi8pIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KHNvdXJjZSk7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBtYXBmbiA9IGFMZW4gPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBtYXBwaW5nID0gbWFwZm4gIT09IHVuZGVmaW5lZDtcbiAgICB2YXIgaXRlckZuID0gZ2V0SXRlckZuKE8pO1xuICAgIHZhciBpLCBsZW5ndGgsIHZhbHVlcywgcmVzdWx0LCBzdGVwLCBpdGVyYXRvcjtcbiAgICBpZiAoaXRlckZuICE9IHVuZGVmaW5lZCAmJiAhaXNBcnJheUl0ZXIoaXRlckZuKSkge1xuICAgICAgZm9yIChpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKE8pLCB2YWx1ZXMgPSBbXSwgaSA9IDA7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaSsrKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHN0ZXAudmFsdWUpO1xuICAgICAgfSBPID0gdmFsdWVzO1xuICAgIH1cbiAgICBpZiAobWFwcGluZyAmJiBhTGVuID4gMikgbWFwZm4gPSBjdHgobWFwZm4sIGFyZ3VtZW50c1syXSwgMik7XG4gICAgZm9yIChpID0gMCwgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpLCByZXN1bHQgPSBhbGxvY2F0ZSh0aGlzLCBsZW5ndGgpOyBsZW5ndGggPiBpOyBpKyspIHtcbiAgICAgIHJlc3VsdFtpXSA9IG1hcHBpbmcgPyBtYXBmbihPW2ldLCBpKSA6IE9baV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyICRvZiA9IGZ1bmN0aW9uIG9mKC8qIC4uLml0ZW1zICovKSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgcmVzdWx0ID0gYWxsb2NhdGUodGhpcywgbGVuZ3RoKTtcbiAgICB3aGlsZSAobGVuZ3RoID4gaW5kZXgpIHJlc3VsdFtpbmRleF0gPSBhcmd1bWVudHNbaW5kZXgrK107XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBpT1MgU2FmYXJpIDYueCBmYWlscyBoZXJlXG4gIHZhciBUT19MT0NBTEVfQlVHID0gISFVaW50OEFycmF5ICYmIGZhaWxzKGZ1bmN0aW9uICgpIHsgYXJyYXlUb0xvY2FsZVN0cmluZy5jYWxsKG5ldyBVaW50OEFycmF5KDEpKTsgfSk7XG5cbiAgdmFyICR0b0xvY2FsZVN0cmluZyA9IGZ1bmN0aW9uIHRvTG9jYWxlU3RyaW5nKCkge1xuICAgIHJldHVybiBhcnJheVRvTG9jYWxlU3RyaW5nLmFwcGx5KFRPX0xPQ0FMRV9CVUcgPyBhcnJheVNsaWNlLmNhbGwodmFsaWRhdGUodGhpcykpIDogdmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgdmFyIHByb3RvID0ge1xuICAgIGNvcHlXaXRoaW46IGZ1bmN0aW9uIGNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCAvKiAsIGVuZCAqLykge1xuICAgICAgcmV0dXJuIGFycmF5Q29weVdpdGhpbi5jYWxsKHZhbGlkYXRlKHRoaXMpLCB0YXJnZXQsIHN0YXJ0LCBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUV2ZXJ5KHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBmaWxsOiBmdW5jdGlvbiBmaWxsKHZhbHVlIC8qICwgc3RhcnQsIGVuZCAqLykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4gYXJyYXlGaWxsLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBzcGVjaWVzRnJvbUxpc3QodGhpcywgYXJyYXlGaWx0ZXIodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sXG4gICAgICAgIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKSk7XG4gICAgfSxcbiAgICBmaW5kOiBmdW5jdGlvbiBmaW5kKHByZWRpY2F0ZSAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUZpbmQodmFsaWRhdGUodGhpcyksIHByZWRpY2F0ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgZmluZEluZGV4OiBmdW5jdGlvbiBmaW5kSW5kZXgocHJlZGljYXRlIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIGFycmF5RmluZEluZGV4KHZhbGlkYXRlKHRoaXMpLCBwcmVkaWNhdGUsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIGFycmF5Rm9yRWFjaCh2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgaW5kZXhPZjogZnVuY3Rpb24gaW5kZXhPZihzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlJbmRleE9mKHZhbGlkYXRlKHRoaXMpLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBpbmNsdWRlczogZnVuY3Rpb24gaW5jbHVkZXMoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCAqLykge1xuICAgICAgcmV0dXJuIGFycmF5SW5jbHVkZXModmFsaWRhdGUodGhpcyksIHNlYXJjaEVsZW1lbnQsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUpvaW4uYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBsYXN0SW5kZXhPZjogZnVuY3Rpb24gbGFzdEluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCAqLykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICByZXR1cm4gYXJyYXlMYXN0SW5kZXhPZi5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIG1hcDogZnVuY3Rpb24gbWFwKG1hcGZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuICRtYXAodmFsaWRhdGUodGhpcyksIG1hcGZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICByZWR1Y2U6IGZ1bmN0aW9uIHJlZHVjZShjYWxsYmFja2ZuIC8qICwgaW5pdGlhbFZhbHVlICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZS5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIHJlZHVjZVJpZ2h0OiBmdW5jdGlvbiByZWR1Y2VSaWdodChjYWxsYmFja2ZuIC8qICwgaW5pdGlhbFZhbHVlICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheVJlZHVjZVJpZ2h0LmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgcmV2ZXJzZTogZnVuY3Rpb24gcmV2ZXJzZSgpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICAgIHZhciBsZW5ndGggPSB2YWxpZGF0ZSh0aGF0KS5sZW5ndGg7XG4gICAgICB2YXIgbWlkZGxlID0gTWF0aC5mbG9vcihsZW5ndGggLyAyKTtcbiAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICB3aGlsZSAoaW5kZXggPCBtaWRkbGUpIHtcbiAgICAgICAgdmFsdWUgPSB0aGF0W2luZGV4XTtcbiAgICAgICAgdGhhdFtpbmRleCsrXSA9IHRoYXRbLS1sZW5ndGhdO1xuICAgICAgICB0aGF0W2xlbmd0aF0gPSB2YWx1ZTtcbiAgICAgIH0gcmV0dXJuIHRoYXQ7XG4gICAgfSxcbiAgICBzb21lOiBmdW5jdGlvbiBzb21lKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlTb21lKHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBzb3J0OiBmdW5jdGlvbiBzb3J0KGNvbXBhcmVmbikge1xuICAgICAgcmV0dXJuIGFycmF5U29ydC5jYWxsKHZhbGlkYXRlKHRoaXMpLCBjb21wYXJlZm4pO1xuICAgIH0sXG4gICAgc3ViYXJyYXk6IGZ1bmN0aW9uIHN1YmFycmF5KGJlZ2luLCBlbmQpIHtcbiAgICAgIHZhciBPID0gdmFsaWRhdGUodGhpcyk7XG4gICAgICB2YXIgbGVuZ3RoID0gTy5sZW5ndGg7XG4gICAgICB2YXIgJGJlZ2luID0gdG9BYnNvbHV0ZUluZGV4KGJlZ2luLCBsZW5ndGgpO1xuICAgICAgcmV0dXJuIG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSkpKFxuICAgICAgICBPLmJ1ZmZlcixcbiAgICAgICAgTy5ieXRlT2Zmc2V0ICsgJGJlZ2luICogTy5CWVRFU19QRVJfRUxFTUVOVCxcbiAgICAgICAgdG9MZW5ndGgoKGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuZ3RoIDogdG9BYnNvbHV0ZUluZGV4KGVuZCwgbGVuZ3RoKSkgLSAkYmVnaW4pXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICB2YXIgJHNsaWNlID0gZnVuY3Rpb24gc2xpY2Uoc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiBzcGVjaWVzRnJvbUxpc3QodGhpcywgYXJyYXlTbGljZS5jYWxsKHZhbGlkYXRlKHRoaXMpLCBzdGFydCwgZW5kKSk7XG4gIH07XG5cbiAgdmFyICRzZXQgPSBmdW5jdGlvbiBzZXQoYXJyYXlMaWtlIC8qICwgb2Zmc2V0ICovKSB7XG4gICAgdmFsaWRhdGUodGhpcyk7XG4gICAgdmFyIG9mZnNldCA9IHRvT2Zmc2V0KGFyZ3VtZW50c1sxXSwgMSk7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgIHZhciBzcmMgPSB0b09iamVjdChhcnJheUxpa2UpO1xuICAgIHZhciBsZW4gPSB0b0xlbmd0aChzcmMubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIGlmIChsZW4gKyBvZmZzZXQgPiBsZW5ndGgpIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICB3aGlsZSAoaW5kZXggPCBsZW4pIHRoaXNbb2Zmc2V0ICsgaW5kZXhdID0gc3JjW2luZGV4KytdO1xuICB9O1xuXG4gIHZhciAkaXRlcmF0b3JzID0ge1xuICAgIGVudHJpZXM6IGZ1bmN0aW9uIGVudHJpZXMoKSB7XG4gICAgICByZXR1cm4gYXJyYXlFbnRyaWVzLmNhbGwodmFsaWRhdGUodGhpcykpO1xuICAgIH0sXG4gICAga2V5czogZnVuY3Rpb24ga2V5cygpIHtcbiAgICAgIHJldHVybiBhcnJheUtleXMuY2FsbCh2YWxpZGF0ZSh0aGlzKSk7XG4gICAgfSxcbiAgICB2YWx1ZXM6IGZ1bmN0aW9uIHZhbHVlcygpIHtcbiAgICAgIHJldHVybiBhcnJheVZhbHVlcy5jYWxsKHZhbGlkYXRlKHRoaXMpKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIGlzVEFJbmRleCA9IGZ1bmN0aW9uICh0YXJnZXQsIGtleSkge1xuICAgIHJldHVybiBpc09iamVjdCh0YXJnZXQpXG4gICAgICAmJiB0YXJnZXRbVFlQRURfQVJSQVldXG4gICAgICAmJiB0eXBlb2Yga2V5ICE9ICdzeW1ib2wnXG4gICAgICAmJiBrZXkgaW4gdGFyZ2V0XG4gICAgICAmJiBTdHJpbmcoK2tleSkgPT0gU3RyaW5nKGtleSk7XG4gIH07XG4gIHZhciAkZ2V0RGVzYyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkge1xuICAgIHJldHVybiBpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxuICAgICAgPyBwcm9wZXJ0eURlc2MoMiwgdGFyZ2V0W2tleV0pXG4gICAgICA6IGdPUEQodGFyZ2V0LCBrZXkpO1xuICB9O1xuICB2YXIgJHNldERlc2MgPSBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzYykge1xuICAgIGlmIChpc1RBSW5kZXgodGFyZ2V0LCBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpKVxuICAgICAgJiYgaXNPYmplY3QoZGVzYylcbiAgICAgICYmIGhhcyhkZXNjLCAndmFsdWUnKVxuICAgICAgJiYgIWhhcyhkZXNjLCAnZ2V0JylcbiAgICAgICYmICFoYXMoZGVzYywgJ3NldCcpXG4gICAgICAvLyBUT0RPOiBhZGQgdmFsaWRhdGlvbiBkZXNjcmlwdG9yIHcvbyBjYWxsaW5nIGFjY2Vzc29yc1xuICAgICAgJiYgIWRlc2MuY29uZmlndXJhYmxlXG4gICAgICAmJiAoIWhhcyhkZXNjLCAnd3JpdGFibGUnKSB8fCBkZXNjLndyaXRhYmxlKVxuICAgICAgJiYgKCFoYXMoZGVzYywgJ2VudW1lcmFibGUnKSB8fCBkZXNjLmVudW1lcmFibGUpXG4gICAgKSB7XG4gICAgICB0YXJnZXRba2V5XSA9IGRlc2MudmFsdWU7XG4gICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH0gcmV0dXJuIGRQKHRhcmdldCwga2V5LCBkZXNjKTtcbiAgfTtcblxuICBpZiAoIUFMTF9DT05TVFJVQ1RPUlMpIHtcbiAgICAkR09QRC5mID0gJGdldERlc2M7XG4gICAgJERQLmYgPSAkc2V0RGVzYztcbiAgfVxuXG4gICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIUFMTF9DT05TVFJVQ1RPUlMsICdPYmplY3QnLCB7XG4gICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0RGVzYyxcbiAgICBkZWZpbmVQcm9wZXJ0eTogJHNldERlc2NcbiAgfSk7XG5cbiAgaWYgKGZhaWxzKGZ1bmN0aW9uICgpIHsgYXJyYXlUb1N0cmluZy5jYWxsKHt9KTsgfSkpIHtcbiAgICBhcnJheVRvU3RyaW5nID0gYXJyYXlUb0xvY2FsZVN0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgcmV0dXJuIGFycmF5Sm9pbi5jYWxsKHRoaXMpO1xuICAgIH07XG4gIH1cblxuICB2YXIgJFR5cGVkQXJyYXlQcm90b3R5cGUkID0gcmVkZWZpbmVBbGwoe30sIHByb3RvKTtcbiAgcmVkZWZpbmVBbGwoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAkaXRlcmF0b3JzKTtcbiAgaGlkZSgkVHlwZWRBcnJheVByb3RvdHlwZSQsIElURVJBVE9SLCAkaXRlcmF0b3JzLnZhbHVlcyk7XG4gIHJlZGVmaW5lQWxsKCRUeXBlZEFycmF5UHJvdG90eXBlJCwge1xuICAgIHNsaWNlOiAkc2xpY2UsXG4gICAgc2V0OiAkc2V0LFxuICAgIGNvbnN0cnVjdG9yOiBmdW5jdGlvbiAoKSB7IC8qIG5vb3AgKi8gfSxcbiAgICB0b1N0cmluZzogYXJyYXlUb1N0cmluZyxcbiAgICB0b0xvY2FsZVN0cmluZzogJHRvTG9jYWxlU3RyaW5nXG4gIH0pO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnVmZmVyJywgJ2InKTtcbiAgYWRkR2V0dGVyKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgJ2J5dGVPZmZzZXQnLCAnbycpO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnl0ZUxlbmd0aCcsICdsJyk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdsZW5ndGgnLCAnZScpO1xuICBkUCgkVHlwZWRBcnJheVByb3RvdHlwZSQsIFRBRywge1xuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpc1tUWVBFRF9BUlJBWV07IH1cbiAgfSk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1zdGF0ZW1lbnRzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSwgQllURVMsIHdyYXBwZXIsIENMQU1QRUQpIHtcbiAgICBDTEFNUEVEID0gISFDTEFNUEVEO1xuICAgIHZhciBOQU1FID0gS0VZICsgKENMQU1QRUQgPyAnQ2xhbXBlZCcgOiAnJykgKyAnQXJyYXknO1xuICAgIHZhciBHRVRURVIgPSAnZ2V0JyArIEtFWTtcbiAgICB2YXIgU0VUVEVSID0gJ3NldCcgKyBLRVk7XG4gICAgdmFyIFR5cGVkQXJyYXkgPSBnbG9iYWxbTkFNRV07XG4gICAgdmFyIEJhc2UgPSBUeXBlZEFycmF5IHx8IHt9O1xuICAgIHZhciBUQUMgPSBUeXBlZEFycmF5ICYmIGdldFByb3RvdHlwZU9mKFR5cGVkQXJyYXkpO1xuICAgIHZhciBGT1JDRUQgPSAhVHlwZWRBcnJheSB8fCAhJHR5cGVkLkFCVjtcbiAgICB2YXIgTyA9IHt9O1xuICAgIHZhciBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheSAmJiBUeXBlZEFycmF5W1BST1RPVFlQRV07XG4gICAgdmFyIGdldHRlciA9IGZ1bmN0aW9uICh0aGF0LCBpbmRleCkge1xuICAgICAgdmFyIGRhdGEgPSB0aGF0Ll9kO1xuICAgICAgcmV0dXJuIGRhdGEudltHRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIExJVFRMRV9FTkRJQU4pO1xuICAgIH07XG4gICAgdmFyIHNldHRlciA9IGZ1bmN0aW9uICh0aGF0LCBpbmRleCwgdmFsdWUpIHtcbiAgICAgIHZhciBkYXRhID0gdGhhdC5fZDtcbiAgICAgIGlmIChDTEFNUEVEKSB2YWx1ZSA9ICh2YWx1ZSA9IE1hdGgucm91bmQodmFsdWUpKSA8IDAgPyAwIDogdmFsdWUgPiAweGZmID8gMHhmZiA6IHZhbHVlICYgMHhmZjtcbiAgICAgIGRhdGEudltTRVRURVJdKGluZGV4ICogQllURVMgKyBkYXRhLm8sIHZhbHVlLCBMSVRUTEVfRU5ESUFOKTtcbiAgICB9O1xuICAgIHZhciBhZGRFbGVtZW50ID0gZnVuY3Rpb24gKHRoYXQsIGluZGV4KSB7XG4gICAgICBkUCh0aGF0LCBpbmRleCwge1xuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gZ2V0dGVyKHRoaXMsIGluZGV4KTtcbiAgICAgICAgfSxcbiAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICByZXR1cm4gc2V0dGVyKHRoaXMsIGluZGV4LCB2YWx1ZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgIH07XG4gICAgaWYgKEZPUkNFRCkge1xuICAgICAgVHlwZWRBcnJheSA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGRhdGEsICRvZmZzZXQsICRsZW5ndGgpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGF0LCBUeXBlZEFycmF5LCBOQU1FLCAnX2QnKTtcbiAgICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgIHZhciBidWZmZXIsIGJ5dGVMZW5ndGgsIGxlbmd0aCwga2xhc3M7XG4gICAgICAgIGlmICghaXNPYmplY3QoZGF0YSkpIHtcbiAgICAgICAgICBsZW5ndGggPSB0b0luZGV4KGRhdGEpO1xuICAgICAgICAgIGJ5dGVMZW5ndGggPSBsZW5ndGggKiBCWVRFUztcbiAgICAgICAgICBidWZmZXIgPSBuZXcgJEFycmF5QnVmZmVyKGJ5dGVMZW5ndGgpO1xuICAgICAgICB9IGVsc2UgaWYgKGRhdGEgaW5zdGFuY2VvZiAkQXJyYXlCdWZmZXIgfHwgKGtsYXNzID0gY2xhc3NvZihkYXRhKSkgPT0gQVJSQVlfQlVGRkVSIHx8IGtsYXNzID09IFNIQVJFRF9CVUZGRVIpIHtcbiAgICAgICAgICBidWZmZXIgPSBkYXRhO1xuICAgICAgICAgIG9mZnNldCA9IHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKTtcbiAgICAgICAgICB2YXIgJGxlbiA9IGRhdGEuYnl0ZUxlbmd0aDtcbiAgICAgICAgICBpZiAoJGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoJGxlbiAlIEJZVEVTKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gJGxlbiAtIG9mZnNldDtcbiAgICAgICAgICAgIGlmIChieXRlTGVuZ3RoIDwgMCkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBieXRlTGVuZ3RoID0gdG9MZW5ndGgoJGxlbmd0aCkgKiBCWVRFUztcbiAgICAgICAgICAgIGlmIChieXRlTGVuZ3RoICsgb2Zmc2V0ID4gJGxlbikgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsZW5ndGggPSBieXRlTGVuZ3RoIC8gQllURVM7XG4gICAgICAgIH0gZWxzZSBpZiAoVFlQRURfQVJSQVkgaW4gZGF0YSkge1xuICAgICAgICAgIHJldHVybiBmcm9tTGlzdChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gJGZyb20uY2FsbChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBoaWRlKHRoYXQsICdfZCcsIHtcbiAgICAgICAgICBiOiBidWZmZXIsXG4gICAgICAgICAgbzogb2Zmc2V0LFxuICAgICAgICAgIGw6IGJ5dGVMZW5ndGgsXG4gICAgICAgICAgZTogbGVuZ3RoLFxuICAgICAgICAgIHY6IG5ldyAkRGF0YVZpZXcoYnVmZmVyKVxuICAgICAgICB9KTtcbiAgICAgICAgd2hpbGUgKGluZGV4IDwgbGVuZ3RoKSBhZGRFbGVtZW50KHRoYXQsIGluZGV4KyspO1xuICAgICAgfSk7XG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlID0gVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gY3JlYXRlKCRUeXBlZEFycmF5UHJvdG90eXBlJCk7XG4gICAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsICdjb25zdHJ1Y3RvcicsIFR5cGVkQXJyYXkpO1xuICAgIH0gZWxzZSBpZiAoIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAgIFR5cGVkQXJyYXkoMSk7XG4gICAgfSkgfHwgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5ldyBUeXBlZEFycmF5KC0xKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICB9KSB8fCAhJGl0ZXJEZXRlY3QoZnVuY3Rpb24gKGl0ZXIpIHtcbiAgICAgIG5ldyBUeXBlZEFycmF5KCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgICBuZXcgVHlwZWRBcnJheShudWxsKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KDEuNSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgICBuZXcgVHlwZWRBcnJheShpdGVyKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICB9LCB0cnVlKSkge1xuICAgICAgVHlwZWRBcnJheSA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGRhdGEsICRvZmZzZXQsICRsZW5ndGgpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0aGF0LCBUeXBlZEFycmF5LCBOQU1FKTtcbiAgICAgICAgdmFyIGtsYXNzO1xuICAgICAgICAvLyBgd3NgIG1vZHVsZSBidWcsIHRlbXBvcmFyaWx5IHJlbW92ZSB2YWxpZGF0aW9uIGxlbmd0aCBmb3IgVWludDhBcnJheVxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vd2Vic29ja2V0cy93cy9wdWxsLzY0NVxuICAgICAgICBpZiAoIWlzT2JqZWN0KGRhdGEpKSByZXR1cm4gbmV3IEJhc2UodG9JbmRleChkYXRhKSk7XG4gICAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgJEFycmF5QnVmZmVyIHx8IChrbGFzcyA9IGNsYXNzb2YoZGF0YSkpID09IEFSUkFZX0JVRkZFUiB8fCBrbGFzcyA9PSBTSEFSRURfQlVGRkVSKSB7XG4gICAgICAgICAgcmV0dXJuICRsZW5ndGggIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBuZXcgQmFzZShkYXRhLCB0b09mZnNldCgkb2Zmc2V0LCBCWVRFUyksICRsZW5ndGgpXG4gICAgICAgICAgICA6ICRvZmZzZXQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IG5ldyBCYXNlKGRhdGEsIHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKSlcbiAgICAgICAgICAgICAgOiBuZXcgQmFzZShkYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoVFlQRURfQVJSQVkgaW4gZGF0YSkgcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICByZXR1cm4gJGZyb20uY2FsbChUeXBlZEFycmF5LCBkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgYXJyYXlGb3JFYWNoKFRBQyAhPT0gRnVuY3Rpb24ucHJvdG90eXBlID8gZ09QTihCYXNlKS5jb25jYXQoZ09QTihUQUMpKSA6IGdPUE4oQmFzZSksIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCEoa2V5IGluIFR5cGVkQXJyYXkpKSBoaWRlKFR5cGVkQXJyYXksIGtleSwgQmFzZVtrZXldKTtcbiAgICAgIH0pO1xuICAgICAgVHlwZWRBcnJheVtQUk9UT1RZUEVdID0gVHlwZWRBcnJheVByb3RvdHlwZTtcbiAgICAgIGlmICghTElCUkFSWSkgVHlwZWRBcnJheVByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFR5cGVkQXJyYXk7XG4gICAgfVxuICAgIHZhciAkbmF0aXZlSXRlcmF0b3IgPSBUeXBlZEFycmF5UHJvdG90eXBlW0lURVJBVE9SXTtcbiAgICB2YXIgQ09SUkVDVF9JVEVSX05BTUUgPSAhISRuYXRpdmVJdGVyYXRvclxuICAgICAgJiYgKCRuYXRpdmVJdGVyYXRvci5uYW1lID09ICd2YWx1ZXMnIHx8ICRuYXRpdmVJdGVyYXRvci5uYW1lID09IHVuZGVmaW5lZCk7XG4gICAgdmFyICRpdGVyYXRvciA9ICRpdGVyYXRvcnMudmFsdWVzO1xuICAgIGhpZGUoVHlwZWRBcnJheSwgVFlQRURfQ09OU1RSVUNUT1IsIHRydWUpO1xuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgVFlQRURfQVJSQVksIE5BTUUpO1xuICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgVklFVywgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBERUZfQ09OU1RSVUNUT1IsIFR5cGVkQXJyYXkpO1xuXG4gICAgaWYgKENMQU1QRUQgPyBuZXcgVHlwZWRBcnJheSgxKVtUQUddICE9IE5BTUUgOiAhKFRBRyBpbiBUeXBlZEFycmF5UHJvdG90eXBlKSkge1xuICAgICAgZFAoVHlwZWRBcnJheVByb3RvdHlwZSwgVEFHLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gTkFNRTsgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgT1tOQU1FXSA9IFR5cGVkQXJyYXk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChUeXBlZEFycmF5ICE9IEJhc2UpLCBPKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5TLCBOQU1FLCB7XG4gICAgICBCWVRFU19QRVJfRUxFTUVOVDogQllURVNcbiAgICB9KTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24gKCkgeyBCYXNlLm9mLmNhbGwoVHlwZWRBcnJheSwgMSk7IH0pLCBOQU1FLCB7XG4gICAgICBmcm9tOiAkZnJvbSxcbiAgICAgIG9mOiAkb2ZcbiAgICB9KTtcblxuICAgIGlmICghKEJZVEVTX1BFUl9FTEVNRU5UIGluIFR5cGVkQXJyYXlQcm90b3R5cGUpKSBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIEJZVEVTX1BFUl9FTEVNRU5ULCBCWVRFUyk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCwgTkFNRSwgcHJvdG8pO1xuXG4gICAgc2V0U3BlY2llcyhOQU1FKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogRk9SQ0VEX1NFVCwgTkFNRSwgeyBzZXQ6ICRzZXQgfSk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFDT1JSRUNUX0lURVJfTkFNRSwgTkFNRSwgJGl0ZXJhdG9ycyk7XG5cbiAgICBpZiAoIUxJQlJBUlkgJiYgVHlwZWRBcnJheVByb3RvdHlwZS50b1N0cmluZyAhPSBhcnJheVRvU3RyaW5nKSBUeXBlZEFycmF5UHJvdG90eXBlLnRvU3RyaW5nID0gYXJyYXlUb1N0cmluZztcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFR5cGVkQXJyYXkoMSkuc2xpY2UoKTtcbiAgICB9KSwgTkFNRSwgeyBzbGljZTogJHNsaWNlIH0pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIFsxLCAyXS50b0xvY2FsZVN0cmluZygpICE9IG5ldyBUeXBlZEFycmF5KFsxLCAyXSkudG9Mb2NhbGVTdHJpbmcoKTtcbiAgICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgVHlwZWRBcnJheVByb3RvdHlwZS50b0xvY2FsZVN0cmluZy5jYWxsKFsxLCAyXSk7XG4gICAgfSkpLCBOQU1FLCB7IHRvTG9jYWxlU3RyaW5nOiAkdG9Mb2NhbGVTdHJpbmcgfSk7XG5cbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBDT1JSRUNUX0lURVJfTkFNRSA/ICRuYXRpdmVJdGVyYXRvciA6ICRpdGVyYXRvcjtcbiAgICBpZiAoIUxJQlJBUlkgJiYgIUNPUlJFQ1RfSVRFUl9OQU1FKSBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIElURVJBVE9SLCAkaXRlcmF0b3IpO1xuICB9O1xufSBlbHNlIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICR0eXBlZCA9IHJlcXVpcmUoJy4vX3R5cGVkJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciB0b0luZGV4ID0gcmVxdWlyZSgnLi9fdG8taW5kZXgnKTtcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciBhcnJheUZpbGwgPSByZXF1aXJlKCcuL19hcnJheS1maWxsJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEFSUkFZX0JVRkZFUiA9ICdBcnJheUJ1ZmZlcic7XG52YXIgREFUQV9WSUVXID0gJ0RhdGFWaWV3JztcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcbnZhciBXUk9OR19MRU5HVEggPSAnV3JvbmcgbGVuZ3RoISc7XG52YXIgV1JPTkdfSU5ERVggPSAnV3JvbmcgaW5kZXghJztcbnZhciAkQXJyYXlCdWZmZXIgPSBnbG9iYWxbQVJSQVlfQlVGRkVSXTtcbnZhciAkRGF0YVZpZXcgPSBnbG9iYWxbREFUQV9WSUVXXTtcbnZhciBNYXRoID0gZ2xvYmFsLk1hdGg7XG52YXIgUmFuZ2VFcnJvciA9IGdsb2JhbC5SYW5nZUVycm9yO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNoYWRvdy1yZXN0cmljdGVkLW5hbWVzXG52YXIgSW5maW5pdHkgPSBnbG9iYWwuSW5maW5pdHk7XG52YXIgQmFzZUJ1ZmZlciA9ICRBcnJheUJ1ZmZlcjtcbnZhciBhYnMgPSBNYXRoLmFicztcbnZhciBwb3cgPSBNYXRoLnBvdztcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG52YXIgbG9nID0gTWF0aC5sb2c7XG52YXIgTE4yID0gTWF0aC5MTjI7XG52YXIgQlVGRkVSID0gJ2J1ZmZlcic7XG52YXIgQllURV9MRU5HVEggPSAnYnl0ZUxlbmd0aCc7XG52YXIgQllURV9PRkZTRVQgPSAnYnl0ZU9mZnNldCc7XG52YXIgJEJVRkZFUiA9IERFU0NSSVBUT1JTID8gJ19iJyA6IEJVRkZFUjtcbnZhciAkTEVOR1RIID0gREVTQ1JJUFRPUlMgPyAnX2wnIDogQllURV9MRU5HVEg7XG52YXIgJE9GRlNFVCA9IERFU0NSSVBUT1JTID8gJ19vJyA6IEJZVEVfT0ZGU0VUO1xuXG4vLyBJRUVFNzU0IGNvbnZlcnNpb25zIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvaWVlZTc1NFxuZnVuY3Rpb24gcGFja0lFRUU3NTQodmFsdWUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgYnVmZmVyID0gbmV3IEFycmF5KG5CeXRlcyk7XG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxO1xuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMTtcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxO1xuICB2YXIgcnQgPSBtTGVuID09PSAyMyA/IHBvdygyLCAtMjQpIC0gcG93KDIsIC03NykgOiAwO1xuICB2YXIgaSA9IDA7XG4gIHZhciBzID0gdmFsdWUgPCAwIHx8IHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDAgPyAxIDogMDtcbiAgdmFyIGUsIG0sIGM7XG4gIHZhbHVlID0gYWJzKHZhbHVlKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICBpZiAodmFsdWUgIT0gdmFsdWUgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgIG0gPSB2YWx1ZSAhPSB2YWx1ZSA/IDEgOiAwO1xuICAgIGUgPSBlTWF4O1xuICB9IGVsc2Uge1xuICAgIGUgPSBmbG9vcihsb2codmFsdWUpIC8gTE4yKTtcbiAgICBpZiAodmFsdWUgKiAoYyA9IHBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tO1xuICAgICAgYyAqPSAyO1xuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBwb3coMiwgMSAtIGVCaWFzKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKys7XG4gICAgICBjIC89IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDA7XG4gICAgICBlID0gZU1heDtcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogcG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogcG93KDIsIGVCaWFzIC0gMSkgKiBwb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW2krK10gPSBtICYgMjU1LCBtIC89IDI1NiwgbUxlbiAtPSA4KTtcbiAgZSA9IGUgPDwgbUxlbiB8IG07XG4gIGVMZW4gKz0gbUxlbjtcbiAgZm9yICg7IGVMZW4gPiAwOyBidWZmZXJbaSsrXSA9IGUgJiAyNTUsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xuICBidWZmZXJbLS1pXSB8PSBzICogMTI4O1xuICByZXR1cm4gYnVmZmVyO1xufVxuZnVuY3Rpb24gdW5wYWNrSUVFRTc1NChidWZmZXIsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMTtcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDE7XG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMTtcbiAgdmFyIG5CaXRzID0gZUxlbiAtIDc7XG4gIHZhciBpID0gbkJ5dGVzIC0gMTtcbiAgdmFyIHMgPSBidWZmZXJbaS0tXTtcbiAgdmFyIGUgPSBzICYgMTI3O1xuICB2YXIgbTtcbiAgcyA+Pj0gNztcbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbaV0sIGktLSwgbkJpdHMgLT0gOCk7XG4gIG0gPSBlICYgKDEgPDwgLW5CaXRzKSAtIDE7XG4gIGUgPj49IC1uQml0cztcbiAgbkJpdHMgKz0gbUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IG0gKiAyNTYgKyBidWZmZXJbaV0sIGktLSwgbkJpdHMgLT0gOCk7XG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhcztcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiBzID8gLUluZmluaXR5IDogSW5maW5pdHk7XG4gIH0gZWxzZSB7XG4gICAgbSA9IG0gKyBwb3coMiwgbUxlbik7XG4gICAgZSA9IGUgLSBlQmlhcztcbiAgfSByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIHBvdygyLCBlIC0gbUxlbik7XG59XG5cbmZ1bmN0aW9uIHVucGFja0kzMihieXRlcykge1xuICByZXR1cm4gYnl0ZXNbM10gPDwgMjQgfCBieXRlc1syXSA8PCAxNiB8IGJ5dGVzWzFdIDw8IDggfCBieXRlc1swXTtcbn1cbmZ1bmN0aW9uIHBhY2tJOChpdCkge1xuICByZXR1cm4gW2l0ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrSTE2KGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmLCBpdCA+PiA4ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrSTMyKGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmLCBpdCA+PiA4ICYgMHhmZiwgaXQgPj4gMTYgJiAweGZmLCBpdCA+PiAyNCAmIDB4ZmZdO1xufVxuZnVuY3Rpb24gcGFja0Y2NChpdCkge1xuICByZXR1cm4gcGFja0lFRUU3NTQoaXQsIDUyLCA4KTtcbn1cbmZ1bmN0aW9uIHBhY2tGMzIoaXQpIHtcbiAgcmV0dXJuIHBhY2tJRUVFNzU0KGl0LCAyMywgNCk7XG59XG5cbmZ1bmN0aW9uIGFkZEdldHRlcihDLCBrZXksIGludGVybmFsKSB7XG4gIGRQKENbUFJPVE9UWVBFXSwga2V5LCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpc1tpbnRlcm5hbF07IH0gfSk7XG59XG5cbmZ1bmN0aW9uIGdldCh2aWV3LCBieXRlcywgaW5kZXgsIGlzTGl0dGxlRW5kaWFuKSB7XG4gIHZhciBudW1JbmRleCA9ICtpbmRleDtcbiAgdmFyIGludEluZGV4ID0gdG9JbmRleChudW1JbmRleCk7XG4gIGlmIChpbnRJbmRleCArIGJ5dGVzID4gdmlld1skTEVOR1RIXSkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19JTkRFWCk7XG4gIHZhciBzdG9yZSA9IHZpZXdbJEJVRkZFUl0uX2I7XG4gIHZhciBzdGFydCA9IGludEluZGV4ICsgdmlld1skT0ZGU0VUXTtcbiAgdmFyIHBhY2sgPSBzdG9yZS5zbGljZShzdGFydCwgc3RhcnQgKyBieXRlcyk7XG4gIHJldHVybiBpc0xpdHRsZUVuZGlhbiA/IHBhY2sgOiBwYWNrLnJldmVyc2UoKTtcbn1cbmZ1bmN0aW9uIHNldCh2aWV3LCBieXRlcywgaW5kZXgsIGNvbnZlcnNpb24sIHZhbHVlLCBpc0xpdHRsZUVuZGlhbikge1xuICB2YXIgbnVtSW5kZXggPSAraW5kZXg7XG4gIHZhciBpbnRJbmRleCA9IHRvSW5kZXgobnVtSW5kZXgpO1xuICBpZiAoaW50SW5kZXggKyBieXRlcyA+IHZpZXdbJExFTkdUSF0pIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfSU5ERVgpO1xuICB2YXIgc3RvcmUgPSB2aWV3WyRCVUZGRVJdLl9iO1xuICB2YXIgc3RhcnQgPSBpbnRJbmRleCArIHZpZXdbJE9GRlNFVF07XG4gIHZhciBwYWNrID0gY29udmVyc2lvbigrdmFsdWUpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHN0b3JlW3N0YXJ0ICsgaV0gPSBwYWNrW2lzTGl0dGxlRW5kaWFuID8gaSA6IGJ5dGVzIC0gaSAtIDFdO1xufVxuXG5pZiAoISR0eXBlZC5BQlYpIHtcbiAgJEFycmF5QnVmZmVyID0gZnVuY3Rpb24gQXJyYXlCdWZmZXIobGVuZ3RoKSB7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkQXJyYXlCdWZmZXIsIEFSUkFZX0JVRkZFUik7XG4gICAgdmFyIGJ5dGVMZW5ndGggPSB0b0luZGV4KGxlbmd0aCk7XG4gICAgdGhpcy5fYiA9IGFycmF5RmlsbC5jYWxsKG5ldyBBcnJheShieXRlTGVuZ3RoKSwgMCk7XG4gICAgdGhpc1skTEVOR1RIXSA9IGJ5dGVMZW5ndGg7XG4gIH07XG5cbiAgJERhdGFWaWV3ID0gZnVuY3Rpb24gRGF0YVZpZXcoYnVmZmVyLCBieXRlT2Zmc2V0LCBieXRlTGVuZ3RoKSB7XG4gICAgYW5JbnN0YW5jZSh0aGlzLCAkRGF0YVZpZXcsIERBVEFfVklFVyk7XG4gICAgYW5JbnN0YW5jZShidWZmZXIsICRBcnJheUJ1ZmZlciwgREFUQV9WSUVXKTtcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYnVmZmVyWyRMRU5HVEhdO1xuICAgIHZhciBvZmZzZXQgPSB0b0ludGVnZXIoYnl0ZU9mZnNldCk7XG4gICAgaWYgKG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gYnVmZmVyTGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKCdXcm9uZyBvZmZzZXQhJyk7XG4gICAgYnl0ZUxlbmd0aCA9IGJ5dGVMZW5ndGggPT09IHVuZGVmaW5lZCA/IGJ1ZmZlckxlbmd0aCAtIG9mZnNldCA6IHRvTGVuZ3RoKGJ5dGVMZW5ndGgpO1xuICAgIGlmIChvZmZzZXQgKyBieXRlTGVuZ3RoID4gYnVmZmVyTGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgdGhpc1skQlVGRkVSXSA9IGJ1ZmZlcjtcbiAgICB0aGlzWyRPRkZTRVRdID0gb2Zmc2V0O1xuICAgIHRoaXNbJExFTkdUSF0gPSBieXRlTGVuZ3RoO1xuICB9O1xuXG4gIGlmIChERVNDUklQVE9SUykge1xuICAgIGFkZEdldHRlcigkQXJyYXlCdWZmZXIsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCVUZGRVIsICdfYicpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJZVEVfTEVOR1RILCAnX2wnKTtcbiAgICBhZGRHZXR0ZXIoJERhdGFWaWV3LCBCWVRFX09GRlNFVCwgJ19vJyk7XG4gIH1cblxuICByZWRlZmluZUFsbCgkRGF0YVZpZXdbUFJPVE9UWVBFXSwge1xuICAgIGdldEludDg6IGZ1bmN0aW9uIGdldEludDgoYnl0ZU9mZnNldCkge1xuICAgICAgcmV0dXJuIGdldCh0aGlzLCAxLCBieXRlT2Zmc2V0KVswXSA8PCAyNCA+PiAyNDtcbiAgICB9LFxuICAgIGdldFVpbnQ4OiBmdW5jdGlvbiBnZXRVaW50OChieXRlT2Zmc2V0KSB7XG4gICAgICByZXR1cm4gZ2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQpWzBdO1xuICAgIH0sXG4gICAgZ2V0SW50MTY6IGZ1bmN0aW9uIGdldEludDE2KGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHZhciBieXRlcyA9IGdldCh0aGlzLCAyLCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pO1xuICAgICAgcmV0dXJuIChieXRlc1sxXSA8PCA4IHwgYnl0ZXNbMF0pIDw8IDE2ID4+IDE2O1xuICAgIH0sXG4gICAgZ2V0VWludDE2OiBmdW5jdGlvbiBnZXRVaW50MTYoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgdmFyIGJ5dGVzID0gZ2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSk7XG4gICAgICByZXR1cm4gYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xuICAgIH0sXG4gICAgZ2V0SW50MzI6IGZ1bmN0aW9uIGdldEludDMyKGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJMzIoZ2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSkpO1xuICAgIH0sXG4gICAgZ2V0VWludDMyOiBmdW5jdGlvbiBnZXRVaW50MzIoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0kzMihnZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKSkgPj4+IDA7XG4gICAgfSxcbiAgICBnZXRGbG9hdDMyOiBmdW5jdGlvbiBnZXRGbG9hdDMyKGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCAyMywgNCk7XG4gICAgfSxcbiAgICBnZXRGbG9hdDY0OiBmdW5jdGlvbiBnZXRGbG9hdDY0KGJ5dGVPZmZzZXQgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHJldHVybiB1bnBhY2tJRUVFNzU0KGdldCh0aGlzLCA4LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pLCA1MiwgOCk7XG4gICAgfSxcbiAgICBzZXRJbnQ4OiBmdW5jdGlvbiBzZXRJbnQ4KGJ5dGVPZmZzZXQsIHZhbHVlKSB7XG4gICAgICBzZXQodGhpcywgMSwgYnl0ZU9mZnNldCwgcGFja0k4LCB2YWx1ZSk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgIHNldCh0aGlzLCAxLCBieXRlT2Zmc2V0LCBwYWNrSTgsIHZhbHVlKTtcbiAgICB9LFxuICAgIHNldEludDE2OiBmdW5jdGlvbiBzZXRJbnQxNihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIHBhY2tJMTYsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0VWludDE2OiBmdW5jdGlvbiBzZXRVaW50MTYoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCAyLCBieXRlT2Zmc2V0LCBwYWNrSTE2LCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEludDMyOiBmdW5jdGlvbiBzZXRJbnQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIHBhY2tJMzIsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0VWludDMyOiBmdW5jdGlvbiBzZXRVaW50MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrSTMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEZsb2F0MzI6IGZ1bmN0aW9uIHNldEZsb2F0MzIoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBwYWNrRjMyLCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9LFxuICAgIHNldEZsb2F0NjQ6IGZ1bmN0aW9uIHNldEZsb2F0NjQoYnl0ZU9mZnNldCwgdmFsdWUgLyogLCBsaXR0bGVFbmRpYW4gKi8pIHtcbiAgICAgIHNldCh0aGlzLCA4LCBieXRlT2Zmc2V0LCBwYWNrRjY0LCB2YWx1ZSwgYXJndW1lbnRzWzJdKTtcbiAgICB9XG4gIH0pO1xufSBlbHNlIHtcbiAgaWYgKCFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgJEFycmF5QnVmZmVyKDEpO1xuICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoLTEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICB9KSB8fCBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3ICRBcnJheUJ1ZmZlcigpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoMS41KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICBuZXcgJEFycmF5QnVmZmVyKE5hTik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgcmV0dXJuICRBcnJheUJ1ZmZlci5uYW1lICE9IEFSUkFZX0JVRkZFUjtcbiAgfSkpIHtcbiAgICAkQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhpcywgJEFycmF5QnVmZmVyKTtcbiAgICAgIHJldHVybiBuZXcgQmFzZUJ1ZmZlcih0b0luZGV4KGxlbmd0aCkpO1xuICAgIH07XG4gICAgdmFyIEFycmF5QnVmZmVyUHJvdG8gPSAkQXJyYXlCdWZmZXJbUFJPVE9UWVBFXSA9IEJhc2VCdWZmZXJbUFJPVE9UWVBFXTtcbiAgICBmb3IgKHZhciBrZXlzID0gZ09QTihCYXNlQnVmZmVyKSwgaiA9IDAsIGtleTsga2V5cy5sZW5ndGggPiBqOykge1xuICAgICAgaWYgKCEoKGtleSA9IGtleXNbaisrXSkgaW4gJEFycmF5QnVmZmVyKSkgaGlkZSgkQXJyYXlCdWZmZXIsIGtleSwgQmFzZUJ1ZmZlcltrZXldKTtcbiAgICB9XG4gICAgaWYgKCFMSUJSQVJZKSBBcnJheUJ1ZmZlclByb3RvLmNvbnN0cnVjdG9yID0gJEFycmF5QnVmZmVyO1xuICB9XG4gIC8vIGlPUyBTYWZhcmkgNy54IGJ1Z1xuICB2YXIgdmlldyA9IG5ldyAkRGF0YVZpZXcobmV3ICRBcnJheUJ1ZmZlcigyKSk7XG4gIHZhciAkc2V0SW50OCA9ICREYXRhVmlld1tQUk9UT1RZUEVdLnNldEludDg7XG4gIHZpZXcuc2V0SW50OCgwLCAyMTQ3NDgzNjQ4KTtcbiAgdmlldy5zZXRJbnQ4KDEsIDIxNDc0ODM2NDkpO1xuICBpZiAodmlldy5nZXRJbnQ4KDApIHx8ICF2aWV3LmdldEludDgoMSkpIHJlZGVmaW5lQWxsKCREYXRhVmlld1tQUk9UT1RZUEVdLCB7XG4gICAgc2V0SW50ODogZnVuY3Rpb24gc2V0SW50OChieXRlT2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgJHNldEludDguY2FsbCh0aGlzLCBieXRlT2Zmc2V0LCB2YWx1ZSA8PCAyNCA+PiAyNCk7XG4gICAgfSxcbiAgICBzZXRVaW50ODogZnVuY3Rpb24gc2V0VWludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgICRzZXRJbnQ4LmNhbGwodGhpcywgYnl0ZU9mZnNldCwgdmFsdWUgPDwgMjQgPj4gMjQpO1xuICAgIH1cbiAgfSwgdHJ1ZSk7XG59XG5zZXRUb1N0cmluZ1RhZygkQXJyYXlCdWZmZXIsIEFSUkFZX0JVRkZFUik7XG5zZXRUb1N0cmluZ1RhZygkRGF0YVZpZXcsIERBVEFfVklFVyk7XG5oaWRlKCREYXRhVmlld1tQUk9UT1RZUEVdLCAkdHlwZWQuVklFVywgdHJ1ZSk7XG5leHBvcnRzW0FSUkFZX0JVRkZFUl0gPSAkQXJyYXlCdWZmZXI7XG5leHBvcnRzW0RBVEFfVklFV10gPSAkRGF0YVZpZXc7XG4iLCJ2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciBUWVBFRCA9IHVpZCgndHlwZWRfYXJyYXknKTtcbnZhciBWSUVXID0gdWlkKCd2aWV3Jyk7XG52YXIgQUJWID0gISEoZ2xvYmFsLkFycmF5QnVmZmVyICYmIGdsb2JhbC5EYXRhVmlldyk7XG52YXIgQ09OU1RSID0gQUJWO1xudmFyIGkgPSAwO1xudmFyIGwgPSA5O1xudmFyIFR5cGVkO1xuXG52YXIgVHlwZWRBcnJheUNvbnN0cnVjdG9ycyA9IChcbiAgJ0ludDhBcnJheSxVaW50OEFycmF5LFVpbnQ4Q2xhbXBlZEFycmF5LEludDE2QXJyYXksVWludDE2QXJyYXksSW50MzJBcnJheSxVaW50MzJBcnJheSxGbG9hdDMyQXJyYXksRmxvYXQ2NEFycmF5J1xuKS5zcGxpdCgnLCcpO1xuXG53aGlsZSAoaSA8IGwpIHtcbiAgaWYgKFR5cGVkID0gZ2xvYmFsW1R5cGVkQXJyYXlDb25zdHJ1Y3RvcnNbaSsrXV0pIHtcbiAgICBoaWRlKFR5cGVkLnByb3RvdHlwZSwgVFlQRUQsIHRydWUpO1xuICAgIGhpZGUoVHlwZWQucHJvdG90eXBlLCBWSUVXLCB0cnVlKTtcbiAgfSBlbHNlIENPTlNUUiA9IGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQUJWOiBBQlYsXG4gIENPTlNUUjogQ09OU1RSLFxuICBUWVBFRDogVFlQRUQsXG4gIFZJRVc6IFZJRVdcbn07XG4iLCJ2YXIgaWQgPSAwO1xudmFyIHB4ID0gTWF0aC5yYW5kb20oKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSkge1xuICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBuYXZpZ2F0b3IgPSBnbG9iYWwubmF2aWdhdG9yO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5hdmlnYXRvciAmJiBuYXZpZ2F0b3IudXNlckFnZW50IHx8ICcnO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgVFlQRSkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSB8fCBpdC5fdCAhPT0gVFlQRSkgdGhyb3cgVHlwZUVycm9yKCdJbmNvbXBhdGlibGUgcmVjZWl2ZXIsICcgKyBUWVBFICsgJyByZXF1aXJlZCEnKTtcbiAgcmV0dXJuIGl0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgd2tzRXh0ID0gcmVxdWlyZSgnLi9fd2tzLWV4dCcpO1xudmFyIGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgdmFyICRTeW1ib2wgPSBjb3JlLlN5bWJvbCB8fCAoY29yZS5TeW1ib2wgPSBMSUJSQVJZID8ge30gOiBnbG9iYWwuU3ltYm9sIHx8IHt9KTtcbiAgaWYgKG5hbWUuY2hhckF0KDApICE9ICdfJyAmJiAhKG5hbWUgaW4gJFN5bWJvbCkpIGRlZmluZVByb3BlcnR5KCRTeW1ib2wsIG5hbWUsIHsgdmFsdWU6IHdrc0V4dC5mKG5hbWUpIH0pO1xufTtcbiIsImV4cG9ydHMuZiA9IHJlcXVpcmUoJy4vX3drcycpO1xuIiwidmFyIHN0b3JlID0gcmVxdWlyZSgnLi9fc2hhcmVkJykoJ3drcycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLlN5bWJvbDtcbnZhciBVU0VfU1lNQk9MID0gdHlwZW9mIFN5bWJvbCA9PSAnZnVuY3Rpb24nO1xuXG52YXIgJGV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIHJldHVybiBzdG9yZVtuYW1lXSB8fCAoc3RvcmVbbmFtZV0gPVxuICAgIFVTRV9TWU1CT0wgJiYgU3ltYm9sW25hbWVdIHx8IChVU0VfU1lNQk9MID8gU3ltYm9sIDogdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59O1xuXG4kZXhwb3J0cy5zdG9yZSA9IHN0b3JlO1xuIiwidmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29yZScpLmdldEl0ZXJhdG9yTWV0aG9kID0gZnVuY3Rpb24gKGl0KSB7XG4gIGlmIChpdCAhPSB1bmRlZmluZWQpIHJldHVybiBpdFtJVEVSQVRPUl1cbiAgICB8fCBpdFsnQEBpdGVyYXRvciddXG4gICAgfHwgSXRlcmF0b3JzW2NsYXNzb2YoaXQpXTtcbn07XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vYmVuamFtaW5nci9SZXhFeHAuZXNjYXBlXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRyZSA9IHJlcXVpcmUoJy4vX3JlcGxhY2VyJykoL1tcXFxcXiQqKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVnRXhwJywgeyBlc2NhcGU6IGZ1bmN0aW9uIGVzY2FwZShpdCkgeyByZXR1cm4gJHJlKGl0KTsgfSB9KTtcbiIsIi8vIDIyLjEuMy4zIEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluKHRhcmdldCwgc3RhcnQsIGVuZCA9IHRoaXMubGVuZ3RoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdBcnJheScsIHsgY29weVdpdGhpbjogcmVxdWlyZSgnLi9fYXJyYXktY29weS13aXRoaW4nKSB9KTtcblxucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoJ2NvcHlXaXRoaW4nKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGV2ZXJ5ID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDQpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uZXZlcnksIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy41IC8gMTUuNC40LjE2IEFycmF5LnByb3RvdHlwZS5ldmVyeShjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGV2ZXJ5KHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiLy8gMjIuMS4zLjYgQXJyYXkucHJvdG90eXBlLmZpbGwodmFsdWUsIHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5JywgeyBmaWxsOiByZXF1aXJlKCcuL19hcnJheS1maWxsJykgfSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdmaWxsJyk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmaWx0ZXIgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMik7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5maWx0ZXIsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy43IC8gMTUuNC40LjIwIEFycmF5LnByb3RvdHlwZS5maWx0ZXIoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGZpbHRlcih0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy45IEFycmF5LnByb3RvdHlwZS5maW5kSW5kZXgocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZmluZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg2KTtcbnZhciBLRVkgPSAnZmluZEluZGV4JztcbnZhciBmb3JjZWQgPSB0cnVlO1xuLy8gU2hvdWxkbid0IHNraXAgaG9sZXNcbmlmIChLRVkgaW4gW10pIEFycmF5KDEpW0tFWV0oZnVuY3Rpb24gKCkgeyBmb3JjZWQgPSBmYWxzZTsgfSk7XG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZvcmNlZCwgJ0FycmF5Jywge1xuICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChjYWxsYmFja2ZuIC8qICwgdGhhdCA9IHVuZGVmaW5lZCAqLykge1xuICAgIHJldHVybiAkZmluZCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoS0VZKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy44IEFycmF5LnByb3RvdHlwZS5maW5kKHByZWRpY2F0ZSwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZpbmQgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoNSk7XG52YXIgS0VZID0gJ2ZpbmQnO1xudmFyIGZvcmNlZCA9IHRydWU7XG4vLyBTaG91bGRuJ3Qgc2tpcCBob2xlc1xuaWYgKEtFWSBpbiBbXSkgQXJyYXkoMSlbS0VZXShmdW5jdGlvbiAoKSB7IGZvcmNlZCA9IGZhbHNlOyB9KTtcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogZm9yY2VkLCAnQXJyYXknLCB7XG4gIGZpbmQ6IGZ1bmN0aW9uIGZpbmQoY2FsbGJhY2tmbiAvKiAsIHRoYXQgPSB1bmRlZmluZWQgKi8pIHtcbiAgICByZXR1cm4gJGZpbmQodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICB9XG59KTtcbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKEtFWSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmb3JFYWNoID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDApO1xudmFyIFNUUklDVCA9IHJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5mb3JFYWNoLCB0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhU1RSSUNULCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMCAvIDE1LjQuNC4xOCBBcnJheS5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgcmV0dXJuICRmb3JFYWNoKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGNyZWF0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fY3JlYXRlLXByb3BlcnR5Jyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikgeyBBcnJheS5mcm9tKGl0ZXIpOyB9KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMSBBcnJheS5mcm9tKGFycmF5TGlrZSwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gIGZyb206IGZ1bmN0aW9uIGZyb20oYXJyYXlMaWtlIC8qICwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQgKi8pIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KGFycmF5TGlrZSk7XG4gICAgdmFyIEMgPSB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nID8gdGhpcyA6IEFycmF5O1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgbWFwZm4gPSBhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDtcbiAgICB2YXIgbWFwcGluZyA9IG1hcGZuICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgaXRlckZuID0gZ2V0SXRlckZuKE8pO1xuICAgIHZhciBsZW5ndGgsIHJlc3VsdCwgc3RlcCwgaXRlcmF0b3I7XG4gICAgaWYgKG1hcHBpbmcpIG1hcGZuID0gY3R4KG1hcGZuLCBhTGVuID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCwgMik7XG4gICAgLy8gaWYgb2JqZWN0IGlzbid0IGl0ZXJhYmxlIG9yIGl0J3MgYXJyYXkgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yIC0gdXNlIHNpbXBsZSBjYXNlXG4gICAgaWYgKGl0ZXJGbiAhPSB1bmRlZmluZWQgJiYgIShDID09IEFycmF5ICYmIGlzQXJyYXlJdGVyKGl0ZXJGbikpKSB7XG4gICAgICBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoTyksIHJlc3VsdCA9IG5ldyBDKCk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaW5kZXgrKykge1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gY2FsbChpdGVyYXRvciwgbWFwZm4sIFtzdGVwLnZhbHVlLCBpbmRleF0sIHRydWUpIDogc3RlcC52YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICAgIGZvciAocmVzdWx0ID0gbmV3IEMobGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICAgICAgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgbWFwcGluZyA/IG1hcGZuKE9baW5kZXhdLCBpbmRleCkgOiBPW2luZGV4XSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5sZW5ndGggPSBpbmRleDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKTtcbnZhciAkbmF0aXZlID0gW10uaW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0uaW5kZXhPZigxLCAtMCkgPCAwO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChORUdBVElWRV9aRVJPIHx8ICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoJG5hdGl2ZSkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMSAvIDE1LjQuNC4xNCBBcnJheS5wcm90b3R5cGUuaW5kZXhPZihzZWFyY2hFbGVtZW50IFssIGZyb21JbmRleF0pXG4gIGluZGV4T2Y6IGZ1bmN0aW9uIGluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gTkVHQVRJVkVfWkVST1xuICAgICAgLy8gY29udmVydCAtMCB0byArMFxuICAgICAgPyAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMFxuICAgICAgOiAkaW5kZXhPZih0aGlzLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIi8vIDIyLjEuMi4yIC8gMTUuNC4zLjIgQXJyYXkuaXNBcnJheShhcmcpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0FycmF5JywgeyBpc0FycmF5OiByZXF1aXJlKCcuL19pcy1hcnJheScpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKTtcbnZhciBzdGVwID0gcmVxdWlyZSgnLi9faXRlci1zdGVwJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xuXG4vLyAyMi4xLjMuNCBBcnJheS5wcm90b3R5cGUuZW50cmllcygpXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmtleXMoKVxuLy8gMjIuMS4zLjI5IEFycmF5LnByb3RvdHlwZS52YWx1ZXMoKVxuLy8gMjIuMS4zLjMwIEFycmF5LnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIga2luZCA9IHRoaXMuX2s7XG4gIHZhciBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYgKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKSB7XG4gICAgdGhpcy5fdCA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gc3RlcCgxKTtcbiAgfVxuICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGluZGV4KTtcbiAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy4xMyBBcnJheS5wcm90b3R5cGUuam9pbihzZXBhcmF0b3IpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBhcnJheUpvaW4gPSBbXS5qb2luO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2Ugc3RyaW5nc1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAocmVxdWlyZSgnLi9faW9iamVjdCcpICE9IE9iamVjdCB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKGFycmF5Sm9pbikpLCAnQXJyYXknLCB7XG4gIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgcmV0dXJuIGFycmF5Sm9pbi5jYWxsKHRvSU9iamVjdCh0aGlzKSwgc2VwYXJhdG9yID09PSB1bmRlZmluZWQgPyAnLCcgOiBzZXBhcmF0b3IpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyICRuYXRpdmUgPSBbXS5sYXN0SW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0ubGFzdEluZGV4T2YoMSwgLTApIDwgMDtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoTkVHQVRJVkVfWkVSTyB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTQgLyAxNS40LjQuMTUgQXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgWywgZnJvbUluZGV4XSlcbiAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgLyogLCBmcm9tSW5kZXggPSBAWyotMV0gKi8pIHtcbiAgICAvLyBjb252ZXJ0IC0wIHRvICswXG4gICAgaWYgKE5FR0FUSVZFX1pFUk8pIHJldHVybiAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMDtcbiAgICB2YXIgTyA9IHRvSU9iamVjdCh0aGlzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IGxlbmd0aCAtIDE7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSBpbmRleCA9IE1hdGgubWluKGluZGV4LCB0b0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgaWYgKGluZGV4IDwgMCkgaW5kZXggPSBsZW5ndGggKyBpbmRleDtcbiAgICBmb3IgKDtpbmRleCA+PSAwOyBpbmRleC0tKSBpZiAoaW5kZXggaW4gTykgaWYgKE9baW5kZXhdID09PSBzZWFyY2hFbGVtZW50KSByZXR1cm4gaW5kZXggfHwgMDtcbiAgICByZXR1cm4gLTE7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkbWFwID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDEpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ubWFwLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTUgLyAxNS40LjQuMTkgQXJyYXkucHJvdG90eXBlLm1hcChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBtYXA6IGZ1bmN0aW9uIG1hcChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgIHJldHVybiAkbWFwKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpO1xuXG4vLyBXZWJLaXQgQXJyYXkub2YgaXNuJ3QgZ2VuZXJpY1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRigpIHsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gIShBcnJheS5vZi5jYWxsKEYpIGluc3RhbmNlb2YgRik7XG59KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMyBBcnJheS5vZiggLi4uaXRlbXMpXG4gIG9mOiBmdW5jdGlvbiBvZigvKiAuLi5hcmdzICovKSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyAodHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheSkoYUxlbik7XG4gICAgd2hpbGUgKGFMZW4gPiBpbmRleCkgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICByZXN1bHQubGVuZ3RoID0gYUxlbjtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHJlZHVjZSA9IHJlcXVpcmUoJy4vX2FycmF5LXJlZHVjZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ucmVkdWNlUmlnaHQsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOSAvIDE1LjQuNC4yMiBBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQoY2FsbGJhY2tmbiBbLCBpbml0aWFsVmFsdWVdKVxuICByZWR1Y2VSaWdodDogZnVuY3Rpb24gcmVkdWNlUmlnaHQoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgdHJ1ZSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcmVkdWNlID0gcmVxdWlyZSgnLi9fYXJyYXktcmVkdWNlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5yZWR1Y2UsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOCAvIDE1LjQuNC4yMSBBcnJheS5wcm90b3R5cGUucmVkdWNlKGNhbGxiYWNrZm4gWywgaW5pdGlhbFZhbHVlXSlcbiAgcmVkdWNlOiBmdW5jdGlvbiByZWR1Y2UoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgZmFsc2UpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaHRtbCA9IHJlcXVpcmUoJy4vX2h0bWwnKTtcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXJyYXlTbGljZSA9IFtdLnNsaWNlO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2UgRVMzIHN0cmluZ3MgYW5kIERPTSBvYmplY3RzXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICBpZiAoaHRtbCkgYXJyYXlTbGljZS5jYWxsKGh0bWwpO1xufSksICdBcnJheScsIHtcbiAgc2xpY2U6IGZ1bmN0aW9uIHNsaWNlKGJlZ2luLCBlbmQpIHtcbiAgICB2YXIgbGVuID0gdG9MZW5ndGgodGhpcy5sZW5ndGgpO1xuICAgIHZhciBrbGFzcyA9IGNvZih0aGlzKTtcbiAgICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IGVuZDtcbiAgICBpZiAoa2xhc3MgPT0gJ0FycmF5JykgcmV0dXJuIGFycmF5U2xpY2UuY2FsbCh0aGlzLCBiZWdpbiwgZW5kKTtcbiAgICB2YXIgc3RhcnQgPSB0b0Fic29sdXRlSW5kZXgoYmVnaW4sIGxlbik7XG4gICAgdmFyIHVwVG8gPSB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pO1xuICAgIHZhciBzaXplID0gdG9MZW5ndGgodXBUbyAtIHN0YXJ0KTtcbiAgICB2YXIgY2xvbmVkID0gbmV3IEFycmF5KHNpemUpO1xuICAgIHZhciBpID0gMDtcbiAgICBmb3IgKDsgaSA8IHNpemU7IGkrKykgY2xvbmVkW2ldID0ga2xhc3MgPT0gJ1N0cmluZydcbiAgICAgID8gdGhpcy5jaGFyQXQoc3RhcnQgKyBpKVxuICAgICAgOiB0aGlzW3N0YXJ0ICsgaV07XG4gICAgcmV0dXJuIGNsb25lZDtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRzb21lID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDMpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uc29tZSwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjIzIC8gMTUuNC40LjE3IEFycmF5LnByb3RvdHlwZS5zb21lKGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXG4gIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJHNvbWUodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciAkc29ydCA9IFtdLnNvcnQ7XG52YXIgdGVzdCA9IFsxLCAyLCAzXTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAvLyBJRTgtXG4gIHRlc3Quc29ydCh1bmRlZmluZWQpO1xufSkgfHwgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gVjggYnVnXG4gIHRlc3Quc29ydChudWxsKTtcbiAgLy8gT2xkIFdlYktpdFxufSkgfHwgIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKSgkc29ydCkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4yNSBBcnJheS5wcm90b3R5cGUuc29ydChjb21wYXJlZm4pXG4gIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZWZuKSB7XG4gICAgcmV0dXJuIGNvbXBhcmVmbiA9PT0gdW5kZWZpbmVkXG4gICAgICA/ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcykpXG4gICAgICA6ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcyksIGFGdW5jdGlvbihjb21wYXJlZm4pKTtcbiAgfVxufSk7XG4iLCJyZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdBcnJheScpO1xuIiwiLy8gMjAuMy4zLjEgLyAxNS45LjQuNCBEYXRlLm5vdygpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0RhdGUnLCB7IG5vdzogZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7IH0gfSk7XG4iLCIvLyAyMC4zLjQuMzYgLyAxNS45LjUuNDMgRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0lTT1N0cmluZyA9IHJlcXVpcmUoJy4vX2RhdGUtdG8taXNvLXN0cmluZycpO1xuXG4vLyBQaGFudG9tSlMgLyBvbGQgV2ViS2l0IGhhcyBhIGJyb2tlbiBpbXBsZW1lbnRhdGlvbnNcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICE9PSB0b0lTT1N0cmluZyksICdEYXRlJywge1xuICB0b0lTT1N0cmluZzogdG9JU09TdHJpbmdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgRGF0ZShOYU4pLnRvSlNPTigpICE9PSBudWxsXG4gICAgfHwgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoeyB0b0lTT1N0cmluZzogZnVuY3Rpb24gKCkgeyByZXR1cm4gMTsgfSB9KSAhPT0gMTtcbn0pLCAnRGF0ZScsIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gIHRvSlNPTjogZnVuY3Rpb24gdG9KU09OKGtleSkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIHB2ID0gdG9QcmltaXRpdmUoTyk7XG4gICAgcmV0dXJuIHR5cGVvZiBwdiA9PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUocHYpID8gbnVsbCA6IE8udG9JU09TdHJpbmcoKTtcbiAgfVxufSk7XG4iLCJ2YXIgVE9fUFJJTUlUSVZFID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvUHJpbWl0aXZlJyk7XG52YXIgcHJvdG8gPSBEYXRlLnByb3RvdHlwZTtcblxuaWYgKCEoVE9fUFJJTUlUSVZFIGluIHByb3RvKSkgcmVxdWlyZSgnLi9faGlkZScpKHByb3RvLCBUT19QUklNSVRJVkUsIHJlcXVpcmUoJy4vX2RhdGUtdG8tcHJpbWl0aXZlJykpO1xuIiwidmFyIERhdGVQcm90byA9IERhdGUucHJvdG90eXBlO1xudmFyIElOVkFMSURfREFURSA9ICdJbnZhbGlkIERhdGUnO1xudmFyIFRPX1NUUklORyA9ICd0b1N0cmluZyc7XG52YXIgJHRvU3RyaW5nID0gRGF0ZVByb3RvW1RPX1NUUklOR107XG52YXIgZ2V0VGltZSA9IERhdGVQcm90by5nZXRUaW1lO1xuaWYgKG5ldyBEYXRlKE5hTikgKyAnJyAhPSBJTlZBTElEX0RBVEUpIHtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShEYXRlUHJvdG8sIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgdmFyIHZhbHVlID0gZ2V0VGltZS5jYWxsKHRoaXMpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gJHRvU3RyaW5nLmNhbGwodGhpcykgOiBJTlZBTElEX0RBVEU7XG4gIH0pO1xufVxuIiwiLy8gMTkuMi4zLjIgLyAxNS4zLjQuNSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCh0aGlzQXJnLCBhcmdzLi4uKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdGdW5jdGlvbicsIHsgYmluZDogcmVxdWlyZSgnLi9fYmluZCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgSEFTX0lOU1RBTkNFID0gcmVxdWlyZSgnLi9fd2tzJykoJ2hhc0luc3RhbmNlJyk7XG52YXIgRnVuY3Rpb25Qcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbi8vIDE5LjIuMy42IEZ1bmN0aW9uLnByb3RvdHlwZVtAQGhhc0luc3RhbmNlXShWKVxuaWYgKCEoSEFTX0lOU1RBTkNFIGluIEZ1bmN0aW9uUHJvdG8pKSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mKEZ1bmN0aW9uUHJvdG8sIEhBU19JTlNUQU5DRSwgeyB2YWx1ZTogZnVuY3Rpb24gKE8pIHtcbiAgaWYgKHR5cGVvZiB0aGlzICE9ICdmdW5jdGlvbicgfHwgIWlzT2JqZWN0KE8pKSByZXR1cm4gZmFsc2U7XG4gIGlmICghaXNPYmplY3QodGhpcy5wcm90b3R5cGUpKSByZXR1cm4gTyBpbnN0YW5jZW9mIHRoaXM7XG4gIC8vIGZvciBlbnZpcm9ubWVudCB3L28gbmF0aXZlIGBAQGhhc0luc3RhbmNlYCBsb2dpYyBlbm91Z2ggYGluc3RhbmNlb2ZgLCBidXQgYWRkIHRoaXM6XG4gIHdoaWxlIChPID0gZ2V0UHJvdG90eXBlT2YoTykpIGlmICh0aGlzLnByb3RvdHlwZSA9PT0gTykgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn0gfSk7XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIEZQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbnZhciBuYW1lUkUgPSAvXlxccypmdW5jdGlvbiAoW14gKF0qKS87XG52YXIgTkFNRSA9ICduYW1lJztcblxuLy8gMTkuMi40LjIgbmFtZVxuTkFNRSBpbiBGUHJvdG8gfHwgcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiBkUChGUHJvdG8sIE5BTUUsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICgnJyArIHRoaXMpLm1hdGNoKG5hbWVSRSlbMV07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgc3Ryb25nID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi1zdHJvbmcnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBNQVAgPSAnTWFwJztcblxuLy8gMjMuMSBNYXAgT2JqZWN0c1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoTUFQLCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBNYXAoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4xLjMuNiBNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIHZhciBlbnRyeSA9IHN0cm9uZy5nZXRFbnRyeSh2YWxpZGF0ZSh0aGlzLCBNQVApLCBrZXkpO1xuICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeS52O1xuICB9LFxuICAvLyAyMy4xLjMuOSBNYXAucHJvdG90eXBlLnNldChrZXksIHZhbHVlKVxuICBzZXQ6IGZ1bmN0aW9uIHNldChrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgTUFQKSwga2V5ID09PSAwID8gMCA6IGtleSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcsIHRydWUpO1xuIiwiLy8gMjAuMi4yLjMgTWF0aC5hY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBsb2cxcCA9IHJlcXVpcmUoJy4vX21hdGgtbG9nMXAnKTtcbnZhciBzcXJ0ID0gTWF0aC5zcXJ0O1xudmFyICRhY29zaCA9IE1hdGguYWNvc2g7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISgkYWNvc2hcbiAgLy8gVjggYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzUwOVxuICAmJiBNYXRoLmZsb29yKCRhY29zaChOdW1iZXIuTUFYX1ZBTFVFKSkgPT0gNzEwXG4gIC8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hY29zaChJbmZpbml0eSkgLT4gTmFOXG4gICYmICRhY29zaChJbmZpbml0eSkgPT0gSW5maW5pdHlcbiksICdNYXRoJywge1xuICBhY29zaDogZnVuY3Rpb24gYWNvc2goeCkge1xuICAgIHJldHVybiAoeCA9ICt4KSA8IDEgPyBOYU4gOiB4ID4gOTQ5MDYyNjUuNjI0MjUxNTZcbiAgICAgID8gTWF0aC5sb2coeCkgKyBNYXRoLkxOMlxuICAgICAgOiBsb2cxcCh4IC0gMSArIHNxcnQoeCAtIDEpICogc3FydCh4ICsgMSkpO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi41IE1hdGguYXNpbmgoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGFzaW5oID0gTWF0aC5hc2luaDtcblxuZnVuY3Rpb24gYXNpbmgoeCkge1xuICByZXR1cm4gIWlzRmluaXRlKHggPSAreCkgfHwgeCA9PSAwID8geCA6IHggPCAwID8gLWFzaW5oKC14KSA6IE1hdGgubG9nKHggKyBNYXRoLnNxcnQoeCAqIHggKyAxKSk7XG59XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hc2luaCgwKSAtPiAtMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhc2luaCAmJiAxIC8gJGFzaW5oKDApID4gMCksICdNYXRoJywgeyBhc2luaDogYXNpbmggfSk7XG4iLCIvLyAyMC4yLjIuNyBNYXRoLmF0YW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhdGFuaCA9IE1hdGguYXRhbmg7XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hdGFuaCgtMCkgLT4gMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhdGFuaCAmJiAxIC8gJGF0YW5oKC0wKSA8IDApLCAnTWF0aCcsIHtcbiAgYXRhbmg6IGZ1bmN0aW9uIGF0YW5oKHgpIHtcbiAgICByZXR1cm4gKHggPSAreCkgPT0gMCA/IHggOiBNYXRoLmxvZygoMSArIHgpIC8gKDEgLSB4KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi45IE1hdGguY2JydCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBzaWduID0gcmVxdWlyZSgnLi9fbWF0aC1zaWduJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2JydDogZnVuY3Rpb24gY2JydCh4KSB7XG4gICAgcmV0dXJuIHNpZ24oeCA9ICt4KSAqIE1hdGgucG93KE1hdGguYWJzKHgpLCAxIC8gMyk7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjExIE1hdGguY2x6MzIoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2x6MzI6IGZ1bmN0aW9uIGNsejMyKHgpIHtcbiAgICByZXR1cm4gKHggPj4+PSAwKSA/IDMxIC0gTWF0aC5mbG9vcihNYXRoLmxvZyh4ICsgMC41KSAqIE1hdGguTE9HMkUpIDogMzI7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjEyIE1hdGguY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjb3NoOiBmdW5jdGlvbiBjb3NoKHgpIHtcbiAgICByZXR1cm4gKGV4cCh4ID0gK3gpICsgZXhwKC14KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xNCBNYXRoLmV4cG0xKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoJGV4cG0xICE9IE1hdGguZXhwbTEpLCAnTWF0aCcsIHsgZXhwbTE6ICRleHBtMSB9KTtcbiIsIi8vIDIwLjIuMi4xNiBNYXRoLmZyb3VuZCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywgeyBmcm91bmQ6IHJlcXVpcmUoJy4vX21hdGgtZnJvdW5kJykgfSk7XG4iLCIvLyAyMC4yLjIuMTcgTWF0aC5oeXBvdChbdmFsdWUxWywgdmFsdWUyWywg4oCmIF1dXSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYWJzID0gTWF0aC5hYnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgaHlwb3Q6IGZ1bmN0aW9uIGh5cG90KHZhbHVlMSwgdmFsdWUyKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICB2YXIgc3VtID0gMDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBsYXJnID0gMDtcbiAgICB2YXIgYXJnLCBkaXY7XG4gICAgd2hpbGUgKGkgPCBhTGVuKSB7XG4gICAgICBhcmcgPSBhYnMoYXJndW1lbnRzW2krK10pO1xuICAgICAgaWYgKGxhcmcgPCBhcmcpIHtcbiAgICAgICAgZGl2ID0gbGFyZyAvIGFyZztcbiAgICAgICAgc3VtID0gc3VtICogZGl2ICogZGl2ICsgMTtcbiAgICAgICAgbGFyZyA9IGFyZztcbiAgICAgIH0gZWxzZSBpZiAoYXJnID4gMCkge1xuICAgICAgICBkaXYgPSBhcmcgLyBsYXJnO1xuICAgICAgICBzdW0gKz0gZGl2ICogZGl2O1xuICAgICAgfSBlbHNlIHN1bSArPSBhcmc7XG4gICAgfVxuICAgIHJldHVybiBsYXJnID09PSBJbmZpbml0eSA/IEluZmluaXR5IDogbGFyZyAqIE1hdGguc3FydChzdW0pO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xOCBNYXRoLmltdWwoeCwgeSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGltdWwgPSBNYXRoLmltdWw7XG5cbi8vIHNvbWUgV2ViS2l0IHZlcnNpb25zIGZhaWxzIHdpdGggYmlnIG51bWJlcnMsIHNvbWUgaGFzIHdyb25nIGFyaXR5XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJGltdWwoMHhmZmZmZmZmZiwgNSkgIT0gLTUgfHwgJGltdWwubGVuZ3RoICE9IDI7XG59KSwgJ01hdGgnLCB7XG4gIGltdWw6IGZ1bmN0aW9uIGltdWwoeCwgeSkge1xuICAgIHZhciBVSU5UMTYgPSAweGZmZmY7XG4gICAgdmFyIHhuID0gK3g7XG4gICAgdmFyIHluID0gK3k7XG4gICAgdmFyIHhsID0gVUlOVDE2ICYgeG47XG4gICAgdmFyIHlsID0gVUlOVDE2ICYgeW47XG4gICAgcmV0dXJuIDAgfCB4bCAqIHlsICsgKChVSU5UMTYgJiB4biA+Pj4gMTYpICogeWwgKyB4bCAqIChVSU5UMTYgJiB5biA+Pj4gMTYpIDw8IDE2ID4+PiAwKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMjEgTWF0aC5sb2cxMCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBsb2cxMDogZnVuY3Rpb24gbG9nMTAoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAqIE1hdGguTE9HMTBFO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IGxvZzFwOiByZXF1aXJlKCcuL19tYXRoLWxvZzFwJykgfSk7XG4iLCIvLyAyMC4yLjIuMjIgTWF0aC5sb2cyKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGxvZzI6IGZ1bmN0aW9uIGxvZzIoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAvIE1hdGguTE4yO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yOCBNYXRoLnNpZ24oeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgc2lnbjogcmVxdWlyZSgnLi9fbWF0aC1zaWduJykgfSk7XG4iLCIvLyAyMC4yLjIuMzAgTWF0aC5zaW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGV4cG0xID0gcmVxdWlyZSgnLi9fbWF0aC1leHBtMScpO1xudmFyIGV4cCA9IE1hdGguZXhwO1xuXG4vLyBWOCBuZWFyIENocm9taXVtIDM4IGhhcyBhIHByb2JsZW0gd2l0aCB2ZXJ5IHNtYWxsIG51bWJlcnNcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhTWF0aC5zaW5oKC0yZS0xNykgIT0gLTJlLTE3O1xufSksICdNYXRoJywge1xuICBzaW5oOiBmdW5jdGlvbiBzaW5oKHgpIHtcbiAgICByZXR1cm4gTWF0aC5hYnMoeCA9ICt4KSA8IDFcbiAgICAgID8gKGV4cG0xKHgpIC0gZXhwbTEoLXgpKSAvIDJcbiAgICAgIDogKGV4cCh4IC0gMSkgLSBleHAoLXggLSAxKSkgKiAoTWF0aC5FIC8gMik7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjMzIE1hdGgudGFuaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0YW5oOiBmdW5jdGlvbiB0YW5oKHgpIHtcbiAgICB2YXIgYSA9IGV4cG0xKHggPSAreCk7XG4gICAgdmFyIGIgPSBleHBtMSgteCk7XG4gICAgcmV0dXJuIGEgPT0gSW5maW5pdHkgPyAxIDogYiA9PSBJbmZpbml0eSA/IC0xIDogKGEgLSBiKSAvIChleHAoeCkgKyBleHAoLXgpKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMzQgTWF0aC50cnVuYyh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0cnVuYzogZnVuY3Rpb24gdHJ1bmMoaXQpIHtcbiAgICByZXR1cm4gKGl0ID4gMCA/IE1hdGguZmxvb3IgOiBNYXRoLmNlaWwpKGl0KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciBOVU1CRVIgPSAnTnVtYmVyJztcbnZhciAkTnVtYmVyID0gZ2xvYmFsW05VTUJFUl07XG52YXIgQmFzZSA9ICROdW1iZXI7XG52YXIgcHJvdG8gPSAkTnVtYmVyLnByb3RvdHlwZTtcbi8vIE9wZXJhIH4xMiBoYXMgYnJva2VuIE9iamVjdCN0b1N0cmluZ1xudmFyIEJST0tFTl9DT0YgPSBjb2YocmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpKHByb3RvKSkgPT0gTlVNQkVSO1xudmFyIFRSSU0gPSAndHJpbScgaW4gU3RyaW5nLnByb3RvdHlwZTtcblxuLy8gNy4xLjMgVG9OdW1iZXIoYXJndW1lbnQpXG52YXIgdG9OdW1iZXIgPSBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgdmFyIGl0ID0gdG9QcmltaXRpdmUoYXJndW1lbnQsIGZhbHNlKTtcbiAgaWYgKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyAmJiBpdC5sZW5ndGggPiAyKSB7XG4gICAgaXQgPSBUUklNID8gaXQudHJpbSgpIDogJHRyaW0oaXQsIDMpO1xuICAgIHZhciBmaXJzdCA9IGl0LmNoYXJDb2RlQXQoMCk7XG4gICAgdmFyIHRoaXJkLCByYWRpeCwgbWF4Q29kZTtcbiAgICBpZiAoZmlyc3QgPT09IDQzIHx8IGZpcnN0ID09PSA0NSkge1xuICAgICAgdGhpcmQgPSBpdC5jaGFyQ29kZUF0KDIpO1xuICAgICAgaWYgKHRoaXJkID09PSA4OCB8fCB0aGlyZCA9PT0gMTIwKSByZXR1cm4gTmFOOyAvLyBOdW1iZXIoJysweDEnKSBzaG91bGQgYmUgTmFOLCBvbGQgVjggZml4XG4gICAgfSBlbHNlIGlmIChmaXJzdCA9PT0gNDgpIHtcbiAgICAgIHN3aXRjaCAoaXQuY2hhckNvZGVBdCgxKSkge1xuICAgICAgICBjYXNlIDY2OiBjYXNlIDk4OiByYWRpeCA9IDI7IG1heENvZGUgPSA0OTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wYlswMV0rJC9pXG4gICAgICAgIGNhc2UgNzk6IGNhc2UgMTExOiByYWRpeCA9IDg7IG1heENvZGUgPSA1NTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wb1swLTddKyQvaVxuICAgICAgICBkZWZhdWx0OiByZXR1cm4gK2l0O1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgZGlnaXRzID0gaXQuc2xpY2UoMiksIGkgPSAwLCBsID0gZGlnaXRzLmxlbmd0aCwgY29kZTsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb2RlID0gZGlnaXRzLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIC8vIHBhcnNlSW50IHBhcnNlcyBhIHN0cmluZyB0byBhIGZpcnN0IHVuYXZhaWxhYmxlIHN5bWJvbFxuICAgICAgICAvLyBidXQgVG9OdW1iZXIgc2hvdWxkIHJldHVybiBOYU4gaWYgYSBzdHJpbmcgY29udGFpbnMgdW5hdmFpbGFibGUgc3ltYm9sc1xuICAgICAgICBpZiAoY29kZSA8IDQ4IHx8IGNvZGUgPiBtYXhDb2RlKSByZXR1cm4gTmFOO1xuICAgICAgfSByZXR1cm4gcGFyc2VJbnQoZGlnaXRzLCByYWRpeCk7XG4gICAgfVxuICB9IHJldHVybiAraXQ7XG59O1xuXG5pZiAoISROdW1iZXIoJyAwbzEnKSB8fCAhJE51bWJlcignMGIxJykgfHwgJE51bWJlcignKzB4MScpKSB7XG4gICROdW1iZXIgPSBmdW5jdGlvbiBOdW1iZXIodmFsdWUpIHtcbiAgICB2YXIgaXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMSA/IDAgOiB2YWx1ZTtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgcmV0dXJuIHRoYXQgaW5zdGFuY2VvZiAkTnVtYmVyXG4gICAgICAvLyBjaGVjayBvbiAxLi5jb25zdHJ1Y3Rvcihmb28pIGNhc2VcbiAgICAgICYmIChCUk9LRU5fQ09GID8gZmFpbHMoZnVuY3Rpb24gKCkgeyBwcm90by52YWx1ZU9mLmNhbGwodGhhdCk7IH0pIDogY29mKHRoYXQpICE9IE5VTUJFUilcbiAgICAgICAgPyBpbmhlcml0SWZSZXF1aXJlZChuZXcgQmFzZSh0b051bWJlcihpdCkpLCB0aGF0LCAkTnVtYmVyKSA6IHRvTnVtYmVyKGl0KTtcbiAgfTtcbiAgZm9yICh2YXIga2V5cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BOKEJhc2UpIDogKFxuICAgIC8vIEVTMzpcbiAgICAnTUFYX1ZBTFVFLE1JTl9WQUxVRSxOYU4sTkVHQVRJVkVfSU5GSU5JVFksUE9TSVRJVkVfSU5GSU5JVFksJyArXG4gICAgLy8gRVM2IChpbiBjYXNlLCBpZiBtb2R1bGVzIHdpdGggRVM2IE51bWJlciBzdGF0aWNzIHJlcXVpcmVkIGJlZm9yZSk6XG4gICAgJ0VQU0lMT04saXNGaW5pdGUsaXNJbnRlZ2VyLGlzTmFOLGlzU2FmZUludGVnZXIsTUFYX1NBRkVfSU5URUdFUiwnICtcbiAgICAnTUlOX1NBRkVfSU5URUdFUixwYXJzZUZsb2F0LHBhcnNlSW50LGlzSW50ZWdlcidcbiAgKS5zcGxpdCgnLCcpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7IGorKykge1xuICAgIGlmIChoYXMoQmFzZSwga2V5ID0ga2V5c1tqXSkgJiYgIWhhcygkTnVtYmVyLCBrZXkpKSB7XG4gICAgICBkUCgkTnVtYmVyLCBrZXksIGdPUEQoQmFzZSwga2V5KSk7XG4gICAgfVxuICB9XG4gICROdW1iZXIucHJvdG90eXBlID0gcHJvdG87XG4gIHByb3RvLmNvbnN0cnVjdG9yID0gJE51bWJlcjtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShnbG9iYWwsIE5VTUJFUiwgJE51bWJlcik7XG59XG4iLCIvLyAyMC4xLjIuMSBOdW1iZXIuRVBTSUxPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7IEVQU0lMT046IE1hdGgucG93KDIsIC01MikgfSk7XG4iLCIvLyAyMC4xLjIuMiBOdW1iZXIuaXNGaW5pdGUobnVtYmVyKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBfaXNGaW5pdGUgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5pc0Zpbml0ZTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzRmluaXRlOiBmdW5jdGlvbiBpc0Zpbml0ZShpdCkge1xuICAgIHJldHVybiB0eXBlb2YgaXQgPT0gJ251bWJlcicgJiYgX2lzRmluaXRlKGl0KTtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuMyBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlcilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBpc0ludGVnZXI6IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKSB9KTtcbiIsIi8vIDIwLjEuMi40IE51bWJlci5pc05hTihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtcbiAgaXNOYU46IGZ1bmN0aW9uIGlzTmFOKG51bWJlcikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gbnVtYmVyICE9IG51bWJlcjtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuNSBOdW1iZXIuaXNTYWZlSW50ZWdlcihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGlzSW50ZWdlciA9IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKTtcbnZhciBhYnMgPSBNYXRoLmFicztcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzU2FmZUludGVnZXI6IGZ1bmN0aW9uIGlzU2FmZUludGVnZXIobnVtYmVyKSB7XG4gICAgcmV0dXJuIGlzSW50ZWdlcihudW1iZXIpICYmIGFicyhudW1iZXIpIDw9IDB4MWZmZmZmZmZmZmZmZmY7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMS4yLjYgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBNQVhfU0FGRV9JTlRFR0VSOiAweDFmZmZmZmZmZmZmZmZmIH0pO1xuIiwiLy8gMjAuMS4yLjEwIE51bWJlci5NSU5fU0FGRV9JTlRFR0VSXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHsgTUlOX1NBRkVfSU5URUdFUjogLTB4MWZmZmZmZmZmZmZmZmYgfSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDIwLjEuMi4xMiBOdW1iZXIucGFyc2VGbG9hdChzdHJpbmcpXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChOdW1iZXIucGFyc2VGbG9hdCAhPSAkcGFyc2VGbG9hdCksICdOdW1iZXInLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDIwLjEuMi4xMyBOdW1iZXIucGFyc2VJbnQoc3RyaW5nLCByYWRpeClcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE51bWJlci5wYXJzZUludCAhPSAkcGFyc2VJbnQpLCAnTnVtYmVyJywgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgYU51bWJlclZhbHVlID0gcmVxdWlyZSgnLi9fYS1udW1iZXItdmFsdWUnKTtcbnZhciByZXBlYXQgPSByZXF1aXJlKCcuL19zdHJpbmctcmVwZWF0Jyk7XG52YXIgJHRvRml4ZWQgPSAxLjAudG9GaXhlZDtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG52YXIgZGF0YSA9IFswLCAwLCAwLCAwLCAwLCAwXTtcbnZhciBFUlJPUiA9ICdOdW1iZXIudG9GaXhlZDogaW5jb3JyZWN0IGludm9jYXRpb24hJztcbnZhciBaRVJPID0gJzAnO1xuXG52YXIgbXVsdGlwbHkgPSBmdW5jdGlvbiAobiwgYykge1xuICB2YXIgaSA9IC0xO1xuICB2YXIgYzIgPSBjO1xuICB3aGlsZSAoKytpIDwgNikge1xuICAgIGMyICs9IG4gKiBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBjMiAlIDFlNztcbiAgICBjMiA9IGZsb29yKGMyIC8gMWU3KTtcbiAgfVxufTtcbnZhciBkaXZpZGUgPSBmdW5jdGlvbiAobikge1xuICB2YXIgaSA9IDY7XG4gIHZhciBjID0gMDtcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgYyArPSBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBmbG9vcihjIC8gbik7XG4gICAgYyA9IChjICUgbikgKiAxZTc7XG4gIH1cbn07XG52YXIgbnVtVG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpID0gNjtcbiAgdmFyIHMgPSAnJztcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgaWYgKHMgIT09ICcnIHx8IGkgPT09IDAgfHwgZGF0YVtpXSAhPT0gMCkge1xuICAgICAgdmFyIHQgPSBTdHJpbmcoZGF0YVtpXSk7XG4gICAgICBzID0gcyA9PT0gJycgPyB0IDogcyArIHJlcGVhdC5jYWxsKFpFUk8sIDcgLSB0Lmxlbmd0aCkgKyB0O1xuICAgIH1cbiAgfSByZXR1cm4gcztcbn07XG52YXIgcG93ID0gZnVuY3Rpb24gKHgsIG4sIGFjYykge1xuICByZXR1cm4gbiA9PT0gMCA/IGFjYyA6IG4gJSAyID09PSAxID8gcG93KHgsIG4gLSAxLCBhY2MgKiB4KSA6IHBvdyh4ICogeCwgbiAvIDIsIGFjYyk7XG59O1xudmFyIGxvZyA9IGZ1bmN0aW9uICh4KSB7XG4gIHZhciBuID0gMDtcbiAgdmFyIHgyID0geDtcbiAgd2hpbGUgKHgyID49IDQwOTYpIHtcbiAgICBuICs9IDEyO1xuICAgIHgyIC89IDQwOTY7XG4gIH1cbiAgd2hpbGUgKHgyID49IDIpIHtcbiAgICBuICs9IDE7XG4gICAgeDIgLz0gMjtcbiAgfSByZXR1cm4gbjtcbn07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKCEhJHRvRml4ZWQgJiYgKFxuICAwLjAwMDA4LnRvRml4ZWQoMykgIT09ICcwLjAwMCcgfHxcbiAgMC45LnRvRml4ZWQoMCkgIT09ICcxJyB8fFxuICAxLjI1NS50b0ZpeGVkKDIpICE9PSAnMS4yNScgfHxcbiAgMTAwMDAwMDAwMDAwMDAwMDEyOC4wLnRvRml4ZWQoMCkgIT09ICcxMDAwMDAwMDAwMDAwMDAwMTI4J1xuKSB8fCAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b0ZpeGVkLmNhbGwoe30pO1xufSkpLCAnTnVtYmVyJywge1xuICB0b0ZpeGVkOiBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKSB7XG4gICAgdmFyIHggPSBhTnVtYmVyVmFsdWUodGhpcywgRVJST1IpO1xuICAgIHZhciBmID0gdG9JbnRlZ2VyKGZyYWN0aW9uRGlnaXRzKTtcbiAgICB2YXIgcyA9ICcnO1xuICAgIHZhciBtID0gWkVSTztcbiAgICB2YXIgZSwgeiwgaiwgaztcbiAgICBpZiAoZiA8IDAgfHwgZiA+IDIwKSB0aHJvdyBSYW5nZUVycm9yKEVSUk9SKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgaWYgKHggIT0geCkgcmV0dXJuICdOYU4nO1xuICAgIGlmICh4IDw9IC0xZTIxIHx8IHggPj0gMWUyMSkgcmV0dXJuIFN0cmluZyh4KTtcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIHMgPSAnLSc7XG4gICAgICB4ID0gLXg7XG4gICAgfVxuICAgIGlmICh4ID4gMWUtMjEpIHtcbiAgICAgIGUgPSBsb2coeCAqIHBvdygyLCA2OSwgMSkpIC0gNjk7XG4gICAgICB6ID0gZSA8IDAgPyB4ICogcG93KDIsIC1lLCAxKSA6IHggLyBwb3coMiwgZSwgMSk7XG4gICAgICB6ICo9IDB4MTAwMDAwMDAwMDAwMDA7XG4gICAgICBlID0gNTIgLSBlO1xuICAgICAgaWYgKGUgPiAwKSB7XG4gICAgICAgIG11bHRpcGx5KDAsIHopO1xuICAgICAgICBqID0gZjtcbiAgICAgICAgd2hpbGUgKGogPj0gNykge1xuICAgICAgICAgIG11bHRpcGx5KDFlNywgMCk7XG4gICAgICAgICAgaiAtPSA3O1xuICAgICAgICB9XG4gICAgICAgIG11bHRpcGx5KHBvdygxMCwgaiwgMSksIDApO1xuICAgICAgICBqID0gZSAtIDE7XG4gICAgICAgIHdoaWxlIChqID49IDIzKSB7XG4gICAgICAgICAgZGl2aWRlKDEgPDwgMjMpO1xuICAgICAgICAgIGogLT0gMjM7XG4gICAgICAgIH1cbiAgICAgICAgZGl2aWRlKDEgPDwgaik7XG4gICAgICAgIG11bHRpcGx5KDEsIDEpO1xuICAgICAgICBkaXZpZGUoMik7XG4gICAgICAgIG0gPSBudW1Ub1N0cmluZygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXVsdGlwbHkoMCwgeik7XG4gICAgICAgIG11bHRpcGx5KDEgPDwgLWUsIDApO1xuICAgICAgICBtID0gbnVtVG9TdHJpbmcoKSArIHJlcGVhdC5jYWxsKFpFUk8sIGYpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZiA+IDApIHtcbiAgICAgIGsgPSBtLmxlbmd0aDtcbiAgICAgIG0gPSBzICsgKGsgPD0gZiA/ICcwLicgKyByZXBlYXQuY2FsbChaRVJPLCBmIC0gaykgKyBtIDogbS5zbGljZSgwLCBrIC0gZikgKyAnLicgKyBtLnNsaWNlKGsgLSBmKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBzICsgbTtcbiAgICB9IHJldHVybiBtO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBhTnVtYmVyVmFsdWUgPSByZXF1aXJlKCcuL19hLW51bWJlci12YWx1ZScpO1xudmFyICR0b1ByZWNpc2lvbiA9IDEuMC50b1ByZWNpc2lvbjtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoJGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gSUU3LVxuICByZXR1cm4gJHRvUHJlY2lzaW9uLmNhbGwoMSwgdW5kZWZpbmVkKSAhPT0gJzEnO1xufSkgfHwgISRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b1ByZWNpc2lvbi5jYWxsKHt9KTtcbn0pKSwgJ051bWJlcicsIHtcbiAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbikge1xuICAgIHZhciB0aGF0ID0gYU51bWJlclZhbHVlKHRoaXMsICdOdW1iZXIjdG9QcmVjaXNpb246IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICAgIHJldHVybiBwcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/ICR0b1ByZWNpc2lvbi5jYWxsKHRoYXQpIDogJHRvUHJlY2lzaW9uLmNhbGwodGhhdCwgcHJlY2lzaW9uKTtcbiAgfVxufSk7XG4iLCIvLyAxOS4xLjMuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYsICdPYmplY3QnLCB7IGFzc2lnbjogcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7IGNyZWF0ZTogcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4zIC8gMTUuMi4zLjcgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyksICdPYmplY3QnLCB7IGRlZmluZVByb3BlcnRpZXM6IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKSB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4vLyAxOS4xLjIuNCAvIDE1LjIuMy42IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSwgJ09iamVjdCcsIHsgZGVmaW5lUHJvcGVydHk6IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmYgfSk7XG4iLCIvLyAxOS4xLjIuNSBPYmplY3QuZnJlZXplKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2ZyZWV6ZScsIGZ1bmN0aW9uICgkZnJlZXplKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmcmVlemUoaXQpIHtcbiAgICByZXR1cm4gJGZyZWV6ZSAmJiBpc09iamVjdChpdCkgPyAkZnJlZXplKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpIHtcbiAgICByZXR1cm4gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0b0lPYmplY3QoaXQpLCBrZXkpO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdnZXRPd25Qcm9wZXJ0eU5hbWVzJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0JykuZjtcbn0pO1xuIiwiLy8gMTkuMS4yLjkgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciAkZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0UHJvdG90eXBlT2YnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBnZXRQcm90b3R5cGVPZihpdCkge1xuICAgIHJldHVybiAkZ2V0UHJvdG90eXBlT2YodG9PYmplY3QoaXQpKTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjExIE9iamVjdC5pc0V4dGVuc2libGUoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzRXh0ZW5zaWJsZScsIGZ1bmN0aW9uICgkaXNFeHRlbnNpYmxlKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpc0V4dGVuc2libGUoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUoaXQpIDogdHJ1ZSA6IGZhbHNlO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTIgT2JqZWN0LmlzRnJvemVuKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc0Zyb3plbicsIGZ1bmN0aW9uICgkaXNGcm96ZW4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGlzRnJvemVuKGl0KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc0Zyb3plbiA/ICRpc0Zyb3plbihpdCkgOiBmYWxzZSA6IHRydWU7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xMyBPYmplY3QuaXNTZWFsZWQoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzU2VhbGVkJywgZnVuY3Rpb24gKCRpc1NlYWxlZCkge1xuICByZXR1cm4gZnVuY3Rpb24gaXNTZWFsZWQoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzU2VhbGVkID8gJGlzU2VhbGVkKGl0KSA6IGZhbHNlIDogdHJ1ZTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjEwIE9iamVjdC5pcyh2YWx1ZTEsIHZhbHVlMilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgaXM6IHJlcXVpcmUoJy4vX3NhbWUtdmFsdWUnKSB9KTtcbiIsIi8vIDE5LjEuMi4xNCBPYmplY3Qua2V5cyhPKVxudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2tleXMnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBrZXlzKGl0KSB7XG4gICAgcmV0dXJuICRrZXlzKHRvT2JqZWN0KGl0KSk7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xNSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgncHJldmVudEV4dGVuc2lvbnMnLCBmdW5jdGlvbiAoJHByZXZlbnRFeHRlbnNpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwcmV2ZW50RXh0ZW5zaW9ucyhpdCkge1xuICAgIHJldHVybiAkcHJldmVudEV4dGVuc2lvbnMgJiYgaXNPYmplY3QoaXQpID8gJHByZXZlbnRFeHRlbnNpb25zKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTcgT2JqZWN0LnNlYWwoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnc2VhbCcsIGZ1bmN0aW9uICgkc2VhbCkge1xuICByZXR1cm4gZnVuY3Rpb24gc2VhbChpdCkge1xuICAgIHJldHVybiAkc2VhbCAmJiBpc09iamVjdChpdCkgPyAkc2VhbChtZXRhKGl0KSkgOiBpdDtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgc2V0UHJvdG90eXBlT2Y6IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldCB9KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgdGVzdCA9IHt9O1xudGVzdFtyZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKV0gPSAneic7XG5pZiAodGVzdCArICcnICE9ICdbb2JqZWN0IHpdJykge1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKE9iamVjdC5wcm90b3R5cGUsICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAnW29iamVjdCAnICsgY2xhc3NvZih0aGlzKSArICddJztcbiAgfSwgdHJ1ZSk7XG59XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDE4LjIuNCBwYXJzZUZsb2F0KHN0cmluZylcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5GICogKHBhcnNlRmxvYXQgIT0gJHBhcnNlRmxvYXQpLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDE4LjIuNSBwYXJzZUludChzdHJpbmcsIHJhZGl4KVxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkYgKiAocGFyc2VJbnQgIT0gJHBhcnNlSW50KSwgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcbnZhciBwZXJmb3JtID0gcmVxdWlyZSgnLi9fcGVyZm9ybScpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4vX3Byb21pc2UtcmVzb2x2ZScpO1xudmFyIFBST01JU0UgPSAnUHJvbWlzZSc7XG52YXIgVHlwZUVycm9yID0gZ2xvYmFsLlR5cGVFcnJvcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgdmVyc2lvbnMgPSBwcm9jZXNzICYmIHByb2Nlc3MudmVyc2lvbnM7XG52YXIgdjggPSB2ZXJzaW9ucyAmJiB2ZXJzaW9ucy52OCB8fCAnJztcbnZhciAkUHJvbWlzZSA9IGdsb2JhbFtQUk9NSVNFXTtcbnZhciBpc05vZGUgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJztcbnZhciBlbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBJbnRlcm5hbCwgbmV3R2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBPd25Qcm9taXNlQ2FwYWJpbGl0eSwgV3JhcHBlcjtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmY7XG5cbnZhciBVU0VfTkFUSVZFID0gISFmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgLy8gY29ycmVjdCBzdWJjbGFzc2luZyB3aXRoIEBAc3BlY2llcyBzdXBwb3J0XG4gICAgdmFyIHByb21pc2UgPSAkUHJvbWlzZS5yZXNvbHZlKDEpO1xuICAgIHZhciBGYWtlUHJvbWlzZSA9IChwcm9taXNlLmNvbnN0cnVjdG9yID0ge30pW3JlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyldID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgICAgIGV4ZWMoZW1wdHksIGVtcHR5KTtcbiAgICB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpXG4gICAgICAmJiBwcm9taXNlLnRoZW4oZW1wdHkpIGluc3RhbmNlb2YgRmFrZVByb21pc2VcbiAgICAgIC8vIHY4IDYuNiAoTm9kZSAxMCBhbmQgQ2hyb21lIDY2KSBoYXZlIGEgYnVnIHdpdGggcmVzb2x2aW5nIGN1c3RvbSB0aGVuYWJsZXNcbiAgICAgIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTgzMDU2NVxuICAgICAgLy8gd2UgY2FuJ3QgZGV0ZWN0IGl0IHN5bmNocm9ub3VzbHksIHNvIGp1c3QgY2hlY2sgdmVyc2lvbnNcbiAgICAgICYmIHY4LmluZGV4T2YoJzYuNicpICE9PSAwXG4gICAgICAmJiB1c2VyQWdlbnQuaW5kZXhPZignQ2hyb21lLzY2JykgPT09IC0xO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn0oKTtcblxuLy8gaGVscGVyc1xudmFyIGlzVGhlbmFibGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIHRoZW47XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcbn07XG52YXIgbm90aWZ5ID0gZnVuY3Rpb24gKHByb21pc2UsIGlzUmVqZWN0KSB7XG4gIGlmIChwcm9taXNlLl9uKSByZXR1cm47XG4gIHByb21pc2UuX24gPSB0cnVlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9jO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIG9rID0gcHJvbWlzZS5fcyA9PSAxO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24gKHJlYWN0aW9uKSB7XG4gICAgICB2YXIgaGFuZGxlciA9IG9rID8gcmVhY3Rpb24ub2sgOiByZWFjdGlvbi5mYWlsO1xuICAgICAgdmFyIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlO1xuICAgICAgdmFyIHJlamVjdCA9IHJlYWN0aW9uLnJlamVjdDtcbiAgICAgIHZhciBkb21haW4gPSByZWFjdGlvbi5kb21haW47XG4gICAgICB2YXIgcmVzdWx0LCB0aGVuLCBleGl0ZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgIGlmIChwcm9taXNlLl9oID09IDIpIG9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xuICAgICAgICAgICAgcHJvbWlzZS5faCA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChoYW5kbGVyID09PSB0cnVlKSByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkb21haW4pIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7IC8vIG1heSB0aHJvd1xuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICBleGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKSB7XG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGRvbWFpbiAmJiAhZXhpdGVkKSBkb21haW4uZXhpdCgpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aGlsZSAoY2hhaW4ubGVuZ3RoID4gaSkgcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYgKGlzUmVqZWN0ICYmICFwcm9taXNlLl9oKSBvblVuaGFuZGxlZChwcm9taXNlKTtcbiAgfSk7XG59O1xudmFyIG9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgdGFzay5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIHVuaGFuZGxlZCA9IGlzVW5oYW5kbGVkKHByb21pc2UpO1xuICAgIHZhciByZXN1bHQsIGhhbmRsZXIsIGNvbnNvbGU7XG4gICAgaWYgKHVuaGFuZGxlZCkge1xuICAgICAgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChpc05vZGUpIHtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYW5kbGVyID0gZ2xvYmFsLm9udW5oYW5kbGVkcmVqZWN0aW9uKSB7XG4gICAgICAgICAgaGFuZGxlcih7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKGNvbnNvbGUgPSBnbG9iYWwuY29uc29sZSkgJiYgY29uc29sZS5lcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZiAodW5oYW5kbGVkICYmIHJlc3VsdC5lKSB0aHJvdyByZXN1bHQudjtcbiAgfSk7XG59O1xudmFyIGlzVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgcmV0dXJuIHByb21pc2UuX2ggIT09IDEgJiYgKHByb21pc2UuX2EgfHwgcHJvbWlzZS5fYykubGVuZ3RoID09PSAwO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFuZGxlcjtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYgKGhhbmRsZXIgPSBnbG9iYWwub25yZWplY3Rpb25oYW5kbGVkKSB7XG4gICAgICBoYW5kbGVyKHsgcHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92IH0pO1xuICAgIH1cbiAgfSk7XG59O1xudmFyICRyZWplY3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fcyA9IDI7XG4gIGlmICghcHJvbWlzZS5fYSkgcHJvbWlzZS5fYSA9IHByb21pc2UuX2Muc2xpY2UoKTtcbiAgbm90aWZ5KHByb21pc2UsIHRydWUpO1xufTtcbnZhciAkcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIHZhciB0aGVuO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB0aHJvdyBUeXBlRXJyb3IoXCJQcm9taXNlIGNhbid0IGJlIHJlc29sdmVkIGl0c2VsZlwiKTtcbiAgICBpZiAodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKSB7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgd3JhcHBlciA9IHsgX3c6IHByb21pc2UsIF9kOiBmYWxzZSB9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgJHJlamVjdC5jYWxsKHdyYXBwZXIsIGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZS5fdiA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fcyA9IDE7XG4gICAgICBub3RpZnkocHJvbWlzZSwgZmFsc2UpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgICRyZWplY3QuY2FsbCh7IF93OiBwcm9taXNlLCBfZDogZmFsc2UgfSwgZSk7IC8vIHdyYXBcbiAgfVxufTtcblxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcbmlmICghVVNFX05BVElWRSkge1xuICAvLyAyNS40LjMuMSBQcm9taXNlKGV4ZWN1dG9yKVxuICAkUHJvbWlzZSA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRQcm9taXNlLCBQUk9NSVNFLCAnX2gnKTtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGN0eCgkcmVzb2x2ZSwgdGhpcywgMSksIGN0eCgkcmVqZWN0LCB0aGlzLCAxKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAkcmVqZWN0LmNhbGwodGhpcywgZXJyKTtcbiAgICB9XG4gIH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBJbnRlcm5hbCA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgIHZhciByZWFjdGlvbiA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkUHJvbWlzZSkpO1xuICAgICAgcmVhY3Rpb24ub2sgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgPSB0eXBlb2Ygb25SZWplY3RlZCA9PSAnZnVuY3Rpb24nICYmIG9uUmVqZWN0ZWQ7XG4gICAgICByZWFjdGlvbi5kb21haW4gPSBpc05vZGUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX2MucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAodGhpcy5fYSkgdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmICh0aGlzLl9zKSBub3RpZnkodGhpcywgZmFsc2UpO1xuICAgICAgcmV0dXJuIHJlYWN0aW9uLnByb21pc2U7XG4gICAgfSxcbiAgICAvLyAyNS40LjUuMSBQcm9taXNlLnByb3RvdHlwZS5jYXRjaChvblJlamVjdGVkKVxuICAgICdjYXRjaCc6IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy50aGVuKHVuZGVmaW5lZCwgb25SZWplY3RlZCk7XG4gICAgfVxuICB9KTtcbiAgT3duUHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgSW50ZXJuYWwoKTtcbiAgICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xuICAgIHRoaXMucmVzb2x2ZSA9IGN0eCgkcmVzb2x2ZSwgcHJvbWlzZSwgMSk7XG4gICAgdGhpcy5yZWplY3QgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG4gIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmYgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uIChDKSB7XG4gICAgcmV0dXJuIEMgPT09ICRQcm9taXNlIHx8IEMgPT09IFdyYXBwZXJcbiAgICAgID8gbmV3IE93blByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICA6IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgfTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgeyBQcm9taXNlOiAkUHJvbWlzZSB9KTtcbnJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJykoJFByb21pc2UsIFBST01JU0UpO1xucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShQUk9NSVNFKTtcbldyYXBwZXIgPSByZXF1aXJlKCcuL19jb3JlJylbUFJPTUlTRV07XG5cbi8vIHN0YXRpY3NcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjUgUHJvbWlzZS5yZWplY3QocilcbiAgcmVqZWN0OiBmdW5jdGlvbiByZWplY3Qocikge1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcyk7XG4gICAgdmFyICQkcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgJCRyZWplY3Qocik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChMSUJSQVJZIHx8ICFVU0VfTkFUSVZFKSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNiBQcm9taXNlLnJlc29sdmUoeClcbiAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKExJQlJBUlkgJiYgdGhpcyA9PT0gV3JhcHBlciA/ICRQcm9taXNlIDogdGhpcywgeCk7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKFVTRV9OQVRJVkUgJiYgcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikge1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICAgIHZhciBDID0gdGhpcztcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpO1xuICAgIHZhciByZXNvbHZlID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgIHZhciByZWplY3QgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgdmFyIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgIHZhciAkaW5kZXggPSBpbmRleCsrO1xuICAgICAgICB2YXIgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKGFscmVhZHlDYWxsZWQpIHJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuZSkgcmVqZWN0KHJlc3VsdC52KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICBDLnJlc29sdmUocHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmUpIHJlamVjdChyZXN1bHQudik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjEgUmVmbGVjdC5hcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgckFwcGx5ID0gKHJlcXVpcmUoJy4vX2dsb2JhbCcpLlJlZmxlY3QgfHwge30pLmFwcGx5O1xudmFyIGZBcHBseSA9IEZ1bmN0aW9uLmFwcGx5O1xuLy8gTVMgRWRnZSBhcmd1bWVudHNMaXN0IGFyZ3VtZW50IGlzIG9wdGlvbmFsXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgckFwcGx5KGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSk7XG59KSwgJ1JlZmxlY3QnLCB7XG4gIGFwcGx5OiBmdW5jdGlvbiBhcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdCkge1xuICAgIHZhciBUID0gYUZ1bmN0aW9uKHRhcmdldCk7XG4gICAgdmFyIEwgPSBhbk9iamVjdChhcmd1bWVudHNMaXN0KTtcbiAgICByZXR1cm4gckFwcGx5ID8gckFwcGx5KFQsIHRoaXNBcmd1bWVudCwgTCkgOiBmQXBwbHkuY2FsbChULCB0aGlzQXJndW1lbnQsIEwpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMiBSZWZsZWN0LmNvbnN0cnVjdCh0YXJnZXQsIGFyZ3VtZW50c0xpc3QgWywgbmV3VGFyZ2V0XSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGJpbmQgPSByZXF1aXJlKCcuL19iaW5kJyk7XG52YXIgckNvbnN0cnVjdCA9IChyZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0IHx8IHt9KS5jb25zdHJ1Y3Q7XG5cbi8vIE1TIEVkZ2Ugc3VwcG9ydHMgb25seSAyIGFyZ3VtZW50cyBhbmQgYXJndW1lbnRzTGlzdCBhcmd1bWVudCBpcyBvcHRpb25hbFxuLy8gRkYgTmlnaHRseSBzZXRzIHRoaXJkIGFyZ3VtZW50IGFzIGBuZXcudGFyZ2V0YCwgYnV0IGRvZXMgbm90IGNyZWF0ZSBgdGhpc2AgZnJvbSBpdFxudmFyIE5FV19UQVJHRVRfQlVHID0gZmFpbHMoZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGKCkgeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiAhKHJDb25zdHJ1Y3QoZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9LCBbXSwgRikgaW5zdGFuY2VvZiBGKTtcbn0pO1xudmFyIEFSR1NfQlVHID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgckNvbnN0cnVjdChmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0pO1xufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE5FV19UQVJHRVRfQlVHIHx8IEFSR1NfQlVHKSwgJ1JlZmxlY3QnLCB7XG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gY29uc3RydWN0KFRhcmdldCwgYXJncyAvKiAsIG5ld1RhcmdldCAqLykge1xuICAgIGFGdW5jdGlvbihUYXJnZXQpO1xuICAgIGFuT2JqZWN0KGFyZ3MpO1xuICAgIHZhciBuZXdUYXJnZXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IFRhcmdldCA6IGFGdW5jdGlvbihhcmd1bWVudHNbMl0pO1xuICAgIGlmIChBUkdTX0JVRyAmJiAhTkVXX1RBUkdFVF9CVUcpIHJldHVybiByQ29uc3RydWN0KFRhcmdldCwgYXJncywgbmV3VGFyZ2V0KTtcbiAgICBpZiAoVGFyZ2V0ID09IG5ld1RhcmdldCkge1xuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBvcHRpbWl6YXRpb24gZm9yIDAtNCBhcmd1bWVudHNcbiAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IFRhcmdldCgpO1xuICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0pO1xuICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICBjYXNlIDM6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICBjYXNlIDQ6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgfVxuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBsb3Qgb2YgYXJndW1lbnRzIGNhc2VcbiAgICAgIHZhciAkYXJncyA9IFtudWxsXTtcbiAgICAgICRhcmdzLnB1c2guYXBwbHkoJGFyZ3MsIGFyZ3MpO1xuICAgICAgcmV0dXJuIG5ldyAoYmluZC5hcHBseShUYXJnZXQsICRhcmdzKSkoKTtcbiAgICB9XG4gICAgLy8gd2l0aCBhbHRlcmVkIG5ld1RhcmdldCwgbm90IHN1cHBvcnQgYnVpbHQtaW4gY29uc3RydWN0b3JzXG4gICAgdmFyIHByb3RvID0gbmV3VGFyZ2V0LnByb3RvdHlwZTtcbiAgICB2YXIgaW5zdGFuY2UgPSBjcmVhdGUoaXNPYmplY3QocHJvdG8pID8gcHJvdG8gOiBPYmplY3QucHJvdG90eXBlKTtcbiAgICB2YXIgcmVzdWx0ID0gRnVuY3Rpb24uYXBwbHkuY2FsbChUYXJnZXQsIGluc3RhbmNlLCBhcmdzKTtcbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IGluc3RhbmNlO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMyBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpXG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuXG4vLyBNUyBFZGdlIGhhcyBicm9rZW4gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSAtIHRocm93aW5nIGluc3RlYWQgb2YgcmV0dXJuaW5nIGZhbHNlXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eShkUC5mKHt9LCAxLCB7IHZhbHVlOiAxIH0pLCAxLCB7IHZhbHVlOiAyIH0pO1xufSksICdSZWZsZWN0Jywge1xuICBkZWZpbmVQcm9wZXJ0eTogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcykge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgcHJvcGVydHlLZXkgPSB0b1ByaW1pdGl2ZShwcm9wZXJ0eUtleSwgdHJ1ZSk7XG4gICAgYW5PYmplY3QoYXR0cmlidXRlcyk7XG4gICAgdHJ5IHtcbiAgICAgIGRQLmYodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59KTtcbiIsIi8vIDI2LjEuNCBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBkZWxldGVQcm9wZXJ0eTogZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHZhciBkZXNjID0gZ09QRChhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSk7XG4gICAgcmV0dXJuIGRlc2MgJiYgIWRlc2MuY29uZmlndXJhYmxlID8gZmFsc2UgOiBkZWxldGUgdGFyZ2V0W3Byb3BlcnR5S2V5XTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyNi4xLjUgUmVmbGVjdC5lbnVtZXJhdGUodGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIEVudW1lcmF0ZSA9IGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICB0aGlzLl90ID0gYW5PYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICB2YXIga2V5cyA9IHRoaXMuX2sgPSBbXTsgICAgICAvLyBrZXlzXG4gIHZhciBrZXk7XG4gIGZvciAoa2V5IGluIGl0ZXJhdGVkKSBrZXlzLnB1c2goa2V5KTtcbn07XG5yZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpKEVudW1lcmF0ZSwgJ09iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIga2V5cyA9IHRoYXQuX2s7XG4gIHZhciBrZXk7XG4gIGRvIHtcbiAgICBpZiAodGhhdC5faSA+PSBrZXlzLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICB9IHdoaWxlICghKChrZXkgPSBrZXlzW3RoYXQuX2krK10pIGluIHRoYXQuX3QpKTtcbiAgcmV0dXJuIHsgdmFsdWU6IGtleSwgZG9uZTogZmFsc2UgfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGVudW1lcmF0ZTogZnVuY3Rpb24gZW51bWVyYXRlKHRhcmdldCkge1xuICAgIHJldHVybiBuZXcgRW51bWVyYXRlKHRhcmdldCk7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS43IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuOCBSZWZsZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZ2V0UHJvdG8gPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBnZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSB7XG4gICAgcmV0dXJuIGdldFByb3RvKGFuT2JqZWN0KHRhcmdldCkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuNiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3BlcnR5S2V5IFssIHJlY2VpdmVyXSlcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xuXG5mdW5jdGlvbiBnZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSAvKiAsIHJlY2VpdmVyICovKSB7XG4gIHZhciByZWNlaXZlciA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdGFyZ2V0IDogYXJndW1lbnRzWzJdO1xuICB2YXIgZGVzYywgcHJvdG87XG4gIGlmIChhbk9iamVjdCh0YXJnZXQpID09PSByZWNlaXZlcikgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eUtleV07XG4gIGlmIChkZXNjID0gZ09QRC5mKHRhcmdldCwgcHJvcGVydHlLZXkpKSByZXR1cm4gaGFzKGRlc2MsICd2YWx1ZScpXG4gICAgPyBkZXNjLnZhbHVlXG4gICAgOiBkZXNjLmdldCAhPT0gdW5kZWZpbmVkXG4gICAgICA/IGRlc2MuZ2V0LmNhbGwocmVjZWl2ZXIpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHJldHVybiBnZXQocHJvdG8sIHByb3BlcnR5S2V5LCByZWNlaXZlcik7XG59XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHsgZ2V0OiBnZXQgfSk7XG4iLCIvLyAyNi4xLjkgUmVmbGVjdC5oYXModGFyZ2V0LCBwcm9wZXJ0eUtleSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaGFzOiBmdW5jdGlvbiBoYXModGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBwcm9wZXJ0eUtleSBpbiB0YXJnZXQ7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMCBSZWZsZWN0LmlzRXh0ZW5zaWJsZSh0YXJnZXQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaXNFeHRlbnNpYmxlOiBmdW5jdGlvbiBpc0V4dGVuc2libGUodGFyZ2V0KSB7XG4gICAgYW5PYmplY3QodGFyZ2V0KTtcbiAgICByZXR1cm4gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUodGFyZ2V0KSA6IHRydWU7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMSBSZWZsZWN0Lm93bktleXModGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBvd25LZXlzOiByZXF1aXJlKCcuL19vd24ta2V5cycpIH0pO1xuIiwiLy8gMjYuMS4xMiBSZWZsZWN0LnByZXZlbnRFeHRlbnNpb25zKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciAkcHJldmVudEV4dGVuc2lvbnMgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgcHJldmVudEV4dGVuc2lvbnM6IGZ1bmN0aW9uIHByZXZlbnRFeHRlbnNpb25zKHRhcmdldCkge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICgkcHJldmVudEV4dGVuc2lvbnMpICRwcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufSk7XG4iLCIvLyAyNi4xLjE0IFJlZmxlY3Quc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgc2V0UHJvdG8gPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKTtcblxuaWYgKHNldFByb3RvKSAkZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIHNldFByb3RvdHlwZU9mOiBmdW5jdGlvbiBzZXRQcm90b3R5cGVPZih0YXJnZXQsIHByb3RvKSB7XG4gICAgc2V0UHJvdG8uY2hlY2sodGFyZ2V0LCBwcm90byk7XG4gICAgdHJ5IHtcbiAgICAgIHNldFByb3RvLnNldCh0YXJnZXQsIHByb3RvKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMyBSZWZsZWN0LnNldCh0YXJnZXQsIHByb3BlcnR5S2V5LCBWIFssIHJlY2VpdmVyXSlcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxuZnVuY3Rpb24gc2V0KHRhcmdldCwgcHJvcGVydHlLZXksIFYgLyogLCByZWNlaXZlciAqLykge1xuICB2YXIgcmVjZWl2ZXIgPSBhcmd1bWVudHMubGVuZ3RoIDwgNCA/IHRhcmdldCA6IGFyZ3VtZW50c1szXTtcbiAgdmFyIG93bkRlc2MgPSBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB2YXIgZXhpc3RpbmdEZXNjcmlwdG9yLCBwcm90bztcbiAgaWYgKCFvd25EZXNjKSB7XG4gICAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHtcbiAgICAgIHJldHVybiBzZXQocHJvdG8sIHByb3BlcnR5S2V5LCBWLCByZWNlaXZlcik7XG4gICAgfVxuICAgIG93bkRlc2MgPSBjcmVhdGVEZXNjKDApO1xuICB9XG4gIGlmIChoYXMob3duRGVzYywgJ3ZhbHVlJykpIHtcbiAgICBpZiAob3duRGVzYy53cml0YWJsZSA9PT0gZmFsc2UgfHwgIWlzT2JqZWN0KHJlY2VpdmVyKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChleGlzdGluZ0Rlc2NyaXB0b3IgPSBnT1BELmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5KSkge1xuICAgICAgaWYgKGV4aXN0aW5nRGVzY3JpcHRvci5nZXQgfHwgZXhpc3RpbmdEZXNjcmlwdG9yLnNldCB8fCBleGlzdGluZ0Rlc2NyaXB0b3Iud3JpdGFibGUgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgICBleGlzdGluZ0Rlc2NyaXB0b3IudmFsdWUgPSBWO1xuICAgICAgZFAuZihyZWNlaXZlciwgcHJvcGVydHlLZXksIGV4aXN0aW5nRGVzY3JpcHRvcik7XG4gICAgfSBlbHNlIGRQLmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5LCBjcmVhdGVEZXNjKDAsIFYpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gb3duRGVzYy5zZXQgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogKG93bkRlc2Muc2V0LmNhbGwocmVjZWl2ZXIsIFYpLCB0cnVlKTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBzZXQ6IHNldCB9KTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBpbmhlcml0SWZSZXF1aXJlZCA9IHJlcXVpcmUoJy4vX2luaGVyaXQtaWYtcmVxdWlyZWQnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBpc1JlZ0V4cCA9IHJlcXVpcmUoJy4vX2lzLXJlZ2V4cCcpO1xudmFyICRmbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG52YXIgJFJlZ0V4cCA9IGdsb2JhbC5SZWdFeHA7XG52YXIgQmFzZSA9ICRSZWdFeHA7XG52YXIgcHJvdG8gPSAkUmVnRXhwLnByb3RvdHlwZTtcbnZhciByZTEgPSAvYS9nO1xudmFyIHJlMiA9IC9hL2c7XG4vLyBcIm5ld1wiIGNyZWF0ZXMgYSBuZXcgb2JqZWN0LCBvbGQgd2Via2l0IGJ1Z2d5IGhlcmVcbnZhciBDT1JSRUNUX05FVyA9IG5ldyAkUmVnRXhwKHJlMSkgIT09IHJlMTtcblxuaWYgKHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgKCFDT1JSRUNUX05FVyB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmUyW3JlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpXSA9IGZhbHNlO1xuICAvLyBSZWdFeHAgY29uc3RydWN0b3IgY2FuIGFsdGVyIGZsYWdzIGFuZCBJc1JlZ0V4cCB3b3JrcyBjb3JyZWN0IHdpdGggQEBtYXRjaFxuICByZXR1cm4gJFJlZ0V4cChyZTEpICE9IHJlMSB8fCAkUmVnRXhwKHJlMikgPT0gcmUyIHx8ICRSZWdFeHAocmUxLCAnaScpICE9ICcvYS9pJztcbn0pKSkge1xuICAkUmVnRXhwID0gZnVuY3Rpb24gUmVnRXhwKHAsIGYpIHtcbiAgICB2YXIgdGlSRSA9IHRoaXMgaW5zdGFuY2VvZiAkUmVnRXhwO1xuICAgIHZhciBwaVJFID0gaXNSZWdFeHAocCk7XG4gICAgdmFyIGZpVSA9IGYgPT09IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gIXRpUkUgJiYgcGlSRSAmJiBwLmNvbnN0cnVjdG9yID09PSAkUmVnRXhwICYmIGZpVSA/IHBcbiAgICAgIDogaW5oZXJpdElmUmVxdWlyZWQoQ09SUkVDVF9ORVdcbiAgICAgICAgPyBuZXcgQmFzZShwaVJFICYmICFmaVUgPyBwLnNvdXJjZSA6IHAsIGYpXG4gICAgICAgIDogQmFzZSgocGlSRSA9IHAgaW5zdGFuY2VvZiAkUmVnRXhwKSA/IHAuc291cmNlIDogcCwgcGlSRSAmJiBmaVUgPyAkZmxhZ3MuY2FsbChwKSA6IGYpXG4gICAgICAsIHRpUkUgPyB0aGlzIDogcHJvdG8sICRSZWdFeHApO1xuICB9O1xuICB2YXIgcHJveHkgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAga2V5IGluICRSZWdFeHAgfHwgZFAoJFJlZ0V4cCwga2V5LCB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIEJhc2Vba2V5XTsgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gKGl0KSB7IEJhc2Vba2V5XSA9IGl0OyB9XG4gICAgfSk7XG4gIH07XG4gIGZvciAodmFyIGtleXMgPSBnT1BOKEJhc2UpLCBpID0gMDsga2V5cy5sZW5ndGggPiBpOykgcHJveHkoa2V5c1tpKytdKTtcbiAgcHJvdG8uY29uc3RydWN0b3IgPSAkUmVnRXhwO1xuICAkUmVnRXhwLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKGdsb2JhbCwgJ1JlZ0V4cCcsICRSZWdFeHApO1xufVxuXG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdSZWdFeHAnKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciByZWdleHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMnKTtcbnJlcXVpcmUoJy4vX2V4cG9ydCcpKHtcbiAgdGFyZ2V0OiAnUmVnRXhwJyxcbiAgcHJvdG86IHRydWUsXG4gIGZvcmNlZDogcmVnZXhwRXhlYyAhPT0gLy4vLmV4ZWNcbn0sIHtcbiAgZXhlYzogcmVnZXhwRXhlY1xufSk7XG4iLCIvLyAyMS4yLjUuMyBnZXQgUmVnRXhwLnByb3RvdHlwZS5mbGFncygpXG5pZiAocmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAvLi9nLmZsYWdzICE9ICdnJykgcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZihSZWdFeHAucHJvdG90eXBlLCAnZmxhZ3MnLCB7XG4gIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgZ2V0OiByZXF1aXJlKCcuL19mbGFncycpXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBhZHZhbmNlU3RyaW5nSW5kZXggPSByZXF1aXJlKCcuL19hZHZhbmNlLXN0cmluZy1pbmRleCcpO1xudmFyIHJlZ0V4cEV4ZWMgPSByZXF1aXJlKCcuL19yZWdleHAtZXhlYy1hYnN0cmFjdCcpO1xuXG4vLyBAQG1hdGNoIGxvZ2ljXG5yZXF1aXJlKCcuL19maXgtcmUtd2tzJykoJ21hdGNoJywgMSwgZnVuY3Rpb24gKGRlZmluZWQsIE1BVENILCAkbWF0Y2gsIG1heWJlQ2FsbE5hdGl2ZSkge1xuICByZXR1cm4gW1xuICAgIC8vIGBTdHJpbmcucHJvdG90eXBlLm1hdGNoYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLm1hdGNoXG4gICAgZnVuY3Rpb24gbWF0Y2gocmVnZXhwKSB7XG4gICAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgICB2YXIgZm4gPSByZWdleHAgPT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogcmVnZXhwW01BVENIXTtcbiAgICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW01BVENIXShTdHJpbmcoTykpO1xuICAgIH0sXG4gICAgLy8gYFJlZ0V4cC5wcm90b3R5cGVbQEBtYXRjaF1gIG1ldGhvZFxuICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXJlZ2V4cC5wcm90b3R5cGUtQEBtYXRjaFxuICAgIGZ1bmN0aW9uIChyZWdleHApIHtcbiAgICAgIHZhciByZXMgPSBtYXliZUNhbGxOYXRpdmUoJG1hdGNoLCByZWdleHAsIHRoaXMpO1xuICAgICAgaWYgKHJlcy5kb25lKSByZXR1cm4gcmVzLnZhbHVlO1xuICAgICAgdmFyIHJ4ID0gYW5PYmplY3QocmVnZXhwKTtcbiAgICAgIHZhciBTID0gU3RyaW5nKHRoaXMpO1xuICAgICAgaWYgKCFyeC5nbG9iYWwpIHJldHVybiByZWdFeHBFeGVjKHJ4LCBTKTtcbiAgICAgIHZhciBmdWxsVW5pY29kZSA9IHJ4LnVuaWNvZGU7XG4gICAgICByeC5sYXN0SW5kZXggPSAwO1xuICAgICAgdmFyIEEgPSBbXTtcbiAgICAgIHZhciBuID0gMDtcbiAgICAgIHZhciByZXN1bHQ7XG4gICAgICB3aGlsZSAoKHJlc3VsdCA9IHJlZ0V4cEV4ZWMocngsIFMpKSAhPT0gbnVsbCkge1xuICAgICAgICB2YXIgbWF0Y2hTdHIgPSBTdHJpbmcocmVzdWx0WzBdKTtcbiAgICAgICAgQVtuXSA9IG1hdGNoU3RyO1xuICAgICAgICBpZiAobWF0Y2hTdHIgPT09ICcnKSByeC5sYXN0SW5kZXggPSBhZHZhbmNlU3RyaW5nSW5kZXgoUywgdG9MZW5ndGgocngubGFzdEluZGV4KSwgZnVsbFVuaWNvZGUpO1xuICAgICAgICBuKys7XG4gICAgICB9XG4gICAgICByZXR1cm4gbiA9PT0gMCA/IG51bGwgOiBBO1xuICAgIH1cbiAgXTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIGFkdmFuY2VTdHJpbmdJbmRleCA9IHJlcXVpcmUoJy4vX2FkdmFuY2Utc3RyaW5nLWluZGV4Jyk7XG52YXIgcmVnRXhwRXhlYyA9IHJlcXVpcmUoJy4vX3JlZ2V4cC1leGVjLWFic3RyYWN0Jyk7XG52YXIgbWF4ID0gTWF0aC5tYXg7XG52YXIgbWluID0gTWF0aC5taW47XG52YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xudmFyIFNVQlNUSVRVVElPTl9TWU1CT0xTID0gL1xcJChbJCZgJ118XFxkXFxkP3w8W14+XSo+KS9nO1xudmFyIFNVQlNUSVRVVElPTl9TWU1CT0xTX05PX05BTUVEID0gL1xcJChbJCZgJ118XFxkXFxkPykvZztcblxudmFyIG1heWJlVG9TdHJpbmcgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ID09PSB1bmRlZmluZWQgPyBpdCA6IFN0cmluZyhpdCk7XG59O1xuXG4vLyBAQHJlcGxhY2UgbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgncmVwbGFjZScsIDIsIGZ1bmN0aW9uIChkZWZpbmVkLCBSRVBMQUNFLCAkcmVwbGFjZSwgbWF5YmVDYWxsTmF0aXZlKSB7XG4gIHJldHVybiBbXG4gICAgLy8gYFN0cmluZy5wcm90b3R5cGUucmVwbGFjZWAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtc3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlXG4gICAgZnVuY3Rpb24gcmVwbGFjZShzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKSB7XG4gICAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgICB2YXIgZm4gPSBzZWFyY2hWYWx1ZSA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzZWFyY2hWYWx1ZVtSRVBMQUNFXTtcbiAgICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gZm4uY2FsbChzZWFyY2hWYWx1ZSwgTywgcmVwbGFjZVZhbHVlKVxuICAgICAgICA6ICRyZXBsYWNlLmNhbGwoU3RyaW5nKE8pLCBzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAcmVwbGFjZV1gIG1ldGhvZFxuICAgIC8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXJlZ2V4cC5wcm90b3R5cGUtQEByZXBsYWNlXG4gICAgZnVuY3Rpb24gKHJlZ2V4cCwgcmVwbGFjZVZhbHVlKSB7XG4gICAgICB2YXIgcmVzID0gbWF5YmVDYWxsTmF0aXZlKCRyZXBsYWNlLCByZWdleHAsIHRoaXMsIHJlcGxhY2VWYWx1ZSk7XG4gICAgICBpZiAocmVzLmRvbmUpIHJldHVybiByZXMudmFsdWU7XG5cbiAgICAgIHZhciByeCA9IGFuT2JqZWN0KHJlZ2V4cCk7XG4gICAgICB2YXIgUyA9IFN0cmluZyh0aGlzKTtcbiAgICAgIHZhciBmdW5jdGlvbmFsUmVwbGFjZSA9IHR5cGVvZiByZXBsYWNlVmFsdWUgPT09ICdmdW5jdGlvbic7XG4gICAgICBpZiAoIWZ1bmN0aW9uYWxSZXBsYWNlKSByZXBsYWNlVmFsdWUgPSBTdHJpbmcocmVwbGFjZVZhbHVlKTtcbiAgICAgIHZhciBnbG9iYWwgPSByeC5nbG9iYWw7XG4gICAgICBpZiAoZ2xvYmFsKSB7XG4gICAgICAgIHZhciBmdWxsVW5pY29kZSA9IHJ4LnVuaWNvZGU7XG4gICAgICAgIHJ4Lmxhc3RJbmRleCA9IDA7XG4gICAgICB9XG4gICAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlZ0V4cEV4ZWMocngsIFMpO1xuICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSBicmVhaztcbiAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgIGlmICghZ2xvYmFsKSBicmVhaztcbiAgICAgICAgdmFyIG1hdGNoU3RyID0gU3RyaW5nKHJlc3VsdFswXSk7XG4gICAgICAgIGlmIChtYXRjaFN0ciA9PT0gJycpIHJ4Lmxhc3RJbmRleCA9IGFkdmFuY2VTdHJpbmdJbmRleChTLCB0b0xlbmd0aChyeC5sYXN0SW5kZXgpLCBmdWxsVW5pY29kZSk7XG4gICAgICB9XG4gICAgICB2YXIgYWNjdW11bGF0ZWRSZXN1bHQgPSAnJztcbiAgICAgIHZhciBuZXh0U291cmNlUG9zaXRpb24gPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdHNbaV07XG4gICAgICAgIHZhciBtYXRjaGVkID0gU3RyaW5nKHJlc3VsdFswXSk7XG4gICAgICAgIHZhciBwb3NpdGlvbiA9IG1heChtaW4odG9JbnRlZ2VyKHJlc3VsdC5pbmRleCksIFMubGVuZ3RoKSwgMCk7XG4gICAgICAgIHZhciBjYXB0dXJlcyA9IFtdO1xuICAgICAgICAvLyBOT1RFOiBUaGlzIGlzIGVxdWl2YWxlbnQgdG9cbiAgICAgICAgLy8gICBjYXB0dXJlcyA9IHJlc3VsdC5zbGljZSgxKS5tYXAobWF5YmVUb1N0cmluZylcbiAgICAgICAgLy8gYnV0IGZvciBzb21lIHJlYXNvbiBgbmF0aXZlU2xpY2UuY2FsbChyZXN1bHQsIDEsIHJlc3VsdC5sZW5ndGgpYCAoY2FsbGVkIGluXG4gICAgICAgIC8vIHRoZSBzbGljZSBwb2x5ZmlsbCB3aGVuIHNsaWNpbmcgbmF0aXZlIGFycmF5cykgXCJkb2Vzbid0IHdvcmtcIiBpbiBzYWZhcmkgOSBhbmRcbiAgICAgICAgLy8gY2F1c2VzIGEgY3Jhc2ggKGh0dHBzOi8vcGFzdGViaW4uY29tL04yMVF6ZVFBKSB3aGVuIHRyeWluZyB0byBkZWJ1ZyBpdC5cbiAgICAgICAgZm9yICh2YXIgaiA9IDE7IGogPCByZXN1bHQubGVuZ3RoOyBqKyspIGNhcHR1cmVzLnB1c2gobWF5YmVUb1N0cmluZyhyZXN1bHRbal0pKTtcbiAgICAgICAgdmFyIG5hbWVkQ2FwdHVyZXMgPSByZXN1bHQuZ3JvdXBzO1xuICAgICAgICBpZiAoZnVuY3Rpb25hbFJlcGxhY2UpIHtcbiAgICAgICAgICB2YXIgcmVwbGFjZXJBcmdzID0gW21hdGNoZWRdLmNvbmNhdChjYXB0dXJlcywgcG9zaXRpb24sIFMpO1xuICAgICAgICAgIGlmIChuYW1lZENhcHR1cmVzICE9PSB1bmRlZmluZWQpIHJlcGxhY2VyQXJncy5wdXNoKG5hbWVkQ2FwdHVyZXMpO1xuICAgICAgICAgIHZhciByZXBsYWNlbWVudCA9IFN0cmluZyhyZXBsYWNlVmFsdWUuYXBwbHkodW5kZWZpbmVkLCByZXBsYWNlckFyZ3MpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXBsYWNlbWVudCA9IGdldFN1YnN0aXR1dGlvbihtYXRjaGVkLCBTLCBwb3NpdGlvbiwgY2FwdHVyZXMsIG5hbWVkQ2FwdHVyZXMsIHJlcGxhY2VWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uID49IG5leHRTb3VyY2VQb3NpdGlvbikge1xuICAgICAgICAgIGFjY3VtdWxhdGVkUmVzdWx0ICs9IFMuc2xpY2UobmV4dFNvdXJjZVBvc2l0aW9uLCBwb3NpdGlvbikgKyByZXBsYWNlbWVudDtcbiAgICAgICAgICBuZXh0U291cmNlUG9zaXRpb24gPSBwb3NpdGlvbiArIG1hdGNoZWQubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW11bGF0ZWRSZXN1bHQgKyBTLnNsaWNlKG5leHRTb3VyY2VQb3NpdGlvbik7XG4gICAgfVxuICBdO1xuXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtZ2V0c3Vic3RpdHV0aW9uXG4gIGZ1bmN0aW9uIGdldFN1YnN0aXR1dGlvbihtYXRjaGVkLCBzdHIsIHBvc2l0aW9uLCBjYXB0dXJlcywgbmFtZWRDYXB0dXJlcywgcmVwbGFjZW1lbnQpIHtcbiAgICB2YXIgdGFpbFBvcyA9IHBvc2l0aW9uICsgbWF0Y2hlZC5sZW5ndGg7XG4gICAgdmFyIG0gPSBjYXB0dXJlcy5sZW5ndGg7XG4gICAgdmFyIHN5bWJvbHMgPSBTVUJTVElUVVRJT05fU1lNQk9MU19OT19OQU1FRDtcbiAgICBpZiAobmFtZWRDYXB0dXJlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBuYW1lZENhcHR1cmVzID0gdG9PYmplY3QobmFtZWRDYXB0dXJlcyk7XG4gICAgICBzeW1ib2xzID0gU1VCU1RJVFVUSU9OX1NZTUJPTFM7XG4gICAgfVxuICAgIHJldHVybiAkcmVwbGFjZS5jYWxsKHJlcGxhY2VtZW50LCBzeW1ib2xzLCBmdW5jdGlvbiAobWF0Y2gsIGNoKSB7XG4gICAgICB2YXIgY2FwdHVyZTtcbiAgICAgIHN3aXRjaCAoY2guY2hhckF0KDApKSB7XG4gICAgICAgIGNhc2UgJyQnOiByZXR1cm4gJyQnO1xuICAgICAgICBjYXNlICcmJzogcmV0dXJuIG1hdGNoZWQ7XG4gICAgICAgIGNhc2UgJ2AnOiByZXR1cm4gc3RyLnNsaWNlKDAsIHBvc2l0aW9uKTtcbiAgICAgICAgY2FzZSBcIidcIjogcmV0dXJuIHN0ci5zbGljZSh0YWlsUG9zKTtcbiAgICAgICAgY2FzZSAnPCc6XG4gICAgICAgICAgY2FwdHVyZSA9IG5hbWVkQ2FwdHVyZXNbY2guc2xpY2UoMSwgLTEpXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDogLy8gXFxkXFxkP1xuICAgICAgICAgIHZhciBuID0gK2NoO1xuICAgICAgICAgIGlmIChuID09PSAwKSByZXR1cm4gbWF0Y2g7XG4gICAgICAgICAgaWYgKG4gPiBtKSB7XG4gICAgICAgICAgICB2YXIgZiA9IGZsb29yKG4gLyAxMCk7XG4gICAgICAgICAgICBpZiAoZiA9PT0gMCkgcmV0dXJuIG1hdGNoO1xuICAgICAgICAgICAgaWYgKGYgPD0gbSkgcmV0dXJuIGNhcHR1cmVzW2YgLSAxXSA9PT0gdW5kZWZpbmVkID8gY2guY2hhckF0KDEpIDogY2FwdHVyZXNbZiAtIDFdICsgY2guY2hhckF0KDEpO1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXB0dXJlID0gY2FwdHVyZXNbbiAtIDFdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNhcHR1cmUgPT09IHVuZGVmaW5lZCA/ICcnIDogY2FwdHVyZTtcbiAgICB9KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHNhbWVWYWx1ZSA9IHJlcXVpcmUoJy4vX3NhbWUtdmFsdWUnKTtcbnZhciByZWdFeHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMtYWJzdHJhY3QnKTtcblxuLy8gQEBzZWFyY2ggbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgnc2VhcmNoJywgMSwgZnVuY3Rpb24gKGRlZmluZWQsIFNFQVJDSCwgJHNlYXJjaCwgbWF5YmVDYWxsTmF0aXZlKSB7XG4gIHJldHVybiBbXG4gICAgLy8gYFN0cmluZy5wcm90b3R5cGUuc2VhcmNoYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLnNlYXJjaFxuICAgIGZ1bmN0aW9uIHNlYXJjaChyZWdleHApIHtcbiAgICAgIHZhciBPID0gZGVmaW5lZCh0aGlzKTtcbiAgICAgIHZhciBmbiA9IHJlZ2V4cCA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZWdleHBbU0VBUkNIXTtcbiAgICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW1NFQVJDSF0oU3RyaW5nKE8pKTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAc2VhcmNoXWAgbWV0aG9kXG4gICAgLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9lY21hMjYyLyNzZWMtcmVnZXhwLnByb3RvdHlwZS1AQHNlYXJjaFxuICAgIGZ1bmN0aW9uIChyZWdleHApIHtcbiAgICAgIHZhciByZXMgPSBtYXliZUNhbGxOYXRpdmUoJHNlYXJjaCwgcmVnZXhwLCB0aGlzKTtcbiAgICAgIGlmIChyZXMuZG9uZSkgcmV0dXJuIHJlcy52YWx1ZTtcbiAgICAgIHZhciByeCA9IGFuT2JqZWN0KHJlZ2V4cCk7XG4gICAgICB2YXIgUyA9IFN0cmluZyh0aGlzKTtcbiAgICAgIHZhciBwcmV2aW91c0xhc3RJbmRleCA9IHJ4Lmxhc3RJbmRleDtcbiAgICAgIGlmICghc2FtZVZhbHVlKHByZXZpb3VzTGFzdEluZGV4LCAwKSkgcngubGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciByZXN1bHQgPSByZWdFeHBFeGVjKHJ4LCBTKTtcbiAgICAgIGlmICghc2FtZVZhbHVlKHJ4Lmxhc3RJbmRleCwgcHJldmlvdXNMYXN0SW5kZXgpKSByeC5sYXN0SW5kZXggPSBwcmV2aW91c0xhc3RJbmRleDtcbiAgICAgIHJldHVybiByZXN1bHQgPT09IG51bGwgPyAtMSA6IHJlc3VsdC5pbmRleDtcbiAgICB9XG4gIF07XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGlzUmVnRXhwID0gcmVxdWlyZSgnLi9faXMtcmVnZXhwJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgYWR2YW5jZVN0cmluZ0luZGV4ID0gcmVxdWlyZSgnLi9fYWR2YW5jZS1zdHJpbmctaW5kZXgnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGNhbGxSZWdFeHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMtYWJzdHJhY3QnKTtcbnZhciByZWdleHBFeGVjID0gcmVxdWlyZSgnLi9fcmVnZXhwLWV4ZWMnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgJG1pbiA9IE1hdGgubWluO1xudmFyICRwdXNoID0gW10ucHVzaDtcbnZhciAkU1BMSVQgPSAnc3BsaXQnO1xudmFyIExFTkdUSCA9ICdsZW5ndGgnO1xudmFyIExBU1RfSU5ERVggPSAnbGFzdEluZGV4JztcbnZhciBNQVhfVUlOVDMyID0gMHhmZmZmZmZmZjtcblxuLy8gYmFiZWwtbWluaWZ5IHRyYW5zcGlsZXMgUmVnRXhwKCd4JywgJ3knKSAtPiAveC95IGFuZCBpdCBjYXVzZXMgU3ludGF4RXJyb3JcbnZhciBTVVBQT1JUU19ZID0gIWZhaWxzKGZ1bmN0aW9uICgpIHsgUmVnRXhwKE1BWF9VSU5UMzIsICd5Jyk7IH0pO1xuXG4vLyBAQHNwbGl0IGxvZ2ljXG5yZXF1aXJlKCcuL19maXgtcmUtd2tzJykoJ3NwbGl0JywgMiwgZnVuY3Rpb24gKGRlZmluZWQsIFNQTElULCAkc3BsaXQsIG1heWJlQ2FsbE5hdGl2ZSkge1xuICB2YXIgaW50ZXJuYWxTcGxpdDtcbiAgaWYgKFxuICAgICdhYmJjJ1skU1BMSVRdKC8oYikqLylbMV0gPT0gJ2MnIHx8XG4gICAgJ3Rlc3QnWyRTUExJVF0oLyg/OikvLCAtMSlbTEVOR1RIXSAhPSA0IHx8XG4gICAgJ2FiJ1skU1BMSVRdKC8oPzphYikqLylbTEVOR1RIXSAhPSAyIHx8XG4gICAgJy4nWyRTUExJVF0oLyguPykoLj8pLylbTEVOR1RIXSAhPSA0IHx8XG4gICAgJy4nWyRTUExJVF0oLygpKCkvKVtMRU5HVEhdID4gMSB8fFxuICAgICcnWyRTUExJVF0oLy4/LylbTEVOR1RIXVxuICApIHtcbiAgICAvLyBiYXNlZCBvbiBlczUtc2hpbSBpbXBsZW1lbnRhdGlvbiwgbmVlZCB0byByZXdvcmsgaXRcbiAgICBpbnRlcm5hbFNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIHZhciBzdHJpbmcgPSBTdHJpbmcodGhpcyk7XG4gICAgICBpZiAoc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDApIHJldHVybiBbXTtcbiAgICAgIC8vIElmIGBzZXBhcmF0b3JgIGlzIG5vdCBhIHJlZ2V4LCB1c2UgbmF0aXZlIHNwbGl0XG4gICAgICBpZiAoIWlzUmVnRXhwKHNlcGFyYXRvcikpIHJldHVybiAkc3BsaXQuY2FsbChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgdmFyIGZsYWdzID0gKHNlcGFyYXRvci5pZ25vcmVDYXNlID8gJ2knIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IubXVsdGlsaW5lID8gJ20nIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnN0aWNreSA/ICd5JyA6ICcnKTtcbiAgICAgIHZhciBsYXN0TGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciBzcGxpdExpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IE1BWF9VSU5UMzIgOiBsaW1pdCA+Pj4gMDtcbiAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICB2YXIgc2VwYXJhdG9yQ29weSA9IG5ldyBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgZmxhZ3MgKyAnZycpO1xuICAgICAgdmFyIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGg7XG4gICAgICB3aGlsZSAobWF0Y2ggPSByZWdleHBFeGVjLmNhbGwoc2VwYXJhdG9yQ29weSwgc3RyaW5nKSkge1xuICAgICAgICBsYXN0SW5kZXggPSBzZXBhcmF0b3JDb3B5W0xBU1RfSU5ERVhdO1xuICAgICAgICBpZiAobGFzdEluZGV4ID4gbGFzdExhc3RJbmRleCkge1xuICAgICAgICAgIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgIGlmIChtYXRjaFtMRU5HVEhdID4gMSAmJiBtYXRjaC5pbmRleCA8IHN0cmluZ1tMRU5HVEhdKSAkcHVzaC5hcHBseShvdXRwdXQsIG1hdGNoLnNsaWNlKDEpKTtcbiAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF1bTEVOR1RIXTtcbiAgICAgICAgICBsYXN0TGFzdEluZGV4ID0gbGFzdEluZGV4O1xuICAgICAgICAgIGlmIChvdXRwdXRbTEVOR1RIXSA+PSBzcGxpdExpbWl0KSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VwYXJhdG9yQ29weVtMQVNUX0lOREVYXSA9PT0gbWF0Y2guaW5kZXgpIHNlcGFyYXRvckNvcHlbTEFTVF9JTkRFWF0rKzsgLy8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcFxuICAgICAgfVxuICAgICAgaWYgKGxhc3RMYXN0SW5kZXggPT09IHN0cmluZ1tMRU5HVEhdKSB7XG4gICAgICAgIGlmIChsYXN0TGVuZ3RoIHx8ICFzZXBhcmF0b3JDb3B5LnRlc3QoJycpKSBvdXRwdXQucHVzaCgnJyk7XG4gICAgICB9IGVsc2Ugb3V0cHV0LnB1c2goc3RyaW5nLnNsaWNlKGxhc3RMYXN0SW5kZXgpKTtcbiAgICAgIHJldHVybiBvdXRwdXRbTEVOR1RIXSA+IHNwbGl0TGltaXQgPyBvdXRwdXQuc2xpY2UoMCwgc3BsaXRMaW1pdCkgOiBvdXRwdXQ7XG4gICAgfTtcbiAgLy8gQ2hha3JhLCBWOFxuICB9IGVsc2UgaWYgKCcwJ1skU1BMSVRdKHVuZGVmaW5lZCwgMClbTEVOR1RIXSkge1xuICAgIGludGVybmFsU3BsaXQgPSBmdW5jdGlvbiAoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgcmV0dXJuIHNlcGFyYXRvciA9PT0gdW5kZWZpbmVkICYmIGxpbWl0ID09PSAwID8gW10gOiAkc3BsaXQuY2FsbCh0aGlzLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGludGVybmFsU3BsaXQgPSAkc3BsaXQ7XG4gIH1cblxuICByZXR1cm4gW1xuICAgIC8vIGBTdHJpbmcucHJvdG90eXBlLnNwbGl0YCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1zdHJpbmcucHJvdG90eXBlLnNwbGl0XG4gICAgZnVuY3Rpb24gc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgdmFyIE8gPSBkZWZpbmVkKHRoaXMpO1xuICAgICAgdmFyIHNwbGl0dGVyID0gc2VwYXJhdG9yID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNlcGFyYXRvcltTUExJVF07XG4gICAgICByZXR1cm4gc3BsaXR0ZXIgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHNwbGl0dGVyLmNhbGwoc2VwYXJhdG9yLCBPLCBsaW1pdClcbiAgICAgICAgOiBpbnRlcm5hbFNwbGl0LmNhbGwoU3RyaW5nKE8pLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICB9LFxuICAgIC8vIGBSZWdFeHAucHJvdG90eXBlW0BAc3BsaXRdYCBtZXRob2RcbiAgICAvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy1yZWdleHAucHJvdG90eXBlLUBAc3BsaXRcbiAgICAvL1xuICAgIC8vIE5PVEU6IFRoaXMgY2Fubm90IGJlIHByb3Blcmx5IHBvbHlmaWxsZWQgaW4gZW5naW5lcyB0aGF0IGRvbid0IHN1cHBvcnRcbiAgICAvLyB0aGUgJ3knIGZsYWcuXG4gICAgZnVuY3Rpb24gKHJlZ2V4cCwgbGltaXQpIHtcbiAgICAgIHZhciByZXMgPSBtYXliZUNhbGxOYXRpdmUoaW50ZXJuYWxTcGxpdCwgcmVnZXhwLCB0aGlzLCBsaW1pdCwgaW50ZXJuYWxTcGxpdCAhPT0gJHNwbGl0KTtcbiAgICAgIGlmIChyZXMuZG9uZSkgcmV0dXJuIHJlcy52YWx1ZTtcblxuICAgICAgdmFyIHJ4ID0gYW5PYmplY3QocmVnZXhwKTtcbiAgICAgIHZhciBTID0gU3RyaW5nKHRoaXMpO1xuICAgICAgdmFyIEMgPSBzcGVjaWVzQ29uc3RydWN0b3IocngsIFJlZ0V4cCk7XG5cbiAgICAgIHZhciB1bmljb2RlTWF0Y2hpbmcgPSByeC51bmljb2RlO1xuICAgICAgdmFyIGZsYWdzID0gKHJ4Lmlnbm9yZUNhc2UgPyAnaScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgKHJ4Lm11bHRpbGluZSA/ICdtJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAocngudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoU1VQUE9SVFNfWSA/ICd5JyA6ICdnJyk7XG5cbiAgICAgIC8vIF4oPyArIHJ4ICsgKSBpcyBuZWVkZWQsIGluIGNvbWJpbmF0aW9uIHdpdGggc29tZSBTIHNsaWNpbmcsIHRvXG4gICAgICAvLyBzaW11bGF0ZSB0aGUgJ3knIGZsYWcuXG4gICAgICB2YXIgc3BsaXR0ZXIgPSBuZXcgQyhTVVBQT1JUU19ZID8gcnggOiAnXig/OicgKyByeC5zb3VyY2UgKyAnKScsIGZsYWdzKTtcbiAgICAgIHZhciBsaW0gPSBsaW1pdCA9PT0gdW5kZWZpbmVkID8gTUFYX1VJTlQzMiA6IGxpbWl0ID4+PiAwO1xuICAgICAgaWYgKGxpbSA9PT0gMCkgcmV0dXJuIFtdO1xuICAgICAgaWYgKFMubGVuZ3RoID09PSAwKSByZXR1cm4gY2FsbFJlZ0V4cEV4ZWMoc3BsaXR0ZXIsIFMpID09PSBudWxsID8gW1NdIDogW107XG4gICAgICB2YXIgcCA9IDA7XG4gICAgICB2YXIgcSA9IDA7XG4gICAgICB2YXIgQSA9IFtdO1xuICAgICAgd2hpbGUgKHEgPCBTLmxlbmd0aCkge1xuICAgICAgICBzcGxpdHRlci5sYXN0SW5kZXggPSBTVVBQT1JUU19ZID8gcSA6IDA7XG4gICAgICAgIHZhciB6ID0gY2FsbFJlZ0V4cEV4ZWMoc3BsaXR0ZXIsIFNVUFBPUlRTX1kgPyBTIDogUy5zbGljZShxKSk7XG4gICAgICAgIHZhciBlO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgeiA9PT0gbnVsbCB8fFxuICAgICAgICAgIChlID0gJG1pbih0b0xlbmd0aChzcGxpdHRlci5sYXN0SW5kZXggKyAoU1VQUE9SVFNfWSA/IDAgOiBxKSksIFMubGVuZ3RoKSkgPT09IHBcbiAgICAgICAgKSB7XG4gICAgICAgICAgcSA9IGFkdmFuY2VTdHJpbmdJbmRleChTLCBxLCB1bmljb2RlTWF0Y2hpbmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEEucHVzaChTLnNsaWNlKHAsIHEpKTtcbiAgICAgICAgICBpZiAoQS5sZW5ndGggPT09IGxpbSkgcmV0dXJuIEE7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gei5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgIEEucHVzaCh6W2ldKTtcbiAgICAgICAgICAgIGlmIChBLmxlbmd0aCA9PT0gbGltKSByZXR1cm4gQTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcSA9IHAgPSBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBBLnB1c2goUy5zbGljZShwKSk7XG4gICAgICByZXR1cm4gQTtcbiAgICB9XG4gIF07XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnJlcXVpcmUoJy4vZXM2LnJlZ2V4cC5mbGFncycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJGZsYWdzID0gcmVxdWlyZSgnLi9fZmxhZ3MnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgVE9fU1RSSU5HID0gJ3RvU3RyaW5nJztcbnZhciAkdG9TdHJpbmcgPSAvLi9bVE9fU1RSSU5HXTtcblxudmFyIGRlZmluZSA9IGZ1bmN0aW9uIChmbikge1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKFJlZ0V4cC5wcm90b3R5cGUsIFRPX1NUUklORywgZm4sIHRydWUpO1xufTtcblxuLy8gMjEuMi41LjE0IFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcoKVxuaWYgKHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkgeyByZXR1cm4gJHRvU3RyaW5nLmNhbGwoeyBzb3VyY2U6ICdhJywgZmxhZ3M6ICdiJyB9KSAhPSAnL2EvYic7IH0pKSB7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICB2YXIgUiA9IGFuT2JqZWN0KHRoaXMpO1xuICAgIHJldHVybiAnLycuY29uY2F0KFIuc291cmNlLCAnLycsXG4gICAgICAnZmxhZ3MnIGluIFIgPyBSLmZsYWdzIDogIURFU0NSSVBUT1JTICYmIFIgaW5zdGFuY2VvZiBSZWdFeHAgPyAkZmxhZ3MuY2FsbChSKSA6IHVuZGVmaW5lZCk7XG4gIH0pO1xuLy8gRkY0NC0gUmVnRXhwI3RvU3RyaW5nIGhhcyBhIHdyb25nIG5hbWVcbn0gZWxzZSBpZiAoJHRvU3RyaW5nLm5hbWUgIT0gVE9fU1RSSU5HKSB7XG4gIGRlZmluZShmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gJHRvU3RyaW5nLmNhbGwodGhpcyk7XG4gIH0pO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIHN0cm9uZyA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24tc3Ryb25nJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgU0VUID0gJ1NldCc7XG5cbi8vIDIzLjIgU2V0IE9iamVjdHNcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFNFVCwgZnVuY3Rpb24gKGdldCkge1xuICByZXR1cm4gZnVuY3Rpb24gU2V0KCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuMi4zLjEgU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgU0VUKSwgdmFsdWUgPSB2YWx1ZSA9PT0gMCA/IDAgOiB2YWx1ZSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMiBTdHJpbmcucHJvdG90eXBlLmFuY2hvcihuYW1lKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnYW5jaG9yJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGFuY2hvcihuYW1lKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2EnLCAnbmFtZScsIG5hbWUpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4zIFN0cmluZy5wcm90b3R5cGUuYmlnKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JpZycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBiaWcoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2JpZycsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjQgU3RyaW5nLnByb3RvdHlwZS5ibGluaygpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdibGluaycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBibGluaygpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYmxpbmsnLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy41IFN0cmluZy5wcm90b3R5cGUuYm9sZCgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdib2xkJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJvbGQoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2InLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKGZhbHNlKTtcbiRleHBvcnQoJGV4cG9ydC5QLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjMuMyBTdHJpbmcucHJvdG90eXBlLmNvZGVQb2ludEF0KHBvcylcbiAgY29kZVBvaW50QXQ6IGZ1bmN0aW9uIGNvZGVQb2ludEF0KHBvcykge1xuICAgIHJldHVybiAkYXQodGhpcywgcG9zKTtcbiAgfVxufSk7XG4iLCIvLyAyMS4xLjMuNiBTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKHNlYXJjaFN0cmluZyBbLCBlbmRQb3NpdGlvbl0pXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgRU5EU19XSVRIID0gJ2VuZHNXaXRoJztcbnZhciAkZW5kc1dpdGggPSAnJ1tFTkRTX1dJVEhdO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzLWlzLXJlZ2V4cCcpKEVORFNfV0lUSCksICdTdHJpbmcnLCB7XG4gIGVuZHNXaXRoOiBmdW5jdGlvbiBlbmRzV2l0aChzZWFyY2hTdHJpbmcgLyogLCBlbmRQb3NpdGlvbiA9IEBsZW5ndGggKi8pIHtcbiAgICB2YXIgdGhhdCA9IGNvbnRleHQodGhpcywgc2VhcmNoU3RyaW5nLCBFTkRTX1dJVEgpO1xuICAgIHZhciBlbmRQb3NpdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkO1xuICAgIHZhciBsZW4gPSB0b0xlbmd0aCh0aGF0Lmxlbmd0aCk7XG4gICAgdmFyIGVuZCA9IGVuZFBvc2l0aW9uID09PSB1bmRlZmluZWQgPyBsZW4gOiBNYXRoLm1pbih0b0xlbmd0aChlbmRQb3NpdGlvbiksIGxlbik7XG4gICAgdmFyIHNlYXJjaCA9IFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgIHJldHVybiAkZW5kc1dpdGhcbiAgICAgID8gJGVuZHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBlbmQpXG4gICAgICA6IHRoYXQuc2xpY2UoZW5kIC0gc2VhcmNoLmxlbmd0aCwgZW5kKSA9PT0gc2VhcmNoO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjYgU3RyaW5nLnByb3RvdHlwZS5maXhlZCgpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdmaXhlZCcsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmaXhlZCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAndHQnLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy43IFN0cmluZy5wcm90b3R5cGUuZm9udGNvbG9yKGNvbG9yKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnZm9udGNvbG9yJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbnRjb2xvcihjb2xvcikge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdmb250JywgJ2NvbG9yJywgY29sb3IpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy44IFN0cmluZy5wcm90b3R5cGUuZm9udHNpemUoc2l6ZSlcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2ZvbnRzaXplJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZvbnRzaXplKHNpemUpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnZm9udCcsICdzaXplJywgc2l6ZSk7XG4gIH07XG59KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbnZhciBmcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xudmFyICRmcm9tQ29kZVBvaW50ID0gU3RyaW5nLmZyb21Db2RlUG9pbnQ7XG5cbi8vIGxlbmd0aCBzaG91bGQgYmUgMSwgb2xkIEZGIHByb2JsZW1cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCEhJGZyb21Db2RlUG9pbnQgJiYgJGZyb21Db2RlUG9pbnQubGVuZ3RoICE9IDEpLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjIuMiBTdHJpbmcuZnJvbUNvZGVQb2ludCguLi5jb2RlUG9pbnRzKVxuICBmcm9tQ29kZVBvaW50OiBmdW5jdGlvbiBmcm9tQ29kZVBvaW50KHgpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIHZhciByZXMgPSBbXTtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBjb2RlO1xuICAgIHdoaWxlIChhTGVuID4gaSkge1xuICAgICAgY29kZSA9ICthcmd1bWVudHNbaSsrXTtcbiAgICAgIGlmICh0b0Fic29sdXRlSW5kZXgoY29kZSwgMHgxMGZmZmYpICE9PSBjb2RlKSB0aHJvdyBSYW5nZUVycm9yKGNvZGUgKyAnIGlzIG5vdCBhIHZhbGlkIGNvZGUgcG9pbnQnKTtcbiAgICAgIHJlcy5wdXNoKGNvZGUgPCAweDEwMDAwXG4gICAgICAgID8gZnJvbUNoYXJDb2RlKGNvZGUpXG4gICAgICAgIDogZnJvbUNoYXJDb2RlKCgoY29kZSAtPSAweDEwMDAwKSA+PiAxMCkgKyAweGQ4MDAsIGNvZGUgJSAweDQwMCArIDB4ZGMwMClcbiAgICAgICk7XG4gICAgfSByZXR1cm4gcmVzLmpvaW4oJycpO1xuICB9XG59KTtcbiIsIi8vIDIxLjEuMy43IFN0cmluZy5wcm90b3R5cGUuaW5jbHVkZXMoc2VhcmNoU3RyaW5nLCBwb3NpdGlvbiA9IDApXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvbnRleHQgPSByZXF1aXJlKCcuL19zdHJpbmctY29udGV4dCcpO1xudmFyIElOQ0xVREVTID0gJ2luY2x1ZGVzJztcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscy1pcy1yZWdleHAnKShJTkNMVURFUyksICdTdHJpbmcnLCB7XG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhzZWFyY2hTdHJpbmcgLyogLCBwb3NpdGlvbiA9IDAgKi8pIHtcbiAgICByZXR1cm4gISF+Y29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIElOQ0xVREVTKVxuICAgICAgLmluZGV4T2Yoc2VhcmNoU3RyaW5nLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuOSBTdHJpbmcucHJvdG90eXBlLml0YWxpY3MoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnaXRhbGljcycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpdGFsaWNzKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdpJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRhdCA9IHJlcXVpcmUoJy4vX3N0cmluZy1hdCcpKHRydWUpO1xuXG4vLyAyMS4xLjMuMjcgU3RyaW5nLnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19pdGVyLWRlZmluZScpKFN0cmluZywgJ1N0cmluZycsIGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICB0aGlzLl90ID0gU3RyaW5nKGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4vLyAyMS4xLjUuMi4xICVTdHJpbmdJdGVyYXRvclByb3RvdHlwZSUubmV4dCgpXG59LCBmdW5jdGlvbiAoKSB7XG4gIHZhciBPID0gdGhpcy5fdDtcbiAgdmFyIGluZGV4ID0gdGhpcy5faTtcbiAgdmFyIHBvaW50O1xuICBpZiAoaW5kZXggPj0gTy5sZW5ndGgpIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgcG9pbnQgPSAkYXQoTywgaW5kZXgpO1xuICB0aGlzLl9pICs9IHBvaW50Lmxlbmd0aDtcbiAgcmV0dXJuIHsgdmFsdWU6IHBvaW50LCBkb25lOiBmYWxzZSB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMCBTdHJpbmcucHJvdG90eXBlLmxpbmsodXJsKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnbGluaycsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBsaW5rKHVybCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdhJywgJ2hyZWYnLCB1cmwpO1xuICB9O1xufSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1N0cmluZycsIHtcbiAgLy8gMjEuMS4yLjQgU3RyaW5nLnJhdyhjYWxsU2l0ZSwgLi4uc3Vic3RpdHV0aW9ucylcbiAgcmF3OiBmdW5jdGlvbiByYXcoY2FsbFNpdGUpIHtcbiAgICB2YXIgdHBsID0gdG9JT2JqZWN0KGNhbGxTaXRlLnJhdyk7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHRwbC5sZW5ndGgpO1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgcmVzID0gW107XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChsZW4gPiBpKSB7XG4gICAgICByZXMucHVzaChTdHJpbmcodHBsW2krK10pKTtcbiAgICAgIGlmIChpIDwgYUxlbikgcmVzLnB1c2goU3RyaW5nKGFyZ3VtZW50c1tpXSkpO1xuICAgIH0gcmV0dXJuIHJlcy5qb2luKCcnKTtcbiAgfVxufSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgLy8gMjEuMS4zLjEzIFN0cmluZy5wcm90b3R5cGUucmVwZWF0KGNvdW50KVxuICByZXBlYXQ6IHJlcXVpcmUoJy4vX3N0cmluZy1yZXBlYXQnKVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4xMSBTdHJpbmcucHJvdG90eXBlLnNtYWxsKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3NtYWxsJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHNtYWxsKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdzbWFsbCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIi8vIDIxLjEuMy4xOCBTdHJpbmcucHJvdG90eXBlLnN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nIFssIHBvc2l0aW9uIF0pXG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgU1RBUlRTX1dJVEggPSAnc3RhcnRzV2l0aCc7XG52YXIgJHN0YXJ0c1dpdGggPSAnJ1tTVEFSVFNfV0lUSF07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMtaXMtcmVnZXhwJykoU1RBUlRTX1dJVEgpLCAnU3RyaW5nJywge1xuICBzdGFydHNXaXRoOiBmdW5jdGlvbiBzdGFydHNXaXRoKHNlYXJjaFN0cmluZyAvKiAsIHBvc2l0aW9uID0gMCAqLykge1xuICAgIHZhciB0aGF0ID0gY29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIFNUQVJUU19XSVRIKTtcbiAgICB2YXIgaW5kZXggPSB0b0xlbmd0aChNYXRoLm1pbihhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgdGhhdC5sZW5ndGgpKTtcbiAgICB2YXIgc2VhcmNoID0gU3RyaW5nKHNlYXJjaFN0cmluZyk7XG4gICAgcmV0dXJuICRzdGFydHNXaXRoXG4gICAgICA/ICRzdGFydHNXaXRoLmNhbGwodGhhdCwgc2VhcmNoLCBpbmRleClcbiAgICAgIDogdGhhdC5zbGljZShpbmRleCwgaW5kZXggKyBzZWFyY2gubGVuZ3RoKSA9PT0gc2VhcmNoO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEyIFN0cmluZy5wcm90b3R5cGUuc3RyaWtlKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N0cmlrZScsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdHJpa2UoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N0cmlrZScsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEzIFN0cmluZy5wcm90b3R5cGUuc3ViKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N1YicsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdWIoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N1YicsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjE0IFN0cmluZy5wcm90b3R5cGUuc3VwKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ3N1cCcsIGZ1bmN0aW9uIChjcmVhdGVIVE1MKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdXAoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3N1cCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIxLjEuMy4yNSBTdHJpbmcucHJvdG90eXBlLnRyaW0oKVxucmVxdWlyZSgnLi9fc3RyaW5nLXRyaW0nKSgndHJpbScsIGZ1bmN0aW9uICgkdHJpbSkge1xuICByZXR1cm4gZnVuY3Rpb24gdHJpbSgpIHtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEVDTUFTY3JpcHQgNiBzeW1ib2xzIHNoaW1cbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBNRVRBID0gcmVxdWlyZSgnLi9fbWV0YScpLktFWTtcbnZhciAkZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpO1xudmFyIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi9fc2V0LXRvLXN0cmluZy10YWcnKTtcbnZhciB1aWQgPSByZXF1aXJlKCcuL191aWQnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciB3a3NFeHQgPSByZXF1aXJlKCcuL193a3MtZXh0Jyk7XG52YXIgd2tzRGVmaW5lID0gcmVxdWlyZSgnLi9fd2tzLWRlZmluZScpO1xudmFyIGVudW1LZXlzID0gcmVxdWlyZSgnLi9fZW51bS1rZXlzJyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vX2lzLWFycmF5Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG52YXIgX2NyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciBnT1BORXh0ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0Jyk7XG52YXIgJEdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyICREUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BEID0gJEdPUEQuZjtcbnZhciBkUCA9ICREUC5mO1xudmFyIGdPUE4gPSBnT1BORXh0LmY7XG52YXIgJFN5bWJvbCA9IGdsb2JhbC5TeW1ib2w7XG52YXIgJEpTT04gPSBnbG9iYWwuSlNPTjtcbnZhciBfc3RyaW5naWZ5ID0gJEpTT04gJiYgJEpTT04uc3RyaW5naWZ5O1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xudmFyIEhJRERFTiA9IHdrcygnX2hpZGRlbicpO1xudmFyIFRPX1BSSU1JVElWRSA9IHdrcygndG9QcmltaXRpdmUnKTtcbnZhciBpc0VudW0gPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbnZhciBTeW1ib2xSZWdpc3RyeSA9IHNoYXJlZCgnc3ltYm9sLXJlZ2lzdHJ5Jyk7XG52YXIgQWxsU3ltYm9scyA9IHNoYXJlZCgnc3ltYm9scycpO1xudmFyIE9QU3ltYm9scyA9IHNoYXJlZCgnb3Atc3ltYm9scycpO1xudmFyIE9iamVjdFByb3RvID0gT2JqZWN0W1BST1RPVFlQRV07XG52YXIgVVNFX05BVElWRSA9IHR5cGVvZiAkU3ltYm9sID09ICdmdW5jdGlvbic7XG52YXIgUU9iamVjdCA9IGdsb2JhbC5RT2JqZWN0O1xuLy8gRG9uJ3QgdXNlIHNldHRlcnMgaW4gUXQgU2NyaXB0LCBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMTczXG52YXIgc2V0dGVyID0gIVFPYmplY3QgfHwgIVFPYmplY3RbUFJPVE9UWVBFXSB8fCAhUU9iamVjdFtQUk9UT1RZUEVdLmZpbmRDaGlsZDtcblxuLy8gZmFsbGJhY2sgZm9yIG9sZCBBbmRyb2lkLCBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9Njg3XG52YXIgc2V0U3ltYm9sRGVzYyA9IERFU0NSSVBUT1JTICYmICRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBfY3JlYXRlKGRQKHt9LCAnYScsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRQKHRoaXMsICdhJywgeyB2YWx1ZTogNyB9KS5hOyB9XG4gIH0pKS5hICE9IDc7XG59KSA/IGZ1bmN0aW9uIChpdCwga2V5LCBEKSB7XG4gIHZhciBwcm90b0Rlc2MgPSBnT1BEKE9iamVjdFByb3RvLCBrZXkpO1xuICBpZiAocHJvdG9EZXNjKSBkZWxldGUgT2JqZWN0UHJvdG9ba2V5XTtcbiAgZFAoaXQsIGtleSwgRCk7XG4gIGlmIChwcm90b0Rlc2MgJiYgaXQgIT09IE9iamVjdFByb3RvKSBkUChPYmplY3RQcm90bywga2V5LCBwcm90b0Rlc2MpO1xufSA6IGRQO1xuXG52YXIgd3JhcCA9IGZ1bmN0aW9uICh0YWcpIHtcbiAgdmFyIHN5bSA9IEFsbFN5bWJvbHNbdGFnXSA9IF9jcmVhdGUoJFN5bWJvbFtQUk9UT1RZUEVdKTtcbiAgc3ltLl9rID0gdGFnO1xuICByZXR1cm4gc3ltO1xufTtcblxudmFyIGlzU3ltYm9sID0gVVNFX05BVElWRSAmJiB0eXBlb2YgJFN5bWJvbC5pdGVyYXRvciA9PSAnc3ltYm9sJyA/IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnO1xufSA6IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXQgaW5zdGFuY2VvZiAkU3ltYm9sO1xufTtcblxudmFyICRkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KGl0LCBrZXksIEQpIHtcbiAgaWYgKGl0ID09PSBPYmplY3RQcm90bykgJGRlZmluZVByb3BlcnR5KE9QU3ltYm9scywga2V5LCBEKTtcbiAgYW5PYmplY3QoaXQpO1xuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xuICBhbk9iamVjdChEKTtcbiAgaWYgKGhhcyhBbGxTeW1ib2xzLCBrZXkpKSB7XG4gICAgaWYgKCFELmVudW1lcmFibGUpIHtcbiAgICAgIGlmICghaGFzKGl0LCBISURERU4pKSBkUChpdCwgSElEREVOLCBjcmVhdGVEZXNjKDEsIHt9KSk7XG4gICAgICBpdFtISURERU5dW2tleV0gPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaGFzKGl0LCBISURERU4pICYmIGl0W0hJRERFTl1ba2V5XSkgaXRbSElEREVOXVtrZXldID0gZmFsc2U7XG4gICAgICBEID0gX2NyZWF0ZShELCB7IGVudW1lcmFibGU6IGNyZWF0ZURlc2MoMCwgZmFsc2UpIH0pO1xuICAgIH0gcmV0dXJuIHNldFN5bWJvbERlc2MoaXQsIGtleSwgRCk7XG4gIH0gcmV0dXJuIGRQKGl0LCBrZXksIEQpO1xufTtcbnZhciAkZGVmaW5lUHJvcGVydGllcyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoaXQsIFApIHtcbiAgYW5PYmplY3QoaXQpO1xuICB2YXIga2V5cyA9IGVudW1LZXlzKFAgPSB0b0lPYmplY3QoUCkpO1xuICB2YXIgaSA9IDA7XG4gIHZhciBsID0ga2V5cy5sZW5ndGg7XG4gIHZhciBrZXk7XG4gIHdoaWxlIChsID4gaSkgJGRlZmluZVByb3BlcnR5KGl0LCBrZXkgPSBrZXlzW2krK10sIFBba2V5XSk7XG4gIHJldHVybiBpdDtcbn07XG52YXIgJGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpdCwgUCkge1xuICByZXR1cm4gUCA9PT0gdW5kZWZpbmVkID8gX2NyZWF0ZShpdCkgOiAkZGVmaW5lUHJvcGVydGllcyhfY3JlYXRlKGl0KSwgUCk7XG59O1xudmFyICRwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IGZ1bmN0aW9uIHByb3BlcnR5SXNFbnVtZXJhYmxlKGtleSkge1xuICB2YXIgRSA9IGlzRW51bS5jYWxsKHRoaXMsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpO1xuICBpZiAodGhpcyA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIEUgfHwgIWhhcyh0aGlzLCBrZXkpIHx8ICFoYXMoQWxsU3ltYm9scywga2V5KSB8fCBoYXModGhpcywgSElEREVOKSAmJiB0aGlzW0hJRERFTl1ba2V5XSA/IEUgOiB0cnVlO1xufTtcbnZhciAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpIHtcbiAgaXQgPSB0b0lPYmplY3QoaXQpO1xuICBrZXkgPSB0b1ByaW1pdGl2ZShrZXksIHRydWUpO1xuICBpZiAoaXQgPT09IE9iamVjdFByb3RvICYmIGhhcyhBbGxTeW1ib2xzLCBrZXkpICYmICFoYXMoT1BTeW1ib2xzLCBrZXkpKSByZXR1cm47XG4gIHZhciBEID0gZ09QRChpdCwga2V5KTtcbiAgaWYgKEQgJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIShoYXMoaXQsIEhJRERFTikgJiYgaXRbSElEREVOXVtrZXldKSkgRC5lbnVtZXJhYmxlID0gdHJ1ZTtcbiAgcmV0dXJuIEQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eU5hbWVzID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCkge1xuICB2YXIgbmFtZXMgPSBnT1BOKHRvSU9iamVjdChpdCkpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBpID0gMDtcbiAgdmFyIGtleTtcbiAgd2hpbGUgKG5hbWVzLmxlbmd0aCA+IGkpIHtcbiAgICBpZiAoIWhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiBrZXkgIT0gSElEREVOICYmIGtleSAhPSBNRVRBKSByZXN1bHQucHVzaChrZXkpO1xuICB9IHJldHVybiByZXN1bHQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoaXQpIHtcbiAgdmFyIElTX09QID0gaXQgPT09IE9iamVjdFByb3RvO1xuICB2YXIgbmFtZXMgPSBnT1BOKElTX09QID8gT1BTeW1ib2xzIDogdG9JT2JqZWN0KGl0KSk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIga2V5O1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkge1xuICAgIGlmIChoYXMoQWxsU3ltYm9scywga2V5ID0gbmFtZXNbaSsrXSkgJiYgKElTX09QID8gaGFzKE9iamVjdFByb3RvLCBrZXkpIDogdHJ1ZSkpIHJlc3VsdC5wdXNoKEFsbFN5bWJvbHNba2V5XSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8vIDE5LjQuMS4xIFN5bWJvbChbZGVzY3JpcHRpb25dKVxuaWYgKCFVU0VfTkFUSVZFKSB7XG4gICRTeW1ib2wgPSBmdW5jdGlvbiBTeW1ib2woKSB7XG4gICAgaWYgKHRoaXMgaW5zdGFuY2VvZiAkU3ltYm9sKSB0aHJvdyBUeXBlRXJyb3IoJ1N5bWJvbCBpcyBub3QgYSBjb25zdHJ1Y3RvciEnKTtcbiAgICB2YXIgdGFnID0gdWlkKGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTtcbiAgICB2YXIgJHNldCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgaWYgKHRoaXMgPT09IE9iamVjdFByb3RvKSAkc2V0LmNhbGwoT1BTeW1ib2xzLCB2YWx1ZSk7XG4gICAgICBpZiAoaGFzKHRoaXMsIEhJRERFTikgJiYgaGFzKHRoaXNbSElEREVOXSwgdGFnKSkgdGhpc1tISURERU5dW3RhZ10gPSBmYWxzZTtcbiAgICAgIHNldFN5bWJvbERlc2ModGhpcywgdGFnLCBjcmVhdGVEZXNjKDEsIHZhbHVlKSk7XG4gICAgfTtcbiAgICBpZiAoREVTQ1JJUFRPUlMgJiYgc2V0dGVyKSBzZXRTeW1ib2xEZXNjKE9iamVjdFByb3RvLCB0YWcsIHsgY29uZmlndXJhYmxlOiB0cnVlLCBzZXQ6ICRzZXQgfSk7XG4gICAgcmV0dXJuIHdyYXAodGFnKTtcbiAgfTtcbiAgcmVkZWZpbmUoJFN5bWJvbFtQUk9UT1RZUEVdLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5faztcbiAgfSk7XG5cbiAgJEdPUEQuZiA9ICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG4gICREUC5mID0gJGRlZmluZVByb3BlcnR5O1xuICByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmYgPSBnT1BORXh0LmYgPSAkZ2V0T3duUHJvcGVydHlOYW1lcztcbiAgcmVxdWlyZSgnLi9fb2JqZWN0LXBpZScpLmYgPSAkcHJvcGVydHlJc0VudW1lcmFibGU7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1nb3BzJykuZiA9ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbiAgaWYgKERFU0NSSVBUT1JTICYmICFyZXF1aXJlKCcuL19saWJyYXJ5JykpIHtcbiAgICByZWRlZmluZShPYmplY3RQcm90bywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJywgJHByb3BlcnR5SXNFbnVtZXJhYmxlLCB0cnVlKTtcbiAgfVxuXG4gIHdrc0V4dC5mID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICByZXR1cm4gd3JhcCh3a3MobmFtZSkpO1xuICB9O1xufVxuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCB7IFN5bWJvbDogJFN5bWJvbCB9KTtcblxuZm9yICh2YXIgZXM2U3ltYm9scyA9IChcbiAgLy8gMTkuNC4yLjIsIDE5LjQuMi4zLCAxOS40LjIuNCwgMTkuNC4yLjYsIDE5LjQuMi44LCAxOS40LjIuOSwgMTkuNC4yLjEwLCAxOS40LjIuMTEsIDE5LjQuMi4xMiwgMTkuNC4yLjEzLCAxOS40LjIuMTRcbiAgJ2hhc0luc3RhbmNlLGlzQ29uY2F0U3ByZWFkYWJsZSxpdGVyYXRvcixtYXRjaCxyZXBsYWNlLHNlYXJjaCxzcGVjaWVzLHNwbGl0LHRvUHJpbWl0aXZlLHRvU3RyaW5nVGFnLHVuc2NvcGFibGVzJ1xuKS5zcGxpdCgnLCcpLCBqID0gMDsgZXM2U3ltYm9scy5sZW5ndGggPiBqOyl3a3MoZXM2U3ltYm9sc1tqKytdKTtcblxuZm9yICh2YXIgd2VsbEtub3duU3ltYm9scyA9ICRrZXlzKHdrcy5zdG9yZSksIGsgPSAwOyB3ZWxsS25vd25TeW1ib2xzLmxlbmd0aCA+IGs7KSB3a3NEZWZpbmUod2VsbEtub3duU3ltYm9sc1trKytdKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgJ1N5bWJvbCcsIHtcbiAgLy8gMTkuNC4yLjEgU3ltYm9sLmZvcihrZXkpXG4gICdmb3InOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGhhcyhTeW1ib2xSZWdpc3RyeSwga2V5ICs9ICcnKVxuICAgICAgPyBTeW1ib2xSZWdpc3RyeVtrZXldXG4gICAgICA6IFN5bWJvbFJlZ2lzdHJ5W2tleV0gPSAkU3ltYm9sKGtleSk7XG4gIH0sXG4gIC8vIDE5LjQuMi41IFN5bWJvbC5rZXlGb3Ioc3ltKVxuICBrZXlGb3I6IGZ1bmN0aW9uIGtleUZvcihzeW0pIHtcbiAgICBpZiAoIWlzU3ltYm9sKHN5bSkpIHRocm93IFR5cGVFcnJvcihzeW0gKyAnIGlzIG5vdCBhIHN5bWJvbCEnKTtcbiAgICBmb3IgKHZhciBrZXkgaW4gU3ltYm9sUmVnaXN0cnkpIGlmIChTeW1ib2xSZWdpc3RyeVtrZXldID09PSBzeW0pIHJldHVybiBrZXk7XG4gIH0sXG4gIHVzZVNldHRlcjogZnVuY3Rpb24gKCkgeyBzZXR0ZXIgPSB0cnVlOyB9LFxuICB1c2VTaW1wbGU6IGZ1bmN0aW9uICgpIHsgc2V0dGVyID0gZmFsc2U7IH1cbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCAnT2JqZWN0Jywge1xuICAvLyAxOS4xLjIuMiBPYmplY3QuY3JlYXRlKE8gWywgUHJvcGVydGllc10pXG4gIGNyZWF0ZTogJGNyZWF0ZSxcbiAgLy8gMTkuMS4yLjQgT2JqZWN0LmRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpXG4gIGRlZmluZVByb3BlcnR5OiAkZGVmaW5lUHJvcGVydHksXG4gIC8vIDE5LjEuMi4zIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpXG4gIGRlZmluZVByb3BlcnRpZXM6ICRkZWZpbmVQcm9wZXJ0aWVzLFxuICAvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogJGdldE93blByb3BlcnR5RGVzY3JpcHRvcixcbiAgLy8gMTkuMS4yLjcgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbiAgZ2V0T3duUHJvcGVydHlOYW1lczogJGdldE93blByb3BlcnR5TmFtZXMsXG4gIC8vIDE5LjEuMi44IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoTylcbiAgZ2V0T3duUHJvcGVydHlTeW1ib2xzOiAkZ2V0T3duUHJvcGVydHlTeW1ib2xzXG59KTtcblxuLy8gMjQuMy4yIEpTT04uc3RyaW5naWZ5KHZhbHVlIFssIHJlcGxhY2VyIFssIHNwYWNlXV0pXG4kSlNPTiAmJiAkZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICghVVNFX05BVElWRSB8fCAkZmFpbHMoZnVuY3Rpb24gKCkge1xuICB2YXIgUyA9ICRTeW1ib2woKTtcbiAgLy8gTVMgRWRnZSBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMge31cbiAgLy8gV2ViS2l0IGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyBudWxsXG4gIC8vIFY4IHRocm93cyBvbiBib3hlZCBzeW1ib2xzXG4gIHJldHVybiBfc3RyaW5naWZ5KFtTXSkgIT0gJ1tudWxsXScgfHwgX3N0cmluZ2lmeSh7IGE6IFMgfSkgIT0gJ3t9JyB8fCBfc3RyaW5naWZ5KE9iamVjdChTKSkgIT0gJ3t9Jztcbn0pKSwgJ0pTT04nLCB7XG4gIHN0cmluZ2lmeTogZnVuY3Rpb24gc3RyaW5naWZ5KGl0KSB7XG4gICAgdmFyIGFyZ3MgPSBbaXRdO1xuICAgIHZhciBpID0gMTtcbiAgICB2YXIgcmVwbGFjZXIsICRyZXBsYWNlcjtcbiAgICB3aGlsZSAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgJHJlcGxhY2VyID0gcmVwbGFjZXIgPSBhcmdzWzFdO1xuICAgIGlmICghaXNPYmplY3QocmVwbGFjZXIpICYmIGl0ID09PSB1bmRlZmluZWQgfHwgaXNTeW1ib2woaXQpKSByZXR1cm47IC8vIElFOCByZXR1cm5zIHN0cmluZyBvbiB1bmRlZmluZWRcbiAgICBpZiAoIWlzQXJyYXkocmVwbGFjZXIpKSByZXBsYWNlciA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mICRyZXBsYWNlciA9PSAnZnVuY3Rpb24nKSB2YWx1ZSA9ICRyZXBsYWNlci5jYWxsKHRoaXMsIGtleSwgdmFsdWUpO1xuICAgICAgaWYgKCFpc1N5bWJvbCh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgICB9O1xuICAgIGFyZ3NbMV0gPSByZXBsYWNlcjtcbiAgICByZXR1cm4gX3N0cmluZ2lmeS5hcHBseSgkSlNPTiwgYXJncyk7XG4gIH1cbn0pO1xuXG4vLyAxOS40LjMuNCBTeW1ib2wucHJvdG90eXBlW0BAdG9QcmltaXRpdmVdKGhpbnQpXG4kU3ltYm9sW1BST1RPVFlQRV1bVE9fUFJJTUlUSVZFXSB8fCByZXF1aXJlKCcuL19oaWRlJykoJFN5bWJvbFtQUk9UT1RZUEVdLCBUT19QUklNSVRJVkUsICRTeW1ib2xbUFJPVE9UWVBFXS52YWx1ZU9mKTtcbi8vIDE5LjQuMy41IFN5bWJvbC5wcm90b3R5cGVbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKCRTeW1ib2wsICdTeW1ib2wnKTtcbi8vIDIwLjIuMS45IE1hdGhbQEB0b1N0cmluZ1RhZ11cbnNldFRvU3RyaW5nVGFnKE1hdGgsICdNYXRoJywgdHJ1ZSk7XG4vLyAyNC4zLjMgSlNPTltAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoZ2xvYmFsLkpTT04sICdKU09OJywgdHJ1ZSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICR0eXBlZCA9IHJlcXVpcmUoJy4vX3R5cGVkJyk7XG52YXIgYnVmZmVyID0gcmVxdWlyZSgnLi9fdHlwZWQtYnVmZmVyJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBBcnJheUJ1ZmZlciA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLkFycmF5QnVmZmVyO1xudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX3NwZWNpZXMtY29uc3RydWN0b3InKTtcbnZhciAkQXJyYXlCdWZmZXIgPSBidWZmZXIuQXJyYXlCdWZmZXI7XG52YXIgJERhdGFWaWV3ID0gYnVmZmVyLkRhdGFWaWV3O1xudmFyICRpc1ZpZXcgPSAkdHlwZWQuQUJWICYmIEFycmF5QnVmZmVyLmlzVmlldztcbnZhciAkc2xpY2UgPSAkQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlO1xudmFyIFZJRVcgPSAkdHlwZWQuVklFVztcbnZhciBBUlJBWV9CVUZGRVIgPSAnQXJyYXlCdWZmZXInO1xuXG4kZXhwb3J0KCRleHBvcnQuRyArICRleHBvcnQuVyArICRleHBvcnQuRiAqIChBcnJheUJ1ZmZlciAhPT0gJEFycmF5QnVmZmVyKSwgeyBBcnJheUJ1ZmZlcjogJEFycmF5QnVmZmVyIH0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICEkdHlwZWQuQ09OU1RSLCBBUlJBWV9CVUZGRVIsIHtcbiAgLy8gMjQuMS4zLjEgQXJyYXlCdWZmZXIuaXNWaWV3KGFyZylcbiAgaXNWaWV3OiBmdW5jdGlvbiBpc1ZpZXcoaXQpIHtcbiAgICByZXR1cm4gJGlzVmlldyAmJiAkaXNWaWV3KGl0KSB8fCBpc09iamVjdChpdCkgJiYgVklFVyBpbiBpdDtcbiAgfVxufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5VICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhbmV3ICRBcnJheUJ1ZmZlcigyKS5zbGljZSgxLCB1bmRlZmluZWQpLmJ5dGVMZW5ndGg7XG59KSwgQVJSQVlfQlVGRkVSLCB7XG4gIC8vIDI0LjEuNC4zIEFycmF5QnVmZmVyLnByb3RvdHlwZS5zbGljZShzdGFydCwgZW5kKVxuICBzbGljZTogZnVuY3Rpb24gc2xpY2Uoc3RhcnQsIGVuZCkge1xuICAgIGlmICgkc2xpY2UgIT09IHVuZGVmaW5lZCAmJiBlbmQgPT09IHVuZGVmaW5lZCkgcmV0dXJuICRzbGljZS5jYWxsKGFuT2JqZWN0KHRoaXMpLCBzdGFydCk7IC8vIEZGIGZpeFxuICAgIHZhciBsZW4gPSBhbk9iamVjdCh0aGlzKS5ieXRlTGVuZ3RoO1xuICAgIHZhciBmaXJzdCA9IHRvQWJzb2x1dGVJbmRleChzdGFydCwgbGVuKTtcbiAgICB2YXIgZmluID0gdG9BYnNvbHV0ZUluZGV4KGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogZW5kLCBsZW4pO1xuICAgIHZhciByZXN1bHQgPSBuZXcgKHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkQXJyYXlCdWZmZXIpKSh0b0xlbmd0aChmaW4gLSBmaXJzdCkpO1xuICAgIHZhciB2aWV3UyA9IG5ldyAkRGF0YVZpZXcodGhpcyk7XG4gICAgdmFyIHZpZXdUID0gbmV3ICREYXRhVmlldyhyZXN1bHQpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgd2hpbGUgKGZpcnN0IDwgZmluKSB7XG4gICAgICB2aWV3VC5zZXRVaW50OChpbmRleCsrLCB2aWV3Uy5nZXRVaW50OChmaXJzdCsrKSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcblxucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShBUlJBWV9CVUZGRVIpO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3R5cGVkJykuQUJWLCB7XG4gIERhdGFWaWV3OiByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKS5EYXRhVmlld1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdGbG9hdDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEZsb2F0MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdGbG9hdDY0JywgOCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEZsb2F0NjRBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdJbnQxNicsIDIsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBJbnQxNkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0ludDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDMyQXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50OCcsIDEsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBJbnQ4QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDE2JywgMiwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQxNkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQzMicsIDQsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBVaW50MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdVaW50OCcsIDEsIGZ1bmN0aW9uIChpbml0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBVaW50OEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQ4JywgMSwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQ4Q2xhbXBlZEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59LCB0cnVlKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBlYWNoID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDApO1xudmFyIHJlZGVmaW5lID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpO1xudmFyIGFzc2lnbiA9IHJlcXVpcmUoJy4vX29iamVjdC1hc3NpZ24nKTtcbnZhciB3ZWFrID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi13ZWFrJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBOQVRJVkVfV0VBS19NQVAgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgSVNfSUUxMSA9ICFnbG9iYWwuQWN0aXZlWE9iamVjdCAmJiAnQWN0aXZlWE9iamVjdCcgaW4gZ2xvYmFsO1xudmFyIFdFQUtfTUFQID0gJ1dlYWtNYXAnO1xudmFyIGdldFdlYWsgPSBtZXRhLmdldFdlYWs7XG52YXIgaXNFeHRlbnNpYmxlID0gT2JqZWN0LmlzRXh0ZW5zaWJsZTtcbnZhciB1bmNhdWdodEZyb3plblN0b3JlID0gd2Vhay51ZnN0b3JlO1xudmFyIEludGVybmFsTWFwO1xuXG52YXIgd3JhcHBlciA9IGZ1bmN0aW9uIChnZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFdlYWtNYXAoKSB7XG4gICAgcmV0dXJuIGdldCh0aGlzLCBhcmd1bWVudHMubGVuZ3RoID4gMCA/IGFyZ3VtZW50c1swXSA6IHVuZGVmaW5lZCk7XG4gIH07XG59O1xuXG52YXIgbWV0aG9kcyA9IHtcbiAgLy8gMjMuMy4zLjMgV2Vha01hcC5wcm90b3R5cGUuZ2V0KGtleSlcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoa2V5KSB7XG4gICAgaWYgKGlzT2JqZWN0KGtleSkpIHtcbiAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgaWYgKGRhdGEgPT09IHRydWUpIHJldHVybiB1bmNhdWdodEZyb3plblN0b3JlKHZhbGlkYXRlKHRoaXMsIFdFQUtfTUFQKSkuZ2V0KGtleSk7XG4gICAgICByZXR1cm4gZGF0YSA/IGRhdGFbdGhpcy5faV0gOiB1bmRlZmluZWQ7XG4gICAgfVxuICB9LFxuICAvLyAyMy4zLjMuNSBXZWFrTWFwLnByb3RvdHlwZS5zZXQoa2V5LCB2YWx1ZSlcbiAgc2V0OiBmdW5jdGlvbiBzZXQoa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiB3ZWFrLmRlZih2YWxpZGF0ZSh0aGlzLCBXRUFLX01BUCksIGtleSwgdmFsdWUpO1xuICB9XG59O1xuXG4vLyAyMy4zIFdlYWtNYXAgT2JqZWN0c1xudmFyICRXZWFrTWFwID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoV0VBS19NQVAsIHdyYXBwZXIsIG1ldGhvZHMsIHdlYWssIHRydWUsIHRydWUpO1xuXG4vLyBJRTExIFdlYWtNYXAgZnJvemVuIGtleXMgZml4XG5pZiAoTkFUSVZFX1dFQUtfTUFQICYmIElTX0lFMTEpIHtcbiAgSW50ZXJuYWxNYXAgPSB3ZWFrLmdldENvbnN0cnVjdG9yKHdyYXBwZXIsIFdFQUtfTUFQKTtcbiAgYXNzaWduKEludGVybmFsTWFwLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gIG1ldGEuTkVFRCA9IHRydWU7XG4gIGVhY2goWydkZWxldGUnLCAnaGFzJywgJ2dldCcsICdzZXQnXSwgZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBwcm90byA9ICRXZWFrTWFwLnByb3RvdHlwZTtcbiAgICB2YXIgbWV0aG9kID0gcHJvdG9ba2V5XTtcbiAgICByZWRlZmluZShwcm90bywga2V5LCBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgLy8gc3RvcmUgZnJvemVuIG9iamVjdHMgb24gaW50ZXJuYWwgd2Vha21hcCBzaGltXG4gICAgICBpZiAoaXNPYmplY3QoYSkgJiYgIWlzRXh0ZW5zaWJsZShhKSkge1xuICAgICAgICBpZiAoIXRoaXMuX2YpIHRoaXMuX2YgPSBuZXcgSW50ZXJuYWxNYXAoKTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHRoaXMuX2Zba2V5XShhLCBiKTtcbiAgICAgICAgcmV0dXJuIGtleSA9PSAnc2V0JyA/IHRoaXMgOiByZXN1bHQ7XG4gICAgICAvLyBzdG9yZSBhbGwgdGhlIHJlc3Qgb24gbmF0aXZlIHdlYWttYXBcbiAgICAgIH0gcmV0dXJuIG1ldGhvZC5jYWxsKHRoaXMsIGEsIGIpO1xuICAgIH0pO1xuICB9KTtcbn1cbiIsIid1c2Ugc3RyaWN0JztcbnZhciB3ZWFrID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi13ZWFrJyk7XG52YXIgdmFsaWRhdGUgPSByZXF1aXJlKCcuL192YWxpZGF0ZS1jb2xsZWN0aW9uJyk7XG52YXIgV0VBS19TRVQgPSAnV2Vha1NldCc7XG5cbi8vIDIzLjQgV2Vha1NldCBPYmplY3RzXG5yZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoV0VBS19TRVQsIGZ1bmN0aW9uIChnZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFdlYWtTZXQoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy40LjMuMSBXZWFrU2V0LnByb3RvdHlwZS5hZGQodmFsdWUpXG4gIGFkZDogZnVuY3Rpb24gYWRkKHZhbHVlKSB7XG4gICAgcmV0dXJuIHdlYWsuZGVmKHZhbGlkYXRlKHRoaXMsIFdFQUtfU0VUKSwgdmFsdWUsIHRydWUpO1xuICB9XG59LCB3ZWFrLCBmYWxzZSwgdHJ1ZSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLWZsYXRNYXAvI3NlYy1BcnJheS5wcm90b3R5cGUuZmxhdE1hcFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBmbGF0dGVuSW50b0FycmF5ID0gcmVxdWlyZSgnLi9fZmxhdHRlbi1pbnRvLWFycmF5Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBhcnJheVNwZWNpZXNDcmVhdGUgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge1xuICBmbGF0TWFwOiBmdW5jdGlvbiBmbGF0TWFwKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgdmFyIE8gPSB0b09iamVjdCh0aGlzKTtcbiAgICB2YXIgc291cmNlTGVuLCBBO1xuICAgIGFGdW5jdGlvbihjYWxsYmFja2ZuKTtcbiAgICBzb3VyY2VMZW4gPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgQSA9IGFycmF5U3BlY2llc0NyZWF0ZShPLCAwKTtcbiAgICBmbGF0dGVuSW50b0FycmF5KEEsIE8sIE8sIHNvdXJjZUxlbiwgMCwgMSwgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgICByZXR1cm4gQTtcbiAgfVxufSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdmbGF0TWFwJyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLWZsYXRNYXAvI3NlYy1BcnJheS5wcm90b3R5cGUuZmxhdHRlblxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBmbGF0dGVuSW50b0FycmF5ID0gcmVxdWlyZSgnLi9fZmxhdHRlbi1pbnRvLWFycmF5Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBhcnJheVNwZWNpZXNDcmVhdGUgPSByZXF1aXJlKCcuL19hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5Jywge1xuICBmbGF0dGVuOiBmdW5jdGlvbiBmbGF0dGVuKC8qIGRlcHRoQXJnID0gMSAqLykge1xuICAgIHZhciBkZXB0aEFyZyA9IGFyZ3VtZW50c1swXTtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICAgIHZhciBzb3VyY2VMZW4gPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gICAgdmFyIEEgPSBhcnJheVNwZWNpZXNDcmVhdGUoTywgMCk7XG4gICAgZmxhdHRlbkludG9BcnJheShBLCBPLCBPLCBzb3VyY2VMZW4sIDAsIGRlcHRoQXJnID09PSB1bmRlZmluZWQgPyAxIDogdG9JbnRlZ2VyKGRlcHRoQXJnKSk7XG4gICAgcmV0dXJuIEE7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKSgnZmxhdHRlbicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvQXJyYXkucHJvdG90eXBlLmluY2x1ZGVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRpbmNsdWRlcyA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykodHJ1ZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnQXJyYXknLCB7XG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhlbCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gJGluY2x1ZGVzKHRoaXMsIGVsLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKSgnaW5jbHVkZXMnKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9yd2FsZHJvbi90YzM5LW5vdGVzL2Jsb2IvbWFzdGVyL2VzNi8yMDE0LTA5L3NlcHQtMjUubWQjNTEwLWdsb2JhbGFzYXAtZm9yLWVucXVldWluZy1hLW1pY3JvdGFza1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBtaWNyb3Rhc2sgPSByZXF1aXJlKCcuL19taWNyb3Rhc2snKSgpO1xudmFyIHByb2Nlc3MgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wcm9jZXNzO1xudmFyIGlzTm9kZSA9IHJlcXVpcmUoJy4vX2NvZicpKHByb2Nlc3MpID09ICdwcm9jZXNzJztcblxuJGV4cG9ydCgkZXhwb3J0LkcsIHtcbiAgYXNhcDogZnVuY3Rpb24gYXNhcChmbikge1xuICAgIHZhciBkb21haW4gPSBpc05vZGUgJiYgcHJvY2Vzcy5kb21haW47XG4gICAgbWljcm90YXNrKGRvbWFpbiA/IGRvbWFpbi5iaW5kKGZuKSA6IGZuKTtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vbGpoYXJiL3Byb3Bvc2FsLWlzLWVycm9yXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0Vycm9yJywge1xuICBpc0Vycm9yOiBmdW5jdGlvbiBpc0Vycm9yKGl0KSB7XG4gICAgcmV0dXJuIGNvZihpdCkgPT09ICdFcnJvcic7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtZ2xvYmFsXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuRywgeyBnbG9iYWw6IHJlcXVpcmUoJy4vX2dsb2JhbCcpIH0pO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnTWFwJyk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy1tYXAub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ01hcCcpO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL0RhdmlkQnJ1YW50L01hcC1TZXQucHJvdG90eXBlLnRvSlNPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdNYXAnLCB7IHRvSlNPTjogcmVxdWlyZSgnLi9fY29sbGVjdGlvbi10by1qc29uJykoJ01hcCcpIH0pO1xuIiwiLy8gaHR0cHM6Ly9yd2FsZHJvbi5naXRodWIuaW8vcHJvcG9zYWwtbWF0aC1leHRlbnNpb25zL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjbGFtcDogZnVuY3Rpb24gY2xhbXAoeCwgbG93ZXIsIHVwcGVyKSB7XG4gICAgcmV0dXJuIE1hdGgubWluKHVwcGVyLCBNYXRoLm1heChsb3dlciwgeCkpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vcndhbGRyb24uZ2l0aHViLmlvL3Byb3Bvc2FsLW1hdGgtZXh0ZW5zaW9ucy9cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgREVHX1BFUl9SQUQ6IE1hdGguUEkgLyAxODAgfSk7XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIFJBRF9QRVJfREVHID0gMTgwIC8gTWF0aC5QSTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBkZWdyZWVzOiBmdW5jdGlvbiBkZWdyZWVzKHJhZGlhbnMpIHtcbiAgICByZXR1cm4gcmFkaWFucyAqIFJBRF9QRVJfREVHO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vcndhbGRyb24uZ2l0aHViLmlvL3Byb3Bvc2FsLW1hdGgtZXh0ZW5zaW9ucy9cbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgc2NhbGUgPSByZXF1aXJlKCcuL19tYXRoLXNjYWxlJyk7XG52YXIgZnJvdW5kID0gcmVxdWlyZSgnLi9fbWF0aC1mcm91bmQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBmc2NhbGU6IGZ1bmN0aW9uIGZzY2FsZSh4LCBpbkxvdywgaW5IaWdoLCBvdXRMb3csIG91dEhpZ2gpIHtcbiAgICByZXR1cm4gZnJvdW5kKHNjYWxlKHgsIGluTG93LCBpbkhpZ2gsIG91dExvdywgb3V0SGlnaCkpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGlhZGRoOiBmdW5jdGlvbiBpYWRkaCh4MCwgeDEsIHkwLCB5MSkge1xuICAgIHZhciAkeDAgPSB4MCA+Pj4gMDtcbiAgICB2YXIgJHgxID0geDEgPj4+IDA7XG4gICAgdmFyICR5MCA9IHkwID4+PiAwO1xuICAgIHJldHVybiAkeDEgKyAoeTEgPj4+IDApICsgKCgkeDAgJiAkeTAgfCAoJHgwIHwgJHkwKSAmIH4oJHgwICsgJHkwID4+PiAwKSkgPj4+IDMxKSB8IDA7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vQnJlbmRhbkVpY2gvNDI5NGQ1YzIxMmE2ZDIyNTQ3MDNcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgaW11bGg6IGZ1bmN0aW9uIGltdWxoKHUsIHYpIHtcbiAgICB2YXIgVUlOVDE2ID0gMHhmZmZmO1xuICAgIHZhciAkdSA9ICt1O1xuICAgIHZhciAkdiA9ICt2O1xuICAgIHZhciB1MCA9ICR1ICYgVUlOVDE2O1xuICAgIHZhciB2MCA9ICR2ICYgVUlOVDE2O1xuICAgIHZhciB1MSA9ICR1ID4+IDE2O1xuICAgIHZhciB2MSA9ICR2ID4+IDE2O1xuICAgIHZhciB0ID0gKHUxICogdjAgPj4+IDApICsgKHUwICogdjAgPj4+IDE2KTtcbiAgICByZXR1cm4gdTEgKiB2MSArICh0ID4+IDE2KSArICgodTAgKiB2MSA+Pj4gMCkgKyAodCAmIFVJTlQxNikgPj4gMTYpO1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL0JyZW5kYW5FaWNoLzQyOTRkNWMyMTJhNmQyMjU0NzAzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGlzdWJoOiBmdW5jdGlvbiBpc3ViaCh4MCwgeDEsIHkwLCB5MSkge1xuICAgIHZhciAkeDAgPSB4MCA+Pj4gMDtcbiAgICB2YXIgJHgxID0geDEgPj4+IDA7XG4gICAgdmFyICR5MCA9IHkwID4+PiAwO1xuICAgIHJldHVybiAkeDEgLSAoeTEgPj4+IDApIC0gKCh+JHgwICYgJHkwIHwgfigkeDAgXiAkeTApICYgJHgwIC0gJHkwID4+PiAwKSA+Pj4gMzEpIHwgMDtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IFJBRF9QRVJfREVHOiAxODAgLyBNYXRoLlBJIH0pO1xuIiwiLy8gaHR0cHM6Ly9yd2FsZHJvbi5naXRodWIuaW8vcHJvcG9zYWwtbWF0aC1leHRlbnNpb25zL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBERUdfUEVSX1JBRCA9IE1hdGguUEkgLyAxODA7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgcmFkaWFuczogZnVuY3Rpb24gcmFkaWFucyhkZWdyZWVzKSB7XG4gICAgcmV0dXJuIGRlZ3JlZXMgKiBERUdfUEVSX1JBRDtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL3J3YWxkcm9uLmdpdGh1Yi5pby9wcm9wb3NhbC1tYXRoLWV4dGVuc2lvbnMvXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IHNjYWxlOiByZXF1aXJlKCcuL19tYXRoLXNjYWxlJykgfSk7XG4iLCIvLyBodHRwOi8vamZiYXN0aWVuLmdpdGh1Yi5pby9wYXBlcnMvTWF0aC5zaWduYml0Lmh0bWxcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgc2lnbmJpdDogZnVuY3Rpb24gc2lnbmJpdCh4KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgcmV0dXJuICh4ID0gK3gpICE9IHggPyB4IDogeCA9PSAwID8gMSAvIHggPT0gSW5maW5pdHkgOiB4ID4gMDtcbn0gfSk7XG4iLCIvLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9CcmVuZGFuRWljaC80Mjk0ZDVjMjEyYTZkMjI1NDcwM1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB1bXVsaDogZnVuY3Rpb24gdW11bGgodSwgdikge1xuICAgIHZhciBVSU5UMTYgPSAweGZmZmY7XG4gICAgdmFyICR1ID0gK3U7XG4gICAgdmFyICR2ID0gK3Y7XG4gICAgdmFyIHUwID0gJHUgJiBVSU5UMTY7XG4gICAgdmFyIHYwID0gJHYgJiBVSU5UMTY7XG4gICAgdmFyIHUxID0gJHUgPj4+IDE2O1xuICAgIHZhciB2MSA9ICR2ID4+PiAxNjtcbiAgICB2YXIgdCA9ICh1MSAqIHYwID4+PiAwKSArICh1MCAqIHYwID4+PiAxNik7XG4gICAgcmV0dXJuIHUxICogdjEgKyAodCA+Pj4gMTYpICsgKCh1MCAqIHYxID4+PiAwKSArICh0ICYgVUlOVDE2KSA+Pj4gMTYpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgJGRlZmluZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG5cbi8vIEIuMi4yLjIgT2JqZWN0LnByb3RvdHlwZS5fX2RlZmluZUdldHRlcl9fKFAsIGdldHRlcilcbnJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgJGV4cG9ydCgkZXhwb3J0LlAgKyByZXF1aXJlKCcuL19vYmplY3QtZm9yY2VkLXBhbScpLCAnT2JqZWN0Jywge1xuICBfX2RlZmluZUdldHRlcl9fOiBmdW5jdGlvbiBfX2RlZmluZUdldHRlcl9fKFAsIGdldHRlcikge1xuICAgICRkZWZpbmVQcm9wZXJ0eS5mKHRvT2JqZWN0KHRoaXMpLCBQLCB7IGdldDogYUZ1bmN0aW9uKGdldHRlciksIGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyICRkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xuXG4vLyBCLjIuMi4zIE9iamVjdC5wcm90b3R5cGUuX19kZWZpbmVTZXR0ZXJfXyhQLCBzZXR0ZXIpXG5yZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmICRleHBvcnQoJGV4cG9ydC5QICsgcmVxdWlyZSgnLi9fb2JqZWN0LWZvcmNlZC1wYW0nKSwgJ09iamVjdCcsIHtcbiAgX19kZWZpbmVTZXR0ZXJfXzogZnVuY3Rpb24gX19kZWZpbmVTZXR0ZXJfXyhQLCBzZXR0ZXIpIHtcbiAgICAkZGVmaW5lUHJvcGVydHkuZih0b09iamVjdCh0aGlzKSwgUCwgeyBzZXQ6IGFGdW5jdGlvbihzZXR0ZXIpLCBlbnVtZXJhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LXZhbHVlcy1lbnRyaWVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRlbnRyaWVzID0gcmVxdWlyZSgnLi9fb2JqZWN0LXRvLWFycmF5JykodHJ1ZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge1xuICBlbnRyaWVzOiBmdW5jdGlvbiBlbnRyaWVzKGl0KSB7XG4gICAgcmV0dXJuICRlbnRyaWVzKGl0KTtcbiAgfVxufSk7XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1vYmplY3QtZ2V0b3ducHJvcGVydHlkZXNjcmlwdG9yc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBvd25LZXlzID0gcmVxdWlyZSgnLi9fb3duLWtleXMnKTtcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgY3JlYXRlUHJvcGVydHkgPSByZXF1aXJlKCcuL19jcmVhdGUtcHJvcGVydHknKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7XG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcnM6IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcnMob2JqZWN0KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3Qob2JqZWN0KTtcbiAgICB2YXIgZ2V0RGVzYyA9IGdPUEQuZjtcbiAgICB2YXIga2V5cyA9IG93bktleXMoTyk7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIga2V5LCBkZXNjO1xuICAgIHdoaWxlIChrZXlzLmxlbmd0aCA+IGkpIHtcbiAgICAgIGRlc2MgPSBnZXREZXNjKE8sIGtleSA9IGtleXNbaSsrXSk7XG4gICAgICBpZiAoZGVzYyAhPT0gdW5kZWZpbmVkKSBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGtleSwgZGVzYyk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xuXG4vLyBCLjIuMi40IE9iamVjdC5wcm90b3R5cGUuX19sb29rdXBHZXR0ZXJfXyhQKVxucmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAkZXhwb3J0KCRleHBvcnQuUCArIHJlcXVpcmUoJy4vX29iamVjdC1mb3JjZWQtcGFtJyksICdPYmplY3QnLCB7XG4gIF9fbG9va3VwR2V0dGVyX186IGZ1bmN0aW9uIF9fbG9va3VwR2V0dGVyX18oUCkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIEsgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgICB2YXIgRDtcbiAgICBkbyB7XG4gICAgICBpZiAoRCA9IGdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBLKSkgcmV0dXJuIEQuZ2V0O1xuICAgIH0gd2hpbGUgKE8gPSBnZXRQcm90b3R5cGVPZihPKSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xuXG4vLyBCLjIuMi41IE9iamVjdC5wcm90b3R5cGUuX19sb29rdXBTZXR0ZXJfXyhQKVxucmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiAkZXhwb3J0KCRleHBvcnQuUCArIHJlcXVpcmUoJy4vX29iamVjdC1mb3JjZWQtcGFtJyksICdPYmplY3QnLCB7XG4gIF9fbG9va3VwU2V0dGVyX186IGZ1bmN0aW9uIF9fbG9va3VwU2V0dGVyX18oUCkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIEsgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgICB2YXIgRDtcbiAgICBkbyB7XG4gICAgICBpZiAoRCA9IGdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBLKSkgcmV0dXJuIEQuc2V0O1xuICAgIH0gd2hpbGUgKE8gPSBnZXRQcm90b3R5cGVPZihPKSk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LXZhbHVlcy1lbnRyaWVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICR2YWx1ZXMgPSByZXF1aXJlKCcuL19vYmplY3QtdG8tYXJyYXknKShmYWxzZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge1xuICB2YWx1ZXM6IGZ1bmN0aW9uIHZhbHVlcyhpdCkge1xuICAgIHJldHVybiAkdmFsdWVzKGl0KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vemVucGFyc2luZy9lcy1vYnNlcnZhYmxlXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBPQlNFUlZBQkxFID0gcmVxdWlyZSgnLi9fd2tzJykoJ29ic2VydmFibGUnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBSRVRVUk4gPSBmb3JPZi5SRVRVUk47XG5cbnZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoZm4pIHtcbiAgcmV0dXJuIGZuID09IG51bGwgPyB1bmRlZmluZWQgOiBhRnVuY3Rpb24oZm4pO1xufTtcblxudmFyIGNsZWFudXBTdWJzY3JpcHRpb24gPSBmdW5jdGlvbiAoc3Vic2NyaXB0aW9uKSB7XG4gIHZhciBjbGVhbnVwID0gc3Vic2NyaXB0aW9uLl9jO1xuICBpZiAoY2xlYW51cCkge1xuICAgIHN1YnNjcmlwdGlvbi5fYyA9IHVuZGVmaW5lZDtcbiAgICBjbGVhbnVwKCk7XG4gIH1cbn07XG5cbnZhciBzdWJzY3JpcHRpb25DbG9zZWQgPSBmdW5jdGlvbiAoc3Vic2NyaXB0aW9uKSB7XG4gIHJldHVybiBzdWJzY3JpcHRpb24uX28gPT09IHVuZGVmaW5lZDtcbn07XG5cbnZhciBjbG9zZVN1YnNjcmlwdGlvbiA9IGZ1bmN0aW9uIChzdWJzY3JpcHRpb24pIHtcbiAgaWYgKCFzdWJzY3JpcHRpb25DbG9zZWQoc3Vic2NyaXB0aW9uKSkge1xuICAgIHN1YnNjcmlwdGlvbi5fbyA9IHVuZGVmaW5lZDtcbiAgICBjbGVhbnVwU3Vic2NyaXB0aW9uKHN1YnNjcmlwdGlvbik7XG4gIH1cbn07XG5cbnZhciBTdWJzY3JpcHRpb24gPSBmdW5jdGlvbiAob2JzZXJ2ZXIsIHN1YnNjcmliZXIpIHtcbiAgYW5PYmplY3Qob2JzZXJ2ZXIpO1xuICB0aGlzLl9jID0gdW5kZWZpbmVkO1xuICB0aGlzLl9vID0gb2JzZXJ2ZXI7XG4gIG9ic2VydmVyID0gbmV3IFN1YnNjcmlwdGlvbk9ic2VydmVyKHRoaXMpO1xuICB0cnkge1xuICAgIHZhciBjbGVhbnVwID0gc3Vic2NyaWJlcihvYnNlcnZlcik7XG4gICAgdmFyIHN1YnNjcmlwdGlvbiA9IGNsZWFudXA7XG4gICAgaWYgKGNsZWFudXAgIT0gbnVsbCkge1xuICAgICAgaWYgKHR5cGVvZiBjbGVhbnVwLnVuc3Vic2NyaWJlID09PSAnZnVuY3Rpb24nKSBjbGVhbnVwID0gZnVuY3Rpb24gKCkgeyBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTsgfTtcbiAgICAgIGVsc2UgYUZ1bmN0aW9uKGNsZWFudXApO1xuICAgICAgdGhpcy5fYyA9IGNsZWFudXA7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgb2JzZXJ2ZXIuZXJyb3IoZSk7XG4gICAgcmV0dXJuO1xuICB9IGlmIChzdWJzY3JpcHRpb25DbG9zZWQodGhpcykpIGNsZWFudXBTdWJzY3JpcHRpb24odGhpcyk7XG59O1xuXG5TdWJzY3JpcHRpb24ucHJvdG90eXBlID0gcmVkZWZpbmVBbGwoe30sIHtcbiAgdW5zdWJzY3JpYmU6IGZ1bmN0aW9uIHVuc3Vic2NyaWJlKCkgeyBjbG9zZVN1YnNjcmlwdGlvbih0aGlzKTsgfVxufSk7XG5cbnZhciBTdWJzY3JpcHRpb25PYnNlcnZlciA9IGZ1bmN0aW9uIChzdWJzY3JpcHRpb24pIHtcbiAgdGhpcy5fcyA9IHN1YnNjcmlwdGlvbjtcbn07XG5cblN1YnNjcmlwdGlvbk9ic2VydmVyLnByb3RvdHlwZSA9IHJlZGVmaW5lQWxsKHt9LCB7XG4gIG5leHQ6IGZ1bmN0aW9uIG5leHQodmFsdWUpIHtcbiAgICB2YXIgc3Vic2NyaXB0aW9uID0gdGhpcy5fcztcbiAgICBpZiAoIXN1YnNjcmlwdGlvbkNsb3NlZChzdWJzY3JpcHRpb24pKSB7XG4gICAgICB2YXIgb2JzZXJ2ZXIgPSBzdWJzY3JpcHRpb24uX287XG4gICAgICB0cnkge1xuICAgICAgICB2YXIgbSA9IGdldE1ldGhvZChvYnNlcnZlci5uZXh0KTtcbiAgICAgICAgaWYgKG0pIHJldHVybiBtLmNhbGwob2JzZXJ2ZXIsIHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjbG9zZVN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIGVycm9yOiBmdW5jdGlvbiBlcnJvcih2YWx1ZSkge1xuICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGlzLl9zO1xuICAgIGlmIChzdWJzY3JpcHRpb25DbG9zZWQoc3Vic2NyaXB0aW9uKSkgdGhyb3cgdmFsdWU7XG4gICAgdmFyIG9ic2VydmVyID0gc3Vic2NyaXB0aW9uLl9vO1xuICAgIHN1YnNjcmlwdGlvbi5fbyA9IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgdmFyIG0gPSBnZXRNZXRob2Qob2JzZXJ2ZXIuZXJyb3IpO1xuICAgICAgaWYgKCFtKSB0aHJvdyB2YWx1ZTtcbiAgICAgIHZhbHVlID0gbS5jYWxsKG9ic2VydmVyLCB2YWx1ZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGNsZWFudXBTdWJzY3JpcHRpb24oc3Vic2NyaXB0aW9uKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIGNvbXBsZXRlOiBmdW5jdGlvbiBjb21wbGV0ZSh2YWx1ZSkge1xuICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGlzLl9zO1xuICAgIGlmICghc3Vic2NyaXB0aW9uQ2xvc2VkKHN1YnNjcmlwdGlvbikpIHtcbiAgICAgIHZhciBvYnNlcnZlciA9IHN1YnNjcmlwdGlvbi5fbztcbiAgICAgIHN1YnNjcmlwdGlvbi5fbyA9IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhciBtID0gZ2V0TWV0aG9kKG9ic2VydmVyLmNvbXBsZXRlKTtcbiAgICAgICAgdmFsdWUgPSBtID8gbS5jYWxsKG9ic2VydmVyLCB2YWx1ZSkgOiB1bmRlZmluZWQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH0gY2xlYW51cFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgfVxufSk7XG5cbnZhciAkT2JzZXJ2YWJsZSA9IGZ1bmN0aW9uIE9ic2VydmFibGUoc3Vic2NyaWJlcikge1xuICBhbkluc3RhbmNlKHRoaXMsICRPYnNlcnZhYmxlLCAnT2JzZXJ2YWJsZScsICdfZicpLl9mID0gYUZ1bmN0aW9uKHN1YnNjcmliZXIpO1xufTtcblxucmVkZWZpbmVBbGwoJE9ic2VydmFibGUucHJvdG90eXBlLCB7XG4gIHN1YnNjcmliZTogZnVuY3Rpb24gc3Vic2NyaWJlKG9ic2VydmVyKSB7XG4gICAgcmV0dXJuIG5ldyBTdWJzY3JpcHRpb24ob2JzZXJ2ZXIsIHRoaXMuX2YpO1xuICB9LFxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGZuKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHJldHVybiBuZXcgKGNvcmUuUHJvbWlzZSB8fCBnbG9iYWwuUHJvbWlzZSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgYUZ1bmN0aW9uKGZuKTtcbiAgICAgIHZhciBzdWJzY3JpcHRpb24gPSB0aGF0LnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZm4odmFsdWUpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IHJlamVjdCxcbiAgICAgICAgY29tcGxldGU6IHJlc29sdmVcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59KTtcblxucmVkZWZpbmVBbGwoJE9ic2VydmFibGUsIHtcbiAgZnJvbTogZnVuY3Rpb24gZnJvbSh4KSB7XG4gICAgdmFyIEMgPSB0eXBlb2YgdGhpcyA9PT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiAkT2JzZXJ2YWJsZTtcbiAgICB2YXIgbWV0aG9kID0gZ2V0TWV0aG9kKGFuT2JqZWN0KHgpW09CU0VSVkFCTEVdKTtcbiAgICBpZiAobWV0aG9kKSB7XG4gICAgICB2YXIgb2JzZXJ2YWJsZSA9IGFuT2JqZWN0KG1ldGhvZC5jYWxsKHgpKTtcbiAgICAgIHJldHVybiBvYnNlcnZhYmxlLmNvbnN0cnVjdG9yID09PSBDID8gb2JzZXJ2YWJsZSA6IG5ldyBDKGZ1bmN0aW9uIChvYnNlcnZlcikge1xuICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZS5zdWJzY3JpYmUob2JzZXJ2ZXIpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQyhmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcbiAgICAgIHZhciBkb25lID0gZmFsc2U7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWRvbmUpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKGZvck9mKHgsIGZhbHNlLCBmdW5jdGlvbiAoaXQpIHtcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChpdCk7XG4gICAgICAgICAgICAgIGlmIChkb25lKSByZXR1cm4gUkVUVVJOO1xuICAgICAgICAgICAgfSkgPT09IFJFVFVSTikgcmV0dXJuO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChkb25lKSB0aHJvdyBlO1xuICAgICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfSBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IGRvbmUgPSB0cnVlOyB9O1xuICAgIH0pO1xuICB9LFxuICBvZjogZnVuY3Rpb24gb2YoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcmd1bWVudHMubGVuZ3RoLCBpdGVtcyA9IG5ldyBBcnJheShsKTsgaSA8IGw7KSBpdGVtc1tpXSA9IGFyZ3VtZW50c1tpKytdO1xuICAgIHJldHVybiBuZXcgKHR5cGVvZiB0aGlzID09PSAnZnVuY3Rpb24nID8gdGhpcyA6ICRPYnNlcnZhYmxlKShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcbiAgICAgIHZhciBkb25lID0gZmFsc2U7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWRvbmUpIHtcbiAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGl0ZW1zLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICBvYnNlcnZlci5uZXh0KGl0ZW1zW2pdKTtcbiAgICAgICAgICAgIGlmIChkb25lKSByZXR1cm47XG4gICAgICAgICAgfSBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IGRvbmUgPSB0cnVlOyB9O1xuICAgIH0pO1xuICB9XG59KTtcblxuaGlkZSgkT2JzZXJ2YWJsZS5wcm90b3R5cGUsIE9CU0VSVkFCTEUsIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0pO1xuXG4kZXhwb3J0KCRleHBvcnQuRywgeyBPYnNlcnZhYmxlOiAkT2JzZXJ2YWJsZSB9KTtcblxucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKSgnT2JzZXJ2YWJsZScpO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcHJvbWlzZS1maW5hbGx5XG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xudmFyIHByb21pc2VSZXNvbHZlID0gcmVxdWlyZSgnLi9fcHJvbWlzZS1yZXNvbHZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5SLCAnUHJvbWlzZScsIHsgJ2ZpbmFsbHknOiBmdW5jdGlvbiAob25GaW5hbGx5KSB7XG4gIHZhciBDID0gc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsIGNvcmUuUHJvbWlzZSB8fCBnbG9iYWwuUHJvbWlzZSk7XG4gIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIG9uRmluYWxseSA9PSAnZnVuY3Rpb24nO1xuICByZXR1cm4gdGhpcy50aGVuKFxuICAgIGlzRnVuY3Rpb24gPyBmdW5jdGlvbiAoeCkge1xuICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKEMsIG9uRmluYWxseSgpKS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHg7IH0pO1xuICAgIH0gOiBvbkZpbmFsbHksXG4gICAgaXNGdW5jdGlvbiA/IGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmUoQywgb25GaW5hbGx5KCkpLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyBlOyB9KTtcbiAgICB9IDogb25GaW5hbGx5XG4gICk7XG59IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcHJvbWlzZS10cnlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgbmV3UHJvbWlzZUNhcGFiaWxpdHkgPSByZXF1aXJlKCcuL19uZXctcHJvbWlzZS1jYXBhYmlsaXR5Jyk7XG52YXIgcGVyZm9ybSA9IHJlcXVpcmUoJy4vX3BlcmZvcm0nKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdQcm9taXNlJywgeyAndHJ5JzogZnVuY3Rpb24gKGNhbGxiYWNrZm4pIHtcbiAgdmFyIHByb21pc2VDYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkuZih0aGlzKTtcbiAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oY2FsbGJhY2tmbik7XG4gIChyZXN1bHQuZSA/IHByb21pc2VDYXBhYmlsaXR5LnJlamVjdCA6IHByb21pc2VDYXBhYmlsaXR5LnJlc29sdmUpKHJlc3VsdC52KTtcbiAgcmV0dXJuIHByb21pc2VDYXBhYmlsaXR5LnByb21pc2U7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvTWV0YUtleSA9IG1ldGFkYXRhLmtleTtcbnZhciBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhID0gbWV0YWRhdGEuc2V0O1xuXG5tZXRhZGF0YS5leHAoeyBkZWZpbmVNZXRhZGF0YTogZnVuY3Rpb24gZGVmaW5lTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIHRhcmdldCwgdGFyZ2V0S2V5KSB7XG4gIG9yZGluYXJ5RGVmaW5lT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUsIGFuT2JqZWN0KHRhcmdldCksIHRvTWV0YUtleSh0YXJnZXRLZXkpKTtcbn0gfSk7XG4iLCJ2YXIgbWV0YWRhdGEgPSByZXF1aXJlKCcuL19tZXRhZGF0YScpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xudmFyIGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAgPSBtZXRhZGF0YS5tYXA7XG52YXIgc3RvcmUgPSBtZXRhZGF0YS5zdG9yZTtcblxubWV0YWRhdGEuZXhwKHsgZGVsZXRlTWV0YWRhdGE6IGZ1bmN0aW9uIGRlbGV0ZU1ldGFkYXRhKG1ldGFkYXRhS2V5LCB0YXJnZXQgLyogLCB0YXJnZXRLZXkgKi8pIHtcbiAgdmFyIHRhcmdldEtleSA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdW5kZWZpbmVkIDogdG9NZXRhS2V5KGFyZ3VtZW50c1syXSk7XG4gIHZhciBtZXRhZGF0YU1hcCA9IGdldE9yQ3JlYXRlTWV0YWRhdGFNYXAoYW5PYmplY3QodGFyZ2V0KSwgdGFyZ2V0S2V5LCBmYWxzZSk7XG4gIGlmIChtZXRhZGF0YU1hcCA9PT0gdW5kZWZpbmVkIHx8ICFtZXRhZGF0YU1hcFsnZGVsZXRlJ10obWV0YWRhdGFLZXkpKSByZXR1cm4gZmFsc2U7XG4gIGlmIChtZXRhZGF0YU1hcC5zaXplKSByZXR1cm4gdHJ1ZTtcbiAgdmFyIHRhcmdldE1ldGFkYXRhID0gc3RvcmUuZ2V0KHRhcmdldCk7XG4gIHRhcmdldE1ldGFkYXRhWydkZWxldGUnXSh0YXJnZXRLZXkpO1xuICByZXR1cm4gISF0YXJnZXRNZXRhZGF0YS5zaXplIHx8IHN0b3JlWydkZWxldGUnXSh0YXJnZXQpO1xufSB9KTtcbiIsInZhciBTZXQgPSByZXF1aXJlKCcuL2VzNi5zZXQnKTtcbnZhciBmcm9tID0gcmVxdWlyZSgnLi9fYXJyYXktZnJvbS1pdGVyYWJsZScpO1xudmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzID0gbWV0YWRhdGEua2V5cztcbnZhciB0b01ldGFLZXkgPSBtZXRhZGF0YS5rZXk7XG5cbnZhciBvcmRpbmFyeU1ldGFkYXRhS2V5cyA9IGZ1bmN0aW9uIChPLCBQKSB7XG4gIHZhciBvS2V5cyA9IG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzKE8sIFApO1xuICB2YXIgcGFyZW50ID0gZ2V0UHJvdG90eXBlT2YoTyk7XG4gIGlmIChwYXJlbnQgPT09IG51bGwpIHJldHVybiBvS2V5cztcbiAgdmFyIHBLZXlzID0gb3JkaW5hcnlNZXRhZGF0YUtleXMocGFyZW50LCBQKTtcbiAgcmV0dXJuIHBLZXlzLmxlbmd0aCA/IG9LZXlzLmxlbmd0aCA/IGZyb20obmV3IFNldChvS2V5cy5jb25jYXQocEtleXMpKSkgOiBwS2V5cyA6IG9LZXlzO1xufTtcblxubWV0YWRhdGEuZXhwKHsgZ2V0TWV0YWRhdGFLZXlzOiBmdW5jdGlvbiBnZXRNZXRhZGF0YUtleXModGFyZ2V0IC8qICwgdGFyZ2V0S2V5ICovKSB7XG4gIHJldHVybiBvcmRpbmFyeU1ldGFkYXRhS2V5cyhhbk9iamVjdCh0YXJnZXQpLCBhcmd1bWVudHMubGVuZ3RoIDwgMiA/IHVuZGVmaW5lZCA6IHRvTWV0YUtleShhcmd1bWVudHNbMV0pKTtcbn0gfSk7XG4iLCJ2YXIgbWV0YWRhdGEgPSByZXF1aXJlKCcuL19tZXRhZGF0YScpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgb3JkaW5hcnlIYXNPd25NZXRhZGF0YSA9IG1ldGFkYXRhLmhhcztcbnZhciBvcmRpbmFyeUdldE93bk1ldGFkYXRhID0gbWV0YWRhdGEuZ2V0O1xudmFyIHRvTWV0YUtleSA9IG1ldGFkYXRhLmtleTtcblxudmFyIG9yZGluYXJ5R2V0TWV0YWRhdGEgPSBmdW5jdGlvbiAoTWV0YWRhdGFLZXksIE8sIFApIHtcbiAgdmFyIGhhc093biA9IG9yZGluYXJ5SGFzT3duTWV0YWRhdGEoTWV0YWRhdGFLZXksIE8sIFApO1xuICBpZiAoaGFzT3duKSByZXR1cm4gb3JkaW5hcnlHZXRPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XG4gIHZhciBwYXJlbnQgPSBnZXRQcm90b3R5cGVPZihPKTtcbiAgcmV0dXJuIHBhcmVudCAhPT0gbnVsbCA/IG9yZGluYXJ5R2V0TWV0YWRhdGEoTWV0YWRhdGFLZXksIHBhcmVudCwgUCkgOiB1bmRlZmluZWQ7XG59O1xuXG5tZXRhZGF0YS5leHAoeyBnZXRNZXRhZGF0YTogZnVuY3Rpb24gZ2V0TWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlHZXRNZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIG9yZGluYXJ5T3duTWV0YWRhdGFLZXlzID0gbWV0YWRhdGEua2V5cztcbnZhciB0b01ldGFLZXkgPSBtZXRhZGF0YS5rZXk7XG5cbm1ldGFkYXRhLmV4cCh7IGdldE93bk1ldGFkYXRhS2V5czogZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGFLZXlzKHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlPd25NZXRhZGF0YUtleXMoYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDIgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzFdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIG9yZGluYXJ5R2V0T3duTWV0YWRhdGEgPSBtZXRhZGF0YS5nZXQ7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xuXG5tZXRhZGF0YS5leHAoeyBnZXRPd25NZXRhZGF0YTogZnVuY3Rpb24gZ2V0T3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlHZXRPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KVxuICAgICwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBtZXRhZGF0YS5oYXM7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xuXG52YXIgb3JkaW5hcnlIYXNNZXRhZGF0YSA9IGZ1bmN0aW9uIChNZXRhZGF0YUtleSwgTywgUCkge1xuICB2YXIgaGFzT3duID0gb3JkaW5hcnlIYXNPd25NZXRhZGF0YShNZXRhZGF0YUtleSwgTywgUCk7XG4gIGlmIChoYXNPd24pIHJldHVybiB0cnVlO1xuICB2YXIgcGFyZW50ID0gZ2V0UHJvdG90eXBlT2YoTyk7XG4gIHJldHVybiBwYXJlbnQgIT09IG51bGwgPyBvcmRpbmFyeUhhc01ldGFkYXRhKE1ldGFkYXRhS2V5LCBwYXJlbnQsIFApIDogZmFsc2U7XG59O1xuXG5tZXRhZGF0YS5leHAoeyBoYXNNZXRhZGF0YTogZnVuY3Rpb24gaGFzTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlIYXNNZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KSwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyIG1ldGFkYXRhID0gcmVxdWlyZSgnLi9fbWV0YWRhdGEnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIG9yZGluYXJ5SGFzT3duTWV0YWRhdGEgPSBtZXRhZGF0YS5oYXM7XG52YXIgdG9NZXRhS2V5ID0gbWV0YWRhdGEua2V5O1xuXG5tZXRhZGF0YS5leHAoeyBoYXNPd25NZXRhZGF0YTogZnVuY3Rpb24gaGFzT3duTWV0YWRhdGEobWV0YWRhdGFLZXksIHRhcmdldCAvKiAsIHRhcmdldEtleSAqLykge1xuICByZXR1cm4gb3JkaW5hcnlIYXNPd25NZXRhZGF0YShtZXRhZGF0YUtleSwgYW5PYmplY3QodGFyZ2V0KVxuICAgICwgYXJndW1lbnRzLmxlbmd0aCA8IDMgPyB1bmRlZmluZWQgOiB0b01ldGFLZXkoYXJndW1lbnRzWzJdKSk7XG59IH0pO1xuIiwidmFyICRtZXRhZGF0YSA9IHJlcXVpcmUoJy4vX21ldGFkYXRhJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgdG9NZXRhS2V5ID0gJG1ldGFkYXRhLmtleTtcbnZhciBvcmRpbmFyeURlZmluZU93bk1ldGFkYXRhID0gJG1ldGFkYXRhLnNldDtcblxuJG1ldGFkYXRhLmV4cCh7IG1ldGFkYXRhOiBmdW5jdGlvbiBtZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24gZGVjb3JhdG9yKHRhcmdldCwgdGFyZ2V0S2V5KSB7XG4gICAgb3JkaW5hcnlEZWZpbmVPd25NZXRhZGF0YShcbiAgICAgIG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlLFxuICAgICAgKHRhcmdldEtleSAhPT0gdW5kZWZpbmVkID8gYW5PYmplY3QgOiBhRnVuY3Rpb24pKHRhcmdldCksXG4gICAgICB0b01ldGFLZXkodGFyZ2V0S2V5KVxuICAgICk7XG4gIH07XG59IH0pO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtc2V0LmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnU2V0Jyk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy1zZXQub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ1NldCcpO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL0RhdmlkQnJ1YW50L01hcC1TZXQucHJvdG90eXBlLnRvSlNPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlIsICdTZXQnLCB7IHRvSlNPTjogcmVxdWlyZSgnLi9fY29sbGVjdGlvbi10by1qc29uJykoJ1NldCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL21hdGhpYXNieW5lbnMvU3RyaW5nLnByb3RvdHlwZS5hdFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkYXQgPSByZXF1aXJlKCcuL19zdHJpbmctYXQnKSh0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdTdHJpbmcnLCB7XG4gIGF0OiBmdW5jdGlvbiBhdChwb3MpIHtcbiAgICByZXR1cm4gJGF0KHRoaXMsIHBvcyk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9TdHJpbmcucHJvdG90eXBlLm1hdGNoQWxsL1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuL19pcy1yZWdleHAnKTtcbnZhciBnZXRGbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG52YXIgUmVnRXhwUHJvdG8gPSBSZWdFeHAucHJvdG90eXBlO1xuXG52YXIgJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yID0gZnVuY3Rpb24gKHJlZ2V4cCwgc3RyaW5nKSB7XG4gIHRoaXMuX3IgPSByZWdleHA7XG4gIHRoaXMuX3MgPSBzdHJpbmc7XG59O1xuXG5yZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpKCRSZWdFeHBTdHJpbmdJdGVyYXRvciwgJ1JlZ0V4cCBTdHJpbmcnLCBmdW5jdGlvbiBuZXh0KCkge1xuICB2YXIgbWF0Y2ggPSB0aGlzLl9yLmV4ZWModGhpcy5fcyk7XG4gIHJldHVybiB7IHZhbHVlOiBtYXRjaCwgZG9uZTogbWF0Y2ggPT09IG51bGwgfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ1N0cmluZycsIHtcbiAgbWF0Y2hBbGw6IGZ1bmN0aW9uIG1hdGNoQWxsKHJlZ2V4cCkge1xuICAgIGRlZmluZWQodGhpcyk7XG4gICAgaWYgKCFpc1JlZ0V4cChyZWdleHApKSB0aHJvdyBUeXBlRXJyb3IocmVnZXhwICsgJyBpcyBub3QgYSByZWdleHAhJyk7XG4gICAgdmFyIFMgPSBTdHJpbmcodGhpcyk7XG4gICAgdmFyIGZsYWdzID0gJ2ZsYWdzJyBpbiBSZWdFeHBQcm90byA/IFN0cmluZyhyZWdleHAuZmxhZ3MpIDogZ2V0RmxhZ3MuY2FsbChyZWdleHApO1xuICAgIHZhciByeCA9IG5ldyBSZWdFeHAocmVnZXhwLnNvdXJjZSwgfmZsYWdzLmluZGV4T2YoJ2cnKSA/IGZsYWdzIDogJ2cnICsgZmxhZ3MpO1xuICAgIHJ4Lmxhc3RJbmRleCA9IHRvTGVuZ3RoKHJlZ2V4cC5sYXN0SW5kZXgpO1xuICAgIHJldHVybiBuZXcgJFJlZ0V4cFN0cmluZ0l0ZXJhdG9yKHJ4LCBTKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vdGMzOS9wcm9wb3NhbC1zdHJpbmctcGFkLXN0YXJ0LWVuZFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFkID0gcmVxdWlyZSgnLi9fc3RyaW5nLXBhZCcpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcblxuLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvaXNzdWVzLzI4MFxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAvVmVyc2lvblxcLzEwXFwuXFxkKyhcXC5cXGQrKT8gU2FmYXJpXFwvLy50ZXN0KHVzZXJBZ2VudCksICdTdHJpbmcnLCB7XG4gIHBhZEVuZDogZnVuY3Rpb24gcGFkRW5kKG1heExlbmd0aCAvKiAsIGZpbGxTdHJpbmcgPSAnICcgKi8pIHtcbiAgICByZXR1cm4gJHBhZCh0aGlzLCBtYXhMZW5ndGgsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCBmYWxzZSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLXBhZC1zdGFydC1lbmRcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHBhZCA9IHJlcXVpcmUoJy4vX3N0cmluZy1wYWQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8yODBcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogL1ZlcnNpb25cXC8xMFxcLlxcZCsoXFwuXFxkKyk/IFNhZmFyaVxcLy8udGVzdCh1c2VyQWdlbnQpLCAnU3RyaW5nJywge1xuICBwYWRTdGFydDogZnVuY3Rpb24gcGFkU3RhcnQobWF4TGVuZ3RoIC8qICwgZmlsbFN0cmluZyA9ICcgJyAqLykge1xuICAgIHJldHVybiAkcGFkKHRoaXMsIG1heExlbmd0aCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsIHRydWUpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zZWJtYXJrYmFnZS9lY21hc2NyaXB0LXN0cmluZy1sZWZ0LXJpZ2h0LXRyaW1cbnJlcXVpcmUoJy4vX3N0cmluZy10cmltJykoJ3RyaW1MZWZ0JywgZnVuY3Rpb24gKCR0cmltKSB7XG4gIHJldHVybiBmdW5jdGlvbiB0cmltTGVmdCgpIHtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMSk7XG4gIH07XG59LCAndHJpbVN0YXJ0Jyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBodHRwczovL2dpdGh1Yi5jb20vc2VibWFya2JhZ2UvZWNtYXNjcmlwdC1zdHJpbmctbGVmdC1yaWdodC10cmltXG5yZXF1aXJlKCcuL19zdHJpbmctdHJpbScpKCd0cmltUmlnaHQnLCBmdW5jdGlvbiAoJHRyaW0pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHRyaW1SaWdodCgpIHtcbiAgICByZXR1cm4gJHRyaW0odGhpcywgMik7XG4gIH07XG59LCAndHJpbUVuZCcpO1xuIiwicmVxdWlyZSgnLi9fd2tzLWRlZmluZScpKCdhc3luY0l0ZXJhdG9yJyk7XG4iLCJyZXF1aXJlKCcuL193a3MtZGVmaW5lJykoJ29ic2VydmFibGUnKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLWdsb2JhbFxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdTeXN0ZW0nLCB7IGdsb2JhbDogcmVxdWlyZSgnLi9fZ2xvYmFsJykgfSk7XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL3Byb3Bvc2FsLXNldG1hcC1vZmZyb20vI3NlYy13ZWFrbWFwLmZyb21cbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLWZyb20nKSgnV2Vha01hcCcpO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtd2Vha21hcC5vZlxucmVxdWlyZSgnLi9fc2V0LWNvbGxlY3Rpb24tb2YnKSgnV2Vha01hcCcpO1xuIiwiLy8gaHR0cHM6Ly90YzM5LmdpdGh1Yi5pby9wcm9wb3NhbC1zZXRtYXAtb2Zmcm9tLyNzZWMtd2Vha3NldC5mcm9tXG5yZXF1aXJlKCcuL19zZXQtY29sbGVjdGlvbi1mcm9tJykoJ1dlYWtTZXQnKTtcbiIsIi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtc2V0bWFwLW9mZnJvbS8jc2VjLXdlYWtzZXQub2ZcbnJlcXVpcmUoJy4vX3NldC1jb2xsZWN0aW9uLW9mJykoJ1dlYWtTZXQnKTtcbiIsInZhciAkaXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciBJVEVSQVRPUiA9IHdrcygnaXRlcmF0b3InKTtcbnZhciBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xudmFyIEFycmF5VmFsdWVzID0gSXRlcmF0b3JzLkFycmF5O1xuXG52YXIgRE9NSXRlcmFibGVzID0ge1xuICBDU1NSdWxlTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIENTU1N0eWxlRGVjbGFyYXRpb246IGZhbHNlLFxuICBDU1NWYWx1ZUxpc3Q6IGZhbHNlLFxuICBDbGllbnRSZWN0TGlzdDogZmFsc2UsXG4gIERPTVJlY3RMaXN0OiBmYWxzZSxcbiAgRE9NU3RyaW5nTGlzdDogZmFsc2UsXG4gIERPTVRva2VuTGlzdDogdHJ1ZSxcbiAgRGF0YVRyYW5zZmVySXRlbUxpc3Q6IGZhbHNlLFxuICBGaWxlTGlzdDogZmFsc2UsXG4gIEhUTUxBbGxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTENvbGxlY3Rpb246IGZhbHNlLFxuICBIVE1MRm9ybUVsZW1lbnQ6IGZhbHNlLFxuICBIVE1MU2VsZWN0RWxlbWVudDogZmFsc2UsXG4gIE1lZGlhTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIE1pbWVUeXBlQXJyYXk6IGZhbHNlLFxuICBOYW1lZE5vZGVNYXA6IGZhbHNlLFxuICBOb2RlTGlzdDogdHJ1ZSxcbiAgUGFpbnRSZXF1ZXN0TGlzdDogZmFsc2UsXG4gIFBsdWdpbjogZmFsc2UsXG4gIFBsdWdpbkFycmF5OiBmYWxzZSxcbiAgU1ZHTGVuZ3RoTGlzdDogZmFsc2UsXG4gIFNWR051bWJlckxpc3Q6IGZhbHNlLFxuICBTVkdQYXRoU2VnTGlzdDogZmFsc2UsXG4gIFNWR1BvaW50TGlzdDogZmFsc2UsXG4gIFNWR1N0cmluZ0xpc3Q6IGZhbHNlLFxuICBTVkdUcmFuc2Zvcm1MaXN0OiBmYWxzZSxcbiAgU291cmNlQnVmZmVyTGlzdDogZmFsc2UsXG4gIFN0eWxlU2hlZXRMaXN0OiB0cnVlLCAvLyBUT0RPOiBOb3Qgc3BlYyBjb21wbGlhbnQsIHNob3VsZCBiZSBmYWxzZS5cbiAgVGV4dFRyYWNrQ3VlTGlzdDogZmFsc2UsXG4gIFRleHRUcmFja0xpc3Q6IGZhbHNlLFxuICBUb3VjaExpc3Q6IGZhbHNlXG59O1xuXG5mb3IgKHZhciBjb2xsZWN0aW9ucyA9IGdldEtleXMoRE9NSXRlcmFibGVzKSwgaSA9IDA7IGkgPCBjb2xsZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICB2YXIgTkFNRSA9IGNvbGxlY3Rpb25zW2ldO1xuICB2YXIgZXhwbGljaXQgPSBET01JdGVyYWJsZXNbTkFNRV07XG4gIHZhciBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgcHJvdG8gPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICB2YXIga2V5O1xuICBpZiAocHJvdG8pIHtcbiAgICBpZiAoIXByb3RvW0lURVJBVE9SXSkgaGlkZShwcm90bywgSVRFUkFUT1IsIEFycmF5VmFsdWVzKTtcbiAgICBpZiAoIXByb3RvW1RPX1NUUklOR19UQUddKSBoaWRlKHByb3RvLCBUT19TVFJJTkdfVEFHLCBOQU1FKTtcbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBBcnJheVZhbHVlcztcbiAgICBpZiAoZXhwbGljaXQpIGZvciAoa2V5IGluICRpdGVyYXRvcnMpIGlmICghcHJvdG9ba2V5XSkgcmVkZWZpbmUocHJvdG8sIGtleSwgJGl0ZXJhdG9yc1trZXldLCB0cnVlKTtcbiAgfVxufVxuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5CLCB7XG4gIHNldEltbWVkaWF0ZTogJHRhc2suc2V0LFxuICBjbGVhckltbWVkaWF0ZTogJHRhc2suY2xlYXJcbn0pO1xuIiwiLy8gaWU5LSBzZXRUaW1lb3V0ICYgc2V0SW50ZXJ2YWwgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGZpeFxudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG52YXIgc2xpY2UgPSBbXS5zbGljZTtcbnZhciBNU0lFID0gL01TSUUgLlxcLi8udGVzdCh1c2VyQWdlbnQpOyAvLyA8LSBkaXJ0eSBpZTktIGNoZWNrXG52YXIgd3JhcCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChmbiwgdGltZSAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgICB2YXIgYm91bmRBcmdzID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gICAgdmFyIGFyZ3MgPSBib3VuZEFyZ3MgPyBzbGljZS5jYWxsKGFyZ3VtZW50cywgMikgOiBmYWxzZTtcbiAgICByZXR1cm4gc2V0KGJvdW5kQXJncyA/IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbikpLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0gOiBmbiwgdGltZSk7XG4gIH07XG59O1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkIgKyAkZXhwb3J0LkYgKiBNU0lFLCB7XG4gIHNldFRpbWVvdXQ6IHdyYXAoZ2xvYmFsLnNldFRpbWVvdXQpLFxuICBzZXRJbnRlcnZhbDogd3JhcChnbG9iYWwuc2V0SW50ZXJ2YWwpXG59KTtcbiIsInJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3ltYm9sJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5jcmVhdGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0eScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZ2V0LW93bi1wcm9wZXJ0eS1uYW1lcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuZnJlZXplJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5wcmV2ZW50LWV4dGVuc2lvbnMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmlzLWZyb3plbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtc2VhbGVkJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5pcy1leHRlbnNpYmxlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYub2JqZWN0LmlzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5mdW5jdGlvbi5uYW1lJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmZ1bmN0aW9uLmhhcy1pbnN0YW5jZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5wYXJzZS1pbnQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucGFyc2UtZmxvYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmNvbnN0cnVjdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci50by1maXhlZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIudG8tcHJlY2lzaW9uJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5lcHNpbG9uJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5pcy1maW5pdGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmlzLWludGVnZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubnVtYmVyLmlzLW5hbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5tYXgtc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5taW4tc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguYWNvc2gnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5hc2luaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmF0YW5oJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguY2JydCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmNsejMyJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguY29zaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmV4cG0xJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguZnJvdW5kJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguaHlwb3QnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5pbXVsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGgubG9nMTAnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5sb2cxcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLmxvZzInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC5zaWduJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2Lm1hdGguc2luaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5tYXRoLnRhbmgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWF0aC50cnVuYycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuZnJvbS1jb2RlLXBvaW50Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5yYXcnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5jb2RlLXBvaW50LWF0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5lbmRzLXdpdGgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmluY2x1ZGVzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5yZXBlYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnN0YXJ0cy13aXRoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5hbmNob3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmJpZycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmxpbmsnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmJvbGQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmZpeGVkJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLmZvbnRzaXplJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5pdGFsaWNzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5saW5rJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5zbWFsbCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5zdHJpbmcuc3RyaWtlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnN0cmluZy5zdWInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuc3RyaW5nLnN1cCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5kYXRlLm5vdycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5kYXRlLnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuZGF0ZS50by1pc28tc3RyaW5nJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmRhdGUudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmRhdGUudG8tcHJpbWl0aXZlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmlzLWFycmF5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZyb20nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkub2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuam9pbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5zbGljZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5zb3J0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZvci1lYWNoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5Lm1hcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5maWx0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuc29tZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5ldmVyeScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkucmVkdWNlLXJpZ2h0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmluZGV4LW9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5Lmxhc3QtaW5kZXgtb2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuY29weS13aXRoaW4nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuZmlsbCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LmFycmF5LmZpbmQtaW5kZXgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYuYXJyYXkuc3BlY2llcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWdleHAuY29uc3RydWN0b3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLmV4ZWMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWdleHAuZmxhZ3MnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLm1hdGNoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZ2V4cC5yZXBsYWNlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZ2V4cC5zZWFyY2gnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVnZXhwLnNwbGl0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnByb21pc2UnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYubWFwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnNldCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi53ZWFrLW1hcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi53ZWFrLXNldCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC5hcnJheS1idWZmZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuZGF0YS12aWV3Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnR5cGVkLmludDgtYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQudWludDgtYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQudWludDgtY2xhbXBlZC1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi50eXBlZC51aW50MTYtYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuaW50MzItYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQudWludDMyLWFycmF5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnR5cGVkLmZsb2F0MzItYXJyYXknKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYudHlwZWQuZmxvYXQ2NC1hcnJheScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmFwcGx5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuY29uc3RydWN0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVmaW5lLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVsZXRlLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZW51bWVyYXRlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmhhcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmlzLWV4dGVuc2libGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczYucmVmbGVjdC5vd24ta2V5cycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnByZXZlbnQtZXh0ZW5zaW9ucycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC1wcm90b3R5cGUtb2YnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuYXJyYXkuaW5jbHVkZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuYXJyYXkuZmxhdC1tYXAnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuYXJyYXkuZmxhdHRlbicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcuYXQnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLWVuZCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zdHJpbmcudHJpbS1sZWZ0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN0cmluZy50cmltLXJpZ2h0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN0cmluZy5tYXRjaC1hbGwnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN5bWJvbC5vYnNlcnZhYmxlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9iamVjdC52YWx1ZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1nZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0LmRlZmluZS1zZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1nZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcub2JqZWN0Lmxvb2t1cC1zZXR0ZXInKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWFwLnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuc2V0LnRvLWpzb24nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWFwLm9mJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnNldC5vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy53ZWFrLW1hcC5vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy53ZWFrLXNldC5vZicpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXAuZnJvbScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5zZXQuZnJvbScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy53ZWFrLW1hcC5mcm9tJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LndlYWstc2V0LmZyb20nKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuZ2xvYmFsJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnN5c3RlbS5nbG9iYWwnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcuZXJyb3IuaXMtZXJyb3InKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWF0aC5jbGFtcCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLmRlZy1wZXItcmFkJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGguZGVncmVlcycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLmZzY2FsZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLmlhZGRoJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGguaXN1YmgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWF0aC5pbXVsaCcpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLnJhZC1wZXItZGVnJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGgucmFkaWFucycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5tYXRoLnNjYWxlJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm1hdGgudW11bGgnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcubWF0aC5zaWduYml0Jyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnByb21pc2UuZmluYWxseScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5wcm9taXNlLnRyeScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlZmluZS1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmRlbGV0ZS1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1tZXRhZGF0YS1rZXlzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3LnJlZmxlY3QuZ2V0LW93bi1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0LmdldC1vd24tbWV0YWRhdGEta2V5cycpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0Lmhhcy1tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5yZWZsZWN0Lmhhcy1vd24tbWV0YWRhdGEnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy9lczcucmVmbGVjdC5tZXRhZGF0YScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL2VzNy5hc2FwJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvZXM3Lm9ic2VydmFibGUnKTtcbnJlcXVpcmUoJy4vbW9kdWxlcy93ZWIudGltZXJzJyk7XG5yZXF1aXJlKCcuL21vZHVsZXMvd2ViLmltbWVkaWF0ZScpO1xucmVxdWlyZSgnLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9tb2R1bGVzL19jb3JlJyk7XG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IChuQnl0ZXMgKiA4KSAtIG1MZW4gLSAxXG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxXG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMVxuICB2YXIgbkJpdHMgPSAtN1xuICB2YXIgaSA9IGlzTEUgPyAobkJ5dGVzIC0gMSkgOiAwXG4gIHZhciBkID0gaXNMRSA/IC0xIDogMVxuICB2YXIgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXVxuXG4gIGkgKz0gZFxuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIHMgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IGVMZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IChlICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpXG4gIGUgPj49ICgtbkJpdHMpXG4gIG5CaXRzICs9IG1MZW5cbiAgZm9yICg7IG5CaXRzID4gMDsgbSA9IChtICogMjU2KSArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSAobkJ5dGVzICogOCkgLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKVxuICB2YXIgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpXG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMVxuICB2YXIgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMFxuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpXG5cbiAgaWYgKGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICBtID0gaXNOYU4odmFsdWUpID8gMSA6IDBcbiAgICBlID0gZU1heFxuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKVxuICAgIGlmICh2YWx1ZSAqIChjID0gTWF0aC5wb3coMiwgLWUpKSA8IDEpIHtcbiAgICAgIGUtLVxuICAgICAgYyAqPSAyXG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKVxuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrK1xuICAgICAgYyAvPSAyXG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMFxuICAgICAgZSA9IGVNYXhcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKCh2YWx1ZSAqIGMpIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IGUgKyBlQmlhc1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbilcbiAgICAgIGUgPSAwXG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gKGUgPDwgbUxlbikgfCBtXG4gIGVMZW4gKz0gbUxlblxuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpIHt9XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4XG59XG4iLCIvKipcbiAqIENvbnZlcnQgYXJyYXkgb2YgMTYgYnl0ZSB2YWx1ZXMgdG8gVVVJRCBzdHJpbmcgZm9ybWF0IG9mIHRoZSBmb3JtOlxuICogWFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYXG4gKi9cbnZhciBieXRlVG9IZXggPSBbXTtcbmZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyArK2kpIHtcbiAgYnl0ZVRvSGV4W2ldID0gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigxKTtcbn1cblxuZnVuY3Rpb24gYnl0ZXNUb1V1aWQoYnVmLCBvZmZzZXQpIHtcbiAgdmFyIGkgPSBvZmZzZXQgfHwgMDtcbiAgdmFyIGJ0aCA9IGJ5dGVUb0hleDtcbiAgLy8gam9pbiB1c2VkIHRvIGZpeCBtZW1vcnkgaXNzdWUgY2F1c2VkIGJ5IGNvbmNhdGVuYXRpb246IGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTMxNzUjYzRcbiAgcmV0dXJuIChbYnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXV0pLmpvaW4oJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJ5dGVzVG9VdWlkO1xuIiwiLy8gVW5pcXVlIElEIGNyZWF0aW9uIHJlcXVpcmVzIGEgaGlnaCBxdWFsaXR5IHJhbmRvbSAjIGdlbmVyYXRvci4gIEluIHRoZVxuLy8gYnJvd3NlciB0aGlzIGlzIGEgbGl0dGxlIGNvbXBsaWNhdGVkIGR1ZSB0byB1bmtub3duIHF1YWxpdHkgb2YgTWF0aC5yYW5kb20oKVxuLy8gYW5kIGluY29uc2lzdGVudCBzdXBwb3J0IGZvciB0aGUgYGNyeXB0b2AgQVBJLiAgV2UgZG8gdGhlIGJlc3Qgd2UgY2FuIHZpYVxuLy8gZmVhdHVyZS1kZXRlY3Rpb25cblxuLy8gZ2V0UmFuZG9tVmFsdWVzIG5lZWRzIHRvIGJlIGludm9rZWQgaW4gYSBjb250ZXh0IHdoZXJlIFwidGhpc1wiIGlzIGEgQ3J5cHRvXG4vLyBpbXBsZW1lbnRhdGlvbi4gQWxzbywgZmluZCB0aGUgY29tcGxldGUgaW1wbGVtZW50YXRpb24gb2YgY3J5cHRvIG9uIElFMTEuXG52YXIgZ2V0UmFuZG9tVmFsdWVzID0gKHR5cGVvZihjcnlwdG8pICE9ICd1bmRlZmluZWQnICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcy5iaW5kKGNyeXB0bykpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgKHR5cGVvZihtc0NyeXB0bykgIT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHdpbmRvdy5tc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMgPT0gJ2Z1bmN0aW9uJyAmJiBtc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChtc0NyeXB0bykpO1xuXG5pZiAoZ2V0UmFuZG9tVmFsdWVzKSB7XG4gIC8vIFdIQVRXRyBjcnlwdG8gUk5HIC0gaHR0cDovL3dpa2kud2hhdHdnLm9yZy93aWtpL0NyeXB0b1xuICB2YXIgcm5kczggPSBuZXcgVWludDhBcnJheSgxNik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHdoYXR3Z1JORygpIHtcbiAgICBnZXRSYW5kb21WYWx1ZXMocm5kczgpO1xuICAgIHJldHVybiBybmRzODtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIE1hdGgucmFuZG9tKCktYmFzZWQgKFJORylcbiAgLy9cbiAgLy8gSWYgYWxsIGVsc2UgZmFpbHMsIHVzZSBNYXRoLnJhbmRvbSgpLiAgSXQncyBmYXN0LCBidXQgaXMgb2YgdW5zcGVjaWZpZWRcbiAgLy8gcXVhbGl0eS5cbiAgdmFyIHJuZHMgPSBuZXcgQXJyYXkoMTYpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbWF0aFJORygpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgcjsgaSA8IDE2OyBpKyspIHtcbiAgICAgIGlmICgoaSAmIDB4MDMpID09PSAwKSByID0gTWF0aC5yYW5kb20oKSAqIDB4MTAwMDAwMDAwO1xuICAgICAgcm5kc1tpXSA9IHIgPj4+ICgoaSAmIDB4MDMpIDw8IDMpICYgMHhmZjtcbiAgICB9XG5cbiAgICByZXR1cm4gcm5kcztcbiAgfTtcbn1cbiIsInZhciBybmcgPSByZXF1aXJlKCcuL2xpYi9ybmcnKTtcbnZhciBieXRlc1RvVXVpZCA9IHJlcXVpcmUoJy4vbGliL2J5dGVzVG9VdWlkJyk7XG5cbmZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gIGlmICh0eXBlb2Yob3B0aW9ucykgPT0gJ3N0cmluZycpIHtcbiAgICBidWYgPSBvcHRpb25zID09PSAnYmluYXJ5JyA/IG5ldyBBcnJheSgxNikgOiBudWxsO1xuICAgIG9wdGlvbnMgPSBudWxsO1xuICB9XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IHJuZykoKTtcblxuICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgcm5kc1s4XSA9IChybmRzWzhdICYgMHgzZikgfCAweDgwO1xuXG4gIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICBpZiAoYnVmKSB7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IDE2OyArK2lpKSB7XG4gICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgfHwgYnl0ZXNUb1V1aWQocm5kcyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjQ7XG4iLCJ2YXIgZztcblxuLy8gVGhpcyB3b3JrcyBpbiBub24tc3RyaWN0IG1vZGVcbmcgPSAoZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzO1xufSkoKTtcblxudHJ5IHtcblx0Ly8gVGhpcyB3b3JrcyBpZiBldmFsIGlzIGFsbG93ZWQgKHNlZSBDU1ApXG5cdGcgPSBnIHx8IG5ldyBGdW5jdGlvbihcInJldHVybiB0aGlzXCIpKCk7XG59IGNhdGNoIChlKSB7XG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXG5cdGlmICh0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiKSBnID0gd2luZG93O1xufVxuXG4vLyBnIGNhbiBzdGlsbCBiZSB1bmRlZmluZWQsIGJ1dCBub3RoaW5nIHRvIGRvIGFib3V0IGl0Li4uXG4vLyBXZSByZXR1cm4gdW5kZWZpbmVkLCBpbnN0ZWFkIG9mIG5vdGhpbmcgaGVyZSwgc28gaXQnc1xuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGc7XG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFRpbWVyIH0gZnJvbSAnLi9UaW1lci5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIEFjY2Vzc1Rva2VuRXZlbnRzIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ1RpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyaW5nXCIpLFxyXG4gICAgICAgIGFjY2Vzc1Rva2VuRXhwaXJlZFRpbWVyID0gbmV3IFRpbWVyKFwiQWNjZXNzIHRva2VuIGV4cGlyZWRcIilcclxuICAgIH0gPSB7fSkge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcgPSBhY2Nlc3NUb2tlbkV4cGlyaW5nVGltZXI7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkID0gYWNjZXNzVG9rZW5FeHBpcmVkVGltZXI7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZChjb250YWluZXIpIHtcclxuICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV2ZW50cyBpZiB0aGVyZSdzIGFuIGFjY2VzcyB0b2tlbiBhbmQgaXQgaGFzIGFuIGV4cGlyYXRpb25cclxuICAgICAgICBpZiAoY29udGFpbmVyLmFjY2Vzc190b2tlbiAmJiBjb250YWluZXIuZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbiA9IGNvbnRhaW5lci5leHBpcmVzX2luO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiBhY2Nlc3MgdG9rZW4gcHJlc2VudCwgcmVtYWluaW5nIGR1cmF0aW9uOlwiLCBkdXJhdGlvbik7XHJcblxyXG4gICAgICAgICAgICBpZiAoZHVyYXRpb24gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBvbmx5IHJlZ2lzdGVyIGV4cGlyaW5nIGlmIHdlIHN0aWxsIGhhdmUgdGltZVxyXG4gICAgICAgICAgICAgICAgbGV0IGV4cGlyaW5nID0gZHVyYXRpb24gLSB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgICAgICAgICAgICAgIGlmIChleHBpcmluZyA8PSAwKXtcclxuICAgICAgICAgICAgICAgICAgICBleHBpcmluZyA9IDE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkFjY2Vzc1Rva2VuRXZlbnRzLmxvYWQ6IHJlZ2lzdGVyaW5nIGV4cGlyaW5nIHRpbWVyIGluOlwiLCBleHBpcmluZyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmluaXQoZXhwaXJpbmcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQWNjZXNzVG9rZW5FdmVudHMubG9hZDogY2FuY2VsaW5nIGV4aXN0aW5nIGV4cGlyaW5nIHRpbWVyIGJlY2FzZSB3ZSdyZSBwYXN0IGV4cGlyYXRpb24uXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmluZy5jYW5jZWwoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gaWYgaXQncyBuZWdhdGl2ZSwgaXQgd2lsbCBzdGlsbCBmaXJlXHJcbiAgICAgICAgICAgIGxldCBleHBpcmVkID0gZHVyYXRpb24gKyAxO1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy5sb2FkOiByZWdpc3RlcmluZyBleHBpcmVkIHRpbWVyIGluOlwiLCBleHBpcmVkKTtcclxuICAgICAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmluaXQoZXhwaXJlZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmNhbmNlbCgpO1xyXG4gICAgICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyZWQuY2FuY2VsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHVubG9hZCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJBY2Nlc3NUb2tlbkV2ZW50cy51bmxvYWQ6IGNhbmNlbGluZyBleGlzdGluZyBhY2Nlc3MgdG9rZW4gdGltZXJzXCIpO1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcuY2FuY2VsKCk7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmNhbmNlbCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZEFjY2Vzc1Rva2VuRXhwaXJpbmcoY2IpIHtcclxuICAgICAgICB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmluZyhjYikge1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmcucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlQWNjZXNzVG9rZW5FeHBpcmVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fYWNjZXNzVG9rZW5FeHBpcmVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRJbnRlcnZhbCA9IDIwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgQ2hlY2tTZXNzaW9uSUZyYW1lIHtcclxuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCBjbGllbnRfaWQsIHVybCwgaW50ZXJ2YWwsIHN0b3BPbkVycm9yID0gdHJ1ZSkge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX3VybCA9IHVybDtcclxuICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IGludGVydmFsIHx8IERlZmF1bHRJbnRlcnZhbDtcclxuICAgICAgICB0aGlzLl9zdG9wT25FcnJvciA9IHN0b3BPbkVycm9yO1xyXG5cclxuICAgICAgICB2YXIgaWR4ID0gdXJsLmluZGV4T2YoXCIvXCIsIHVybC5pbmRleE9mKFwiLy9cIikgKyAyKTtcclxuICAgICAgICB0aGlzLl9mcmFtZV9vcmlnaW4gPSB1cmwuc3Vic3RyKDAsIGlkeCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpZnJhbWVcIik7XHJcblxyXG4gICAgICAgIC8vIHNob3RndW4gYXBwcm9hY2hcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUud2lkdGggPSAwO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmhlaWdodCA9IDA7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnNyYyA9IHVybDtcclxuICAgIH1cclxuICAgIGxvYWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lLm9ubG9hZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfbWVzc2FnZShlKSB7XHJcbiAgICAgICAgaWYgKGUub3JpZ2luID09PSB0aGlzLl9mcmFtZV9vcmlnaW4gJiZcclxuICAgICAgICAgICAgZS5zb3VyY2UgPT09IHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3dcclxuICAgICAgICApIHtcclxuICAgICAgICAgICAgaWYgKGUuZGF0YSA9PT0gXCJlcnJvclwiKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJDaGVja1Nlc3Npb25JRnJhbWU6IGVycm9yIG1lc3NhZ2UgZnJvbSBjaGVjayBzZXNzaW9uIG9wIGlmcmFtZVwiKTtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdG9wT25FcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGUuZGF0YSA9PT0gXCJjaGFuZ2VkXCIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZTogY2hhbmdlZCBtZXNzYWdlIGZyb20gY2hlY2sgc2Vzc2lvbiBvcCBpZnJhbWVcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN0b3AoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJDaGVja1Nlc3Npb25JRnJhbWU6IFwiICsgZS5kYXRhICsgXCIgbWVzc2FnZSBmcm9tIGNoZWNrIHNlc3Npb24gb3AgaWZyYW1lXCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhcnQoc2Vzc2lvbl9zdGF0ZSkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXNzaW9uX3N0YXRlICE9PSBzZXNzaW9uX3N0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdGFydFwiKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcblxyXG4gICAgICAgICAgICBsZXQgc2VuZCA9ICgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2ZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UodGhpcy5fY2xpZW50X2lkICsgXCIgXCIgKyB0aGlzLl9zZXNzaW9uX3N0YXRlLCB0aGlzLl9mcmFtZV9vcmlnaW4pO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gdHJpZ2dlciBub3dcclxuICAgICAgICAgICAgc2VuZCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gYW5kIHNldHVwIHRpbWVyXHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldEludGVydmFsKHNlbmQsIHRoaXMuX2ludGVydmFsKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgc3RvcCgpIHtcclxuICAgICAgICB0aGlzLl9zZXNzaW9uX3N0YXRlID0gbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkNoZWNrU2Vzc2lvbklGcmFtZS5zdG9wXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IENvcmRvdmFQb3B1cFdpbmRvdyB9IGZyb20gJy4vQ29yZG92YVBvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDb3Jkb3ZhSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzID0gJ2hpZGRlbj15ZXMnO1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBDb3Jkb3ZhUG9wdXBXaW5kb3cgfSBmcm9tICcuL0NvcmRvdmFQb3B1cFdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgQ29yZG92YVBvcHVwTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBwb3B1cCA9IG5ldyBDb3Jkb3ZhUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHpvb209bm8nO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIENvcmRvdmFQb3B1cFdpbmRvdyB7XHJcblxyXG4gICAgY29uc3RydWN0b3IocGFyYW1zKSB7XHJcbiAgICAgICAgdGhpcy5fcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgdGhpcy5fcmVzb2x2ZSA9IHJlc29sdmU7XHJcbiAgICAgICAgICAgIHRoaXMuX3JlamVjdCA9IHJlamVjdDtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5mZWF0dXJlcyA9IHBhcmFtcy5wb3B1cFdpbmRvd0ZlYXR1cmVzIHx8IERlZmF1bHRQb3B1cEZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnJlZGlyZWN0X3VyaSA9IHBhcmFtcy5zdGFydFVybDtcclxuICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3cuY3RvcjogcmVkaXJlY3RfdXJpOiBcIiArIHRoaXMucmVkaXJlY3RfdXJpKTtcclxuICAgIH1cclxuXHJcbiAgICBfaXNJbkFwcEJyb3dzZXJJbnN0YWxsZWQoY29yZG92YU1ldGFkYXRhKSB7XHJcbiAgICAgICAgcmV0dXJuIFtcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3NlclwiLCBcImNvcmRvdmEtcGx1Z2luLWluYXBwYnJvd3Nlci5pbmFwcGJyb3dzZXJcIiwgXCJvcmcuYXBhY2hlLmNvcmRvdmEuaW5hcHBicm93c2VyXCJdLnNvbWUoZnVuY3Rpb24gKG5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGNvcmRvdmFNZXRhZGF0YS5oYXNPd25Qcm9wZXJ0eShuYW1lKVxyXG4gICAgICAgIH0pXHJcbiAgICB9XHJcbiAgICBcclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICghd2luZG93LmNvcmRvdmEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9lcnJvcihcImNvcmRvdmEgaXMgdW5kZWZpbmVkXCIpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIHZhciBjb3Jkb3ZhTWV0YWRhdGEgPSB3aW5kb3cuY29yZG92YS5yZXF1aXJlKFwiY29yZG92YS9wbHVnaW5fbGlzdFwiKS5tZXRhZGF0YTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzSW5BcHBCcm93c2VySW5zdGFsbGVkKGNvcmRvdmFNZXRhZGF0YSkgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3IoXCJJbkFwcEJyb3dzZXIgcGx1Z2luIG5vdCBmb3VuZFwiKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwID0gY29yZG92YS5JbkFwcEJyb3dzZXIub3BlbihwYXJhbXMudXJsLCB0aGlzLnRhcmdldCwgdGhpcy5mZWF0dXJlcyk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9wb3B1cCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiQ29yZG92YVBvcHVwV2luZG93Lm5hdmlnYXRlOiBwb3B1cCBzdWNjZXNzZnVsbHkgY3JlYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQgPSB0aGlzLl9leGl0Q2FsbGJhY2suYmluZCh0aGlzKTsgXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9sb2FkU3RhcnRDYWxsYmFja0V2ZW50ID0gdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2suYmluZCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fcG9wdXAuYWRkRXZlbnRMaXN0ZW5lcihcImV4aXRcIiwgdGhpcy5fZXhpdENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3BvcHVwLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2Fkc3RhcnRcIiwgdGhpcy5fbG9hZFN0YXJ0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJFcnJvciBvcGVuaW5nIHBvcHVwIHdpbmRvd1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwcm9taXNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkU3RhcnRDYWxsYmFjayhldmVudCkge1xyXG4gICAgICAgIGlmIChldmVudC51cmwuaW5kZXhPZih0aGlzLnJlZGlyZWN0X3VyaSkgPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5fc3VjY2Vzcyh7IHVybDogZXZlbnQudXJsIH0pO1xyXG4gICAgICAgIH0gICAgXHJcbiAgICB9XHJcbiAgICBfZXhpdENhbGxiYWNrKG1lc3NhZ2UpIHtcclxuICAgICAgICB0aGlzLl9lcnJvcihtZXNzYWdlKTsgICAgXHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICB0aGlzLl9jbGVhbnVwKCk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIkNvcmRvdmFQb3B1cFdpbmRvdzogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIGNvcmRvdmEgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fcG9wdXApe1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJDb3Jkb3ZhUG9wdXBXaW5kb3c6IGNsZWFuaW5nIHVwIHBvcHVwXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXhpdFwiLCB0aGlzLl9leGl0Q2FsbGJhY2tFdmVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKFwibG9hZHN0YXJ0XCIsIHRoaXMuX2xvYWRTdGFydENhbGxiYWNrRXZlbnQsIGZhbHNlKTtcclxuICAgICAgICAgICAgdGhpcy5fcG9wdXAuY2xvc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSBudWxsO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBFcnJvclJlc3BvbnNlIGV4dGVuZHMgRXJyb3Ige1xyXG4gICAgY29uc3RydWN0b3Ioe2Vycm9yLCBlcnJvcl9kZXNjcmlwdGlvbiwgZXJyb3JfdXJpLCBzdGF0ZSwgc2Vzc2lvbl9zdGF0ZX09e31cclxuICAgICkge1xyXG4gICAgICAgICBpZiAoIWVycm9yKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiTm8gZXJyb3IgcGFzc2VkIHRvIEVycm9yUmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImVycm9yXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgc3VwZXIoZXJyb3JfZGVzY3JpcHRpb24gfHwgZXJyb3IpO1xyXG5cclxuICAgICAgICB0aGlzLm5hbWUgPSBcIkVycm9yUmVzcG9uc2VcIjtcclxuXHJcbiAgICAgICAgdGhpcy5lcnJvciA9IGVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSBlcnJvcl9kZXNjcmlwdGlvbjtcclxuICAgICAgICB0aGlzLmVycm9yX3VyaSA9IGVycm9yX3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEV2ZW50IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lKSB7XHJcbiAgICAgICAgdGhpcy5fbmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgYWRkSGFuZGxlcihjYikge1xyXG4gICAgICAgIHRoaXMuX2NhbGxiYWNrcy5wdXNoKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVIYW5kbGVyKGNiKSB7XHJcbiAgICAgICAgdmFyIGlkeCA9IHRoaXMuX2NhbGxiYWNrcy5maW5kSW5kZXgoaXRlbSA9PiBpdGVtID09PSBjYik7XHJcbiAgICAgICAgaWYgKGlkeCA+PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmFpc2UoLi4ucGFyYW1zKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiRXZlbnQ6IFJhaXNpbmcgZXZlbnQ6IFwiICsgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9jYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzW2ldKC4uLnBhcmFtcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmNvbnN0IHRpbWVyID0ge1xyXG4gICAgc2V0SW50ZXJ2YWw6IGZ1bmN0aW9uIChjYiwgZHVyYXRpb24pIHtcclxuICAgICAgICByZXR1cm4gc2V0SW50ZXJ2YWwoY2IsIGR1cmF0aW9uKTtcclxuICAgIH0sXHJcbiAgICBjbGVhckludGVydmFsOiBmdW5jdGlvbiAoaGFuZGxlKSB7XHJcbiAgICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwoaGFuZGxlKTtcclxuICAgIH1cclxufTtcclxuXHJcbmxldCB0ZXN0aW5nID0gZmFsc2U7XHJcbmxldCByZXF1ZXN0ID0gbnVsbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBHbG9iYWwge1xyXG5cclxuICAgIHN0YXRpYyBfdGVzdGluZygpIHtcclxuICAgICAgICB0ZXN0aW5nID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IGxvY2F0aW9uKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYXRpb247XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgbG9jYWxTdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gbG9jYWxTdG9yYWdlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZ2V0IHNlc3Npb25TdG9yYWdlKCkge1xyXG4gICAgICAgIGlmICghdGVzdGluZyAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICByZXR1cm4gc2Vzc2lvblN0b3JhZ2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBzZXRYTUxIdHRwUmVxdWVzdChuZXdSZXF1ZXN0KSB7XHJcbiAgICAgICAgcmVxdWVzdCA9IG5ld1JlcXVlc3Q7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGdldCBYTUxIdHRwUmVxdWVzdCgpIHtcclxuICAgICAgICBpZiAoIXRlc3RpbmcgJiYgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QgfHwgWE1MSHR0cFJlcXVlc3Q7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBnZXQgdGltZXIoKSB7XHJcbiAgICAgICAgaWYgKCF0ZXN0aW5nKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aW1lcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVXaW5kb3cgfSBmcm9tICcuL0lGcmFtZVdpbmRvdy5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lTmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKHBhcmFtcykge1xyXG4gICAgICAgIGxldCBmcmFtZSA9IG5ldyBJRnJhbWVXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZyYW1lKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVOYXZpZ2F0b3IuY2FsbGJhY2tcIik7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIElGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQodXJsKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmNvbnN0IERlZmF1bHRUaW1lb3V0ID0gMTAwMDA7XHJcblxyXG5leHBvcnQgY2xhc3MgSUZyYW1lV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLl9ib3VuZE1lc3NhZ2VFdmVudCA9IHRoaXMuX21lc3NhZ2UuYmluZCh0aGlzKTtcclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQsIGZhbHNlKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZnJhbWUgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlmcmFtZVwiKTtcclxuXHJcbiAgICAgICAgLy8gc2hvdGd1biBhcHByb2FjaFxyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnZpc2liaWxpdHkgPSBcImhpZGRlblwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLnBvc2l0aW9uID0gXCJhYnNvbHV0ZVwiO1xyXG4gICAgICAgIHRoaXMuX2ZyYW1lLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcclxuICAgICAgICB0aGlzLl9mcmFtZS5zdHlsZS53aWR0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5fZnJhbWUuc3R5bGUuaGVpZ2h0ID0gMDtcclxuXHJcbiAgICAgICAgd2luZG93LmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy5fZnJhbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIG5hdmlnYXRlKHBhcmFtcykge1xyXG4gICAgICAgIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiTm8gdXJsIHByb3ZpZGVkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IHRpbWVvdXQgPSBwYXJhbXMuc2lsZW50UmVxdWVzdFRpbWVvdXQgfHwgRGVmYXVsdFRpbWVvdXQ7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5uYXZpZ2F0ZTogVXNpbmcgdGltZW91dCBvZjpcIiwgdGltZW91dCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyID0gd2luZG93LnNldFRpbWVvdXQodGhpcy5fdGltZW91dC5iaW5kKHRoaXMpLCB0aW1lb3V0KTtcclxuICAgICAgICAgICAgdGhpcy5fZnJhbWUuc3JjID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnByb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHByb21pc2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb21pc2U7XHJcbiAgICB9XHJcblxyXG4gICAgX3N1Y2Nlc3MoZGF0YSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBTdWNjZXNzZnVsIHJlc3BvbnNlIGZyb20gZnJhbWUgd2luZG93XCIpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuXHJcbiAgICAgICAgTG9nLmVycm9yKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBfY2xlYW51cCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fZnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93OiBjbGVhbnVwXCIpO1xyXG5cclxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIHRoaXMuX2JvdW5kTWVzc2FnZUV2ZW50LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xyXG4gICAgICAgICAgICB3aW5kb3cuZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZCh0aGlzLl9mcmFtZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl90aW1lciA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1lID0gbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5fYm91bmRNZXNzYWdlRXZlbnQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdGltZW91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJJRnJhbWVXaW5kb3cudGltZW91dFwiKTtcclxuICAgICAgICB0aGlzLl9lcnJvcihcIkZyYW1lIHdpbmRvdyB0aW1lZCBvdXRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgX21lc3NhZ2UoZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5tZXNzYWdlXCIpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fdGltZXIgJiZcclxuICAgICAgICAgICAgZS5vcmlnaW4gPT09IHRoaXMuX29yaWdpbiAmJlxyXG4gICAgICAgICAgICBlLnNvdXJjZSA9PT0gdGhpcy5fZnJhbWUuY29udGVudFdpbmRvd1xyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgICBsZXQgdXJsID0gZS5kYXRhO1xyXG4gICAgICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWNjZXNzKHsgdXJsOiB1cmwgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9lcnJvcihcIkludmFsaWQgcmVzcG9uc2UgZnJvbSBmcmFtZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX29yaWdpbigpIHtcclxuICAgICAgICByZXR1cm4gbG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyBsb2NhdGlvbi5ob3N0O1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBub3RpZnlQYXJlbnQodXJsKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSUZyYW1lV2luZG93Lm5vdGlmeVBhcmVudFwiKTtcclxuICAgICAgICBpZiAod2luZG93LmZyYW1lRWxlbWVudCkge1xyXG4gICAgICAgICAgICB1cmwgPSB1cmwgfHwgd2luZG93LmxvY2F0aW9uLmhyZWY7XHJcbiAgICAgICAgICAgIGlmICh1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIklGcmFtZVdpbmRvdy5ub3RpZnlQYXJlbnQ6IHBvc3RpbmcgdXJsIG1lc3NhZ2UgdG8gcGFyZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZSh1cmwsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICsgbG9jYXRpb24uaG9zdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIEluTWVtb3J5V2ViU3RvcmFnZXtcclxuICAgIGNvbnN0cnVjdG9yKCl7XHJcbiAgICAgICAgdGhpcy5fZGF0YSA9IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIGdldEl0ZW0oa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLmdldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIHNldEl0ZW0oa2V5LCB2YWx1ZSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnNldEl0ZW1cIiwga2V5KTtcclxuICAgICAgICB0aGlzLl9kYXRhW2tleV0gPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVJdGVtKGtleSl7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSW5NZW1vcnlXZWJTdG9yYWdlLnJlbW92ZUl0ZW1cIiwga2V5KTtcclxuICAgICAgICBkZWxldGUgdGhpcy5fZGF0YVtrZXldO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBsZW5ndGgoKSB7XHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMuX2RhdGEpLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgICBrZXkoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGhpcy5fZGF0YSlbaW5kZXhdO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IGp3cywgS2V5VXRpbCwgWDUwOSwgY3J5cHRvLCBoZXh0b2I2NHUsIGI2NHRvaGV4LCBBbGxvd2VkU2lnbmluZ0FsZ3MgfSBmcm9tICcuL2NyeXB0by9qc3JzYXNpZ24nO1xyXG5pbXBvcnQgZ2V0Sm9zZVV0aWwgZnJvbSAnLi9Kb3NlVXRpbEltcGwnO1xyXG5cclxuZXhwb3J0IGNvbnN0IEpvc2VVdGlsID0gZ2V0Sm9zZVV0aWwoeyBqd3MsIEtleVV0aWwsIFg1MDksIGNyeXB0bywgaGV4dG9iNjR1LCBiNjR0b2hleCwgQWxsb3dlZFNpZ25pbmdBbGdzIH0pO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRKb3NlVXRpbCh7IGp3cywgS2V5VXRpbCwgWDUwOSwgY3J5cHRvLCBoZXh0b2I2NHUsIGI2NHRvaGV4LCBBbGxvd2VkU2lnbmluZ0FsZ3MgfSkge1xyXG4gICAgcmV0dXJuIGNsYXNzIEpvc2VVdGlsIHtcclxuXHJcbiAgICAgICAgc3RhdGljIHBhcnNlSnd0KGp3dCkge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJKb3NlVXRpbC5wYXJzZUp3dFwiKTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHZhciB0b2tlbiA9IGp3cy5KV1MucGFyc2Uoand0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyOiB0b2tlbi5oZWFkZXJPYmosXHJcbiAgICAgICAgICAgICAgICAgICAgcGF5bG9hZDogdG9rZW4ucGF5bG9hZE9ialxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyB2YWxpZGF0ZUp3dChqd3QsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3LCBub3csIHRpbWVJbnNlbnNpdGl2ZSkge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dFwiKTtcclxuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoa2V5Lmt0eSA9PT0gXCJSU0FcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXkuZSAmJiBrZXkubikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBLZXlVdGlsLmdldEtleShrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5Lng1YyAmJiBrZXkueDVjLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGV4ID0gYjY0dG9oZXgoa2V5Lng1Y1swXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IFg1MDkuZ2V0UHVibGljS2V5RnJvbUNlcnRIZXgoaGV4KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dDogUlNBIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiUlNBIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkua3R5ID09PSBcIkVDXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LmNydiAmJiBrZXkueCAmJiBrZXkueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBLZXlVdGlsLmdldEtleShrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLnZhbGlkYXRlSnd0OiBFQyBrZXkgbWlzc2luZyBrZXkgbWF0ZXJpYWxcIiwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkVDIGtleSBtaXNzaW5nIGtleSBtYXRlcmlhbFwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC52YWxpZGF0ZUp3dDogVW5zdXBwb3J0ZWQga2V5IHR5cGVcIiwga2V5ICYmIGtleS5rdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBrZXkgdHlwZTogXCIgKyBrZXkgJiYga2V5Lmt0eSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBKb3NlVXRpbC5fdmFsaWRhdGVKd3Qoand0LCBrZXksIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSAmJiBlLm1lc3NhZ2UgfHwgZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJKV1QgdmFsaWRhdGlvbiBmYWlsZWRcIik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyB2YWxpZGF0ZUp3dEF0dHJpYnV0ZXMoand0LCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXcsIG5vdywgdGltZUluc2Vuc2l0aXZlKSB7XHJcbiAgICAgICAgICAgIGlmICghY2xvY2tTa2V3KSB7XHJcbiAgICAgICAgICAgICAgICBjbG9ja1NrZXcgPSAwO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIW5vdykge1xyXG4gICAgICAgICAgICAgICAgbm93ID0gcGFyc2VJbnQoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIgcGF5bG9hZCA9IEpvc2VVdGlsLnBhcnNlSnd0KGp3dCkucGF5bG9hZDtcclxuXHJcbiAgICAgICAgICAgIGlmICghcGF5bG9hZC5pc3MpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogaXNzdWVyIHdhcyBub3QgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaXNzdWVyIHdhcyBub3QgcHJvdmlkZWRcIikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwYXlsb2FkLmlzcyAhPT0gaXNzdWVyKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IEludmFsaWQgaXNzdWVyIGluIHRva2VuXCIsIHBheWxvYWQuaXNzKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIGlzc3VlciBpbiB0b2tlbjogXCIgKyBwYXlsb2FkLmlzcykpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoIXBheWxvYWQuYXVkKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGF1ZCB3YXMgbm90IHByb3ZpZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImF1ZCB3YXMgbm90IHByb3ZpZGVkXCIpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgdmFsaWRBdWRpZW5jZSA9IHBheWxvYWQuYXVkID09PSBhdWRpZW5jZSB8fCAoQXJyYXkuaXNBcnJheShwYXlsb2FkLmF1ZCkgJiYgcGF5bG9hZC5hdWQuaW5kZXhPZihhdWRpZW5jZSkgPj0gMCk7XHJcbiAgICAgICAgICAgIGlmICghdmFsaWRBdWRpZW5jZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBJbnZhbGlkIGF1ZGllbmNlIGluIHRva2VuXCIsIHBheWxvYWQuYXVkKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJJbnZhbGlkIGF1ZGllbmNlIGluIHRva2VuOiBcIiArIHBheWxvYWQuYXVkKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHBheWxvYWQuYXpwICYmIHBheWxvYWQuYXpwICE9PSBhdWRpZW5jZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBJbnZhbGlkIGF6cCBpbiB0b2tlblwiLCBwYXlsb2FkLmF6cCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiSW52YWxpZCBhenAgaW4gdG9rZW46IFwiICsgcGF5bG9hZC5henApKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aW1lSW5zZW5zaXRpdmUpIHtcclxuICAgICAgICAgICAgICAgIHZhciBsb3dlck5vdyA9IG5vdyArIGNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgIHZhciB1cHBlck5vdyA9IG5vdyAtIGNsb2NrU2tldztcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXBheWxvYWQuaWF0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSm9zZVV0aWwuX3ZhbGlkYXRlSnd0OiBpYXQgd2FzIG5vdCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaWF0IHdhcyBub3QgcHJvdmlkZWRcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGxvd2VyTm93IDwgcGF5bG9hZC5pYXQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGlhdCBpcyBpbiB0aGUgZnV0dXJlXCIsIHBheWxvYWQuaWF0KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiaWF0IGlzIGluIHRoZSBmdXR1cmU6IFwiICsgcGF5bG9hZC5pYXQpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5uYmYgJiYgbG93ZXJOb3cgPCBwYXlsb2FkLm5iZikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogbmJmIGlzIGluIHRoZSBmdXR1cmVcIiwgcGF5bG9hZC5uYmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJuYmYgaXMgaW4gdGhlIGZ1dHVyZTogXCIgKyBwYXlsb2FkLm5iZikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5leHApIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKb3NlVXRpbC5fdmFsaWRhdGVKd3Q6IGV4cCB3YXMgbm90IHByb3ZpZGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJleHAgd2FzIG5vdCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5leHAgPCB1cHBlck5vdykge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogZXhwIGlzIGluIHRoZSBwYXN0XCIsIHBheWxvYWQuZXhwKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiZXhwIGlzIGluIHRoZSBwYXN0OlwiICsgcGF5bG9hZC5leHApKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwYXlsb2FkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRpYyBfdmFsaWRhdGVKd3Qoand0LCBrZXksIGlzc3VlciwgYXVkaWVuY2UsIGNsb2NrU2tldywgbm93LCB0aW1lSW5zZW5zaXRpdmUpIHtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBKb3NlVXRpbC52YWxpZGF0ZUp3dEF0dHJpYnV0ZXMoand0LCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXcsIG5vdywgdGltZUluc2Vuc2l0aXZlKS50aGVuKHBheWxvYWQgPT4ge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWp3cy5KV1MudmVyaWZ5KGp3dCwga2V5LCBBbGxvd2VkU2lnbmluZ0FsZ3MpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpvc2VVdGlsLl92YWxpZGF0ZUp3dDogc2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXlsb2FkO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihlICYmIGUubWVzc2FnZSB8fCBlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic2lnbmF0dXJlIHZhbGlkYXRpb24gZmFpbGVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGF0aWMgaGFzaFN0cmluZyh2YWx1ZSwgYWxnKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY3J5cHRvLlV0aWwuaGFzaFN0cmluZyh2YWx1ZSwgYWxnKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdGF0aWMgaGV4VG9CYXNlNjRVcmwodmFsdWUpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBoZXh0b2I2NHUodmFsdWUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgSnNvblNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgYWRkaXRpb25hbENvbnRlbnRUeXBlcyA9IG51bGwsIFxyXG4gICAgICAgIFhNTEh0dHBSZXF1ZXN0Q3RvciA9IEdsb2JhbC5YTUxIdHRwUmVxdWVzdCwgXHJcbiAgICAgICAgand0SGFuZGxlciA9IG51bGxcclxuICAgICkge1xyXG4gICAgICAgIGlmIChhZGRpdGlvbmFsQ29udGVudFR5cGVzICYmIEFycmF5LmlzQXJyYXkoYWRkaXRpb25hbENvbnRlbnRUeXBlcykpXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMgPSBhZGRpdGlvbmFsQ29udGVudFR5cGVzLnNsaWNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2VcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcyA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9jb250ZW50VHlwZXMucHVzaCgnYXBwbGljYXRpb24vanNvbicpO1xyXG4gICAgICAgIGlmIChqd3RIYW5kbGVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlcy5wdXNoKCdhcHBsaWNhdGlvbi9qd3QnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX1hNTEh0dHBSZXF1ZXN0ID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX2p3dEhhbmRsZXIgPSBqd3RIYW5kbGVyO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEpzb24odXJsLCB0b2tlbikge1xyXG4gICAgICAgIGlmICghdXJsKXtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbiwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ0dFVCcsIHVybCk7XHJcblxyXG4gICAgICAgICAgICB2YXIgYWxsb3dlZENvbnRlbnRUeXBlcyA9IHRoaXMuX2NvbnRlbnRUeXBlcztcclxuICAgICAgICAgICAgdmFyIGp3dEhhbmRsZXIgPSB0aGlzLl9qd3RIYW5kbGVyO1xyXG5cclxuICAgICAgICAgICAgcmVxLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kID09IFwiYXBwbGljYXRpb24vand0XCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGp3dEhhbmRsZXIocmVxKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKEpTT04ucGFyc2UocmVxLnJlc3BvbnNlVGV4dCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UuZ2V0SnNvbjogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IocmVxLnN0YXR1c1RleHQgKyBcIiAoXCIgKyByZXEuc3RhdHVzICsgXCIpXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHJlcS5vbmVycm9yID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5nZXRKc29uOiBuZXR3b3JrIGVycm9yXCIpO1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiTmV0d29yayBFcnJvclwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBpZiAodG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIkpzb25TZXJ2aWNlLmdldEpzb246IHRva2VuIHBhc3NlZCwgc2V0dGluZyBBdXRob3JpemF0aW9uIGhlYWRlclwiKTtcclxuICAgICAgICAgICAgICAgIHJlcS5zZXRSZXF1ZXN0SGVhZGVyKFwiQXV0aG9yaXphdGlvblwiLCBcIkJlYXJlciBcIiArIHRva2VuKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNlbmQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwb3N0Rm9ybSh1cmwsIHBheWxvYWQpIHtcclxuICAgICAgICBpZiAoIXVybCl7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybSwgdXJsOiBcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuXHJcbiAgICAgICAgICAgIHZhciByZXEgPSBuZXcgdGhpcy5fWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgcmVxLm9wZW4oJ1BPU1QnLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgdmFyIGFsbG93ZWRDb250ZW50VHlwZXMgPSB0aGlzLl9jb250ZW50VHlwZXM7XHJcblxyXG4gICAgICAgICAgICByZXEub25sb2FkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogSFRUUCByZXNwb25zZSByZWNlaXZlZCwgc3RhdHVzXCIsIHJlcS5zdGF0dXMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSAyMDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJKc29uU2VydmljZS5wb3N0Rm9ybTogRXJyb3IgcGFyc2luZyBKU09OIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKFwiSW52YWxpZCByZXNwb25zZSBDb250ZW50LVR5cGU6IFwiICsgY29udGVudFR5cGUgKyBcIiwgZnJvbSBVUkw6IFwiICsgdXJsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChyZXEuc3RhdHVzID09PSA0MDApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gcmVxLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1UeXBlXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZvdW5kID0gYWxsb3dlZENvbnRlbnRUeXBlcy5maW5kKGl0ZW09PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50VHlwZS5zdGFydHNXaXRoKGl0ZW0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYXlsb2FkID0gSlNPTi5wYXJzZShyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF5bG9hZCAmJiBwYXlsb2FkLmVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIkpzb25TZXJ2aWNlLnBvc3RGb3JtOiBFcnJvciBmcm9tIHNlcnZlcjogXCIsIHBheWxvYWQuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKHBheWxvYWQuZXJyb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IEVycm9yIHBhcnNpbmcgSlNPTiByZXNwb25zZVwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlcS5zdGF0dXNUZXh0ICsgXCIgKFwiICsgcmVxLnN0YXR1cyArIFwiKVwiKSk7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXEub25lcnJvciA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiSnNvblNlcnZpY2UucG9zdEZvcm06IG5ldHdvcmsgZXJyb3JcIik7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IoXCJOZXR3b3JrIEVycm9yXCIpKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGxldCBib2R5ID0gXCJcIjtcclxuICAgICAgICAgICAgZm9yKGxldCBrZXkgaW4gcGF5bG9hZCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHBheWxvYWRba2V5XTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJvZHkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiJlwiO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYm9keSArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KTtcclxuICAgICAgICAgICAgICAgICAgICBib2R5ICs9IFwiPVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmVxLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIik7XHJcbiAgICAgICAgICAgIHJlcS5zZW5kKGJvZHkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmxldCBub3BMb2dnZXIgPSB7XHJcbiAgICBkZWJ1Zygpe30sXHJcbiAgICBpbmZvKCl7fSxcclxuICAgIHdhcm4oKXt9LFxyXG4gICAgZXJyb3IoKXt9XHJcbn07XHJcblxyXG5jb25zdCBOT05FID0gMDtcclxuY29uc3QgRVJST1IgPSAxO1xyXG5jb25zdCBXQVJOID0gMjtcclxuY29uc3QgSU5GTyA9IDM7XHJcbmNvbnN0IERFQlVHID0gNDtcclxuXHJcbmxldCBsb2dnZXI7XHJcbmxldCBsZXZlbDtcclxuXHJcbmV4cG9ydCBjbGFzcyBMb2cge1xyXG4gICAgc3RhdGljIGdldCBOT05FKCkge3JldHVybiBOT05FfTtcclxuICAgIHN0YXRpYyBnZXQgRVJST1IoKSB7cmV0dXJuIEVSUk9SfTtcclxuICAgIHN0YXRpYyBnZXQgV0FSTigpIHtyZXR1cm4gV0FSTn07XHJcbiAgICBzdGF0aWMgZ2V0IElORk8oKSB7cmV0dXJuIElORk99O1xyXG4gICAgc3RhdGljIGdldCBERUJVRygpIHtyZXR1cm4gREVCVUd9O1xyXG4gICAgXHJcbiAgICBzdGF0aWMgcmVzZXQoKXtcclxuICAgICAgICBsZXZlbCA9IElORk87XHJcbiAgICAgICAgbG9nZ2VyID0gbm9wTG9nZ2VyO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxldmVsKCl7XHJcbiAgICAgICAgcmV0dXJuIGxldmVsO1xyXG4gICAgfVxyXG4gICAgc3RhdGljIHNldCBsZXZlbCh2YWx1ZSl7XHJcbiAgICAgICAgaWYgKE5PTkUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gREVCVUcpe1xyXG4gICAgICAgICAgICBsZXZlbCA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBsb2cgbGV2ZWxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICBzdGF0aWMgZ2V0IGxvZ2dlcigpe1xyXG4gICAgICAgIHJldHVybiBsb2dnZXI7XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgc2V0IGxvZ2dlcih2YWx1ZSl7XHJcbiAgICAgICAgaWYgKCF2YWx1ZS5kZWJ1ZyAmJiB2YWx1ZS5pbmZvKSB7XHJcbiAgICAgICAgICAgIC8vIGp1c3QgdG8gc3RheSBiYWNrd2FyZHMgY29tcGF0LiBjYW4gcmVtb3ZlIGluIDIuMFxyXG4gICAgICAgICAgICB2YWx1ZS5kZWJ1ZyA9IHZhbHVlLmluZm87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmFsdWUuZGVidWcgJiYgdmFsdWUuaW5mbyAmJiB2YWx1ZS53YXJuICYmIHZhbHVlLmVycm9yKXtcclxuICAgICAgICAgICAgbG9nZ2VyID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGxvZ2dlclwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHN0YXRpYyBkZWJ1ZyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gREVCVUcpe1xyXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBzdGF0aWMgaW5mbyguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gSU5GTyl7XHJcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvLmFwcGx5KGxvZ2dlciwgQXJyYXkuZnJvbShhcmdzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgc3RhdGljIHdhcm4oLi4uYXJncyl7XHJcbiAgICAgICAgaWYgKGxldmVsID49IFdBUk4pe1xyXG4gICAgICAgICAgICBsb2dnZXIud2Fybi5hcHBseShsb2dnZXIsIEFycmF5LmZyb20oYXJncykpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHN0YXRpYyBlcnJvciguLi5hcmdzKXtcclxuICAgICAgICBpZiAobGV2ZWwgPj0gRVJST1Ipe1xyXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IuYXBwbHkobG9nZ2VyLCBBcnJheS5mcm9tKGFyZ3MpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbkxvZy5yZXNldCgpO1xyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmV4cG9ydCBjbGFzcyBNZXRhZGF0YVNlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MsIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2U6IE5vIHNldHRpbmdzIHBhc3NlZCB0byBNZXRhZGF0YVNlcnZpY2VcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IoWydhcHBsaWNhdGlvbi9qd2stc2V0K2pzb24nXSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1ldGFkYXRhVXJsKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5fbWV0YWRhdGFVcmwpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhVXJsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgPSB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsICYmIHRoaXMuX21ldGFkYXRhVXJsLmluZGV4T2YoT2lkY01ldGFkYXRhVXJsUGF0aCkgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX21ldGFkYXRhVXJsW3RoaXMuX21ldGFkYXRhVXJsLmxlbmd0aCAtIDFdICE9PSAnLycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCArPSBPaWRjTWV0YWRhdGFVcmxQYXRoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFVcmw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0TWV0YWRhdGEoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3NldHRpbmdzLm1ldGFkYXRhKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogUmV0dXJuaW5nIG1ldGFkYXRhIGZyb20gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5fc2V0dGluZ3MubWV0YWRhdGEpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YTogTm8gYXV0aG9yaXR5IG9yIG1ldGFkYXRhVXJsIGNvbmZpZ3VyZWQgb24gc2V0dGluZ3NcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb3IgbWV0YWRhdGFVcmwgY29uZmlndXJlZCBvbiBzZXR0aW5nc1wiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGE6IGdldHRpbmcgbWV0YWRhdGEgZnJvbVwiLCB0aGlzLm1ldGFkYXRhVXJsKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24odGhpcy5tZXRhZGF0YVVybClcclxuICAgICAgICAgICAgLnRoZW4obWV0YWRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiTWV0YWRhdGFTZXJ2aWNlLmdldE1ldGFkYXRhOiBqc29uIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MubWV0YWRhdGEgPSBtZXRhZGF0YTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0SXNzdWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiaXNzdWVyXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEF1dGhvcml6YXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImF1dGhvcml6YXRpb25fZW5kcG9pbnRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlckluZm9FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInVzZXJpbmZvX2VuZHBvaW50XCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFRva2VuRW5kcG9pbnQob3B0aW9uYWw9dHJ1ZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwidG9rZW5fZW5kcG9pbnRcIiwgb3B0aW9uYWwpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENoZWNrU2Vzc2lvbklmcmFtZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImNoZWNrX3Nlc3Npb25faWZyYW1lXCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldEVuZFNlc3Npb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcImVuZF9zZXNzaW9uX2VuZHBvaW50XCIsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFJldm9jYXRpb25FbmRwb2ludCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0TWV0YWRhdGFQcm9wZXJ0eShcInJldm9jYXRpb25fZW5kcG9pbnRcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0S2V5c0VuZHBvaW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX2dldE1ldGFkYXRhUHJvcGVydHkobmFtZSwgb3B0aW9uYWw9ZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eSBmb3I6IFwiICsgbmFtZSk7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1ldGFkYXRhKCkudGhlbihtZXRhZGF0YSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRNZXRhZGF0YVByb3BlcnR5OiBtZXRhZGF0YSByZWNpZXZlZFwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChtZXRhZGF0YVtuYW1lXSA9PT0gdW5kZWZpbmVkKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbmFsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBvcHRpb25hbCBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0TWV0YWRhdGFQcm9wZXJ0eTogTWV0YWRhdGEgZG9lcyBub3QgY29udGFpbiBwcm9wZXJ0eSBcIiArIG5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1ldGFkYXRhIGRvZXMgbm90IGNvbnRhaW4gcHJvcGVydHkgXCIgKyBuYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhW25hbWVdO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IFJldHVybmluZyBzaWduaW5nS2V5cyBmcm9tIHNldHRpbmdzXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRNZXRhZGF0YVByb3BlcnR5KFwiandrc191cmlcIikudGhlbihqd2tzX3VyaSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czogandrc191cmkgcmVjZWl2ZWRcIiwgandrc191cmkpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLmdldEpzb24oandrc191cmkpLnRoZW4oa2V5U2V0ID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk1ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5czoga2V5IHNldCByZWNlaXZlZFwiLCBrZXlTZXQpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICgha2V5U2V0LmtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJNZXRhZGF0YVNlcnZpY2UuZ2V0U2lnbmluZ0tleXM6IE1pc3Npbmcga2V5cyBvbiBrZXlzZXRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBrZXlzIG9uIGtleXNldFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXR0aW5ncy5zaWduaW5nS2V5cyA9IGtleVNldC5rZXlzO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLnNpZ25pbmdLZXlzO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE9pZGNDbGllbnRTZXR0aW5ncyB9IGZyb20gJy4vT2lkY0NsaWVudFNldHRpbmdzLmpzJztcclxuaW1wb3J0IHsgRXJyb3JSZXNwb25zZSB9IGZyb20gJy4vRXJyb3JSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblJlcXVlc3QgfSBmcm9tICcuL1NpZ25pblJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWduaW5SZXNwb25zZSB9IGZyb20gJy4vU2lnbmluUmVzcG9uc2UuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVxdWVzdCB9IGZyb20gJy4vU2lnbm91dFJlcXVlc3QuanMnO1xyXG5pbXBvcnQgeyBTaWdub3V0UmVzcG9uc2UgfSBmcm9tICcuL1NpZ25vdXRSZXNwb25zZS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9KSB7XHJcbiAgICAgICAgaWYgKHNldHRpbmdzIGluc3RhbmNlb2YgT2lkY0NsaWVudFNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9zZXR0aW5ncyA9IG5ldyBPaWRjQ2xpZW50U2V0dGluZ3Moc2V0dGluZ3MpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3N0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0dGluZ3Muc3RhdGVTdG9yZTtcclxuICAgIH1cclxuICAgIGdldCBfdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnZhbGlkYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLm1ldGFkYXRhU2VydmljZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2V0dGluZ3MoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG5cclxuICAgIGNyZWF0ZVNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgIHJlc3BvbnNlX3R5cGUsIHNjb3BlLCByZWRpcmVjdF91cmksXHJcbiAgICAgICAgLy8gZGF0YSB3YXMgbWVhbnQgdG8gYmUgdGhlIHBsYWNlIGEgY2FsbGVyIGNvdWxkIGluZGljYXRlIHRoZSBkYXRhIHRvXHJcbiAgICAgICAgLy8gaGF2ZSByb3VuZCB0cmlwcGVkLCBidXQgcGVvcGxlIHdlcmUgZ2V0dGluZyBjb25mdXNlZCwgc28gaSBhZGRlZCBzdGF0ZSAoc2luY2UgdGhhdCBtYXRjaGVzIHRoZSBzcGVjKVxyXG4gICAgICAgIC8vIGFuZCBzbyBub3cgaWYgZGF0YSBpcyBub3QgcGFzc2VkLCBidXQgc3RhdGUgaXMgdGhlbiBzdGF0ZSB3aWxsIGJlIHVzZWRcclxuICAgICAgICBkYXRhLCBzdGF0ZSwgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBpZF90b2tlbl9oaW50LCBsb2dpbl9oaW50LCBhY3JfdmFsdWVzLFxyXG4gICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgcmVzcG9uc2VfbW9kZSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCBza2lwVXNlckluZm8gfSA9IHt9LFxyXG4gICAgICAgIHN0YXRlU3RvcmVcclxuICAgICkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbmluUmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICByZXNwb25zZV90eXBlID0gcmVzcG9uc2VfdHlwZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHNjb3BlID0gc2NvcGUgfHwgdGhpcy5fc2V0dGluZ3Muc2NvcGU7XHJcbiAgICAgICAgcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgLy8gaWRfdG9rZW5faGludCwgbG9naW5faGludCBhcmVuJ3QgYWxsb3dlZCBvbiBfc2V0dGluZ3NcclxuICAgICAgICBwcm9tcHQgPSBwcm9tcHQgfHwgdGhpcy5fc2V0dGluZ3MucHJvbXB0O1xyXG4gICAgICAgIGRpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuX3NldHRpbmdzLmRpc3BsYXk7XHJcbiAgICAgICAgbWF4X2FnZSA9IG1heF9hZ2UgfHwgdGhpcy5fc2V0dGluZ3MubWF4X2FnZTtcclxuICAgICAgICB1aV9sb2NhbGVzID0gdWlfbG9jYWxlcyB8fCB0aGlzLl9zZXR0aW5ncy51aV9sb2NhbGVzO1xyXG4gICAgICAgIGFjcl92YWx1ZXMgPSBhY3JfdmFsdWVzIHx8IHRoaXMuX3NldHRpbmdzLmFjcl92YWx1ZXM7XHJcbiAgICAgICAgcmVzb3VyY2UgPSByZXNvdXJjZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNvdXJjZTtcclxuICAgICAgICByZXNwb25zZV9tb2RlID0gcmVzcG9uc2VfbW9kZSB8fCB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlO1xyXG4gICAgICAgIGV4dHJhUXVlcnlQYXJhbXMgPSBleHRyYVF1ZXJ5UGFyYW1zIHx8IHRoaXMuX3NldHRpbmdzLmV4dHJhUXVlcnlQYXJhbXM7XHJcbiAgICAgICAgZXh0cmFUb2tlblBhcmFtcyA9IGV4dHJhVG9rZW5QYXJhbXMgfHwgdGhpcy5fc2V0dGluZ3MuZXh0cmFUb2tlblBhcmFtcztcclxuXHJcbiAgICAgICAgbGV0IGF1dGhvcml0eSA9IHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eTtcclxuXHJcbiAgICAgICAgaWYgKFNpZ25pblJlcXVlc3QuaXNDb2RlKHJlc3BvbnNlX3R5cGUpICYmIHJlc3BvbnNlX3R5cGUgIT09IFwiY29kZVwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJPcGVuSUQgQ29ubmVjdCBoeWJyaWQgZmxvdyBpcyBub3Qgc3VwcG9ydGVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0QXV0aG9yaXphdGlvbkVuZHBvaW50KCkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25pblJlcXVlc3Q6IFJlY2VpdmVkIGF1dGhvcml6YXRpb24gZW5kcG9pbnRcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBzaWduaW5SZXF1ZXN0ID0gbmV3IFNpZ25pblJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X2lkLFxyXG4gICAgICAgICAgICAgICAgcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VfdHlwZSxcclxuICAgICAgICAgICAgICAgIHNjb3BlLFxyXG4gICAgICAgICAgICAgICAgZGF0YTogZGF0YSB8fCBzdGF0ZSxcclxuICAgICAgICAgICAgICAgIGF1dGhvcml0eSxcclxuICAgICAgICAgICAgICAgIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcyxcclxuICAgICAgICAgICAgICAgIHJlc291cmNlLCByZXF1ZXN0LCByZXF1ZXN0X3VyaSwgZXh0cmFRdWVyeVBhcmFtcywgZXh0cmFUb2tlblBhcmFtcywgcmVxdWVzdF90eXBlLCByZXNwb25zZV9tb2RlLFxyXG4gICAgICAgICAgICAgICAgY2xpZW50X3NlY3JldDogdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgICAgIHNraXBVc2VySW5mb1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHZhciBzaWduaW5TdGF0ZSA9IHNpZ25pblJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gc3RhdGVTdG9yZS5zZXQoc2lnbmluU3RhdGUuaWQsIHNpZ25pblN0YXRlLnRvU3RvcmFnZVN0cmluZygpKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzaWduaW5SZXF1ZXN0O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbmluUmVzcG9uc2VTdGF0ZSh1cmwsIHN0YXRlU3RvcmUsIHJlbW92ZVN0YXRlID0gZmFsc2UpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBsZXQgdXNlUXVlcnkgPSB0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV9tb2RlID09PSBcInF1ZXJ5XCIgfHwgXHJcbiAgICAgICAgICAgICghdGhpcy5fc2V0dGluZ3MucmVzcG9uc2VfbW9kZSAmJiBTaWduaW5SZXF1ZXN0LmlzQ29kZSh0aGlzLl9zZXR0aW5ncy5yZXNwb25zZV90eXBlKSk7XHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9IHVzZVF1ZXJ5ID8gXCI/XCIgOiBcIiNcIjtcclxuXHJcbiAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNpZ25pblJlc3BvbnNlKHVybCwgZGVsaW1pdGVyKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50LnJlYWRTaWduaW5SZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN0YXRlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN0YXRlU3RvcmUgPSBzdGF0ZVN0b3JlIHx8IHRoaXMuX3N0YXRlU3RvcmU7XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUFwaSA9IHJlbW92ZVN0YXRlID8gc3RhdGVTdG9yZS5yZW1vdmUuYmluZChzdGF0ZVN0b3JlKSA6IHN0YXRlU3RvcmUuZ2V0LmJpbmQoc3RhdGVTdG9yZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShyZXNwb25zZS5zdGF0ZSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25pblJlc3BvbnNlU3RhdGU6IE5vIG1hdGNoaW5nIHN0YXRlIGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBsZXQgc3RhdGUgPSBTaWduaW5TdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhzdG9yZWRTdGF0ZVN0cmluZyk7XHJcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGUsIHJlc3BvbnNlfTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcm9jZXNzU2lnbmluUmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCwgc3RhdGVTdG9yZSwgdHJ1ZSkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbmluUmVzcG9uc2U6IFJlY2VpdmVkIHN0YXRlIGZyb20gc3RvcmFnZTsgdmFsaWRhdGluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgY3JlYXRlU2lnbm91dFJlcXVlc3Qoe2lkX3Rva2VuX2hpbnQsIGRhdGEsIHN0YXRlLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSB9ID0ge30sXHJcbiAgICAgICAgc3RhdGVTdG9yZVxyXG4gICAgKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5jcmVhdGVTaWdub3V0UmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuX3NldHRpbmdzLnBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zID0gZXh0cmFRdWVyeVBhcmFtcyB8fCB0aGlzLl9zZXR0aW5ncy5leHRyYVF1ZXJ5UGFyYW1zO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldEVuZFNlc3Npb25FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IE5vIGVuZCBzZXNzaW9uIGVuZHBvaW50IHVybCByZXR1cm5lZFwiKTtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5vIGVuZCBzZXNzaW9uIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJPaWRjQ2xpZW50LmNyZWF0ZVNpZ25vdXRSZXF1ZXN0OiBSZWNlaXZlZCBlbmQgc2Vzc2lvbiBlbmRwb2ludFwiLCB1cmwpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHJlcXVlc3QgPSBuZXcgU2lnbm91dFJlcXVlc3Qoe1xyXG4gICAgICAgICAgICAgICAgdXJsLFxyXG4gICAgICAgICAgICAgICAgaWRfdG9rZW5faGludCxcclxuICAgICAgICAgICAgICAgIHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEgfHwgc3RhdGUsXHJcbiAgICAgICAgICAgICAgICBleHRyYVF1ZXJ5UGFyYW1zLFxyXG4gICAgICAgICAgICAgICAgcmVxdWVzdF90eXBlXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgdmFyIHNpZ25vdXRTdGF0ZSA9IHJlcXVlc3Quc3RhdGU7XHJcbiAgICAgICAgICAgIGlmIChzaWdub3V0U3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY3JlYXRlU2lnbm91dFJlcXVlc3Q6IFNpZ25vdXQgcmVxdWVzdCBoYXMgc3RhdGUgdG8gcGVyc2lzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG4gICAgICAgICAgICAgICAgc3RhdGVTdG9yZS5zZXQoc2lnbm91dFN0YXRlLmlkLCBzaWdub3V0U3RhdGUudG9TdG9yYWdlU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCByZW1vdmVTdGF0ZSA9IGZhbHNlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGVcIik7XHJcblxyXG4gICAgICAgIHZhciByZXNwb25zZSA9IG5ldyBTaWdub3V0UmVzcG9uc2UodXJsKTtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBzdGF0ZSBpbiByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLndhcm4oXCJPaWRjQ2xpZW50LnJlYWRTaWdub3V0UmVzcG9uc2VTdGF0ZTogUmVzcG9uc2Ugd2FzIGVycm9yOiBcIiwgcmVzcG9uc2UuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe3VuZGVmaW5lZCwgcmVzcG9uc2V9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBzdGF0ZUtleSA9IHJlc3BvbnNlLnN0YXRlO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICB2YXIgc3RhdGVBcGkgPSByZW1vdmVTdGF0ZSA/IHN0YXRlU3RvcmUucmVtb3ZlLmJpbmQoc3RhdGVTdG9yZSkgOiBzdGF0ZVN0b3JlLmdldC5iaW5kKHN0YXRlU3RvcmUpO1xyXG4gICAgICAgIHJldHVybiBzdGF0ZUFwaShzdGF0ZUtleSkudGhlbihzdG9yZWRTdGF0ZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmICghc3RvcmVkU3RhdGVTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnQucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlOiBObyBtYXRjaGluZyBzdGF0ZSBmb3VuZCBpbiBzdG9yYWdlXCIpO1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWF0Y2hpbmcgc3RhdGUgZm91bmQgaW4gc3RvcmFnZVwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgbGV0IHN0YXRlID0gU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmVkU3RhdGVTdHJpbmcpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtzdGF0ZSwgcmVzcG9uc2V9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsLCBzdGF0ZVN0b3JlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5yZWFkU2lnbm91dFJlc3BvbnNlU3RhdGUodXJsLCBzdGF0ZVN0b3JlLCB0cnVlKS50aGVuKCh7c3RhdGUsIHJlc3BvbnNlfSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoc3RhdGUpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQucHJvY2Vzc1NpZ25vdXRSZXNwb25zZTogUmVjZWl2ZWQgc3RhdGUgZnJvbSBzdG9yYWdlOyB2YWxpZGF0aW5nIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiT2lkY0NsaWVudC5wcm9jZXNzU2lnbm91dFJlc3BvbnNlOiBObyBzdGF0ZSBmcm9tIHN0b3JhZ2U7IHNraXBwaW5nIHZhbGlkYXRpbmcgcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhclN0YWxlU3RhdGUoc3RhdGVTdG9yZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIk9pZGNDbGllbnQuY2xlYXJTdGFsZVN0YXRlXCIpO1xyXG5cclxuICAgICAgICBzdGF0ZVN0b3JlID0gc3RhdGVTdG9yZSB8fCB0aGlzLl9zdGF0ZVN0b3JlO1xyXG5cclxuICAgICAgICByZXR1cm4gU3RhdGUuY2xlYXJTdGFsZVN0YXRlKHN0YXRlU3RvcmUsIHRoaXMuc2V0dGluZ3Muc3RhbGVTdGF0ZUFnZSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB9IGZyb20gJy4vV2ViU3RvcmFnZVN0YXRlU3RvcmUuanMnO1xyXG5pbXBvcnQgeyBSZXNwb25zZVZhbGlkYXRvciB9IGZyb20gJy4vUmVzcG9uc2VWYWxpZGF0b3IuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcblxyXG5jb25zdCBPaWRjTWV0YWRhdGFVcmxQYXRoID0gJy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uJztcclxuXHJcbmNvbnN0IERlZmF1bHRSZXNwb25zZVR5cGUgPSBcImlkX3Rva2VuXCI7XHJcbmNvbnN0IERlZmF1bHRTY29wZSA9IFwib3BlbmlkXCI7XHJcbmNvbnN0IERlZmF1bHRTdGFsZVN0YXRlQWdlID0gNjAgKiAxNTsgLy8gc2Vjb25kc1xyXG5jb25zdCBEZWZhdWx0Q2xvY2tTa2V3SW5TZWNvbmRzID0gNjAgKiA1O1xyXG5cclxuZXhwb3J0IGNsYXNzIE9pZGNDbGllbnRTZXR0aW5ncyB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWV0YWRhdGEgcmVsYXRlZFxyXG4gICAgICAgIGF1dGhvcml0eSwgbWV0YWRhdGFVcmwsIG1ldGFkYXRhLCBzaWduaW5nS2V5cyxcclxuICAgICAgICAvLyBjbGllbnQgcmVsYXRlZFxyXG4gICAgICAgIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgcmVzcG9uc2VfdHlwZSA9IERlZmF1bHRSZXNwb25zZVR5cGUsIHNjb3BlID0gRGVmYXVsdFNjb3BlLFxyXG4gICAgICAgIHJlZGlyZWN0X3VyaSwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIC8vIG9wdGlvbmFsIHByb3RvY29sXHJcbiAgICAgICAgcHJvbXB0LCBkaXNwbGF5LCBtYXhfYWdlLCB1aV9sb2NhbGVzLCBhY3JfdmFsdWVzLCByZXNvdXJjZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAvLyBiZWhhdmlvciBmbGFnc1xyXG4gICAgICAgIGZpbHRlclByb3RvY29sQ2xhaW1zID0gdHJ1ZSwgbG9hZFVzZXJJbmZvID0gdHJ1ZSxcclxuICAgICAgICBzdGFsZVN0YXRlQWdlID0gRGVmYXVsdFN0YWxlU3RhdGVBZ2UsIGNsb2NrU2tldyA9IERlZmF1bHRDbG9ja1NrZXdJblNlY29uZHMsXHJcbiAgICAgICAgdXNlckluZm9Kd3RJc3N1ZXIgPSAnT1AnLFxyXG4gICAgICAgIC8vIG90aGVyIGJlaGF2aW9yXHJcbiAgICAgICAgc3RhdGVTdG9yZSA9IG5ldyBXZWJTdG9yYWdlU3RhdGVTdG9yZSgpLFxyXG4gICAgICAgIFJlc3BvbnNlVmFsaWRhdG9yQ3RvciA9IFJlc3BvbnNlVmFsaWRhdG9yLFxyXG4gICAgICAgIE1ldGFkYXRhU2VydmljZUN0b3IgPSBNZXRhZGF0YVNlcnZpY2UsXHJcbiAgICAgICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICAgICAgZXh0cmFRdWVyeVBhcmFtcyA9IHt9LFxyXG4gICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgPSB7fVxyXG4gICAgfSA9IHt9KSB7XHJcblxyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVVybCA9IG1ldGFkYXRhVXJsO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gbWV0YWRhdGE7XHJcbiAgICAgICAgdGhpcy5fc2lnbmluZ0tleXMgPSBzaWduaW5nS2V5cztcclxuXHJcbiAgICAgICAgdGhpcy5fY2xpZW50X2lkID0gY2xpZW50X2lkO1xyXG4gICAgICAgIHRoaXMuX2NsaWVudF9zZWNyZXQgPSBjbGllbnRfc2VjcmV0O1xyXG4gICAgICAgIHRoaXMuX3Jlc3BvbnNlX3R5cGUgPSByZXNwb25zZV90eXBlO1xyXG4gICAgICAgIHRoaXMuX3Njb3BlID0gc2NvcGU7XHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSA9IHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaTtcclxuXHJcbiAgICAgICAgdGhpcy5fcHJvbXB0ID0gcHJvbXB0O1xyXG4gICAgICAgIHRoaXMuX2Rpc3BsYXkgPSBkaXNwbGF5O1xyXG4gICAgICAgIHRoaXMuX21heF9hZ2UgPSBtYXhfYWdlO1xyXG4gICAgICAgIHRoaXMuX3VpX2xvY2FsZXMgPSB1aV9sb2NhbGVzO1xyXG4gICAgICAgIHRoaXMuX2Fjcl92YWx1ZXMgPSBhY3JfdmFsdWVzO1xyXG4gICAgICAgIHRoaXMuX3Jlc291cmNlID0gcmVzb3VyY2U7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcblxyXG4gICAgICAgIHRoaXMuX2ZpbHRlclByb3RvY29sQ2xhaW1zID0gISFmaWx0ZXJQcm90b2NvbENsYWltcztcclxuICAgICAgICB0aGlzLl9sb2FkVXNlckluZm8gPSAhIWxvYWRVc2VySW5mbztcclxuICAgICAgICB0aGlzLl9zdGFsZVN0YXRlQWdlID0gc3RhbGVTdGF0ZUFnZTtcclxuICAgICAgICB0aGlzLl9jbG9ja1NrZXcgPSBjbG9ja1NrZXc7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXIgPSB1c2VySW5mb0p3dElzc3VlcjtcclxuXHJcbiAgICAgICAgdGhpcy5fc3RhdGVTdG9yZSA9IHN0YXRlU3RvcmU7XHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yID0gbmV3IFJlc3BvbnNlVmFsaWRhdG9yQ3Rvcih0aGlzKTtcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHR5cGVvZiBleHRyYVF1ZXJ5UGFyYW1zID09PSAnb2JqZWN0JyA/IGV4dHJhUXVlcnlQYXJhbXMgOiB7fTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gdHlwZW9mIGV4dHJhVG9rZW5QYXJhbXMgPT09ICdvYmplY3QnID8gZXh0cmFUb2tlblBhcmFtcyA6IHt9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGNsaWVudCBjb25maWdcclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIHNldCBjbGllbnRfaWQodmFsdWUpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NsaWVudF9pZCkge1xyXG4gICAgICAgICAgICAvLyBvbmUtdGltZSBzZXQgb25seVxyXG4gICAgICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIk9pZGNDbGllbnRTZXR0aW5ncy5zZXRfY2xpZW50X2lkOiBjbGllbnRfaWQgaGFzIGFscmVhZHkgYmVlbiBhc3NpZ25lZC5cIilcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkIGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzcG9uc2VfdHlwZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVzcG9uc2VfdHlwZTtcclxuICAgIH1cclxuICAgIGdldCBzY29wZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2NvcGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG9wdGlvbmFsIHByb3RvY29sIHBhcmFtc1xyXG4gICAgZ2V0IHByb21wdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbXB0O1xyXG4gICAgfVxyXG4gICAgZ2V0IGRpc3BsYXkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3BsYXk7XHJcbiAgICB9XHJcbiAgICBnZXQgbWF4X2FnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWF4X2FnZTtcclxuICAgIH1cclxuICAgIGdldCB1aV9sb2NhbGVzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl91aV9sb2NhbGVzO1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjcl92YWx1ZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Fjcl92YWx1ZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcmVzb3VyY2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc291cmNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IHJlc3BvbnNlX21vZGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jlc3BvbnNlX21vZGU7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIC8vIG1ldGFkYXRhXHJcbiAgICBnZXQgYXV0aG9yaXR5KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hdXRob3JpdHk7XHJcbiAgICB9XHJcbiAgICBzZXQgYXV0aG9yaXR5KHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgLy8gb25lLXRpbWUgc2V0IG9ubHlcclxuICAgICAgICAgICAgdGhpcy5fYXV0aG9yaXR5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJPaWRjQ2xpZW50U2V0dGluZ3Muc2V0X2F1dGhvcml0eTogYXV0aG9yaXR5IGhhcyBhbHJlYWR5IGJlZW4gYXNzaWduZWQuXCIpXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eSBoYXMgYWxyZWFkeSBiZWVuIGFzc2lnbmVkLlwiKVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBtZXRhZGF0YVVybCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX21ldGFkYXRhVXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhVXJsID0gdGhpcy5hdXRob3JpdHk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5fbWV0YWRhdGFVcmwgJiYgdGhpcy5fbWV0YWRhdGFVcmwuaW5kZXhPZihPaWRjTWV0YWRhdGFVcmxQYXRoKSA8IDApIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9tZXRhZGF0YVVybFt0aGlzLl9tZXRhZGF0YVVybC5sZW5ndGggLSAxXSAhPT0gJy8nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gJy8nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fbWV0YWRhdGFVcmwgKz0gT2lkY01ldGFkYXRhVXJsUGF0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhVXJsO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHNldHRhYmxlL2NhY2hhYmxlIG1ldGFkYXRhIHZhbHVlc1xyXG4gICAgZ2V0IG1ldGFkYXRhKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YTtcclxuICAgIH1cclxuICAgIHNldCBtZXRhZGF0YSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNpZ25pbmdLZXlzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5nS2V5cztcclxuICAgIH1cclxuICAgIHNldCBzaWduaW5nS2V5cyh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX3NpZ25pbmdLZXlzID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYmVoYXZpb3IgZmxhZ3NcclxuICAgIGdldCBmaWx0ZXJQcm90b2NvbENsYWltcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyUHJvdG9jb2xDbGFpbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgbG9hZFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBnZXQgc3RhbGVTdGF0ZUFnZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RhbGVTdGF0ZUFnZTtcclxuICAgIH1cclxuICAgIGdldCBjbG9ja1NrZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrU2tldztcclxuICAgIH1cclxuICAgIGdldCB1c2VySW5mb0p3dElzc3VlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlckluZm9Kd3RJc3N1ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHN0YXRlU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlU3RvcmU7XHJcbiAgICB9XHJcbiAgICBnZXQgdmFsaWRhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgbWV0YWRhdGFTZXJ2aWNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZXh0cmEgcXVlcnkgcGFyYW1zXHJcbiAgICBnZXQgZXh0cmFRdWVyeVBhcmFtcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fZXh0cmFRdWVyeVBhcmFtcztcclxuICAgIH1cclxuICAgIHNldCBleHRyYVF1ZXJ5UGFyYW1zKHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpe1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVF1ZXJ5UGFyYW1zID0gdmFsdWU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fZXh0cmFRdWVyeVBhcmFtcyA9IHt9O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBleHRyYSB0b2tlbiBwYXJhbXNcclxuICAgIGdldCBleHRyYVRva2VuUGFyYW1zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHRyYVRva2VuUGFyYW1zO1xyXG4gICAgfVxyXG4gICAgc2V0IGV4dHJhVG9rZW5QYXJhbXModmFsdWUpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jyl7XHJcbiAgICAgICAgICAgIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXMgPSB2YWx1ZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0ge307XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgUG9wdXBXaW5kb3cgfSBmcm9tICcuL1BvcHVwV2luZG93LmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBQb3B1cE5hdmlnYXRvciB7XHJcblxyXG4gICAgcHJlcGFyZShwYXJhbXMpIHtcclxuICAgICAgICBsZXQgcG9wdXAgPSBuZXcgUG9wdXBXaW5kb3cocGFyYW1zKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHBvcHVwKTtcclxuICAgIH1cclxuXHJcbiAgICBjYWxsYmFjayh1cmwsIGtlZXBPcGVuLCBkZWxpbWl0ZXIpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cE5hdmlnYXRvci5jYWxsYmFja1wiKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgUG9wdXBXaW5kb3cubm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgQ2hlY2tGb3JQb3B1cENsb3NlZEludGVydmFsID0gNTAwO1xyXG5jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7JztcclxuLy9jb25zdCBEZWZhdWx0UG9wdXBGZWF0dXJlcyA9ICdsb2NhdGlvbj1ubyx0b29sYmFyPW5vLHdpZHRoPTUwMCxoZWlnaHQ9NTAwLGxlZnQ9MTAwLHRvcD0xMDA7cmVzaXphYmxlPXllcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0UG9wdXBUYXJnZXQgPSBcIl9ibGFua1wiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFBvcHVwV2luZG93IHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihwYXJhbXMpIHtcclxuICAgICAgICB0aGlzLl9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlID0gcmVzb2x2ZTtcclxuICAgICAgICAgICAgdGhpcy5fcmVqZWN0ID0gcmVqZWN0O1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBsZXQgdGFyZ2V0ID0gcGFyYW1zLnBvcHVwV2luZG93VGFyZ2V0IHx8IERlZmF1bHRQb3B1cFRhcmdldDtcclxuICAgICAgICBsZXQgZmVhdHVyZXMgPSBwYXJhbXMucG9wdXBXaW5kb3dGZWF0dXJlcyB8fCBEZWZhdWx0UG9wdXBGZWF0dXJlcztcclxuXHJcbiAgICAgICAgdGhpcy5fcG9wdXAgPSB3aW5kb3cub3BlbignJywgdGFyZ2V0LCBmZWF0dXJlcyk7XHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmN0b3I6IHBvcHVwIHN1Y2Nlc3NmdWxseSBjcmVhdGVkXCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSB3aW5kb3cuc2V0SW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZC5iaW5kKHRoaXMpLCBDaGVja0ZvclBvcHVwQ2xvc2VkSW50ZXJ2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgcHJvbWlzZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvbWlzZTtcclxuICAgIH1cclxuXHJcbiAgICBuYXZpZ2F0ZShwYXJhbXMpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX3BvcHVwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IEVycm9yIG9wZW5pbmcgcG9wdXAgd2luZG93XCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICghcGFyYW1zIHx8ICFwYXJhbXMudXJsKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiUG9wdXBXaW5kb3cubmF2aWdhdGU6IG5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJObyB1cmwgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5uYXZpZ2F0ZTogU2V0dGluZyBVUkwgaW4gcG9wdXBcIik7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9pZCA9IHBhcmFtcy5pZDtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX2lkKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3dbXCJwb3B1cENhbGxiYWNrX1wiICsgcGFyYW1zLmlkXSA9IHRoaXMuX2NhbGxiYWNrLmJpbmQodGhpcyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIHRoaXMuX3BvcHVwLndpbmRvdy5sb2NhdGlvbiA9IHBhcmFtcy51cmw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5wcm9taXNlO1xyXG4gICAgfVxyXG5cclxuICAgIF9zdWNjZXNzKGRhdGEpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJQb3B1cFdpbmRvdy5jYWxsYmFjazogU3VjY2Vzc2Z1bCByZXNwb25zZSBmcm9tIHBvcHVwIHdpbmRvd1wiKTtcclxuXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3Jlc29sdmUoZGF0YSk7XHJcbiAgICB9XHJcbiAgICBfZXJyb3IobWVzc2FnZSkge1xyXG4gICAgICAgIExvZy5lcnJvcihcIlBvcHVwV2luZG93LmVycm9yOiBcIiwgbWVzc2FnZSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5fY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX3JlamVjdChuZXcgRXJyb3IobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCkge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoZmFsc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIF9jbGVhbnVwKGtlZXBPcGVuKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUG9wdXBXaW5kb3cuY2xlYW51cFwiKTtcclxuXHJcbiAgICAgICAgd2luZG93LmNsZWFySW50ZXJ2YWwodGhpcy5fY2hlY2tGb3JQb3B1cENsb3NlZFRpbWVyKTtcclxuICAgICAgICB0aGlzLl9jaGVja0ZvclBvcHVwQ2xvc2VkVGltZXIgPSBudWxsO1xyXG5cclxuICAgICAgICBkZWxldGUgd2luZG93W1wicG9wdXBDYWxsYmFja19cIiArIHRoaXMuX2lkXTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuX3BvcHVwICYmICFrZWVwT3Blbikge1xyXG4gICAgICAgICAgICB0aGlzLl9wb3B1cC5jbG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9wb3B1cCA9IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgX2NoZWNrRm9yUG9wdXBDbG9zZWQoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9wb3B1cCB8fCB0aGlzLl9wb3B1cC5jbG9zZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3IoXCJQb3B1cCB3aW5kb3cgY2xvc2VkXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfY2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIHRoaXMuX2NsZWFudXAoa2VlcE9wZW4pO1xyXG5cclxuICAgICAgICBpZiAodXJsKSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrIHN1Y2Nlc3NcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX3N1Y2Nlc3MoeyB1cmw6IHVybCB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93LmNhbGxiYWNrOiBJbnZhbGlkIHJlc3BvbnNlIGZyb20gcG9wdXBcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yKFwiSW52YWxpZCByZXNwb25zZSBmcm9tIHBvcHVwXCIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgbm90aWZ5T3BlbmVyKHVybCwga2VlcE9wZW4sIGRlbGltaXRlcikge1xyXG4gICAgICAgIGlmICh3aW5kb3cub3BlbmVyKSB7XHJcbiAgICAgICAgICAgIHVybCA9IHVybCB8fCB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5hbWUgPSBcInBvcHVwQ2FsbGJhY2tfXCIgKyBkYXRhLnN0YXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IHdpbmRvdy5vcGVuZXJbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogcGFzc2luZyB1cmwgbWVzc2FnZSB0byBvcGVuZXJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJQb3B1cFdpbmRvdy5ub3RpZnlPcGVuZXI6IG5vIG1hdGNoaW5nIGNhbGxiYWNrIGZvdW5kIG9uIG9wZW5lclwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gc3RhdGUgZm91bmQgaW4gcmVzcG9uc2UgdXJsXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cud2FybihcIlBvcHVwV2luZG93Lm5vdGlmeU9wZW5lcjogbm8gd2luZG93Lm9wZW5lci4gQ2FuJ3QgY29tcGxldGUgbm90aWZpY2F0aW9uLlwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlZGlyZWN0TmF2aWdhdG9yIHtcclxuXHJcbiAgICBwcmVwYXJlKCkge1xyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgbmF2aWdhdGUocGFyYW1zKSB7XHJcbiAgICAgICAgaWYgKCFwYXJhbXMgfHwgIXBhcmFtcy51cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVkaXJlY3ROYXZpZ2F0b3IubmF2aWdhdGU6IE5vIHVybCBwcm92aWRlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHVybCBwcm92aWRlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAocGFyYW1zLnVzZVJlcGxhY2VUb05hdmlnYXRlKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHBhcmFtcy51cmwpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gcGFyYW1zLnVybDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgdXJsKCkge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24uaHJlZjtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgVXNlckluZm9TZXJ2aWNlIH0gZnJvbSAnLi9Vc2VySW5mb1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBUb2tlbkNsaWVudCB9IGZyb20gJy4vVG9rZW5DbGllbnQuanMnO1xyXG5pbXBvcnQgeyBFcnJvclJlc3BvbnNlIH0gZnJvbSAnLi9FcnJvclJlc3BvbnNlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmNvbnN0IFByb3RvY29sQ2xhaW1zID0gW1wibm9uY2VcIiwgXCJhdF9oYXNoXCIsIFwiaWF0XCIsIFwibmJmXCIsIFwiZXhwXCIsIFwiYXVkXCIsIFwiaXNzXCIsIFwiY19oYXNoXCJdO1xyXG5cclxuZXhwb3J0IGNsYXNzIFJlc3BvbnNlVmFsaWRhdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgXHJcbiAgICAgICAgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSxcclxuICAgICAgICBVc2VySW5mb1NlcnZpY2VDdG9yID0gVXNlckluZm9TZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsLFxyXG4gICAgICAgIFRva2VuQ2xpZW50Q3RvciA9IFRva2VuQ2xpZW50KSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWQgdG8gUmVzcG9uc2VWYWxpZGF0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9tZXRhZGF0YVNlcnZpY2UgPSBuZXcgTWV0YWRhdGFTZXJ2aWNlQ3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckluZm9TZXJ2aWNlID0gbmV3IFVzZXJJbmZvU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICAgICAgdGhpcy5fdG9rZW5DbGllbnQgPSBuZXcgVG9rZW5DbGllbnRDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25pblJlc3BvbnNlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2VcIik7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzU2lnbmluUGFyYW1zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbmluUmVzcG9uc2U6IHN0YXRlIHByb2Nlc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlVG9rZW5zKHN0YXRlLCByZXNwb25zZSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiB0b2tlbnMgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3NDbGFpbXMoc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25pblJlc3BvbnNlOiBjbGFpbXMgcHJvY2Vzc2VkXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZVNpZ25vdXRSZXNwb25zZShzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoc3RhdGUuaWQgIT09IHJlc3BvbnNlLnN0YXRlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLnZhbGlkYXRlU2lnbm91dFJlc3BvbnNlOiBTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlN0YXRlIGRvZXMgbm90IG1hdGNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIG5vdyB0aGF0IHdlIGtub3cgdGhlIHN0YXRlIG1hdGNoZXMsIHRha2UgdGhlIHN0b3JlZCBkYXRhXHJcbiAgICAgICAgLy8gYW5kIHNldCBpdCBpbnRvIHRoZSByZXNwb25zZSBzbyBjYWxsZXJzIGNhbiBnZXQgdGhlaXIgc3RhdGVcclxuICAgICAgICAvLyB0aGlzIGlzIGltcG9ydGFudCBmb3IgYm90aCBzdWNjZXNzICYgZXJyb3Igb3V0Y29tZXNcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci52YWxpZGF0ZVNpZ25vdXRSZXNwb25zZTogc3RhdGUgdmFsaWRhdGVkXCIpO1xyXG4gICAgICAgIHJlc3BvbnNlLnN0YXRlID0gc3RhdGUuZGF0YTtcclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmVycm9yKSB7XHJcbiAgICAgICAgICAgIExvZy53YXJuKFwiUmVzcG9uc2VWYWxpZGF0b3IudmFsaWRhdGVTaWdub3V0UmVzcG9uc2U6IFJlc3BvbnNlIHdhcyBlcnJvclwiLCByZXNwb25zZS5lcnJvcik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3JSZXNwb25zZShyZXNwb25zZSkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NTaWduaW5QYXJhbXMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHN0YXRlLmlkICE9PSByZXNwb25zZS5zdGF0ZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogU3RhdGUgZG9lcyBub3QgbWF0Y2hcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJTdGF0ZSBkb2VzIG5vdCBtYXRjaFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gY2xpZW50X2lkIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuYXV0aG9yaXR5KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBObyBhdXRob3JpdHkgb24gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBhdXRob3JpdHkgb24gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gdGhpcyBhbGxvd3MgdGhlIGF1dGhvcml0eSB0byBiZSBsb2FkZWQgZnJvbSB0aGUgc2lnbmluIHN0YXRlXHJcbiAgICAgICAgaWYgKCF0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2V0dGluZ3MuYXV0aG9yaXR5ID0gc3RhdGUuYXV0aG9yaXR5O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBlbnN1cmUgd2UncmUgdXNpbmcgdGhlIGNvcnJlY3QgYXV0aG9yaXR5IGlmIHRoZSBhdXRob3JpdHkgaXMgbm90IGxvYWRlZCBmcm9tIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLmF1dGhvcml0eSAmJiB0aGlzLl9zZXR0aW5ncy5hdXRob3JpdHkgIT09IHN0YXRlLmF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogYXV0aG9yaXR5IG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJhdXRob3JpdHkgbWlzbWF0Y2ggb24gc2V0dGluZ3MgdnMuIHNpZ25pbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHRoaXMgYWxsb3dzIHRoZSBjbGllbnRfaWQgdG8gYmUgbG9hZGVkIGZyb20gdGhlIHNpZ25pbiBzdGF0ZVxyXG4gICAgICAgIGlmICghdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZCA9IHN0YXRlLmNsaWVudF9pZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZW5zdXJlIHdlJ3JlIHVzaW5nIHRoZSBjb3JyZWN0IGNsaWVudF9pZCBpZiB0aGUgY2xpZW50X2lkIGlzIG5vdCBsb2FkZWQgZnJvbSBzaWduaW4gc3RhdGVcclxuICAgICAgICBlbHNlIGlmICh0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQgJiYgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkICE9PSBzdGF0ZS5jbGllbnRfaWQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NTaWduaW5QYXJhbXM6IGNsaWVudF9pZCBtaXNtYXRjaCBvbiBzZXR0aW5ncyB2cy4gc2lnbmluIHN0YXRlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiY2xpZW50X2lkIG1pc21hdGNoIG9uIHNldHRpbmdzIHZzLiBzaWduaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gbm93IHRoYXQgd2Uga25vdyB0aGUgc3RhdGUgbWF0Y2hlcywgdGFrZSB0aGUgc3RvcmVkIGRhdGFcclxuICAgICAgICAvLyBhbmQgc2V0IGl0IGludG8gdGhlIHJlc3BvbnNlIHNvIGNhbGxlcnMgY2FuIGdldCB0aGVpciBzdGF0ZVxyXG4gICAgICAgIC8vIHRoaXMgaXMgaW1wb3J0YW50IGZvciBib3RoIHN1Y2Nlc3MgJiBlcnJvciBvdXRjb21lc1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBzdGF0ZSB2YWxpZGF0ZWRcIik7XHJcbiAgICAgICAgcmVzcG9uc2Uuc3RhdGUgPSBzdGF0ZS5kYXRhO1xyXG5cclxuICAgICAgICBpZiAocmVzcG9uc2UuZXJyb3IpIHtcclxuICAgICAgICAgICAgTG9nLndhcm4oXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogUmVzcG9uc2Ugd2FzIGVycm9yXCIsIHJlc3BvbnNlLmVycm9yKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvclJlc3BvbnNlKHJlc3BvbnNlKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUubm9uY2UgJiYgIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBFeHBlY3RpbmcgaWRfdG9rZW4gaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN0YXRlLm5vbmNlICYmIHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGlkX3Rva2VuIGluIHJlc3BvbnNlXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5leHBlY3RlZCBpZF90b2tlbiBpbiByZXNwb25zZVwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoc3RhdGUuY29kZV92ZXJpZmllciAmJiAhcmVzcG9uc2UuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc1NpZ25pblBhcmFtczogRXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBjb2RlIGluIHJlc3BvbnNlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghc3RhdGUuY29kZV92ZXJpZmllciAmJiByZXNwb25zZS5jb2RlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzU2lnbmluUGFyYW1zOiBOb3QgZXhwZWN0aW5nIGNvZGUgaW4gcmVzcG9uc2VcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbmV4cGVjdGVkIGNvZGUgaW4gcmVzcG9uc2VcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZS5zY29wZSkge1xyXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSdzIG5vIHNjb3BlIG9uIHRoZSByZXNwb25zZSwgdGhlbiBhc3N1bWUgYWxsIHNjb3BlcyBncmFudGVkIChwZXItc3BlYykgYW5kIGNvcHkgb3ZlciBzY29wZXMgZnJvbSBvcmlnaW5hbCByZXF1ZXN0XHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnNjb3BlID0gc3RhdGUuc2NvcGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcHJvY2Vzc0NsYWltcyhzdGF0ZSwgcmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAocmVzcG9uc2UuaXNPcGVuSWRDb25uZWN0KSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiByZXNwb25zZSBpcyBPSURDLCBwcm9jZXNzaW5nIGNsYWltc1wiKTtcclxuXHJcbiAgICAgICAgICAgIHJlc3BvbnNlLnByb2ZpbGUgPSB0aGlzLl9maWx0ZXJQcm90b2NvbENsYWltcyhyZXNwb25zZS5wcm9maWxlKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5za2lwVXNlckluZm8gIT09IHRydWUgJiYgdGhpcy5fc2V0dGluZ3MubG9hZFVzZXJJbmZvICYmIHJlc3BvbnNlLmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IGxvYWRpbmcgdXNlciBpbmZvXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zKHJlc3BvbnNlLmFjY2Vzc190b2tlbikudGhlbihjbGFpbXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ2xhaW1zOiB1c2VyIGluZm8gY2xhaW1zIHJlY2VpdmVkIGZyb20gdXNlciBpbmZvIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2xhaW1zLnN1YiAhPT0gcmVzcG9uc2UucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHN1YiBmcm9tIHVzZXIgaW5mbyBlbmRwb2ludCBkb2VzIG5vdCBtYXRjaCBzdWIgaW4gYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwic3ViIGZyb20gdXNlciBpbmZvIGVuZHBvaW50IGRvZXMgbm90IG1hdGNoIHN1YiBpbiBhY2Nlc3NfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UucHJvZmlsZSA9IHRoaXMuX21lcmdlQ2xhaW1zKHJlc3BvbnNlLnByb2ZpbGUsIGNsYWltcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHVzZXIgaW5mbyBjbGFpbXMgcmVjZWl2ZWQsIHVwZGF0ZWQgcHJvZmlsZTpcIiwgcmVzcG9uc2UucHJvZmlsZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IG5vdCBsb2FkaW5nIHVzZXIgaW5mb1wiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3Byb2Nlc3NDbGFpbXM6IHJlc3BvbnNlIGlzIG5vdCBPSURDLCBub3QgcHJvY2Vzc2luZyBjbGFpbXNcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfbWVyZ2VDbGFpbXMoY2xhaW1zMSwgY2xhaW1zMikge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSBPYmplY3QuYXNzaWduKHt9LCBjbGFpbXMxKTtcclxuXHJcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBjbGFpbXMyKSB7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZXMgPSBjbGFpbXMyW25hbWVdO1xyXG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWVzKSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzID0gW3ZhbHVlc107XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgdmFsdWUgPSB2YWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdFtuYW1lXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRbbmFtZV0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdFtuYW1lXS5pbmRleE9mKHZhbHVlKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W25hbWVdLnB1c2godmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdFtuYW1lXSAhPT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSB0aGlzLl9tZXJnZUNsYWltcyhyZXN1bHRbbmFtZV0sIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSBbcmVzdWx0W25hbWVdLCB2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIF9maWx0ZXJQcm90b2NvbENsYWltcyhjbGFpbXMpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyUHJvdG9jb2xDbGFpbXMsIGluY29taW5nIGNsYWltczpcIiwgY2xhaW1zKTtcclxuXHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IE9iamVjdC5hc3NpZ24oe30sIGNsYWltcyk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9zZXR0aW5ncy5fZmlsdGVyUHJvdG9jb2xDbGFpbXMpIHtcclxuICAgICAgICAgICAgUHJvdG9jb2xDbGFpbXMuZm9yRWFjaCh0eXBlID0+IHtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRbdHlwZV07XHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlclByb3RvY29sQ2xhaW1zOiBwcm90b2NvbCBjbGFpbXMgZmlsdGVyZWRcIiwgcmVzdWx0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJQcm90b2NvbENsYWltczogcHJvdG9jb2wgY2xhaW1zIG5vdCBmaWx0ZXJlZFwiKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBfdmFsaWRhdGVUb2tlbnMoc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmNvZGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBWYWxpZGF0aW5nIGNvZGVcIik7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wcm9jZXNzQ29kZShzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5hY2Nlc3NfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlbiBhbmQgYWNjZXNzX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZVRva2VuczogVmFsaWRhdGluZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlSWRUb2tlbihzdGF0ZSwgcmVzcG9uc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlVG9rZW5zOiBObyBjb2RlIHRvIHByb2Nlc3Mgb3IgaWRfdG9rZW4gdG8gdmFsaWRhdGVcIik7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3Byb2Nlc3NDb2RlKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHZhciByZXF1ZXN0ID0ge1xyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHN0YXRlLmNsaWVudF9pZCxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldDogc3RhdGUuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgY29kZSA6IHJlc3BvbnNlLmNvZGUsXHJcbiAgICAgICAgICAgIHJlZGlyZWN0X3VyaTogc3RhdGUucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBjb2RlX3ZlcmlmaWVyOiBzdGF0ZS5jb2RlX3ZlcmlmaWVyXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgaWYgKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMgJiYgdHlwZW9mKHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHJlcXVlc3QsIHN0YXRlLmV4dHJhVG9rZW5QYXJhbXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5DbGllbnQuZXhjaGFuZ2VDb2RlKHJlcXVlc3QpLnRoZW4odG9rZW5SZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBmb3IodmFyIGtleSBpbiB0b2tlblJlc3BvbnNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gdG9rZW5SZXNwb25zZVtrZXldO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2UuaWRfdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9wcm9jZXNzQ29kZTogdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc2Z1bCwgcHJvY2Vzc2luZyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fcHJvY2Vzc0NvZGU6IHRva2VuIHJlc3BvbnNlIHN1Y2Nlc3NmdWwsIHJldHVybmluZyByZXNwb25zZVwiKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5BdHRyaWJ1dGVzKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCkudGhlbihpc3N1ZXIgPT4ge1xyXG5cclxuICAgICAgICAgICAgbGV0IGF1ZGllbmNlID0gc3RhdGUuY2xpZW50X2lkO1xyXG4gICAgICAgICAgICBsZXQgY2xvY2tTa2V3SW5TZWNvbmRzID0gdGhpcy5fc2V0dGluZ3MuY2xvY2tTa2V3O1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogVmFsaWRhaW5nIEpXVCBhdHRyaWJ1dGVzOyB1c2luZyBjbG9jayBza2V3IChpbiBzZWNvbmRzKSBvZjogXCIsIGNsb2NrU2tld0luU2Vjb25kcyk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3RBdHRyaWJ1dGVzKHJlc3BvbnNlLmlkX3Rva2VuLCBpc3N1ZXIsIGF1ZGllbmNlLCBjbG9ja1NrZXdJblNlY29uZHMpLnRoZW4ocGF5bG9hZCA9PiB7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLm5vbmNlICYmIHN0YXRlLm5vbmNlICE9PSBwYXlsb2FkLm5vbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbkF0dHJpYnV0ZXM6IEludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuQXR0cmlidXRlczogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHN1YiBwcmVzZW50IGluIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gcGF5bG9hZDtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlSWRUb2tlbkFuZEFjY2Vzc1Rva2VuKHN0YXRlLCByZXNwb25zZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW4oc3RhdGUsIHJlc3BvbnNlKSB7XHJcbiAgICAgICAgaWYgKCFzdGF0ZS5ub25jZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBub25jZSBvbiBzdGF0ZVwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIG5vbmNlIG9uIHN0YXRlXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChzdGF0ZS5ub25jZSAhPT0gand0LnBheWxvYWQubm9uY2UpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSW52YWxpZCBub25jZSBpbiBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgbm9uY2UgaW4gaWRfdG9rZW5cIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGtpZCA9IGp3dC5oZWFkZXIua2lkO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogUmVjZWl2ZWQgaXNzdWVyXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRTaWduaW5nS2V5cygpLnRoZW4oa2V5cyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVJZFRva2VuOiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gc2lnbmluZyBrZXlzIGZyb20gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFJlY2VpdmVkIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWtpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleXMgPSB0aGlzLl9maWx0ZXJCeUFsZyhrZXlzLCBqd3QuaGVhZGVyLmFsZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGtpZCBmb3VuZCBpbiBpZF90b2tlbiBhbmQgbW9yZSB0aGFuIG9uZSBrZXkgZm91bmQgaW4gbWV0YWRhdGFcIikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8ga2lkIGlzIG1hbmRhdG9yeSBvbmx5IHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIGtleXMgaW4gdGhlIHJlZmVyZW5jZWQgSldLIFNldCBkb2N1bWVudFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzZWUgaHR0cDovL29wZW5pZC5uZXQvc3BlY3Mvb3BlbmlkLWNvbm5lY3QtY29yZS0xXzAuaHRtbCNTaWduaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5cy5maWx0ZXIoa2V5ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGtleS5raWQgPT09IGtpZDtcclxuICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IE5vIGtleSBtYXRjaGluZyBraWQgb3IgYWxnIGZvdW5kIGluIHNpZ25pbmcga2V5c1wiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBsZXQgYXVkaWVuY2UgPSBzdGF0ZS5jbGllbnRfaWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUlkVG9rZW46IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fam9zZVV0aWwudmFsaWRhdGVKd3QocmVzcG9uc2UuaWRfdG9rZW4sIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzKS50aGVuKCgpPT57XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogSldUIHZhbGlkYXRpb24gc3VjY2Vzc2Z1bFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqd3QucGF5bG9hZC5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlSWRUb2tlbjogTm8gc3ViIHByZXNlbnQgaW4gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzdWIgcHJlc2VudCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5wcm9maWxlID0gand0LnBheWxvYWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKXtcclxuICAgICAgICB2YXIga3R5ID0gbnVsbDtcclxuICAgICAgICBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJSU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlJTQVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChhbGcuc3RhcnRzV2l0aChcIlBTXCIpKSB7XHJcbiAgICAgICAgICAgIGt0eSA9IFwiUFNcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJFU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIkVDXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJSZXNwb25zZVZhbGlkYXRvci5fZmlsdGVyQnlBbGc6IGFsZyBub3Qgc3VwcG9ydGVkOiBcIiwgYWxnKTtcclxuICAgICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nLmRlYnVnKFwiUmVzcG9uc2VWYWxpZGF0b3IuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl9maWx0ZXJCeUFsZzogTnVtYmVyIG9mIGtleXMgdGhhdCBtYXRjaCBrdHk6IFwiLCBrdHksIGtleXMubGVuZ3RoKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGtleXM7XHJcbiAgICB9XHJcblxyXG4gICAgX3ZhbGlkYXRlQWNjZXNzVG9rZW4ocmVzcG9uc2UpIHtcclxuICAgICAgICBpZiAoIXJlc3BvbnNlLnByb2ZpbGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IE5vIHByb2ZpbGUgbG9hZGVkIGZyb20gaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBwcm9maWxlIGxvYWRlZCBmcm9tIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBhdF9oYXNoIGluIGlkX3Rva2VuXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gYXRfaGFzaCBpbiBpZF90b2tlblwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXJlc3BvbnNlLmlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBObyBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXNwb25zZS5pZF90b2tlbik7XHJcbiAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byBwYXJzZSBpZF90b2tlblwiLCBqd3QpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHBhcnNlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQWxnID0gand0LmhlYWRlci5hbGc7XHJcbiAgICAgICAgaWYgKCFoYXNoQWxnIHx8IGhhc2hBbGcubGVuZ3RoICE9PSA1KSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBVbnN1cHBvcnRlZCBhbGc6XCIsIGhhc2hBbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBoYXNoQml0cyA9IGhhc2hBbGcuc3Vic3RyKDIsIDMpO1xyXG4gICAgICAgIGlmICghaGFzaEJpdHMpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IFVuc3VwcG9ydGVkIGFsZzpcIiwgaGFzaEFsZywgaGFzaEJpdHMpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWxnOiBcIiArIGhhc2hBbGcpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGhhc2hCaXRzID0gcGFyc2VJbnQoaGFzaEJpdHMpO1xyXG4gICAgICAgIGlmIChoYXNoQml0cyAhPT0gMjU2ICYmIGhhc2hCaXRzICE9PSAzODQgJiYgaGFzaEJpdHMgIT09IDUxMikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogVW5zdXBwb3J0ZWQgYWxnOlwiLCBoYXNoQWxnLCBoYXNoQml0cyk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBhbGc6IFwiICsgaGFzaEFsZykpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IHNoYSA9IFwic2hhXCIgKyBoYXNoQml0cztcclxuICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2pvc2VVdGlsLmhhc2hTdHJpbmcocmVzcG9uc2UuYWNjZXNzX3Rva2VuLCBzaGEpO1xyXG4gICAgICAgIGlmICghaGFzaCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJSZXNwb25zZVZhbGlkYXRvci5fdmFsaWRhdGVBY2Nlc3NUb2tlbjogYWNjZXNzX3Rva2VuIGhhc2ggZmFpbGVkOlwiLCBzaGEpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGF0X2hhc2hcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGxlZnQgPSBoYXNoLnN1YnN0cigwLCBoYXNoLmxlbmd0aCAvIDIpO1xyXG4gICAgICAgIHZhciBsZWZ0X2I2NHUgPSB0aGlzLl9qb3NlVXRpbC5oZXhUb0Jhc2U2NFVybChsZWZ0KTtcclxuICAgICAgICBpZiAobGVmdF9iNjR1ICE9PSByZXNwb25zZS5wcm9maWxlLmF0X2hhc2gpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiUmVzcG9uc2VWYWxpZGF0b3IuX3ZhbGlkYXRlQWNjZXNzVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIsIGxlZnRfYjY0dSwgcmVzcG9uc2UucHJvZmlsZS5hdF9oYXNoKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkZhaWxlZCB0byB2YWxpZGF0ZSBhdF9oYXNoXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlJlc3BvbnNlVmFsaWRhdG9yLl92YWxpZGF0ZUFjY2Vzc1Rva2VuOiBzdWNjZXNzXCIpO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IENoZWNrU2Vzc2lvbklGcmFtZSB9IGZyb20gJy4vQ2hlY2tTZXNzaW9uSUZyYW1lLmpzJztcclxuaW1wb3J0IHsgR2xvYmFsIH0gZnJvbSAnLi9HbG9iYWwuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFNlc3Npb25Nb25pdG9yIHtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih1c2VyTWFuYWdlciwgQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvciA9IENoZWNrU2Vzc2lvbklGcmFtZSwgdGltZXIgPSBHbG9iYWwudGltZXIpIHtcclxuICAgICAgICBpZiAoIXVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLmN0b3I6IE5vIHVzZXIgbWFuYWdlciBwYXNzZWQgdG8gU2Vzc2lvbk1vbml0b3JcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInVzZXJNYW5hZ2VyXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgICAgICB0aGlzLl9DaGVja1Nlc3Npb25JRnJhbWVDdG9yID0gQ2hlY2tTZXNzaW9uSUZyYW1lQ3RvcjtcclxuICAgICAgICB0aGlzLl90aW1lciA9IHRpbWVyO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlckxvYWRlZCh0aGlzLl9zdGFydC5iaW5kKHRoaXMpKTtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkVXNlclVubG9hZGVkKHRoaXMuX3N0b3AuYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICAvLyBkb2luZyB0aGlzIG1hbnVhbGx5IGhlcmUgc2luY2UgY2FsbGluZyBnZXRVc2VyIFxyXG4gICAgICAgICAgICAvLyBkb2Vzbid0IHRyaWdnZXIgbG9hZCBldmVudC5cclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHVzZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3NldHRpbmdzLm1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXMoKS50aGVuKHNlc3Npb24gPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB0bXBVc2VyID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uX3N0YXRlIDogc2Vzc2lvbi5zZXNzaW9uX3N0YXRlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgJiYgc2Vzc2lvbi5zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG1wVXNlci5wcm9maWxlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViOiBzZXNzaW9uLnN1YixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2Vzc2lvbi5zaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodG1wVXNlcik7XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yIGN0b3I6IGVycm9yIGZyb20gcXVlcnlTZXNzaW9uU3RhdHVzOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBhIGN0b3JcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2Vzc2lvbk1vbml0b3IgY3RvcjogZXJyb3IgZnJvbSBnZXRVc2VyOlwiLCBlcnIubWVzc2FnZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IF9zZXR0aW5ncygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIuc2V0dGluZ3M7XHJcbiAgICB9XHJcbiAgICBnZXQgX21ldGFkYXRhU2VydmljZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlck1hbmFnZXIubWV0YWRhdGFTZXJ2aWNlO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9jbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCBfY2hlY2tTZXNzaW9uSW50ZXJ2YWwoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldHRpbmdzLmNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9zdG9wQ2hlY2tTZXNzaW9uT25FcnJvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0dGluZ3Muc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcblxyXG4gICAgX3N0YXJ0KHVzZXIpIHtcclxuICAgICAgICBsZXQgc2Vzc2lvbl9zdGF0ZSA9IHVzZXIuc2Vzc2lvbl9zdGF0ZTtcclxuXHJcbiAgICAgICAgaWYgKHNlc3Npb25fc3RhdGUpIHtcclxuICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3ViID0gdXNlci5wcm9maWxlLnN1YjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3NpZCA9IHVzZXIucHJvZmlsZS5zaWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBzdWI6XCIsIHRoaXMuX3N1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdWIgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb25fc3RhdGUsIFwiLCBhbm9ueW1vdXMgdXNlclwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRDaGVja1Nlc3Npb25JZnJhbWUoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IEluaXRpYWxpemluZyBjaGVjayBzZXNzaW9uIGlmcmFtZVwiKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNsaWVudF9pZCA9IHRoaXMuX2NsaWVudF9pZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGludGVydmFsID0gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzdG9wT25FcnJvciA9IHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lID0gbmV3IHRoaXMuX0NoZWNrU2Vzc2lvbklGcmFtZUN0b3IodGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKSwgY2xpZW50X2lkLCB1cmwsIGludGVydmFsLCBzdG9wT25FcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5sb2FkKCkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLndhcm4oXCJTZXNzaW9uTW9uaXRvci5fc3RhcnQ6IE5vIGNoZWNrIHNlc3Npb24gaWZyYW1lIGZvdW5kIGluIHRoZSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KS5jYXRjaChlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNhdGNoIHRvIHN1cHByZXNzIGVycm9ycyBzaW5jZSB3ZSdyZSBpbiBub24tcHJvbWlzZSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yLl9zdGFydDogRXJyb3IgZnJvbSBnZXRDaGVja1Nlc3Npb25JZnJhbWU6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tTZXNzaW9uSUZyYW1lLnN0YXJ0KHNlc3Npb25fc3RhdGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9zdG9wKCkge1xyXG4gICAgICAgIHRoaXMuX3N1YiA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLl9zaWQgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX3N0b3BcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2NoZWNrU2Vzc2lvbklGcmFtZS5zdG9wKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5fc2V0dGluZ3MubW9uaXRvckFub255bW91c1Nlc3Npb24pIHtcclxuICAgICAgICAgICAgLy8gdXNpbmcgYSB0aW1lciB0byBkZWxheSByZS1pbml0aWFsaXphdGlvbiB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnMgZHVyaW5nIHNpZ25vdXRcclxuICAgICAgICAgICAgbGV0IHRpbWVySGFuZGxlID0gdGhpcy5fdGltZXIuc2V0SW50ZXJ2YWwoKCk9PntcclxuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGltZXJIYW5kbGUpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRtcFVzZXIgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGUgOiBzZXNzaW9uLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXNzaW9uLnN1YiAmJiBzZXNzaW9uLnNpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0bXBVc2VyLnByb2ZpbGUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWI6IHNlc3Npb24uc3ViLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lkOiBzZXNzaW9uLnNpZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0bXBVc2VyKTtcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjYXRjaCB0byBzdXBwcmVzcyBlcnJvcnMgc2luY2Ugd2UncmUgaW4gYSBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlNlc3Npb25Nb25pdG9yOiBlcnJvciBmcm9tIHF1ZXJ5U2Vzc2lvblN0YXR1czpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB9LCAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgX2NhbGxiYWNrKCkge1xyXG4gICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1cygpLnRoZW4oc2Vzc2lvbiA9PiB7XHJcbiAgICAgICAgICAgIHZhciByYWlzZUV2ZW50ID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGlmIChzZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdWIgPT09IHRoaXMuX3N1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJhaXNlRXZlbnQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JRnJhbWUuc3RhcnQoc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlc3Npb24uc2lkID09PSB0aGlzLl9zaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTYW1lIHN1YiBzdGlsbCBsb2dnZWQgaW4gYXQgT1AsIHJlc3RhcnRpbmcgY2hlY2sgc2Vzc2lvbiBpZnJhbWU7IHNlc3Npb25fc3RhdGU6XCIsIHNlc3Npb24uc2Vzc2lvbl9zdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s6IFNhbWUgc3ViIHN0aWxsIGxvZ2dlZCBpbiBhdCBPUCwgc2Vzc2lvbiBzdGF0ZSBoYXMgY2hhbmdlZCwgcmVzdGFydGluZyBjaGVjayBzZXNzaW9uIGlmcmFtZTsgc2Vzc2lvbl9zdGF0ZTpcIiwgc2Vzc2lvbi5zZXNzaW9uX3N0YXRlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTZXNzaW9uQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRGlmZmVyZW50IHN1YmplY3Qgc2lnbmVkIGludG8gT1A6XCIsIHNlc3Npb24uc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogU3ViamVjdCBubyBsb25nZXIgc2lnbmVkIGludG8gT1BcIik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIG91dCBldmVudFwiKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlVXNlclNpZ25lZE91dCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiU2Vzc2lvbk1vbml0b3IuX2NhbGxiYWNrOiBTZXNzaW9uTW9uaXRvci5fY2FsbGJhY2s7IHJhaXNpbmcgc2lnbmVkIGluIGV2ZW50XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkSW4oKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdWIpIHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlNlc3Npb25Nb25pdG9yLl9jYWxsYmFjazogRXJyb3IgY2FsbGluZyBxdWVyeUN1cnJlbnRTaWduaW5TZXNzaW9uOyByYWlzaW5nIHNpZ25lZCBvdXQgZXZlbnRcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIuZXZlbnRzLl9yYWlzZVVzZXJTaWduZWRPdXQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFNpZ25pblN0YXRlIH0gZnJvbSAnLi9TaWduaW5TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluUmVxdWVzdCB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7XHJcbiAgICAgICAgLy8gbWFuZGF0b3J5XHJcbiAgICAgICAgdXJsLCBjbGllbnRfaWQsIHJlZGlyZWN0X3VyaSwgcmVzcG9uc2VfdHlwZSwgc2NvcGUsIGF1dGhvcml0eSxcclxuICAgICAgICAvLyBvcHRpb25hbFxyXG4gICAgICAgIGRhdGEsIHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgcmVxdWVzdCwgcmVxdWVzdF91cmksIGV4dHJhUXVlcnlQYXJhbXMsIHJlcXVlc3RfdHlwZSwgY2xpZW50X3NlY3JldCwgZXh0cmFUb2tlblBhcmFtcywgc2tpcFVzZXJJbmZvXHJcbiAgICB9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyB1cmwgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1cmxcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2xpZW50X2lkXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlZGlyZWN0X3VyaVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlNpZ25pblJlcXVlc3QuY3RvcjogTm8gcmVzcG9uc2VfdHlwZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInJlc3BvbnNlX3R5cGVcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghc2NvcGUpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbmluUmVxdWVzdC5jdG9yOiBObyBzY29wZSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNjb3BlXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWF1dGhvcml0eSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJTaWduaW5SZXF1ZXN0LmN0b3I6IE5vIGF1dGhvcml0eSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImF1dGhvcml0eVwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBvaWRjID0gU2lnbmluUmVxdWVzdC5pc09pZGMocmVzcG9uc2VfdHlwZSk7XHJcbiAgICAgICAgbGV0IGNvZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKTtcclxuXHJcbiAgICAgICAgaWYgKCFyZXNwb25zZV9tb2RlKSB7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlX21vZGUgPSBTaWduaW5SZXF1ZXN0LmlzQ29kZShyZXNwb25zZV90eXBlKSA/IFwicXVlcnlcIiA6IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFNpZ25pblN0YXRlKHsgbm9uY2U6IG9pZGMsIFxyXG4gICAgICAgICAgICBkYXRhLCBjbGllbnRfaWQsIGF1dGhvcml0eSwgcmVkaXJlY3RfdXJpLCBcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogY29kZSwgXHJcbiAgICAgICAgICAgIHJlcXVlc3RfdHlwZSwgcmVzcG9uc2VfbW9kZSxcclxuICAgICAgICAgICAgY2xpZW50X3NlY3JldCwgc2NvcGUsIGV4dHJhVG9rZW5QYXJhbXMsIHNraXBVc2VySW5mbyB9KTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJjbGllbnRfaWRcIiwgY2xpZW50X2lkKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInJlZGlyZWN0X3VyaVwiLCByZWRpcmVjdF91cmkpO1xyXG4gICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIFwicmVzcG9uc2VfdHlwZVwiLCByZXNwb25zZV90eXBlKTtcclxuICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInNjb3BlXCIsIHNjb3BlKTtcclxuXHJcbiAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICBpZiAob2lkYykge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcIm5vbmNlXCIsIHRoaXMuc3RhdGUubm9uY2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY29kZSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlXCIsIHRoaXMuc3RhdGUuY29kZV9jaGFsbGVuZ2UpO1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcImNvZGVfY2hhbGxlbmdlX21ldGhvZFwiLCBcIlMyNTZcIik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgb3B0aW9uYWwgPSB7IHByb21wdCwgZGlzcGxheSwgbWF4X2FnZSwgdWlfbG9jYWxlcywgaWRfdG9rZW5faGludCwgbG9naW5faGludCwgYWNyX3ZhbHVlcywgcmVzb3VyY2UsIHJlcXVlc3QsIHJlcXVlc3RfdXJpLCByZXNwb25zZV9tb2RlIH07XHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gb3B0aW9uYWwpe1xyXG4gICAgICAgICAgICBpZiAob3B0aW9uYWxba2V5XSkge1xyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwga2V5LCBvcHRpb25hbFtrZXldKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGlzT2lkYyhyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiaWRfdG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgaXNPQXV0aChyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwidG9rZW5cIjtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gISEocmVzdWx0WzBdKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgc3RhdGljIGlzQ29kZShyZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlc3BvbnNlX3R5cGUuc3BsaXQoL1xccysvZykuZmlsdGVyKGZ1bmN0aW9uKGl0ZW0pIHtcclxuICAgICAgICAgICAgcmV0dXJuIGl0ZW0gPT09IFwiY29kZVwiO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiAhIShyZXN1bHRbMF0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IFVybFV0aWxpdHkgfSBmcm9tICcuL1VybFV0aWxpdHkuanMnO1xyXG5cclxuY29uc3QgT2lkY1Njb3BlID0gXCJvcGVuaWRcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWduaW5SZXNwb25zZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih1cmwsIGRlbGltaXRlciA9IFwiI1wiKSB7XHJcblxyXG4gICAgICAgIHZhciB2YWx1ZXMgPSBVcmxVdGlsaXR5LnBhcnNlVXJsRnJhZ21lbnQodXJsLCBkZWxpbWl0ZXIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLmNvZGUgPSB2YWx1ZXMuY29kZTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgICAgIHRoaXMuaWRfdG9rZW4gPSB2YWx1ZXMuaWRfdG9rZW47XHJcbiAgICAgICAgdGhpcy5zZXNzaW9uX3N0YXRlID0gdmFsdWVzLnNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSB2YWx1ZXMuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgIHRoaXMudG9rZW5fdHlwZSA9IHZhbHVlcy50b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSB2YWx1ZXMuc2NvcGU7XHJcbiAgICAgICAgdGhpcy5wcm9maWxlID0gdW5kZWZpbmVkOyAvLyB3aWxsIGJlIHNldCBmcm9tIFJlc3BvbnNlVmFsaWRhdG9yXHJcblxyXG4gICAgICAgIHRoaXMuZXhwaXJlc19pbiA9IHZhbHVlcy5leHBpcmVzX2luO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKXtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHBhcnNlSW50KHZhbHVlKTtcclxuICAgICAgICBpZiAodHlwZW9mIGV4cGlyZXNfaW4gPT09ICdudW1iZXInICYmIGV4cGlyZXNfaW4gPiAwKSB7XHJcbiAgICAgICAgICAgIGxldCBub3cgPSBwYXJzZUludChEYXRlLm5vdygpIC8gMTAwMCk7XHJcbiAgICAgICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IG5vdyArIGV4cGlyZXNfaW47XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVkKCkge1xyXG4gICAgICAgIGxldCBleHBpcmVzX2luID0gdGhpcy5leHBpcmVzX2luO1xyXG4gICAgICAgIGlmIChleHBpcmVzX2luICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGV4cGlyZXNfaW4gPD0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2NvcGVzKCkge1xyXG4gICAgICAgIHJldHVybiAodGhpcy5zY29wZSB8fCBcIlwiKS5zcGxpdChcIiBcIik7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGlzT3BlbklkQ29ubmVjdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zY29wZXMuaW5kZXhPZihPaWRjU2NvcGUpID49IDAgfHwgISF0aGlzLmlkX3Rva2VuO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgU3RhdGUgfSBmcm9tICcuL1N0YXRlLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbmluU3RhdGUgZXh0ZW5kcyBTdGF0ZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7bm9uY2UsIGF1dGhvcml0eSwgY2xpZW50X2lkLCByZWRpcmVjdF91cmksIGNvZGVfdmVyaWZpZXIsIHJlc3BvbnNlX21vZGUsIGNsaWVudF9zZWNyZXQsIHNjb3BlLCBleHRyYVRva2VuUGFyYW1zLCBza2lwVXNlckluZm99ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICBpZiAobm9uY2UgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSByYW5kb20oKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAobm9uY2UpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm9uY2UgPSBub25jZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjb2RlX3ZlcmlmaWVyID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIC8vIHJhbmRvbSgpIHByb2R1Y2VzIDMyIGxlbmd0aFxyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX3ZlcmlmaWVyID0gcmFuZG9tKCkgKyByYW5kb20oKSArIHJhbmRvbSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChjb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvZGVfdmVyaWZpZXIgPSBjb2RlX3ZlcmlmaWVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAodGhpcy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIGxldCBoYXNoID0gSm9zZVV0aWwuaGFzaFN0cmluZyh0aGlzLmNvZGVfdmVyaWZpZXIsIFwiU0hBMjU2XCIpO1xyXG4gICAgICAgICAgICB0aGlzLl9jb2RlX2NoYWxsZW5nZSA9IEpvc2VVdGlsLmhleFRvQmFzZTY0VXJsKGhhc2gpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RfdXJpID0gcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX2F1dGhvcml0eSA9IGF1dGhvcml0eTtcclxuICAgICAgICB0aGlzLl9jbGllbnRfaWQgPSBjbGllbnRfaWQ7XHJcbiAgICAgICAgdGhpcy5fcmVzcG9uc2VfbW9kZSA9IHJlc3BvbnNlX21vZGU7XHJcbiAgICAgICAgdGhpcy5fY2xpZW50X3NlY3JldCA9IGNsaWVudF9zZWNyZXQ7XHJcbiAgICAgICAgdGhpcy5fc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLl9leHRyYVRva2VuUGFyYW1zID0gZXh0cmFUb2tlblBhcmFtcztcclxuICAgICAgICB0aGlzLl9za2lwVXNlckluZm8gPSBza2lwVXNlckluZm87XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG5vbmNlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ub25jZTtcclxuICAgIH1cclxuICAgIGdldCBhdXRob3JpdHkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dGhvcml0eTtcclxuICAgIH1cclxuICAgIGdldCBjbGllbnRfaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9pZDtcclxuICAgIH1cclxuICAgIGdldCByZWRpcmVjdF91cmkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlZGlyZWN0X3VyaTtcclxuICAgIH1cclxuICAgIGdldCBjb2RlX3ZlcmlmaWVyKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX3ZlcmlmaWVyO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNvZGVfY2hhbGxlbmdlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb2RlX2NoYWxsZW5nZTtcclxuICAgIH1cclxuICAgIGdldCByZXNwb25zZV9tb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yZXNwb25zZV9tb2RlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGNsaWVudF9zZWNyZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWVudF9zZWNyZXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgc2NvcGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Njb3BlO1xyXG4gICAgfVxyXG4gICAgZ2V0IGV4dHJhVG9rZW5QYXJhbXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4dHJhVG9rZW5QYXJhbXM7XHJcbiAgICB9XHJcbiAgICBnZXQgc2tpcFVzZXJJbmZvKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9za2lwVXNlckluZm87XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJTaWduaW5TdGF0ZS50b1N0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgICAgICAgaWQ6IHRoaXMuaWQsXHJcbiAgICAgICAgICAgIGRhdGE6IHRoaXMuZGF0YSxcclxuICAgICAgICAgICAgY3JlYXRlZDogdGhpcy5jcmVhdGVkLFxyXG4gICAgICAgICAgICByZXF1ZXN0X3R5cGU6IHRoaXMucmVxdWVzdF90eXBlLFxyXG4gICAgICAgICAgICBub25jZTogdGhpcy5ub25jZSxcclxuICAgICAgICAgICAgY29kZV92ZXJpZmllcjogdGhpcy5jb2RlX3ZlcmlmaWVyLFxyXG4gICAgICAgICAgICByZWRpcmVjdF91cmk6IHRoaXMucmVkaXJlY3RfdXJpLFxyXG4gICAgICAgICAgICBhdXRob3JpdHk6IHRoaXMuYXV0aG9yaXR5LFxyXG4gICAgICAgICAgICBjbGllbnRfaWQ6IHRoaXMuY2xpZW50X2lkLFxyXG4gICAgICAgICAgICByZXNwb25zZV9tb2RlOiB0aGlzLnJlc3BvbnNlX21vZGUsXHJcbiAgICAgICAgICAgIGNsaWVudF9zZWNyZXQ6IHRoaXMuY2xpZW50X3NlY3JldCxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIGV4dHJhVG9rZW5QYXJhbXMgOiB0aGlzLmV4dHJhVG9rZW5QYXJhbXMsXHJcbiAgICAgICAgICAgIHNraXBVc2VySW5mbzogdGhpcy5za2lwVXNlckluZm9cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgZnJvbVN0b3JhZ2VTdHJpbmcoc3RvcmFnZVN0cmluZykge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlNpZ25pblN0YXRlLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHZhciBkYXRhID0gSlNPTi5wYXJzZShzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICByZXR1cm4gbmV3IFNpZ25pblN0YXRlKGRhdGEpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcbmltcG9ydCB7IFN0YXRlIH0gZnJvbSAnLi9TdGF0ZS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlcXVlc3Qge1xyXG4gICAgY29uc3RydWN0b3Ioe3VybCwgaWRfdG9rZW5faGludCwgcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLCBkYXRhLCBleHRyYVF1ZXJ5UGFyYW1zLCByZXF1ZXN0X3R5cGV9KSB7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lnbm91dFJlcXVlc3QuY3RvcjogTm8gdXJsIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGlkX3Rva2VuX2hpbnQpIHtcclxuICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJpZF90b2tlbl9oaW50XCIsIGlkX3Rva2VuX2hpbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICB1cmwgPSBVcmxVdGlsaXR5LmFkZFF1ZXJ5UGFyYW0odXJsLCBcInBvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaVwiLCBwb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBuZXcgU3RhdGUoeyBkYXRhLCByZXF1ZXN0X3R5cGUgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdXJsID0gVXJsVXRpbGl0eS5hZGRRdWVyeVBhcmFtKHVybCwgXCJzdGF0ZVwiLCB0aGlzLnN0YXRlLmlkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZm9yKGxldCBrZXkgaW4gZXh0cmFRdWVyeVBhcmFtcyl7XHJcbiAgICAgICAgICAgIHVybCA9IFVybFV0aWxpdHkuYWRkUXVlcnlQYXJhbSh1cmwsIGtleSwgZXh0cmFRdWVyeVBhcmFtc1trZXldKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy51cmwgPSB1cmw7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgVXJsVXRpbGl0eSB9IGZyb20gJy4vVXJsVXRpbGl0eS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU2lnbm91dFJlc3BvbnNlIHtcclxuICAgIGNvbnN0cnVjdG9yKHVybCkge1xyXG5cclxuICAgICAgICB2YXIgdmFsdWVzID0gVXJsVXRpbGl0eS5wYXJzZVVybEZyYWdtZW50KHVybCwgXCI/XCIpO1xyXG5cclxuICAgICAgICB0aGlzLmVycm9yID0gdmFsdWVzLmVycm9yO1xyXG4gICAgICAgIHRoaXMuZXJyb3JfZGVzY3JpcHRpb24gPSB2YWx1ZXMuZXJyb3JfZGVzY3JpcHRpb247XHJcbiAgICAgICAgdGhpcy5lcnJvcl91cmkgPSB2YWx1ZXMuZXJyb3JfdXJpO1xyXG5cclxuICAgICAgICB0aGlzLnN0YXRlID0gdmFsdWVzLnN0YXRlO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBTaWxlbnRSZW5ld1NlcnZpY2Uge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHVzZXJNYW5hZ2VyKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlck1hbmFnZXIgPSB1c2VyTWFuYWdlcjtcclxuICAgIH1cclxuXHJcbiAgICBzdGFydCgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrID0gdGhpcy5fdG9rZW5FeHBpcmluZy5iaW5kKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuYWRkQWNjZXNzVG9rZW5FeHBpcmluZyh0aGlzLl9jYWxsYmFjayk7XHJcblxyXG4gICAgICAgICAgICAvLyB0aGlzIHdpbGwgdHJpZ2dlciBsb2FkaW5nIG9mIHRoZSB1c2VyIHNvIHRoZSBleHBpcmluZyBldmVudHMgY2FuIGJlIGluaXRpYWxpemVkXHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmdldFVzZXIoKS50aGVuKHVzZXI9PntcclxuICAgICAgICAgICAgICAgIC8vIGRlbGliZXJhdGUgbm9wXHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVycj0+e1xyXG4gICAgICAgICAgICAgICAgLy8gY2F0Y2ggdG8gc3VwcHJlc3MgZXJyb3JzIHNpbmNlIHdlJ3JlIGluIGEgY3RvclxyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLnN0YXJ0OiBFcnJvciBmcm9tIGdldFVzZXI6XCIsIGVyci5tZXNzYWdlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHN0b3AoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJNYW5hZ2VyLmV2ZW50cy5yZW1vdmVBY2Nlc3NUb2tlbkV4cGlyaW5nKHRoaXMuX2NhbGxiYWNrKTtcclxuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfdG9rZW5FeHBpcmluZygpIHtcclxuICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5zaWduaW5TaWxlbnQoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTaWxlbnRSZW5ld1NlcnZpY2UuX3Rva2VuRXhwaXJpbmc6IFNpbGVudCB0b2tlbiByZW5ld2FsIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgfSwgZXJyID0+IHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiU2lsZW50UmVuZXdTZXJ2aWNlLl90b2tlbkV4cGlyaW5nOiBFcnJvciBmcm9tIHNpZ25pblNpbGVudDpcIiwgZXJyLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl91c2VyTWFuYWdlci5ldmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlcnIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHJhbmRvbSBmcm9tICcuL3JhbmRvbS5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgU3RhdGUge1xyXG4gICAgY29uc3RydWN0b3Ioe2lkLCBkYXRhLCBjcmVhdGVkLCByZXF1ZXN0X3R5cGV9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9pZCA9IGlkIHx8IHJhbmRvbSgpO1xyXG4gICAgICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xyXG5cclxuICAgICAgICBpZiAodHlwZW9mIGNyZWF0ZWQgPT09ICdudW1iZXInICYmIGNyZWF0ZWQgPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZWQgPSBjcmVhdGVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fY3JlYXRlZCA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdF90eXBlID0gIHJlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgaWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lkO1xyXG4gICAgfVxyXG4gICAgZ2V0IGRhdGEoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XHJcbiAgICB9XHJcbiAgICBnZXQgY3JlYXRlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY3JlYXRlZDtcclxuICAgIH1cclxuICAgIGdldCByZXF1ZXN0X3R5cGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RfdHlwZTtcclxuICAgIH1cclxuXHJcbiAgICB0b1N0b3JhZ2VTdHJpbmcoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUudG9TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxyXG4gICAgICAgICAgICBkYXRhOiB0aGlzLmRhdGEsXHJcbiAgICAgICAgICAgIGNyZWF0ZWQ6IHRoaXMuY3JlYXRlZCxcclxuICAgICAgICAgICAgcmVxdWVzdF90eXBlOiB0aGlzLnJlcXVlc3RfdHlwZVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0YXRpYyBmcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuZnJvbVN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBTdGF0ZShKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgY2xlYXJTdGFsZVN0YXRlKHN0b3JhZ2UsIGFnZSkge1xyXG5cclxuICAgICAgICB2YXIgY3V0b2ZmID0gRGF0ZS5ub3coKSAvIDEwMDAgLSBhZ2U7XHJcblxyXG4gICAgICAgIHJldHVybiBzdG9yYWdlLmdldEFsbEtleXMoKS50aGVuKGtleXMgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IGdvdCBrZXlzXCIsIGtleXMpO1xyXG5cclxuICAgICAgICAgICAgdmFyIHByb21pc2VzID0gW107XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgbGV0IGtleSA9IGtleXNbaV07XHJcbiAgICAgICAgICAgICAgICB2YXIgcCA9IHN0b3JhZ2UuZ2V0KGtleSkudGhlbihpdGVtID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgcmVtb3ZlID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBTdGF0ZS5mcm9tU3RvcmFnZVN0cmluZyhpdGVtKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogZ290IGl0ZW0gZnJvbSBrZXk6IFwiLCBrZXksIHN0YXRlLmNyZWF0ZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZS5jcmVhdGVkIDw9IGN1dG9mZikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogRXJyb3IgcGFyc2luZyBzdGF0ZSBmb3Iga2V5XCIsIGtleSwgZS5tZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlN0YXRlLmNsZWFyU3RhbGVTdGF0ZTogbm8gaXRlbSBpbiBzdG9yYWdlIGZvciBrZXk6IFwiLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJTdGF0ZS5jbGVhclN0YWxlU3RhdGU6IHJlbW92ZWQgaXRlbSBmb3Iga2V5OiBcIiwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0b3JhZ2UucmVtb3ZlKGtleSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChwKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiU3RhdGUuY2xlYXJTdGFsZVN0YXRlOiB3YWl0aW5nIG9uIHByb21pc2UgY291bnQ6XCIsIHByb21pc2VzLmxlbmd0aCk7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5jb25zdCBUaW1lckR1cmF0aW9uID0gNTsgLy8gc2Vjb25kc1xyXG5cclxuZXhwb3J0IGNsYXNzIFRpbWVyIGV4dGVuZHMgRXZlbnQge1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKG5hbWUsIHRpbWVyID0gR2xvYmFsLnRpbWVyLCBub3dGdW5jID0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc3VwZXIobmFtZSk7XHJcbiAgICAgICAgdGhpcy5fdGltZXIgPSB0aW1lcjtcclxuXHJcbiAgICAgICAgaWYgKG5vd0Z1bmMpIHtcclxuICAgICAgICAgICAgdGhpcy5fbm93RnVuYyA9IG5vd0Z1bmM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9ub3dGdW5jID0gKCkgPT4gRGF0ZS5ub3coKSAvIDEwMDA7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldCBub3coKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnNlSW50KHRoaXMuX25vd0Z1bmMoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaW5pdChkdXJhdGlvbikge1xyXG4gICAgICAgIGlmIChkdXJhdGlvbiA8PSAwKSB7XHJcbiAgICAgICAgICAgIGR1cmF0aW9uID0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZHVyYXRpb24gPSBwYXJzZUludChkdXJhdGlvbik7XHJcblxyXG4gICAgICAgIHZhciBleHBpcmF0aW9uID0gdGhpcy5ub3cgKyBkdXJhdGlvbjtcclxuICAgICAgICBpZiAodGhpcy5leHBpcmF0aW9uID09PSBleHBpcmF0aW9uICYmIHRoaXMuX3RpbWVySGFuZGxlKSB7XHJcbiAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gcmVpbml0aWFsaXplIHRvIHNhbWUgZXhwaXJhdGlvbiwgc28gYmFpbCBvdXRcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuaW5pdCB0aW1lciBcIiArIHRoaXMuX25hbWUgKyBcIiBza2lwcGluZyBpbml0aWFsaXphdGlvbiBzaW5jZSBhbHJlYWR5IGluaXRpYWxpemVkIGZvciBleHBpcmF0aW9uOlwiLCB0aGlzLmV4cGlyYXRpb24pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmNhbmNlbCgpO1xyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5pbml0IHRpbWVyIFwiICsgdGhpcy5fbmFtZSArIFwiIGZvciBkdXJhdGlvbjpcIiwgZHVyYXRpb24pO1xyXG4gICAgICAgIHRoaXMuX2V4cGlyYXRpb24gPSBleHBpcmF0aW9uO1xyXG5cclxuICAgICAgICAvLyB3ZSdyZSB1c2luZyBhIGZhaXJseSBzaG9ydCB0aW1lciBhbmQgdGhlbiBjaGVja2luZyB0aGUgZXhwaXJhdGlvbiBpbiB0aGVcclxuICAgICAgICAvLyBjYWxsYmFjayB0byBoYW5kbGUgc2NlbmFyaW9zIHdoZXJlIHRoZSBicm93c2VyIGRldmljZSBzbGVlcHMsIGFuZCB0aGVuXHJcbiAgICAgICAgLy8gdGhlIHRpbWVycyBlbmQgdXAgZ2V0dGluZyBkZWxheWVkLlxyXG4gICAgICAgIHZhciB0aW1lckR1cmF0aW9uID0gVGltZXJEdXJhdGlvbjtcclxuICAgICAgICBpZiAoZHVyYXRpb24gPCB0aW1lckR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHRpbWVyRHVyYXRpb24gPSBkdXJhdGlvbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5fdGltZXJIYW5kbGUgPSB0aGlzLl90aW1lci5zZXRJbnRlcnZhbCh0aGlzLl9jYWxsYmFjay5iaW5kKHRoaXMpLCB0aW1lckR1cmF0aW9uICogMTAwMCk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGdldCBleHBpcmF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9leHBpcmF0aW9uO1xyXG4gICAgfVxyXG5cclxuICAgIGNhbmNlbCgpIHtcclxuICAgICAgICBpZiAodGhpcy5fdGltZXJIYW5kbGUpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVGltZXIuY2FuY2VsOiBcIiwgdGhpcy5fbmFtZSk7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVyLmNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXJIYW5kbGUpO1xyXG4gICAgICAgICAgICB0aGlzLl90aW1lckhhbmRsZSA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIF9jYWxsYmFjaygpIHtcclxuICAgICAgICB2YXIgZGlmZiA9IHRoaXMuX2V4cGlyYXRpb24gLSB0aGlzLm5vdztcclxuICAgICAgICBMb2cuZGVidWcoXCJUaW1lci5jYWxsYmFjazsgXCIgKyB0aGlzLl9uYW1lICsgXCIgdGltZXIgZXhwaXJlcyBpbjpcIiwgZGlmZik7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9leHBpcmF0aW9uIDw9IHRoaXMubm93KSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsKCk7XHJcbiAgICAgICAgICAgIHN1cGVyLnJhaXNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IEpzb25TZXJ2aWNlIH0gZnJvbSAnLi9Kc29uU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IE1ldGFkYXRhU2VydmljZSB9IGZyb20gJy4vTWV0YWRhdGFTZXJ2aWNlLmpzJztcclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuQ2xpZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKHNldHRpbmdzLCBKc29uU2VydmljZUN0b3IgPSBKc29uU2VydmljZSwgTWV0YWRhdGFTZXJ2aWNlQ3RvciA9IE1ldGFkYXRhU2VydmljZSkge1xyXG4gICAgICAgIGlmICghc2V0dGluZ3MpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZXR0aW5nc1wiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fanNvblNlcnZpY2UgPSBuZXcgSnNvblNlcnZpY2VDdG9yKCk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGV4Y2hhbmdlQ29kZShhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcImF1dGhvcml6YXRpb25fY29kZVwiO1xyXG4gICAgICAgIGFyZ3MuY2xpZW50X2lkID0gYXJncy5jbGllbnRfaWQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X2lkO1xyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gYXJncy5yZWRpcmVjdF91cmkgfHwgdGhpcy5fc2V0dGluZ3MucmVkaXJlY3RfdXJpO1xyXG5cclxuICAgICAgICBpZiAoIWFyZ3MuY29kZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIGNvZGUgcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSBjb2RlIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZGlyZWN0X3VyaSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IE5vIHJlZGlyZWN0X3VyaSBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHJlZGlyZWN0X3VyaSBpcyByZXF1aXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghYXJncy5jb2RlX3ZlcmlmaWVyKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY29kZV92ZXJpZmllciBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIGNvZGVfdmVyaWZpZXIgaXMgcmVxdWlyZWRcIikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWFyZ3MuY2xpZW50X2lkKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlRva2VuQ2xpZW50LmV4Y2hhbmdlQ29kZTogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IFJlY2VpdmVkIHRva2VuIGVuZHBvaW50XCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pzb25TZXJ2aWNlLnBvc3RGb3JtKHVybCwgYXJncykudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZUNvZGU6IHJlc3BvbnNlIHJlY2VpdmVkXCIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBleGNoYW5nZVJlZnJlc2hUb2tlbihhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MuZ3JhbnRfdHlwZSA9IGFyZ3MuZ3JhbnRfdHlwZSB8fCBcInJlZnJlc2hfdG9rZW5cIjtcclxuICAgICAgICBhcmdzLmNsaWVudF9pZCA9IGFyZ3MuY2xpZW50X2lkIHx8IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuICAgICAgICBhcmdzLmNsaWVudF9zZWNyZXQgPSBhcmdzLmNsaWVudF9zZWNyZXQgfHwgdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuXHJcbiAgICAgICAgaWYgKCFhcmdzLnJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5DbGllbnQuZXhjaGFuZ2VSZWZyZXNoVG9rZW46IE5vIHJlZnJlc2hfdG9rZW4gcGFzc2VkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQSByZWZyZXNoX3Rva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmdzLmNsaWVudF9pZCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogTm8gY2xpZW50X2lkIHBhc3NlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkEgY2xpZW50X2lkIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VG9rZW5FbmRwb2ludChmYWxzZSkudGhlbih1cmwgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlbkNsaWVudC5leGNoYW5nZVJlZnJlc2hUb2tlbjogUmVjZWl2ZWQgdG9rZW4gZW5kcG9pbnRcIik7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UucG9zdEZvcm0odXJsLCBhcmdzKS50aGVuKHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuOiByZXNwb25zZSByZWNlaXZlZFwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmNvbnN0IEFjY2Vzc1Rva2VuVHlwZUhpbnQgPSBcImFjY2Vzc190b2tlblwiO1xyXG5jb25zdCBSZWZyZXNoVG9rZW5UeXBlSGludCA9IFwicmVmcmVzaF90b2tlblwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRva2VuUmV2b2NhdGlvbkNsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncywgWE1MSHR0cFJlcXVlc3RDdG9yID0gR2xvYmFsLlhNTEh0dHBSZXF1ZXN0LCBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlKSB7XHJcbiAgICAgICAgaWYgKCFzZXR0aW5ncykge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQuY3RvcjogTm8gc2V0dGluZ3MgcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHNldHRpbmdzIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NldHRpbmdzID0gc2V0dGluZ3M7XHJcbiAgICAgICAgdGhpcy5fWE1MSHR0cFJlcXVlc3RDdG9yID0gWE1MSHR0cFJlcXVlc3RDdG9yO1xyXG4gICAgICAgIHRoaXMuX21ldGFkYXRhU2VydmljZSA9IG5ldyBNZXRhZGF0YVNlcnZpY2VDdG9yKHRoaXMuX3NldHRpbmdzKTtcclxuICAgIH1cclxuXHJcbiAgICByZXZva2UodG9rZW4sIHJlcXVpcmVkLCB0eXBlID0gXCJhY2Nlc3NfdG9rZW5cIikge1xyXG4gICAgICAgIGlmICghdG9rZW4pIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogTm8gdG9rZW4gcHJvdmlkZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIHRva2VuIHByb3ZpZGVkLlwiKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0eXBlICE9PSBBY2Nlc3NUb2tlblR5cGVIaW50ICYmIHR5cGUgIT0gUmVmcmVzaFRva2VuVHlwZUhpbnQpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZTogSW52YWxpZCB0b2tlbiB0eXBlXCIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHRva2VuIHR5cGUuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21ldGFkYXRhU2VydmljZS5nZXRSZXZvY2F0aW9uRW5kcG9pbnQoKS50aGVuKHVybCA9PiB7XHJcbiAgICAgICAgICAgIGlmICghdXJsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBSZXZvY2F0aW9uIG5vdCBzdXBwb3J0ZWRcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmV2b2NhdGlvbiBub3Qgc3VwcG9ydGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIG5vdCByZXF1aXJlZCwgc28gZG9uJ3QgZXJyb3IgYW5kIGp1c3QgcmV0dXJuXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlRva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2U6IFJldm9raW5nIFwiICsgdHlwZSk7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfaWQgPSB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQ7XHJcbiAgICAgICAgICAgIHZhciBjbGllbnRfc2VjcmV0ID0gdGhpcy5fc2V0dGluZ3MuY2xpZW50X3NlY3JldDtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZSh1cmwsIGNsaWVudF9pZCwgY2xpZW50X3NlY3JldCwgdG9rZW4sIHR5cGUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2UodXJsLCBjbGllbnRfaWQsIGNsaWVudF9zZWNyZXQsIHRva2VuLCB0eXBlKSB7XHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcblxyXG4gICAgICAgICAgICB2YXIgeGhyID0gbmV3IHRoaXMuX1hNTEh0dHBSZXF1ZXN0Q3RvcigpO1xyXG4gICAgICAgICAgICB4aHIub3BlbihcIlBPU1RcIiwgdXJsKTtcclxuXHJcbiAgICAgICAgICAgIHhoci5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBIVFRQIHJlc3BvbnNlIHJlY2VpdmVkLCBzdGF0dXNcIiwgeGhyLnN0YXR1cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcih4aHIuc3RhdHVzVGV4dCArIFwiIChcIiArIHhoci5zdGF0dXMgKyBcIilcIikpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB4aHIub25lcnJvciA9ICgpID0+IHsgXHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJUb2tlblJldm9jYXRpb25DbGllbnQucmV2b2tlOiBOZXR3b3JrIEVycm9yLlwiKVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KFwiTmV0d29yayBFcnJvclwiKTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIHZhciBib2R5ID0gXCJjbGllbnRfaWQ9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoY2xpZW50X2lkKTtcclxuICAgICAgICAgICAgaWYgKGNsaWVudF9zZWNyZXQpIHtcclxuICAgICAgICAgICAgICAgIGJvZHkgKz0gXCImY2xpZW50X3NlY3JldD1cIiArIGVuY29kZVVSSUNvbXBvbmVudChjbGllbnRfc2VjcmV0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBib2R5ICs9IFwiJnRva2VuX3R5cGVfaGludD1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0eXBlKTtcclxuICAgICAgICAgICAgYm9keSArPSBcIiZ0b2tlbj1cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0b2tlbik7XHJcblxyXG4gICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKTtcclxuICAgICAgICAgICAgeGhyLnNlbmQoYm9keSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIiwiLy8gQ29weXJpZ2h0IChjKSBCcm9jayBBbGxlbiAmIERvbWluaWNrIEJhaWVyLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wLiBTZWUgTElDRU5TRSBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG5cclxuaW1wb3J0IHsgTG9nIH0gZnJvbSAnLi9Mb2cuanMnO1xyXG5pbXBvcnQgeyBHbG9iYWwgfSBmcm9tICcuL0dsb2JhbC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXJsVXRpbGl0eSB7XHJcbiAgICBzdGF0aWMgYWRkUXVlcnlQYXJhbSh1cmwsIG5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHVybC5pbmRleE9mKCc/JykgPCAwKSB7XHJcbiAgICAgICAgICAgIHVybCArPSBcIj9cIjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh1cmxbdXJsLmxlbmd0aCAtIDFdICE9PSBcIj9cIikge1xyXG4gICAgICAgICAgICB1cmwgKz0gXCImXCI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KG5hbWUpO1xyXG4gICAgICAgIHVybCArPSBcIj1cIjtcclxuICAgICAgICB1cmwgKz0gZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHVybDtcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgcGFyc2VVcmxGcmFnbWVudCh2YWx1ZSwgZGVsaW1pdGVyID0gXCIjXCIsIGdsb2JhbCA9IEdsb2JhbCkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKXtcclxuICAgICAgICAgICAgdmFsdWUgPSBnbG9iYWwubG9jYXRpb24uaHJlZjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBpZHggPSB2YWx1ZS5sYXN0SW5kZXhPZihkZWxpbWl0ZXIpO1xyXG4gICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN1YnN0cihpZHggKyAxKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChkZWxpbWl0ZXIgPT09IFwiP1wiKSB7XHJcbiAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGRvaW5nIHF1ZXJ5LCB0aGVuIHN0cmlwIG9mZiBoYXNoIGZyYWdtZW50IGJlZm9yZSB3ZSBwYXJzZVxyXG4gICAgICAgICAgICBpZHggPSB2YWx1ZS5pbmRleE9mKCcjJyk7XHJcbiAgICAgICAgICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zdWJzdHIoMCwgaWR4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHBhcmFtcyA9IHt9LFxyXG4gICAgICAgICAgICByZWdleCA9IC8oW14mPV0rKT0oW14mXSopL2csXHJcbiAgICAgICAgICAgIG07XHJcblxyXG4gICAgICAgIHZhciBjb3VudGVyID0gMDtcclxuICAgICAgICB3aGlsZSAobSA9IHJlZ2V4LmV4ZWModmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHBhcmFtc1tkZWNvZGVVUklDb21wb25lbnQobVsxXSldID0gZGVjb2RlVVJJQ29tcG9uZW50KG1bMl0pO1xyXG4gICAgICAgICAgICBpZiAoY291bnRlcisrID4gNTApIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVybFV0aWxpdHkucGFyc2VVcmxGcmFnbWVudDogcmVzcG9uc2UgZXhjZWVkZWQgZXhwZWN0ZWQgbnVtYmVyIG9mIHBhcmFtZXRlcnNcIiwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogXCJSZXNwb25zZSBleGNlZWRlZCBleHBlY3RlZCBudW1iZXIgb2YgcGFyYW1ldGVyc1wiXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIHBhcmFtcykge1xyXG4gICAgICAgICAgICByZXR1cm4gcGFyYW1zO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHt9O1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyIHtcclxuICAgIGNvbnN0cnVjdG9yKHtpZF90b2tlbiwgc2Vzc2lvbl9zdGF0ZSwgYWNjZXNzX3Rva2VuLCByZWZyZXNoX3Rva2VuLCB0b2tlbl90eXBlLCBzY29wZSwgcHJvZmlsZSwgZXhwaXJlc19hdCwgc3RhdGV9KSB7XHJcbiAgICAgICAgdGhpcy5pZF90b2tlbiA9IGlkX3Rva2VuO1xyXG4gICAgICAgIHRoaXMuc2Vzc2lvbl9zdGF0ZSA9IHNlc3Npb25fc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY2Nlc3NfdG9rZW4gPSBhY2Nlc3NfdG9rZW47XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoX3Rva2VuID0gcmVmcmVzaF90b2tlbjtcclxuICAgICAgICB0aGlzLnRva2VuX3R5cGUgPSB0b2tlbl90eXBlO1xyXG4gICAgICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcclxuICAgICAgICB0aGlzLnByb2ZpbGUgPSBwcm9maWxlO1xyXG4gICAgICAgIHRoaXMuZXhwaXJlc19hdCA9IGV4cGlyZXNfYXQ7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBleHBpcmVzX2luKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmV4cGlyZXNfYXQpIHtcclxuICAgICAgICAgICAgbGV0IG5vdyA9IHBhcnNlSW50KERhdGUubm93KCkgLyAxMDAwKTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhwaXJlc19hdCAtIG5vdztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIHNldCBleHBpcmVzX2luKHZhbHVlKSB7XHJcbiAgICAgICAgbGV0IGV4cGlyZXNfaW4gPSBwYXJzZUludCh2YWx1ZSk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBleHBpcmVzX2luID09PSAnbnVtYmVyJyAmJiBleHBpcmVzX2luID4gMCkge1xyXG4gICAgICAgICAgICBsZXQgbm93ID0gcGFyc2VJbnQoRGF0ZS5ub3coKSAvIDEwMDApO1xyXG4gICAgICAgICAgICB0aGlzLmV4cGlyZXNfYXQgPSBub3cgKyBleHBpcmVzX2luO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXhwaXJlZCgpIHtcclxuICAgICAgICBsZXQgZXhwaXJlc19pbiA9IHRoaXMuZXhwaXJlc19pbjtcclxuICAgICAgICBpZiAoZXhwaXJlc19pbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBleHBpcmVzX2luIDw9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHNjb3BlcygpIHtcclxuICAgICAgICByZXR1cm4gKHRoaXMuc2NvcGUgfHwgXCJcIikuc3BsaXQoXCIgXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHRvU3RvcmFnZVN0cmluZygpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLnRvU3RvcmFnZVN0cmluZ1wiKTtcclxuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoe1xyXG4gICAgICAgICAgICBpZF90b2tlbjogdGhpcy5pZF90b2tlbixcclxuICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogdGhpcy5zZXNzaW9uX3N0YXRlLFxyXG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46IHRoaXMuYWNjZXNzX3Rva2VuLFxyXG4gICAgICAgICAgICByZWZyZXNoX3Rva2VuOiB0aGlzLnJlZnJlc2hfdG9rZW4sXHJcbiAgICAgICAgICAgIHRva2VuX3R5cGU6IHRoaXMudG9rZW5fdHlwZSxcclxuICAgICAgICAgICAgc2NvcGU6IHRoaXMuc2NvcGUsXHJcbiAgICAgICAgICAgIHByb2ZpbGU6IHRoaXMucHJvZmlsZSxcclxuICAgICAgICAgICAgZXhwaXJlc19hdDogdGhpcy5leHBpcmVzX2F0XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhdGljIGZyb21TdG9yYWdlU3RyaW5nKHN0b3JhZ2VTdHJpbmcpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyLmZyb21TdG9yYWdlU3RyaW5nXCIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgVXNlcihKU09OLnBhcnNlKHN0b3JhZ2VTdHJpbmcpKTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBKc29uU2VydmljZSB9IGZyb20gJy4vSnNvblNlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBNZXRhZGF0YVNlcnZpY2UgfSBmcm9tICcuL01ldGFkYXRhU2VydmljZS5qcyc7XHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgSm9zZVV0aWwgfSBmcm9tICcuL0pvc2VVdGlsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VySW5mb1NlcnZpY2Uge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgc2V0dGluZ3MsIFxyXG4gICAgICAgIEpzb25TZXJ2aWNlQ3RvciA9IEpzb25TZXJ2aWNlLCBcclxuICAgICAgICBNZXRhZGF0YVNlcnZpY2VDdG9yID0gTWV0YWRhdGFTZXJ2aWNlLCBcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuICAgICAgICBpZiAoIXNldHRpbmdzKSB7XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5jdG9yOiBObyBzZXR0aW5ncyBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInNldHRpbmdzXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc2V0dGluZ3MgPSBzZXR0aW5ncztcclxuICAgICAgICB0aGlzLl9qc29uU2VydmljZSA9IG5ldyBKc29uU2VydmljZUN0b3IodW5kZWZpbmVkLCB1bmRlZmluZWQsIHRoaXMuX2dldENsYWltc0Zyb21Kd3QuYmluZCh0aGlzKSk7XHJcbiAgICAgICAgdGhpcy5fbWV0YWRhdGFTZXJ2aWNlID0gbmV3IE1ldGFkYXRhU2VydmljZUN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX2pvc2VVdGlsID0gam9zZVV0aWw7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0Q2xhaW1zKHRva2VuKSB7XHJcbiAgICAgICAgaWYgKCF0b2tlbikge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBObyB0b2tlbiBwYXNzZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJBIHRva2VuIGlzIHJlcXVpcmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0VXNlckluZm9FbmRwb2ludCgpLnRoZW4odXJsID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLmdldENsYWltczogcmVjZWl2ZWQgdXNlcmluZm8gdXJsXCIsIHVybCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fanNvblNlcnZpY2UuZ2V0SnNvbih1cmwsIHRva2VuKS50aGVuKGNsYWltcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuZ2V0Q2xhaW1zOiBjbGFpbXMgcmVjZWl2ZWRcIiwgY2xhaW1zKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjbGFpbXM7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9nZXRDbGFpbXNGcm9tSnd0KHJlcSkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGxldCBqd3QgPSB0aGlzLl9qb3NlVXRpbC5wYXJzZUp3dChyZXEucmVzcG9uc2VUZXh0KTtcclxuICAgICAgICAgICAgaWYgKCFqd3QgfHwgIWp3dC5oZWFkZXIgfHwgIWp3dC5wYXlsb2FkKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEZhaWxlZCB0byBwYXJzZSBKV1RcIiwgand0KTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJGYWlsZWQgdG8gcGFyc2UgaWRfdG9rZW5cIikpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIga2lkID0gand0LmhlYWRlci5raWQ7XHJcblxyXG4gICAgICAgICAgICBsZXQgaXNzdWVyUHJvbWlzZTtcclxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcikge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnT1AnOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSB0aGlzLl9tZXRhZGF0YVNlcnZpY2UuZ2V0SXNzdWVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlICdBTlknOlxyXG4gICAgICAgICAgICAgICAgICAgIGlzc3VlclByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoand0LnBheWxvYWQuaXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaXNzdWVyUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh0aGlzLl9zZXR0aW5ncy51c2VySW5mb0p3dElzc3Vlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBpc3N1ZXJQcm9taXNlLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgaXNzdWVyOlwiICsgaXNzdWVyKTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldFNpZ25pbmdLZXlzKCkudGhlbihrZXlzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWtleXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlckluZm9TZXJ2aWNlLl9nZXRDbGFpbXNGcm9tSnd0OiBObyBzaWduaW5nIGtleXMgZnJvbSBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpZ25pbmcga2V5cyBmcm9tIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogUmVjZWl2ZWQgc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFraWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAga2V5cyA9IHRoaXMuX2ZpbHRlckJ5QWxnKGtleXMsIGp3dC5oZWFkZXIuYWxnKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2lkIGZvdW5kIGluIGlkX3Rva2VuIGFuZCBtb3JlIHRoYW4gb25lIGtleSBmb3VuZCBpbiBtZXRhZGF0YVwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBraWQgZm91bmQgaW4gaWRfdG9rZW4gYW5kIG1vcmUgdGhhbiBvbmUga2V5IGZvdW5kIGluIG1ldGFkYXRhXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGtpZCBpcyBtYW5kYXRvcnkgb25seSB3aGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBrZXlzIGluIHRoZSByZWZlcmVuY2VkIEpXSyBTZXQgZG9jdW1lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlZSBodHRwOi8vb3BlbmlkLm5ldC9zcGVjcy9vcGVuaWQtY29ubmVjdC1jb3JlLTFfMC5odG1sI1NpZ25pbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ga2V5LmtpZCA9PT0ga2lkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVswXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgha2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJJbmZvU2VydmljZS5fZ2V0Q2xhaW1zRnJvbUp3dDogTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8ga2V5IG1hdGNoaW5nIGtpZCBvciBhbGcgZm91bmQgaW4gc2lnbmluZyBrZXlzXCIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxldCBhdWRpZW5jZSA9IHRoaXMuX3NldHRpbmdzLmNsaWVudF9pZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNsb2NrU2tld0luU2Vjb25kcyA9IHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldztcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IFZhbGlkYWluZyBKV1Q7IHVzaW5nIGNsb2NrIHNrZXcgKGluIHNlY29uZHMpIG9mOiBcIiwgY2xvY2tTa2V3SW5TZWNvbmRzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0KHJlcS5yZXNwb25zZVRleHQsIGtleSwgaXNzdWVyLCBhdWRpZW5jZSwgY2xvY2tTa2V3SW5TZWNvbmRzLCB1bmRlZmluZWQsIHRydWUpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEpXVCB2YWxpZGF0aW9uIHN1Y2Nlc3NmdWxcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBqd3QucGF5bG9hZDtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VySW5mb1NlcnZpY2UuX2dldENsYWltc0Zyb21Kd3Q6IEVycm9yIHBhcnNpbmcgSldUIHJlc3BvbnNlXCIsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIHJlamVjdChlKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZmlsdGVyQnlBbGcoa2V5cywgYWxnKSB7XHJcbiAgICAgICAgdmFyIGt0eSA9IG51bGw7XHJcbiAgICAgICAgaWYgKGFsZy5zdGFydHNXaXRoKFwiUlNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJSU0FcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoYWxnLnN0YXJ0c1dpdGgoXCJQU1wiKSkge1xyXG4gICAgICAgICAgICBrdHkgPSBcIlBTXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGFsZy5zdGFydHNXaXRoKFwiRVNcIikpIHtcclxuICAgICAgICAgICAga3R5ID0gXCJFQ1wiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlckluZm9TZXJ2aWNlLl9maWx0ZXJCeUFsZzogYWxnIG5vdCBzdXBwb3J0ZWQ6IFwiLCBhbGcpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VySW5mb1NlcnZpY2UuX2ZpbHRlckJ5QWxnOiBMb29raW5nIGZvciBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5KTtcclxuXHJcbiAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGtleSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiBrZXkua3R5ID09PSBrdHk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJJbmZvU2VydmljZS5fZmlsdGVyQnlBbGc6IE51bWJlciBvZiBrZXlzIHRoYXQgbWF0Y2gga3R5OiBcIiwga3R5LCBrZXlzLmxlbmd0aCk7XHJcblxyXG4gICAgICAgIHJldHVybiBrZXlzO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudCB9IGZyb20gJy4vT2lkY0NsaWVudC5qcyc7XHJcbmltcG9ydCB7IFVzZXJNYW5hZ2VyU2V0dGluZ3MgfSBmcm9tICcuL1VzZXJNYW5hZ2VyU2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi9Vc2VyLmpzJztcclxuaW1wb3J0IHsgVXNlck1hbmFnZXJFdmVudHMgfSBmcm9tICcuL1VzZXJNYW5hZ2VyRXZlbnRzLmpzJztcclxuaW1wb3J0IHsgU2lsZW50UmVuZXdTZXJ2aWNlIH0gZnJvbSAnLi9TaWxlbnRSZW5ld1NlcnZpY2UuanMnO1xyXG5pbXBvcnQgeyBTZXNzaW9uTW9uaXRvciB9IGZyb20gJy4vU2Vzc2lvbk1vbml0b3IuanMnO1xyXG5pbXBvcnQgeyBUb2tlblJldm9jYXRpb25DbGllbnQgfSBmcm9tICcuL1Rva2VuUmV2b2NhdGlvbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IFRva2VuQ2xpZW50IH0gZnJvbSAnLi9Ub2tlbkNsaWVudC5qcyc7XHJcbmltcG9ydCB7IEpvc2VVdGlsIH0gZnJvbSAnLi9Kb3NlVXRpbC5qcyc7XHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFVzZXJNYW5hZ2VyIGV4dGVuZHMgT2lkY0NsaWVudCB7XHJcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncyA9IHt9LFxyXG4gICAgICAgIFNpbGVudFJlbmV3U2VydmljZUN0b3IgPSBTaWxlbnRSZW5ld1NlcnZpY2UsXHJcbiAgICAgICAgU2Vzc2lvbk1vbml0b3JDdG9yID0gU2Vzc2lvbk1vbml0b3IsXHJcbiAgICAgICAgVG9rZW5SZXZvY2F0aW9uQ2xpZW50Q3RvciA9IFRva2VuUmV2b2NhdGlvbkNsaWVudCxcclxuICAgICAgICBUb2tlbkNsaWVudEN0b3IgPSBUb2tlbkNsaWVudCxcclxuICAgICAgICBqb3NlVXRpbCA9IEpvc2VVdGlsXHJcbiAgICApIHtcclxuXHJcbiAgICAgICAgaWYgKCEoc2V0dGluZ3MgaW5zdGFuY2VvZiBVc2VyTWFuYWdlclNldHRpbmdzKSkge1xyXG4gICAgICAgICAgICBzZXR0aW5ncyA9IG5ldyBVc2VyTWFuYWdlclNldHRpbmdzKHNldHRpbmdzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xyXG5cclxuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVXNlck1hbmFnZXJFdmVudHMoc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3U2VydmljZSA9IG5ldyBTaWxlbnRSZW5ld1NlcnZpY2VDdG9yKHRoaXMpO1xyXG5cclxuICAgICAgICAvLyBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczsgdGhlc2Ugc2VydmljZXMgZGVwZW5kIHVwb24gdGhlIGV2ZW50cy5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5hdXRvbWF0aWNTaWxlbnRSZW5ldykge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBhdXRvbWF0aWNTaWxlbnRSZW5ldyBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNpbGVudCByZW5ld1wiKTtcclxuICAgICAgICAgICAgdGhpcy5zdGFydFNpbGVudFJlbmV3KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5zZXR0aW5ncy5tb25pdG9yU2Vzc2lvbikge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5jdG9yOiBtb25pdG9yU2Vzc2lvbiBpcyBjb25maWd1cmVkLCBzZXR0aW5nIHVwIHNlc3Npb24gbW9uaXRvclwiKTtcclxuICAgICAgICAgICAgdGhpcy5fc2Vzc2lvbk1vbml0b3IgPSBuZXcgU2Vzc2lvbk1vbml0b3JDdG9yKHRoaXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50ID0gbmV3IFRva2VuUmV2b2NhdGlvbkNsaWVudEN0b3IodGhpcy5fc2V0dGluZ3MpO1xyXG4gICAgICAgIHRoaXMuX3Rva2VuQ2xpZW50ID0gbmV3IFRva2VuQ2xpZW50Q3Rvcih0aGlzLl9zZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fam9zZVV0aWwgPSBqb3NlVXRpbDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3JlZGlyZWN0TmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IF9wb3B1cE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZXR0aW5ncy5wb3B1cE5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfaWZyYW1lTmF2aWdhdG9yKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLmlmcmFtZU5hdmlnYXRvcjtcclxuICAgIH1cclxuICAgIGdldCBfdXNlclN0b3JlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNldHRpbmdzLnVzZXJTdG9yZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgZXZlbnRzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0VXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbG9hZFVzZXIoKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5nZXRVc2VyOiB1c2VyIGxvYWRlZFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMubG9hZCh1c2VyLCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLmdldFVzZXI6IHVzZXIgbm90IGZvdW5kIGluIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVVzZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKG51bGwpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnJlbW92ZVVzZXI6IHVzZXIgcmVtb3ZlZCBmcm9tIHN0b3JhZ2VcIik7XHJcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy51bmxvYWQoKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5SZWRpcmVjdChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpyXCI7XHJcbiAgICAgICAgbGV0IG5hdlBhcmFtcyA9IHtcclxuICAgICAgICAgICAgdXNlUmVwbGFjZVRvTmF2aWdhdGUgOiBhcmdzLnVzZVJlcGxhY2VUb05hdmlnYXRlXHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0OiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbmluUmVkaXJlY3RDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5SZWRpcmVjdENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbmluUG9wdXAoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6cFwiO1xyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnBvcHVwX3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cDogTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiTm8gcG9wdXBfcmVkaXJlY3RfdXJpIG9yIHJlZGlyZWN0X3VyaSBjb25maWd1cmVkXCIpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFyZ3MucmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pbihhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IHNpZ25pblBvcHVwIHN1Y2Nlc3NmdWwsIHNpZ25lZCBpbiBzdWI6IFwiLCB1c2VyLnByb2ZpbGUuc3ViKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluUG9wdXA6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBzaWduaW5Qb3B1cENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWduaW5DYWxsYmFjayh1cmwsIHRoaXMuX3BvcHVwTmF2aWdhdG9yKS50aGVuKHVzZXIgPT4ge1xyXG4gICAgICAgICAgICBpZiAodXNlcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIucHJvZmlsZSAmJiB1c2VyLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWduaW5Qb3B1cENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2s6IG5vIHN1YlwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgfSkuY2F0Y2goZXJyPT57XHJcbiAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLnNpZ25pblBvcHVwQ2FsbGJhY2sgZXJyb3I6IFwiICsgZXJyICYmIGVyci5tZXNzYWdlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnQoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGFyZ3MpO1xyXG5cclxuICAgICAgICBhcmdzLnJlcXVlc3RfdHlwZSA9IFwic2k6c1wiO1xyXG4gICAgICAgIC8vIGZpcnN0IGRldGVybWluZSBpZiB3ZSBoYXZlIGEgcmVmcmVzaCB0b2tlbiwgb3IgbmVlZCB0byB1c2UgaWZyYW1lXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIgJiYgdXNlci5yZWZyZXNoX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICBhcmdzLnJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlUmVmcmVzaFRva2VuKGFyZ3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYXJncy5pZF90b2tlbl9oaW50ID0gYXJncy5pZF90b2tlbl9oaW50IHx8ICh0aGlzLnNldHRpbmdzLmluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyAmJiB1c2VyICYmIHVzZXIuaWRfdG9rZW4pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHVzZXIgJiYgdGhpcy5fc2V0dGluZ3MudmFsaWRhdGVTdWJPblNpbGVudFJlbmV3KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50LCBzdWJqZWN0IHByaW9yIHRvIHNpbGVudCByZW5ldzogXCIsIHVzZXIucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MuY3VycmVudF9zdWIgPSB1c2VyLnByb2ZpbGUuc3ViO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblNpbGVudElmcmFtZShhcmdzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF91c2VSZWZyZXNoVG9rZW4oYXJncyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuQ2xpZW50LmV4Y2hhbmdlUmVmcmVzaFRva2VuKGFyZ3MpLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IE5vIHJlc3BvbnNlIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyByZXNwb25zZSByZXR1cm5lZCBmcm9tIHRva2VuIGVuZHBvaW50XCIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghcmVzdWx0LmFjY2Vzc190b2tlbikge1xyXG4gICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3VzZVJlZnJlc2hUb2tlbjogTm8gYWNjZXNzIHRva2VuIHJldHVybmVkIGZyb20gdG9rZW4gZW5kcG9pbnRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXCJObyBhY2Nlc3MgdG9rZW4gcmV0dXJuZWQgZnJvbSB0b2tlbiBlbmRwb2ludFwiKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IGlkVG9rZW5WYWxpZGF0aW9uID0gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5pZF90b2tlbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZFRva2VuVmFsaWRhdGlvbiA9IHRoaXMuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbih1c2VyLnByb2ZpbGUsIHJlc3VsdC5pZF90b2tlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWRUb2tlblZhbGlkYXRpb24udGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl91c2VSZWZyZXNoVG9rZW46IHJlZnJlc2ggdG9rZW4gcmVzcG9uc2Ugc3VjY2Vzc1wiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5pZF90b2tlbiA9IHJlc3VsdC5pZF90b2tlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSByZXN1bHQuYWNjZXNzX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VyLnJlZnJlc2hfdG9rZW4gPSByZXN1bHQucmVmcmVzaF90b2tlbiB8fCB1c2VyLnJlZnJlc2hfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXIuZXhwaXJlc19pbiA9IHJlc3VsdC5leHBpcmVzX2luO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RvcmVVc2VyKHVzZXIpLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVzZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW4ocHJvZmlsZSwgaWRfdG9rZW4pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbWV0YWRhdGFTZXJ2aWNlLmdldElzc3VlcigpLnRoZW4oaXNzdWVyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2pvc2VVdGlsLnZhbGlkYXRlSnd0QXR0cmlidXRlcyhpZF90b2tlbiwgaXNzdWVyLCB0aGlzLl9zZXR0aW5ncy5jbGllbnRfaWQsIHRoaXMuX3NldHRpbmdzLmNsb2NrU2tldykudGhlbihwYXlsb2FkID0+IHtcclxuICAgICAgICAgICAgICAgIGlmICghcGF5bG9hZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5lcnJvcihcIlVzZXJNYW5hZ2VyLl92YWxpZGF0ZUlkVG9rZW5Gcm9tVG9rZW5SZWZyZXNoVG9rZW46IEZhaWxlZCB0byB2YWxpZGF0ZSBpZF90b2tlblwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiRmFpbGVkIHRvIHZhbGlkYXRlIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChwYXlsb2FkLnN1YiAhPT0gcHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5fdmFsaWRhdGVJZFRva2VuRnJvbVRva2VuUmVmcmVzaFRva2VuOiBzdWIgaW4gaWRfdG9rZW4gZG9lcyBub3QgbWF0Y2ggY3VycmVudCBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcInN1YiBpbiBpZF90b2tlbiBkb2VzIG5vdCBtYXRjaCBjdXJyZW50IHN1YlwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5hdXRoX3RpbWUgJiYgcGF5bG9hZC5hdXRoX3RpbWUgIT09IHByb2ZpbGUuYXV0aF90aW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXV0aF90aW1lIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF1dGhfdGltZVwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGF5bG9hZC5henAgJiYgcGF5bG9hZC5henAgIT09IHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiYXpwIGluIGlkX3Rva2VuIGRvZXMgbm90IG1hdGNoIG9yaWdpbmFsIGF6cFwiKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIXBheWxvYWQuYXpwICYmIHByb2ZpbGUuYXpwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIuX3ZhbGlkYXRlSWRUb2tlbkZyb21Ub2tlblJlZnJlc2hUb2tlbjogYXpwIG5vdCBpbiBpZF90b2tlbiwgYnV0IHByZXNlbnQgaW4gb3JpZ2luYWwgaWRfdG9rZW5cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImF6cCBub3QgaW4gaWRfdG9rZW4sIGJ1dCBwcmVzZW50IGluIG9yaWdpbmFsIGlkX3Rva2VuXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIF9zaWduaW5TaWxlbnRJZnJhbWUoYXJncyA9IHt9KSB7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3Muc2lsZW50X3JlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnJlZGlyZWN0X3VyaTtcclxuICAgICAgICBpZiAoIXVybCkge1xyXG4gICAgICAgICAgICBMb2cuZXJyb3IoXCJVc2VyTWFuYWdlci5zaWduaW5TaWxlbnQ6IE5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIk5vIHNpbGVudF9yZWRpcmVjdF91cmkgY29uZmlndXJlZFwiKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhcmdzLnJlZGlyZWN0X3VyaSA9IHVybDtcclxuICAgICAgICBhcmdzLnByb21wdCA9IGFyZ3MucHJvbXB0IHx8IFwibm9uZVwiO1xyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluKGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgICAgIGlmICh1c2VyLnByb2ZpbGUgJiYgdXNlci5wcm9maWxlLnN1Yikge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbmluU2lsZW50OiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudDogbm8gc3ViXCIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdXNlcjtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBzaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluQ2FsbGJhY2sodXJsLCB0aGlzLl9pZnJhbWVOYXZpZ2F0b3IpLnRoZW4odXNlciA9PiB7XHJcbiAgICAgICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodXNlci5wcm9maWxlICYmIHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBzdWNjZXNzZnVsLCBzaWduZWQgaW4gc3ViOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25pblNpbGVudENhbGxiYWNrOiBubyBzdWJcIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25pbkNhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRTaWduaW5SZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlLnJlcXVlc3RfdHlwZSA9PT0gXCJzaTpyXCIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25pblJlZGlyZWN0Q2FsbGJhY2sodXJsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNpOnBcIikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2lnbmluUG9wdXBDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5yZXF1ZXN0X3R5cGUgPT09IFwic2k6c1wiKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zaWduaW5TaWxlbnRDYWxsYmFjayh1cmwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJpbnZhbGlkIHJlc3BvbnNlX3R5cGUgaW4gc3RhdGVcIikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRDYWxsYmFjayh1cmwsIGtlZXBPcGVuKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZFNpZ25vdXRSZXNwb25zZVN0YXRlKHVybCkudGhlbigoe3N0YXRlLCByZXNwb25zZX0pID0+IHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnJcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUucmVxdWVzdF90eXBlID09PSBcInNvOnBcIikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNpZ25vdXRQb3B1cENhbGxiYWNrKHVybCwga2VlcE9wZW4pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImludmFsaWQgcmVzcG9uc2VfdHlwZSBpbiBzdGF0ZVwiKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHF1ZXJ5U2Vzc2lvblN0YXR1cyhhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzaTpzXCI7IC8vIHRoaXMgYWN0cyBsaWtlIGEgc2lnbmluIHNpbGVudFxyXG4gICAgICAgIGxldCB1cmwgPSBhcmdzLnJlZGlyZWN0X3VyaSB8fCB0aGlzLnNldHRpbmdzLnNpbGVudF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKCF1cmwpIHtcclxuICAgICAgICAgICAgTG9nLmVycm9yKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXCJObyBzaWxlbnRfcmVkaXJlY3RfdXJpIGNvbmZpZ3VyZWRcIikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYXJncy5yZWRpcmVjdF91cmkgPSB1cmw7XHJcbiAgICAgICAgYXJncy5wcm9tcHQgPSBcIm5vbmVcIjtcclxuICAgICAgICBhcmdzLnJlc3BvbnNlX3R5cGUgPSBhcmdzLnJlc3BvbnNlX3R5cGUgfHwgdGhpcy5zZXR0aW5ncy5xdWVyeV9zdGF0dXNfcmVzcG9uc2VfdHlwZTtcclxuICAgICAgICBhcmdzLnNjb3BlID0gYXJncy5zY29wZSB8fCBcIm9wZW5pZFwiO1xyXG4gICAgICAgIGFyZ3Muc2tpcFVzZXJJbmZvID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25pblN0YXJ0KGFyZ3MsIHRoaXMuX2lmcmFtZU5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dDogYXJncy5zaWxlbnRSZXF1ZXN0VGltZW91dCB8fCB0aGlzLnNldHRpbmdzLnNpbGVudFJlcXVlc3RUaW1lb3V0XHJcbiAgICAgICAgfSkudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZShuYXZSZXNwb25zZS51cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucXVlcnlTZXNzaW9uU3RhdHVzOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChzaWduaW5SZXNwb25zZS5zZXNzaW9uX3N0YXRlICYmIHNpZ25pblJlc3BvbnNlLnByb2ZpbGUuc3ViKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5xdWVyeVNlc3Npb25TdGF0dXM6IHF1ZXJ5U2Vzc2lvblN0YXR1cyBzdWNjZXNzIGZvciBzdWI6IFwiLCAgc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25fc3RhdGU6IHNpZ25pblJlc3BvbnNlLnNlc3Npb25fc3RhdGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Yjogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zdWIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZDogc2lnbmluUmVzcG9uc2UucHJvZmlsZS5zaWRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmluZm8oXCJxdWVyeVNlc3Npb25TdGF0dXMgc3VjY2Vzc2Z1bCwgdXNlciBub3QgYXV0aGVudGljYXRlZFwiKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXJyLnNlc3Npb25fc3RhdGUgJiYgdGhpcy5zZXR0aW5ncy5tb25pdG9yQW5vbnltb3VzU2Vzc2lvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIubWVzc2FnZSA9PSBcImxvZ2luX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiY29uc2VudF9yZXF1aXJlZFwiIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnIubWVzc2FnZSA9PSBcImludGVyYWN0aW9uX3JlcXVpcmVkXCIgfHwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IFwiYWNjb3VudF9zZWxlY3Rpb25fcmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnF1ZXJ5U2Vzc2lvblN0YXR1czogcXVlcnlTZXNzaW9uU3RhdHVzIHN1Y2Nlc3MgZm9yIGFub255bW91cyB1c2VyXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbl9zdGF0ZTogZXJyLnNlc3Npb25fc3RhdGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbmluKGFyZ3MsIG5hdmlnYXRvciwgbmF2aWdhdG9yUGFyYW1zID0ge30pIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMpLnRoZW4obmF2UmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2lnbmluRW5kKG5hdlJlc3BvbnNlLnVybCwgYXJncyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbmluU3RhcnQoYXJncywgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG5cclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLnByZXBhcmUobmF2aWdhdG9yUGFyYW1zKS50aGVuKGhhbmRsZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5TdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2lnbmluUmVxdWVzdChhcmdzKS50aGVuKHNpZ25pblJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBnb3Qgc2lnbmluIHJlcXVlc3RcIik7XHJcblxyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLnVybCA9IHNpZ25pblJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbmluUmVxdWVzdC5zdGF0ZS5pZDtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25pblN0YXJ0OiBFcnJvciBhZnRlciBwcmVwYXJpbmcgbmF2aWdhdG9yLCBjbG9zaW5nIG5hdmlnYXRvciB3aW5kb3dcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgX3NpZ25pbkVuZCh1cmwsIGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWduaW5SZXNwb25zZSh1cmwpLnRoZW4oc2lnbmluUmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBnb3Qgc2lnbmluIHJlc3BvbnNlXCIpO1xyXG5cclxuICAgICAgICAgICAgbGV0IHVzZXIgPSBuZXcgVXNlcihzaWduaW5SZXNwb25zZSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoYXJncy5jdXJyZW50X3N1Yikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MuY3VycmVudF9zdWIgIT09IHVzZXIucHJvZmlsZS5zdWIpIHtcclxuICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbmluRW5kOiBjdXJyZW50IHVzZXIgZG9lcyBub3QgbWF0Y2ggdXNlciByZXR1cm5lZCBmcm9tIHNpZ25pbi4gc3ViIGZyb20gc2lnbmluOiBcIiwgdXNlci5wcm9maWxlLnN1Yik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcImxvZ2luX3JlcXVpcmVkXCIpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IGN1cnJlbnQgdXNlciBtYXRjaGVzIHVzZXIgcmV0dXJuZWQgZnJvbSBzaWduaW5cIik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0b3JlVXNlcih1c2VyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5FbmQ6IHVzZXIgc3RvcmVkXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5sb2FkKHVzZXIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB1c2VyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWduaW5DYWxsYmFjayh1cmwsIG5hdmlnYXRvcikge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWduaW5DYWxsYmFja1wiKTtcclxuICAgICAgICByZXR1cm4gbmF2aWdhdG9yLmNhbGxiYWNrKHVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgc2lnbm91dFJlZGlyZWN0KGFyZ3MgPSB7fSkge1xyXG4gICAgICAgIGFyZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBhcmdzKTtcclxuXHJcbiAgICAgICAgYXJncy5yZXF1ZXN0X3R5cGUgPSBcInNvOnJcIjtcclxuICAgICAgICBsZXQgcG9zdExvZ291dFJlZGlyZWN0VXJpID0gYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkgfHwgdGhpcy5zZXR0aW5ncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgaWYgKHBvc3RMb2dvdXRSZWRpcmVjdFVyaSl7XHJcbiAgICAgICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9zdExvZ291dFJlZGlyZWN0VXJpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgbmF2UGFyYW1zID0ge1xyXG4gICAgICAgICAgICB1c2VSZXBsYWNlVG9OYXZpZ2F0ZSA6IGFyZ3MudXNlUmVwbGFjZVRvTmF2aWdhdGVcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0U3RhcnQoYXJncywgdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3IsIG5hdlBhcmFtcykudGhlbigoKT0+e1xyXG4gICAgICAgICAgICBMb2cuaW5mbyhcIlVzZXJNYW5hZ2VyLnNpZ25vdXRSZWRpcmVjdDogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHNpZ25vdXRSZWRpcmVjdENhbGxiYWNrKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKHVybCB8fCB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvci51cmwpLnRoZW4ocmVzcG9uc2U9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UmVkaXJlY3RDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHNpZ25vdXRQb3B1cChhcmdzID0ge30pIHtcclxuICAgICAgICBhcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgYXJncyk7XHJcblxyXG4gICAgICAgIGFyZ3MucmVxdWVzdF90eXBlID0gXCJzbzpwXCI7XHJcbiAgICAgICAgbGV0IHVybCA9IGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpIHx8IHRoaXMuc2V0dGluZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIGFyZ3MucG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gdXJsO1xyXG4gICAgICAgIGFyZ3MuZGlzcGxheSA9IFwicG9wdXBcIjtcclxuICAgICAgICBpZiAoYXJncy5wb3N0X2xvZ291dF9yZWRpcmVjdF91cmkpe1xyXG4gICAgICAgICAgICAvLyB3ZSdyZSBwdXR0aW5nIGEgZHVtbXkgZW50cnkgaW4gaGVyZSBiZWNhdXNlIHdlXHJcbiAgICAgICAgICAgIC8vIG5lZWQgYSB1bmlxdWUgaWQgZnJvbSB0aGUgc3RhdGUgZm9yIG5vdGlmaWNhdGlvblxyXG4gICAgICAgICAgICAvLyB0byB0aGUgcGFyZW50IHdpbmRvdywgd2hpY2ggaXMgbmVjZXNzYXJ5IGlmIHdlXHJcbiAgICAgICAgICAgIC8vIHBsYW4gdG8gcmV0dXJuIGJhY2sgdG8gdGhlIGNsaWVudCBhZnRlciBzaWdub3V0XHJcbiAgICAgICAgICAgIC8vIGFuZCBzbyB3ZSBjYW4gY2xvc2UgdGhlIHBvcHVwIGFmdGVyIHNpZ25vdXRcclxuICAgICAgICAgICAgYXJncy5zdGF0ZSA9IGFyZ3Muc3RhdGUgfHwge307XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lnbm91dChhcmdzLCB0aGlzLl9wb3B1cE5hdmlnYXRvciwge1xyXG4gICAgICAgICAgICBzdGFydFVybDogdXJsLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd0ZlYXR1cmVzOiBhcmdzLnBvcHVwV2luZG93RmVhdHVyZXMgfHwgdGhpcy5zZXR0aW5ncy5wb3B1cFdpbmRvd0ZlYXR1cmVzLFxyXG4gICAgICAgICAgICBwb3B1cFdpbmRvd1RhcmdldDogYXJncy5wb3B1cFdpbmRvd1RhcmdldCB8fCB0aGlzLnNldHRpbmdzLnBvcHVwV2luZG93VGFyZ2V0XHJcbiAgICAgICAgfSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5pbmZvKFwiVXNlck1hbmFnZXIuc2lnbm91dFBvcHVwOiBzdWNjZXNzZnVsXCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgc2lnbm91dFBvcHVwQ2FsbGJhY2sodXJsLCBrZWVwT3Blbikge1xyXG4gICAgICAgIGlmICh0eXBlb2Yoa2VlcE9wZW4pID09PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YodXJsKSA9PT0gJ2Jvb2xlYW4nKSB7XHJcbiAgICAgICAgICAgIGtlZXBPcGVuID0gdXJsO1xyXG4gICAgICAgICAgICB1cmwgPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGRlbGltaXRlciA9ICc/JztcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBOYXZpZ2F0b3IuY2FsbGJhY2sodXJsLCBrZWVwT3BlbiwgZGVsaW1pdGVyKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5zaWdub3V0UG9wdXBDYWxsYmFjazogc3VjY2Vzc2Z1bFwiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBfc2lnbm91dChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcyA9IHt9KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25vdXRTdGFydChhcmdzLCBuYXZpZ2F0b3IsIG5hdmlnYXRvclBhcmFtcykudGhlbihuYXZSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zaWdub3V0RW5kKG5hdlJlc3BvbnNlLnVybCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBfc2lnbm91dFN0YXJ0KGFyZ3MgPSB7fSwgbmF2aWdhdG9yLCBuYXZpZ2F0b3JQYXJhbXMgPSB7fSkge1xyXG4gICAgICAgIHJldHVybiBuYXZpZ2F0b3IucHJlcGFyZShuYXZpZ2F0b3JQYXJhbXMpLnRoZW4oaGFuZGxlID0+IHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IG5hdmlnYXRvciB3aW5kb3cgaGFuZGxlXCIpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IGxvYWRlZCBjdXJyZW50IHVzZXIgZnJvbSBzdG9yYWdlXCIpO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciByZXZva2VQcm9taXNlID0gdGhpcy5fc2V0dGluZ3MucmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQgPyB0aGlzLl9yZXZva2VJbnRlcm5hbCh1c2VyKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldm9rZVByb21pc2UudGhlbigoKSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZF90b2tlbiA9IGFyZ3MuaWRfdG9rZW5faGludCB8fCB1c2VyICYmIHVzZXIuaWRfdG9rZW47XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkX3Rva2VuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0U3RhcnQ6IFNldHRpbmcgaWRfdG9rZW4gaW50byBzaWdub3V0IHJlcXVlc3RcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MuaWRfdG9rZW5faGludCA9IGlkX3Rva2VuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlVXNlcigpLnRoZW4oKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fc2lnbm91dFN0YXJ0OiB1c2VyIHJlbW92ZWQsIGNyZWF0aW5nIHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVNpZ25vdXRSZXF1ZXN0KGFyZ3MpLnRoZW4oc2lnbm91dFJlcXVlc3QgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogZ290IHNpZ25vdXQgcmVxdWVzdFwiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXZpZ2F0b3JQYXJhbXMudXJsID0gc2lnbm91dFJlcXVlc3QudXJsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNpZ25vdXRSZXF1ZXN0LnN0YXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yUGFyYW1zLmlkID0gc2lnbm91dFJlcXVlc3Quc3RhdGUuaWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlLm5hdmlnYXRlKG5hdmlnYXRvclBhcmFtcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlLmNsb3NlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX3NpZ25vdXRTdGFydDogRXJyb3IgYWZ0ZXIgcHJlcGFyaW5nIG5hdmlnYXRvciwgY2xvc2luZyBuYXZpZ2F0b3Igd2luZG93XCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZS5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIF9zaWdub3V0RW5kKHVybCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnByb2Nlc3NTaWdub3V0UmVzcG9uc2UodXJsKS50aGVuKHNpZ25vdXRSZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLl9zaWdub3V0RW5kOiBnb3Qgc2lnbm91dCByZXNwb25zZVwiKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBzaWdub3V0UmVzcG9uc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV2b2tlQWNjZXNzVG9rZW4oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRVc2VyKCkudGhlbih1c2VyID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUludGVybmFsKHVzZXIsIHRydWUpLnRoZW4oc3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc3VjY2Vzcykge1xyXG4gICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiByZW1vdmluZyB0b2tlbiBwcm9wZXJ0aWVzIGZyb20gdXNlciBhbmQgcmUtc3RvcmluZ1wiKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5hY2Nlc3NfdG9rZW4gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHVzZXIucmVmcmVzaF90b2tlbiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdXNlci5leHBpcmVzX2F0ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB1c2VyLnRva2VuX3R5cGUgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zdG9yZVVzZXIodXNlcikudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyLnJldm9rZUFjY2Vzc1Rva2VuOiB1c2VyIHN0b3JlZFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmxvYWQodXNlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pLnRoZW4oKCk9PntcclxuICAgICAgICAgICAgTG9nLmluZm8oXCJVc2VyTWFuYWdlci5yZXZva2VBY2Nlc3NUb2tlbjogYWNjZXNzIHRva2VuIHJldm9rZWQgc3VjY2Vzc2Z1bGx5XCIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIF9yZXZva2VJbnRlcm5hbCh1c2VyLCByZXF1aXJlZCkge1xyXG4gICAgICAgIGlmICh1c2VyKSB7XHJcbiAgICAgICAgICAgIHZhciBhY2Nlc3NfdG9rZW4gPSB1c2VyLmFjY2Vzc190b2tlbjtcclxuICAgICAgICAgICAgdmFyIHJlZnJlc2hfdG9rZW4gPSB1c2VyLnJlZnJlc2hfdG9rZW47XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oYXRTdWNjZXNzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKHJ0U3VjY2VzcyA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWF0U3VjY2VzcyAmJiAhcnRTdWNjZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIucmV2b2tlQWNjZXNzVG9rZW46IG5vIG5lZWQgdG8gcmV2b2tlIGR1ZSB0byBubyB0b2tlbihzKSwgb3IgSldUIGZvcm1hdFwiKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0U3VjY2VzcyB8fCBydFN1Y2Nlc3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlQWNjZXNzVG9rZW5JbnRlcm5hbChhY2Nlc3NfdG9rZW4sIHJlcXVpcmVkKSB7XHJcbiAgICAgICAgLy8gY2hlY2sgZm9yIEpXVCB2cy4gcmVmZXJlbmNlIHRva2VuXHJcbiAgICAgICAgaWYgKCFhY2Nlc3NfdG9rZW4gfHwgYWNjZXNzX3Rva2VuLmluZGV4T2YoJy4nKSA+PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuUmV2b2NhdGlvbkNsaWVudC5yZXZva2UoYWNjZXNzX3Rva2VuLCByZXF1aXJlZCkudGhlbigoKSA9PiB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICBfcmV2b2tlUmVmcmVzaFRva2VuSW50ZXJuYWwocmVmcmVzaF90b2tlbiwgcmVxdWlyZWQpIHtcclxuICAgICAgICBpZiAoIXJlZnJlc2hfdG9rZW4pIHtcclxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9rZW5SZXZvY2F0aW9uQ2xpZW50LnJldm9rZShyZWZyZXNoX3Rva2VuLCByZXF1aXJlZCwgXCJyZWZyZXNoX3Rva2VuXCIpLnRoZW4oKCkgPT4gdHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgc3RhcnRTaWxlbnRSZW5ldygpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld1NlcnZpY2Uuc3RhcnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBzdG9wU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdTZXJ2aWNlLnN0b3AoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgX3VzZXJTdG9yZUtleSgpIHtcclxuICAgICAgICByZXR1cm4gYHVzZXI6JHt0aGlzLnNldHRpbmdzLmF1dGhvcml0eX06JHt0aGlzLnNldHRpbmdzLmNsaWVudF9pZH1gO1xyXG4gICAgfVxyXG5cclxuICAgIF9sb2FkVXNlcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLmdldCh0aGlzLl91c2VyU3RvcmVLZXkpLnRoZW4oc3RvcmFnZVN0cmluZyA9PiB7XHJcbiAgICAgICAgICAgIGlmIChzdG9yYWdlU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlci5fbG9hZFVzZXI6IHVzZXIgc3RvcmFnZVN0cmluZyBsb2FkZWRcIik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gVXNlci5mcm9tU3RvcmFnZVN0cmluZyhzdG9yYWdlU3RyaW5nKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuX2xvYWRVc2VyOiBubyB1c2VyIHN0b3JhZ2VTdHJpbmdcIik7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHN0b3JlVXNlcih1c2VyKSB7XHJcbiAgICAgICAgaWYgKHVzZXIpIHtcclxuICAgICAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXIuc3RvcmVVc2VyOiBzdG9yaW5nIHVzZXJcIik7XHJcblxyXG4gICAgICAgICAgICB2YXIgc3RvcmFnZVN0cmluZyA9IHVzZXIudG9TdG9yYWdlU3RyaW5nKCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl91c2VyU3RvcmUuc2V0KHRoaXMuX3VzZXJTdG9yZUtleSwgc3RvcmFnZVN0cmluZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBMb2cuZGVidWcoXCJzdG9yZVVzZXIuc3RvcmVVc2VyOiByZW1vdmluZyB1c2VyXCIpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdXNlclN0b3JlLnJlbW92ZSh0aGlzLl91c2VyU3RvcmVLZXkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEFjY2Vzc1Rva2VuRXZlbnRzIH0gZnJvbSAnLi9BY2Nlc3NUb2tlbkV2ZW50cy5qcyc7XHJcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudC5qcyc7XHJcblxyXG5leHBvcnQgY2xhc3MgVXNlck1hbmFnZXJFdmVudHMgZXh0ZW5kcyBBY2Nlc3NUb2tlbkV2ZW50cyB7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcclxuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgbG9hZGVkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZCA9IG5ldyBFdmVudChcIlVzZXIgdW5sb2FkZWRcIik7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvciA9IG5ldyBFdmVudChcIlNpbGVudCByZW5ldyBlcnJvclwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4gPSBuZXcgRXZlbnQoXCJVc2VyIHNpZ25lZCBpblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0ID0gbmV3IEV2ZW50KFwiVXNlciBzaWduZWQgb3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZCA9IG5ldyBFdmVudChcIlVzZXIgc2Vzc2lvbiBjaGFuZ2VkXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGxvYWQodXNlciwgcmFpc2VFdmVudD10cnVlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMubG9hZFwiKTtcclxuICAgICAgICBzdXBlci5sb2FkKHVzZXIpO1xyXG4gICAgICAgIGlmIChyYWlzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3VzZXJMb2FkZWQucmFpc2UodXNlcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdW5sb2FkKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLnVubG9hZFwiKTtcclxuICAgICAgICBzdXBlci51bmxvYWQoKTtcclxuICAgICAgICB0aGlzLl91c2VyVW5sb2FkZWQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyTG9hZGVkKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlckxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJMb2FkZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyTG9hZGVkLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZFVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJVbmxvYWRlZChjYikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJVbmxvYWRlZC5yZW1vdmVIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRTaWxlbnRSZW5ld0Vycm9yKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fc2lsZW50UmVuZXdFcnJvci5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVNpbGVudFJlbmV3RXJyb3IoY2IpIHtcclxuICAgICAgICB0aGlzLl9zaWxlbnRSZW5ld0Vycm9yLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlU2lsZW50UmVuZXdFcnJvcihlKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlU2lsZW50UmVuZXdFcnJvclwiLCBlLm1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlbmV3RXJyb3IucmFpc2UoZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLmFkZEhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgcmVtb3ZlVXNlclNpZ25lZEluKGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZEluLnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZEluKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIlVzZXJNYW5hZ2VyRXZlbnRzLl9yYWlzZVVzZXJTaWduZWRJblwiKTtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkSW4ucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2lnbmVkT3V0KGNiKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNpZ25lZE91dC5hZGRIYW5kbGVyKGNiKTtcclxuICAgIH1cclxuICAgIHJlbW92ZVVzZXJTaWduZWRPdXQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2lnbmVkT3V0LnJlbW92ZUhhbmRsZXIoY2IpO1xyXG4gICAgfVxyXG4gICAgX3JhaXNlVXNlclNpZ25lZE91dCgpIHtcclxuICAgICAgICBMb2cuZGVidWcoXCJVc2VyTWFuYWdlckV2ZW50cy5fcmFpc2VVc2VyU2lnbmVkT3V0XCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTaWduZWRPdXQucmFpc2UoKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGRVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQuYWRkSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICByZW1vdmVVc2VyU2Vzc2lvbkNoYW5nZWQoY2IpIHtcclxuICAgICAgICB0aGlzLl91c2VyU2Vzc2lvbkNoYW5nZWQucmVtb3ZlSGFuZGxlcihjYik7XHJcbiAgICB9XHJcbiAgICBfcmFpc2VVc2VyU2Vzc2lvbkNoYW5nZWQoKSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiVXNlck1hbmFnZXJFdmVudHMuX3JhaXNlVXNlclNlc3Npb25DaGFuZ2VkXCIpO1xyXG4gICAgICAgIHRoaXMuX3VzZXJTZXNzaW9uQ2hhbmdlZC5yYWlzZSgpO1xyXG4gICAgfVxyXG59XHJcbiIsIi8vIENvcHlyaWdodCAoYykgQnJvY2sgQWxsZW4gJiBEb21pbmljayBCYWllci4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC4gU2VlIExJQ0VOU0UgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbmltcG9ydCB7IExvZyB9IGZyb20gJy4vTG9nLmpzJztcclxuaW1wb3J0IHsgT2lkY0NsaWVudFNldHRpbmdzIH0gZnJvbSAnLi9PaWRjQ2xpZW50U2V0dGluZ3MuanMnO1xyXG5pbXBvcnQgeyBSZWRpcmVjdE5hdmlnYXRvciB9IGZyb20gJy4vUmVkaXJlY3ROYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBQb3B1cE5hdmlnYXRvciB9IGZyb20gJy4vUG9wdXBOYXZpZ2F0b3IuanMnO1xyXG5pbXBvcnQgeyBJRnJhbWVOYXZpZ2F0b3IgfSBmcm9tICcuL0lGcmFtZU5hdmlnYXRvci5qcyc7XHJcbmltcG9ydCB7IFdlYlN0b3JhZ2VTdGF0ZVN0b3JlIH0gZnJvbSAnLi9XZWJTdG9yYWdlU3RhdGVTdG9yZS5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuaW1wb3J0IHsgU2lnbmluUmVxdWVzdCB9IGZyb20gJy4vU2lnbmluUmVxdWVzdC5qcyc7XHJcblxyXG5jb25zdCBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSA2MDtcclxuY29uc3QgRGVmYXVsdENoZWNrU2Vzc2lvbkludGVydmFsID0gMjAwMDtcclxuXHJcbmV4cG9ydCBjbGFzcyBVc2VyTWFuYWdlclNldHRpbmdzIGV4dGVuZHMgT2lkY0NsaWVudFNldHRpbmdzIHtcclxuICAgIGNvbnN0cnVjdG9yKHtcclxuICAgICAgICBwb3B1cF9yZWRpcmVjdF91cmksXHJcbiAgICAgICAgcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpLFxyXG4gICAgICAgIHBvcHVwV2luZG93RmVhdHVyZXMsXHJcbiAgICAgICAgcG9wdXBXaW5kb3dUYXJnZXQsXHJcbiAgICAgICAgc2lsZW50X3JlZGlyZWN0X3VyaSxcclxuICAgICAgICBzaWxlbnRSZXF1ZXN0VGltZW91dCxcclxuICAgICAgICBhdXRvbWF0aWNTaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldyA9IGZhbHNlLFxyXG4gICAgICAgIGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldyA9IHRydWUsXHJcbiAgICAgICAgbW9uaXRvclNlc3Npb24gPSB0cnVlLFxyXG4gICAgICAgIG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uID0gZmFsc2UsXHJcbiAgICAgICAgY2hlY2tTZXNzaW9uSW50ZXJ2YWwgPSBEZWZhdWx0Q2hlY2tTZXNzaW9uSW50ZXJ2YWwsXHJcbiAgICAgICAgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IgPSB0cnVlLFxyXG4gICAgICAgIHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlLFxyXG4gICAgICAgIHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0ID0gZmFsc2UsXHJcbiAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUgPSBEZWZhdWx0QWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWUsXHJcbiAgICAgICAgcmVkaXJlY3ROYXZpZ2F0b3IgPSBuZXcgUmVkaXJlY3ROYXZpZ2F0b3IoKSxcclxuICAgICAgICBwb3B1cE5hdmlnYXRvciA9IG5ldyBQb3B1cE5hdmlnYXRvcigpLFxyXG4gICAgICAgIGlmcmFtZU5hdmlnYXRvciA9IG5ldyBJRnJhbWVOYXZpZ2F0b3IoKSxcclxuICAgICAgICB1c2VyU3RvcmUgPSBuZXcgV2ViU3RvcmFnZVN0YXRlU3RvcmUoeyBzdG9yZTogR2xvYmFsLnNlc3Npb25TdG9yYWdlIH0pXHJcbiAgICB9ID0ge30pIHtcclxuICAgICAgICBzdXBlcihhcmd1bWVudHNbMF0pO1xyXG5cclxuICAgICAgICB0aGlzLl9wb3B1cF9yZWRpcmVjdF91cmkgPSBwb3B1cF9yZWRpcmVjdF91cmk7XHJcbiAgICAgICAgdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpID0gcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXMgPSBwb3B1cFdpbmRvd0ZlYXR1cmVzO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0ID0gcG9wdXBXaW5kb3dUYXJnZXQ7XHJcblxyXG4gICAgICAgIHRoaXMuX3NpbGVudF9yZWRpcmVjdF91cmkgPSBzaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgICAgIHRoaXMuX3NpbGVudFJlcXVlc3RUaW1lb3V0ID0gc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICAgICAgdGhpcy5fYXV0b21hdGljU2lsZW50UmVuZXcgPSBhdXRvbWF0aWNTaWxlbnRSZW5ldztcclxuICAgICAgICB0aGlzLl92YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXcgPSB2YWxpZGF0ZVN1Yk9uU2lsZW50UmVuZXc7XHJcbiAgICAgICAgdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3ID0gaW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgICAgIHRoaXMuX2FjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lID0gYWNjZXNzVG9rZW5FeHBpcmluZ05vdGlmaWNhdGlvblRpbWU7XHJcblxyXG4gICAgICAgIHRoaXMuX21vbml0b3JTZXNzaW9uID0gbW9uaXRvclNlc3Npb247XHJcbiAgICAgICAgdGhpcy5fbW9uaXRvckFub255bW91c1Nlc3Npb24gPSBtb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgICAgICB0aGlzLl9jaGVja1Nlc3Npb25JbnRlcnZhbCA9IGNoZWNrU2Vzc2lvbkludGVydmFsO1xyXG4gICAgICAgIHRoaXMuX3N0b3BDaGVja1Nlc3Npb25PbkVycm9yID0gc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICAgICAgaWYgKHF1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICAgICAgfSBcclxuICAgICAgICBlbHNlIGlmIChhcmd1bWVudHNbMF0gJiYgYXJndW1lbnRzWzBdLnJlc3BvbnNlX3R5cGUpIHtcclxuICAgICAgICAgICAgdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUgPSBTaWduaW5SZXF1ZXN0LmlzT2lkYyhhcmd1bWVudHNbMF0ucmVzcG9uc2VfdHlwZSkgPyBcImlkX3Rva2VuXCIgOiBcImNvZGVcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3F1ZXJ5X3N0YXR1c19yZXNwb25zZV90eXBlID0gXCJpZF90b2tlblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9yZXZva2VBY2Nlc3NUb2tlbk9uU2lnbm91dCA9IHJldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG5cclxuICAgICAgICB0aGlzLl9yZWRpcmVjdE5hdmlnYXRvciA9IHJlZGlyZWN0TmF2aWdhdG9yO1xyXG4gICAgICAgIHRoaXMuX3BvcHVwTmF2aWdhdG9yID0gcG9wdXBOYXZpZ2F0b3I7XHJcbiAgICAgICAgdGhpcy5faWZyYW1lTmF2aWdhdG9yID0gaWZyYW1lTmF2aWdhdG9yO1xyXG5cclxuICAgICAgICB0aGlzLl91c2VyU3RvcmUgPSB1c2VyU3RvcmU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHBvcHVwX3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwX3Bvc3RfbG9nb3V0X3JlZGlyZWN0X3VyaSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcG9wdXBfcG9zdF9sb2dvdXRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgZ2V0IHBvcHVwV2luZG93RmVhdHVyZXMoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93RmVhdHVyZXM7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBXaW5kb3dUYXJnZXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwV2luZG93VGFyZ2V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBzaWxlbnRfcmVkaXJlY3RfdXJpKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zaWxlbnRfcmVkaXJlY3RfdXJpO1xyXG4gICAgfVxyXG4gICAgIGdldCBzaWxlbnRSZXF1ZXN0VGltZW91dCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2lsZW50UmVxdWVzdFRpbWVvdXQ7XHJcbiAgICB9XHJcbiAgICBnZXQgYXV0b21hdGljU2lsZW50UmVuZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9tYXRpY1NpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IHZhbGlkYXRlU3ViT25TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVTdWJPblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGluY2x1ZGVJZFRva2VuSW5TaWxlbnRSZW5ldygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faW5jbHVkZUlkVG9rZW5JblNpbGVudFJlbmV3O1xyXG4gICAgfVxyXG4gICAgZ2V0IGFjY2Vzc1Rva2VuRXhwaXJpbmdOb3RpZmljYXRpb25UaW1lKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hY2Nlc3NUb2tlbkV4cGlyaW5nTm90aWZpY2F0aW9uVGltZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgbW9uaXRvclNlc3Npb24oKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vbml0b3JTZXNzaW9uO1xyXG4gICAgfVxyXG4gICAgZ2V0IG1vbml0b3JBbm9ueW1vdXNTZXNzaW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9tb25pdG9yQW5vbnltb3VzU2Vzc2lvbjtcclxuICAgIH1cclxuICAgIGdldCBjaGVja1Nlc3Npb25JbnRlcnZhbCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fY2hlY2tTZXNzaW9uSW50ZXJ2YWw7XHJcbiAgICB9XHJcbiAgICBnZXQgc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3IoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc3RvcENoZWNrU2Vzc2lvbk9uRXJyb3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGUoKXtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcXVlcnlfc3RhdHVzX3Jlc3BvbnNlX3R5cGU7XHJcbiAgICB9XHJcbiAgICBnZXQgcmV2b2tlQWNjZXNzVG9rZW5PblNpZ25vdXQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jldm9rZUFjY2Vzc1Rva2VuT25TaWdub3V0O1xyXG4gICAgfVxyXG5cclxuICAgIGdldCByZWRpcmVjdE5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcmVkaXJlY3ROYXZpZ2F0b3I7XHJcbiAgICB9XHJcbiAgICBnZXQgcG9wdXBOYXZpZ2F0b3IoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BvcHVwTmF2aWdhdG9yO1xyXG4gICAgfVxyXG4gICAgZ2V0IGlmcmFtZU5hdmlnYXRvcigpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5faWZyYW1lTmF2aWdhdG9yO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB1c2VyU3RvcmUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VzZXJTdG9yZTtcclxuICAgIH1cclxufVxyXG4iLCIvLyBDb3B5cmlnaHQgKGMpIEJyb2NrIEFsbGVuICYgRG9taW5pY2sgQmFpZXIuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuIFNlZSBMSUNFTlNFIGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG5pbXBvcnQgeyBMb2cgfSBmcm9tICcuL0xvZy5qcyc7XHJcbmltcG9ydCB7IEdsb2JhbCB9IGZyb20gJy4vR2xvYmFsLmpzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBXZWJTdG9yYWdlU3RhdGVTdG9yZSB7XHJcbiAgICBjb25zdHJ1Y3Rvcih7cHJlZml4ID0gXCJvaWRjLlwiLCBzdG9yZSA9IEdsb2JhbC5sb2NhbFN0b3JhZ2V9ID0ge30pIHtcclxuICAgICAgICB0aGlzLl9zdG9yZSA9IHN0b3JlO1xyXG4gICAgICAgIHRoaXMuX3ByZWZpeCA9IHByZWZpeDtcclxuICAgIH1cclxuXHJcbiAgICBzZXQoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnNldFwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIHRoaXMuX3N0b3JlLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQoa2V5KSB7XHJcbiAgICAgICAgTG9nLmRlYnVnKFwiV2ViU3RvcmFnZVN0YXRlU3RvcmUuZ2V0XCIsIGtleSk7XHJcblxyXG4gICAgICAgIGtleSA9IHRoaXMuX3ByZWZpeCArIGtleTtcclxuXHJcbiAgICAgICAgbGV0IGl0ZW0gPSB0aGlzLl9zdG9yZS5nZXRJdGVtKGtleSk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoaXRlbSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlKGtleSkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLnJlbW92ZVwiLCBrZXkpO1xyXG5cclxuICAgICAgICBrZXkgPSB0aGlzLl9wcmVmaXggKyBrZXk7XHJcblxyXG4gICAgICAgIGxldCBpdGVtID0gdGhpcy5fc3RvcmUuZ2V0SXRlbShrZXkpO1xyXG4gICAgICAgIHRoaXMuX3N0b3JlLnJlbW92ZUl0ZW0oa2V5KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpdGVtKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRBbGxLZXlzKCkge1xyXG4gICAgICAgIExvZy5kZWJ1ZyhcIldlYlN0b3JhZ2VTdGF0ZVN0b3JlLmdldEFsbEtleXNcIik7XHJcblxyXG4gICAgICAgIHZhciBrZXlzID0gW107XHJcblxyXG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLl9zdG9yZS5sZW5ndGg7IGluZGV4KyspIHtcclxuICAgICAgICAgICAgbGV0IGtleSA9IHRoaXMuX3N0b3JlLmtleShpbmRleCk7XHJcblxyXG4gICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YodGhpcy5fcHJlZml4KSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAga2V5cy5wdXNoKGtleS5zdWJzdHIodGhpcy5fcHJlZml4Lmxlbmd0aCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGtleXMpO1xyXG4gICAgfVxyXG59XHJcbiIsImltcG9ydCB7IGp3cywgS0VZVVRJTCBhcyBLZXlVdGlsLCBYNTA5LCBjcnlwdG8sIGhleHRvYjY0dSwgYjY0dG9oZXggfSBmcm9tICcuLi8uLi9qc3JzYXNpZ24vZGlzdC9qc3JzYXNpZ24uanMnO1xyXG5cclxuY29uc3QgQWxsb3dlZFNpZ25pbmdBbGdzID0gWydSUzI1NicsICdSUzM4NCcsICdSUzUxMicsICdQUzI1NicsICdQUzM4NCcsICdQUzUxMicsICdFUzI1NicsICdFUzM4NCcsICdFUzUxMiddO1xyXG5cclxuZXhwb3J0IHtcclxuICAgIGp3cyxcclxuICAgIEtleVV0aWwsXHJcbiAgICBYNTA5LFxyXG4gICAgY3J5cHRvLFxyXG4gICAgaGV4dG9iNjR1LFxyXG4gICAgYjY0dG9oZXgsXHJcbiAgICBBbGxvd2VkU2lnbmluZ0FsZ3NcclxufTtcclxuIiwiaW1wb3J0IHV1aWQ0IGZyb20gJ3V1aWQvdjQnO1xyXG5cclxuLyoqXHJcbiAqIEdlbmVyYXRlcyBSRkM0MTIyIHZlcnNpb24gNCBndWlkICgpXHJcbiAqL1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmFuZG9tKCkge1xyXG4gIHJldHVybiB1dWlkNCgpLnJlcGxhY2UoLy0vZywgJycpO1xyXG59XHJcbiIsImNvbnN0IFZlcnNpb24gPSBcIjEuMTAuMVwiOyBleHBvcnQge1ZlcnNpb259OyJdLCJzb3VyY2VSb290IjoiIn0="
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly ILogger<HomeController> _logger;\n\n    public HomeController(ILogger<HomeController> logger)\n    {\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    public async Task<IActionResult> CallApi()\n    {\n        var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = new HttpClient();\n        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n        var content = await client.GetStringAsync(\"https://localhost:6001/identity\");\n\n        var obj = JsonSerializer.Deserialize<JsonElement>(content);\n        ViewBag.Json = obj.ToString();\n        return View(\"json\");\n    }\n\n    public IActionResult Logout()\n    {\n        return SignOut(\"Cookies\", \"oidc\");\n    }\n\n    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n    public IActionResult Error()\n    {\n        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using System.Diagnostics;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net.Http.Headers;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Models/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class ErrorViewModel\n{\n    public string RequestId { get; set; }\n\n    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/MvcClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.OpenIdConnect\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Update=\"Views\\Shared\\Json.cshtml\">\n      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n    </Content>\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddControllersWithViews();\nbuilder.Services\n    .AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"Cookies\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n    .AddCookie(\"Cookies\")\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        options.Authority = \"https://localhost:5001\";\n\n        options.ClientId = \"mvc\";\n        options.ClientSecret = \"secret\";\n        options.ResponseType = \"code\";\n\n        options.Scope.Add(\"api1\");\n\n        options.SaveTokens = true;\n    });\n\n\nusing (var app = builder.Build())\n{\n    if (app.Environment.IsDevelopment())\n        app.UseDeveloperExceptionPage();\n    else\n        app.UseExceptionHandler(\"/Home/Error\");\n\n    app.UseStaticFiles();\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n    app.MapDefaultControllerRoute().RequireAuthorization();\n\n    await app.RunAsync();\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"MvcClient\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5002\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing System.IdentityModel.Tokens.Jwt;\n\nnamespace MvcClient\n{\n    public class Startup\n    {\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddControllersWithViews();\n\n            JwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n            services.AddAuthentication(options =>\n            {\n                options.DefaultScheme = \"Cookies\";\n                options.DefaultChallengeScheme = \"oidc\";\n            })\n            .AddCookie(\"Cookies\")\n            .AddOpenIdConnect(\"oidc\", options =>\n            {\n                options.Authority = \"https://localhost:5001\";\n\n                options.ClientId = \"mvc\";\n                options.ClientSecret = \"secret\";\n                options.ResponseType = \"code\";\n                \n                options.Scope.Add(\"api1\");\n\n                options.SaveTokens = true;\n            });\n        }\n\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n            }\n            else\n            {\n                app.UseExceptionHandler(\"/Home/Error\");\n            }\n\n            app.UseStaticFiles();\n\n            app.UseRouting();\n            app.UseAuthentication();\n            app.UseAuthorization();\n\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapDefaultControllerRoute()\n                    .RequireAuthorization();\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/Home/Index.cshtml",
    "content": "@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/Home/Privacy.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Privacy Policy\";\n}\n<h1>@ViewData[\"Title\"]</h1>\n\n<p>Use this page to detail your site's privacy policy.</p>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/Shared/Error.cshtml",
    "content": "﻿@model ErrorViewModel\n@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n@if (Model.ShowRequestId)\n{\n    <p>\n        <strong>Request ID:</strong> <code>@Model.RequestId</code>\n    </p>\n}\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n    It can result in displaying sensitive information from exceptions to end users.\n    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n    and restarting the app.\n</p>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcClient</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcClient</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/Shared/json.cshtml",
    "content": "<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Quickstarts/4_JavaScriptClient/src/MvcClient/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/Quickstart.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{BD8BA25C-A91D-419D-99B6-B575ADD6D061}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer\", \"src\\IdentityServer\\IdentityServer.csproj\", \"{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcClient\", \"src\\MvcClient\\MvcClient.csproj\", \"{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Api\", \"..\\Shared\\src\\Api\\Api.csproj\", \"{F555BE49-9B75-4379-96A5-A0490B18EDDB}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Client\", \"..\\Shared\\src\\Client\\Client.csproj\", \"{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x64.Build.0 = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E}.Release|x86.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.Build.0 = Release|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Release|x64.Build.0 = Release|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{F555BE49-9B75-4379-96A5-A0490B18EDDB}.Release|x86.Build.0 = Release|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Release|x64.Build.0 = Release|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{EFC08DC4-FF0B-4B06-A784-4F85C4CCB41C}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{79D1F107-F3AF-4A93-BF5D-49EF6A46E50E} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {84D5AF06-1243-46F1-9D58-70ED572832C3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/Quickstart.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Secret = IdentityServer8.Models.Secret;\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> IdentityResources =>\n        new List<IdentityResource>\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n        };\n\n\n    public static IEnumerable<ApiScope> ApiScopes =>\n        new List<ApiScope>\n        {\n            new ApiScope(\"api1\", \"My API\")\n        };\n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            // machine to machine client\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            },\n            \n            // interactive ASP.NET Core MVC client\n            new Client\n            {\n                ClientId = \"mvc\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                \n                // where to redirect to after login\n                RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                // where to redirect to after logout\n                PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                AllowedScopes = new List<string>\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    \"api1\"\n                }\n            }\n        };\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Data/Migrations/IdentityServer/ConfigurationDb/20200625203625_InitialIdentityServerConfigurationDbMigration.Designer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace IdentityServer.Data.Migrations.IdentityServer.ConfigurationDb\n{\n    [DbContext(typeof(ConfigurationDbContext))]\n    [Migration(\"20200625203625_InitialIdentityServerConfigurationDbMigration\")]\n    partial class InitialIdentityServerConfigurationDbMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"AllowedAccessTokenSigningAlgorithms\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(4000)\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.Client\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"AbsoluteRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenType\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"AllowAccessTokensViaBrowser\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowOfflineAccess\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowPlainTextPkce\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowRememberConsent\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"AllowedIdentityTokenSigningAlgorithms\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<bool>(\"AlwaysIncludeUserClaimsInIdToken\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AlwaysSendClientClaims\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<int>(\"AuthorizationCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"BackChannelLogoutSessionRequired\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"BackChannelLogoutUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<string>(\"ClientClaimsPrefix\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int?>(\"ConsentLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<int>(\"DeviceCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"EnableLocalLogin\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"FrontChannelLogoutSessionRequired\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"FrontChannelLogoutUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int>(\"IdentityTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"IncludeJwtId\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"LogoUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"PairWiseSubjectSalt\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ProtocolType\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<int>(\"RefreshTokenExpiration\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RefreshTokenUsage\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"RequireClientSecret\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequireConsent\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequirePkce\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequireRequestObject\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<int>(\"SlidingRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"UpdateAccessTokenClaimsOnRefresh\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"UserCodeType\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<int?>(\"UserSsoLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\")\n                        .IsUnique();\n\n                    b.ToTable(\"Clients\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Origin\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(150)\")\n                        .HasMaxLength(150);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientCorsOrigins\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"GrantType\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientGrantTypes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Provider\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientIdPRestrictions\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"PostLogoutRedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientPostLogoutRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"RedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(4000)\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"IdentityResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Scopes\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Secrets\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Claims\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedCorsOrigins\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedGrantTypes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"IdentityProviderRestrictions\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"PostLogoutRedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"RedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedScopes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"ClientSecrets\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Data/Migrations/IdentityServer/ConfigurationDb/20200625203625_InitialIdentityServerConfigurationDbMigration.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace IdentityServer.Data.Migrations.IdentityServer.ConfigurationDb\n{\n    public partial class InitialIdentityServerConfigurationDbMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"ApiResources\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Enabled = table.Column<bool>(nullable: false),\n                    Name = table.Column<string>(maxLength: 200, nullable: false),\n                    DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    AllowedAccessTokenSigningAlgorithms = table.Column<string>(maxLength: 100, nullable: true),\n                    ShowInDiscoveryDocument = table.Column<bool>(nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    Updated = table.Column<DateTime>(nullable: true),\n                    LastAccessed = table.Column<DateTime>(nullable: true),\n                    NonEditable = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResources\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiScopes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Enabled = table.Column<bool>(nullable: false),\n                    Name = table.Column<string>(maxLength: 200, nullable: false),\n                    DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Required = table.Column<bool>(nullable: false),\n                    Emphasize = table.Column<bool>(nullable: false),\n                    ShowInDiscoveryDocument = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiScopes\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Clients\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Enabled = table.Column<bool>(nullable: false),\n                    ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                    ProtocolType = table.Column<string>(maxLength: 200, nullable: false),\n                    RequireClientSecret = table.Column<bool>(nullable: false),\n                    ClientName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    ClientUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    LogoUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    RequireConsent = table.Column<bool>(nullable: false),\n                    AllowRememberConsent = table.Column<bool>(nullable: false),\n                    AlwaysIncludeUserClaimsInIdToken = table.Column<bool>(nullable: false),\n                    RequirePkce = table.Column<bool>(nullable: false),\n                    AllowPlainTextPkce = table.Column<bool>(nullable: false),\n                    RequireRequestObject = table.Column<bool>(nullable: false),\n                    AllowAccessTokensViaBrowser = table.Column<bool>(nullable: false),\n                    FrontChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    FrontChannelLogoutSessionRequired = table.Column<bool>(nullable: false),\n                    BackChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),\n                    BackChannelLogoutSessionRequired = table.Column<bool>(nullable: false),\n                    AllowOfflineAccess = table.Column<bool>(nullable: false),\n                    IdentityTokenLifetime = table.Column<int>(nullable: false),\n                    AllowedIdentityTokenSigningAlgorithms = table.Column<string>(maxLength: 100, nullable: true),\n                    AccessTokenLifetime = table.Column<int>(nullable: false),\n                    AuthorizationCodeLifetime = table.Column<int>(nullable: false),\n                    ConsentLifetime = table.Column<int>(nullable: true),\n                    AbsoluteRefreshTokenLifetime = table.Column<int>(nullable: false),\n                    SlidingRefreshTokenLifetime = table.Column<int>(nullable: false),\n                    RefreshTokenUsage = table.Column<int>(nullable: false),\n                    UpdateAccessTokenClaimsOnRefresh = table.Column<bool>(nullable: false),\n                    RefreshTokenExpiration = table.Column<int>(nullable: false),\n                    AccessTokenType = table.Column<int>(nullable: false),\n                    EnableLocalLogin = table.Column<bool>(nullable: false),\n                    IncludeJwtId = table.Column<bool>(nullable: false),\n                    AlwaysSendClientClaims = table.Column<bool>(nullable: false),\n                    ClientClaimsPrefix = table.Column<string>(maxLength: 200, nullable: true),\n                    PairWiseSubjectSalt = table.Column<string>(maxLength: 200, nullable: true),\n                    Created = table.Column<DateTime>(nullable: false),\n                    Updated = table.Column<DateTime>(nullable: true),\n                    LastAccessed = table.Column<DateTime>(nullable: true),\n                    UserSsoLifetime = table.Column<int>(nullable: true),\n                    UserCodeType = table.Column<string>(maxLength: 100, nullable: true),\n                    DeviceCodeLifetime = table.Column<int>(nullable: false),\n                    NonEditable = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Clients\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityResources\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Enabled = table.Column<bool>(nullable: false),\n                    Name = table.Column<string>(maxLength: 200, nullable: false),\n                    DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Required = table.Column<bool>(nullable: false),\n                    Emphasize = table.Column<bool>(nullable: false),\n                    ShowInDiscoveryDocument = table.Column<bool>(nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    Updated = table.Column<DateTime>(nullable: true),\n                    NonEditable = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityResources\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiResourceClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Type = table.Column<string>(maxLength: 200, nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResourceClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiResourceClaims_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiResourceProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResourceProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiResourceProperties_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiResourceScopes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Scope = table.Column<string>(maxLength: 200, nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResourceScopes\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiResourceScopes_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiResourceSecrets\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Description = table.Column<string>(maxLength: 1000, nullable: true),\n                    Value = table.Column<string>(maxLength: 4000, nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: true),\n                    Type = table.Column<string>(maxLength: 250, nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    ApiResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiResourceSecrets\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiResourceSecrets_ApiResources_ApiResourceId\",\n                        column: x => x.ApiResourceId,\n                        principalTable: \"ApiResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiScopeClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Type = table.Column<string>(maxLength: 200, nullable: false),\n                    ScopeId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiScopeClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiScopeClaims_ApiScopes_ScopeId\",\n                        column: x => x.ScopeId,\n                        principalTable: \"ApiScopes\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ApiScopeProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    ScopeId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ApiScopeProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ApiScopeProperties_ApiScopes_ScopeId\",\n                        column: x => x.ScopeId,\n                        principalTable: \"ApiScopes\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Type = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 250, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientClaims_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientCorsOrigins\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Origin = table.Column<string>(maxLength: 150, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientCorsOrigins\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientCorsOrigins_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientGrantTypes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    GrantType = table.Column<string>(maxLength: 250, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientGrantTypes\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientGrantTypes_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientIdPRestrictions\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Provider = table.Column<string>(maxLength: 200, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientIdPRestrictions\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientIdPRestrictions_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientPostLogoutRedirectUris\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    PostLogoutRedirectUri = table.Column<string>(maxLength: 2000, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientPostLogoutRedirectUris\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientPostLogoutRedirectUris_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientProperties_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientRedirectUris\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    RedirectUri = table.Column<string>(maxLength: 2000, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientRedirectUris\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientRedirectUris_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientScopes\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Scope = table.Column<string>(maxLength: 200, nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientScopes\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientScopes_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClientSecrets\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Description = table.Column<string>(maxLength: 2000, nullable: true),\n                    Value = table.Column<string>(maxLength: 4000, nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: true),\n                    Type = table.Column<string>(maxLength: 250, nullable: false),\n                    Created = table.Column<DateTime>(nullable: false),\n                    ClientId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClientSecrets\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_ClientSecrets_Clients_ClientId\",\n                        column: x => x.ClientId,\n                        principalTable: \"Clients\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityResourceClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Type = table.Column<string>(maxLength: 200, nullable: false),\n                    IdentityResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityResourceClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_IdentityResourceClaims_IdentityResources_IdentityResourceId\",\n                        column: x => x.IdentityResourceId,\n                        principalTable: \"IdentityResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"IdentityResourceProperties\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                    Key = table.Column<string>(maxLength: 250, nullable: false),\n                    Value = table.Column<string>(maxLength: 2000, nullable: false),\n                    IdentityResourceId = table.Column<int>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_IdentityResourceProperties\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_IdentityResourceProperties_IdentityResources_IdentityResourceId\",\n                        column: x => x.IdentityResourceId,\n                        principalTable: \"IdentityResources\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResourceClaims_ApiResourceId\",\n                table: \"ApiResourceClaims\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResourceProperties_ApiResourceId\",\n                table: \"ApiResourceProperties\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResources_Name\",\n                table: \"ApiResources\",\n                column: \"Name\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResourceScopes_ApiResourceId\",\n                table: \"ApiResourceScopes\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiResourceSecrets_ApiResourceId\",\n                table: \"ApiResourceSecrets\",\n                column: \"ApiResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopeClaims_ScopeId\",\n                table: \"ApiScopeClaims\",\n                column: \"ScopeId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopeProperties_ScopeId\",\n                table: \"ApiScopeProperties\",\n                column: \"ScopeId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ApiScopes_Name\",\n                table: \"ApiScopes\",\n                column: \"Name\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientClaims_ClientId\",\n                table: \"ClientClaims\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientCorsOrigins_ClientId\",\n                table: \"ClientCorsOrigins\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientGrantTypes_ClientId\",\n                table: \"ClientGrantTypes\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientIdPRestrictions_ClientId\",\n                table: \"ClientIdPRestrictions\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientPostLogoutRedirectUris_ClientId\",\n                table: \"ClientPostLogoutRedirectUris\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientProperties_ClientId\",\n                table: \"ClientProperties\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientRedirectUris_ClientId\",\n                table: \"ClientRedirectUris\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_Clients_ClientId\",\n                table: \"Clients\",\n                column: \"ClientId\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientScopes_ClientId\",\n                table: \"ClientScopes\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_ClientSecrets_ClientId\",\n                table: \"ClientSecrets\",\n                column: \"ClientId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityResourceClaims_IdentityResourceId\",\n                table: \"IdentityResourceClaims\",\n                column: \"IdentityResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityResourceProperties_IdentityResourceId\",\n                table: \"IdentityResourceProperties\",\n                column: \"IdentityResourceId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_IdentityResources_Name\",\n                table: \"IdentityResources\",\n                column: \"Name\",\n                unique: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"ApiResourceClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiResourceProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiResourceScopes\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiResourceSecrets\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiScopeClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiScopeProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientCorsOrigins\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientGrantTypes\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientIdPRestrictions\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientPostLogoutRedirectUris\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientRedirectUris\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientScopes\");\n\n            migrationBuilder.DropTable(\n                name: \"ClientSecrets\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityResourceClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityResourceProperties\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiResources\");\n\n            migrationBuilder.DropTable(\n                name: \"ApiScopes\");\n\n            migrationBuilder.DropTable(\n                name: \"Clients\");\n\n            migrationBuilder.DropTable(\n                name: \"IdentityResources\");\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Data/Migrations/IdentityServer/ConfigurationDb/ConfigurationDbContextModelSnapshot.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\n\nnamespace IdentityServer.Data.Migrations.IdentityServer.ConfigurationDb\n{\n    [DbContext(typeof(ConfigurationDbContext))]\n    partial class ConfigurationDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"AllowedAccessTokenSigningAlgorithms\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(4000)\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.Client\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"AbsoluteRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenType\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"AllowAccessTokensViaBrowser\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowOfflineAccess\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowPlainTextPkce\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowRememberConsent\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"AllowedIdentityTokenSigningAlgorithms\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<bool>(\"AlwaysIncludeUserClaimsInIdToken\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AlwaysSendClientClaims\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<int>(\"AuthorizationCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"BackChannelLogoutSessionRequired\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"BackChannelLogoutUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<string>(\"ClientClaimsPrefix\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int?>(\"ConsentLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<int>(\"DeviceCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"EnableLocalLogin\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"FrontChannelLogoutSessionRequired\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"FrontChannelLogoutUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int>(\"IdentityTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"IncludeJwtId\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"LogoUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"PairWiseSubjectSalt\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ProtocolType\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<int>(\"RefreshTokenExpiration\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RefreshTokenUsage\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"RequireClientSecret\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequireConsent\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequirePkce\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequireRequestObject\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<int>(\"SlidingRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"UpdateAccessTokenClaimsOnRefresh\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"UserCodeType\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<int?>(\"UserSsoLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\")\n                        .IsUnique();\n\n                    b.ToTable(\"Clients\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Origin\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(150)\")\n                        .HasMaxLength(150);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientCorsOrigins\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"GrantType\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientGrantTypes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Provider\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientIdPRestrictions\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"PostLogoutRedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientPostLogoutRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"RedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(4000)\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"IdentityResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Scopes\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Secrets\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Claims\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedCorsOrigins\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedGrantTypes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"IdentityProviderRestrictions\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"PostLogoutRedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"RedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedScopes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"ClientSecrets\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Data/Migrations/IdentityServer/PersistedGrantDb/20200625203357_InitialIdentityServerPersistedGrantDbMigration.Designer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace IdentityServer.Data.Migrations.IdentityServer.PersistedGrantDb\n{\n    [DbContext(typeof(PersistedGrantDbContext))]\n    [Migration(\"20200625203357_InitialIdentityServerPersistedGrantDbMigration\")]\n    partial class InitialIdentityServerPersistedGrantDbMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.DeviceFlowCodes\", b =>\n                {\n                    b.Property<string>(\"UserCode\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(max)\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"DeviceCode\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .IsRequired()\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"UserCode\");\n\n                    b.HasIndex(\"DeviceCode\")\n                        .IsUnique();\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.ToTable(\"DeviceCodes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.PersistedGrant\", b =>\n                {\n                    b.Property<string>(\"Key\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"ConsumedTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(max)\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(50)\")\n                        .HasMaxLength(50);\n\n                    b.HasKey(\"Key\");\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.HasIndex(\"SubjectId\", \"ClientId\", \"Type\");\n\n                    b.HasIndex(\"SubjectId\", \"SessionId\", \"Type\");\n\n                    b.ToTable(\"PersistedGrants\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Data/Migrations/IdentityServer/PersistedGrantDb/20200625203357_InitialIdentityServerPersistedGrantDbMigration.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace IdentityServer.Data.Migrations.IdentityServer.PersistedGrantDb\n{\n    public partial class InitialIdentityServerPersistedGrantDbMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"DeviceCodes\",\n                columns: table => new\n                {\n                    UserCode = table.Column<string>(maxLength: 200, nullable: false),\n                    DeviceCode = table.Column<string>(maxLength: 200, nullable: false),\n                    SubjectId = table.Column<string>(maxLength: 200, nullable: true),\n                    SessionId = table.Column<string>(maxLength: 100, nullable: true),\n                    ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                    Description = table.Column<string>(maxLength: 200, nullable: true),\n                    CreationTime = table.Column<DateTime>(nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: false),\n                    Data = table.Column<string>(maxLength: 50000, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_DeviceCodes\", x => x.UserCode);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"PersistedGrants\",\n                columns: table => new\n                {\n                    Key = table.Column<string>(maxLength: 200, nullable: false),\n                    Type = table.Column<string>(maxLength: 50, nullable: false),\n                    SubjectId = table.Column<string>(maxLength: 200, nullable: true),\n                    SessionId = table.Column<string>(maxLength: 100, nullable: true),\n                    ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                    Description = table.Column<string>(maxLength: 200, nullable: true),\n                    CreationTime = table.Column<DateTime>(nullable: false),\n                    Expiration = table.Column<DateTime>(nullable: true),\n                    ConsumedTime = table.Column<DateTime>(nullable: true),\n                    Data = table.Column<string>(maxLength: 50000, nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_PersistedGrants\", x => x.Key);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_DeviceCodes_DeviceCode\",\n                table: \"DeviceCodes\",\n                column: \"DeviceCode\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_DeviceCodes_Expiration\",\n                table: \"DeviceCodes\",\n                column: \"Expiration\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_PersistedGrants_Expiration\",\n                table: \"PersistedGrants\",\n                column: \"Expiration\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_PersistedGrants_SubjectId_ClientId_Type\",\n                table: \"PersistedGrants\",\n                columns: new[] { \"SubjectId\", \"ClientId\", \"Type\" });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_PersistedGrants_SubjectId_SessionId_Type\",\n                table: \"PersistedGrants\",\n                columns: new[] { \"SubjectId\", \"SessionId\", \"Type\" });\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"DeviceCodes\");\n\n            migrationBuilder.DropTable(\n                name: \"PersistedGrants\");\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Data/Migrations/IdentityServer/PersistedGrantDb/PersistedGrantDbContextModelSnapshot.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\n\nnamespace IdentityServer.Data.Migrations.IdentityServer.PersistedGrantDb\n{\n    [DbContext(typeof(PersistedGrantDbContext))]\n    partial class PersistedGrantDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.5\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.DeviceFlowCodes\", b =>\n                {\n                    b.Property<string>(\"UserCode\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(max)\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"DeviceCode\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .IsRequired()\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"UserCode\");\n\n                    b.HasIndex(\"DeviceCode\")\n                        .IsUnique();\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.ToTable(\"DeviceCodes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.PersistedGrant\", b =>\n                {\n                    b.Property<string>(\"Key\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"ConsumedTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(max)\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(50)\")\n                        .HasMaxLength(50);\n\n                    b.HasKey(\"Key\");\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.HasIndex(\"SubjectId\", \"ClientId\", \"Type\");\n\n                    b.HasIndex(\"SubjectId\", \"SessionId\", \"Type\");\n\n                    b.ToTable(\"PersistedGrants\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.EntityFramework.DbContexts;\nglobal using IdentityServer8.EntityFramework.Mappers;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Reflection;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using System.Text.Json;\nglobal using static IdentityModel.JwtClaimTypes;\nglobal using IdentityServerClaimValueTypes = IdentityServer8.IdentityServerConstants.ClaimValueTypes;\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/IdentityServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n    <ItemGroup>\n        <PackageReference Include=\"HigginsSoft.IdentityServer8\" />\n        <PackageReference Include=\"HigginsSoft.IdentityServer8.EntityFramework\" />\n        <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n\n        <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Google\" />\n        <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n        <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" />\n    </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\ntry\n{\n    Log.Information(\"Starting host...\");\n\n    var builder = WebApplication.CreateBuilder(args);\n\n    var services = builder.Services;\n\n    services.AddControllersWithViews();\n\n    var migrationsAssembly = typeof(Program).GetTypeInfo().Assembly.GetName().Name;\n    const string connectionString = @\"Data Source=(LocalDb)\\MSSQLLocalDB;database=IdentityServer8.Quickstart.EntityFramework-4.0.0;trusted_connection=yes;\";\n\n    services.AddIdentityServer()\n        .AddTestUsers(TestUsers.Users)\n        .AddConfigurationStore(options =>\n        {\n            options.ConfigureDbContext = b => b.UseSqlServer(connectionString,\n                sql => sql.MigrationsAssembly(migrationsAssembly));\n        })\n        .AddOperationalStore(options =>\n        {\n            options.ConfigureDbContext = b => b.UseSqlServer(connectionString,\n                sql => sql.MigrationsAssembly(migrationsAssembly));\n        })\n        .AddDeveloperSigningCredential();\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"<insert here>\";\n            options.ClientSecret = \"<insert here>\";\n        })\n        .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n            options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n            options.SaveTokens = true;\n\n            options.Authority = \"https://demo.identityserver8.io/\";\n            options.ClientId = \"interactive.confidential\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.TokenValidationParameters = new()\n            {\n                NameClaimType = \"name\",\n                RoleClaimType = \"role\"\n            };\n        });\n\n\n    using (var app = builder.Build())\n    {\n        // this will do the initial DB population\n        InitializeDatabase(app);\n\n        if (app.Environment.IsDevelopment())\n            app.UseDeveloperExceptionPage();\n\n        app.UseStaticFiles()\n            .UseRouting()\n            .UseIdentityServer()\n            .UseAuthorization();\n\n        app.MapDefaultControllerRoute();\n\n        await app.RunAsync();\n    }\n\n    return 0;\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\n\nvoid ConfigureLogger() => Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Debug()\n    .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    // uncomment to write to Azure diagnostics stream\n    //.WriteTo.File(\n    //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n    //    fileSizeLimitBytes: 1_000_000,\n    //    rollOnFileSizeLimit: true,\n    //    shared: true,\n    //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n    .CreateLogger();\n\n void InitializeDatabase(IApplicationBuilder app)\n{\n    using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())\n    {\n        serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();\n\n        var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();\n        context.Database.Migrate();\n        if (!context.Clients.Any())\n        {\n            foreach (var client in Config.Clients)\n            {\n                context.Clients.Add(client.ToEntity());\n            }\n            context.SaveChanges();\n        }\n\n        if (!context.IdentityResources.Any())\n        {\n            foreach (var resource in Config.IdentityResources)\n            {\n                context.IdentityResources.Add(resource.ToEntity());\n            }\n            context.SaveChanges();\n        }\n\n        if (!context.ApiScopes.Any())\n        {\n            foreach (var resource in Config.ApiScopes)\n            {\n                context.ApiScopes.Add(resource.ToEntity());\n            }\n            context.SaveChanges();\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (ModelState.IsValid)\n        {\n            // validate username/password against in-memory store\n            if (_users.ValidateCredentials(model.Username, model.Password))\n            {\n                var user = _users.FindByUsername(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                // only set explicit expiration here if user chooses \"remember me\". \n                // otherwise we rely upon expiration configured in cookie middleware.\n                AuthenticationProperties props = null;\n                if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                {\n                    props = new AuthenticationProperties\n                    {\n                        IsPersistent = true,\n                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                    };\n                };\n\n                // issue authentication cookie with subject ID and username\n                var isuser = new IdentityServerUser(user.SubjectId)\n                {\n                    DisplayName = user.Username\n                };\n\n                await HttpContext.SignInAsync(isuser, props);\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI\n{\n    public class AccountOptions\n    {\n        public static bool AllowLocalLogin = true;\n        public static bool AllowRememberLogin = true;\n        public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n        public static bool ShowLogoutPrompt = true;\n        public static bool AutomaticRedirectAfterSignOut = false;\n\n        public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly ILogger<ExternalController> _logger;\n    private readonly IEventService _events;\n\n    public ExternalController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _logger = logger;\n        _events = events;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = AutoProvisionUser(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        var isuser = new IdentityServerUser(user.SubjectId)\n        {\n            DisplayName = user.Username,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = _users.FindByExternalProvider(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonSerializer.Deserialize<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n\n    static readonly object UserAddress = new\n    {\n        street_address = \"One Hacker Way\",\n        locality = \"Heidelberg\",\n        postal_code = 69118,\n        country = \"Germany\"\n    };\n\n    public static List<TestUser> Users => new List<TestUser>\n    {\n        new()\n        {\n            SubjectId = \"818727\",\n            Username = \"alice\",\n            Password = \"alice\",\n            Claims =\n            {\n                new (Name, \"Alice Smith\"),\n                new (GivenName, \"Alice\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"AliceSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://alice.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        },\n        new()\n        {\n            SubjectId = \"88421113\",\n            Username = \"bob\",\n            Password = \"bob\",\n            Claims =\n            {\n                new (Name, \"Bob Smith\"),\n                new (GivenName, \"Bob\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"BobSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://bob.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8;\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServerHost.Quickstart.UI;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.IdentityModel.Tokens;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace IdentityServer\n{\n    public class Startup\n    {\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddControllersWithViews();\n\n            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;\n            const string connectionString = @\"Data Source=(LocalDb)\\MSSQLLocalDB;database=IdentityServer8.Quickstart.EntityFramework-4.0.0;trusted_connection=yes;\";\n            \n            var builder = services.AddIdentityServer()\n                .AddTestUsers(TestUsers.Users)\n                .AddConfigurationStore(options =>\n                {\n                    options.ConfigureDbContext = b => b.UseSqlServer(connectionString,\n                        sql => sql.MigrationsAssembly(migrationsAssembly));\n                })\n                .AddOperationalStore(options =>\n                {\n                    options.ConfigureDbContext = b => b.UseSqlServer(connectionString,\n                        sql => sql.MigrationsAssembly(migrationsAssembly));\n                });\n\n            builder.AddDeveloperSigningCredential();\n\n            services.AddAuthentication()\n                .AddGoogle(\"Google\", options =>\n                {\n                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n                    options.ClientId = \"<insert here>\";\n                    options.ClientSecret = \"<insert here>\";\n                })\n                .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n                {\n                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n                    options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n                    options.SaveTokens = true;\n\n                    options.Authority = \"https://demo.identityserver8.io/\";\n                    options.ClientId = \"interactive.confidential\";\n                    options.ClientSecret = \"secret\";\n                    options.ResponseType = \"code\";\n\n                    options.TokenValidationParameters = new TokenValidationParameters\n                    {\n                        NameClaimType = \"name\",\n                        RoleClaimType = \"role\"\n                    };\n                });\n        }\n\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            // this will do the initial DB population\n            InitializeDatabase(app);\n\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n            }\n\n            app.UseStaticFiles();\n            app.UseRouting();\n\n            app.UseIdentityServer();\n            app.UseAuthorization();\n\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapDefaultControllerRoute();\n            });\n        }\n\n        private void InitializeDatabase(IApplicationBuilder app)\n        {\n            using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())\n            {\n                serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();\n\n                var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();\n                context.Database.Migrate();\n                if (!context.Clients.Any())\n                {\n                    foreach (var client in Config.Clients)\n                    {\n                        context.Clients.Add(client.ToEntity());\n                    }\n                    context.SaveChanges();\n                }\n\n                if (!context.IdentityResources.Any())\n                {\n                    foreach (var resource in Config.IdentityResources)\n                    {\n                        context.IdentityResources.Add(resource.ToEntity());\n                    }\n                    context.SaveChanges();\n                }\n\n                if (!context.ApiScopes.Any())\n                {\n                    foreach (var resource in Config.ApiScopes)\n                    {\n                        context.ApiScopes.Add(resource.ToEntity());\n                    }\n                    context.SaveChanges();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n\n@{\n    var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Ioc.Sanitizer.Url.Sanitize(Model.RedirectUrl)';\n    window.location.href = url;\n</script>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/wwwroot/js/signin-redirect.js",
    "content": "// window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/IdentityServer/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly ILogger<HomeController> _logger;\n\n    public HomeController(ILogger<HomeController> logger)\n    {\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    public async Task<IActionResult> CallApi()\n    {\n        var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = new HttpClient();\n        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n        var content = await client.GetStringAsync(\"https://localhost:6001/identity\");\n\n        var obj = JsonSerializer.Deserialize<JsonElement>(content);\n        ViewBag.Json = obj.ToString();\n        return View(\"json\");\n    }\n\n    public IActionResult Logout()\n    {\n        return SignOut(\"Cookies\", \"oidc\");\n    }\n\n    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n    public IActionResult Error()\n    {\n        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using System.Diagnostics;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net.Http.Headers;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Models/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class ErrorViewModel\n{\n    public string RequestId { get; set; }\n\n    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/MvcClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.OpenIdConnect\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Update=\"Views\\Shared\\Json.cshtml\">\n      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n    </Content>\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddControllersWithViews();\nbuilder.Services\n    .AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"Cookies\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n    .AddCookie(\"Cookies\")\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        options.Authority = \"https://localhost:5001\";\n\n        options.ClientId = \"mvc\";\n        options.ClientSecret = \"secret\";\n        options.ResponseType = \"code\";\n\n        options.Scope.Add(\"api1\");\n\n        options.SaveTokens = true;\n    });\n\n\nusing (var app = builder.Build())\n{\n    if (app.Environment.IsDevelopment())\n        app.UseDeveloperExceptionPage();\n    else\n        app.UseExceptionHandler(\"/Home/Error\");\n\n    app.UseStaticFiles();\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n    app.MapDefaultControllerRoute().RequireAuthorization();\n\n    await app.RunAsync();\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"MvcClient\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5002\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/Home/Index.cshtml",
    "content": "@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/Home/Privacy.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Privacy Policy\";\n}\n<h1>@ViewData[\"Title\"]</h1>\n\n<p>Use this page to detail your site's privacy policy.</p>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/Shared/Error.cshtml",
    "content": "﻿@model ErrorViewModel\n@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n@if (Model.ShowRequestId)\n{\n    <p>\n        <strong>Request ID:</strong> <code>@Model.RequestId</code>\n    </p>\n}\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n    It can result in displaying sensitive information from exceptions to end users.\n    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n    and restarting the app.\n</p>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcClient</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcClient</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/Shared/json.cshtml",
    "content": "<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Quickstarts/5_EntityFramework/src/MvcClient/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/Quickstart.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{BD8BA25C-A91D-419D-99B6-B575ADD6D061}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"MvcClient\", \"src\\MvcClient\\MvcClient.csproj\", \"{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServerAspNetIdentity\", \"src\\IdentityServerAspNetIdentity\\IdentityServerAspNetIdentity.csproj\", \"{C49859B4-B34C-4594-A307-674719F71122}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Api\", \"..\\Shared\\src\\Api\\Api.csproj\", \"{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Client\", \"..\\Shared\\src\\Client\\Client.csproj\", \"{3BFAC242-776F-4B31-9658-D48F05BF355D}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x64.Build.0 = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12}.Release|x86.Build.0 = Release|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Release|x64.Build.0 = Release|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{C49859B4-B34C-4594-A307-674719F71122}.Release|x86.Build.0 = Release|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Release|x64.Build.0 = Release|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{BC4283E1-A6F7-43BF-B0E4-8D91531DD0BE}.Release|x86.Build.0 = Release|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Release|x64.Build.0 = Release|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{3BFAC242-776F-4B31-9658-D48F05BF355D}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{BF5923FF-9E93-4C01-93C2-8CE7A3F62D12} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\t\t{C49859B4-B34C-4594-A307-674719F71122} = {BD8BA25C-A91D-419D-99B6-B575ADD6D061}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {84D5AF06-1243-46F1-9D58-70ED572832C3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/Quickstart.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> IdentityResources =>\n        new List<IdentityResource>\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n        };\n\n\n    public static IEnumerable<ApiScope> ApiScopes =>\n        new List<ApiScope>\n        {\n            new ApiScope(\"api1\", \"My API\")\n        };\n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            // machine to machine client\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            },\n            \n            // interactive ASP.NET Core MVC client\n            new Client\n            {\n                ClientId = \"mvc\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                \n                // where to redirect to after login\n                RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                // where to redirect to after logout\n                PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                AllowedScopes = new List<string>\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    \"api1\"\n                }\n            }\n        };\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Data/ApplicationDbContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.Identity.EntityFrameworkCore;\n\nnamespace IdentityServerAspNetIdentity.Data\n{\n    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>\n    {\n        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)\n            : base(options)\n        {\n        }\n\n        protected override void OnModelCreating(ModelBuilder builder)\n        {\n            base.OnModelCreating(builder);\n            // Customize the ASP.NET Identity model and override the defaults if needed.\n            // For example, you can rename the ASP.NET Identity table names and more.\n            // Add your customizations after calling base.OnModelCreating(builder);\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Data/Migrations/20180109192453_CreateIdentitySchema.Designer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace IdentityServerAspNetIdentity.Data.Migrations\n{\n    [DbContext(typeof(ApplicationDbContext))]\n    [Migration(\"20180109192453_CreateIdentitySchema\")]\n    partial class CreateIdentitySchema\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"2.0.1-rtm-125\");\n\n            modelBuilder.Entity(\"IdentityServerAspNetIdentity.Models.ApplicationUser\", b =>\n                {\n                    b.Property<string>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"AccessFailedCount\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken();\n\n                    b.Property<string>(\"Email\")\n                        .HasMaxLength(256);\n\n                    b.Property<bool>(\"EmailConfirmed\");\n\n                    b.Property<bool>(\"LockoutEnabled\");\n\n                    b.Property<DateTimeOffset?>(\"LockoutEnd\");\n\n                    b.Property<string>(\"NormalizedEmail\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedUserName\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"PasswordHash\");\n\n                    b.Property<string>(\"PhoneNumber\");\n\n                    b.Property<bool>(\"PhoneNumberConfirmed\");\n\n                    b.Property<string>(\"SecurityStamp\");\n\n                    b.Property<bool>(\"TwoFactorEnabled\");\n\n                    b.Property<string>(\"UserName\")\n                        .HasMaxLength(256);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedEmail\")\n                        .HasName(\"EmailIndex\");\n\n                    b.HasIndex(\"NormalizedUserName\")\n                        .IsUnique()\n                        .HasName(\"UserNameIndex\");\n\n                    b.ToTable(\"AspNetUsers\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRole\", b =>\n                {\n                    b.Property<string>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken();\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedName\")\n                        .HasMaxLength(256);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedName\")\n                        .IsUnique()\n                        .HasName(\"RoleNameIndex\");\n\n                    b.ToTable(\"AspNetRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ClaimType\");\n\n                    b.Property<string>(\"ClaimValue\");\n\n                    b.Property<string>(\"RoleId\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetRoleClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ClaimType\");\n\n                    b.Property<string>(\"ClaimValue\");\n\n                    b.Property<string>(\"UserId\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n                {\n                    b.Property<string>(\"LoginProvider\");\n\n                    b.Property<string>(\"ProviderKey\");\n\n                    b.Property<string>(\"ProviderDisplayName\");\n\n                    b.Property<string>(\"UserId\")\n                        .IsRequired();\n\n                    b.HasKey(\"LoginProvider\", \"ProviderKey\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserLogins\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n                {\n                    b.Property<string>(\"UserId\");\n\n                    b.Property<string>(\"RoleId\");\n\n                    b.HasKey(\"UserId\", \"RoleId\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetUserRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n                {\n                    b.Property<string>(\"UserId\");\n\n                    b.Property<string>(\"LoginProvider\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<string>(\"Value\");\n\n                    b.HasKey(\"UserId\", \"LoginProvider\", \"Name\");\n\n                    b.ToTable(\"AspNetUserTokens\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n                {\n                    b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\")\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n                {\n                    b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\")\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Data/Migrations/20180109192453_CreateIdentitySchema.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace IdentityServerAspNetIdentity.Data.Migrations\n{\n    public partial class CreateIdentitySchema : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"AspNetRoles\",\n                columns: table => new\n                {\n                    Id = table.Column<string>(nullable: false),\n                    ConcurrencyStamp = table.Column<string>(nullable: true),\n                    Name = table.Column<string>(maxLength: 256, nullable: true),\n                    NormalizedName = table.Column<string>(maxLength: 256, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetRoles\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUsers\",\n                columns: table => new\n                {\n                    Id = table.Column<string>(nullable: false),\n                    AccessFailedCount = table.Column<int>(nullable: false),\n                    ConcurrencyStamp = table.Column<string>(nullable: true),\n                    Email = table.Column<string>(maxLength: 256, nullable: true),\n                    EmailConfirmed = table.Column<bool>(nullable: false),\n                    LockoutEnabled = table.Column<bool>(nullable: false),\n                    LockoutEnd = table.Column<DateTimeOffset>(nullable: true),\n                    NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),\n                    NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),\n                    PasswordHash = table.Column<string>(nullable: true),\n                    PhoneNumber = table.Column<string>(nullable: true),\n                    PhoneNumberConfirmed = table.Column<bool>(nullable: false),\n                    SecurityStamp = table.Column<string>(nullable: true),\n                    TwoFactorEnabled = table.Column<bool>(nullable: false),\n                    UserName = table.Column<string>(maxLength: 256, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUsers\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetRoleClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"Sqlite:Autoincrement\", true),\n                    ClaimType = table.Column<string>(nullable: true),\n                    ClaimValue = table.Column<string>(nullable: true),\n                    RoleId = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetRoleClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_AspNetRoleClaims_AspNetRoles_RoleId\",\n                        column: x => x.RoleId,\n                        principalTable: \"AspNetRoles\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserClaims\",\n                columns: table => new\n                {\n                    Id = table.Column<int>(nullable: false)\n                        .Annotation(\"Sqlite:Autoincrement\", true),\n                    ClaimType = table.Column<string>(nullable: true),\n                    ClaimValue = table.Column<string>(nullable: true),\n                    UserId = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserClaims\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserClaims_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserLogins\",\n                columns: table => new\n                {\n                    LoginProvider = table.Column<string>(nullable: false),\n                    ProviderKey = table.Column<string>(nullable: false),\n                    ProviderDisplayName = table.Column<string>(nullable: true),\n                    UserId = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserLogins\", x => new { x.LoginProvider, x.ProviderKey });\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserLogins_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserRoles\",\n                columns: table => new\n                {\n                    UserId = table.Column<string>(nullable: false),\n                    RoleId = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserRoles\", x => new { x.UserId, x.RoleId });\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserRoles_AspNetRoles_RoleId\",\n                        column: x => x.RoleId,\n                        principalTable: \"AspNetRoles\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserRoles_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AspNetUserTokens\",\n                columns: table => new\n                {\n                    UserId = table.Column<string>(nullable: false),\n                    LoginProvider = table.Column<string>(nullable: false),\n                    Name = table.Column<string>(nullable: false),\n                    Value = table.Column<string>(nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AspNetUserTokens\", x => new { x.UserId, x.LoginProvider, x.Name });\n                    table.ForeignKey(\n                        name: \"FK_AspNetUserTokens_AspNetUsers_UserId\",\n                        column: x => x.UserId,\n                        principalTable: \"AspNetUsers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetRoleClaims_RoleId\",\n                table: \"AspNetRoleClaims\",\n                column: \"RoleId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"RoleNameIndex\",\n                table: \"AspNetRoles\",\n                column: \"NormalizedName\",\n                unique: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserClaims_UserId\",\n                table: \"AspNetUserClaims\",\n                column: \"UserId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserLogins_UserId\",\n                table: \"AspNetUserLogins\",\n                column: \"UserId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_AspNetUserRoles_RoleId\",\n                table: \"AspNetUserRoles\",\n                column: \"RoleId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"EmailIndex\",\n                table: \"AspNetUsers\",\n                column: \"NormalizedEmail\");\n\n            migrationBuilder.CreateIndex(\n                name: \"UserNameIndex\",\n                table: \"AspNetUsers\",\n                column: \"NormalizedUserName\",\n                unique: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"AspNetRoleClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserClaims\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserLogins\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserRoles\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUserTokens\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetRoles\");\n\n            migrationBuilder.DropTable(\n                name: \"AspNetUsers\");\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Data/Migrations/ApplicationDbContextModelSnapshot.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\nusing Microsoft.EntityFrameworkCore.Infrastructure;\n\nnamespace IdentityServerAspNetIdentity.Data.Migrations\n{\n    [DbContext(typeof(ApplicationDbContext))]\n    partial class ApplicationDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"2.0.1-rtm-125\");\n\n            modelBuilder.Entity(\"IdentityServerAspNetIdentity.Models.ApplicationUser\", b =>\n                {\n                    b.Property<string>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"AccessFailedCount\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken();\n\n                    b.Property<string>(\"Email\")\n                        .HasMaxLength(256);\n\n                    b.Property<bool>(\"EmailConfirmed\");\n\n                    b.Property<bool>(\"LockoutEnabled\");\n\n                    b.Property<DateTimeOffset?>(\"LockoutEnd\");\n\n                    b.Property<string>(\"NormalizedEmail\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedUserName\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"PasswordHash\");\n\n                    b.Property<string>(\"PhoneNumber\");\n\n                    b.Property<bool>(\"PhoneNumberConfirmed\");\n\n                    b.Property<string>(\"SecurityStamp\");\n\n                    b.Property<bool>(\"TwoFactorEnabled\");\n\n                    b.Property<string>(\"UserName\")\n                        .HasMaxLength(256);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedEmail\")\n                        .HasName(\"EmailIndex\");\n\n                    b.HasIndex(\"NormalizedUserName\")\n                        .IsUnique()\n                        .HasName(\"UserNameIndex\");\n\n                    b.ToTable(\"AspNetUsers\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRole\", b =>\n                {\n                    b.Property<string>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken();\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedName\")\n                        .HasMaxLength(256);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedName\")\n                        .IsUnique()\n                        .HasName(\"RoleNameIndex\");\n\n                    b.ToTable(\"AspNetRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ClaimType\");\n\n                    b.Property<string>(\"ClaimValue\");\n\n                    b.Property<string>(\"RoleId\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetRoleClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ClaimType\");\n\n                    b.Property<string>(\"ClaimValue\");\n\n                    b.Property<string>(\"UserId\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n                {\n                    b.Property<string>(\"LoginProvider\");\n\n                    b.Property<string>(\"ProviderKey\");\n\n                    b.Property<string>(\"ProviderDisplayName\");\n\n                    b.Property<string>(\"UserId\")\n                        .IsRequired();\n\n                    b.HasKey(\"LoginProvider\", \"ProviderKey\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserLogins\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n                {\n                    b.Property<string>(\"UserId\");\n\n                    b.Property<string>(\"RoleId\");\n\n                    b.HasKey(\"UserId\", \"RoleId\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetUserRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n                {\n                    b.Property<string>(\"UserId\");\n\n                    b.Property<string>(\"LoginProvider\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<string>(\"Value\");\n\n                    b.HasKey(\"UserId\", \"LoginProvider\", \"Name\");\n\n                    b.ToTable(\"AspNetUserTokens\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n                {\n                    b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\")\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n                {\n                    b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\")\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServerAspNetIdentity.Models.ApplicationUser\")\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerAspNetIdentity;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Linq;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using System.Text.Json;\nglobal using static IdentityModel.JwtClaimTypes;\nglobal using IdentityServerClaimValueTypes = IdentityServer8.IdentityServerConstants.ClaimValueTypes;\nglobal using IdentityServerAspNetIdentity.Data;\nglobal using IdentityServerAspNetIdentity.Models;\nglobal using Microsoft.AspNetCore.Identity;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Secret = IdentityServer8.Models.Secret;"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/IdentityServerAspNetIdentity.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"jQuery\" />\n    <PackageReference Include=\"jQuery.validation\" />\n    <PackageReference Include=\"HigginsSoft.IdentityServer8\" />\n    <PackageReference Include=\"HigginsSoft.IdentityServer8.AspnetIdentity\" />\n     <PackageReference Include=\"HigginsSoft.IdentityServer8.Security\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Google\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n\n\n    <PackageReference Include=\"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Sqlite\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Tools\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n\n    <PackageReference Include=\"Microsoft.AspNetCore.Identity.EntityFrameworkCore\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Identity.UI\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Models/ApplicationUser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.Identity;\n\nnamespace IdentityServerAspNetIdentity.Models\n{\n    // Add profile data for application users by adding properties to the ApplicationUser class\n    public class ApplicationUser : IdentityUser\n    {\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\ntry\n{\n    var builder = WebApplication.CreateBuilder(args.Where(x => x != \"/seed\").ToArray());\n\n    var services = builder.Services;\n\n    services.AddControllersWithViews();\n\n    services.AddDbContext<ApplicationDbContext>(options =>\n        options.UseSqlite(builder.Configuration.GetConnectionString(\"DefaultConnection\")));\n\n    services.AddIdentity<ApplicationUser, IdentityRole>()\n        .AddEntityFrameworkStores<ApplicationDbContext>()\n        .AddDefaultTokenProviders();\n\n    services.AddIdentityServer(options =>\n         {\n             options.Events.RaiseErrorEvents = true;\n             options.Events.RaiseInformationEvents = true;\n             options.Events.RaiseFailureEvents = true;\n             options.Events.RaiseSuccessEvents = true;\n\n             // see https://IdentityServer8.readthedocs.io/en/latest/topics/resources.html\n             options.EmitStaticAudienceClaim = true;\n         })\n         .AddInMemoryIdentityResources(Config.IdentityResources)\n         .AddInMemoryApiScopes(Config.ApiScopes)\n         .AddInMemoryClients(Config.Clients)\n         .AddAspNetIdentity<ApplicationUser>()\n         // not recommended for production - you need to store your key material somewhere secure\n         .AddDeveloperSigningCredential();\n\n\n    services.AddAuthentication()\n        .AddGoogle(options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            // register your IdentityServer with Google at https://console.developers.google.com\n            // enable the Google+ API\n            // set the redirect URI to https://localhost:5001/signin-google\n            options.ClientId = \"copy client ID from Google here\";\n            options.ClientSecret = \"copy client secret from Google here\";\n        });\n\n\n    using (var app = builder.Build())\n    {\n\n\n        if (args.Contains(\"/seed\"))\n        {\n            Log.Information(\"Seeding database...\");\n            var config = app.Services.GetRequiredService<IConfiguration>();\n            var connectionString = config.GetConnectionString(\"DefaultConnection\");\n            SeedData.EnsureSeedData(connectionString);\n            Log.Information(\"Done seeding database.\");\n            return 0;\n        }\n\n        if (app.Environment.IsDevelopment())\n        {\n            app.UseDeveloperExceptionPage();\n            app.UseMigrationsEndPoint();\n            app.UseDatabaseErrorPage();\n        }\n        else\n        {\n            app.UseExceptionHandler(\"/Home/Error\");\n            app.UseHsts();\n        }\n\n\n        app.UseStaticFiles();\n\n        app.UseRouting();\n        app.UseIdentityServer();\n        app.UseAuthorization();\n        app.MapDefaultControllerRoute();\n\n\n        Log.Information(\"Starting host...\");\n\n        await app.RunAsync();\n    }\n    return 0;\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\nvoid ConfigureLogger() => Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Debug()\n    .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    // uncomment to write to Azure diagnostics stream\n    //.WriteTo.File(\n    //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n    //    fileSizeLimitBytes: 1_000_000,\n    //    rollOnFileSizeLimit: true,\n    //    shared: true,\n    //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n    .CreateLogger();\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (ModelState.IsValid)\n        {\n            // validate username/password against in-memory store\n            if (_users.ValidateCredentials(model.Username, model.Password))\n            {\n                var user = _users.FindByUsername(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                // only set explicit expiration here if user chooses \"remember me\". \n                // otherwise we rely upon expiration configured in cookie middleware.\n                AuthenticationProperties props = null;\n                if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                {\n                    props = new AuthenticationProperties\n                    {\n                        IsPersistent = true,\n                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                    };\n                };\n\n                // issue authentication cookie with subject ID and username\n                var isuser = new IdentityServerUser(user.SubjectId)\n                {\n                    DisplayName = user.Username\n                };\n\n                await HttpContext.SignInAsync(isuser, props);\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI\n{\n    public class AccountOptions\n    {\n        public static bool AllowLocalLogin = true;\n        public static bool AllowRememberLogin = true;\n        public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n        public static bool ShowLogoutPrompt = true;\n        public static bool AutomaticRedirectAfterSignOut = false;\n\n        public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly ILogger<ExternalController> _logger;\n    private readonly IEventService _events;\n\n    public ExternalController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _logger = logger;\n        _events = events;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = AutoProvisionUser(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        var isuser = new IdentityServerUser(user.SubjectId)\n        {\n            DisplayName = user.Username,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = _users.FindByExternalProvider(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonSerializer.Deserialize<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n\n    static readonly object UserAddress = new\n    {\n        street_address = \"One Hacker Way\",\n        locality = \"Heidelberg\",\n        postal_code = 69118,\n        country = \"Germany\"\n    };\n\n    public static List<TestUser> Users => new List<TestUser>\n    {\n        new()\n        {\n            SubjectId = \"818727\",\n            Username = \"alice\",\n            Password = \"alice\",\n            Claims =\n            {\n                new (Name, \"Alice Smith\"),\n                new (GivenName, \"Alice\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"AliceSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://alice.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        },\n        new()\n        {\n            SubjectId = \"88421113\",\n            Username = \"bob\",\n            Password = \"bob\",\n            Claims =\n            {\n                new (Name, \"Bob Smith\"),\n                new (GivenName, \"Bob\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"BobSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://bob.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/SeedData.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerAspNetIdentity\n{\n    public class SeedData\n    {\n        public static void EnsureSeedData(string connectionString)\n        {\n            var services = new ServiceCollection();\n            services.AddLogging();\n            services.AddDbContext<ApplicationDbContext>(options =>\n               options.UseSqlite(connectionString));\n\n            services.AddIdentity<ApplicationUser, IdentityRole>()\n                .AddEntityFrameworkStores<ApplicationDbContext>()\n                .AddDefaultTokenProviders();\n\n            using (var serviceProvider = services.BuildServiceProvider())\n            {\n                using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())\n                {\n                    var context = scope.ServiceProvider.GetService<ApplicationDbContext>();\n                    context.Database.Migrate();\n\n                    var userMgr = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();\n                    var alice = userMgr.FindByNameAsync(\"alice\").Result;\n                    if (alice == null)\n                    {\n                        alice = new ApplicationUser\n                        {\n                            UserName = \"alice\",\n                            Email = \"AliceSmith@email.com\",\n                            EmailConfirmed = true,\n                        };\n                        var result = userMgr.CreateAsync(alice, \"Pass123$\").Result;\n                        if (!result.Succeeded)\n                        {\n                            throw new Exception(result.Errors.First().Description);\n                        }\n\n                        result = userMgr.AddClaimsAsync(alice, new Claim[]{\n                            new Claim(JwtClaimTypes.Name, \"Alice Smith\"),\n                            new Claim(JwtClaimTypes.GivenName, \"Alice\"),\n                            new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                            new Claim(JwtClaimTypes.WebSite, \"http://alice.com\"),\n                        }).Result;\n                        if (!result.Succeeded)\n                        {\n                            throw new Exception(result.Errors.First().Description);\n                        }\n                        Log.Debug(\"alice created\");\n                    }\n                    else\n                    {\n                        Log.Debug(\"alice already exists\");\n                    }\n\n                    var bob = userMgr.FindByNameAsync(\"bob\").Result;\n                    if (bob == null)\n                    {\n                        bob = new ApplicationUser\n                        {\n                            UserName = \"bob\",\n                            Email = \"BobSmith@email.com\",\n                            EmailConfirmed = true\n                        };\n                        var result = userMgr.CreateAsync(bob, \"Pass123$\").Result;\n                        if (!result.Succeeded)\n                        {\n                            throw new Exception(result.Errors.First().Description);\n                        }\n\n                        result = userMgr.AddClaimsAsync(bob, new Claim[]{\n                            new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                            new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                            new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                            new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                            new Claim(\"location\", \"somewhere\")\n                        }).Result;\n                        if (!result.Succeeded)\n                        {\n                            throw new Exception(result.Errors.First().Description);\n                        }\n                        Log.Debug(\"bob created\");\n                    }\n                    else\n                    {\n                        Log.Debug(\"bob already exists\");\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n\n@{\n    var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Ioc.Sanitizer.Url.Sanitize(Model.RedirectUrl)';\n    window.location.href = url;\n</script>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/appsettings.json",
    "content": "﻿{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Data Source=AspIdUsers.db;\"\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/updateUI.ps1",
    "content": "iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer8.Quickstart.UI.AspNetIdentity/main/getmain.ps1'))\t\n# SIG # Begin signature block\n# MIIfnQYJKoZIhvcNAQcCoIIfjjCCH4oCAQExDzANBglghkgBZQMEAgEFADB5Bgor\n# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG\n# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAmjChzA8Tk4hB4\n# nAolI/h9hR7E40n+o1koeC4dCBgwCqCCDgcwggPFMIICraADAgECAhACrFwmagtA\n# m48LefKuRiV3MA0GCSqGSIb3DQEBBQUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK\n# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNV\n# BAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMDYxMTEw\n# MDAwMDAwWhcNMzExMTEwMDAwMDAwWjBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM\n# RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQD\n# EyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMIIBIjANBgkqhkiG\n# 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxszlc+b71LvlLS0ypt/lgT/JzSVJtnEqw9WU\n# NGeiChywX2mmQLHEt7KP0JikqUFZOtPclNY823Q4pErMTSWC90qlUxI47vNJbXGR\n# fmO2q6Zfw6SE+E9iUb74xezbOJLjBuUIkQzEKEFV+8taiRV+ceg1v01yCT2+OjhQ\n# W3cxG42zxyRFmqesbQAUWgS3uhPrUQqYQUEiTmVhh4FBUKZ5XIneGUpX1S7mXRxT\n# LH6YzRoGFqRoc9A0BBNcoXHTWnxV215k4TeHMFYE5RG0KYAS8Xk5iKICEXwnZreI\n# t3jyygqoOKsKZMK/Zl2VhMGhJR6HXRpQCyASzEG7bgtROLhLywIDAQABo2MwYTAO\n# BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUsT7DaQP4\n# v0cB1JgmGggC72NkK8MwHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8Mw\n# DQYJKoZIhvcNAQEFBQADggEBABwaBpfc15yfPIhmBghXIdshR/gqZ6q/GDJ2QBBX\n# wYrzetkRZY41+p78RbWe2UwxS7iR6EMsjrN4ztvjU3lx1uUhlAHaVYeaJGT2imbM\n# 3pw3zag0sWmbI8ieeCIrcEPjVUcxYRnvWMWFL04w9qAxFiPI5+JlFjPLvxoboD34\n# yl6LMYtgCIktDAZcUrfE+QqY0RVfnxK+fDZjOL1EpH/kJisKxJdpDemM4sAQV7jI\n# dhKRVfJIadi8KgJbD0TUIDHb9LpwJl2QYJ68SxcJL7TLHkNoyQcnwdJc9+ohuWgS\n# nDycv578gFybY83sR6olJ2egN/MAgn1U16n46S4To3foH0owggSRMIIDeaADAgEC\n# AhAHsEGNpR4UjDMbvN63E4MjMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVT\n# MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n# b20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0Ew\n# HhcNMTgwNDI3MTI0MTU5WhcNMjgwNDI3MTI0MTU5WjBaMQswCQYDVQQGEwJVUzEY\n# MBYGA1UEChMPLk5FVCBGb3VuZGF0aW9uMTEwLwYDVQQDEyguTkVUIEZvdW5kYXRp\n# b24gUHJvamVjdHMgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC\n# AQ8AMIIBCgKCAQEAwQqv4aI0CI20XeYqTTZmyoxsSQgcCBGQnXnufbuDLhAB6GoT\n# NB7HuEhNSS8ftV+6yq8GztBzYAJ0lALdBjWypMfL451/84AO5ZiZB3V7MB2uxgWo\n# cV1ekDduU9bm1Q48jmR4SVkLItC+oQO/FIA2SBudVZUvYKeCJS5Ri9ibV7La4oo7\n# BJChFiP8uR+v3OU33dgm5BBhWmth4oTyq22zCfP3NO6gBWEIPFR5S+KcefUTYmn2\n# o7IvhvxzJsMCrNH1bxhwOyMl+DQcdWiVPuJBKDOO/hAKIxBG4i6ryQYBaKdhDgaA\n# NSCik0UgZasz8Qgl8n0A73+dISPumD8L/4mdywIDAQABo4IBPzCCATswHQYDVR0O\n# BBYEFMtck66Im/5Db1ZQUgJtePys4bFaMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY\n# JhoIAu9jZCvDMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzAS\n# BgNVHRMBAf8ECDAGAQH/AgEAMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY\n# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6\n# Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RD\n# QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v\n# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQELBQADggEBALNGxKTz6gq6\n# clMF01GjC3RmJ/ZAoK1V7rwkqOkY3JDl++v1F4KrFWEzS8MbZsI/p4W31Eketazo\n# Nxy23RT0zDsvJrwEC3R+/MRdkB7aTecsYmMeMHgtUrl3xEO3FubnQ0kKEU/HBCTd\n# hR14GsQEccQQE6grFVlglrew+FzehWUu3SUQEp9t+iWpX/KfviDWx0H1azilMX15\n# lzJUxK7kCzmflrk5jCOCjKqhOdGJoQqstmwP+07qXO18bcCzEC908P+TYkh0z9gV\n# rlj7tyW9K9zPVPJZsLRaBp/QjMcH65o9Y1hD1uWtFQYmbEYkT1K9tuXHtQYx1Rpf\n# /dC8Nbl4iukwggWlMIIEjaADAgECAhAL5Ofkz0TFYBmonpg7pehYMA0GCSqGSIb3\n# DQEBCwUAMFoxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw8uTkVUIEZvdW5kYXRpb24x\n# MTAvBgNVBAMTKC5ORVQgRm91bmRhdGlvbiBQcm9qZWN0cyBDb2RlIFNpZ25pbmcg\n# Q0EwHhcNMTgwNjExMDAwMDAwWhcNMjEwNjE1MTIwMDAwWjCBoDEUMBIGA1UEBRML\n# NjAzIDM4OSAwNjgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw\n# DgYDVQQHEwdSZWRtb25kMSkwJwYDVQQKEyBJZGVudGl0eVNlcnZlciAoLk5FVCBG\n# b3VuZGF0aW9uKTEpMCcGA1UEAxMgSWRlbnRpdHlTZXJ2ZXIgKC5ORVQgRm91bmRh\n# dGlvbikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwEhFpSIYi3hrr\n# v/X9BtZkzufk7puhmTCVmQAPNm2R1eZZyMPhfxm5Sh/w/42CzlCG9LFgooha69z3\n# uoMMOKJEEQKZ6ByIV+r81o4lrHtSFbe4VlXavjQVFaVVjPSG6vWGykfHVCAeVpjx\n# fVk/HH6tEX506lBiHgOrQGogoQrwdVnObc3c6RiVSIuvFeCoHvk2GgiqyzFER7iO\n# R1055npVSAAAdxBvPA6KREcLb/qHukYCJZX4mY/SajBXwxupSnhRDbYhb+qHpFIL\n# x7s/azxg7tVRpVh49oJimHA2uZ/jzh/KgUsUe9MFzT7KPduBK/pfX/fXED9Pt1NN\n# 48VfPSuzAgMBAAGjggIeMIICGjAfBgNVHSMEGDAWgBTLXJOuiJv+Q29WUFICbXj8\n# rOGxWjAdBgNVHQ4EFgQU3CQnBPLvFkovKU/is0/LgQF/49swNAYDVR0RBC0wK6Ap\n# BggrBgEFBQcIA6AdMBsMGVVTLVdBU0hJTkdUT04tNjAzIDM4OSAwNjgwDgYDVR0P\n# AQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIGZBgNVHR8EgZEwgY4wRaBD\n# oEGGP2h0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9ORVRGb3VuZGF0aW9uUHJvamVj\n# dHNDb2RlU2lnbmluZ0NBLmNybDBFoEOgQYY/aHR0cDovL2NybDQuZGlnaWNlcnQu\n# Y29tL05FVEZvdW5kYXRpb25Qcm9qZWN0c0NvZGVTaWduaW5nQ0EuY3JsMEwGA1Ud\n# IARFMEMwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRp\n# Z2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYIKwYB\n# BQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0\n# cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL05FVEZvdW5kYXRpb25Qcm9qZWN0c0Nv\n# ZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEB\n# AH0FqXX4p5RlC27jX6tcTEf2HT4mAiqosnYU/napWgQE2U9m73IZO+2MuiQWkUQi\n# 2PLjbQQcOwfMwkt0SDaSAlfC1zhjZkZb2NcpJRg0cUAjcDzqh6hTzXRVJPD/UrW2\n# a5qBhYnSQDSWbYnVwfAQFFvnQcR5i/xnoOxq7+3LIvHoJafpsxcAFS57Vdsuw91u\n# keB6uasOfvdd06Mpl9BLWZHpyEdnPIKMv6ALibTdw9lNzCQ+EmdT5Fwky8wHE8BH\n# hhAdjSuGiyd+AzR3IuL96Q41h34c7pL827atOHwkkjUx+QTVkXbYoal6wwBKhi6I\n# QJEhT0s/yyFFM7BrLhQpRSsxghDsMIIQ6AIBATBuMFoxCzAJBgNVBAYTAlVTMRgw\n# FgYDVQQKEw8uTkVUIEZvdW5kYXRpb24xMTAvBgNVBAMTKC5ORVQgRm91bmRhdGlv\n# biBQcm9qZWN0cyBDb2RlIFNpZ25pbmcgQ0ECEAvk5+TPRMVgGaiemDul6FgwDQYJ\n# YIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG\n# 9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIB\n# FTAvBgkqhkiG9w0BCQQxIgQg3M8y2Uovs3GZZGILEzOaZ5eGje/9PkpzoByKnbYv\n# zTYwDQYJKoZIhvcNAQEBBQAEggEAnU9xhSBP/Rv/Cgvmzp0LcG8pjxPlbjvPef7V\n# xvkeQzTvMHYg0LiveMH1y94PyfBdxqUAGRuCblBOmlECw24w8Hdv8dY2LQMhqJu8\n# Qt08UVYtiJQBHwclFmnK8ER8g/Wc5LPsuvzoYzTvvr/FS2wSCaMV7p2WHIwjJxXR\n# sLaccoU2fuPbmE1WVPsjy3ttzkmfyhbl3Mc2QXiLNTQJ+gSNBg2s2eSzf7eDcM2Z\n# kysuAEdu4kKhSsHOhkkpBHffplg9pYrehbUq8QJ+T/9e0vHPbbP5xIPaRqvBEMWy\n# ydh0LWvK6GnJ+/yPHjddtrjpY4ncTlK5ii+wyzyZc9k4rryOKaGCDsgwgg7EBgor\n# BgEEAYI3AwMBMYIOtDCCDrAGCSqGSIb3DQEHAqCCDqEwgg6dAgEDMQ8wDQYJYIZI\n# AWUDBAIBBQAwdwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG/WwHATAxMA0G\n# CWCGSAFlAwQCAQUABCDIQfwOJSjewgHOlovqbOQetKuLbiiSjibgzLTQTnzqLAIQ\n# BSEyueNQrxAikpAH0FblzhgPMjAyMDA2MjUxNDI4NTNaoIILuzCCBoIwggVqoAMC\n# AQICEATNP4VornbGG7D+cWDMp20wDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMC\n# VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0\n# LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFt\n# cGluZyBDQTAeFw0xOTEwMDEwMDAwMDBaFw0zMDEwMTcwMDAwMDBaMEwxCzAJBgNV\n# BAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEkMCIGA1UEAxMbVElNRVNU\n# QU1QLVNIQTI1Ni0yMDE5LTEwLTE1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n# CgKCAQEA6WQ1nPqpmGVkG+QX3LgpNsxnCViFTTDgyf/lOzwRKFCvBzHiXQkYwvaJ\n# jGkIBCPgdy2dFeW46KFqjv/UrtJ6Fu/4QbUdOXXBzy+nrEV+lG2sAwGZPGI+fnr9\n# RZcxtPq32UI+p1Wb31pPWAKoMmkiE76Lgi3GmKtrm7TJ8mURDHQNsvAIlnTE6LJI\n# oqEUpfj64YlwRDuN7/uk9MO5vRQs6wwoJyWAqxBLFhJgC2kijE7NxtWyZVkh4Hws\n# Eo1wDo+KyuDT17M5d1DQQiwues6cZ3o4d1RA/0+VBCDU68jOhxQI/h2A3dDnK3jq\n# vx9wxu5CFlM2RZtTGUlinXoCm5UUowIDAQABo4IDODCCAzQwDgYDVR0PAQH/BAQD\n# AgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwggG/BgNV\n# HSAEggG2MIIBsjCCAaEGCWCGSAGG/WwHATCCAZIwKAYIKwYBBQUHAgEWHGh0dHBz\n# Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwggFkBggrBgEFBQcCAjCCAVYeggFSAEEA\n# bgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEA\n# dABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMA\n# ZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMA\n# IABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEA\n# ZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEA\n# YgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEA\n# dABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4w\n# CwYJYIZIAYb9bAMVMB8GA1UdIwQYMBaAFPS24SAd/imu0uRhpbKiJbLIFzVuMB0G\n# A1UdDgQWBBRWUw/BxgenTdfYbldygFBM5OyewTBxBgNVHR8EajBoMDKgMKAuhixo\n# dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRzLmNybDAyoDCg\n# LoYsaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC10cy5jcmww\n# gYUGCCsGAQUFBwEBBHkwdzAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl\n# cnQuY29tME8GCCsGAQUFBzAChkNodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v\n# RGlnaUNlcnRTSEEyQXNzdXJlZElEVGltZXN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3\n# DQEBCwUAA4IBAQAug6FEBUoE47kyUvrZgfAau/gJjSO5PdiSoeZGHEovbno8Y243\n# F6Mav1gjskOclINOOQmwLOjH4eLM7ct5a87eIwFH7ZVUgeCAexKxrwKGqTpzav74\n# n8GN0SGM5CmCw4oLYAACnR9HxJ+0CmhTf1oQpvgi5vhTkjFf2IKDLW0TQq6DwRBO\n# pCT0R5zeDyJyd1x/T+k5mCtXkkTX726T2UPHBDNjUTdWnkcEEcOjWFQh2OKOVtdJ\n# P1f8Cp8jXnv0lI3dnRq733oqptJFplUMj/ZMivKWz4lG3DGykZCjXzMwYFX1/Gsw\n# rKHt5EdOM55naii1TcLtW5eC+MupCGxTCbT3MIIFMTCCBBmgAwIBAgIQCqEl1tYy\n# G35B5AXaNpfCFTANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UE\n# ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD\n# VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTYwMTA3MTIwMDAw\n# WhcNMzEwMTA3MTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl\n# cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdp\n# Q2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMIIBIjANBgkqhkiG\n# 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdAy7kvNj3/dqbqCmcU5VChXtiNKxA4HRTNR\n# EH3Q+X1NaH7ntqD0jbOI5Je/YyGQmL8TvFfTw+F+CNZqFAA49y4eO+7MpvYyWf5f\n# ZT/gm+vjRkcGGlV+Cyd+wKL1oODeIj8O/36V+/OjuiI+GKwR5PCZA207hXwJ0+5d\n# yJoLVOOoCXFr4M8iEA91z3FyTgqt30A6XLdR4aF5FMZNJCMwXbzsPGBqrC8HzP3w\n# 6kfZiFBe/WZuVmEnKYmEUeaC50ZQ/ZQqLKfkdT66mA+Ef58xFNat1fJky3seBdCE\n# GXIX8RcG7z3N1k3vBkL9olMqT4UdxB08r8/arBD13ays6Vb/kwIDAQABo4IBzjCC\n# AcowHQYDVR0OBBYEFPS24SAd/imu0uRhpbKiJbLIFzVuMB8GA1UdIwQYMBaAFEXr\n# oq/0ksuCMS1Ri6enIZ3zbcgPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/\n# BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHkGCCsGAQUFBwEBBG0wazAkBggr\n# BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdo\n# dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290\n# Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5j\n# b20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3Js\n# My5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMFAGA1Ud\n# IARJMEcwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k\n# aWdpY2VydC5jb20vQ1BTMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAQEA\n# cZUS6VGHVmnN793afKpjerN4zwY3QITvS4S/ys8DAv3Fp8MOIEIsr3fzKx8MIVoq\n# twU0HWqumfgnoma/Capg33akOpMP+LLR2HwZYuhegiUexLoceywh4tZbLBQ1QwRo\n# stt1AuByx5jWPGTlH0gQGF+JOGFNYkYkh2OMkVIsrymJ5Xgf1gsUpYDXEkdws3XV\n# k4WTfraSZ/tTYYmo9WuWwPRYaQ18yAGxuSh1t5ljhSKMYcp5lH5Z/IwP42+1ASa2\n# bKXuh1Eh5Fhgm7oMLSttosR+u8QlK0cCCHxJrhO24XxCQijGGFbPQTS2Zl22dHv1\n# VjMiLyI2skuiSpXY9aaOUjGCAk0wggJJAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUw\n# EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x\n# MTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcg\n# Q0ECEATNP4VornbGG7D+cWDMp20wDQYJYIZIAWUDBAIBBQCggZgwGgYJKoZIhvcN\n# AQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yMDA2MjUxNDI4NTNa\n# MCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFAMlvVBe2pYwLcIvT6AeTCi+KDTFMC8G\n# CSqGSIb3DQEJBDEiBCAvoc+rYs7skpQOtoc7TrhDopI+gY0L5n1xBAzyBSyC8TAN\n# BgkqhkiG9w0BAQEFAASCAQCRIBcC0oeOOjuPQ2x9QeqG+lmZXas8Y2P9oaXzmbFS\n# 6okl0cflVVL3m9EvPJ3ofob8aQ9PRmyJRIaDP24R8GGS9m8ZTLZJvg8wPOtoE/3t\n# mLfPaY1KFSqtKWF8sLSHkWJzF50FvboB00E4f1mRDBCAZPNfyKSBYiW7b60Blcnz\n# mf721nSHxPPbGtoU4ObXcR4qHyWbrlIMcihIkkwf8HEU3MqqsLSnpGoKeNvS/quz\n# N2mp2eJl9YezOn+yzSkDKSQKg5x+2ZI/2UCstJaq73ahuRSpcdw3Lu6FgWs7n8Wc\n# N6gU/Mpvb3GqgwZWpbSoa9PusWSNLjOyrWAwjhdeBCvV\n# SIG # End signature block\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/wwwroot/js/signin-redirect.js",
    "content": "// window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/IdentityServerAspNetIdentity/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly ILogger<HomeController> _logger;\n\n    public HomeController(ILogger<HomeController> logger)\n    {\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    public async Task<IActionResult> CallApi()\n    {\n        var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = new HttpClient();\n        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n        var content = await client.GetStringAsync(\"https://localhost:6001/identity\");\n\n        var obj = JsonSerializer.Deserialize<JsonElement>(content);\n        ViewBag.Json = obj.ToString();\n        return View(\"json\");\n    }\n\n    public IActionResult Logout()\n    {\n        return SignOut(\"Cookies\", \"oidc\");\n    }\n\n    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n    public IActionResult Error()\n    {\n        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using System.Diagnostics;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net.Http.Headers;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Models/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class ErrorViewModel\n{\n    public string RequestId { get; set; }\n\n    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/MvcClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Update=\"Views\\Shared\\Json.cshtml\">\n      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n    </Content>\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddControllersWithViews();\nbuilder.Services\n    .AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"Cookies\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n    .AddCookie(\"Cookies\")\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        options.Authority = \"https://localhost:5001\";\n\n        options.ClientId = \"mvc\";\n        options.ClientSecret = \"secret\";\n        options.ResponseType = \"code\";\n\n        options.Scope.Add(\"api1\");\n\n        options.SaveTokens = true;\n    });\n\n\nusing (var app = builder.Build())\n{\n    if (app.Environment.IsDevelopment())\n        app.UseDeveloperExceptionPage();\n    else\n        app.UseExceptionHandler(\"/Home/Error\");\n\n    app.UseStaticFiles();\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n    app.MapDefaultControllerRoute().RequireAuthorization();\n\n    await app.RunAsync();\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"MvcClient\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5002\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/Home/Index.cshtml",
    "content": "@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/Home/Privacy.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Privacy Policy\";\n}\n<h1>@ViewData[\"Title\"]</h1>\n\n<p>Use this page to detail your site's privacy policy.</p>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/Shared/Error.cshtml",
    "content": "﻿@model ErrorViewModel\n@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n@if (Model.ShowRequestId)\n{\n    <p>\n        <strong>Request ID:</strong> <code>@Model.RequestId</code>\n    </p>\n}\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n    It can result in displaying sensitive information from exceptions to end users.\n    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n    and restarting the app.\n</p>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcClient</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcClient</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/Shared/json.cshtml",
    "content": "<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Quickstarts/6_AspNetIdentity/src/MvcClient/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/Quickstarts/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "samples/Quickstarts/Quickstart.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft\n Written by Alexander Higgins https://github.com/alexhiggins732/ \n \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code for this software can be found at https://github.com/alexhiggins732/IdentityServer8\n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n\n*/\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/Api/Api.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n</Project>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/Api/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.Mvc;\n\nConsole.Title = \"API\";\n\nvar builder = WebApplication.CreateBuilder(args);\n\nvar services = builder.Services;\n\n// accepts any access token issued by identity server\n// adds an authorization policy for scope 'api1'\nservices\n    .AddAuthorization(options =>\n    {\n        options.AddPolicy(\"ApiScope\", policy =>\n        {\n            policy\n                .RequireAuthenticatedUser()\n                .RequireClaim(\"scope\", \"api1\");\n        });\n    })\n    .AddCors(options =>\n    {\n        // this defines a CORS policy called \"default\"\n        options.AddPolicy(\"default\", policy =>\n        {\n            policy.WithOrigins(\"https://localhost:5003\")\n                .AllowAnyHeader()\n                .AllowAnyMethod();\n        });\n    })\n    .AddControllers();\n\n// accepts any access token issued by identity server\nservices\n    .AddAuthentication(\"Bearer\")\n    .AddJwtBearer(\"Bearer\", options =>\n    {\n        options.Authority = \"https://localhost:5001\";\n        options.TokenValidationParameters =\n            new() { ValidateAudience = false };\n    });\n\n\n\nusing (var app = builder.Build())\n{\n    if (app.Environment.IsDevelopment())\n        app.UseDeveloperExceptionPage();\n\n    app\n        .UseRouting()\n        .UseAuthentication()\n        .UseAuthorization()\n        .UseCors(\"default\");\n\n    app.MapGet(\"/identity\", (HttpContext context) =>\n            new JsonResult(context?.User?.Claims.Select(c => new { c.Type, c.Value }))\n        ).RequireAuthorization(\"ApiScope\");\n\n    await app.RunAsync();\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/Api/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:6001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/Shared/src/Client/Client.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"IdentityModel\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/Client/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityModel.Client;\nusing System.Diagnostics;\nusing System.Text.Json;\n\n// discover endpoints from metadata\nusing HttpClient client = new();\n\nvar disco = await client.GetDiscoveryDocumentAsync(\"https://localhost:5001\");\nif (disco.IsError)\n    Exit(disco.Error);\n\n// request token\nvar tokenResponse = await client.RequestClientCredentialsTokenAsync(\n    new()\n{\n    Address = disco.TokenEndpoint,\n    ClientId = \"client\",\n    ClientSecret = \"secret\",\n\n    Scope = \"api1\"\n});\n\nif (tokenResponse.IsError)\n    Exit(tokenResponse.Error);\n\nConsole.WriteLine(tokenResponse.Json);\nConsole.WriteLine(\"\\n\\n\");\n\n// call api\nclient.SetBearerToken(tokenResponse.AccessToken);\n\nvar response = await client.GetAsync(\"https://localhost:6001/identity\");\nif (!response.IsSuccessStatusCode)\n    Console.WriteLine(response.StatusCode);\nelse\n{\n    var responseJson = await response.Content.ReadAsStringAsync();\n    var obj = JsonSerializer.Deserialize<JsonElement>(responseJson);\n    Console.WriteLine(obj);\n}\n\nExit(\"Done!\", 0);\n\nvoid Exit(string message, int exitCode = 1)\n{\n    Console.WriteLine(message);\n    if (Debugger.IsAttached)\n        Debugger.Break();\n    Environment.Exit(exitCode);\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic static class Config\n{\n    public static IEnumerable<IdentityResource> IdentityResources =>\n        new List<IdentityResource>\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n        };\n\n\n    public static IEnumerable<ApiScope> ApiScopes =>\n        new List<ApiScope>\n        {\n            new ApiScope(\"api1\", \"My API\")\n        };\n\n    public static IEnumerable<Client> Clients =>\n        new List<Client>\n        {\n            // machine to machine client\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                // scopes that client has access to\n                AllowedScopes = { \"api1\" }\n            },\n            \n            // interactive ASP.NET Core MVC client\n            new Client\n            {\n                ClientId = \"mvc\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                \n                // where to redirect to after login\n                RedirectUris = { \"https://localhost:5002/signin-oidc\" },\n\n                // where to redirect to after logout\n                PostLogoutRedirectUris = { \"https://localhost:5002/signout-callback-oidc\" },\n\n                AllowedScopes = new List<string>\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    \"api1\"\n                }\n            }\n        };\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using System.Text.Json;\nglobal using static IdentityModel.JwtClaimTypes;\nglobal using IdentityServerClaimValueTypes = IdentityServer8.IdentityServerConstants.ClaimValueTypes;\nglobal using ILogger = Microsoft.Extensions.Logging.ILogger;\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/IdentityServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"HigginsSoft.IdentityServer8\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n    <PackageReference Include=\"Serilog.AspNetCore\" />  \n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Google\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nConfigureLogger();\n\ntry\n{\n    Log.Information(\"Starting host...\");\n\n    var builder = WebApplication.CreateBuilder(args);\n\n    var services = builder.Services;\n\n    services.AddControllersWithViews();\n\n    services\n        .AddIdentityServer()\n        .AddInMemoryIdentityResources(Config.IdentityResources)\n        .AddInMemoryApiScopes(Config.ApiScopes)\n        .AddInMemoryClients(Config.Clients)\n        .AddTestUsers(TestUsers.Users)\n        .AddDeveloperSigningCredential();\n\n    services.AddAuthentication()\n        .AddGoogle(\"Google\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n\n            options.ClientId = \"<insert here>\";\n            options.ClientSecret = \"<insert here>\";\n        })\n        .AddOpenIdConnect(\"oidc\", \"Demo IdentityServer\", options =>\n        {\n            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n            options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n            options.SaveTokens = true;\n\n            options.Authority = \"https://demo.identityserver8.io/\";\n            options.ClientId = \"interactive.confidential\";\n            options.ClientSecret = \"secret\";\n            options.ResponseType = \"code\";\n\n            options.TokenValidationParameters = new()\n            {\n                NameClaimType = \"name\",\n                RoleClaimType = \"role\"\n            };\n        });\n\n\n    using (var app = builder.Build())\n    {\n        if (app.Environment.IsDevelopment())\n            app.UseDeveloperExceptionPage();\n\n        app.UseStaticFiles()\n            .UseRouting()\n            .UseIdentityServer()\n            .UseAuthorization();\n\n        app.MapDefaultControllerRoute();\n\n        await app.RunAsync();\n    }\n\n    return 0;\n}\ncatch (Exception ex)\n{\n    Log.Fatal(ex, \"Host terminated unexpectedly.\");\n    return 1;\n}\nfinally\n{\n    Log.CloseAndFlush();\n}\n\n\nvoid ConfigureLogger() => Log.Logger = new LoggerConfiguration()\n    .MinimumLevel.Debug()\n    .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n    .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n    .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n    .Enrich.FromLogContext()\n    // uncomment to write to Azure diagnostics stream\n    //.WriteTo.File(\n    //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n    //    fileSizeLimitBytes: 1_000_000,\n    //    rollOnFileSizeLimit: true,\n    //    shared: true,\n    //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n    .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n    .CreateLogger();\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"SelfHost\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (ModelState.IsValid)\n        {\n            // validate username/password against in-memory store\n            if (_users.ValidateCredentials(model.Username, model.Password))\n            {\n                var user = _users.FindByUsername(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                // only set explicit expiration here if user chooses \"remember me\". \n                // otherwise we rely upon expiration configured in cookie middleware.\n                AuthenticationProperties props = null;\n                if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                {\n                    props = new AuthenticationProperties\n                    {\n                        IsPersistent = true,\n                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                    };\n                };\n\n                // issue authentication cookie with subject ID and username\n                var isuser = new IdentityServerUser(user.SubjectId)\n                {\n                    DisplayName = user.Username\n                };\n\n                await HttpContext.SignInAsync(isuser, props);\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI\n{\n    public class AccountOptions\n    {\n        public static bool AllowLocalLogin = true;\n        public static bool AllowRememberLogin = true;\n        public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n        public static bool ShowLogoutPrompt = true;\n        public static bool AutomaticRedirectAfterSignOut = false;\n\n        public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly ILogger<ExternalController> _logger;\n    private readonly IEventService _events;\n\n    public ExternalController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _logger = logger;\n        _events = events;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = AutoProvisionUser(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        var isuser = new IdentityServerUser(user.SubjectId)\n        {\n            DisplayName = user.Username,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = _users.FindByExternalProvider(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonSerializer.Deserialize<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n\n    static readonly object UserAddress = new\n    {\n        street_address = \"One Hacker Way\",\n        locality = \"Heidelberg\",\n        postal_code = 69118,\n        country = \"Germany\"\n    };\n\n    public static List<TestUser> Users => new List<TestUser>\n    {\n        new()\n        {\n            SubjectId = \"818727\",\n            Username = \"alice\",\n            Password = \"alice\",\n            Claims =\n            {\n                new (Name, \"Alice Smith\"),\n                new (GivenName, \"Alice\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"AliceSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://alice.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        },\n        new()\n        {\n            SubjectId = \"88421113\",\n            Username = \"bob\",\n            Password = \"bob\",\n            Claims =\n            {\n                new (Name, \"Bob Smith\"),\n                new (GivenName, \"Bob\"),\n                new (FamilyName, \"Smith\"),\n                new (Email, \"BobSmith@email.com\"),\n                new (EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new (WebSite, \"http://bob.com\"),\n                new (Address, JsonSerializer.Serialize(UserAddress), IdentityServerClaimValueTypes.Json)\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n\n@{\n    var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Ioc.Sanitizer.Url.Sanitize(Model.RedirectUrl)';\n    window.location.href = url;\n</script>\n\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/wwwroot/js/signin-redirect.js",
    "content": "//window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/IdentityServer/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Controllers/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class HomeController : Controller\n{\n    private readonly ILogger<HomeController> _logger;\n\n    public HomeController(ILogger<HomeController> logger)\n    {\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        return View();\n    }\n\n    public async Task<IActionResult> CallApi()\n    {\n        var accessToken = await HttpContext.GetTokenAsync(\"access_token\");\n\n        var client = new HttpClient();\n        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Bearer\", accessToken);\n        var content = await client.GetStringAsync(\"https://localhost:6001/identity\");\n\n        var obj = JsonSerializer.Deserialize<JsonElement>(content);\n        ViewBag.Json = obj.ToString();\n        return View(\"json\");\n    }\n\n    public IActionResult Logout()\n    {\n        return SignOut(\"Cookies\", \"oidc\");\n    }\n\n    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n    public IActionResult Error()\n    {\n        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });\n    }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using System.Diagnostics;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net.Http.Headers;\nglobal using System.Text.Json;\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Models/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\npublic class ErrorViewModel\n{\n    public string RequestId { get; set; }\n\n    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/MvcClient.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.OpenIdConnect\" />\n    <PackageReference Include=\"Microsoft.Web.LibraryManager.Build\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Content Update=\"Views\\Shared\\Json.cshtml\">\n      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n    </Content>\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nJwtSecurityTokenHandler.DefaultMapInboundClaims = false;\n\n\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddControllersWithViews();\nbuilder.Services\n    .AddAuthentication(options =>\n    {\n        options.DefaultScheme = \"Cookies\";\n        options.DefaultChallengeScheme = \"oidc\";\n    })\n    .AddCookie(\"Cookies\")\n    .AddOpenIdConnect(\"oidc\", options =>\n    {\n        options.Authority = \"https://localhost:5001\";\n\n        options.ClientId = \"mvc\";\n        options.ClientSecret = \"secret\";\n        options.ResponseType = \"code\";\n\n        options.Scope.Add(\"api1\");\n\n        options.SaveTokens = true;\n    });\n\n\nusing (var app = builder.Build())\n{\n    if (app.Environment.IsDevelopment())\n        app.UseDeveloperExceptionPage();\n    else\n        app.UseExceptionHandler(\"/Home/Error\");\n\n    app.UseStaticFiles();\n    app.UseRouting();\n    app.UseAuthentication();\n    app.UseAuthorization();\n    app.MapDefaultControllerRoute().RequireAuthorization();\n\n    await app.RunAsync();\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"MvcClient\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5002\"\n    }\n  }\n}"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/Home/Index.cshtml",
    "content": "@using Microsoft.AspNetCore.Authentication\n\n<h2>Claims</h2>\n\n<dl>\n    @foreach (var claim in User.Claims)\n    {\n        <dt>@claim.Type</dt>\n        <dd>@claim.Value</dd>\n    }\n</dl>\n\n<h2>Properties</h2>\n\n<dl>\n    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)\n    {\n        <dt>@prop.Key</dt>\n        <dd>@prop.Value</dd>\n    }\n</dl>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/Home/Privacy.cshtml",
    "content": "﻿@{\n    ViewData[\"Title\"] = \"Privacy Policy\";\n}\n<h1>@ViewData[\"Title\"]</h1>\n\n<p>Use this page to detail your site's privacy policy.</p>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/Shared/Error.cshtml",
    "content": "﻿@model ErrorViewModel\n@{\n    ViewData[\"Title\"] = \"Error\";\n}\n\n<h1 class=\"text-danger\">Error.</h1>\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n@if (Model.ShowRequestId)\n{\n    <p>\n        <strong>Request ID:</strong> <code>@Model.RequestId</code>\n    </p>\n}\n\n<h3>Development Mode</h3>\n<p>\n    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.\n</p>\n<p>\n    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n    It can result in displaying sensitive information from exceptions to end users.\n    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n    and restarting the app.\n</p>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>@ViewData[\"Title\"] - MvcClient</title>\n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <header>\n        <nav class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\n            <div class=\"container\">\n                <a class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">MvcClient</a>\n                <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\">\n                    <span class=\"navbar-toggler-icon\"></span>\n                </button>\n                <div class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\">\n                    <ul class=\"navbar-nav flex-grow-1\">\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\">Home</a>\n                        </li>\n                        <li class=\"nav-item\">\n                            <a class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Logout\">Logout</a>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </nav>\n    </header>\n    <div class=\"container\">\n        <main role=\"main\" class=\"pb-3\">\n            @RenderBody()\n        </main>\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n    <script src=\"~/js/site.js\" asp-append-version=\"true\"></script>\n    @RenderSection(\"Scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml",
    "content": "﻿<script src=\"~/lib/jquery-validation/dist/jquery.validate.min.js\"></script>\n<script src=\"~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js\"></script>\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/Shared/json.cshtml",
    "content": "<pre>@ViewBag.Json</pre>"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/_ViewImports.cshtml",
    "content": "@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/appsettings.Development.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  }\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft\": \"Warning\",\n      \"Microsoft.Hosting.Lifetime\": \"Information\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/wwwroot/css/site.css",
    "content": "﻿/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\nfor details on configuring this project to bundle and minify static web assets. */\n\na.navbar-brand {\n  white-space: normal;\n  text-align: center;\n  word-break: break-all;\n}\n\n/* Provide sufficient contrast against white background */\na {\n  color: #0366d6;\n}\n\n.btn-primary {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n.nav-pills .nav-link.active, .nav-pills .show > .nav-link {\n  color: #fff;\n  background-color: #1b6ec2;\n  border-color: #1861ac;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  font-size: 14px;\n}\n@media (min-width: 768px) {\n  html {\n    font-size: 16px;\n  }\n}\n\n.border-top {\n  border-top: 1px solid #e5e5e5;\n}\n.border-bottom {\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.box-shadow {\n  box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);\n}\n\nbutton.accept-policy {\n  font-size: 1rem;\n  line-height: inherit;\n}\n\n/* Sticky footer styles\n-------------------------------------------------- */\nhtml {\n  position: relative;\n  min-height: 100%;\n}\n\nbody {\n  /* Margin bottom by footer height */\n  margin-bottom: 60px;\n}\n.footer {\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  white-space: nowrap;\n  line-height: 60px; /* Vertically center the text there */\n}\n"
  },
  {
    "path": "samples/Quickstarts/Shared/src/MvcClient/wwwroot/js/site.js",
    "content": "﻿// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification\n// for details on configuring this project to bundle and minify static web assets.\n\n// Write your JavaScript code.\n"
  },
  {
    "path": "samples/SamplesGlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityModel.Client;\nglobal using Serilog;\nglobal using System.Diagnostics;\nglobal using System.Text;\nglobal using System.Text.Json;\n\n\nglobal using IdentityModel.OidcClient;\nglobal using IdentityModel.OidcClient.Browser;\nglobal using IdentityModel.AspNetCore.AccessTokenValidation;\n\n\nglobal using Microsoft.AspNetCore.Builder;\nglobal using Microsoft.AspNetCore.DataProtection;\nglobal using Microsoft.AspNetCore.Hosting;\nglobal using Microsoft.AspNetCore.Http;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\n\nglobal using System.Net;\nglobal using System.Net.Sockets;\nglobal using System.Runtime.InteropServices;\nglobal using System.Security.Cryptography.X509Certificates;\n\n\nglobal using ILogger = Microsoft.Extensions.Logging.ILogger;\n\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Security.Claims;\nglobal using System.Runtime.Versioning;"
  },
  {
    "path": "src/AspNetIdentity/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/AspNetIdentity/IdentityServer8.AspNetIdentity.sln",
    "content": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26228.9\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{932FA9D0-7FB4-4047-8FFD-B74907B5FA15}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.AspNetIdentity\", \"src\\IdentityServer8.AspNetIdentity.csproj\", \"{A2CDBE15-5898-4A04-94DC-133EE03A78B3}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Host\", \"host\\Host.csproj\", \"{B7FBA07C-A462-4869-AF94-5E36DFC3742D}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"migrations\", \"migrations\", \"{4BC142B6-4922-4203-82A2-F28CB6AC5004}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SqlServer\", \"migrations\\SqlServer\\SqlServer.csproj\", \"{DD44B9E9-C32E-4F89-92C9-25444A709BBB}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3} = {932FA9D0-7FB4-4047-8FFD-B74907B5FA15}\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D} = {932FA9D0-7FB4-4047-8FFD-B74907B5FA15}\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB} = {4BC142B6-4922-4203-82A2-F28CB6AC5004}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {03AF716A-120B-409D-B384-B65E7FDEFEEF}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/AspNetIdentity/README.md",
    "content": "# IdentityServer8.AspNetIdentity\n\nASP.NET Core Identity integration support for IdentityServer8.\n\nYou can find a detailed walk-through for ASP.NET Core Identity integration [here](https://IdentityServer8.readthedocs.io/en/latest/quickstarts/6_aspnet_identity.html).\n\n## Issues\n\nFor issues, use the [consolidated IdentityServer8 issue tracker](https://github.com/alexhiggins732/IdentityServer8/issues).\n"
  },
  {
    "path": "src/AspNetIdentity/build.cmd",
    "content": "@echo off\ndotnet run --project build -- %*"
  },
  {
    "path": "src/AspNetIdentity/build.ps1",
    "content": "$ErrorActionPreference = \"Stop\";\ndotnet run --project build -- $args"
  },
  {
    "path": "src/AspNetIdentity/build.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\ndotnet run --project build -- \"$@\""
  },
  {
    "path": "src/AspNetIdentity/host/Configuration/Clients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class Clients\n{\n    public static IEnumerable<Client> Get()\n    {\n        var clients = new List<Client>();\n        \n        clients.AddRange(ClientsConsole.Get());\n        clients.AddRange(ClientsWeb.Get());\n\n        return clients;\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Configuration/ClientsConsole.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class ClientsConsole\n{\n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            ///////////////////////////////////////////////////////////////\n            // Console-based Client\n            ///////////////////////////////////////////////////////////////\n\n\n            ///////////////////////////////////////////\n            // Console Client Credentials Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\", IdentityServerConstants.LocalApi.ScopeName}\n            },\n            \n            ///////////////////////////////////////////\n            // Console Structured Scope Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"parameterized.client\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"transaction\" }\n            },\n\n            ///////////////////////////////////////////\n            // X509 mTLS Client\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mtls\",\n                ClientSecrets =\n                {\n                    // new Secret(@\"CN=mtls.test, OU=ROO\\ballen@roo, O=mkcert development certificate\", \"mtls.test\")\n                    // {\n                    //     Type = SecretTypes.X509CertificateName\n                    // },\n                    new Secret(\"5D9E9B6B333CD42C99D1DE6175CC0F3EF99DDF68\", \"mtls.test\")\n                    {\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateThumbprint\n                    },\n                },\n                \n                AccessTokenType = AccessTokenType.Jwt,\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Console Client Credentials Flow with client JWT assertion\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client.jwt\",\n                ClientSecrets =\n                {\n                    new Secret\n                    {\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                        Value =\n                            \"MIIEgTCCAumgAwIBAgIQDMMu7l/umJhfEbzJMpcttzANBgkqhkiG9w0BAQsFADCBkzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTQwMgYDVQQLDCtkb21pbmlja0Bkb21icDE2LmZyaXR6LmJveCAoRG9taW5pY2sgQmFpZXIpMTswOQYDVQQDDDJta2NlcnQgZG9taW5pY2tAZG9tYnAxNi5mcml0ei5ib3ggKERvbWluaWNrIEJhaWVyKTAeFw0xOTA2MDEwMDAwMDBaFw0zMDAxMDMxMjM0MDdaMHAxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTE0MDIGA1UECwwrZG9taW5pY2tAZG9tYnAxNi5mcml0ei5ib3ggKERvbWluaWNrIEJhaWVyKTEPMA0GA1UEAxMGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvNtpipaS8k1zA6w0Aoy8U4l+8zM4jHhhblExf3PULrMR6RauxniTki8p+P8CsZT4V8A4qo+JwsgpLIHrVQrbt9DEhHfBKzxwHqt+GoHt7byTfTtp8A/5nLhYc/5CW4HiR194gVx5+HAlvt+BriMTb1czvTf+H20dj41yUPsN7nMdyRLF+uXapQYMLYnq2BJIDq83mqGwojHk7d+N6GwoO95jlyas7KSoj8/FvfbaqkRNx0446hqPOzFHKc8er8K5VrLp6tVjh8ZJyY0F0dKgx6yWITsL54ctbj/cCyfuGjWEMbS2XXgc+x/xQMnmpfhK1qQAUn9jg5EzF9n6mQomOwIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUEMUlw41YsKZQVls3pEG6CrJk4O8wEQYDVR0RBAowCIIGY2xpZW50MA0GCSqGSIb3DQEBCwUAA4IBgQC0TjNY4Q3Wmw7ggamDImV6HUng3WbYGLYbbL2e3myBrjIxGd1Bi8ZyOu8qeUMIRAbZt2YsSX5S8kx0biaVg2zC+aO5eHhEWMwKB66huInXFjI4wtxZ22r+33fg1R0cLuEUePhftOWrbL0MS4YXVyn9HUMWO4WptG9PJdxNw1UbEB8nw3FkVOdAC9RGqiqalSK+E2UT/kUbTIQ1gPSdQ3nh52mre0H/T9+IRqiozJtNK/CQg4NuEV7rUXHnp7Fmigp6RIJ4TCozglspL341y0rV8M7npU1FYZC2UKNr4ed+GOO1n/sF3LbXDlPXwne99CVVn85wjDaevoR7Md0y2KwE9EggLYcViXNehx4YVv/BjfgqxW8NxiKAxP6kPOZE0XdBrZj2rmcDcGOXCzzYpcduKhFyTOpA0K5RNGC3j1KOUjPVlOtLvjASP7udBEYNfH3mgqXAgqNDOEKi2jG9LITv2IyGUsXhTAsKNJ6A6qiDBzDrvPAYDvsfabPq6tRTwjA=\"\n                    },\n                    new Secret\n                    {\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value =\n                            \"{'e':'AQAB','kid':'ZzAjSnraU3bkWGnnAqLapYGpTyNfLbjbzgAPbbW2GEA','kty':'RSA','n':'wWwQFtSzeRjjerpEM5Rmqz_DsNaZ9S1Bw6UbZkDLowuuTCjBWUax0vBMMxdy6XjEEK4Oq9lKMvx9JzjmeJf1knoqSNrox3Ka0rnxXpNAz6sATvme8p9mTXyp0cX4lF4U2J54xa2_S9NF5QWvpXvBeC4GAJx7QaSw4zrUkrc6XyaAiFnLhQEwKJCwUw4NOqIuYvYp_IXhw-5Ti_icDlZS-282PcccnBeOcX7vc21pozibIdmZJKqXNsL1Ibx5Nkx1F1jLnekJAmdaACDjYRLL_6n3W4wUp19UvzB1lGtXcJKLLkqB6YDiZNu16OSiSprfmrRXvYmvD8m6Fnl5aetgKw'}\"\n                    }\n                },\n                \n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Custom Grant Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client.custom\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = {\"custom\", \"custom.nosubject\"},\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Console Resource Owner Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    \"custom.profile\",\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n\n            ///////////////////////////////////////////\n            // Console Public Resource Owner Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient.public\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n\n            ///////////////////////////////////////////\n            // Console with PKCE Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"console.pkce\",\n                ClientName = \"Console with PKCE Sample\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n                RedirectUris = {\"http://127.0.0.1\"},\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n            ///////////////////////////////////////////\n            // WinConsole with PKCE Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"winconsole\",\n                ClientName = \"Windows Console with PKCE Sample\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n                RedirectUris = {\"sample-windows-client://callback\"},\n                RequireConsent = false,\n                AllowOfflineAccess = true,\n                AllowedIdentityTokenSigningAlgorithms = {\"ES256\"},\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n\n\n            ///////////////////////////////////////////\n            // Introspection Client Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient.reference\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" },\n                AccessTokenType = AccessTokenType.Reference\n            },\n            \n            ///////////////////////////////////////////\n            // Device Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"device\",\n                ClientName = \"Device Flow Client\",\n\n                AllowedGrantTypes = GrantTypes.DeviceFlow,\n                RequireClientSecret = false,\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Configuration/ClientsWeb.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class ClientsWeb\n{\n    static string[] allowedScopes = \n    {\n        IdentityServerConstants.StandardScopes.OpenId,\n        IdentityServerConstants.StandardScopes.Profile,\n        IdentityServerConstants.StandardScopes.Email,\n        \"resource1.scope1\", \n        \"resource2.scope1\",\n        \"transaction\"\n    };\n    \n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            ///////////////////////////////////////////\n            // JS OIDC Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"js_oidc\",\n                ClientName = \"JavaScript OIDC Client\",\n                ClientUri = \"http://identityserver8.io\",\n                \n                AllowedGrantTypes = GrantTypes.Code,\n                RequireClientSecret = false,\n                \n                RedirectUris = \n                {\n                    \"https://localhost:44300/index.html\",\n                    \"https://localhost:44300/callback.html\",\n                    \"https://localhost:44300/silent.html\",\n                    \"https://localhost:44300/popup.html\"\n                },\n\n                PostLogoutRedirectUris = { \"https://localhost:44300/index.html\" },\n                AllowedCorsOrigins = { \"https://localhost:44300\" },\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Automatic Token Management Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.tokenmanagement\",\n                \n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n\n                AccessTokenLifetime = 75,\n\n                RedirectUris = { \"https://localhost:44301/signin-oidc\" },\n                FrontChannelLogoutUri = \"https://localhost:44301/signout-oidc\",\n                PostLogoutRedirectUris = { \"https://localhost:44301/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Code Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.code\",\n                ClientName = \"MVC Code Flow\",\n                ClientUri = \"http://identityserver8.io\",\n\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                RequireConsent = true,\n                AllowedGrantTypes = GrantTypes.Code,\n\n                RedirectUris = { \"https://localhost:44302/signin-oidc\" },\n                FrontChannelLogoutUri = \"https://localhost:44302/signout-oidc\",\n                PostLogoutRedirectUris = { \"https://localhost:44302/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Hybrid Flow Sample (Back Channel logout)\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.hybrid.backchannel\",\n                ClientName = \"MVC Hybrid (with BackChannel logout)\",\n                ClientUri = \"http://identityserver8.io\",\n\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.Hybrid,\n                RequirePkce = false,\n\n                RedirectUris = { \"https://localhost:44303/signin-oidc\" },\n                BackChannelLogoutUri = \"https://localhost:44303/logout\",\n                PostLogoutRedirectUris = { \"https://localhost:44303/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Configuration/Resources.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic class Resources\n{\n    // identity resources represent identity data about a user that can be requested via the scope parameter (OpenID Connect)\n    public static readonly IEnumerable<IdentityResource> IdentityResources =\n        new[]\n        {\n            // some standard scopes from the OIDC spec\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email(),\n\n            // custom identity resource with some consolidated claims\n            new IdentityResource(\"custom.profile\", new[] { JwtClaimTypes.Name, JwtClaimTypes.Email, \"location\" })\n        };\n\n    // API scopes represent values that describe scope of access and can be requested by the scope parameter (OAuth)\n    public static readonly IEnumerable<ApiScope> ApiScopes =\n        new[]\n        {\n            // local API scope\n            new ApiScope(LocalApi.ScopeName),\n\n            // resource specific scopes\n            new ApiScope(\"resource1.scope1\"),\n            new ApiScope(\"resource2.scope1\"), \n            \n            // a scope without resource association\n            new ApiScope(\"scope3\"),\n            \n            // a scope shared by multiple resources\n            new ApiScope(\"shared.scope\"),\n\n            // a parameterized scope\n            new ApiScope(\"transaction\", \"Transaction\")\n            {\n                Description = \"Some Transaction\"\n            }\n        };\n\n    // API resources are more formal representation of a resource with processing rules and their scopes (if any)\n    public static readonly IEnumerable<ApiResource> ApiResources = \n        new[]\n        {\n            new ApiResource(\"resource1\", \"Resource 1\")\n            {\n                ApiSecrets = { new Secret(\"secret\".Sha256()) },\n\n                Scopes = { \"resource1.scope1\", \"shared.scope\" }\n            },\n            \n            // expanded version if more control is needed\n            new ApiResource(\"resource2\", \"Resource 2\")\n            {\n                ApiSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                // additional claims to put into access token\n                UserClaims =\n                {\n                    JwtClaimTypes.Name,\n                    JwtClaimTypes.Email\n                },\n\n                Scopes = { \"resource2.scope1\", \"shared.scope\" }\n            }\n        };\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Data/ApplicationDbContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Data;\n\npublic class ApplicationDbContext : IdentityDbContext<ApplicationUser>\n{\n    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)\n        : base(options)\n    {\n    }\n\n    protected override void OnModelCreating(ModelBuilder builder)\n    {\n        base.OnModelCreating(builder);\n        // Customize the ASP.NET Identity model and override the defaults if needed.\n        // For example, you can rename the ASP.NET Identity table names and more.\n        // Add your customizations after calling base.OnModelCreating(builder);\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Configuration;\nglobal using IdentityServerHost.Data;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Identity;\nglobal using Microsoft.AspNetCore.Identity.EntityFrameworkCore;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.Extensions.Options;\nglobal using Newtonsoft.Json;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System.ComponentModel;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Diagnostics;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using static IdentityServer8.IdentityServerConstants;\nglobal using ILogger = Microsoft.Extensions.Logging.ILogger;\nglobal using ClaimValueTypes = System.Security.Claims.ClaimValueTypes;\n"
  },
  {
    "path": "src/AspNetIdentity/host/Host.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Serilog\" />\n    <PackageReference Include=\"Serilog.AspNetCore\" />\n    <PackageReference Include=\"Serilog.Sinks.Console\" />\n    <PackageReference Include=\"Serilog.Sinks.File\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Identity.EntityFrameworkCore\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n    <PackageReference Include=\"System.Security.Principal.Windows\" />\n    \n    <ProjectReference Include=\"..\\src\\IdentityServer8.AspNetIdentity.csproj\" />\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "src/AspNetIdentity/host/Models/AccountViewModels/ExternalLoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.AccountViewModels;\n\npublic class ExternalLoginViewModel\n{\n    [Required]\n    [EmailAddress]\n    public string Email { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/AccountViewModels/ForgotPasswordViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.AccountViewModels;\n\npublic class ForgotPasswordViewModel\n{\n    [Required]\n    [EmailAddress]\n    public string Email { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/AccountViewModels/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.AccountViewModels;\n\npublic class LoginViewModel\n{\n    [Required]\n    [EmailAddress]\n    public string Email { get; set; }\n\n    [Required]\n    [DataType(DataType.Password)]\n    public string Password { get; set; }\n\n    [Display(Name = \"Remember me?\")]\n    public bool RememberMe { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/AccountViewModels/LoginWith2faViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.AccountViewModels;\n\npublic class LoginWith2faViewModel\n{\n    [Required]\n    [StringLength(7, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n    [DataType(DataType.Text)]\n    [Display(Name = \"Authenticator code\")]\n    public string TwoFactorCode { get; set; }\n\n    [Display(Name = \"Remember this machine\")]\n    public bool RememberMachine { get; set; }\n\n    public bool RememberMe { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/AccountViewModels/LoginWithRecoveryCodeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.AccountViewModels;\n\npublic class LoginWithRecoveryCodeViewModel\n{\n        [Required]\n        [DataType(DataType.Text)]\n        [Display(Name = \"Recovery Code\")]\n        public string RecoveryCode { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/AccountViewModels/RegisterViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.AccountViewModels;\n\npublic class RegisterViewModel\n{\n    [Required]\n    [EmailAddress]\n    [Display(Name = \"Email\")]\n    public string Email { get; set; }\n\n    [Required]\n    [StringLength(100, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n    [DataType(DataType.Password)]\n    [Display(Name = \"Password\")]\n    public string Password { get; set; }\n\n    [DataType(DataType.Password)]\n    [Display(Name = \"Confirm password\")]\n    [Compare(\"Password\", ErrorMessage = \"The password and confirmation password do not match.\")]\n    public string ConfirmPassword { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/AccountViewModels/ResetPasswordViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.AccountViewModels;\n\npublic class ResetPasswordViewModel\n{\n    [Required]\n    [EmailAddress]\n    public string Email { get; set; }\n\n    [Required]\n    [StringLength(100, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n    [DataType(DataType.Password)]\n    public string Password { get; set; }\n\n    [DataType(DataType.Password)]\n    [Display(Name = \"Confirm password\")]\n    [Compare(\"Password\", ErrorMessage = \"The password and confirmation password do not match.\")]\n    public string ConfirmPassword { get; set; }\n\n    public string Code { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ApplicationUser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n// Add profile data for application users by adding properties to the ApplicationUser class\npublic class ApplicationUser : IdentityUser\n{\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/ChangePasswordViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class ChangePasswordViewModel\n{\n    [Required]\n    [DataType(DataType.Password)]\n    [Display(Name = \"Current password\")]\n    public string OldPassword { get; set; }\n\n    [Required]\n    [StringLength(100, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n    [DataType(DataType.Password)]\n    [Display(Name = \"New password\")]\n    public string NewPassword { get; set; }\n\n    [DataType(DataType.Password)]\n    [Display(Name = \"Confirm new password\")]\n    [Compare(\"NewPassword\", ErrorMessage = \"The new password and confirmation password do not match.\")]\n    public string ConfirmPassword { get; set; }\n\n    public string StatusMessage { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/EnableAuthenticatorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class EnableAuthenticatorViewModel\n{\n        [Required]\n        [StringLength(7, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n        [DataType(DataType.Text)]\n        [Display(Name = \"Verification Code\")]\n        public string Code { get; set; }\n\n        [ReadOnly(true)]\n        public string SharedKey { get; set; }\n\n        public string AuthenticatorUri { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/ExternalLoginsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class ExternalLoginsViewModel\n{\n    public IList<UserLoginInfo> CurrentLogins { get; set; }\n\n    public IList<AuthenticationScheme> OtherLogins { get; set; }\n\n    public bool ShowRemoveButton { get; set; }\n\n    public string StatusMessage { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/GenerateRecoveryCodesViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class GenerateRecoveryCodesViewModel\n{\n    public string[] RecoveryCodes { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/IndexViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class IndexViewModel\n{\n    public string Username { get; set; }\n\n    public bool IsEmailConfirmed { get; set; }\n\n    [Required]\n    [EmailAddress]\n    public string Email { get; set; }\n\n    [Phone]\n    [Display(Name = \"Phone number\")]\n    public string PhoneNumber { get; set; }\n\n    public string StatusMessage { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/RemoveLoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class RemoveLoginViewModel\n{\n    public string LoginProvider { get; set; }\n    public string ProviderKey { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/SetPasswordViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class SetPasswordViewModel\n{\n    [Required]\n    [StringLength(100, ErrorMessage = \"The {0} must be at least {2} and at max {1} characters long.\", MinimumLength = 6)]\n    [DataType(DataType.Password)]\n    [Display(Name = \"New password\")]\n    public string NewPassword { get; set; }\n\n    [DataType(DataType.Password)]\n    [Display(Name = \"Confirm new password\")]\n    [Compare(\"NewPassword\", ErrorMessage = \"The new password and confirmation password do not match.\")]\n    public string ConfirmPassword { get; set; }\n\n    public string StatusMessage { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Models/ManageViewModels/TwoFactorAuthenticationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models.ManageViewModels;\n\npublic class TwoFactorAuthenticationViewModel\n{\n    public bool HasAuthenticator { get; set; }\n\n    public int RecoveryCodesLeft { get; set; }\n\n    public bool Is2faEnabled { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost;\n\npublic class Program\n{\n    public static int Main(string[] args)\n    {\n        Console.Title = \"IdentityServer8.AspNetIdentity\";\n        Activity.DefaultIdFormat = ActivityIdFormat.W3C;\n\n        Log.Logger = new LoggerConfiguration()\n            .MinimumLevel.Debug()\n            .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n            .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n            .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n            .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n            .Enrich.FromLogContext()\n            //.WriteTo.File(@\"IdentityServer8_log.txt\")\n            // uncomment to write to Azure diagnostics stream\n            //.WriteTo.File(\n            //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n            //    fileSizeLimitBytes: 1_000_000,\n            //    rollOnFileSizeLimit: true,\n            //    shared: true,\n            //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n            .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n            .CreateLogger();\n\n        try\n        {\n            Log.Information(\"Starting host...\");\n            CreateHostBuilder(args).Build().Run();\n            return 0;\n        }\n        catch (Exception ex)\n        {\n            Log.Fatal(ex, \"Host terminated unexpectedly.\");\n            return 1;\n        }\n        finally\n        {\n            Log.CloseAndFlush();\n        }\n    }\n\n    public static IHostBuilder CreateHostBuilder(string[] args) =>\n        Host.CreateDefaultBuilder(args)\n            .UseSerilog()\n            .ConfigureWebHostDefaults(webBuilder =>\n            {\n                webBuilder.UseStartup<Startup>();\n            });\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": true,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:5000\",\n      \"sslPort\": 44334\n    }\n  },\n  \"profiles\": {\n    \"Host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly UserManager<ApplicationUser> _userManager;\n    private readonly SignInManager<ApplicationUser> _signInManager;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        UserManager<ApplicationUser> userManager,\n        SignInManager<ApplicationUser> signInManager,\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events)\n    {\n        _userManager = userManager;\n        _signInManager = signInManager;\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        // check if we are in the context of an authorization request\n        if (ModelState.IsValid)\n        {\n            var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure: true);\n            if (result.Succeeded)\n            {\n                var user = await _userManager.FindByNameAsync(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId));\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return this.LoadingPage(\"Redirect\", model.ReturnUrl);\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return Redirect(\"~/\");\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return Redirect(\"~/\");\n        }\n\n    }\n\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await _signInManager.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class AccountOptions\n{\n    public static bool AllowLocalLogin = true;\n    public static bool AllowRememberLogin = true;\n    public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n    public static bool ShowLogoutPrompt = true;\n    public static bool AutomaticRedirectAfterSignOut = false;\n\n    public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly UserManager<ApplicationUser> _userManager;\n    private readonly SignInManager<ApplicationUser> _signInManager;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IEventService _events;\n    private readonly ILogger<ExternalController> _logger;\n\n    public ExternalController(\n        UserManager<ApplicationUser> userManager,\n        SignInManager<ApplicationUser> signInManager,\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger)\n    {\n        _userManager = userManager;\n        _signInManager = signInManager;\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = await FindUserFromExternalProviderAsync(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = await AutoProvisionUserAsync(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        // we must issue the cookie maually, and can't use the SignInManager because\n        // it doesn't expose an API to issue additional claims from the login workflow\n        var principal = await _signInManager.CreateUserPrincipalAsync(user);\n        additionalLocalClaims.AddRange(principal.Claims);\n        var name = principal.FindFirst(JwtClaimTypes.Name)?.Value ?? user.Id;\n        \n        var isuser = new IdentityServerUser(user.Id)\n        {\n            DisplayName = name,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, name, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private async Task<(ApplicationUser user, string provider, string providerUserId, IEnumerable<Claim> claims)>\n        FindUserFromExternalProviderAsync(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = await _userManager.FindByLoginAsync(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private async Task<ApplicationUser> AutoProvisionUserAsync(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        // create a list of claims that we want to transfer into our store\n        var filtered = new List<Claim>();\n\n        // user's display name\n        var name = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Name)?.Value ??\n            claims.FirstOrDefault(x => x.Type == ClaimTypes.Name)?.Value;\n        if (name != null)\n        {\n            filtered.Add(new Claim(JwtClaimTypes.Name, name));\n        }\n        else\n        {\n            var first = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.GivenName)?.Value ??\n                claims.FirstOrDefault(x => x.Type == ClaimTypes.GivenName)?.Value;\n            var last = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.FamilyName)?.Value ??\n                claims.FirstOrDefault(x => x.Type == ClaimTypes.Surname)?.Value;\n            if (first != null && last != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, first + \" \" + last));\n            }\n            else if (first != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, first));\n            }\n            else if (last != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, last));\n            }\n        }\n\n        // email\n        var email = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Email)?.Value ??\n           claims.FirstOrDefault(x => x.Type == ClaimTypes.Email)?.Value;\n        if (email != null)\n        {\n            filtered.Add(new Claim(JwtClaimTypes.Email, email));\n        }\n\n        var user = new ApplicationUser\n        {\n            UserName = Guid.NewGuid().ToString(),\n        };\n        var identityResult = await _userManager.CreateAsync(user);\n        if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n\n        if (filtered.Any())\n        {\n            identityResult = await _userManager.AddClaimsAsync(user, filtered);\n            if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n        }\n\n        identityResult = await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, providerUserId, provider));\n        if (!identityResult.Succeeded) throw new Exception(identityResult.Errors.First().Description);\n\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", Ioc.Sanitizer.Log.Sanitize(returnUrl));\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonConvert.DeserializeObject<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n    public static List<TestUser> Users = new List<TestUser>\n    {\n        new TestUser{SubjectId = \"818727\", Username = \"alice\", Password = \"alice\", \n            Claims = \n            {\n                new Claim(JwtClaimTypes.Name, \"Alice Smith\"),\n                new Claim(JwtClaimTypes.GivenName, \"Alice\"),\n                new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                new Claim(JwtClaimTypes.Email, \"AliceSmith@email.com\"),\n                new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new Claim(JwtClaimTypes.WebSite, \"http://alice.com\"),\n                new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServer8.IdentityServerConstants.ClaimValueTypes.Json)\n            }\n        },\n        new TestUser{SubjectId = \"88421113\", Username = \"bob\", Password = \"bob\", \n            Claims = \n            {\n                new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                new Claim(JwtClaimTypes.Email, \"BobSmith@email.com\"),\n                new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServer8.IdentityServerConstants.ClaimValueTypes.Json),\n                new Claim(\"location\", \"somewhere\")\n            }\n        }\n    };\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost\n{\n    public class Startup\n    {\n        public Startup(IConfiguration configuration)\n        {\n            Configuration = configuration;\n        }\n\n        public IConfiguration Configuration { get; }\n\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddDbContext<ApplicationDbContext>(options =>\n                options.UseSqlServer(Configuration.GetConnectionString(\"DefaultConnection\")));\n\n            services.AddIdentity<ApplicationUser, IdentityRole>()\n                .AddEntityFrameworkStores<ApplicationDbContext>()\n                .AddDefaultTokenProviders();\n\n            services.AddControllersWithViews();\n\n            services.AddIdentityServer()\n                .AddDeveloperSigningCredential()\n                .AddInMemoryIdentityResources(IdentityServerHost.Configuration.Resources.IdentityResources)\n                .AddInMemoryApiResources(IdentityServerHost.Configuration.Resources.ApiResources)\n                .AddInMemoryApiScopes(IdentityServerHost.Configuration.Resources.ApiScopes)\n                .AddInMemoryClients(Clients.Get())\n                .AddAspNetIdentity<ApplicationUser>();\n\n            services.AddAuthentication()\n                .AddOpenIdConnect(\"Google\", \"Google\", options =>\n                {\n                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n                    options.ForwardSignOut = IdentityServerConstants.DefaultCookieAuthenticationScheme;\n\n                    options.Authority = \"https://accounts.google.com/\";\n                    options.ClientId = \"708996912208-9m4dkjb5hscn7cjrn5u0r4tbgkbj1fko.apps.googleusercontent.com\";\n\n                    options.CallbackPath = \"/signin-google\";\n                    options.Scope.Add(\"email\");\n                });\n        }\n\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n                //app.UseDatabaseErrorPage();\n            }\n            else\n            {\n                app.UseExceptionHandler(\"/Home/Error\");\n            }\n\n            app.UseStaticFiles();\n\n            app.UseRouting();\n\n            app.UseIdentityServer();\n\n            app.UseAuthorization();\n\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapDefaultControllerRoute();\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n\n@{\n    var version = FileVersionInfo.GetVersionInfo(typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.Location).ProductVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl.SantizeForRedirect()\">\n<script>\n    var url = '@Model.RedirectUrl.SanitizeForUrl()';\n    window.location.href = url;\n</script>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "src/AspNetIdentity/host/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "src/AspNetIdentity/host/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "src/AspNetIdentity/host/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=(localdb)\\\\mssqllocaldb;Database=IdentityServer8.AspNetIdentity-8.0.0;Trusted_Connection=True;MultipleActiveResultSets=true\"\n  },\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Warning\"\n    }\n  }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/host/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "src/AspNetIdentity/host/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "src/AspNetIdentity/host/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "src/AspNetIdentity/host/wwwroot/js/signin-redirect.js",
    "content": "//window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "src/AspNetIdentity/host/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8.Models;\nglobal using IdentityServerHost;\nglobal using IdentityServerHost.Data;\nglobal using Microsoft.AspNetCore;\nglobal using Microsoft.AspNetCore.Identity;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.EntityFrameworkCore.Infrastructure;\nglobal using Microsoft.EntityFrameworkCore.Metadata;\nglobal using Microsoft.EntityFrameworkCore.Migrations;\nglobal using System.Security.Claims;\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/Migrations/UsersDb/20200323135751_Users.Designer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\nnamespace SqlServer.Migrations.UsersDb\n{\n    [DbContext(typeof(ApplicationDbContext))]\n    [Migration(\"20200323135751_Users\")]\n    partial class Users\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.0\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"IdentityServer8.Models.ApplicationUser\", b =>\n                {\n                    b.Property<string>(\"Id\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<int>(\"AccessFailedCount\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"Email\")\n                        .HasColumnType(\"nvarchar(256)\")\n                        .HasMaxLength(256);\n\n                    b.Property<bool>(\"EmailConfirmed\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"LockoutEnabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTimeOffset?>(\"LockoutEnd\")\n                        .HasColumnType(\"datetimeoffset\");\n\n                    b.Property<string>(\"NormalizedEmail\")\n                        .HasColumnType(\"nvarchar(256)\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedUserName\")\n                        .HasColumnType(\"nvarchar(256)\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"PasswordHash\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"PhoneNumber\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<bool>(\"PhoneNumberConfirmed\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"SecurityStamp\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<bool>(\"TwoFactorEnabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"UserName\")\n                        .HasColumnType(\"nvarchar(256)\")\n                        .HasMaxLength(256);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedEmail\")\n                        .HasName(\"EmailIndex\");\n\n                    b.HasIndex(\"NormalizedUserName\")\n                        .IsUnique()\n                        .HasName(\"UserNameIndex\")\n                        .HasFilter(\"[NormalizedUserName] IS NOT NULL\");\n\n                    b.ToTable(\"AspNetUsers\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRole\", b =>\n                {\n                    b.Property<string>(\"Id\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<string>(\"ConcurrencyStamp\")\n                        .IsConcurrencyToken()\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"nvarchar(256)\")\n                        .HasMaxLength(256);\n\n                    b.Property<string>(\"NormalizedName\")\n                        .HasColumnType(\"nvarchar(256)\")\n                        .HasMaxLength(256);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"NormalizedName\")\n                        .IsUnique()\n                        .HasName(\"RoleNameIndex\")\n                        .HasFilter(\"[NormalizedName] IS NOT NULL\");\n\n                    b.ToTable(\"AspNetRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"RoleId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetRoleClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"ClaimType\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"ClaimValue\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"UserId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserClaims\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n                {\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<string>(\"ProviderKey\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<string>(\"ProviderDisplayName\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.Property<string>(\"UserId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.HasKey(\"LoginProvider\", \"ProviderKey\");\n\n                    b.HasIndex(\"UserId\");\n\n                    b.ToTable(\"AspNetUserLogins\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n                {\n                    b.Property<string>(\"UserId\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<string>(\"RoleId\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.HasKey(\"UserId\", \"RoleId\");\n\n                    b.HasIndex(\"RoleId\");\n\n                    b.ToTable(\"AspNetUserRoles\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n                {\n                    b.Property<string>(\"UserId\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<string>(\"LoginProvider\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<string>(\"Name\")\n                        .HasColumnType(\"nvarchar(450)\");\n\n                    b.Property<string>(\"Value\")\n                        .HasColumnType(\"nvarchar(max)\");\n\n                    b.HasKey(\"UserId\", \"LoginProvider\", \"Name\");\n\n                    b.ToTable(\"AspNetUserTokens\");\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n                {\n                    b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n                {\n                    b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\", null)\n                        .WithMany()\n                        .HasForeignKey(\"RoleId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n\n                    b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                        .WithMany()\n                        .HasForeignKey(\"UserId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/Migrations/UsersDb/20200323135751_Users.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace SqlServer.Migrations.UsersDb;\n\npublic partial class Users : Migration\n{\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.CreateTable(\n            name: \"AspNetRoles\",\n            columns: table => new\n            {\n                Id = table.Column<string>(nullable: false),\n                Name = table.Column<string>(maxLength: 256, nullable: true),\n                NormalizedName = table.Column<string>(maxLength: 256, nullable: true),\n                ConcurrencyStamp = table.Column<string>(nullable: true)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_AspNetRoles\", x => x.Id);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"AspNetUsers\",\n            columns: table => new\n            {\n                Id = table.Column<string>(nullable: false),\n                UserName = table.Column<string>(maxLength: 256, nullable: true),\n                NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),\n                Email = table.Column<string>(maxLength: 256, nullable: true),\n                NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),\n                EmailConfirmed = table.Column<bool>(nullable: false),\n                PasswordHash = table.Column<string>(nullable: true),\n                SecurityStamp = table.Column<string>(nullable: true),\n                ConcurrencyStamp = table.Column<string>(nullable: true),\n                PhoneNumber = table.Column<string>(nullable: true),\n                PhoneNumberConfirmed = table.Column<bool>(nullable: false),\n                TwoFactorEnabled = table.Column<bool>(nullable: false),\n                LockoutEnd = table.Column<DateTimeOffset>(nullable: true),\n                LockoutEnabled = table.Column<bool>(nullable: false),\n                AccessFailedCount = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_AspNetUsers\", x => x.Id);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"AspNetRoleClaims\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                RoleId = table.Column<string>(nullable: false),\n                ClaimType = table.Column<string>(nullable: true),\n                ClaimValue = table.Column<string>(nullable: true)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_AspNetRoleClaims\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_AspNetRoleClaims_AspNetRoles_RoleId\",\n                    column: x => x.RoleId,\n                    principalTable: \"AspNetRoles\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"AspNetUserClaims\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                UserId = table.Column<string>(nullable: false),\n                ClaimType = table.Column<string>(nullable: true),\n                ClaimValue = table.Column<string>(nullable: true)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_AspNetUserClaims\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_AspNetUserClaims_AspNetUsers_UserId\",\n                    column: x => x.UserId,\n                    principalTable: \"AspNetUsers\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"AspNetUserLogins\",\n            columns: table => new\n            {\n                LoginProvider = table.Column<string>(nullable: false),\n                ProviderKey = table.Column<string>(nullable: false),\n                ProviderDisplayName = table.Column<string>(nullable: true),\n                UserId = table.Column<string>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_AspNetUserLogins\", x => new { x.LoginProvider, x.ProviderKey });\n                table.ForeignKey(\n                    name: \"FK_AspNetUserLogins_AspNetUsers_UserId\",\n                    column: x => x.UserId,\n                    principalTable: \"AspNetUsers\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"AspNetUserRoles\",\n            columns: table => new\n            {\n                UserId = table.Column<string>(nullable: false),\n                RoleId = table.Column<string>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_AspNetUserRoles\", x => new { x.UserId, x.RoleId });\n                table.ForeignKey(\n                    name: \"FK_AspNetUserRoles_AspNetRoles_RoleId\",\n                    column: x => x.RoleId,\n                    principalTable: \"AspNetRoles\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n                table.ForeignKey(\n                    name: \"FK_AspNetUserRoles_AspNetUsers_UserId\",\n                    column: x => x.UserId,\n                    principalTable: \"AspNetUsers\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"AspNetUserTokens\",\n            columns: table => new\n            {\n                UserId = table.Column<string>(nullable: false),\n                LoginProvider = table.Column<string>(nullable: false),\n                Name = table.Column<string>(nullable: false),\n                Value = table.Column<string>(nullable: true)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_AspNetUserTokens\", x => new { x.UserId, x.LoginProvider, x.Name });\n                table.ForeignKey(\n                    name: \"FK_AspNetUserTokens_AspNetUsers_UserId\",\n                    column: x => x.UserId,\n                    principalTable: \"AspNetUsers\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_AspNetRoleClaims_RoleId\",\n            table: \"AspNetRoleClaims\",\n            column: \"RoleId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"RoleNameIndex\",\n            table: \"AspNetRoles\",\n            column: \"NormalizedName\",\n            unique: true,\n            filter: \"[NormalizedName] IS NOT NULL\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_AspNetUserClaims_UserId\",\n            table: \"AspNetUserClaims\",\n            column: \"UserId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_AspNetUserLogins_UserId\",\n            table: \"AspNetUserLogins\",\n            column: \"UserId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_AspNetUserRoles_RoleId\",\n            table: \"AspNetUserRoles\",\n            column: \"RoleId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"EmailIndex\",\n            table: \"AspNetUsers\",\n            column: \"NormalizedEmail\");\n\n        migrationBuilder.CreateIndex(\n            name: \"UserNameIndex\",\n            table: \"AspNetUsers\",\n            column: \"NormalizedUserName\",\n            unique: true,\n            filter: \"[NormalizedUserName] IS NOT NULL\");\n    }\n\n    protected override void Down(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.DropTable(\n            name: \"AspNetRoleClaims\");\n\n        migrationBuilder.DropTable(\n            name: \"AspNetUserClaims\");\n\n        migrationBuilder.DropTable(\n            name: \"AspNetUserLogins\");\n\n        migrationBuilder.DropTable(\n            name: \"AspNetUserRoles\");\n\n        migrationBuilder.DropTable(\n            name: \"AspNetUserTokens\");\n\n        migrationBuilder.DropTable(\n            name: \"AspNetRoles\");\n\n        migrationBuilder.DropTable(\n            name: \"AspNetUsers\");\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/Migrations/UsersDb/ApplicationDbContextModelSnapshot.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\nnamespace SqlServer.Migrations.UsersDb;\n\n[DbContext(typeof(ApplicationDbContext))]\npartial class ApplicationDbContextModelSnapshot : ModelSnapshot\n{\n    protected override void BuildModel(ModelBuilder modelBuilder)\n    {\n#pragma warning disable 612, 618\n        modelBuilder\n            .HasAnnotation(\"ProductVersion\", \"3.1.0\")\n            .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n            .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n        modelBuilder.Entity(\"IdentityServer8.Models.ApplicationUser\", b =>\n            {\n                b.Property<string>(\"Id\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<int>(\"AccessFailedCount\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"ConcurrencyStamp\")\n                    .IsConcurrencyToken()\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"Email\")\n                    .HasColumnType(\"nvarchar(256)\")\n                    .HasMaxLength(256);\n\n                b.Property<bool>(\"EmailConfirmed\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"LockoutEnabled\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<DateTimeOffset?>(\"LockoutEnd\")\n                    .HasColumnType(\"datetimeoffset\");\n\n                b.Property<string>(\"NormalizedEmail\")\n                    .HasColumnType(\"nvarchar(256)\")\n                    .HasMaxLength(256);\n\n                b.Property<string>(\"NormalizedUserName\")\n                    .HasColumnType(\"nvarchar(256)\")\n                    .HasMaxLength(256);\n\n                b.Property<string>(\"PasswordHash\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"PhoneNumber\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<bool>(\"PhoneNumberConfirmed\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"SecurityStamp\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<bool>(\"TwoFactorEnabled\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"UserName\")\n                    .HasColumnType(\"nvarchar(256)\")\n                    .HasMaxLength(256);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"NormalizedEmail\")\n                    .HasName(\"EmailIndex\");\n\n                b.HasIndex(\"NormalizedUserName\")\n                    .IsUnique()\n                    .HasName(\"UserNameIndex\")\n                    .HasFilter(\"[NormalizedUserName] IS NOT NULL\");\n\n                b.ToTable(\"AspNetUsers\");\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRole\", b =>\n            {\n                b.Property<string>(\"Id\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<string>(\"ConcurrencyStamp\")\n                    .IsConcurrencyToken()\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"Name\")\n                    .HasColumnType(\"nvarchar(256)\")\n                    .HasMaxLength(256);\n\n                b.Property<string>(\"NormalizedName\")\n                    .HasColumnType(\"nvarchar(256)\")\n                    .HasMaxLength(256);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"NormalizedName\")\n                    .IsUnique()\n                    .HasName(\"RoleNameIndex\")\n                    .HasFilter(\"[NormalizedName] IS NOT NULL\");\n\n                b.ToTable(\"AspNetRoles\");\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<string>(\"ClaimType\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"ClaimValue\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"RoleId\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"RoleId\");\n\n                b.ToTable(\"AspNetRoleClaims\");\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<string>(\"ClaimType\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"ClaimValue\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"UserId\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"UserId\");\n\n                b.ToTable(\"AspNetUserClaims\");\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n            {\n                b.Property<string>(\"LoginProvider\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<string>(\"ProviderKey\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<string>(\"ProviderDisplayName\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.Property<string>(\"UserId\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.HasKey(\"LoginProvider\", \"ProviderKey\");\n\n                b.HasIndex(\"UserId\");\n\n                b.ToTable(\"AspNetUserLogins\");\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n            {\n                b.Property<string>(\"UserId\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<string>(\"RoleId\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.HasKey(\"UserId\", \"RoleId\");\n\n                b.HasIndex(\"RoleId\");\n\n                b.ToTable(\"AspNetUserRoles\");\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n            {\n                b.Property<string>(\"UserId\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<string>(\"LoginProvider\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<string>(\"Name\")\n                    .HasColumnType(\"nvarchar(450)\");\n\n                b.Property<string>(\"Value\")\n                    .HasColumnType(\"nvarchar(max)\");\n\n                b.HasKey(\"UserId\", \"LoginProvider\", \"Name\");\n\n                b.ToTable(\"AspNetUserTokens\");\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>\", b =>\n            {\n                b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\", null)\n                    .WithMany()\n                    .HasForeignKey(\"RoleId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserClaim<string>\", b =>\n            {\n                b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                    .WithMany()\n                    .HasForeignKey(\"UserId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserLogin<string>\", b =>\n            {\n                b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                    .WithMany()\n                    .HasForeignKey(\"UserId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserRole<string>\", b =>\n            {\n                b.HasOne(\"Microsoft.AspNetCore.Identity.IdentityRole\", null)\n                    .WithMany()\n                    .HasForeignKey(\"RoleId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n\n                b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                    .WithMany()\n                    .HasForeignKey(\"UserId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"Microsoft.AspNetCore.Identity.IdentityUserToken<string>\", b =>\n            {\n                b.HasOne(\"IdentityServer8.Models.ApplicationUser\", null)\n                    .WithMany()\n                    .HasForeignKey(\"UserId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n#pragma warning restore 612, 618\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/Migrations/UsersDb.sql",
    "content": "﻿IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL\nBEGIN\n    CREATE TABLE [__EFMigrationsHistory] (\n        [MigrationId] nvarchar(150) NOT NULL,\n        [ProductVersion] nvarchar(32) NOT NULL,\n        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])\n    );\nEND;\n\nGO\n\nCREATE TABLE [AspNetRoles] (\n    [Id] nvarchar(450) NOT NULL,\n    [Name] nvarchar(256) NULL,\n    [NormalizedName] nvarchar(256) NULL,\n    [ConcurrencyStamp] nvarchar(max) NULL,\n    CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE TABLE [AspNetUsers] (\n    [Id] nvarchar(450) NOT NULL,\n    [UserName] nvarchar(256) NULL,\n    [NormalizedUserName] nvarchar(256) NULL,\n    [Email] nvarchar(256) NULL,\n    [NormalizedEmail] nvarchar(256) NULL,\n    [EmailConfirmed] bit NOT NULL,\n    [PasswordHash] nvarchar(max) NULL,\n    [SecurityStamp] nvarchar(max) NULL,\n    [ConcurrencyStamp] nvarchar(max) NULL,\n    [PhoneNumber] nvarchar(max) NULL,\n    [PhoneNumberConfirmed] bit NOT NULL,\n    [TwoFactorEnabled] bit NOT NULL,\n    [LockoutEnd] datetimeoffset NULL,\n    [LockoutEnabled] bit NOT NULL,\n    [AccessFailedCount] int NOT NULL,\n    CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE TABLE [AspNetRoleClaims] (\n    [Id] int NOT NULL IDENTITY,\n    [RoleId] nvarchar(450) NOT NULL,\n    [ClaimType] nvarchar(max) NULL,\n    [ClaimValue] nvarchar(max) NULL,\n    CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [AspNetUserClaims] (\n    [Id] int NOT NULL IDENTITY,\n    [UserId] nvarchar(450) NOT NULL,\n    [ClaimType] nvarchar(max) NULL,\n    [ClaimValue] nvarchar(max) NULL,\n    CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [AspNetUserLogins] (\n    [LoginProvider] nvarchar(450) NOT NULL,\n    [ProviderKey] nvarchar(450) NOT NULL,\n    [ProviderDisplayName] nvarchar(max) NULL,\n    [UserId] nvarchar(450) NOT NULL,\n    CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]),\n    CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [AspNetUserRoles] (\n    [UserId] nvarchar(450) NOT NULL,\n    [RoleId] nvarchar(450) NOT NULL,\n    CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY ([UserId], [RoleId]),\n    CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE,\n    CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [AspNetUserTokens] (\n    [UserId] nvarchar(450) NOT NULL,\n    [LoginProvider] nvarchar(450) NOT NULL,\n    [Name] nvarchar(450) NOT NULL,\n    [Value] nvarchar(max) NULL,\n    CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]),\n    CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE INDEX [IX_AspNetRoleClaims_RoleId] ON [AspNetRoleClaims] ([RoleId]);\n\nGO\n\nCREATE UNIQUE INDEX [RoleNameIndex] ON [AspNetRoles] ([NormalizedName]) WHERE [NormalizedName] IS NOT NULL;\n\nGO\n\nCREATE INDEX [IX_AspNetUserClaims_UserId] ON [AspNetUserClaims] ([UserId]);\n\nGO\n\nCREATE INDEX [IX_AspNetUserLogins_UserId] ON [AspNetUserLogins] ([UserId]);\n\nGO\n\nCREATE INDEX [IX_AspNetUserRoles_RoleId] ON [AspNetUserRoles] ([RoleId]);\n\nGO\n\nCREATE INDEX [EmailIndex] ON [AspNetUsers] ([NormalizedEmail]);\n\nGO\n\nCREATE UNIQUE INDEX [UserNameIndex] ON [AspNetUsers] ([NormalizedUserName]) WHERE [NormalizedUserName] IS NOT NULL;\n\nGO\n\nINSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])\nVALUES (N'20200323135751_Users', N'3.1.0');\n\nGO\n\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace SqlServer;\n\nclass Program\n{\n    public static void Main(string[] args)\n    {\n        var host = BuildWebHost(args);\n        SeedData.EnsureSeedData(host.Services);\n    }\n\n    public static IWebHost BuildWebHost(string[] args) =>\n        WebHost.CreateDefaultBuilder(args)\n            .UseStartup<Startup>()\n            .Build();\n}\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:7603/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"SqlServer\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:7604/\"\n    }\n  }\n}"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/SeedData.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost;\n\npublic class SeedData\n{\n    public static void EnsureSeedData(IServiceProvider serviceProvider)\n    {\n        using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())\n        {\n            var context = scope.ServiceProvider.GetService<ApplicationDbContext>();\n            context.Database.Migrate();\n\n            var userMgr = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();\n            var alice = userMgr.FindByNameAsync(\"alice\").Result;\n            if (alice == null)\n            {\n                alice = new ApplicationUser\n                {\n                    UserName = \"alice\"\n                };\n                var result = userMgr.CreateAsync(alice, \"Pass123$\").Result;\n                if (!result.Succeeded)\n                {\n                    throw new Exception(result.Errors.First().Description);\n                }\n\n                result = userMgr.AddClaimsAsync(alice, new Claim[]{\n                    new Claim(JwtClaimTypes.Name, \"Alice Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Alice\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"AliceSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.WebSite, \"http://alice.com\"),\n                    new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServer8.IdentityServerConstants.ClaimValueTypes.Json)\n                }).Result;\n                if (!result.Succeeded)\n                {\n                    throw new Exception(result.Errors.First().Description);\n                }\n                Console.WriteLine(\"alice created\");\n            }\n            else\n            {\n                Console.WriteLine(\"alice already exists\");\n            }\n\n            var bob = userMgr.FindByNameAsync(\"bob\").Result;\n            if (bob == null)\n            {\n                bob = new ApplicationUser\n                {\n                    UserName = \"bob\"\n                };\n                var result = userMgr.CreateAsync(bob, \"Pass123$\").Result;\n                if (!result.Succeeded)\n                {\n                    throw new Exception(result.Errors.First().Description);\n                }\n\n                result = userMgr.AddClaimsAsync(bob, new Claim[]{\n                    new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"BobSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                    new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServer8.IdentityServerConstants.ClaimValueTypes.Json),\n                    new Claim(\"location\", \"somewhere\")\n                }).Result;\n                if (!result.Succeeded)\n                {\n                    throw new Exception(result.Errors.First().Description);\n                }\n                Console.WriteLine(\"bob created\");\n            }\n            else\n            {\n                Console.WriteLine(\"bob already exists\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/SqlServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" PrivateAssets=\"All\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\host\\Host.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.AspNetIdentity.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace SqlServer;\n\npublic class Startup\n{\n    public IConfiguration Configuration { get; }\n\n    public Startup(IConfiguration config)\n    {\n        Configuration = config;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var cn = Configuration.GetConnectionString(\"db\");\n        services.AddDbContext<ApplicationDbContext>(options =>\n        {\n            options.UseSqlServer(cn, dbOpts => dbOpts.MigrationsAssembly(typeof(Startup).Assembly.FullName));\n        });\n\n        services.AddIdentity<ApplicationUser, IdentityRole>()\n            .AddEntityFrameworkStores<ApplicationDbContext>()\n            .AddDefaultTokenProviders();\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"db\": \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.AspNetIdentity-8.0.0;trusted_connection=yes;\"\n  }\n}"
  },
  {
    "path": "src/AspNetIdentity/migrations/SqlServer/builddb.bat",
    "content": "rmdir /S /Q Migrations\n\ndotnet ef database drop\n\ndotnet ef migrations add Users -o Migrations/UsersDb\ndotnet ef migrations script -o Migrations/UsersDb.sql\n\ndotnet ef database update\n"
  },
  {
    "path": "src/AspNetIdentity/src/Decorator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.AspNetIdentity;\n\ninternal class Decorator<TService>\n{\n    public TService Instance { get; set; }\n\n    public Decorator(TService instance)\n    {\n        Instance = instance;\n    }\n}\n\ninternal class Decorator<TService, TImpl> : Decorator<TService>\n    where TImpl : class, TService\n{\n    public Decorator(TImpl instance) : base(instance)\n    {\n    }\n}\n\ninternal class DisposableDecorator<TService> : Decorator<TService>, IDisposable\n{\n    public DisposableDecorator(TService instance) : base(instance)\n    {\n    }\n\n    public void Dispose()\n    {\n        (Instance as IDisposable)?.Dispose();\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/src/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.AspNetIdentity;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Validation;\nglobal using Microsoft.AspNetCore.Authentication.Cookies;\nglobal using Microsoft.AspNetCore.Identity;\nglobal using Microsoft.Extensions.Logging;\nglobal using System.Security.Claims;\nglobal using static IdentityModel.OidcConstants;\n"
  },
  {
    "path": "src/AspNetIdentity/src/IdentityServer8.AspNetIdentity.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n      <Description>ASP.NET Core Identity Integration for IdentityServer8</Description>\n      <IsPackable>true</IsPackable>\n      <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n      <SignAssembly>true</SignAssembly>\n  </PropertyGroup>\n\n  <PropertyGroup>\n    <ContinuousIntegrationBuild Condition=\"'$(TF_BUILD)' == 'true'\">True</ContinuousIntegrationBuild>\n    <ContinuousIntegrationBuild Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">True</ContinuousIntegrationBuild>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\IdentityServer8\\src\\IdentityServer8.csproj\" />\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "src/AspNetIdentity/src/IdentityServerBuilderExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Extension methods to add ASP.NET Identity support to IdentityServer.\n/// </summary>\npublic static class IdentityServerBuilderExtensions\n{\n    /// <summary>\n    /// Configures IdentityServer to use the ASP.NET Identity implementations \n    /// of IUserClaimsPrincipalFactory, IResourceOwnerPasswordValidator, and IProfileService.\n    /// Also configures some of ASP.NET Identity's options for use with IdentityServer (such as claim types to use\n    /// and authentication cookie settings).\n    /// </summary>\n    /// <typeparam name=\"TUser\">The type of the user.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddAspNetIdentity<TUser>(this IIdentityServerBuilder builder)\n        where TUser : class\n    {\n        builder.Services.AddTransientDecorator<IUserClaimsPrincipalFactory<TUser>, UserClaimsFactory<TUser>>();\n\n        builder.Services.Configure<IdentityOptions>(options =>\n        {\n            options.ClaimsIdentity.UserIdClaimType = JwtClaimTypes.Subject;\n            options.ClaimsIdentity.UserNameClaimType = JwtClaimTypes.Name;\n            options.ClaimsIdentity.RoleClaimType = JwtClaimTypes.Role;\n        });\n\n        builder.Services.Configure<SecurityStampValidatorOptions>(opts =>\n        {\n            opts.OnRefreshingPrincipal = SecurityStampValidatorCallback.UpdatePrincipal;\n        });\n\n        builder.Services.ConfigureApplicationCookie(options =>\n        {\n            options.Cookie.IsEssential = true;\n            // we need to disable to allow iframe for authorize requests\n            options.Cookie.SameSite = AspNetCore.Http.SameSiteMode.None;\n        });\n\n        builder.Services.ConfigureExternalCookie(options =>\n        {\n            options.Cookie.IsEssential = true;\n            // https://github.com/alexhiggins732/IdentityServer8/issues/2595\n            options.Cookie.SameSite = AspNetCore.Http.SameSiteMode.None;\n        });\n\n        builder.Services.Configure<CookieAuthenticationOptions>(IdentityConstants.TwoFactorRememberMeScheme, options =>\n        {\n            options.Cookie.IsEssential = true;\n        });\n\n        builder.Services.Configure<CookieAuthenticationOptions>(IdentityConstants.TwoFactorUserIdScheme, options =>\n        {\n            options.Cookie.IsEssential = true;\n        });\n\n        builder.Services.AddAuthentication(options =>\n        {\n            if (options.DefaultAuthenticateScheme == null &&\n                options.DefaultScheme == IdentityServerConstants.DefaultCookieAuthenticationScheme)\n            {\n                options.DefaultScheme = IdentityConstants.ApplicationScheme;\n            }\n        });\n\n        builder.AddResourceOwnerValidator<ResourceOwnerPasswordValidator<TUser>>();\n        builder.AddProfileService<ProfileService<TUser>>();\n\n        return builder;\n    }\n\n    internal static void AddTransientDecorator<TService, TImplementation>(this IServiceCollection services)\n        where TService : class\n        where TImplementation : class, TService\n    {\n        services.AddDecorator<TService>();\n        services.AddTransient<TService, TImplementation>();\n    }\n\n    internal static void AddDecorator<TService>(this IServiceCollection services)\n    {\n        var registration = services.LastOrDefault(x => x.ServiceType == typeof(TService));\n        if (registration == null)\n        {\n            throw new InvalidOperationException(\"Service type: \" + typeof(TService).Name + \" not registered.\");\n        }\n        if (services.Any(x => x.ServiceType == typeof(Decorator<TService>)))\n        {\n            throw new InvalidOperationException(\"Decorator already registered for type: \" + typeof(TService).Name + \".\");\n        }\n\n        services.Remove(registration);\n\n        if (registration.ImplementationInstance != null)\n        {\n            var type = registration.ImplementationInstance.GetType();\n            var innerType = typeof(Decorator<,>).MakeGenericType(typeof(TService), type);\n            services.Add(new ServiceDescriptor(typeof(Decorator<TService>), innerType, ServiceLifetime.Transient));\n            services.Add(new ServiceDescriptor(type, registration.ImplementationInstance));\n        }\n        else if (registration.ImplementationFactory != null)\n        {\n            services.Add(new ServiceDescriptor(typeof(Decorator<TService>), provider =>\n            {\n                return new DisposableDecorator<TService>((TService)registration.ImplementationFactory(provider));\n            }, registration.Lifetime));\n        }\n        else\n        {\n            var type = registration.ImplementationType;\n            var innerType = typeof(Decorator<,>).MakeGenericType(typeof(TService), registration.ImplementationType);\n            services.Add(new ServiceDescriptor(typeof(Decorator<TService>), innerType, ServiceLifetime.Transient));\n            services.Add(new ServiceDescriptor(type, type, registration.Lifetime));\n        }\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/src/ProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.AspNetIdentity;\n\n/// <summary>\n/// IProfileService to integrate with ASP.NET Identity.\n/// </summary>\n/// <typeparam name=\"TUser\">The type of the user.</typeparam>\n/// <seealso cref=\"IdentityServer8.Services.IProfileService\" />\npublic class ProfileService<TUser> : IProfileService\n    where TUser : class\n{\n    /// <summary>\n    /// The claims factory.\n    /// </summary>\n    protected readonly IUserClaimsPrincipalFactory<TUser> ClaimsFactory;\n    \n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger<ProfileService<TUser>> Logger;\n\n    /// <summary>\n    /// The user manager.\n    /// </summary>\n    protected readonly UserManager<TUser> UserManager;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ProfileService{TUser}\"/> class.\n    /// </summary>\n    /// <param name=\"userManager\">The user manager.</param>\n    /// <param name=\"claimsFactory\">The claims factory.</param>\n    public ProfileService(UserManager<TUser> userManager,\n        IUserClaimsPrincipalFactory<TUser> claimsFactory)\n    {\n        UserManager = userManager;\n        ClaimsFactory = claimsFactory;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ProfileService{TUser}\"/> class.\n    /// </summary>\n    /// <param name=\"userManager\">The user manager.</param>\n    /// <param name=\"claimsFactory\">The claims factory.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public ProfileService(UserManager<TUser> userManager,\n        IUserClaimsPrincipalFactory<TUser> claimsFactory,\n        ILogger<ProfileService<TUser>> logger)\n    {\n        UserManager = userManager;\n        ClaimsFactory = claimsFactory;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint)\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public virtual async Task GetProfileDataAsync(ProfileDataRequestContext context)\n    {\n        var sub = context.Subject?.GetSubjectId();\n        if (sub == null) throw new Exception(\"No sub claim present\");\n\n        await GetProfileDataAsync(context, sub);\n    }\n\n    /// <summary>\n    /// Called to get the claims for the subject based on the profile request.\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <param name=\"subjectId\"></param>\n    /// <returns></returns>\n    protected virtual async Task GetProfileDataAsync(ProfileDataRequestContext context, string subjectId)\n    {\n        var user = await FindUserAsync(subjectId);\n        if (user != null)\n        {\n            await GetProfileDataAsync(context, user);\n        }\n    }\n\n    /// <summary>\n    /// Called to get the claims for the user based on the profile request.\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <param name=\"user\"></param>\n    /// <returns></returns>\n    protected virtual async Task GetProfileDataAsync(ProfileDataRequestContext context, TUser user)\n    {\n        var principal = await GetUserClaimsAsync(user);\n        context.AddRequestedClaims(principal.Claims);\n    }\n\n    /// <summary>\n    /// Gets the claims for a user.\n    /// </summary>\n    /// <param name=\"user\"></param>\n    /// <returns></returns>\n    protected virtual async Task<ClaimsPrincipal> GetUserClaimsAsync(TUser user)\n    {\n        var principal = await ClaimsFactory.CreateAsync(user);\n        if (principal == null) throw new Exception(\"ClaimsFactory failed to create a principal\");\n        \n        return principal;\n    }\n\n    /// <summary>\n    /// This method gets called whenever identity server needs to determine if the user is valid or active (e.g. if the user's account has been deactivated since they logged in).\n    /// (e.g. during token issuance or validation).\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public virtual async Task IsActiveAsync(IsActiveContext context)\n    {\n        var sub = context.Subject?.GetSubjectId();\n        if (sub == null) throw new Exception(\"No subject Id claim present\");\n\n        await IsActiveAsync(context, sub);\n    }\n\n    /// <summary>\n    /// Determines if the subject is active.\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <param name=\"subjectId\"></param>\n    /// <returns></returns>\n    protected virtual async Task IsActiveAsync(IsActiveContext context, string subjectId)\n    {\n        var user = await FindUserAsync(subjectId);\n        if (user != null)\n        {\n            await IsActiveAsync(context, user);\n        }\n        else\n        {\n            context.IsActive = false;\n        }\n    }\n\n    /// <summary>\n    /// Determines if the user is active.\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <param name=\"user\"></param>\n    /// <returns></returns>\n    protected virtual async Task IsActiveAsync(IsActiveContext context, TUser user)\n    {\n        context.IsActive = await IsUserActiveAsync(user);\n    }\n\n    /// <summary>\n    /// Returns if the user is active.\n    /// </summary>\n    /// <param name=\"user\"></param>\n    /// <returns></returns>\n    public virtual Task<bool> IsUserActiveAsync(TUser user)\n    {\n        return Task.FromResult(true);\n    }\n\n    /// <summary>\n    /// Loads the user by the subject id.\n    /// </summary>\n    /// <param name=\"subjectId\"></param>\n    /// <returns></returns>\n    protected virtual async Task<TUser> FindUserAsync(string subjectId)\n    {\n        var user = await UserManager.FindByIdAsync(subjectId);\n        if (user == null)\n        {\n            Logger?.LogWarning(\"No user found matching subject Id: {subjectId}\", subjectId);\n        }\n\n        return user;\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/src/ResourceOwnerPasswordValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.AspNetIdentity;\n\n/// <summary>\n/// IResourceOwnerPasswordValidator that integrates with ASP.NET Identity.\n/// </summary>\n/// <typeparam name=\"TUser\">The type of the user.</typeparam>\n/// <seealso cref=\"IdentityServer8.Validation.IResourceOwnerPasswordValidator\" />\npublic class ResourceOwnerPasswordValidator<TUser> : IResourceOwnerPasswordValidator\n    where TUser : class\n{\n    private readonly SignInManager<TUser> _signInManager;\n    private readonly UserManager<TUser> _userManager;\n    private readonly ILogger<ResourceOwnerPasswordValidator<TUser>> _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ResourceOwnerPasswordValidator{TUser}\"/> class.\n    /// </summary>\n    /// <param name=\"userManager\">The user manager.</param>\n    /// <param name=\"signInManager\">The sign in manager.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public ResourceOwnerPasswordValidator(\n        UserManager<TUser> userManager,\n        SignInManager<TUser> signInManager,\n        ILogger<ResourceOwnerPasswordValidator<TUser>> logger)\n    {\n        _userManager = userManager;\n        _signInManager = signInManager;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the resource owner password credential\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public virtual async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)\n    {\n        var user = await _userManager.FindByNameAsync(context.UserName);\n        if (user != null)\n        {\n            var result = await _signInManager.CheckPasswordSignInAsync(user, context.Password, true);\n            if (result.Succeeded)\n            {\n                var sub = await _userManager.GetUserIdAsync(user);\n\n                _logger.LogInformation(\"Credentials validated for username: {username}\", context.UserName);\n\n                context.Result = new GrantValidationResult(sub, AuthenticationMethods.Password);\n                return;\n            }\n            else if (result.IsLockedOut)\n            {\n                _logger.LogInformation(\"Authentication failed for username: {username}, reason: locked out\", context.UserName);\n            }\n            else if (result.IsNotAllowed)\n            {\n                _logger.LogInformation(\"Authentication failed for username: {username}, reason: not allowed\", context.UserName);\n            }\n            else\n            {\n                _logger.LogInformation(\"Authentication failed for username: {username}, reason: invalid credentials\", context.UserName);\n            }\n        }\n        else\n        {\n            _logger.LogInformation(\"No user found matching username: {username}\", context.UserName);\n        }\n\n        context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant);\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/src/SecurityStampValidatorCallback.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.AspNetIdentity;\n\n/// <summary>\n/// Implements callback for SecurityStampValidator's OnRefreshingPrincipal event.\n/// </summary>\npublic class SecurityStampValidatorCallback\n{\n    /// <summary>\n    /// Maintains the claims captured at login time that are not being created by ASP.NET Identity.\n    /// This is needed to preserve claims such as idp, auth_time, amr.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public static Task UpdatePrincipal(SecurityStampRefreshingPrincipalContext context)\n    {\n        var newClaimTypes = context.NewPrincipal.Claims.Select(x => x.Type).ToArray();\n        var currentClaimsToKeep = context.CurrentPrincipal.Claims.Where(x => !newClaimTypes.Contains(x.Type)).ToArray();\n\n        var id = context.NewPrincipal.Identities.First();\n        id.AddClaims(currentClaimsToKeep);\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/AspNetIdentity/src/UserClaimsFactory.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.AspNetIdentity;\n\ninternal class UserClaimsFactory<TUser> : IUserClaimsPrincipalFactory<TUser>\n    where TUser : class\n{\n    private readonly Decorator<IUserClaimsPrincipalFactory<TUser>> _inner;\n    private UserManager<TUser> _userManager;\n\n    public UserClaimsFactory(Decorator<IUserClaimsPrincipalFactory<TUser>> inner, UserManager<TUser> userManager)\n    {\n        _inner = inner;\n        _userManager = userManager;\n    }\n\n    public async Task<ClaimsPrincipal> CreateAsync(TUser user)\n    {\n        var principal = await _inner.Instance.CreateAsync(user);\n        var identity = principal.Identities.First();\n\n        if (!identity.HasClaim(x => x.Type == JwtClaimTypes.Subject))\n        {\n            var sub = await _userManager.GetUserIdAsync(user);\n            identity.AddClaim(new Claim(JwtClaimTypes.Subject, sub));\n        }\n\n        var username = await _userManager.GetUserNameAsync(user);\n        var usernameClaim = identity.FindFirst(claim => claim.Type == _userManager.Options.ClaimsIdentity.UserNameClaimType && claim.Value == username);\n        if (usernameClaim != null)\n        {\n            identity.RemoveClaim(usernameClaim);\n            identity.AddClaim(new Claim(JwtClaimTypes.PreferredUserName, username));\n        }\n\n        if (!identity.HasClaim(x=>x.Type == JwtClaimTypes.Name))\n        {\n            identity.AddClaim(new Claim(JwtClaimTypes.Name, username));\n        }\n\n        if (_userManager.SupportsUserEmail)\n        {\n            var email = await _userManager.GetEmailAsync(user);\n            if (!String.IsNullOrWhiteSpace(email))\n            {\n                identity.AddClaims(new[]\n                {\n                    new Claim(JwtClaimTypes.Email, email),\n                    new Claim(JwtClaimTypes.EmailVerified,\n                        await _userManager.IsEmailConfirmedAsync(user) ? \"true\" : \"false\", ClaimValueTypes.Boolean)\n                });\n            }\n        }\n\n        if (_userManager.SupportsUserPhoneNumber)\n        {\n            var phoneNumber = await _userManager.GetPhoneNumberAsync(user);\n            if (!String.IsNullOrWhiteSpace(phoneNumber))\n            {\n                identity.AddClaims(new[]\n                {\n                    new Claim(JwtClaimTypes.PhoneNumber, phoneNumber),\n                    new Claim(JwtClaimTypes.PhoneNumberVerified,\n                        await _userManager.IsPhoneNumberConfirmedAsync(user) ? \"true\" : \"false\", ClaimValueTypes.Boolean)\n                });\n            }\n        }\n\n        return principal;\n    }\n}\n"
  },
  {
    "path": "src/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/Directory.BuildOld.targets",
    "content": "<Project>\n\n  <PropertyGroup>\n    <FrameworkVersion>3.1.0</FrameworkVersion>\n    <ExtensionsVersion>3.1.0</ExtensionsVersion>\n    <EntityFrameworkVersion>3.1.0</EntityFrameworkVersion>\n    \n    <IdentityServerVersion>4.1.2-*</IdentityServerVersion>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <!--build related-->\n    <PackageReference Include=\"MinVer\" Version=\"2.3.0\" PrivateAssets=\"All\" />\n    <PackageReference Update=\"SimpleExec\" Version=\"6.2.0\" />\n    <PackageReference Update=\"Bullseye\" Version=\"3.3.0\" />\n    <PackageReference Update=\"Microsoft.SourceLink.GitHub\" Version=\"1.0.0\" PrivateAssets=\"All\" />\n\n    <!--tests -->\n    <PackageReference Update=\"FluentAssertions\" Version=\"5.10.2\" />\n    <PackageReference Update=\"Microsoft.NET.Test.Sdk\" Version=\"16.2.0\" />\n    <PackageReference Update=\"xunit\" Version=\"2.4.1\" />\n    <PackageReference Update=\"xunit.runner.visualstudio\" Version=\"2.4.1\" PrivateAssets=\"All\" />\n\n    <!--our stuff -->\n    <PackageReference Update=\"IdentityModel\" Version=\"4.4.0\" />\n\n    <PackageReference Update=\"IdentityServer8\" Version=\"$(IdentityServerVersion)\" />\n    <PackageReference Update=\"IdentityServer8.AspNetIdentity\" Version=\"$(IdentityServerVersion)\" />\n    <PackageReference Update=\"IdentityServer8.Storage\" Version=\"$(IdentityServerVersion)\" />\n    <PackageReference Update=\"IdentityServer8.EntityFramework.Storage\" Version=\"$(IdentityServerVersion)\" />\n    <PackageReference Update=\"IdentityServer8.EntityFramework\" Version=\"$(IdentityServerVersion)\" />\n\n    <!--microsoft extensions -->\n    <PackageReference Update=\"Microsoft.Extensions.Caching.Memory\" Version=\"$(ExtensionsVersion)\" />\n    <PackageReference Update=\"Microsoft.Extensions.Http\" Version=\"$(ExtensionsVersion)\" />\n    <PackageReference Update=\"Microsoft.Extensions.Http.Polly\" Version=\"$(ExtensionsVersion)\" />\n    <PackageReference Update=\"Microsoft.Extensions.Logging\" Version=\"$(ExtensionsVersion)\" />\n    <PackageReference Update=\"Microsoft.Extensions.Logging.Console\" Version=\"$(ExtensionsVersion)\" />\n    <PackageReference Update=\"Microsoft.Extensions.Options.ConfigurationExtensions\" Version=\"$(ExtensionsVersion)\" />\n    \n    <!--misc -->\n    <PackageReference Update=\"Newtonsoft.Json\" Version=\"12.0.2\" />\n    <PackageReference Update=\"Microsoft.IdentityModel.Protocols.OpenIdConnect\" Version=\"5.6.0\" />\n    <PackageReference Update=\"System.IdentityModel.Tokens.Jwt\" Version=\"[5.6.0,6.0)\" />\n    <PackageReference Update=\"System.Security.Principal.Windows\" Version=\"4.7.0\" />\n    <PackageReference Update=\"AutoMapper\" Version=\"[10.0.0,11.0)\" />\n    \n    <!--microsoft asp.net core -->\n    <PackageReference Update=\"Microsoft.AspNetCore.Authentication.OpenIdConnect\" Version=\"$(FrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.AspNetCore.TestHost\" Version=\"$(FrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.AspNetCore.Identity\" Version=\"$(FrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.AspNetCore.Identity.EntityFrameworkCore\" Version=\"$(FrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.AspNetCore.Mvc.NewtonsoftJson\" Version=\"$(FrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.AspNetCore.Authentication.Certificate\" Version=\"$(FrameworkVersion)\"/>\n    \n    <!--microsoft entity framework -->\n    <PackageReference Update=\"Microsoft.EntityFrameworkCore.Relational\" Version=\"$(EntityFrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.EntityFrameworkCore.Sqlite\" Version=\"$(EntityFrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.EntityFrameworkCore.InMemory\" Version=\"$(EntityFrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"$(EntityFrameworkVersion)\" />\n    <PackageReference Update=\"Microsoft.EntityFrameworkCore.Design\" Version=\"$(EntityFrameworkVersion)\" PrivateAssets=\"All\" />\n\n  </ItemGroup>\n\n  <Target Name=\"SetAssemblyVersion\" AfterTargets=\"MinVer\">\n    <PropertyGroup>\n      <AssemblyVersion>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch).0</AssemblyVersion>\n    </PropertyGroup>\n  </Target>\n</Project>"
  },
  {
    "path": "src/EntityFramework/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/EntityFramework/IdentityServer8.EntityFramework.sln",
    "content": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.29230.61\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{8BFDA83B-FD73-4776-9C2C-5F7FFE440C1F}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework\", \"src\\IdentityServer8.EntityFramework.csproj\", \"{AB83F911-8B78-4973-A3A9-2A2D85581F25}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Host\", \"host\\Host.csproj\", \"{9E9EE58E-4B98-4495-8E8B-00281B3EABDA}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"seeding\", \"seeding\", \"{26921EED-9592-4174-94D6-8A0F604029F1}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SqlServer\", \"migrations\\SqlServer\\SqlServer.csproj\", \"{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"tests\", \"tests\", \"{19FEB622-0912-4F5E-840F-827B4B9EF026}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"IdentityServer8.EntityFramework.Tests\", \"test\\IdentityServer8.EntityFramework.Tests\\IdentityServer8.EntityFramework.Tests.csproj\", \"{E3685B06-F135-4318-B841-889C35479D5C}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{9E9EE58E-4B98-4495-8E8B-00281B3EABDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{9E9EE58E-4B98-4495-8E8B-00281B3EABDA}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{9E9EE58E-4B98-4495-8E8B-00281B3EABDA}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{9E9EE58E-4B98-4495-8E8B-00281B3EABDA}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25} = {8BFDA83B-FD73-4776-9C2C-5F7FFE440C1F}\n\t\t{9E9EE58E-4B98-4495-8E8B-00281B3EABDA} = {8BFDA83B-FD73-4776-9C2C-5F7FFE440C1F}\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69} = {26921EED-9592-4174-94D6-8A0F604029F1}\n\t\t{E3685B06-F135-4318-B841-889C35479D5C} = {19FEB622-0912-4F5E-840F-827B4B9EF026}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {A023D63E-FDD1-4984-9746-45981BCFBACA}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/EntityFramework/README.md",
    "content": "# IdentityServer8.EntityFramework\n\nIdentityServer8.EntityFramework is a package that provides the configuration APIs to add persistence for IdentityServer 4 configuration data that uses EntityFramework as its database abstraction.\n\n## Issues\n\nFor issues, use the [consolidated IdentityServer8 issue tracker](https://github.com/alexhiggins732/IdentityServer8/issues).\n"
  },
  {
    "path": "src/EntityFramework/build.cmd",
    "content": "@echo off\ndotnet run --project build -- %*"
  },
  {
    "path": "src/EntityFramework/build.ps1",
    "content": "$ErrorActionPreference = \"Stop\";\ndotnet run --project build -- $args"
  },
  {
    "path": "src/EntityFramework/build.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\ndotnet run --project build -- \"$@\""
  },
  {
    "path": "src/EntityFramework/dropdb.bat",
    "content": "cd src\\Host\ndotnet ef database drop -c PersistedGrantDbContext\ndotnet ef database drop -c ConfigurationDbContext\ncd ..\\..\n"
  },
  {
    "path": "src/EntityFramework/host/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.Options;\nglobal using Newtonsoft.Json;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Diagnostics;\nglobal using System.Security.Claims;\nglobal using System.Text;\nglobal using ILogger = Microsoft.Extensions.Logging.ILogger;\nglobal using ClaimValueTypes = System.Security.Claims.ClaimValueTypes;\n"
  },
  {
    "path": "src/EntityFramework/host/Host.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\src\\IdentityServer8.EntityFramework.csproj\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Certificate\" />\n    \n    <PackageReference Include=\"Serilog.AspNetCore\" />\n\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"System.Security.Principal.Windows\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/EntityFramework/host/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost;\n\npublic class Program\n{\n        public static int Main(string[] args)\n        {\n            Console.Title = \"IdentityServer8.EntityFramework\";\n            Activity.DefaultIdFormat = ActivityIdFormat.W3C;\n\n            Log.Logger = new LoggerConfiguration()\n                .MinimumLevel.Debug()\n                .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n                .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n                .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n                .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n                .Enrich.FromLogContext()\n                //.WriteTo.File(@\"IdentityServer8_log.txt\")\n                // uncomment to write to Azure diagnostics stream\n                //.WriteTo.File(\n                //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n                //    fileSizeLimitBytes: 1_000_000,\n                //    rollOnFileSizeLimit: true,\n                //    shared: true,\n                //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n                .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n                .CreateLogger();\n\n            try\n            {\n                Log.Information(\"Starting host...\");\n                CreateHostBuilder(args).Build().Run();\n                return 0;\n            }\n            catch (Exception ex)\n            {\n                Log.Fatal(ex, \"Host terminated unexpectedly.\");\n                return 1;\n            }\n            finally\n            {\n                Log.CloseAndFlush();\n            }\n        }\n\n        public static IHostBuilder CreateHostBuilder(string[] args) =>\n            Host.CreateDefaultBuilder(args)\n                .UseSerilog()\n                .ConfigureWebHostDefaults(webBuilder =>\n                {\n                    webBuilder.UseStartup<Startup>();\n                });\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": true,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:5000\",\n      \"sslPort\": 44334\n    }\n  },\n  \"profiles\": {\n    \"Host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001\"\n    }\n  }\n}"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n        private readonly TestUserStore _users;\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IClientStore _clientStore;\n        private readonly IAuthenticationSchemeProvider _schemeProvider;\n        private readonly IEventService _events;\n\n        public AccountController(\n            IIdentityServerInteractionService interaction,\n            IClientStore clientStore,\n            IAuthenticationSchemeProvider schemeProvider,\n            IEventService events,\n            TestUserStore users = null)\n        {\n            // if the TestUserStore is not in DI, then we'll just use the global users collection\n            // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n            _users = users ?? new TestUserStore(TestUsers.Users);\n\n            _interaction = interaction;\n            _clientStore = clientStore;\n            _schemeProvider = schemeProvider;\n            _events = events;\n        }\n\n        /// <summary>\n        /// Entry point into the login workflow\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> Login(string returnUrl)\n        {\n            // build a model so we know what to show on the login page\n            var vm = await BuildLoginViewModelAsync(returnUrl);\n\n            if (vm.IsExternalLoginOnly)\n            {\n                // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n            }\n\n            return View(vm);\n        }\n\n        /// <summary>\n        /// Handle postback from username/password login\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n        {\n            // check if we are in the context of an authorization request\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n            if (ModelState.IsValid)\n            {\n                // validate username/password against in-memory store\n                if (_users.ValidateCredentials(model.Username, model.Password))\n                {\n                    var user = _users.FindByUsername(model.Username);\n                    await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                    // only set explicit expiration here if user chooses \"remember me\". \n                    // otherwise we rely upon expiration configured in cookie middleware.\n                    AuthenticationProperties props = null;\n                    if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                    {\n                        props = new AuthenticationProperties\n                        {\n                            IsPersistent = true,\n                            ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                        };\n                    };\n\n                    // issue authentication cookie with subject ID and username\n                    var isuser = new IdentityServerUser(user.SubjectId)\n                    {\n                        DisplayName = user.Username\n                    };\n\n                    await HttpContext.SignInAsync(isuser, props);\n\n                    if (context != null)\n                    {\n                        if (context.IsNativeClient())\n                        {\n                            // The client is native, so this change in how to\n                            // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                        }\n\n                        // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // request for a local page\n                    if (Url.IsLocalUrl(model.ReturnUrl))\n                    {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n                    else if (string.IsNullOrEmpty(model.ReturnUrl))\n                    {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                    }\n                    else\n                    {\n                        // user might have clicked on a malicious link - should be logged\n                        throw new Exception(\"invalid return URL\");\n                    }\n                }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n                ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n            }\n\n            // something went wrong, show form with error\n            var vm = await BuildLoginViewModelAsync(model);\n            return View(vm);\n        }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n        \n        /// <summary>\n        /// Show logout page\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> Logout(string logoutId)\n        {\n            // build a model so the logout page knows what to display\n            var vm = await BuildLogoutViewModelAsync(logoutId);\n\n            if (vm.ShowLogoutPrompt == false)\n            {\n                // if the request for logout was properly authenticated from IdentityServer, then\n                // we don't need to show the prompt and can just log the user out directly.\n                return await Logout(vm);\n            }\n\n            return View(vm);\n        }\n\n        /// <summary>\n        /// Handle logout page postback\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Logout(LogoutInputModel model)\n        {\n            // build a model so the logged out page knows what to display\n            var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n            if (User?.Identity.IsAuthenticated == true)\n            {\n                // delete local authentication cookie\n                await HttpContext.SignOutAsync();\n\n                // raise the logout event\n                await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n            }\n\n            // check if we need to trigger sign-out at an upstream identity provider\n            if (vm.TriggerExternalSignout)\n            {\n                // build a return URL so the upstream provider will redirect back\n                // to us after the user has logged out. this allows us to then\n                // complete our single sign-out processing.\n                string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n                // this triggers a redirect to the external provider for sign-out\n                return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n            }\n\n            return View(\"LoggedOut\", vm);\n        }\n\n        [HttpGet]\n        public IActionResult AccessDenied()\n        {\n            return View();\n        }\n\n\n        /*****************************************/\n        /* helper APIs for the AccountController */\n        /*****************************************/\n        private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n            if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n            {\n                var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n                // this is meant to short circuit the UI and only trigger the one external IdP\n                var vm = new LoginViewModel\n                {\n                    EnableLocalLogin = local,\n                    ReturnUrl = returnUrl,\n                    Username = context?.LoginHint,\n                };\n\n                if (!local)\n                {\n                    vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n                }\n\n                return vm;\n            }\n\n            var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n            var providers = schemes\n                .Where(x => x.DisplayName != null)\n                .Select(x => new ExternalProvider\n                {\n                    DisplayName = x.DisplayName ?? x.Name,\n                    AuthenticationScheme = x.Name\n                }).ToList();\n\n            var allowLocal = true;\n            if (context?.Client.ClientId != null)\n            {\n                var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n                if (client != null)\n                {\n                    allowLocal = client.EnableLocalLogin;\n\n                    if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                    {\n                        providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                    }\n                }\n            }\n\n            return new LoginViewModel\n            {\n                AllowRememberLogin = AccountOptions.AllowRememberLogin,\n                EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n                ExternalProviders = providers.ToArray()\n            };\n        }\n\n        private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n        {\n            var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n            vm.Username = model.Username;\n            vm.RememberLogin = model.RememberLogin;\n            return vm;\n        }\n\n        private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n        {\n            var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n            if (User?.Identity.IsAuthenticated != true)\n            {\n                // if the user is not authenticated, then just show logged out page\n                vm.ShowLogoutPrompt = false;\n                return vm;\n            }\n\n            var context = await _interaction.GetLogoutContextAsync(logoutId);\n            if (context?.ShowSignoutPrompt == false)\n            {\n                // it's safe to automatically sign-out\n                vm.ShowLogoutPrompt = false;\n                return vm;\n            }\n\n            // show the logout prompt. this prevents attacks where the user\n            // is automatically signed out by another malicious web page.\n            return vm;\n        }\n\n        private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n        {\n            // get context information (client name, post logout redirect URI and iframe for federated signout)\n            var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n            var vm = new LoggedOutViewModel\n            {\n                AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n                PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n                ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n                SignOutIframeUrl = logout?.SignOutIFrameUrl,\n                LogoutId = logoutId\n            };\n\n            if (User?.Identity.IsAuthenticated == true)\n            {\n                var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n                if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n                {\n                    var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                    if (providerSupportsSignout)\n                    {\n                        if (vm.LogoutId == null)\n                        {\n                            // if there's no current logout context, we need to create one\n                            // this captures necessary info from the current logged in user\n                            // before we signout and redirect away to the external IdP for signout\n                            vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                        }\n\n                        vm.ExternalAuthenticationScheme = idp;\n                    }\n                }\n            }\n\n            return vm;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class AccountOptions\n{\n    public static bool AllowLocalLogin = true;\n    public static bool AllowRememberLogin = true;\n    public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n    public static bool ShowLogoutPrompt = true;\n    public static bool AutomaticRedirectAfterSignOut = false;\n\n    public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n        private readonly TestUserStore _users;\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IClientStore _clientStore;\n        private readonly ILogger<ExternalController> _logger;\n        private readonly IEventService _events;\n\n        public ExternalController(\n            IIdentityServerInteractionService interaction,\n            IClientStore clientStore,\n            IEventService events,\n            ILogger<ExternalController> logger,\n            TestUserStore users = null)\n        {\n            // if the TestUserStore is not in DI, then we'll just use the global users collection\n            // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n            _users = users ?? new TestUserStore(TestUsers.Users);\n\n            _interaction = interaction;\n            _clientStore = clientStore;\n            _logger = logger;\n            _events = events;\n        }\n\n        /// <summary>\n        /// initiate roundtrip to external authentication provider\n        /// </summary>\n        [HttpGet]\n        public IActionResult Challenge(string scheme, string returnUrl)\n        {\n            if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n            // validate returnUrl - either it is a valid OIDC URL or back to a local page\n            if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n            {\n                // user might have clicked on a malicious link - should be logged\n                throw new Exception(\"invalid return URL\");\n            }\n            \n            // start challenge and roundtrip the return URL and scheme \n            var props = new AuthenticationProperties\n            {\n                RedirectUri = Url.Action(nameof(Callback)), \n                Items =\n                {\n                    { \"returnUrl\", returnUrl }, \n                    { \"scheme\", scheme },\n                }\n            };\n\n            return Challenge(props, scheme);\n            \n        }\n\n        /// <summary>\n        /// Post processing of external authentication\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> Callback()\n        {\n            // read external identity from the temporary cookie\n            var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n            if (result?.Succeeded != true)\n            {\n                throw new Exception(\"External authentication error\");\n            }\n\n            if (_logger.IsEnabled(LogLevel.Debug))\n            {\n                var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n                _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n            }\n\n            // lookup our user and external provider info\n            var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n            if (user == null)\n            {\n                // this might be where you might initiate a custom workflow for user registration\n                // in this sample we don't show how that would be done, as our sample implementation\n                // simply auto-provisions new external user\n                user = AutoProvisionUser(provider, providerUserId, claims);\n            }\n\n            // this allows us to collect any additional claims or properties\n            // for the specific protocols used and store them in the local auth cookie.\n            // this is typically used to store data needed for signout from those protocols.\n            var additionalLocalClaims = new List<Claim>();\n            var localSignInProps = new AuthenticationProperties();\n            ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n            \n            // issue authentication cookie for user\n            var isuser = new IdentityServerUser(user.SubjectId)\n            {\n                DisplayName = user.Username,\n                IdentityProvider = provider,\n                AdditionalClaims = additionalLocalClaims\n            };\n\n            await HttpContext.SignInAsync(isuser, localSignInProps);\n\n            // delete temporary cookie used during external authentication\n            await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n            // retrieve return URL\n            var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n            // check if external login is in the context of an OIDC request\n            var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n            await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n            if (context != null)\n            {\n                if (context.IsNativeClient())\n                {\n                    // The client is native, so this change in how to\n                    // return the response is for better UX for the end user.\n                    return this.LoadingPage(\"Redirect\", returnUrl);\n                }\n            }\n\n            return Redirect(returnUrl);\n        }\n\n        private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n        {\n            var externalUser = result.Principal;\n\n            // try to determine the unique id of the external user (issued by the provider)\n            // the most common claim type for that are the sub claim and the NameIdentifier\n            // depending on the external provider, some other claim type might be used\n            var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                              externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                              throw new Exception(\"Unknown userid\");\n\n            // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n            var claims = externalUser.Claims.ToList();\n            claims.Remove(userIdClaim);\n\n            var provider = result.Properties.Items[\"scheme\"];\n            var providerUserId = userIdClaim.Value;\n\n            // find external user\n            var user = _users.FindByExternalProvider(provider, providerUserId);\n\n            return (user, provider, providerUserId, claims);\n        }\n\n        private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n        {\n            var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n            return user;\n        }\n\n        // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n        // this will be different for WS-Fed, SAML2p or other protocols\n        private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n        {\n            // if the external system sent a session id claim, copy it over\n            // so we can use it for single sign-out\n            var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n            if (sid != null)\n            {\n                localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n            }\n\n            // if the external provider issued an id_token, we'll keep it for signout\n            var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n            if (idToken != null)\n            {\n                localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n        public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n        public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n        public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IEventService _events;\n        private readonly ILogger<ConsentController> _logger;\n\n        public ConsentController(\n            IIdentityServerInteractionService interaction,\n            IEventService events,\n            ILogger<ConsentController> logger)\n        {\n            _interaction = interaction;\n            _events = events;\n            _logger = logger;\n        }\n\n        /// <summary>\n        /// Shows the consent screen\n        /// </summary>\n        /// <param name=\"returnUrl\"></param>\n        /// <returns></returns>\n        [HttpGet]\n        public async Task<IActionResult> Index(string returnUrl)\n        {\n            var vm = await BuildViewModelAsync(returnUrl);\n            if (vm != null)\n            {\n                return View(\"Index\", vm);\n            }\n\n            return View(\"Error\");\n        }\n\n        /// <summary>\n        /// Handles the consent screen postback\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Index(ConsentInputModel model)\n        {\n            var result = await ProcessConsent(model);\n\n            if (result.IsRedirect)\n            {\n                var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n                if (context?.IsNativeClient() == true)\n                {\n                    // The client is native, so this change in how to\n                    // return the response is for better UX for the end user.\n                    return this.LoadingPage(\"Redirect\", result.RedirectUri);\n                }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n            }\n\n            if (result.HasValidationError)\n            {\n                ModelState.AddModelError(string.Empty, result.ValidationError);\n            }\n\n            if (result.ShowView)\n            {\n                return View(\"Index\", result.ViewModel);\n            }\n\n            return View(\"Error\");\n        }\n\n        /*****************************************/\n        /* helper APIs for the ConsentController */\n        /*****************************************/\n        private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n        {\n            var result = new ProcessConsentResult();\n\n            // validate return url is still valid\n            var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (request == null) return result;\n\n            ConsentResponse grantedConsent = null;\n\n            // user clicked 'no' - send back the standard 'access_denied' response\n            if (model?.Button == \"no\")\n            {\n                grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n            }\n            // user clicked 'yes' - validate the data\n            else if (model?.Button == \"yes\")\n            {\n                // if the user consented to some scope, build the response model\n                if (model.ScopesConsented != null && model.ScopesConsented.Any())\n                {\n                    var scopes = model.ScopesConsented;\n                    if (ConsentOptions.EnableOfflineAccess == false)\n                    {\n                        scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                    }\n\n                    grantedConsent = new ConsentResponse\n                    {\n                        RememberConsent = model.RememberConsent,\n                        ScopesValuesConsented = scopes.ToArray(),\n                        Description = model.Description\n                    };\n\n                    // emit event\n                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n                }\n                else\n                {\n                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n                }\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n            }\n\n            if (grantedConsent != null)\n            {\n                // communicate outcome of consent back to identityserver\n                await _interaction.GrantConsentAsync(request, grantedConsent);\n\n                // indicate that's it ok to redirect back to authorization endpoint\n                result.RedirectUri = model.ReturnUrl;\n                result.Client = request.Client;\n            }\n            else\n            {\n                // we need to redisplay the consent UI\n                result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n            }\n\n            return result;\n        }\n\n        private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n        {\n            var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n            if (request != null)\n            {\n                return CreateConsentViewModel(model, returnUrl, request);\n            }\n            else\n            {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n            }\n\n            return null;\n        }\n\n        private ConsentViewModel CreateConsentViewModel(\n            ConsentInputModel model, string returnUrl,\n            AuthorizationRequest request)\n        {\n            var vm = new ConsentViewModel\n            {\n                RememberConsent = model?.RememberConsent ?? true,\n                ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n                Description = model?.Description,\n\n                ReturnUrl = returnUrl,\n\n                ClientName = request.Client.ClientName ?? request.Client.ClientId,\n                ClientUrl = request.Client.ClientUri,\n                ClientLogoUrl = request.Client.LogoUri,\n                AllowRememberConsent = request.Client.AllowRememberConsent\n            };\n\n            vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n            var apiScopes = new List<ScopeViewModel>();\n            foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n            {\n                var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n                if (apiScope != null)\n                {\n                    var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                    apiScopes.Add(scopeVm);\n                }\n            }\n            if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n            {\n                apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n            }\n            vm.ApiScopes = apiScopes;\n\n            return vm;\n        }\n\n        private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = identity.Name,\n                DisplayName = identity.DisplayName ?? identity.Name,\n                Description = identity.Description,\n                Emphasize = identity.Emphasize,\n                Required = identity.Required,\n                Checked = check || identity.Required\n            };\n        }\n\n        public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n        {\n            var displayName = apiScope.DisplayName ?? apiScope.Name;\n            if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n            {\n                displayName += \":\" + parsedScopeValue.ParsedParameter;\n            }\n\n            return new ScopeViewModel\n            {\n                Value = parsedScopeValue.RawValue,\n                DisplayName = displayName,\n                Description = apiScope.Description,\n                Emphasize = apiScope.Emphasize,\n                Required = apiScope.Required,\n                Checked = check || apiScope.Required\n            };\n        }\n\n        private ScopeViewModel GetOfflineAccessScope(bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n                DisplayName = ConsentOptions.OfflineAccessDisplayName,\n                Description = ConsentOptions.OfflineAccessDescription,\n                Emphasize = true,\n                Checked = check\n            };\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n        public string Button { get; set; }\n        public IEnumerable<string> ScopesConsented { get; set; }\n        public bool RememberConsent { get; set; }\n        public string ReturnUrl { get; set; }\n        public string Description { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n        public static bool EnableOfflineAccess = true;\n        public static string OfflineAccessDisplayName = \"Offline Access\";\n        public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n        public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n        public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n        public string ClientName { get; set; }\n        public string ClientUrl { get; set; }\n        public string ClientLogoUrl { get; set; }\n        public bool AllowRememberConsent { get; set; }\n\n        public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n        public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n        public bool IsRedirect => RedirectUri != null;\n        public string RedirectUri { get; set; }\n        public Client Client { get; set; }\n\n        public bool ShowView => ViewModel != null;\n        public ConsentViewModel ViewModel { get; set; }\n\n        public bool HasValidationError => ValidationError != null;\n        public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n        public string Value { get; set; }\n        public string DisplayName { get; set; }\n        public string Description { get; set; }\n        public bool Emphasize { get; set; }\n        public bool Required { get; set; }\n        public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n        public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n        public string UserCode { get; set; }\n        public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n        private readonly IDeviceFlowInteractionService _interaction;\n        private readonly IEventService _events;\n        private readonly IOptions<IdentityServerOptions> _options;\n        private readonly ILogger<DeviceController> _logger;\n\n        public DeviceController(\n            IDeviceFlowInteractionService interaction,\n            IEventService eventService,\n            IOptions<IdentityServerOptions> options,\n            ILogger<DeviceController> logger)\n        {\n            _interaction = interaction;\n            _events = eventService;\n            _options = options;\n            _logger = logger;\n        }\n\n        [HttpGet]\n        public async Task<IActionResult> Index()\n        {\n            string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n            string userCode = Request.Query[userCodeParamName];\n            if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n            var vm = await BuildViewModelAsync(userCode);\n            if (vm == null) return View(\"Error\");\n\n            vm.ConfirmUserCode = true;\n            return View(\"UserCodeConfirmation\", vm);\n        }\n\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> UserCodeCapture(string userCode)\n        {\n            var vm = await BuildViewModelAsync(userCode);\n            if (vm == null) return View(\"Error\");\n\n            return View(\"UserCodeConfirmation\", vm);\n        }\n\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n        {\n            if (model == null) throw new ArgumentNullException(nameof(model));\n\n            var result = await ProcessConsent(model);\n            if (result.HasValidationError) return View(\"Error\");\n\n            return View(\"Success\");\n        }\n\n        private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n        {\n            var result = new ProcessConsentResult();\n\n            var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n            if (request == null) return result;\n\n            ConsentResponse grantedConsent = null;\n\n            // user clicked 'no' - send back the standard 'access_denied' response\n            if (model.Button == \"no\")\n            {\n                grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n            }\n            // user clicked 'yes' - validate the data\n            else if (model.Button == \"yes\")\n            {\n                // if the user consented to some scope, build the response model\n                if (model.ScopesConsented != null && model.ScopesConsented.Any())\n                {\n                    var scopes = model.ScopesConsented;\n                    if (ConsentOptions.EnableOfflineAccess == false)\n                    {\n                        scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                    }\n\n                    grantedConsent = new ConsentResponse\n                    {\n                        RememberConsent = model.RememberConsent,\n                        ScopesValuesConsented = scopes.ToArray(),\n                        Description = model.Description\n                    };\n\n                    // emit event\n                    await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n                }\n                else\n                {\n                    result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n                }\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n            }\n\n            if (grantedConsent != null)\n            {\n                // communicate outcome of consent back to identityserver\n                await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n                // indicate that's it ok to redirect back to authorization endpoint\n                result.RedirectUri = model.ReturnUrl;\n                result.Client = request.Client;\n            }\n            else\n            {\n                // we need to redisplay the consent UI\n                result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n            }\n\n            return result;\n        }\n\n        private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n        {\n            var request = await _interaction.GetAuthorizationContextAsync(userCode);\n            if (request != null)\n            {\n                return CreateConsentViewModel(userCode, model, request);\n            }\n\n            return null;\n        }\n\n        private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n        {\n            var vm = new DeviceAuthorizationViewModel\n            {\n                UserCode = userCode,\n                Description = model?.Description,\n\n                RememberConsent = model?.RememberConsent ?? true,\n                ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n                ClientName = request.Client.ClientName ?? request.Client.ClientId,\n                ClientUrl = request.Client.ClientUri,\n                ClientLogoUrl = request.Client.LogoUri,\n                AllowRememberConsent = request.Client.AllowRememberConsent\n            };\n\n            vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n            var apiScopes = new List<ScopeViewModel>();\n            foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n            {\n                var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n                if (apiScope != null)\n                {\n                    var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                    apiScopes.Add(scopeVm);\n                }\n            }\n            if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n            {\n                apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n            }\n            vm.ApiScopes = apiScopes;\n\n            return vm;\n        }\n\n        private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = identity.Name,\n                DisplayName = identity.DisplayName ?? identity.Name,\n                Description = identity.Description,\n                Emphasize = identity.Emphasize,\n                Required = identity.Required,\n                Checked = check || identity.Required\n            };\n        }\n\n        public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = parsedScopeValue.RawValue,\n                // todo: use the parsed scope value in the display?\n                DisplayName = apiScope.DisplayName ?? apiScope.Name,\n                Description = apiScope.Description,\n                Emphasize = apiScope.Emphasize,\n                Required = apiScope.Required,\n                Checked = check || apiScope.Required\n            };\n        }\n        private ScopeViewModel GetOfflineAccessScope(bool check)\n        {\n            return new ScopeViewModel\n            {\n                Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n                DisplayName = ConsentOptions.OfflineAccessDisplayName,\n                Description = ConsentOptions.OfflineAccessDescription,\n                Emphasize = true,\n                Checked = check\n            };\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n        public async Task<IActionResult> Index()\n        {\n            var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n            if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n            {\n                return NotFound();\n            }\n\n            var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n            return View(model);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n        public DiagnosticsViewModel(AuthenticateResult result)\n        {\n            AuthenticateResult = result;\n\n            if (result.Properties.Items.ContainsKey(\"client_list\"))\n            {\n                var encoded = result.Properties.Items[\"client_list\"];\n                var bytes = Base64Url.Decode(encoded);\n                var value = Encoding.UTF8.GetString(bytes);\n\n                Clients = JsonConvert.DeserializeObject<string[]>(value);\n            }\n        }\n\n        public AuthenticateResult AuthenticateResult { get; }\n        public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n        /// <summary>\n        /// Checks if the redirect URI is for a native client.\n        /// </summary>\n        /// <returns></returns>\n        public static bool IsNativeClient(this AuthorizationRequest context)\n        {\n            return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n               && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n        }\n\n        public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n        {\n            controller.HttpContext.Response.StatusCode = 200;\n            controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n            \n            return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IClientStore _clients;\n        private readonly IResourceStore _resources;\n        private readonly IEventService _events;\n\n        public GrantsController(IIdentityServerInteractionService interaction,\n            IClientStore clients,\n            IResourceStore resources,\n            IEventService events)\n        {\n            _interaction = interaction;\n            _clients = clients;\n            _resources = resources;\n            _events = events;\n        }\n\n        /// <summary>\n        /// Show list of grants\n        /// </summary>\n        [HttpGet]\n        public async Task<IActionResult> Index()\n        {\n            return View(\"Index\", await BuildViewModelAsync());\n        }\n\n        /// <summary>\n        /// Handle postback to revoke a client\n        /// </summary>\n        [HttpPost]\n        [ValidateAntiForgeryToken]\n        public async Task<IActionResult> Revoke(string clientId)\n        {\n            await _interaction.RevokeUserConsentAsync(clientId);\n            await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n            return RedirectToAction(\"Index\");\n        }\n\n        private async Task<GrantsViewModel> BuildViewModelAsync()\n        {\n            var grants = await _interaction.GetAllUserGrantsAsync();\n\n            var list = new List<GrantViewModel>();\n            foreach(var grant in grants)\n            {\n                var client = await _clients.FindClientByIdAsync(grant.ClientId);\n                if (client != null)\n                {\n                    var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                    var item = new GrantViewModel()\n                    {\n                        ClientId = client.ClientId,\n                        ClientName = client.ClientName ?? client.ClientId,\n                        ClientLogoUrl = client.LogoUri,\n                        ClientUrl = client.ClientUri,\n                        Description = grant.Description,\n                        Created = grant.CreationTime,\n                        Expires = grant.Expiration,\n                        IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                        ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                    };\n\n                    list.Add(item);\n                }\n            }\n\n            return new GrantsViewModel\n            {\n                Grants = list\n            };\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n        public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n        public string ClientId { get; set; }\n        public string ClientName { get; set; }\n        public string ClientUrl { get; set; }\n        public string ClientLogoUrl { get; set; }\n        public string Description { get; set; }\n        public DateTime Created { get; set; }\n        public DateTime? Expires { get; set; }\n        public IEnumerable<string> IdentityGrantNames { get; set; }\n        public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n        public ErrorViewModel()\n        {\n        }\n\n        public ErrorViewModel(string error)\n        {\n            Error = new ErrorMessage { Error = error };\n        }\n\n        public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n        private readonly IIdentityServerInteractionService _interaction;\n        private readonly IWebHostEnvironment _environment;\n        private readonly ILogger _logger;\n\n        public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n        {\n            _interaction = interaction;\n            _environment = environment;\n            _logger = logger;\n        }\n\n        public IActionResult Index()\n        {\n            if (_environment.IsDevelopment())\n            {\n                // only show in development\n                return View();\n            }\n\n            _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n            return NotFound();\n        }\n\n        /// <summary>\n        /// Shows the error page\n        /// </summary>\n        public async Task<IActionResult> Error(string errorId)\n        {\n            var vm = new ErrorViewModel();\n\n            // retrieve error details from identityserver\n            var message = await _interaction.GetErrorContextAsync(errorId);\n            if (message != null)\n            {\n                vm.Error = message;\n\n                if (!_environment.IsDevelopment())\n                {\n                    // only show in development\n                    message.ErrorDescription = null;\n                }\n            }\n\n            return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n        public override void OnResultExecuting(ResultExecutingContext context)\n        {\n            var result = context.Result;\n            if (result is ViewResult)\n            {\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n                {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n                }\n\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n                {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n                }\n\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n                var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n                // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n                //csp += \"upgrade-insecure-requests;\";\n                // also an example if you need client images to be displayed from twitter\n                // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n                // once for standards compliant browsers\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n                {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n                }\n                // and once again for IE\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n                {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n                }\n\n                // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n                var referrer_policy = \"no-referrer\";\n                if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n                {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonSerializer = System.Text.Json.JsonSerializer;\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n    public static List<TestUser> Users\n    {\n        get\n        {\n            var address = new\n            {\n                street_address = \"One Hacker Way\",\n                locality = \"Heidelberg\",\n                postal_code = 69118,\n                country = \"Germany\"\n            };\n\n            return new List<TestUser>\n    {\n                new TestUser\n        {\n                    SubjectId = \"818727\",\n                    Username = \"alice\",\n                    Password = \"alice\",\n                Claims = \n                {\n                    new Claim(JwtClaimTypes.Name, \"Alice Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Alice\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"AliceSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.WebSite, \"http://alice.com\"),\n                        new Claim(JwtClaimTypes.Address, JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json)\n                }\n            },\n                new TestUser\n                {\n                    SubjectId = \"88421113\",\n                    Username = \"bob\",\n                    Password = \"bob\",\n                Claims = \n                {\n                    new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"BobSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                        new Claim(JwtClaimTypes.Address, JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json)\n                }\n            }\n        };\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore;\n\nnamespace IdentityServerHost;\n\npublic class Startup\n{\n    private readonly IConfiguration _config;\n\n    public Startup(IConfiguration config)\n    {\n        _config = config;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddControllersWithViews();\n\n        var connectionString = _config.GetConnectionString(\"db\");\n\n        services.AddIdentityServer()\n            .AddDeveloperSigningCredential()\n            .AddTestUsers(TestUsers.Users)\n            // this adds the config data from DB (clients, resources, CORS)\n            .AddConfigurationStore(options =>\n            {\n                options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString);\n            })\n            // this adds the operational data from DB (codes, tokens, consents)\n            .AddOperationalStore(options =>\n            {\n                options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString);\n\n                // this enables automatic token cleanup. this is optional.\n                options.EnableTokenCleanup = true;\n                options.TokenCleanupInterval = 5; // interval in seconds, short for testing\n            });\n        // this is something you will want in production to reduce load on and requests to the DB\n        //.AddConfigurationStoreCache();\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseDeveloperExceptionPage();\n\n        app.UseStaticFiles();\n\n        app.UseRouting();\n\n        app.UseIdentityServer();\n\n        app.UseAuthorization();\n\n        app.UseEndpoints(endpoints =>\n        {\n            endpoints.MapDefaultControllerRoute();\n        });\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/TestOperationalStoreNotification.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework;\nusing IdentityServer8.EntityFramework.Entities;\nusing PersistedGrant = IdentityServer8.EntityFramework.Entities.PersistedGrant;\n\nnamespace IdentityServerHost\n{\n    public class TestOperationalStoreNotification : IOperationalStoreNotification\n    {\n        public TestOperationalStoreNotification()\n        {\n            Console.WriteLine(\"ctor\");\n        }\n\n        public Task PersistedGrantsRemovedAsync(IEnumerable<PersistedGrant> persistedGrants)\n        {\n            foreach (var grant in persistedGrants)\n            {\n                Console.WriteLine(\"cleaned: \" + grant.Type);\n            }\n            return Task.CompletedTask;\n        }\n\n        public Task DeviceCodesRemovedAsync(IEnumerable<DeviceFlowCodes> deviceCodes)\n        {\n            foreach (var deviceCode in deviceCodes) \n            {\n                Console.WriteLine(\"cleaned device code\");\n            }\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "src/EntityFramework/host/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "src/EntityFramework/host/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "src/EntityFramework/host/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n@using System.Reflection\n\n@{\n    var version = typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Model.RedirectUrl.SanitizeForUrl()';\n    window.location.href = url;\n</script>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "src/EntityFramework/host/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "src/EntityFramework/host/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "src/EntityFramework/host/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "src/EntityFramework/host/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "src/EntityFramework/host/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"db\": \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.EntityFramework-4.0.0;trusted_connection=yes;\",\n  }\n}"
  },
  {
    "path": "src/EntityFramework/host/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "src/EntityFramework/host/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "src/EntityFramework/host/wwwroot/js/signin-redirect.js",
    "content": "//window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "src/EntityFramework/host/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/Configuration/Clients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing System.Collections.Generic;\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class Clients\n{\n    public static IEnumerable<Client> Get()\n    {\n        var clients = new List<Client>();\n        \n        clients.AddRange(ClientsConsole.Get());\n        clients.AddRange(ClientsWeb.Get());\n\n        return clients;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/Configuration/ClientsConsole.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8;\nusing IdentityServer8.Models;\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class ClientsConsole\n{\n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            ///////////////////////////////////////////////////////////////\n            // Console-based Client\n            ///////////////////////////////////////////////////////////////\n\n\n            ///////////////////////////////////////////\n            // Console Client Credentials Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\", IdentityServerConstants.LocalApi.ScopeName}\n            },\n            \n            ///////////////////////////////////////////\n            // Console Structured Scope Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"parameterized.client\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"transaction\" }\n            },\n\n            ///////////////////////////////////////////\n            // X509 mTLS Client\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mtls\",\n                ClientSecrets =\n                {\n                    // new Secret(@\"CN=mtls.test, OU=ROO\\ballen@roo, O=mkcert development certificate\", \"mtls.test\")\n                    // {\n                    //     Type = SecretTypes.X509CertificateName\n                    // },\n                    new Secret(\"5D9E9B6B333CD42C99D1DE6175CC0F3EF99DDF68\", \"mtls.test\")\n                    {\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateThumbprint\n                    },\n                },\n                \n                AccessTokenType = AccessTokenType.Jwt,\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Console Client Credentials Flow with client JWT assertion\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client.jwt\",\n                ClientSecrets =\n                {\n                    new Secret\n                    {\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                        Value =\n                            \"MIIEgTCCAumgAwIBAgIQDMMu7l/umJhfEbzJMpcttzANBgkqhkiG9w0BAQsFADCBkzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTQwMgYDVQQLDCtkb21pbmlja0Bkb21icDE2LmZyaXR6LmJveCAoRG9taW5pY2sgQmFpZXIpMTswOQYDVQQDDDJta2NlcnQgZG9taW5pY2tAZG9tYnAxNi5mcml0ei5ib3ggKERvbWluaWNrIEJhaWVyKTAeFw0xOTA2MDEwMDAwMDBaFw0zMDAxMDMxMjM0MDdaMHAxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTE0MDIGA1UECwwrZG9taW5pY2tAZG9tYnAxNi5mcml0ei5ib3ggKERvbWluaWNrIEJhaWVyKTEPMA0GA1UEAxMGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvNtpipaS8k1zA6w0Aoy8U4l+8zM4jHhhblExf3PULrMR6RauxniTki8p+P8CsZT4V8A4qo+JwsgpLIHrVQrbt9DEhHfBKzxwHqt+GoHt7byTfTtp8A/5nLhYc/5CW4HiR194gVx5+HAlvt+BriMTb1czvTf+H20dj41yUPsN7nMdyRLF+uXapQYMLYnq2BJIDq83mqGwojHk7d+N6GwoO95jlyas7KSoj8/FvfbaqkRNx0446hqPOzFHKc8er8K5VrLp6tVjh8ZJyY0F0dKgx6yWITsL54ctbj/cCyfuGjWEMbS2XXgc+x/xQMnmpfhK1qQAUn9jg5EzF9n6mQomOwIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUEMUlw41YsKZQVls3pEG6CrJk4O8wEQYDVR0RBAowCIIGY2xpZW50MA0GCSqGSIb3DQEBCwUAA4IBgQC0TjNY4Q3Wmw7ggamDImV6HUng3WbYGLYbbL2e3myBrjIxGd1Bi8ZyOu8qeUMIRAbZt2YsSX5S8kx0biaVg2zC+aO5eHhEWMwKB66huInXFjI4wtxZ22r+33fg1R0cLuEUePhftOWrbL0MS4YXVyn9HUMWO4WptG9PJdxNw1UbEB8nw3FkVOdAC9RGqiqalSK+E2UT/kUbTIQ1gPSdQ3nh52mre0H/T9+IRqiozJtNK/CQg4NuEV7rUXHnp7Fmigp6RIJ4TCozglspL341y0rV8M7npU1FYZC2UKNr4ed+GOO1n/sF3LbXDlPXwne99CVVn85wjDaevoR7Md0y2KwE9EggLYcViXNehx4YVv/BjfgqxW8NxiKAxP6kPOZE0XdBrZj2rmcDcGOXCzzYpcduKhFyTOpA0K5RNGC3j1KOUjPVlOtLvjASP7udBEYNfH3mgqXAgqNDOEKi2jG9LITv2IyGUsXhTAsKNJ6A6qiDBzDrvPAYDvsfabPq6tRTwjA=\"\n                    },\n                    new Secret\n                    {\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value =\n                            \"{'e':'AQAB','kid':'ZzAjSnraU3bkWGnnAqLapYGpTyNfLbjbzgAPbbW2GEA','kty':'RSA','n':'wWwQFtSzeRjjerpEM5Rmqz_DsNaZ9S1Bw6UbZkDLowuuTCjBWUax0vBMMxdy6XjEEK4Oq9lKMvx9JzjmeJf1knoqSNrox3Ka0rnxXpNAz6sATvme8p9mTXyp0cX4lF4U2J54xa2_S9NF5QWvpXvBeC4GAJx7QaSw4zrUkrc6XyaAiFnLhQEwKJCwUw4NOqIuYvYp_IXhw-5Ti_icDlZS-282PcccnBeOcX7vc21pozibIdmZJKqXNsL1Ibx5Nkx1F1jLnekJAmdaACDjYRLL_6n3W4wUp19UvzB1lGtXcJKLLkqB6YDiZNu16OSiSprfmrRXvYmvD8m6Fnl5aetgKw'}\"\n                    }\n                },\n                \n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Custom Grant Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client.custom\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = {\"custom\", \"custom.nosubject\"},\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Console Resource Owner Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    \"custom.profile\",\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n\n            ///////////////////////////////////////////\n            // Console Public Resource Owner Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient.public\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n\n            ///////////////////////////////////////////\n            // Console with PKCE Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"console.pkce\",\n                ClientName = \"Console with PKCE Sample\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n                RedirectUris = {\"http://127.0.0.1\"},\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n            ///////////////////////////////////////////\n            // WinConsole with PKCE Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"winconsole\",\n                ClientName = \"Windows Console with PKCE Sample\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n                RedirectUris = {\"sample-windows-client://callback\"},\n                RequireConsent = false,\n                AllowOfflineAccess = true,\n                AllowedIdentityTokenSigningAlgorithms = {\"ES256\"},\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            },\n\n\n            ///////////////////////////////////////////\n            // Introspection Client Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient.reference\",\n                ClientSecrets = {new Secret(\"secret\".Sha256())},\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" },\n                AccessTokenType = AccessTokenType.Reference\n            },\n            \n            ///////////////////////////////////////////\n            // Device Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"device\",\n                ClientName = \"Device Flow Client\",\n\n                AllowedGrantTypes = GrantTypes.DeviceFlow,\n                RequireClientSecret = false,\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\", \"resource2.scope1\"\n                }\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/Configuration/ClientsWeb.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8;\nusing IdentityServer8.Models;\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class ClientsWeb\n{\n    static string[] allowedScopes = \n    {\n        IdentityServerConstants.StandardScopes.OpenId,\n        IdentityServerConstants.StandardScopes.Profile,\n        IdentityServerConstants.StandardScopes.Email,\n        \"resource1.scope1\", \n        \"resource2.scope1\",\n        \"transaction\"\n    };\n    \n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            ///////////////////////////////////////////\n            // JS OIDC Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"js_oidc\",\n                ClientName = \"JavaScript OIDC Client\",\n                ClientUri = \"http://identityserver8.io\",\n                \n                AllowedGrantTypes = GrantTypes.Code,\n                RequireClientSecret = false,\n                \n                RedirectUris = \n                {\n                    \"https://localhost:44300/index.html\",\n                    \"https://localhost:44300/callback.html\",\n                    \"https://localhost:44300/silent.html\",\n                    \"https://localhost:44300/popup.html\"\n                },\n\n                PostLogoutRedirectUris = { \"https://localhost:44300/index.html\" },\n                AllowedCorsOrigins = { \"https://localhost:44300\" },\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Automatic Token Management Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.tokenmanagement\",\n                \n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n\n                AccessTokenLifetime = 75,\n\n                RedirectUris = { \"https://localhost:44301/signin-oidc\" },\n                FrontChannelLogoutUri = \"https://localhost:44301/signout-oidc\",\n                PostLogoutRedirectUris = { \"https://localhost:44301/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Code Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.code\",\n                ClientName = \"MVC Code Flow\",\n                ClientUri = \"http://identityserver8.io\",\n\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                RequireConsent = true,\n                AllowedGrantTypes = GrantTypes.Code,\n\n                RedirectUris = { \"https://localhost:44302/signin-oidc\" },\n                FrontChannelLogoutUri = \"https://localhost:44302/signout-oidc\",\n                PostLogoutRedirectUris = { \"https://localhost:44302/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Hybrid Flow Sample (Back Channel logout)\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.hybrid.backchannel\",\n                ClientName = \"MVC Hybrid (with BackChannel logout)\",\n                ClientUri = \"http://identityserver8.io\",\n\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.Hybrid,\n                RequirePkce = false,\n\n                RedirectUris = { \"https://localhost:44303/signin-oidc\" },\n                BackChannelLogoutUri = \"https://localhost:44303/logout\",\n                PostLogoutRedirectUris = { \"https://localhost:44303/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/Configuration/Resources.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityModel;\nusing IdentityServer8.Models;\nusing System.Collections.Generic;\nusing static IdentityServer8.IdentityServerConstants;\n\nnamespace IdentityServerHost.Configuration;\n\npublic class Resources\n{\n    // identity resources represent identity data about a user that can be requested via the scope parameter (OpenID Connect)\n    public static readonly IEnumerable<IdentityResource> IdentityResources =\n        new[]\n        {\n            // some standard scopes from the OIDC spec\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email(),\n\n            // custom identity resource with some consolidated claims\n            new IdentityResource(\"custom.profile\", new[] { JwtClaimTypes.Name, JwtClaimTypes.Email, \"location\" })\n        };\n\n    // API scopes represent values that describe scope of access and can be requested by the scope parameter (OAuth)\n    public static readonly IEnumerable<ApiScope> ApiScopes =\n        new[]\n        {\n            // local API scope\n            new ApiScope(LocalApi.ScopeName),\n\n            // resource specific scopes\n            new ApiScope(\"resource1.scope1\"),\n            new ApiScope(\"resource2.scope1\"), \n            \n            // a scope without resource association\n            new ApiScope(\"scope3\"),\n            \n            // a scope shared by multiple resources\n            new ApiScope(\"shared.scope\"),\n\n            // a parameterized scope\n            new ApiScope(\"transaction\", \"Transaction\")\n            {\n                Description = \"Some Transaction\"\n            }\n        };\n\n    // API resources are more formal representation of a resource with processing rules and their scopes (if any)\n    public static readonly IEnumerable<ApiResource> ApiResources = \n        new[]\n        {\n            new ApiResource(\"resource1\", \"Resource 1\")\n            {\n                ApiSecrets = { new Secret(\"secret\".Sha256()) },\n\n                Scopes = { \"resource1.scope1\", \"shared.scope\" }\n            },\n            \n            // expanded version if more control is needed\n            new ApiResource(\"resource2\", \"Resource 2\")\n            {\n                ApiSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                // additional claims to put into access token\n                UserClaims =\n                {\n                    JwtClaimTypes.Name,\n                    JwtClaimTypes.Email\n                },\n\n                Scopes = { \"resource2.scope1\", \"shared.scope\" }\n            }\n        };\n}\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore;\n\nnamespace SqlServer;\n\nclass Program\n{\n    public static void Main(string[] args)\n    {\n        var host = BuildWebHost(args);\n        SeedData.EnsureSeedData(host.Services);\n    }\n\n    public static IWebHost BuildWebHost(string[] args) =>\n        WebHost.CreateDefaultBuilder(args)\n            .UseStartup<Startup>()\n            .Build();\n}\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:7603/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"SqlServer\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:7604/\"\n    }\n  }\n}"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/SeedData.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServerHost.Configuration;\n\nnamespace SqlServer;\n\npublic class SeedData\n{\n    public static void EnsureSeedData(IServiceProvider serviceProvider)\n    {\n        using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())\n        {\n            using (var context = scope.ServiceProvider.GetService<ConfigurationDbContext>())\n            {\n                EnsureSeedData(context);\n            }\n        }\n    }\n\n    private static void EnsureSeedData(ConfigurationDbContext context)\n    {\n        Console.WriteLine(\"Seeding database...\");\n\n        if (!context.Clients.Any())\n        {\n            Console.WriteLine(\"Clients being populated\");\n            foreach (var client in Clients.Get())\n            {\n                context.Clients.Add(client.ToEntity());\n            }\n            context.SaveChanges();\n        }\n        else\n        {\n            Console.WriteLine(\"Clients already populated\");\n        }\n\n        if (!context.IdentityResources.Any())\n        {\n            Console.WriteLine(\"IdentityResources being populated\");\n            foreach (var resource in Resources.IdentityResources)\n            {\n                context.IdentityResources.Add(resource.ToEntity());\n            }\n            context.SaveChanges();\n        }\n        else\n        {\n            Console.WriteLine(\"IdentityResources already populated\");\n        }\n\n        if (!context.ApiResources.Any())\n        {\n            Console.WriteLine(\"ApiResources being populated\");\n            foreach (var resource in Resources.ApiResources)\n            {\n                context.ApiResources.Add(resource.ToEntity());\n            }\n            context.SaveChanges();\n        }\n        else\n        {\n            Console.WriteLine(\"ApiResources already populated\");\n        }\n\n        if (!context.ApiScopes.Any())\n        {\n            Console.WriteLine(\"Scopes being populated\");\n            foreach (var resource in Resources.ApiScopes)\n            {\n                context.ApiScopes.Add(resource.ToEntity());\n            }\n            context.SaveChanges();\n        }\n        else\n        {\n            Console.WriteLine(\"Scopes already populated\");\n        }\n\n        Console.WriteLine(\"Done seeding database.\");\n        Console.WriteLine();\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/SqlServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.EntityFramework.csproj\" />\n\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore;\n\nnamespace SqlServer;\n\npublic class Startup\n{\n    public IConfiguration Configuration { get; }\n\n    public Startup(IConfiguration config)\n    {\n        Configuration = config;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var cn = Configuration.GetConnectionString(\"db\");\n\n        services.AddIdentityServer()\n            .AddConfigurationStore(options => {\n                options.ConfigureDbContext = b => b.UseSqlServer(cn);\n            })\n            .AddOperationalStore(options => {\n                options.ConfigureDbContext = b => b.UseSqlServer(cn);\n            });\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/migrations/SqlServer/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"db\": \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.EntityFramework-8.0.0;trusted_connection=yes;\",\n  }\n}"
  },
  {
    "path": "src/EntityFramework/migrations.bat",
    "content": "cd host\nrmdir /S /Q Migrations\n\ndotnet ef migrations add Grants -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb\ndotnet ef migrations add Config -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb\ndotnet ef migrations script -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb.sql\ndotnet ef migrations script -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb.sql\n\ncd ..\n"
  },
  {
    "path": "src/EntityFramework/src/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityServer8.EntityFramework;\nglobal using IdentityServer8.EntityFramework.DbContexts;\nglobal using IdentityServer8.EntityFramework.Interfaces;\nglobal using IdentityServer8.EntityFramework.Options;\nglobal using IdentityServer8.EntityFramework.Services;\nglobal using IdentityServer8.EntityFramework.Storage;\nglobal using IdentityServer8.EntityFramework.Stores;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using Microsoft.AspNetCore.Http;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Hosting;\nglobal using Microsoft.Extensions.Logging;\n"
  },
  {
    "path": "src/EntityFramework/src/IdentityServer8.EntityFramework.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <Description>EntityFramework persistence layer for IdentityServer8</Description>\n        <IsPackable>true</IsPackable>\n        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n    </PropertyGroup>\n\n    <PropertyGroup>\n        <ContinuousIntegrationBuild Condition=\"'$(TF_BUILD)' == 'true'\">True</ContinuousIntegrationBuild>\n        <ContinuousIntegrationBuild Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">True</ContinuousIntegrationBuild>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <ProjectReference Include=\"..\\..\\EntityFramework.Storage\\src\\IdentityServer8.EntityFramework.Storage.csproj\" />\n        <ProjectReference Include=\"..\\..\\IdentityServer8\\src\\IdentityServer8.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "src/EntityFramework/src/IdentityServerEntityFrameworkBuilderExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Extension methods to add EF database support to IdentityServer.\n/// </summary>\npublic static class IdentityServerEntityFrameworkBuilderExtensions\n{\n    /// <summary>\n    /// Configures EF implementation of IClientStore, IResourceStore, and ICorsPolicyService with IdentityServer.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"storeOptionsAction\">The store options action.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddConfigurationStore(\n        this IIdentityServerBuilder builder,\n        Action<ConfigurationStoreOptions> storeOptionsAction = null)\n    {\n        return builder.AddConfigurationStore<ConfigurationDbContext>(storeOptionsAction);\n    }\n\n    /// <summary>\n    /// Configures EF implementation of IClientStore, IResourceStore, and ICorsPolicyService with IdentityServer.\n    /// </summary>\n    /// <typeparam name=\"TContext\">The IConfigurationDbContext to use.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"storeOptionsAction\">The store options action.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddConfigurationStore<TContext>(\n        this IIdentityServerBuilder builder,\n        Action<ConfigurationStoreOptions> storeOptionsAction = null)\n        where TContext : DbContext, IConfigurationDbContext\n    {\n        builder.Services.AddConfigurationDbContext<TContext>(storeOptionsAction);\n\n        builder.AddClientStore<ClientStore>();\n        builder.AddResourceStore<ResourceStore>();\n        builder.AddCorsPolicyService<CorsPolicyService>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Configures caching for IClientStore, IResourceStore, and ICorsPolicyService with IdentityServer.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddConfigurationStoreCache(\n        this IIdentityServerBuilder builder)\n    {\n        builder.AddInMemoryCaching();\n\n        // add the caching decorators\n        builder.AddClientStoreCache<ClientStore>();\n        builder.AddResourceStoreCache<ResourceStore>();\n        builder.AddCorsPolicyCache<CorsPolicyService>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Configures EF implementation of IPersistedGrantStore with IdentityServer.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"storeOptionsAction\">The store options action.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddOperationalStore(\n        this IIdentityServerBuilder builder,\n        Action<OperationalStoreOptions> storeOptionsAction = null)\n    {\n        return builder.AddOperationalStore<PersistedGrantDbContext>(storeOptionsAction);\n    }\n\n    /// <summary>\n    /// Configures EF implementation of IPersistedGrantStore with IdentityServer.\n    /// </summary>\n    /// <typeparam name=\"TContext\">The IPersistedGrantDbContext to use.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"storeOptionsAction\">The store options action.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddOperationalStore<TContext>(\n        this IIdentityServerBuilder builder,\n        Action<OperationalStoreOptions> storeOptionsAction = null)\n        where TContext : DbContext, IPersistedGrantDbContext\n    {\n        builder.Services.AddOperationalDbContext<TContext>(storeOptionsAction);\n\n        builder.Services.AddTransient<IPersistedGrantStore, PersistedGrantStore>();\n        builder.Services.AddTransient<IDeviceFlowStore, DeviceFlowStore>();\n        builder.Services.AddSingleton<IHostedService, TokenCleanupHost>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds an implementation of the IOperationalStoreNotification to IdentityServer.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\"></param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddOperationalStoreNotification<T>(\n       this IIdentityServerBuilder builder)\n       where T : class, IOperationalStoreNotification\n    {\n        builder.Services.AddOperationalStoreNotification<T>();\n        return builder;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/src/Services/CorsPolicyService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Services;\n\n/// <summary>\n/// Implementation of ICorsPolicyService that consults the client configuration in the database for allowed CORS origins.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.ICorsPolicyService\" />\npublic class CorsPolicyService : ICorsPolicyService\n{\n    private readonly IHttpContextAccessor _context;\n    private readonly ILogger<CorsPolicyService> _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"CorsPolicyService\"/> class.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"logger\">The logger.</param>\n    /// <exception cref=\"ArgumentNullException\">context</exception>\n    public CorsPolicyService(IHttpContextAccessor context, ILogger<CorsPolicyService> logger)\n    {\n        _context = context ?? throw new ArgumentNullException(nameof(context));\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Determines whether origin is allowed.\n    /// </summary>\n    /// <param name=\"origin\">The origin.</param>\n    /// <returns></returns>\n    public async Task<bool> IsOriginAllowedAsync(string origin)\n    {\n        origin = origin.ToLowerInvariant();\n\n        // doing this here and not in the ctor because: https://github.com/aspnet/CORS/issues/105\n        var dbContext = _context.HttpContext.RequestServices.GetRequiredService<IConfigurationDbContext>();\n\n        var query = from o in dbContext.ClientCorsOrigins\n                    where o.Origin == origin\n                    select o;\n        \n        var isAllowed = await query.AnyAsync();\n\n        _logger.LogDebug(\"Origin {origin} is allowed: {originAllowed}\", Ioc.Sanitizer.Log.Sanitize(origin), isAllowed);\n\n        return isAllowed;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/src/TokenCleanupHost.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Helper to cleanup expired persisted grants.\n/// </summary>\npublic class TokenCleanupHost : IHostedService\n{\n    private readonly IServiceProvider _serviceProvider;\n    private readonly OperationalStoreOptions _options;\n    private readonly ILogger<TokenCleanupHost> _logger;\n\n    private TimeSpan CleanupInterval => TimeSpan.FromSeconds(_options.TokenCleanupInterval);\n    \n    private CancellationTokenSource _source;\n\n    /// <summary>\n    /// Constructor for TokenCleanupHost.\n    /// </summary>\n    /// <param name=\"serviceProvider\"></param>\n    /// <param name=\"options\"></param>\n    /// <param name=\"logger\"></param>\n    public TokenCleanupHost(IServiceProvider serviceProvider, OperationalStoreOptions options, ILogger<TokenCleanupHost> logger)\n    {\n        _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));\n        _options = options ?? throw new ArgumentNullException(nameof(options));\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Starts the token cleanup polling.\n    /// </summary>\n    public Task StartAsync(CancellationToken cancellationToken)\n    {\n        if (_options.EnableTokenCleanup)\n        {\n            if (_source != null) throw new InvalidOperationException(\"Already started. Call Stop first.\");\n\n            _logger.LogDebug(\"Starting grant removal\");\n\n            _source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);\n\n            Task.Factory.StartNew(() => StartInternalAsync(_source.Token));\n        }\n        \n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Stops the token cleanup polling.\n    /// </summary>\n    public Task StopAsync(CancellationToken cancellationToken)\n    {\n        if (_options.EnableTokenCleanup)\n        {\n            if (_source == null) throw new InvalidOperationException(\"Not started. Call Start first.\");\n\n            _logger.LogDebug(\"Stopping grant removal\");\n\n            _source.Cancel();\n            _source = null;\n        }\n\n        return Task.CompletedTask;\n    }\n\n    private async Task StartInternalAsync(CancellationToken cancellationToken)\n    {\n        while (true)\n        {\n            if (cancellationToken.IsCancellationRequested)\n            {\n                _logger.LogDebug(\"CancellationRequested. Exiting.\");\n                break;\n            }\n\n            try\n            {\n                await Task.Delay(CleanupInterval, cancellationToken);\n            }\n            catch (TaskCanceledException)\n            {\n                _logger.LogDebug(\"TaskCanceledException. Exiting.\");\n                break;\n            }\n            catch (Exception ex)\n            {\n                _logger.LogError(\"Task.Delay exception: {0}. Exiting.\", ex.Message);\n                break;\n            }\n\n            if (cancellationToken.IsCancellationRequested)\n            {\n                _logger.LogDebug(\"CancellationRequested. Exiting.\");\n                break;\n            }\n\n            await RemoveExpiredGrantsAsync();\n        }\n    }\n\n    async Task RemoveExpiredGrantsAsync()\n    {\n        try\n        {\n            using (var serviceScope = _serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())\n            {\n                var tokenCleanupService = serviceScope.ServiceProvider.GetRequiredService<TokenCleanupService>();\n                await tokenCleanupService.RemoveExpiredGrantsAsync();\n            }\n        }\n        catch (Exception ex)\n        {\n            _logger.LogError(\"Exception removing expired grants: {exception}\", ex.Message);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/test/IdentityServer8.EntityFramework.Tests/DatabaseProviderBuilder.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\n/// <summary>\n/// Helper methods to initialize DbContextOptions for the specified database provider and context.\n/// </summary>\npublic class DatabaseProviderBuilder\n{\n    public static DbContextOptions<T> BuildInMemory<T>(string name) where T : DbContext\n    {\n        var builder = new DbContextOptionsBuilder<T>();\n        builder.UseInMemoryDatabase(name);\n        return builder.Options;\n    }\n\n    public static DbContextOptions<T> BuildSqlite<T>(string name) where T : DbContext\n    {\n        var builder = new DbContextOptionsBuilder<T>();\n        builder.UseSqlite($\"Filename=./Test.IdentityServer8.EntityFramework-3.1.0.{name}.db\");\n        return builder.Options;\n    }\n\n    public static DbContextOptions<T> BuildLocalDb<T>(string name) where T : DbContext\n    {\n        var builder = new DbContextOptionsBuilder<T>();\n        builder.UseSqlServer(\n            $@\"Data Source=(LocalDb)\\MSSQLLocalDB;database=Test.IdentityServer8.EntityFramework-3.1.0.{name};trusted_connection=yes;\");\n        return builder.Options;\n    }\n\n    public static DbContextOptions<T> BuildAppVeyorSqlServer2016<T>(string name) where T : DbContext\n    {\n        var builder = new DbContextOptionsBuilder<T>();\n        builder.UseSqlServer($@\"Server=(local)\\SQL2016;Database=Test.IdentityServer8.EntityFramework-3.1.0.{name};User ID=sa;Password=Password12!\");\n        return builder.Options;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/test/IdentityServer8.EntityFramework.Tests/DatabaseProviderFixture.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\n/// <summary>\n/// xUnit ClassFixture for creating and deleting integration test databases.\n/// </summary>\n/// <typeparam name=\"T\">DbContext of Type T</typeparam>\npublic class DatabaseProviderFixture<T> : IDisposable where T : DbContext\n{\n    public object StoreOptions;\n    public List<DbContextOptions<T>> Options;\n\n    public void Dispose()\n    {\n        if (Options != null) // null check since fixtures are created even when tests are skipped\n        {\n            foreach (var option in Options.ToList())\n            {\n                using (var context = (T)Activator.CreateInstance(typeof(T), option, StoreOptions))\n                {\n                    context.Database.EnsureDeleted();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/test/IdentityServer8.EntityFramework.Tests/FakeLogger.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\npublic class FakeLogger<T> : FakeLogger, ILogger<T>\n{\n    public static ILogger<T> Create()\n    {\n        return new FakeLogger<T>();\n    }\n}\n\npublic class FakeLogger : ILogger, IDisposable\n{\n    public IDisposable BeginScope<TState>(TState state)\n    {\n        return this;\n    }\n\n    public void Dispose()\n    {\n    }\n\n    public bool IsEnabled(LogLevel logLevel)\n    {\n        return false;\n    }\n\n    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)\n    {\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/test/IdentityServer8.EntityFramework.Tests/IdentityServer8.EntityFramework.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" />\n    <PackageReference Include=\"FluentAssertions\" />\n    <PackageReference Include=\"coverlet.collector\" GeneratePathProperty=\"true\">\n        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n        <PrivateAssets>all</PrivateAssets>\n    </PackageReference>\n      <PackageReference Include=\"Microsoft.EntityFrameworkCore.Sqlite\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.InMemory\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.EntityFramework.csproj\" />\n  </ItemGroup>\n  \n  \n\n</Project>\n"
  },
  {
    "path": "src/EntityFramework/test/IdentityServer8.EntityFramework.Tests/IntegrationTest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.Configuration;\nusing System.Runtime.InteropServices;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\n/// <summary>\n/// Base class for integration tests, responsible for initializing test database providers & an xUnit class fixture\n/// </summary>\n/// <typeparam name=\"TClass\">The type of the class.</typeparam>\n/// <typeparam name=\"TDbContext\">The type of the database context.</typeparam>\n/// <typeparam name=\"TStoreOption\">The type of the store option.</typeparam>\n/// <seealso cref=\"DatabaseProviderFixture{T}\" />\npublic class IntegrationTest<TClass, TDbContext, TStoreOption> : IClassFixture<DatabaseProviderFixture<TDbContext>>\n    where TDbContext : DbContext\n{\n    public static readonly TheoryData<DbContextOptions<TDbContext>> TestDatabaseProviders;\n    protected readonly TStoreOption StoreOptions = Activator.CreateInstance<TStoreOption>();\n\n    static IntegrationTest()\n    {\n        var config = new ConfigurationBuilder()\n            .AddEnvironmentVariables()\n            .Build();\n\n        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n        {\n            Console.WriteLine($\"Running Local Tests for {typeof(TClass).Name}\");\n\n            TestDatabaseProviders = new TheoryData<DbContextOptions<TDbContext>>\n            {\n                DatabaseProviderBuilder.BuildInMemory<TDbContext>(typeof(TClass).Name),\n                DatabaseProviderBuilder.BuildSqlite<TDbContext>(typeof(TClass).Name),\n                DatabaseProviderBuilder.BuildLocalDb<TDbContext>(typeof(TClass).Name)\n            };\n        }\n        else\n        {\n            TestDatabaseProviders = new TheoryData<DbContextOptions<TDbContext>>\n            {\n                DatabaseProviderBuilder.BuildInMemory<TDbContext>(typeof(TClass).Name),\n                DatabaseProviderBuilder.BuildSqlite<TDbContext>(typeof(TClass).Name)\n            };\n            Console.WriteLine(\"Skipping DB integration tests on non-Windows\");\n        }\n    }\n\n    protected IntegrationTest(DatabaseProviderFixture<TDbContext> fixture)\n    {\n        fixture.Options = TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<TDbContext>)y)).ToList();\n        fixture.StoreOptions = StoreOptions;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/test/IdentityServer8.EntityFramework.Tests/Services/CorsPolicyServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Interfaces;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServer8.EntityFramework.Options;\nusing IdentityServer8.EntityFramework.Services;\nusing IdentityServer8.Models;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests.Services;\n\npublic class CorsPolicyServiceTests : IntegrationTest<CorsPolicyServiceTests, ConfigurationDbContext, ConfigurationStoreOptions>\n{\n    public CorsPolicyServiceTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)\n    {\n        foreach (var options in TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<ConfigurationDbContext>)y)).ToList())\n        {\n            using (var context = new ConfigurationDbContext(options, StoreOptions))\n                context.Database.EnsureCreated();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task IsOriginAllowedAsync_WhenOriginIsAllowed_ExpectTrue(DbContextOptions<ConfigurationDbContext> options)\n    {\n        const string testCorsOrigin = \"https://identityserver8.io/\";\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.Clients.Add(new Client\n            {\n                ClientId = Guid.NewGuid().ToString(),\n                ClientName = Guid.NewGuid().ToString(),\n                AllowedCorsOrigins = new List<string> { \"https://www.identityserver8.com\" }\n            }.ToEntity());\n            context.Clients.Add(new Client\n            {\n                ClientId = \"2\",\n                ClientName = \"2\",\n                AllowedCorsOrigins = new List<string> { \"https://www.identityserver8.com\", testCorsOrigin }\n            }.ToEntity());\n            context.SaveChanges();\n        }\n\n        bool result;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var ctx = new DefaultHttpContext();\n            var svcs = new ServiceCollection();\n            svcs.AddSingleton<IConfigurationDbContext>(context);\n            ctx.RequestServices = svcs.BuildServiceProvider();\n            var ctxAccessor = new HttpContextAccessor();\n            ctxAccessor.HttpContext = ctx;\n\n            var service = new CorsPolicyService(ctxAccessor, FakeLogger<CorsPolicyService>.Create());\n            result = await service.IsOriginAllowedAsync(testCorsOrigin);\n        }\n\n        Assert.True(result);\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task IsOriginAllowedAsync_WhenOriginIsNotAllowed_ExpectFalse(DbContextOptions<ConfigurationDbContext> options)\n    {\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.Clients.Add(new Client\n            {\n                ClientId = Guid.NewGuid().ToString(),\n                ClientName = Guid.NewGuid().ToString(),\n                AllowedCorsOrigins = new List<string> { \"https://www.identityserver8.com\" }\n            }.ToEntity());\n            context.SaveChanges();\n        }\n\n        bool result;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var ctx = new DefaultHttpContext();\n            var svcs = new ServiceCollection();\n            svcs.AddSingleton<IConfigurationDbContext>(context);\n            ctx.RequestServices = svcs.BuildServiceProvider();\n            var ctxAccessor = new HttpContextAccessor();\n            ctxAccessor.HttpContext = ctx;\n\n            var service = new CorsPolicyService(ctxAccessor, FakeLogger<CorsPolicyService>.Create());\n            result = await service.IsOriginAllowedAsync(\"InvalidOrigin\");\n        }\n\n        Assert.False(result);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework/updatedb.bat",
    "content": "cd host\ndotnet ef database update -c PersistedGrantDbContext\ndotnet ef database update -c ConfigurationDbContext\ndotnet run /seed\ncd ..\n"
  },
  {
    "path": "src/EntityFramework.Storage/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/EntityFramework.Storage/IdentityServer8.EntityFramework.Storage.sln",
    "content": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.30204.135\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{AF5DAC33-08AC-45EE-9772-4FF39FB09E57}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework.Storage\", \"src\\IdentityServer8.EntityFramework.Storage.csproj\", \"{5302DAB3-1662-4956-97AA-5EA5E85B10F6}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"test\", \"test\", \"{712ED94A-F982-4667-A9CE-E8F21900BBED}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework.UnitTests\", \"test\\UnitTests\\IdentityServer8.EntityFramework.UnitTests.csproj\", \"{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework.IntegrationTests\", \"test\\IntegrationTests\\IdentityServer8.EntityFramework.IntegrationTests.csproj\", \"{E90F7470-C7F8-464B-9C28-87C474085812}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"migrations\", \"migrations\", \"{E3EF31E0-6658-4899-8BDA-FF84355E2FDD}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SqlServer\", \"migrations\\SqlServer\\SqlServer.csproj\", \"{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"host\", \"host\", \"{07C56E10-A807-4372-ACD9-ADED2D099BC8}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"ConsoleHost\", \"host\\ConsoleHost\\ConsoleHost.csproj\", \"{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|x64.Build.0 = Release|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|x86.Build.0 = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|x64.Build.0 = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|x86.Build.0 = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|x64.Build.0 = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|x86.Build.0 = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|x64.Build.0 = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|x86.Build.0 = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|x64.Build.0 = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6} = {AF5DAC33-08AC-45EE-9772-4FF39FB09E57}\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC} = {712ED94A-F982-4667-A9CE-E8F21900BBED}\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812} = {712ED94A-F982-4667-A9CE-E8F21900BBED}\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3} = {E3EF31E0-6658-4899-8BDA-FF84355E2FDD}\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5} = {07C56E10-A807-4372-ACD9-ADED2D099BC8}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {4DB894E3-1BF2-4410-911A-14D32FD79A96}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/EntityFramework.Storage/README.md",
    "content": "# IdentityServer8.EntityFramework.Storage\n\nIdentityServer8.EntityFramework.Storage is a persistence layer for IdentityServer 4 configuration data that uses EntityFramework as its database abstraction.\n\n## Issues\n\nFor issues, use the [consolidated IdentityServer8 issue tracker](https://github.com/alexhiggins732/IdentityServer8/issues).\n"
  },
  {
    "path": "src/EntityFramework.Storage/build.cmd",
    "content": "@echo off\ndotnet run --project build -- %*"
  },
  {
    "path": "src/EntityFramework.Storage/build.ps1",
    "content": "$ErrorActionPreference = \"Stop\";\ndotnet run --project build -- $args"
  },
  {
    "path": "src/EntityFramework.Storage/build.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\ndotnet run --project build -- \"$@\""
  },
  {
    "path": "src/EntityFramework.Storage/host/ConsoleHost/ConsoleHost.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <FrameworkReference Include=\"Microsoft.AspNetCore.App\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.EntityFramework.Storage.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/EntityFramework.Storage/host/ConsoleHost/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityServer8.EntityFramework;\nglobal using IdentityServer8.EntityFramework.Storage;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Logging;"
  },
  {
    "path": "src/EntityFramework.Storage/host/ConsoleHost/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace ConsoleHost;\n\nclass Program\n{\n    static void Main(string[] args)\n    {\n        var connectionString = \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.EntityFramework-8.0.0;trusted_connection=yes;\";\n\n        var services = new ServiceCollection();\n        services.AddLogging(b => b.AddConsole().SetMinimumLevel(LogLevel.Trace));\n        services.AddOperationalDbContext(options =>\n        {\n            options.ConfigureDbContext = builder => builder.UseSqlServer(connectionString);\n\n            // this enables automatic token cleanup. this is optional.\n            options.EnableTokenCleanup = false;\n            options.TokenCleanupInterval = 5; // interval in seconds, short for testing\n        });\n\n        var sp = services.BuildServiceProvider();\n        using (var scope = sp.CreateScope())\n        {\n            var svc = scope.ServiceProvider.GetRequiredService<TokenCleanupService>();\n            svc.RemoveExpiredGrantsAsync().GetAwaiter().GetResult();\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/host/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityServer8.EntityFramework.DbContexts;\nglobal using IdentityServer8.EntityFramework.Storage;\nglobal using Microsoft.AspNetCore;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.EntityFrameworkCore.Infrastructure;\nglobal using Microsoft.EntityFrameworkCore.Metadata;\nglobal using Microsoft.EntityFrameworkCore.Migrations;\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/ConfigurationDb/20200522172542_Config.Designer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\nnamespace SqlServer.Migrations.ConfigurationDb\n{\n    [DbContext(typeof(ConfigurationDbContext))]\n    [Migration(\"20200522172542_Config\")]\n    partial class Config\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.0\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"AllowedAccessTokenSigningAlgorithms\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ApiResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(4000)\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ApiResourceId\");\n\n                    b.ToTable(\"ApiResourceSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"ApiScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<int>(\"ScopeId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ScopeId\");\n\n                    b.ToTable(\"ApiScopeProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.Client\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"AbsoluteRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"AccessTokenType\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"AllowAccessTokensViaBrowser\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowOfflineAccess\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowPlainTextPkce\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AllowRememberConsent\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"AllowedIdentityTokenSigningAlgorithms\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<bool>(\"AlwaysIncludeUserClaimsInIdToken\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"AlwaysSendClientClaims\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<int>(\"AuthorizationCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"BackChannelLogoutSessionRequired\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"BackChannelLogoutUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<string>(\"ClientClaimsPrefix\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int?>(\"ConsentLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<int>(\"DeviceCodeLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"EnableLocalLogin\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"FrontChannelLogoutSessionRequired\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"FrontChannelLogoutUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<int>(\"IdentityTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"IncludeJwtId\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"LastAccessed\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"LogoUri\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"PairWiseSubjectSalt\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ProtocolType\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<int>(\"RefreshTokenExpiration\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<int>(\"RefreshTokenUsage\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"RequireClientSecret\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequireConsent\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequirePkce\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"RequireRequestObject\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<int>(\"SlidingRefreshTokenLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<bool>(\"UpdateAccessTokenClaimsOnRefresh\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"UserCodeType\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<int?>(\"UserSsoLifetime\")\n                        .HasColumnType(\"int\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\")\n                        .IsUnique();\n\n                    b.ToTable(\"Clients\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Origin\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(150)\")\n                        .HasMaxLength(150);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientCorsOrigins\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"GrantType\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientGrantTypes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Provider\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientIdPRestrictions\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"PostLogoutRedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientPostLogoutRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"RedirectUri\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientRedirectUris\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Scope\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientScopes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"ClientId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(4000)\")\n                        .HasMaxLength(4000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ClientId\");\n\n                    b.ToTable(\"ClientSecrets\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(1000)\")\n                        .HasMaxLength(1000);\n\n                    b.Property<string>(\"DisplayName\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"Emphasize\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<bool>(\"NonEditable\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"Required\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<bool>(\"ShowInDiscoveryDocument\")\n                        .HasColumnType(\"bit\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"Name\")\n                        .IsUnique();\n\n                    b.ToTable(\"IdentityResources\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceClaims\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.Property<int>(\"Id\")\n                        .ValueGeneratedOnAdd()\n                        .HasColumnType(\"int\")\n                        .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                    b.Property<int>(\"IdentityResourceId\")\n                        .HasColumnType(\"int\");\n\n                    b.Property<string>(\"Key\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(250)\")\n                        .HasMaxLength(250);\n\n                    b.Property<string>(\"Value\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(2000)\")\n                        .HasMaxLength(2000);\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"IdentityResourceId\");\n\n                    b.ToTable(\"IdentityResourceProperties\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Scopes\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                        .WithMany(\"Secrets\")\n                        .HasForeignKey(\"ApiResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ScopeId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Claims\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedCorsOrigins\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedGrantTypes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"IdentityProviderRestrictions\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"PostLogoutRedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"RedirectUris\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"AllowedScopes\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                        .WithMany(\"ClientSecrets\")\n                        .HasForeignKey(\"ClientId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"UserClaims\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n                {\n                    b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                        .WithMany(\"Properties\")\n                        .HasForeignKey(\"IdentityResourceId\")\n                        .OnDelete(DeleteBehavior.Cascade)\n                        .IsRequired();\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/ConfigurationDb/20200522172542_Config.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace SqlServer.Migrations.ConfigurationDb;\n\npublic partial class Config : Migration\n{\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.CreateTable(\n            name: \"ApiResources\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Enabled = table.Column<bool>(nullable: false),\n                Name = table.Column<string>(maxLength: 200, nullable: false),\n                DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                Description = table.Column<string>(maxLength: 1000, nullable: true),\n                AllowedAccessTokenSigningAlgorithms = table.Column<string>(maxLength: 100, nullable: true),\n                ShowInDiscoveryDocument = table.Column<bool>(nullable: false),\n                Created = table.Column<DateTime>(nullable: false),\n                Updated = table.Column<DateTime>(nullable: true),\n                LastAccessed = table.Column<DateTime>(nullable: true),\n                NonEditable = table.Column<bool>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiResources\", x => x.Id);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ApiScopes\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Enabled = table.Column<bool>(nullable: false),\n                Name = table.Column<string>(maxLength: 200, nullable: false),\n                DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                Description = table.Column<string>(maxLength: 1000, nullable: true),\n                Required = table.Column<bool>(nullable: false),\n                Emphasize = table.Column<bool>(nullable: false),\n                ShowInDiscoveryDocument = table.Column<bool>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiScopes\", x => x.Id);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"Clients\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Enabled = table.Column<bool>(nullable: false),\n                ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                ProtocolType = table.Column<string>(maxLength: 200, nullable: false),\n                RequireClientSecret = table.Column<bool>(nullable: false),\n                ClientName = table.Column<string>(maxLength: 200, nullable: true),\n                Description = table.Column<string>(maxLength: 1000, nullable: true),\n                ClientUri = table.Column<string>(maxLength: 2000, nullable: true),\n                LogoUri = table.Column<string>(maxLength: 2000, nullable: true),\n                RequireConsent = table.Column<bool>(nullable: false),\n                AllowRememberConsent = table.Column<bool>(nullable: false),\n                AlwaysIncludeUserClaimsInIdToken = table.Column<bool>(nullable: false),\n                RequirePkce = table.Column<bool>(nullable: false),\n                AllowPlainTextPkce = table.Column<bool>(nullable: false),\n                RequireRequestObject = table.Column<bool>(nullable: false),\n                AllowAccessTokensViaBrowser = table.Column<bool>(nullable: false),\n                FrontChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),\n                FrontChannelLogoutSessionRequired = table.Column<bool>(nullable: false),\n                BackChannelLogoutUri = table.Column<string>(maxLength: 2000, nullable: true),\n                BackChannelLogoutSessionRequired = table.Column<bool>(nullable: false),\n                AllowOfflineAccess = table.Column<bool>(nullable: false),\n                IdentityTokenLifetime = table.Column<int>(nullable: false),\n                AllowedIdentityTokenSigningAlgorithms = table.Column<string>(maxLength: 100, nullable: true),\n                AccessTokenLifetime = table.Column<int>(nullable: false),\n                AuthorizationCodeLifetime = table.Column<int>(nullable: false),\n                ConsentLifetime = table.Column<int>(nullable: true),\n                AbsoluteRefreshTokenLifetime = table.Column<int>(nullable: false),\n                SlidingRefreshTokenLifetime = table.Column<int>(nullable: false),\n                RefreshTokenUsage = table.Column<int>(nullable: false),\n                UpdateAccessTokenClaimsOnRefresh = table.Column<bool>(nullable: false),\n                RefreshTokenExpiration = table.Column<int>(nullable: false),\n                AccessTokenType = table.Column<int>(nullable: false),\n                EnableLocalLogin = table.Column<bool>(nullable: false),\n                IncludeJwtId = table.Column<bool>(nullable: false),\n                AlwaysSendClientClaims = table.Column<bool>(nullable: false),\n                ClientClaimsPrefix = table.Column<string>(maxLength: 200, nullable: true),\n                PairWiseSubjectSalt = table.Column<string>(maxLength: 200, nullable: true),\n                Created = table.Column<DateTime>(nullable: false),\n                Updated = table.Column<DateTime>(nullable: true),\n                LastAccessed = table.Column<DateTime>(nullable: true),\n                UserSsoLifetime = table.Column<int>(nullable: true),\n                UserCodeType = table.Column<string>(maxLength: 100, nullable: true),\n                DeviceCodeLifetime = table.Column<int>(nullable: false),\n                NonEditable = table.Column<bool>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_Clients\", x => x.Id);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"IdentityResources\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Enabled = table.Column<bool>(nullable: false),\n                Name = table.Column<string>(maxLength: 200, nullable: false),\n                DisplayName = table.Column<string>(maxLength: 200, nullable: true),\n                Description = table.Column<string>(maxLength: 1000, nullable: true),\n                Required = table.Column<bool>(nullable: false),\n                Emphasize = table.Column<bool>(nullable: false),\n                ShowInDiscoveryDocument = table.Column<bool>(nullable: false),\n                Created = table.Column<DateTime>(nullable: false),\n                Updated = table.Column<DateTime>(nullable: true),\n                NonEditable = table.Column<bool>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_IdentityResources\", x => x.Id);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ApiResourceClaims\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Type = table.Column<string>(maxLength: 200, nullable: false),\n                ApiResourceId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiResourceClaims\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ApiResourceClaims_ApiResources_ApiResourceId\",\n                    column: x => x.ApiResourceId,\n                    principalTable: \"ApiResources\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ApiResourceProperties\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Key = table.Column<string>(maxLength: 250, nullable: false),\n                Value = table.Column<string>(maxLength: 2000, nullable: false),\n                ApiResourceId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiResourceProperties\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ApiResourceProperties_ApiResources_ApiResourceId\",\n                    column: x => x.ApiResourceId,\n                    principalTable: \"ApiResources\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ApiResourceScopes\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Scope = table.Column<string>(maxLength: 200, nullable: false),\n                ApiResourceId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiResourceScopes\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ApiResourceScopes_ApiResources_ApiResourceId\",\n                    column: x => x.ApiResourceId,\n                    principalTable: \"ApiResources\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ApiResourceSecrets\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Description = table.Column<string>(maxLength: 1000, nullable: true),\n                Value = table.Column<string>(maxLength: 4000, nullable: false),\n                Expiration = table.Column<DateTime>(nullable: true),\n                Type = table.Column<string>(maxLength: 250, nullable: false),\n                Created = table.Column<DateTime>(nullable: false),\n                ApiResourceId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiResourceSecrets\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ApiResourceSecrets_ApiResources_ApiResourceId\",\n                    column: x => x.ApiResourceId,\n                    principalTable: \"ApiResources\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ApiScopeClaims\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Type = table.Column<string>(maxLength: 200, nullable: false),\n                ScopeId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiScopeClaims\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ApiScopeClaims_ApiScopes_ScopeId\",\n                    column: x => x.ScopeId,\n                    principalTable: \"ApiScopes\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ApiScopeProperties\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Key = table.Column<string>(maxLength: 250, nullable: false),\n                Value = table.Column<string>(maxLength: 2000, nullable: false),\n                ScopeId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ApiScopeProperties\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ApiScopeProperties_ApiScopes_ScopeId\",\n                    column: x => x.ScopeId,\n                    principalTable: \"ApiScopes\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientClaims\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Type = table.Column<string>(maxLength: 250, nullable: false),\n                Value = table.Column<string>(maxLength: 250, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientClaims\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientClaims_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientCorsOrigins\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Origin = table.Column<string>(maxLength: 150, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientCorsOrigins\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientCorsOrigins_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientGrantTypes\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                GrantType = table.Column<string>(maxLength: 250, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientGrantTypes\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientGrantTypes_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientIdPRestrictions\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Provider = table.Column<string>(maxLength: 200, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientIdPRestrictions\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientIdPRestrictions_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientPostLogoutRedirectUris\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                PostLogoutRedirectUri = table.Column<string>(maxLength: 2000, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientPostLogoutRedirectUris\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientPostLogoutRedirectUris_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientProperties\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Key = table.Column<string>(maxLength: 250, nullable: false),\n                Value = table.Column<string>(maxLength: 2000, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientProperties\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientProperties_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientRedirectUris\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                RedirectUri = table.Column<string>(maxLength: 2000, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientRedirectUris\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientRedirectUris_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientScopes\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Scope = table.Column<string>(maxLength: 200, nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientScopes\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientScopes_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"ClientSecrets\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Description = table.Column<string>(maxLength: 2000, nullable: true),\n                Value = table.Column<string>(maxLength: 4000, nullable: false),\n                Expiration = table.Column<DateTime>(nullable: true),\n                Type = table.Column<string>(maxLength: 250, nullable: false),\n                Created = table.Column<DateTime>(nullable: false),\n                ClientId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_ClientSecrets\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_ClientSecrets_Clients_ClientId\",\n                    column: x => x.ClientId,\n                    principalTable: \"Clients\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"IdentityResourceClaims\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Type = table.Column<string>(maxLength: 200, nullable: false),\n                IdentityResourceId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_IdentityResourceClaims\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_IdentityResourceClaims_IdentityResources_IdentityResourceId\",\n                    column: x => x.IdentityResourceId,\n                    principalTable: \"IdentityResources\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"IdentityResourceProperties\",\n            columns: table => new\n            {\n                Id = table.Column<int>(nullable: false)\n                    .Annotation(\"SqlServer:Identity\", \"1, 1\"),\n                Key = table.Column<string>(maxLength: 250, nullable: false),\n                Value = table.Column<string>(maxLength: 2000, nullable: false),\n                IdentityResourceId = table.Column<int>(nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_IdentityResourceProperties\", x => x.Id);\n                table.ForeignKey(\n                    name: \"FK_IdentityResourceProperties_IdentityResources_IdentityResourceId\",\n                    column: x => x.IdentityResourceId,\n                    principalTable: \"IdentityResources\",\n                    principalColumn: \"Id\",\n                    onDelete: ReferentialAction.Cascade);\n            });\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiResourceClaims_ApiResourceId\",\n            table: \"ApiResourceClaims\",\n            column: \"ApiResourceId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiResourceProperties_ApiResourceId\",\n            table: \"ApiResourceProperties\",\n            column: \"ApiResourceId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiResources_Name\",\n            table: \"ApiResources\",\n            column: \"Name\",\n            unique: true);\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiResourceScopes_ApiResourceId\",\n            table: \"ApiResourceScopes\",\n            column: \"ApiResourceId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiResourceSecrets_ApiResourceId\",\n            table: \"ApiResourceSecrets\",\n            column: \"ApiResourceId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiScopeClaims_ScopeId\",\n            table: \"ApiScopeClaims\",\n            column: \"ScopeId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiScopeProperties_ScopeId\",\n            table: \"ApiScopeProperties\",\n            column: \"ScopeId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ApiScopes_Name\",\n            table: \"ApiScopes\",\n            column: \"Name\",\n            unique: true);\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientClaims_ClientId\",\n            table: \"ClientClaims\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientCorsOrigins_ClientId\",\n            table: \"ClientCorsOrigins\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientGrantTypes_ClientId\",\n            table: \"ClientGrantTypes\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientIdPRestrictions_ClientId\",\n            table: \"ClientIdPRestrictions\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientPostLogoutRedirectUris_ClientId\",\n            table: \"ClientPostLogoutRedirectUris\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientProperties_ClientId\",\n            table: \"ClientProperties\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientRedirectUris_ClientId\",\n            table: \"ClientRedirectUris\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_Clients_ClientId\",\n            table: \"Clients\",\n            column: \"ClientId\",\n            unique: true);\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientScopes_ClientId\",\n            table: \"ClientScopes\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_ClientSecrets_ClientId\",\n            table: \"ClientSecrets\",\n            column: \"ClientId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_IdentityResourceClaims_IdentityResourceId\",\n            table: \"IdentityResourceClaims\",\n            column: \"IdentityResourceId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_IdentityResourceProperties_IdentityResourceId\",\n            table: \"IdentityResourceProperties\",\n            column: \"IdentityResourceId\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_IdentityResources_Name\",\n            table: \"IdentityResources\",\n            column: \"Name\",\n            unique: true);\n    }\n\n    protected override void Down(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.DropTable(\n            name: \"ApiResourceClaims\");\n\n        migrationBuilder.DropTable(\n            name: \"ApiResourceProperties\");\n\n        migrationBuilder.DropTable(\n            name: \"ApiResourceScopes\");\n\n        migrationBuilder.DropTable(\n            name: \"ApiResourceSecrets\");\n\n        migrationBuilder.DropTable(\n            name: \"ApiScopeClaims\");\n\n        migrationBuilder.DropTable(\n            name: \"ApiScopeProperties\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientClaims\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientCorsOrigins\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientGrantTypes\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientIdPRestrictions\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientPostLogoutRedirectUris\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientProperties\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientRedirectUris\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientScopes\");\n\n        migrationBuilder.DropTable(\n            name: \"ClientSecrets\");\n\n        migrationBuilder.DropTable(\n            name: \"IdentityResourceClaims\");\n\n        migrationBuilder.DropTable(\n            name: \"IdentityResourceProperties\");\n\n        migrationBuilder.DropTable(\n            name: \"ApiResources\");\n\n        migrationBuilder.DropTable(\n            name: \"ApiScopes\");\n\n        migrationBuilder.DropTable(\n            name: \"Clients\");\n\n        migrationBuilder.DropTable(\n            name: \"IdentityResources\");\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/ConfigurationDb/ConfigurationDbContextModelSnapshot.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\nnamespace SqlServer.Migrations.ConfigurationDb;\n\n[DbContext(typeof(ConfigurationDbContext))]\npartial class ConfigurationDbContextModelSnapshot : ModelSnapshot\n{\n    protected override void BuildModel(ModelBuilder modelBuilder)\n    {\n#pragma warning disable 612, 618\n        modelBuilder\n            .HasAnnotation(\"ProductVersion\", \"3.1.0\")\n            .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n            .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResource\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<string>(\"AllowedAccessTokenSigningAlgorithms\")\n                    .HasColumnType(\"nvarchar(100)\")\n                    .HasMaxLength(100);\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(1000)\")\n                    .HasMaxLength(1000);\n\n                b.Property<string>(\"DisplayName\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<bool>(\"Enabled\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<DateTime?>(\"LastAccessed\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Name\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<bool>(\"NonEditable\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"ShowInDiscoveryDocument\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<DateTime?>(\"Updated\")\n                    .HasColumnType(\"datetime2\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"Name\")\n                    .IsUnique();\n\n                b.ToTable(\"ApiResources\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ApiResourceId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Type\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ApiResourceId\");\n\n                b.ToTable(\"ApiResourceClaims\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ApiResourceId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Key\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ApiResourceId\");\n\n                b.ToTable(\"ApiResourceProperties\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ApiResourceId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Scope\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ApiResourceId\");\n\n                b.ToTable(\"ApiResourceScopes\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ApiResourceId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(1000)\")\n                    .HasMaxLength(1000);\n\n                b.Property<DateTime?>(\"Expiration\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Type\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(4000)\")\n                    .HasMaxLength(4000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ApiResourceId\");\n\n                b.ToTable(\"ApiResourceSecrets\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScope\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(1000)\")\n                    .HasMaxLength(1000);\n\n                b.Property<string>(\"DisplayName\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<bool>(\"Emphasize\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"Enabled\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"Name\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<bool>(\"Required\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"ShowInDiscoveryDocument\")\n                    .HasColumnType(\"bit\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"Name\")\n                    .IsUnique();\n\n                b.ToTable(\"ApiScopes\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ScopeId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Type\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ScopeId\");\n\n                b.ToTable(\"ApiScopeClaims\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<string>(\"Key\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.Property<int>(\"ScopeId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ScopeId\");\n\n                b.ToTable(\"ApiScopeProperties\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.Client\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"AbsoluteRefreshTokenLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.Property<int>(\"AccessTokenLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.Property<int>(\"AccessTokenType\")\n                    .HasColumnType(\"int\");\n\n                b.Property<bool>(\"AllowAccessTokensViaBrowser\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"AllowOfflineAccess\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"AllowPlainTextPkce\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"AllowRememberConsent\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"AllowedIdentityTokenSigningAlgorithms\")\n                    .HasColumnType(\"nvarchar(100)\")\n                    .HasMaxLength(100);\n\n                b.Property<bool>(\"AlwaysIncludeUserClaimsInIdToken\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"AlwaysSendClientClaims\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<int>(\"AuthorizationCodeLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.Property<bool>(\"BackChannelLogoutSessionRequired\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"BackChannelLogoutUri\")\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.Property<string>(\"ClientClaimsPrefix\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"ClientId\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"ClientName\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"ClientUri\")\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.Property<int?>(\"ConsentLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(1000)\")\n                    .HasMaxLength(1000);\n\n                b.Property<int>(\"DeviceCodeLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.Property<bool>(\"EnableLocalLogin\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"Enabled\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"FrontChannelLogoutSessionRequired\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"FrontChannelLogoutUri\")\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.Property<int>(\"IdentityTokenLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.Property<bool>(\"IncludeJwtId\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<DateTime?>(\"LastAccessed\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"LogoUri\")\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.Property<bool>(\"NonEditable\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"PairWiseSubjectSalt\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"ProtocolType\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<int>(\"RefreshTokenExpiration\")\n                    .HasColumnType(\"int\");\n\n                b.Property<int>(\"RefreshTokenUsage\")\n                    .HasColumnType(\"int\");\n\n                b.Property<bool>(\"RequireClientSecret\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"RequireConsent\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"RequirePkce\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"RequireRequestObject\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<int>(\"SlidingRefreshTokenLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.Property<bool>(\"UpdateAccessTokenClaimsOnRefresh\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<DateTime?>(\"Updated\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"UserCodeType\")\n                    .HasColumnType(\"nvarchar(100)\")\n                    .HasMaxLength(100);\n\n                b.Property<int?>(\"UserSsoLifetime\")\n                    .HasColumnType(\"int\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\")\n                    .IsUnique();\n\n                b.ToTable(\"Clients\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Type\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientClaims\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Origin\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(150)\")\n                    .HasMaxLength(150);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientCorsOrigins\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"GrantType\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientGrantTypes\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Provider\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientIdPRestrictions\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"PostLogoutRedirectUri\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientPostLogoutRedirectUris\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Key\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientProperties\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"RedirectUri\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientRedirectUris\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Scope\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientScopes\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"ClientId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.Property<DateTime?>(\"Expiration\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Type\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(4000)\")\n                    .HasMaxLength(4000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"ClientId\");\n\n                b.ToTable(\"ClientSecrets\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<DateTime>(\"Created\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(1000)\")\n                    .HasMaxLength(1000);\n\n                b.Property<string>(\"DisplayName\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<bool>(\"Emphasize\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"Enabled\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<string>(\"Name\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<bool>(\"NonEditable\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"Required\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<bool>(\"ShowInDiscoveryDocument\")\n                    .HasColumnType(\"bit\");\n\n                b.Property<DateTime?>(\"Updated\")\n                    .HasColumnType(\"datetime2\");\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"Name\")\n                    .IsUnique();\n\n                b.ToTable(\"IdentityResources\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"IdentityResourceId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Type\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"IdentityResourceId\");\n\n                b.ToTable(\"IdentityResourceClaims\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n            {\n                b.Property<int>(\"Id\")\n                    .ValueGeneratedOnAdd()\n                    .HasColumnType(\"int\")\n                    .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n                b.Property<int>(\"IdentityResourceId\")\n                    .HasColumnType(\"int\");\n\n                b.Property<string>(\"Key\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(250)\")\n                    .HasMaxLength(250);\n\n                b.Property<string>(\"Value\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(2000)\")\n                    .HasMaxLength(2000);\n\n                b.HasKey(\"Id\");\n\n                b.HasIndex(\"IdentityResourceId\");\n\n                b.ToTable(\"IdentityResourceProperties\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceClaim\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                    .WithMany(\"UserClaims\")\n                    .HasForeignKey(\"ApiResourceId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceProperty\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                    .WithMany(\"Properties\")\n                    .HasForeignKey(\"ApiResourceId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceScope\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                    .WithMany(\"Scopes\")\n                    .HasForeignKey(\"ApiResourceId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiResourceSecret\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiResource\", \"ApiResource\")\n                    .WithMany(\"Secrets\")\n                    .HasForeignKey(\"ApiResourceId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeClaim\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                    .WithMany(\"UserClaims\")\n                    .HasForeignKey(\"ScopeId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ApiScopeProperty\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.ApiScope\", \"Scope\")\n                    .WithMany(\"Properties\")\n                    .HasForeignKey(\"ScopeId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientClaim\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"Claims\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientCorsOrigin\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"AllowedCorsOrigins\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientGrantType\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"AllowedGrantTypes\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientIdPRestriction\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"IdentityProviderRestrictions\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientPostLogoutRedirectUri\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"PostLogoutRedirectUris\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientProperty\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"Properties\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientRedirectUri\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"RedirectUris\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientScope\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"AllowedScopes\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.ClientSecret\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.Client\", \"Client\")\n                    .WithMany(\"ClientSecrets\")\n                    .HasForeignKey(\"ClientId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceClaim\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                    .WithMany(\"UserClaims\")\n                    .HasForeignKey(\"IdentityResourceId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.IdentityResourceProperty\", b =>\n            {\n                b.HasOne(\"IdentityServer8.EntityFramework.Entities.IdentityResource\", \"IdentityResource\")\n                    .WithMany(\"Properties\")\n                    .HasForeignKey(\"IdentityResourceId\")\n                    .OnDelete(DeleteBehavior.Cascade)\n                    .IsRequired();\n            });\n#pragma warning restore 612, 618\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/ConfigurationDb.sql",
    "content": "﻿IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL\nBEGIN\n    CREATE TABLE [__EFMigrationsHistory] (\n        [MigrationId] nvarchar(150) NOT NULL,\n        [ProductVersion] nvarchar(32) NOT NULL,\n        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])\n    );\nEND;\n\nGO\n\nCREATE TABLE [ApiResources] (\n    [Id] int NOT NULL IDENTITY,\n    [Enabled] bit NOT NULL,\n    [Name] nvarchar(200) NOT NULL,\n    [DisplayName] nvarchar(200) NULL,\n    [Description] nvarchar(1000) NULL,\n    [AllowedAccessTokenSigningAlgorithms] nvarchar(100) NULL,\n    [ShowInDiscoveryDocument] bit NOT NULL,\n    [Created] datetime2 NOT NULL,\n    [Updated] datetime2 NULL,\n    [LastAccessed] datetime2 NULL,\n    [NonEditable] bit NOT NULL,\n    CONSTRAINT [PK_ApiResources] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE TABLE [ApiScopes] (\n    [Id] int NOT NULL IDENTITY,\n    [Enabled] bit NOT NULL,\n    [Name] nvarchar(200) NOT NULL,\n    [DisplayName] nvarchar(200) NULL,\n    [Description] nvarchar(1000) NULL,\n    [Required] bit NOT NULL,\n    [Emphasize] bit NOT NULL,\n    [ShowInDiscoveryDocument] bit NOT NULL,\n    CONSTRAINT [PK_ApiScopes] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE TABLE [Clients] (\n    [Id] int NOT NULL IDENTITY,\n    [Enabled] bit NOT NULL,\n    [ClientId] nvarchar(200) NOT NULL,\n    [ProtocolType] nvarchar(200) NOT NULL,\n    [RequireClientSecret] bit NOT NULL,\n    [ClientName] nvarchar(200) NULL,\n    [Description] nvarchar(1000) NULL,\n    [ClientUri] nvarchar(2000) NULL,\n    [LogoUri] nvarchar(2000) NULL,\n    [RequireConsent] bit NOT NULL,\n    [AllowRememberConsent] bit NOT NULL,\n    [AlwaysIncludeUserClaimsInIdToken] bit NOT NULL,\n    [RequirePkce] bit NOT NULL,\n    [AllowPlainTextPkce] bit NOT NULL,\n    [RequireRequestObject] bit NOT NULL,\n    [AllowAccessTokensViaBrowser] bit NOT NULL,\n    [FrontChannelLogoutUri] nvarchar(2000) NULL,\n    [FrontChannelLogoutSessionRequired] bit NOT NULL,\n    [BackChannelLogoutUri] nvarchar(2000) NULL,\n    [BackChannelLogoutSessionRequired] bit NOT NULL,\n    [AllowOfflineAccess] bit NOT NULL,\n    [IdentityTokenLifetime] int NOT NULL,\n    [AllowedIdentityTokenSigningAlgorithms] nvarchar(100) NULL,\n    [AccessTokenLifetime] int NOT NULL,\n    [AuthorizationCodeLifetime] int NOT NULL,\n    [ConsentLifetime] int NULL,\n    [AbsoluteRefreshTokenLifetime] int NOT NULL,\n    [SlidingRefreshTokenLifetime] int NOT NULL,\n    [RefreshTokenUsage] int NOT NULL,\n    [UpdateAccessTokenClaimsOnRefresh] bit NOT NULL,\n    [RefreshTokenExpiration] int NOT NULL,\n    [AccessTokenType] int NOT NULL,\n    [EnableLocalLogin] bit NOT NULL,\n    [IncludeJwtId] bit NOT NULL,\n    [AlwaysSendClientClaims] bit NOT NULL,\n    [ClientClaimsPrefix] nvarchar(200) NULL,\n    [PairWiseSubjectSalt] nvarchar(200) NULL,\n    [Created] datetime2 NOT NULL,\n    [Updated] datetime2 NULL,\n    [LastAccessed] datetime2 NULL,\n    [UserSsoLifetime] int NULL,\n    [UserCodeType] nvarchar(100) NULL,\n    [DeviceCodeLifetime] int NOT NULL,\n    [NonEditable] bit NOT NULL,\n    CONSTRAINT [PK_Clients] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE TABLE [IdentityResources] (\n    [Id] int NOT NULL IDENTITY,\n    [Enabled] bit NOT NULL,\n    [Name] nvarchar(200) NOT NULL,\n    [DisplayName] nvarchar(200) NULL,\n    [Description] nvarchar(1000) NULL,\n    [Required] bit NOT NULL,\n    [Emphasize] bit NOT NULL,\n    [ShowInDiscoveryDocument] bit NOT NULL,\n    [Created] datetime2 NOT NULL,\n    [Updated] datetime2 NULL,\n    [NonEditable] bit NOT NULL,\n    CONSTRAINT [PK_IdentityResources] PRIMARY KEY ([Id])\n);\n\nGO\n\nCREATE TABLE [ApiResourceClaims] (\n    [Id] int NOT NULL IDENTITY,\n    [Type] nvarchar(200) NOT NULL,\n    [ApiResourceId] int NOT NULL,\n    CONSTRAINT [PK_ApiResourceClaims] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ApiResourceClaims_ApiResources_ApiResourceId] FOREIGN KEY ([ApiResourceId]) REFERENCES [ApiResources] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ApiResourceProperties] (\n    [Id] int NOT NULL IDENTITY,\n    [Key] nvarchar(250) NOT NULL,\n    [Value] nvarchar(2000) NOT NULL,\n    [ApiResourceId] int NOT NULL,\n    CONSTRAINT [PK_ApiResourceProperties] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ApiResourceProperties_ApiResources_ApiResourceId] FOREIGN KEY ([ApiResourceId]) REFERENCES [ApiResources] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ApiResourceScopes] (\n    [Id] int NOT NULL IDENTITY,\n    [Scope] nvarchar(200) NOT NULL,\n    [ApiResourceId] int NOT NULL,\n    CONSTRAINT [PK_ApiResourceScopes] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ApiResourceScopes_ApiResources_ApiResourceId] FOREIGN KEY ([ApiResourceId]) REFERENCES [ApiResources] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ApiResourceSecrets] (\n    [Id] int NOT NULL IDENTITY,\n    [Description] nvarchar(1000) NULL,\n    [Value] nvarchar(4000) NOT NULL,\n    [Expiration] datetime2 NULL,\n    [Type] nvarchar(250) NOT NULL,\n    [Created] datetime2 NOT NULL,\n    [ApiResourceId] int NOT NULL,\n    CONSTRAINT [PK_ApiResourceSecrets] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ApiResourceSecrets_ApiResources_ApiResourceId] FOREIGN KEY ([ApiResourceId]) REFERENCES [ApiResources] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ApiScopeClaims] (\n    [Id] int NOT NULL IDENTITY,\n    [Type] nvarchar(200) NOT NULL,\n    [ScopeId] int NOT NULL,\n    CONSTRAINT [PK_ApiScopeClaims] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ApiScopeClaims_ApiScopes_ScopeId] FOREIGN KEY ([ScopeId]) REFERENCES [ApiScopes] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ApiScopeProperties] (\n    [Id] int NOT NULL IDENTITY,\n    [Key] nvarchar(250) NOT NULL,\n    [Value] nvarchar(2000) NOT NULL,\n    [ScopeId] int NOT NULL,\n    CONSTRAINT [PK_ApiScopeProperties] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ApiScopeProperties_ApiScopes_ScopeId] FOREIGN KEY ([ScopeId]) REFERENCES [ApiScopes] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientClaims] (\n    [Id] int NOT NULL IDENTITY,\n    [Type] nvarchar(250) NOT NULL,\n    [Value] nvarchar(250) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientClaims] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientClaims_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientCorsOrigins] (\n    [Id] int NOT NULL IDENTITY,\n    [Origin] nvarchar(150) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientCorsOrigins] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientCorsOrigins_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientGrantTypes] (\n    [Id] int NOT NULL IDENTITY,\n    [GrantType] nvarchar(250) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientGrantTypes] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientGrantTypes_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientIdPRestrictions] (\n    [Id] int NOT NULL IDENTITY,\n    [Provider] nvarchar(200) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientIdPRestrictions] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientIdPRestrictions_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientPostLogoutRedirectUris] (\n    [Id] int NOT NULL IDENTITY,\n    [PostLogoutRedirectUri] nvarchar(2000) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientPostLogoutRedirectUris] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientPostLogoutRedirectUris_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientProperties] (\n    [Id] int NOT NULL IDENTITY,\n    [Key] nvarchar(250) NOT NULL,\n    [Value] nvarchar(2000) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientProperties] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientProperties_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientRedirectUris] (\n    [Id] int NOT NULL IDENTITY,\n    [RedirectUri] nvarchar(2000) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientRedirectUris] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientRedirectUris_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientScopes] (\n    [Id] int NOT NULL IDENTITY,\n    [Scope] nvarchar(200) NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientScopes] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientScopes_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [ClientSecrets] (\n    [Id] int NOT NULL IDENTITY,\n    [Description] nvarchar(2000) NULL,\n    [Value] nvarchar(4000) NOT NULL,\n    [Expiration] datetime2 NULL,\n    [Type] nvarchar(250) NOT NULL,\n    [Created] datetime2 NOT NULL,\n    [ClientId] int NOT NULL,\n    CONSTRAINT [PK_ClientSecrets] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_ClientSecrets_Clients_ClientId] FOREIGN KEY ([ClientId]) REFERENCES [Clients] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [IdentityResourceClaims] (\n    [Id] int NOT NULL IDENTITY,\n    [Type] nvarchar(200) NOT NULL,\n    [IdentityResourceId] int NOT NULL,\n    CONSTRAINT [PK_IdentityResourceClaims] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_IdentityResourceClaims_IdentityResources_IdentityResourceId] FOREIGN KEY ([IdentityResourceId]) REFERENCES [IdentityResources] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE TABLE [IdentityResourceProperties] (\n    [Id] int NOT NULL IDENTITY,\n    [Key] nvarchar(250) NOT NULL,\n    [Value] nvarchar(2000) NOT NULL,\n    [IdentityResourceId] int NOT NULL,\n    CONSTRAINT [PK_IdentityResourceProperties] PRIMARY KEY ([Id]),\n    CONSTRAINT [FK_IdentityResourceProperties_IdentityResources_IdentityResourceId] FOREIGN KEY ([IdentityResourceId]) REFERENCES [IdentityResources] ([Id]) ON DELETE CASCADE\n);\n\nGO\n\nCREATE INDEX [IX_ApiResourceClaims_ApiResourceId] ON [ApiResourceClaims] ([ApiResourceId]);\n\nGO\n\nCREATE INDEX [IX_ApiResourceProperties_ApiResourceId] ON [ApiResourceProperties] ([ApiResourceId]);\n\nGO\n\nCREATE UNIQUE INDEX [IX_ApiResources_Name] ON [ApiResources] ([Name]);\n\nGO\n\nCREATE INDEX [IX_ApiResourceScopes_ApiResourceId] ON [ApiResourceScopes] ([ApiResourceId]);\n\nGO\n\nCREATE INDEX [IX_ApiResourceSecrets_ApiResourceId] ON [ApiResourceSecrets] ([ApiResourceId]);\n\nGO\n\nCREATE INDEX [IX_ApiScopeClaims_ScopeId] ON [ApiScopeClaims] ([ScopeId]);\n\nGO\n\nCREATE INDEX [IX_ApiScopeProperties_ScopeId] ON [ApiScopeProperties] ([ScopeId]);\n\nGO\n\nCREATE UNIQUE INDEX [IX_ApiScopes_Name] ON [ApiScopes] ([Name]);\n\nGO\n\nCREATE INDEX [IX_ClientClaims_ClientId] ON [ClientClaims] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientCorsOrigins_ClientId] ON [ClientCorsOrigins] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientGrantTypes_ClientId] ON [ClientGrantTypes] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientIdPRestrictions_ClientId] ON [ClientIdPRestrictions] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientPostLogoutRedirectUris_ClientId] ON [ClientPostLogoutRedirectUris] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientProperties_ClientId] ON [ClientProperties] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientRedirectUris_ClientId] ON [ClientRedirectUris] ([ClientId]);\n\nGO\n\nCREATE UNIQUE INDEX [IX_Clients_ClientId] ON [Clients] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientScopes_ClientId] ON [ClientScopes] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_ClientSecrets_ClientId] ON [ClientSecrets] ([ClientId]);\n\nGO\n\nCREATE INDEX [IX_IdentityResourceClaims_IdentityResourceId] ON [IdentityResourceClaims] ([IdentityResourceId]);\n\nGO\n\nCREATE INDEX [IX_IdentityResourceProperties_IdentityResourceId] ON [IdentityResourceProperties] ([IdentityResourceId]);\n\nGO\n\nCREATE UNIQUE INDEX [IX_IdentityResources_Name] ON [IdentityResources] ([Name]);\n\nGO\n\nINSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])\nVALUES (N'20200522172542_Config', N'3.1.0');\n\nGO\n\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/PersistedGrantDb/20200522172538_Grants.Designer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\nnamespace SqlServer.Migrations.PersistedGrantDb\n{\n    [DbContext(typeof(PersistedGrantDbContext))]\n    [Migration(\"20200522172538_Grants\")]\n    partial class Grants\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"3.1.0\")\n                .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.DeviceFlowCodes\", b =>\n                {\n                    b.Property<string>(\"UserCode\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(max)\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"DeviceCode\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .IsRequired()\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.HasKey(\"UserCode\");\n\n                    b.HasIndex(\"DeviceCode\")\n                        .IsUnique();\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.ToTable(\"DeviceCodes\");\n                });\n\n            modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.PersistedGrant\", b =>\n                {\n                    b.Property<string>(\"Key\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"ClientId\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"ConsumedTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<DateTime>(\"CreationTime\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"Data\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(max)\")\n                        .HasMaxLength(50000);\n\n                    b.Property<string>(\"Description\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<DateTime?>(\"Expiration\")\n                        .HasColumnType(\"datetime2\");\n\n                    b.Property<string>(\"SessionId\")\n                        .HasColumnType(\"nvarchar(100)\")\n                        .HasMaxLength(100);\n\n                    b.Property<string>(\"SubjectId\")\n                        .HasColumnType(\"nvarchar(200)\")\n                        .HasMaxLength(200);\n\n                    b.Property<string>(\"Type\")\n                        .IsRequired()\n                        .HasColumnType(\"nvarchar(50)\")\n                        .HasMaxLength(50);\n\n                    b.HasKey(\"Key\");\n\n                    b.HasIndex(\"Expiration\");\n\n                    b.HasIndex(\"SubjectId\", \"ClientId\", \"Type\");\n\n                    b.HasIndex(\"SubjectId\", \"SessionId\", \"Type\");\n\n                    b.ToTable(\"PersistedGrants\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/PersistedGrantDb/20200522172538_Grants.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace SqlServer.Migrations.PersistedGrantDb;\n\npublic partial class Grants : Migration\n{\n    protected override void Up(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.CreateTable(\n            name: \"DeviceCodes\",\n            columns: table => new\n            {\n                UserCode = table.Column<string>(maxLength: 200, nullable: false),\n                DeviceCode = table.Column<string>(maxLength: 200, nullable: false),\n                SubjectId = table.Column<string>(maxLength: 200, nullable: true),\n                SessionId = table.Column<string>(maxLength: 100, nullable: true),\n                ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                Description = table.Column<string>(maxLength: 200, nullable: true),\n                CreationTime = table.Column<DateTime>(nullable: false),\n                Expiration = table.Column<DateTime>(nullable: false),\n                Data = table.Column<string>(maxLength: 50000, nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_DeviceCodes\", x => x.UserCode);\n            });\n\n        migrationBuilder.CreateTable(\n            name: \"PersistedGrants\",\n            columns: table => new\n            {\n                Key = table.Column<string>(maxLength: 200, nullable: false),\n                Type = table.Column<string>(maxLength: 50, nullable: false),\n                SubjectId = table.Column<string>(maxLength: 200, nullable: true),\n                SessionId = table.Column<string>(maxLength: 100, nullable: true),\n                ClientId = table.Column<string>(maxLength: 200, nullable: false),\n                Description = table.Column<string>(maxLength: 200, nullable: true),\n                CreationTime = table.Column<DateTime>(nullable: false),\n                Expiration = table.Column<DateTime>(nullable: true),\n                ConsumedTime = table.Column<DateTime>(nullable: true),\n                Data = table.Column<string>(maxLength: 50000, nullable: false)\n            },\n            constraints: table =>\n            {\n                table.PrimaryKey(\"PK_PersistedGrants\", x => x.Key);\n            });\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_DeviceCodes_DeviceCode\",\n            table: \"DeviceCodes\",\n            column: \"DeviceCode\",\n            unique: true);\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_DeviceCodes_Expiration\",\n            table: \"DeviceCodes\",\n            column: \"Expiration\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_PersistedGrants_Expiration\",\n            table: \"PersistedGrants\",\n            column: \"Expiration\");\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_PersistedGrants_SubjectId_ClientId_Type\",\n            table: \"PersistedGrants\",\n            columns: new[] { \"SubjectId\", \"ClientId\", \"Type\" });\n\n        migrationBuilder.CreateIndex(\n            name: \"IX_PersistedGrants_SubjectId_SessionId_Type\",\n            table: \"PersistedGrants\",\n            columns: new[] { \"SubjectId\", \"SessionId\", \"Type\" });\n    }\n\n    protected override void Down(MigrationBuilder migrationBuilder)\n    {\n        migrationBuilder.DropTable(\n            name: \"DeviceCodes\");\n\n        migrationBuilder.DropTable(\n            name: \"PersistedGrants\");\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/PersistedGrantDb/PersistedGrantDbContextModelSnapshot.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n// <auto-generated />\n\nnamespace SqlServer.Migrations.PersistedGrantDb;\n\n[DbContext(typeof(PersistedGrantDbContext))]\npartial class PersistedGrantDbContextModelSnapshot : ModelSnapshot\n{\n    protected override void BuildModel(ModelBuilder modelBuilder)\n    {\n#pragma warning disable 612, 618\n        modelBuilder\n            .HasAnnotation(\"ProductVersion\", \"3.1.0\")\n            .HasAnnotation(\"Relational:MaxIdentifierLength\", 128)\n            .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.DeviceFlowCodes\", b =>\n            {\n                b.Property<string>(\"UserCode\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"ClientId\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<DateTime>(\"CreationTime\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Data\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(max)\")\n                    .HasMaxLength(50000);\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"DeviceCode\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<DateTime?>(\"Expiration\")\n                    .IsRequired()\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"SessionId\")\n                    .HasColumnType(\"nvarchar(100)\")\n                    .HasMaxLength(100);\n\n                b.Property<string>(\"SubjectId\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.HasKey(\"UserCode\");\n\n                b.HasIndex(\"DeviceCode\")\n                    .IsUnique();\n\n                b.HasIndex(\"Expiration\");\n\n                b.ToTable(\"DeviceCodes\");\n            });\n\n        modelBuilder.Entity(\"IdentityServer8.EntityFramework.Entities.PersistedGrant\", b =>\n            {\n                b.Property<string>(\"Key\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"ClientId\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<DateTime?>(\"ConsumedTime\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<DateTime>(\"CreationTime\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"Data\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(max)\")\n                    .HasMaxLength(50000);\n\n                b.Property<string>(\"Description\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<DateTime?>(\"Expiration\")\n                    .HasColumnType(\"datetime2\");\n\n                b.Property<string>(\"SessionId\")\n                    .HasColumnType(\"nvarchar(100)\")\n                    .HasMaxLength(100);\n\n                b.Property<string>(\"SubjectId\")\n                    .HasColumnType(\"nvarchar(200)\")\n                    .HasMaxLength(200);\n\n                b.Property<string>(\"Type\")\n                    .IsRequired()\n                    .HasColumnType(\"nvarchar(50)\")\n                    .HasMaxLength(50);\n\n                b.HasKey(\"Key\");\n\n                b.HasIndex(\"Expiration\");\n\n                b.HasIndex(\"SubjectId\", \"ClientId\", \"Type\");\n\n                b.HasIndex(\"SubjectId\", \"SessionId\", \"Type\");\n\n                b.ToTable(\"PersistedGrants\");\n            });\n#pragma warning restore 612, 618\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Migrations/PersistedGrantDb.sql",
    "content": "﻿IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL\nBEGIN\n    CREATE TABLE [__EFMigrationsHistory] (\n        [MigrationId] nvarchar(150) NOT NULL,\n        [ProductVersion] nvarchar(32) NOT NULL,\n        CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])\n    );\nEND;\n\nGO\n\nCREATE TABLE [DeviceCodes] (\n    [UserCode] nvarchar(200) NOT NULL,\n    [DeviceCode] nvarchar(200) NOT NULL,\n    [SubjectId] nvarchar(200) NULL,\n    [SessionId] nvarchar(100) NULL,\n    [ClientId] nvarchar(200) NOT NULL,\n    [Description] nvarchar(200) NULL,\n    [CreationTime] datetime2 NOT NULL,\n    [Expiration] datetime2 NOT NULL,\n    [Data] nvarchar(max) NOT NULL,\n    CONSTRAINT [PK_DeviceCodes] PRIMARY KEY ([UserCode])\n);\n\nGO\n\nCREATE TABLE [PersistedGrants] (\n    [Key] nvarchar(200) NOT NULL,\n    [Type] nvarchar(50) NOT NULL,\n    [SubjectId] nvarchar(200) NULL,\n    [SessionId] nvarchar(100) NULL,\n    [ClientId] nvarchar(200) NOT NULL,\n    [Description] nvarchar(200) NULL,\n    [CreationTime] datetime2 NOT NULL,\n    [Expiration] datetime2 NULL,\n    [ConsumedTime] datetime2 NULL,\n    [Data] nvarchar(max) NOT NULL,\n    CONSTRAINT [PK_PersistedGrants] PRIMARY KEY ([Key])\n);\n\nGO\n\nCREATE UNIQUE INDEX [IX_DeviceCodes_DeviceCode] ON [DeviceCodes] ([DeviceCode]);\n\nGO\n\nCREATE INDEX [IX_DeviceCodes_Expiration] ON [DeviceCodes] ([Expiration]);\n\nGO\n\nCREATE INDEX [IX_PersistedGrants_Expiration] ON [PersistedGrants] ([Expiration]);\n\nGO\n\nCREATE INDEX [IX_PersistedGrants_SubjectId_ClientId_Type] ON [PersistedGrants] ([SubjectId], [ClientId], [Type]);\n\nGO\n\nCREATE INDEX [IX_PersistedGrants_SubjectId_SessionId_Type] ON [PersistedGrants] ([SubjectId], [SessionId], [Type]);\n\nGO\n\nINSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])\nVALUES (N'20200522172538_Grants', N'3.1.0');\n\nGO\n\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace SqlServer;\n\nclass Program\n{\n    public static void Main(string[] args)\n    {\n    }\n\n    public static IWebHost BuildWebHost(string[] args) =>\n        WebHost.CreateDefaultBuilder(args)\n            .UseStartup<Startup>()\n            .Build();\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:7603/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"SqlServer\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:7604/\"\n    }\n  }\n}"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/SqlServer.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.EntityFramework.Storage.csproj\" />\n  </ItemGroup>\n  \n</Project>"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace SqlServer;\n\npublic class Startup\n{\n    public IConfiguration Configuration { get; }\n\n    public Startup(IConfiguration config)\n    {\n        Configuration = config;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var cn = Configuration.GetConnectionString(\"db\");\n\n        services.AddOperationalDbContext(options => {\n            options.ConfigureDbContext = b =>\n                b.UseSqlServer(cn, dbOpts => dbOpts.MigrationsAssembly(typeof(Startup).Assembly.FullName));\n        });\n\n        services.AddConfigurationDbContext(options => {\n            options.ConfigureDbContext = b =>\n                b.UseSqlServer(cn, dbOpts => dbOpts.MigrationsAssembly(typeof(Startup).Assembly.FullName));\n        });\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/appsettings.json",
    "content": "{\n  \"ConnectionStrings\": {\n    \"db\": \"server=(localdb)\\\\mssqllocaldb;database=IdentityServer8.EntityFramework-8.0.0;trusted_connection=yes;\",\n    //\"db\": \"Data Source=IdentityServer.db;\"\n  }\n}"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/buildschema.bat",
    "content": "rmdir /S /Q Migrations\n\ndotnet ef migrations add Grants -c PersistedGrantDbContext -o Migrations/PersistedGrantDb\ndotnet ef migrations add Configuration -c ConfigurationDbContext -o Migrations/ConfigurationDb\n\ndotnet ef migrations script -c PersistedGrantDbContext -o Migrations/PersistedGrantDb.sql\ndotnet ef migrations script -c ConfigurationDbContext -o Migrations/ConfigurationDb.sql\n"
  },
  {
    "path": "src/EntityFramework.Storage/migrations/SqlServer/createdb.bat",
    "content": "dotnet ef database update -c PersistedGrantDbContext\ndotnet ef database update -c ConfigurationDbContext \n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Configuration/ServiceCollectionExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Storage\n{\n    /// <summary>\n    /// Extension methods to add EF database support to IdentityServer.\n    /// </summary>\n    public static class IdentityServerEntityFrameworkBuilderExtensions\n    {\n        /// <summary>\n        /// Add Configuration DbContext to the DI system.\n        /// </summary>\n        /// <param name=\"services\"></param>\n        /// <param name=\"storeOptionsAction\">The store options action.</param>\n        /// <returns></returns>\n        public static IServiceCollection AddConfigurationDbContext(this IServiceCollection services,\n            Action<ConfigurationStoreOptions> storeOptionsAction = null)\n        {\n            return services.AddConfigurationDbContext<ConfigurationDbContext>(storeOptionsAction);\n        }\n\n        /// <summary>\n        /// Add Configuration DbContext to the DI system.\n        /// </summary>\n        /// <typeparam name=\"TContext\">The IConfigurationDbContext to use.</typeparam>\n        /// <param name=\"services\"></param>\n        /// <param name=\"storeOptionsAction\">The store options action.</param>\n        /// <returns></returns>\n        public static IServiceCollection AddConfigurationDbContext<TContext>(this IServiceCollection services,\n        Action<ConfigurationStoreOptions> storeOptionsAction = null)\n        where TContext : DbContext, IConfigurationDbContext\n        {\n            var options = new ConfigurationStoreOptions();\n            services.AddSingleton(options);\n            storeOptionsAction?.Invoke(options);\n\n            if (options.ResolveDbContextOptions != null)\n            {\n                services.AddDbContext<TContext>(options.ResolveDbContextOptions);\n            }\n            else\n            {\n                services.AddDbContext<TContext>(dbCtxBuilder =>\n                {\n                    options.ConfigureDbContext?.Invoke(dbCtxBuilder);\n                });\n            }\n            services.AddScoped<IConfigurationDbContext, TContext>();\n\n            return services;\n        }\n\n        /// <summary>\n        /// Adds operational DbContext to the DI system.\n        /// </summary>\n        /// <param name=\"services\"></param>\n        /// <param name=\"storeOptionsAction\">The store options action.</param>\n        /// <returns></returns>\n        public static IServiceCollection AddOperationalDbContext(this IServiceCollection services,\n            Action<OperationalStoreOptions> storeOptionsAction = null)\n        {\n            return services.AddOperationalDbContext<PersistedGrantDbContext>(storeOptionsAction);\n        }\n\n        /// <summary>\n        /// Adds operational DbContext to the DI system.\n        /// </summary>\n        /// <typeparam name=\"TContext\">The IPersistedGrantDbContext to use.</typeparam>\n        /// <param name=\"services\"></param>\n        /// <param name=\"storeOptionsAction\">The store options action.</param>\n        /// <returns></returns>\n        public static IServiceCollection AddOperationalDbContext<TContext>(this IServiceCollection services,\n            Action<OperationalStoreOptions> storeOptionsAction = null)\n            where TContext : DbContext, IPersistedGrantDbContext\n        {\n            var storeOptions = new OperationalStoreOptions();\n            services.AddSingleton(storeOptions);\n            storeOptionsAction?.Invoke(storeOptions);\n\n            if (storeOptions.ResolveDbContextOptions != null)\n            {\n                services.AddDbContext<TContext>(storeOptions.ResolveDbContextOptions);\n            }\n            else\n            {\n                services.AddDbContext<TContext>(dbCtxBuilder =>\n                {\n                    storeOptions.ConfigureDbContext?.Invoke(dbCtxBuilder);\n                });\n            }\n\n            services.AddScoped<IPersistedGrantDbContext, TContext>();\n            services.AddTransient<TokenCleanupService>();\n\n            return services;\n        }\n\n        /// <summary>\n        /// Adds an implementation of the IOperationalStoreNotification to the DI system.\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"services\"></param>\n        /// <returns></returns>\n        public static IServiceCollection AddOperationalStoreNotification<T>(this IServiceCollection services)\n           where T : class, IOperationalStoreNotification\n        {\n            services.AddTransient<IOperationalStoreNotification, T>();\n            return services;\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/DbContexts/ConfigurationDbContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.DbContexts\n{\n    /// <summary>\n    /// DbContext for the IdentityServer configuration data.\n    /// </summary>\n    /// <seealso cref=\"Microsoft.EntityFrameworkCore.DbContext\" />\n    /// <seealso cref=\"IdentityServer8.EntityFramework.Interfaces.IConfigurationDbContext\" />\n    public class ConfigurationDbContext : ConfigurationDbContext<ConfigurationDbContext>\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ConfigurationDbContext\"/> class.\n        /// </summary>\n        /// <param name=\"options\">The options.</param>\n        /// <param name=\"storeOptions\">The store options.</param>\n        /// <exception cref=\"ArgumentNullException\">storeOptions</exception>\n        public ConfigurationDbContext(DbContextOptions<ConfigurationDbContext> options, ConfigurationStoreOptions storeOptions)\n            : base(options, storeOptions)\n        {\n        }\n    }\n\n    /// <summary>\n    /// DbContext for the IdentityServer configuration data.\n    /// </summary>\n    /// <seealso cref=\"Microsoft.EntityFrameworkCore.DbContext\" />\n    /// <seealso cref=\"IdentityServer8.EntityFramework.Interfaces.IConfigurationDbContext\" />\n    public class ConfigurationDbContext<TContext> : DbContext, IConfigurationDbContext\n        where TContext : DbContext, IConfigurationDbContext\n    {\n        private readonly ConfigurationStoreOptions storeOptions;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ConfigurationDbContext\"/> class.\n        /// </summary>\n        /// <param name=\"options\">The options.</param>\n        /// <param name=\"storeOptions\">The store options.</param>\n        /// <exception cref=\"ArgumentNullException\">storeOptions</exception>\n        public ConfigurationDbContext(DbContextOptions<TContext> options, ConfigurationStoreOptions storeOptions)\n            : base(options)\n        {\n            this.storeOptions = storeOptions ?? throw new ArgumentNullException(nameof(storeOptions));\n        }\n\n        /// <summary>\n        /// Gets or sets the clients.\n        /// </summary>\n        /// <value>\n        /// The clients.\n        /// </value>\n        public DbSet<Client> Clients { get; set; }\n\n        /// <summary>\n        /// Gets or sets the clients' CORS origins.\n        /// </summary>\n        /// <value>\n        /// The clients CORS origins.\n        /// </value>\n        public DbSet<ClientCorsOrigin> ClientCorsOrigins { get; set; }\n\n        /// <summary>\n        /// Gets or sets the identity resources.\n        /// </summary>\n        /// <value>\n        /// The identity resources.\n        /// </value>\n        public DbSet<IdentityResource> IdentityResources { get; set; }\n\n        /// <summary>\n        /// Gets or sets the API resources.\n        /// </summary>\n        /// <value>\n        /// The API resources.\n        /// </value>\n        public DbSet<ApiResource> ApiResources { get; set; }\n\n        /// <summary>\n        /// Gets or sets the API scopes.\n        /// </summary>\n        /// <value>\n        /// The API resources.\n        /// </value>\n        public DbSet<ApiScope> ApiScopes { get; set; }\n\n        /// <summary>\n        /// Override this method to further configure the model that was discovered by convention from the entity types\n        /// exposed in <see cref=\"T:Microsoft.EntityFrameworkCore.DbSet`1\" /> properties on your derived context. The resulting model may be cached\n        /// and re-used for subsequent instances of your derived context.\n        /// </summary>\n        /// <param name=\"modelBuilder\">The builder being used to construct the model for this context. Databases (and other extensions) typically\n        /// define extension methods on this object that allow you to configure aspects of the model that are specific\n        /// to a given database.</param>\n        /// <remarks>\n        /// If a model is explicitly set on the options for this context (via <see cref=\"M:Microsoft.EntityFrameworkCore.DbContextOptionsBuilder.UseModel(Microsoft.EntityFrameworkCore.Metadata.IModel)\" />)\n        /// then this method will not be run.\n        /// </remarks>\n        protected override void OnModelCreating(ModelBuilder modelBuilder)\n        {\n            modelBuilder.ConfigureClientContext(storeOptions);\n            modelBuilder.ConfigureResourcesContext(storeOptions);\n\n            base.OnModelCreating(modelBuilder);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/DbContexts/PersistedGrantDbContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.DbContexts\n{\n    /// <summary>\n    /// DbContext for the IdentityServer operational data.\n    /// </summary>\n    /// <seealso cref=\"Microsoft.EntityFrameworkCore.DbContext\" />\n    /// <seealso cref=\"IdentityServer8.EntityFramework.Interfaces.IPersistedGrantDbContext\" />\n    public class PersistedGrantDbContext : PersistedGrantDbContext<PersistedGrantDbContext>\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"PersistedGrantDbContext\"/> class.\n        /// </summary>\n        /// <param name=\"options\">The options.</param>\n        /// <param name=\"storeOptions\">The store options.</param>\n        /// <exception cref=\"ArgumentNullException\">storeOptions</exception>\n        public PersistedGrantDbContext(DbContextOptions<PersistedGrantDbContext> options, OperationalStoreOptions storeOptions)\n            : base(options, storeOptions)\n        {\n        }\n    }\n\n    /// <summary>\n    /// DbContext for the IdentityServer operational data.\n    /// </summary>\n    /// <seealso cref=\"Microsoft.EntityFrameworkCore.DbContext\" />\n    /// <seealso cref=\"IdentityServer8.EntityFramework.Interfaces.IPersistedGrantDbContext\" />\n    public class PersistedGrantDbContext<TContext> : DbContext, IPersistedGrantDbContext\n        where TContext : DbContext, IPersistedGrantDbContext\n    {\n        private readonly OperationalStoreOptions storeOptions;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"PersistedGrantDbContext\"/> class.\n        /// </summary>\n        /// <param name=\"options\">The options.</param>\n        /// <param name=\"storeOptions\">The store options.</param>\n        /// <exception cref=\"ArgumentNullException\">storeOptions</exception>\n        public PersistedGrantDbContext(DbContextOptions options, OperationalStoreOptions storeOptions)\n            : base(options)\n        {\n            if (storeOptions == null) throw new ArgumentNullException(nameof(storeOptions));\n            this.storeOptions = storeOptions;\n        }\n\n        /// <summary>\n        /// Gets or sets the persisted grants.\n        /// </summary>\n        /// <value>\n        /// The persisted grants.\n        /// </value>\n        public DbSet<PersistedGrant> PersistedGrants { get; set; }\n\n        /// <summary>\n        /// Gets or sets the device codes.\n        /// </summary>\n        /// <value>\n        /// The device codes.\n        /// </value>\n        public DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }\n\n        /// <summary>\n        /// Saves the changes.\n        /// </summary>\n        /// <returns></returns>\n        public virtual Task<int> SaveChangesAsync()\n        {\n            return base.SaveChangesAsync();\n        }\n\n        /// <summary>\n        /// Override this method to further configure the model that was discovered by convention from the entity types\n        /// exposed in <see cref=\"T:Microsoft.EntityFrameworkCore.DbSet`1\" /> properties on your derived context. The resulting model may be cached\n        /// and re-used for subsequent instances of your derived context.\n        /// </summary>\n        /// <param name=\"modelBuilder\">The builder being used to construct the model for this context. Databases (and other extensions) typically\n        /// define extension methods on this object that allow you to configure aspects of the model that are specific\n        /// to a given database.</param>\n        /// <remarks>\n        /// If a model is explicitly set on the options for this context (via <see cref=\"M:Microsoft.EntityFrameworkCore.DbContextOptionsBuilder.UseModel(Microsoft.EntityFrameworkCore.Metadata.IModel)\" />)\n        /// then this method will not be run.\n        /// </remarks>\n        protected override void OnModelCreating(ModelBuilder modelBuilder)\n        {\n            modelBuilder.ConfigurePersistedGrantContext(storeOptions);\n\n            base.OnModelCreating(modelBuilder);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiResource.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiResource\n    {\n        public int Id { get; set; }\n        public bool Enabled { get; set; } = true;\n        public string Name { get; set; }\n        public string DisplayName { get; set; }\n        public string Description { get; set; }\n        public string AllowedAccessTokenSigningAlgorithms { get; set; }\n        public bool ShowInDiscoveryDocument { get; set; } = true;\n        public List<ApiResourceSecret> Secrets { get; set; }\n        public List<ApiResourceScope> Scopes { get; set; }\n        public List<ApiResourceClaim> UserClaims { get; set; }\n        public List<ApiResourceProperty> Properties { get; set; }\n        public DateTime Created { get; set; } = DateTime.UtcNow;\n        public DateTime? Updated { get; set; }\n        public DateTime? LastAccessed { get; set; }\n        public bool NonEditable { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiResourceClaim.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiResourceClaim : UserClaim\n    {\n        public int ApiResourceId { get; set; }\n        public ApiResource ApiResource { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiResourceProperty.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiResourceProperty : Property\n    {\n        public int ApiResourceId { get; set; }\n        public ApiResource ApiResource { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiResourceScope.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiResourceScope\n    {\n        public int Id { get; set; }\n        public string Scope { get; set; }\n\n        public int ApiResourceId { get; set; }\n        public ApiResource ApiResource { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiResourceSecret.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiResourceSecret : Secret\n    {\n        public int ApiResourceId { get; set; }\n        public ApiResource ApiResource { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiScope.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nusing System.Collections.Generic;\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiScope\n    {\n        public int Id { get; set; }\n        public bool Enabled { get; set; } = true;\n        public string Name { get; set; }\n        public string DisplayName { get; set; }\n        public string Description { get; set; }\n        public bool Required { get; set; }\n        public bool Emphasize { get; set; }\n        public bool ShowInDiscoveryDocument { get; set; } = true;\n        public List<ApiScopeClaim> UserClaims { get; set; }\n        public List<ApiScopeProperty> Properties { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiScopeClaim.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiScopeClaim : UserClaim\n    {\n        public int ScopeId { get; set; }\n        public ApiScope Scope { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ApiScopeProperty.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ApiScopeProperty : Property\n    {\n        public int ScopeId { get; set; }\n        public ApiScope Scope { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/Client.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nusing IdentityServer8.Models;\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class Client\n    {\n        public int Id { get; set; }\n        public bool Enabled { get; set; } = true;\n        public string ClientId { get; set; }\n        public string ProtocolType { get; set; } = \"oidc\";\n        public List<ClientSecret> ClientSecrets { get; set; }\n        public bool RequireClientSecret { get; set; } = true;\n        public string ClientName { get; set; }\n        public string Description { get; set; }\n        public string ClientUri { get; set; }\n        public string LogoUri { get; set; }\n        public bool RequireConsent { get; set; } = false;\n        public bool AllowRememberConsent { get; set; } = true;\n        public bool AlwaysIncludeUserClaimsInIdToken { get; set; }\n        public List<ClientGrantType> AllowedGrantTypes { get; set; }\n        public bool RequirePkce { get; set; } = true;\n        public bool AllowPlainTextPkce { get; set; }\n        public bool RequireRequestObject { get; set; }\n        public bool AllowAccessTokensViaBrowser { get; set; }\n        public List<ClientRedirectUri> RedirectUris { get; set; }\n        public List<ClientPostLogoutRedirectUri> PostLogoutRedirectUris { get; set; }\n        public string FrontChannelLogoutUri { get; set; }\n        public bool FrontChannelLogoutSessionRequired { get; set; } = true;\n        public string BackChannelLogoutUri { get; set; }\n        public bool BackChannelLogoutSessionRequired { get; set; } = true;\n        public bool AllowOfflineAccess { get; set; }\n        public List<ClientScope> AllowedScopes { get; set; }\n        public int IdentityTokenLifetime { get; set; } = 300;\n        public string AllowedIdentityTokenSigningAlgorithms { get; set; }\n        public int AccessTokenLifetime { get; set; } = 3600;\n        public int AuthorizationCodeLifetime { get; set; } = 300;\n        public int? ConsentLifetime { get; set; } = null;\n        public int AbsoluteRefreshTokenLifetime { get; set; } = 2592000;\n        public int SlidingRefreshTokenLifetime { get; set; } = 1296000;\n        public int RefreshTokenUsage { get; set; } = (int)TokenUsage.OneTimeOnly;\n        public bool UpdateAccessTokenClaimsOnRefresh { get; set; }\n        public int RefreshTokenExpiration { get; set; } = (int)TokenExpiration.Absolute;\n        public int AccessTokenType { get; set; } = (int)0; // AccessTokenType.Jwt;\n        public bool EnableLocalLogin { get; set; } = true;\n        public List<ClientIdPRestriction> IdentityProviderRestrictions { get; set; }\n        public bool IncludeJwtId { get; set; }\n        public List<ClientClaim> Claims { get; set; }\n        public bool AlwaysSendClientClaims { get; set; }\n        public string ClientClaimsPrefix { get; set; } = \"client_\";\n        public string PairWiseSubjectSalt { get; set; }\n        public List<ClientCorsOrigin> AllowedCorsOrigins { get; set; }\n        public List<ClientProperty> Properties { get; set; }\n        public DateTime Created { get; set; } = DateTime.UtcNow;\n        public DateTime? Updated { get; set; }\n        public DateTime? LastAccessed { get; set; }\n        public int? UserSsoLifetime { get; set; }\n        public string UserCodeType { get; set; }\n        public int DeviceCodeLifetime { get; set; } = 300;\n        public bool NonEditable { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientClaim.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientClaim\n    {\n        public int Id { get; set; }\n        public string Type { get; set; }\n        public string Value { get; set; }\n\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientCorsOrigin.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientCorsOrigin\n    {\n        public int Id { get; set; }\n        public string Origin { get; set; }\n\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientGrantType.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientGrantType\n    {\n        public int Id { get; set; }\n        public string GrantType { get; set; }\n\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientIdPRestriction.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientIdPRestriction\n    {\n        public int Id { get; set; }\n        public string Provider { get; set; }\n\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientPostLogoutRedirectUri.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientPostLogoutRedirectUri\n    {\n        public int Id { get; set; }\n        public string PostLogoutRedirectUri { get; set; }\n\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientProperty.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientProperty : Property\n    {\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientRedirectUri.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientRedirectUri\n    {\n        public int Id { get; set; }\n        public string RedirectUri { get; set; }\n\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientScope.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientScope\n    {\n        public int Id { get; set; }\n        public string Scope { get; set; }\n\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/ClientSecret.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class ClientSecret : Secret\n    {\n        public int ClientId { get; set; }\n        public Client Client { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/DeviceFlowCodes.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    /// <summary>\n    /// Entity for device flow codes\n    /// </summary>\n    public class DeviceFlowCodes\n    {\n        /// <summary>\n        /// Gets or sets the device code.\n        /// </summary>\n        /// <value>\n        /// The device code.\n        /// </value>\n        public string DeviceCode { get; set; }\n\n        /// <summary>\n        /// Gets or sets the user code.\n        /// </summary>\n        /// <value>\n        /// The user code.\n        /// </value>\n        public string UserCode { get; set; }\n\n        /// <summary>\n        /// Gets or sets the subject identifier.\n        /// </summary>\n        /// <value>\n        /// The subject identifier.\n        /// </value>\n        public string SubjectId { get; set; }\n\n        /// <summary>\n        /// Gets or sets the session identifier.\n        /// </summary>\n        /// <value>\n        /// The session identifier.\n        /// </value>\n        public string SessionId { get; set; }\n\n        /// <summary>\n        /// Gets or sets the client identifier.\n        /// </summary>\n        /// <value>\n        /// The client identifier.\n        /// </value>\n        public string ClientId { get; set; }\n\n        /// <summary>\n        /// Gets the description the user assigned to the device being authorized.\n        /// </summary>\n        /// <value>\n        /// The description.\n        /// </value>\n        public string Description { get; set; }\n\n        /// <summary>\n        /// Gets or sets the creation time.\n        /// </summary>\n        /// <value>\n        /// The creation time.\n        /// </value>\n        public DateTime CreationTime { get; set; }\n\n        /// <summary>\n        /// Gets or sets the expiration.\n        /// </summary>\n        /// <value>\n        /// The expiration.\n        /// </value>\n        public DateTime? Expiration { get; set; }\n\n        /// <summary>\n        /// Gets or sets the data.\n        /// </summary>\n        /// <value>\n        /// The data.\n        /// </value>\n        public string Data { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/IdentityResource.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class IdentityResource\n    {\n        public int Id { get; set; }\n        public bool Enabled { get; set; } = true;\n        public string Name { get; set; }\n        public string DisplayName { get; set; }\n        public string Description { get; set; }\n        public bool Required { get; set; }\n        public bool Emphasize { get; set; }\n        public bool ShowInDiscoveryDocument { get; set; } = true;\n        public List<IdentityResourceClaim> UserClaims { get; set; }\n        public List<IdentityResourceProperty> Properties { get; set; }\n        public DateTime Created { get; set; } = DateTime.UtcNow;\n        public DateTime? Updated { get; set; }\n        public bool NonEditable { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/IdentityResourceClaim.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class IdentityResourceClaim : UserClaim\n    {\n        public int IdentityResourceId { get; set; }\n        public IdentityResource IdentityResource { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/IdentityResourceProperty.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class IdentityResourceProperty : Property\n    {\n        public int IdentityResourceId { get; set; }\n        public IdentityResource IdentityResource { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/PersistedGrant.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public class PersistedGrant\n    {\n        public string Key { get; set; }\n        public string Type { get; set; }\n        public string SubjectId { get; set; }\n        public string SessionId { get; set; }\n        public string ClientId { get; set; }\n        public string Description { get; set; }\n        public DateTime CreationTime { get; set; }\n        public DateTime? Expiration { get; set; }\n        public DateTime? ConsumedTime { get; set; }\n        public string Data { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/Property.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public abstract class Property\n    {\n        public int Id { get; set; }\n        public string Key { get; set; }\n        public string Value { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/Secret.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public abstract class Secret\n    {\n        public int Id { get; set; }\n        public string Description { get; set; }\n        public string Value { get; set; }\n        public DateTime? Expiration { get; set; }\n        public string Type { get; set; } = \"SharedSecret\";\n        public DateTime Created { get; set; } = DateTime.UtcNow;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Entities/UserClaim.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.EntityFramework.Entities\n{\n    public abstract class UserClaim\n    {\n        public int Id { get; set; }\n        public string Type { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Extensions/ModelBuilderExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.Extensions\n{\n    /// <summary>\n    /// Extension methods to define the database schema for the configuration and operational data stores.\n    /// </summary>\n    public static class ModelBuilderExtensions\n    {\n        private static EntityTypeBuilder<TEntity> ToTable<TEntity>(this EntityTypeBuilder<TEntity> entityTypeBuilder, TableConfiguration configuration)\n            where TEntity : class\n        {\n            return string.IsNullOrWhiteSpace(configuration.Schema) ? entityTypeBuilder.ToTable(configuration.Name) : entityTypeBuilder.ToTable(configuration.Name, configuration.Schema);\n        }\n\n        /// <summary>\n        /// Configures the client context.\n        /// </summary>\n        /// <param name=\"modelBuilder\">The model builder.</param>\n        /// <param name=\"storeOptions\">The store options.</param>\n        public static void ConfigureClientContext(this ModelBuilder modelBuilder, ConfigurationStoreOptions storeOptions)\n        {\n            if (!string.IsNullOrWhiteSpace(storeOptions.DefaultSchema)) modelBuilder.HasDefaultSchema(storeOptions.DefaultSchema);\n\n            modelBuilder.Entity<Client>(client =>\n            {\n                client.ToTable(storeOptions.Client);\n                client.HasKey(x => x.Id);\n\n                client.Property(x => x.ClientId).HasMaxLength(200).IsRequired();\n                client.Property(x => x.ProtocolType).HasMaxLength(200).IsRequired();\n                client.Property(x => x.ClientName).HasMaxLength(200);\n                client.Property(x => x.ClientUri).HasMaxLength(2000);\n                client.Property(x => x.LogoUri).HasMaxLength(2000);\n                client.Property(x => x.Description).HasMaxLength(1000);\n                client.Property(x => x.FrontChannelLogoutUri).HasMaxLength(2000);\n                client.Property(x => x.BackChannelLogoutUri).HasMaxLength(2000);\n                client.Property(x => x.ClientClaimsPrefix).HasMaxLength(200);\n                client.Property(x => x.PairWiseSubjectSalt).HasMaxLength(200);\n                client.Property(x => x.UserCodeType).HasMaxLength(100);\n                client.Property(x => x.AllowedIdentityTokenSigningAlgorithms).HasMaxLength(100);\n\n                client.HasIndex(x => x.ClientId).IsUnique();\n\n                client.HasMany(x => x.AllowedGrantTypes).WithOne(x => x.Client).HasForeignKey(x=>x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.RedirectUris).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.PostLogoutRedirectUris).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.AllowedScopes).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.ClientSecrets).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.Claims).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.IdentityProviderRestrictions).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.AllowedCorsOrigins).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                client.HasMany(x => x.Properties).WithOne(x => x.Client).HasForeignKey(x => x.ClientId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n            });\n\n            modelBuilder.Entity<ClientGrantType>(grantType =>\n            {\n                grantType.ToTable(storeOptions.ClientGrantType);\n                grantType.Property(x => x.GrantType).HasMaxLength(250).IsRequired();\n            });\n\n            modelBuilder.Entity<ClientRedirectUri>(redirectUri =>\n            {\n                redirectUri.ToTable(storeOptions.ClientRedirectUri);\n                redirectUri.Property(x => x.RedirectUri).HasMaxLength(2000).IsRequired();\n            });\n\n            modelBuilder.Entity<ClientPostLogoutRedirectUri>(postLogoutRedirectUri =>\n            {\n                postLogoutRedirectUri.ToTable(storeOptions.ClientPostLogoutRedirectUri);\n                postLogoutRedirectUri.Property(x => x.PostLogoutRedirectUri).HasMaxLength(2000).IsRequired();\n            });\n\n            modelBuilder.Entity<ClientScope>(scope =>\n            {\n                scope.ToTable(storeOptions.ClientScopes);\n                scope.Property(x => x.Scope).HasMaxLength(200).IsRequired();\n            });\n\n            modelBuilder.Entity<ClientSecret>(secret =>\n            {\n                secret.ToTable(storeOptions.ClientSecret);\n                secret.Property(x => x.Value).HasMaxLength(4000).IsRequired();\n                secret.Property(x => x.Type).HasMaxLength(250).IsRequired();\n                secret.Property(x => x.Description).HasMaxLength(2000);\n            });\n\n            modelBuilder.Entity<ClientClaim>(claim =>\n            {\n                claim.ToTable(storeOptions.ClientClaim);\n                claim.Property(x => x.Type).HasMaxLength(250).IsRequired();\n                claim.Property(x => x.Value).HasMaxLength(250).IsRequired();\n            });\n\n            modelBuilder.Entity<ClientIdPRestriction>(idPRestriction =>\n            {\n                idPRestriction.ToTable(storeOptions.ClientIdPRestriction);\n                idPRestriction.Property(x => x.Provider).HasMaxLength(200).IsRequired();\n            });\n\n            modelBuilder.Entity<ClientCorsOrigin>(corsOrigin =>\n            {\n                corsOrigin.ToTable(storeOptions.ClientCorsOrigin);\n                corsOrigin.Property(x => x.Origin).HasMaxLength(150).IsRequired();\n            });\n\n            modelBuilder.Entity<ClientProperty>(property =>\n            {\n                property.ToTable(storeOptions.ClientProperty);\n                property.Property(x => x.Key).HasMaxLength(250).IsRequired();\n                property.Property(x => x.Value).HasMaxLength(2000).IsRequired();\n            });\n        }\n\n        /// <summary>\n        /// Configures the persisted grant context.\n        /// </summary>\n        /// <param name=\"modelBuilder\">The model builder.</param>\n        /// <param name=\"storeOptions\">The store options.</param>\n        public static void ConfigurePersistedGrantContext(this ModelBuilder modelBuilder, OperationalStoreOptions storeOptions)\n        {\n            if (!string.IsNullOrWhiteSpace(storeOptions.DefaultSchema)) modelBuilder.HasDefaultSchema(storeOptions.DefaultSchema);\n\n            modelBuilder.Entity<PersistedGrant>(grant =>\n            {\n                grant.ToTable(storeOptions.PersistedGrants);\n\n                grant.Property(x => x.Key).HasMaxLength(200).ValueGeneratedNever();\n                grant.Property(x => x.Type).HasMaxLength(50).IsRequired();\n                grant.Property(x => x.SubjectId).HasMaxLength(200);\n                grant.Property(x => x.SessionId).HasMaxLength(100);\n                grant.Property(x => x.ClientId).HasMaxLength(200).IsRequired();\n                grant.Property(x => x.Description).HasMaxLength(200);\n                grant.Property(x => x.CreationTime).IsRequired();\n                // 50000 chosen to be explicit to allow enough size to avoid truncation, yet stay beneath the MySql row size limit of ~65K\n                // apparently anything over 4K converts to nvarchar(max) on SqlServer\n                grant.Property(x => x.Data).HasMaxLength(50000).IsRequired();\n\n                grant.HasKey(x => x.Key);\n\n                grant.HasIndex(x => new { x.SubjectId, x.ClientId, x.Type });\n                grant.HasIndex(x => new { x.SubjectId, x.SessionId, x.Type });\n                grant.HasIndex(x => x.Expiration);\n            });\n\n            modelBuilder.Entity<DeviceFlowCodes>(codes =>\n            {\n                codes.ToTable(storeOptions.DeviceFlowCodes);\n\n                codes.Property(x => x.DeviceCode).HasMaxLength(200).IsRequired();\n                codes.Property(x => x.UserCode).HasMaxLength(200).IsRequired();\n                codes.Property(x => x.SubjectId).HasMaxLength(200);\n                codes.Property(x => x.SessionId).HasMaxLength(100);\n                codes.Property(x => x.ClientId).HasMaxLength(200).IsRequired();\n                codes.Property(x => x.Description).HasMaxLength(200);\n                codes.Property(x => x.CreationTime).IsRequired();\n                codes.Property(x => x.Expiration).IsRequired();\n                // 50000 chosen to be explicit to allow enough size to avoid truncation, yet stay beneath the MySql row size limit of ~65K\n                // apparently anything over 4K converts to nvarchar(max) on SqlServer\n                codes.Property(x => x.Data).HasMaxLength(50000).IsRequired();\n\n                codes.HasKey(x => new {x.UserCode});\n\n                codes.HasIndex(x => x.DeviceCode).IsUnique();\n                codes.HasIndex(x => x.Expiration);\n            });\n        }\n\n        /// <summary>\n        /// Configures the resources context.\n        /// </summary>\n        /// <param name=\"modelBuilder\">The model builder.</param>\n        /// <param name=\"storeOptions\">The store options.</param>\n        public static void ConfigureResourcesContext(this ModelBuilder modelBuilder, ConfigurationStoreOptions storeOptions)\n        {\n            if (!string.IsNullOrWhiteSpace(storeOptions.DefaultSchema)) modelBuilder.HasDefaultSchema(storeOptions.DefaultSchema);\n\n            modelBuilder.Entity<IdentityResource>(identityResource =>\n            {\n                identityResource.ToTable(storeOptions.IdentityResource).HasKey(x => x.Id);\n\n                identityResource.Property(x => x.Name).HasMaxLength(200).IsRequired();\n                identityResource.Property(x => x.DisplayName).HasMaxLength(200);\n                identityResource.Property(x => x.Description).HasMaxLength(1000);\n\n                identityResource.HasIndex(x => x.Name).IsUnique();\n\n                identityResource.HasMany(x => x.UserClaims).WithOne(x => x.IdentityResource).HasForeignKey(x => x.IdentityResourceId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                identityResource.HasMany(x => x.Properties).WithOne(x => x.IdentityResource).HasForeignKey(x => x.IdentityResourceId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n            });\n\n            modelBuilder.Entity<IdentityResourceClaim>(claim =>\n            {\n                claim.ToTable(storeOptions.IdentityResourceClaim).HasKey(x => x.Id);\n\n                claim.Property(x => x.Type).HasMaxLength(200).IsRequired();\n            });\n\n            modelBuilder.Entity<IdentityResourceProperty>(property =>\n            {\n                property.ToTable(storeOptions.IdentityResourceProperty);\n                property.Property(x => x.Key).HasMaxLength(250).IsRequired();\n                property.Property(x => x.Value).HasMaxLength(2000).IsRequired();\n            });\n\n\n\n            modelBuilder.Entity<ApiResource>(apiResource =>\n            {\n                apiResource.ToTable(storeOptions.ApiResource).HasKey(x => x.Id);\n\n                apiResource.Property(x => x.Name).HasMaxLength(200).IsRequired();\n                apiResource.Property(x => x.DisplayName).HasMaxLength(200);\n                apiResource.Property(x => x.Description).HasMaxLength(1000);\n                apiResource.Property(x => x.AllowedAccessTokenSigningAlgorithms).HasMaxLength(100);\n\n                apiResource.HasIndex(x => x.Name).IsUnique();\n\n                apiResource.HasMany(x => x.Secrets).WithOne(x => x.ApiResource).HasForeignKey(x => x.ApiResourceId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                apiResource.HasMany(x => x.Scopes).WithOne(x => x.ApiResource).HasForeignKey(x => x.ApiResourceId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                apiResource.HasMany(x => x.UserClaims).WithOne(x => x.ApiResource).HasForeignKey(x => x.ApiResourceId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n                apiResource.HasMany(x => x.Properties).WithOne(x => x.ApiResource).HasForeignKey(x => x.ApiResourceId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n            });\n\n            modelBuilder.Entity<ApiResourceSecret>(apiSecret =>\n            {\n                apiSecret.ToTable(storeOptions.ApiResourceSecret).HasKey(x => x.Id);\n\n                apiSecret.Property(x => x.Description).HasMaxLength(1000);\n                apiSecret.Property(x => x.Value).HasMaxLength(4000).IsRequired();\n                apiSecret.Property(x => x.Type).HasMaxLength(250).IsRequired();\n            });\n\n            modelBuilder.Entity<ApiResourceClaim>(apiClaim =>\n            {\n                apiClaim.ToTable(storeOptions.ApiResourceClaim).HasKey(x => x.Id);\n\n                apiClaim.Property(x => x.Type).HasMaxLength(200).IsRequired();\n            });\n\n            modelBuilder.Entity<ApiResourceScope>((System.Action<EntityTypeBuilder<ApiResourceScope>>)(apiScope =>\n            {\n                apiScope.ToTable((TableConfiguration)storeOptions.ApiResourceScope).HasKey(x => x.Id);\n\n                apiScope.Property(x => x.Scope).HasMaxLength(200).IsRequired();\n            }));\n\n            modelBuilder.Entity<ApiResourceProperty>(property =>\n            {\n                property.ToTable(storeOptions.ApiResourceProperty);\n                property.Property(x => x.Key).HasMaxLength(250).IsRequired();\n                property.Property(x => x.Value).HasMaxLength(2000).IsRequired();\n            });\n\n\n            modelBuilder.Entity<ApiScope>(scope =>\n            {\n                scope.ToTable(storeOptions.ApiScope).HasKey(x => x.Id);\n\n                scope.Property(x => x.Name).HasMaxLength(200).IsRequired();\n                scope.Property(x => x.DisplayName).HasMaxLength(200);\n                scope.Property(x => x.Description).HasMaxLength(1000);\n\n                scope.HasIndex(x => x.Name).IsUnique();\n\n                scope.HasMany(x => x.UserClaims).WithOne(x => x.Scope).HasForeignKey(x => x.ScopeId).IsRequired().OnDelete(DeleteBehavior.Cascade);\n            });\n            modelBuilder.Entity<ApiScopeClaim>(scopeClaim =>\n            {\n                scopeClaim.ToTable(storeOptions.ApiScopeClaim).HasKey(x => x.Id);\n\n                scopeClaim.Property(x => x.Type).HasMaxLength(200).IsRequired();\n            });\n            modelBuilder.Entity<ApiScopeProperty>(property =>\n            {\n                property.ToTable(storeOptions.ApiScopeProperty).HasKey(x => x.Id);\n                property.Property(x => x.Key).HasMaxLength(250).IsRequired();\n                property.Property(x => x.Value).HasMaxLength(2000).IsRequired();\n            });\n\n\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using AutoMapper;\nglobal using IdentityModel;\nglobal using IdentityServer8.EntityFramework.DbContexts;\nglobal using IdentityServer8.EntityFramework.Extensions;\nglobal using IdentityServer8.EntityFramework.Interfaces;\n//global using IdentityServer8.EntityFramework.Entities;\nglobal using IdentityServer8.EntityFramework.Mappers;\nglobal using IdentityServer8.EntityFramework.Options;\nglobal using IdentityServer8.Extensions;\n//global using IdentityServer8.Models;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Stores.Serialization;\nglobal using Microsoft.EntityFrameworkCore;\nglobal using Microsoft.EntityFrameworkCore.Metadata.Builders;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Logging;\nglobal using System.Buffers;\nglobal using System.Runtime.CompilerServices;\nglobal using ClaimValueTypes = System.Security.Claims.ClaimValueTypes;\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/IdentityServer8.EntityFramework.Storage.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <Description>EntityFramework persistence layer for IdentityServer8</Description>\n        <IsPackable>true</IsPackable>\n        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n    </PropertyGroup>\n\n    <PropertyGroup>\n        <ContinuousIntegrationBuild Condition=\"'$(TF_BUILD)' == 'true'\">True</ContinuousIntegrationBuild>\n        <ContinuousIntegrationBuild Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">True</ContinuousIntegrationBuild>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <PackageReference Include=\"AutoMapper\" />\n        <PackageReference Include=\"Microsoft.EntityFrameworkCore.Relational\" />\n    </ItemGroup>\n\n    <ItemGroup>\n        <ProjectReference Include=\"..\\..\\Security\\IdentityServer8.Security\\IdentityServer8.Security.csproj\" />\n        <ProjectReference Include=\"..\\..\\Storage\\src\\IdentityServer8.Storage.csproj\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Interfaces/IConfigurationDbContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.Interfaces\n{\n    /// <summary>\n    /// Abstraction for the configuration context.\n    /// </summary>\n    /// <seealso cref=\"System.IDisposable\" />\n    public interface IConfigurationDbContext : IDisposable\n    {\n        /// <summary>\n        /// Gets or sets the clients.\n        /// </summary>\n        /// <value>\n        /// The clients.\n        /// </value>\n        DbSet<Client> Clients { get; set; }\n        \n        /// <summary>\n        /// Gets or sets the clients' CORS origins.\n        /// </summary>\n        /// <value>\n        /// The clients CORS origins.\n        /// </value>\n        DbSet<ClientCorsOrigin> ClientCorsOrigins { get; set; }\n\n        /// <summary>\n        /// Gets or sets the identity resources.\n        /// </summary>\n        /// <value>\n        /// The identity resources.\n        /// </value>\n        DbSet<IdentityResource> IdentityResources { get; set; }\n\n        /// <summary>\n        /// Gets or sets the API resources.\n        /// </summary>\n        /// <value>\n        /// The API resources.\n        /// </value>\n        DbSet<ApiResource> ApiResources { get; set; }\n\n        /// <summary>\n        /// Gets or sets the scopes.\n        /// </summary>\n        /// <value>\n        /// The identity resources.\n        /// </value>\n        DbSet<ApiScope> ApiScopes { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Interfaces/IPersistedGrantDbContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.Interfaces\n{\n    /// <summary>\n    /// Abstraction for the operational data context.\n    /// </summary>\n    /// <seealso cref=\"System.IDisposable\" />\n    public interface IPersistedGrantDbContext : IDisposable\n    {\n        /// <summary>\n        /// Gets or sets the persisted grants.\n        /// </summary>\n        /// <value>\n        /// The persisted grants.\n        /// </value>\n        DbSet<PersistedGrant> PersistedGrants { get; set; }\n\n        /// <summary>\n        /// Gets or sets the device flow codes.\n        /// </summary>\n        /// <value>\n        /// The device flow codes.\n        /// </value>\n        DbSet<DeviceFlowCodes> DeviceFlowCodes { get; set; }\n\n        /// <summary>\n        /// Saves the changes.\n        /// </summary>\n        /// <returns></returns>\n        Task<int> SaveChangesAsync();\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/AllowedSigningAlgorithmsConverter.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    class AllowedSigningAlgorithmsConverter : \n        IValueConverter<ICollection<string>, string>,\n        IValueConverter<string, ICollection<string>>\n    {\n        public static AllowedSigningAlgorithmsConverter Converter = new AllowedSigningAlgorithmsConverter();\n\n        public string Convert(ICollection<string> sourceMember, ResolutionContext context)\n        {\n            if (sourceMember == null || !sourceMember.Any())\n            {\n                return null;\n            }\n            return sourceMember.Aggregate((x, y) => $\"{x},{y}\");\n        }\n\n        public ICollection<string> Convert(string sourceMember, ResolutionContext context)\n        {\n            var list = new HashSet<string>();\n            if (!String.IsNullOrWhiteSpace(sourceMember))\n            {\n                sourceMember = sourceMember.Trim();\n                foreach (var item in sourceMember.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Distinct())\n                {\n                    list.Add(item);\n                }\n            }\n            return list;\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/ApiResourceMapperProfile.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Defines entity/model mapping for API resources.\n    /// </summary>\n    /// <seealso cref=\"AutoMapper.Profile\" />\n    public class ApiResourceMapperProfile : Profile\n    {\n        /// <summary>\n        /// <see cref=\"ApiResourceMapperProfile\"/>\n        /// </summary>\n        public ApiResourceMapperProfile()\n        {\n            CreateMap<Entities.ApiResourceProperty, KeyValuePair<string, string>>()\n                .ReverseMap();\n\n            CreateMap<Entities.ApiResource, Models.ApiResource>(MemberList.Destination)\n                .ConstructUsing(src => new Models.ApiResource())\n                .ForMember(x => x.ApiSecrets, opts => opts.MapFrom(x => x.Secrets))\n                .ForMember(x=>x.AllowedAccessTokenSigningAlgorithms, opts => opts.ConvertUsing(AllowedSigningAlgorithmsConverter.Converter, x=>x.AllowedAccessTokenSigningAlgorithms))\n                .ReverseMap()\n                .ForMember(x => x.AllowedAccessTokenSigningAlgorithms, opts => opts.ConvertUsing(AllowedSigningAlgorithmsConverter.Converter, x => x.AllowedAccessTokenSigningAlgorithms));\n\n            CreateMap<Entities.ApiResourceClaim, string>()\n                .ConstructUsing(x => x.Type)\n                .ReverseMap()\n                .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ApiResourceSecret, Models.Secret>(MemberList.Destination)\n                .ForMember(dest => dest.Type, opt => opt.Condition(srs => srs != null))\n                .ReverseMap();\n\n            CreateMap<Entities.ApiResourceScope, string>()\n                .ConstructUsing(x => x.Scope)\n                .ReverseMap()\n                .ForMember(dest => dest.Scope, opt => opt.MapFrom(src => src));\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/ApiResourceMappers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Extension methods to map to/from entity/model for API resources.\n    /// </summary>\n    public static class ApiResourceMappers\n    {\n        static ApiResourceMappers()\n        {\n            Mapper = new MapperConfiguration(cfg => cfg.AddProfile<ApiResourceMapperProfile>())\n                .CreateMapper();\n        }\n\n        internal static IMapper Mapper { get; }\n\n        /// <summary>\n        /// Maps an entity to a model.\n        /// </summary>\n        /// <param name=\"entity\">The entity.</param>\n        /// <returns></returns>\n        public static Models.ApiResource ToModel(this ApiResource entity)\n        {\n            return entity == null ? null : Mapper.Map<Models.ApiResource>(entity);\n        }\n\n        /// <summary>\n        /// Maps a model to an entity.\n        /// </summary>\n        /// <param name=\"model\">The model.</param>\n        /// <returns></returns>\n        public static ApiResource ToEntity(this Models.ApiResource model)\n        {\n            return model == null ? null : Mapper.Map<ApiResource>(model);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/ClientMapperProfile.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Defines entity/model mapping for clients.\n    /// </summary>\n    /// <seealso cref=\"AutoMapper.Profile\" />\n    public class ClientMapperProfile : Profile\n    {\n        /// <summary>\n        /// <see>\n        ///     <cref>{ClientMapperProfile}</cref>\n        /// </see>\n        /// </summary>\n        public ClientMapperProfile()\n        {\n            CreateMap<Entities.ClientProperty, KeyValuePair<string, string>>()\n                .ReverseMap();\n\n            CreateMap<Entities.Client, Models.Client>()\n                .ForMember(dest => dest.ProtocolType, opt => opt.Condition(srs => srs != null))\n                .ForMember(x => x.AllowedIdentityTokenSigningAlgorithms, opts => opts.ConvertUsing(AllowedSigningAlgorithmsConverter.Converter, x => x.AllowedIdentityTokenSigningAlgorithms))\n                .ReverseMap()\n                .ForMember(x => x.AllowedIdentityTokenSigningAlgorithms, opts => opts.ConvertUsing(AllowedSigningAlgorithmsConverter.Converter, x => x.AllowedIdentityTokenSigningAlgorithms));\n\n            CreateMap<Entities.ClientCorsOrigin, string>()\n                .ConstructUsing(src => src.Origin)\n                .ReverseMap()\n                .ForMember(dest => dest.Origin, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ClientIdPRestriction, string>()\n                .ConstructUsing(src => src.Provider)\n                .ReverseMap()\n                .ForMember(dest => dest.Provider, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ClientClaim, ClientClaim>(MemberList.None)\n                .ConstructUsing(src => new ClientClaim(src.Type, src.Value, ClaimValueTypes.String))\n                .ReverseMap();\n\n            CreateMap<Entities.ClientScope, string>()\n                .ConstructUsing(src => src.Scope)\n                .ReverseMap()\n                .ForMember(dest => dest.Scope, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ClientPostLogoutRedirectUri, string>()\n                .ConstructUsing(src => src.PostLogoutRedirectUri)\n                .ReverseMap()\n                .ForMember(dest => dest.PostLogoutRedirectUri, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ClientRedirectUri, string>()\n                .ConstructUsing(src => src.RedirectUri)\n                .ReverseMap()\n                .ForMember(dest => dest.RedirectUri, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ClientGrantType, string>()\n                .ConstructUsing(src => src.GrantType)\n                .ReverseMap()\n                .ForMember(dest => dest.GrantType, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ClientSecret, Models.Secret>(MemberList.Destination)\n                .ForMember(dest => dest.Type, opt => opt.Condition(srs => srs != null))\n                .ReverseMap();\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/ClientMappers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Extension methods to map to/from entity/model for clients.\n    /// </summary>\n    public static class ClientMappers\n    {\n        static ClientMappers()\n        {\n            Mapper = new MapperConfiguration(cfg => cfg.AddProfile<ClientMapperProfile>())\n                .CreateMapper();\n        }\n\n        internal static IMapper Mapper { get; }\n\n        /// <summary>\n        /// Maps an entity to a model.\n        /// </summary>\n        /// <param name=\"entity\">The entity.</param>\n        /// <returns></returns>\n        public static Models.Client ToModel(this Entities.Client entity)\n        {\n            return Mapper.Map<Models.Client>(entity);\n        }\n\n        /// <summary>\n        /// Maps a model to an entity.\n        /// </summary>\n        /// <param name=\"model\">The model.</param>\n        /// <returns></returns>\n        public static Entities.Client ToEntity(this Models.Client model)\n        {\n            return Mapper.Map<Entities.Client>(model);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/IdentityResourceMapperProfile.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Defines entity/model mapping for identity resources.\n    /// </summary>\n    /// <seealso cref=\"AutoMapper.Profile\" />\n    public class IdentityResourceMapperProfile : Profile\n    {\n        /// <summary>\n        /// <see cref=\"IdentityResourceMapperProfile\"/>\n        /// </summary>\n        public IdentityResourceMapperProfile()\n        {\n            CreateMap<Entities.IdentityResourceProperty, KeyValuePair<string, string>>()\n                .ReverseMap();\n\n            CreateMap<Entities.IdentityResource, Models.IdentityResource>(MemberList.Destination)\n                .ConstructUsing(src => new Models.IdentityResource())\n                .ReverseMap();\n\n            CreateMap<Entities.IdentityResourceClaim, string>()\n               .ConstructUsing(x => x.Type)\n               .ReverseMap()\n               .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src));\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/IdentityResourceMappers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Extension methods to map to/from entity/model for identity resources.\n    /// </summary>\n    public static class IdentityResourceMappers\n    {\n        static IdentityResourceMappers()\n        {\n            Mapper = new MapperConfiguration(cfg => cfg.AddProfile<IdentityResourceMapperProfile>())\n                .CreateMapper();\n        }\n\n        internal static IMapper Mapper { get; }\n\n        /// <summary>\n        /// Maps an entity to a model.\n        /// </summary>\n        /// <param name=\"entity\">The entity.</param>\n        /// <returns></returns>\n        public static Models.IdentityResource ToModel(this IdentityResource entity)\n        {\n            return entity == null ? null : Mapper.Map<Models.IdentityResource>(entity);\n        }\n\n        /// <summary>\n        /// Maps a model to an entity.\n        /// </summary>\n        /// <param name=\"model\">The model.</param>\n        /// <returns></returns>\n        public static IdentityResource ToEntity(this Models.IdentityResource model)\n        {\n            return model == null ? null : Mapper.Map<IdentityResource>(model);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/PersistedGrantMapperProfile.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Defines entity/model mapping for persisted grants.\n    /// </summary>\n    /// <seealso cref=\"AutoMapper.Profile\" />\n    public class PersistedGrantMapperProfile:Profile\n    {\n        /// <summary>\n        /// <see cref=\"PersistedGrantMapperProfile\">\n        /// </see>\n        /// </summary>\n        public PersistedGrantMapperProfile()\n        {\n            CreateMap<Entities.PersistedGrant, Models.PersistedGrant>(MemberList.Destination)\n                .ReverseMap();\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/PersistedGrantMappers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Extension methods to map to/from entity/model for persisted grants.\n    /// </summary>\n    public static class PersistedGrantMappers\n    {\n        static PersistedGrantMappers()\n        {\n            Mapper = new MapperConfiguration(cfg =>cfg.AddProfile<PersistedGrantMapperProfile>())\n                .CreateMapper();\n        }\n\n        internal static IMapper Mapper { get; }\n\n        /// <summary>\n        /// Maps an entity to a model.\n        /// </summary>\n        /// <param name=\"entity\">The entity.</param>\n        /// <returns></returns>\n        public static PersistedGrant ToModel(this Entities.PersistedGrant entity)\n        {\n            return entity == null ? null : Mapper.Map<PersistedGrant>(entity);\n        }\n\n        /// <summary>\n        /// Maps a model to an entity.\n        /// </summary>\n        /// <param name=\"model\">The model.</param>\n        /// <returns></returns>\n        public static Entities.PersistedGrant ToEntity(this PersistedGrant model)\n        {\n            return model == null ? null : Mapper.Map<Entities.PersistedGrant>(model);\n        }\n\n        /// <summary>\n        /// Updates an entity from a model.\n        /// </summary>\n        /// <param name=\"model\">The model.</param>\n        /// <param name=\"entity\">The entity.</param>\n        public static void UpdateEntity(this PersistedGrant model, Entities.PersistedGrant entity)\n        {\n            Mapper.Map(model, entity);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/ScopeMapperProfile.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Defines entity/model mapping for scopes.\n    /// </summary>\n    /// <seealso cref=\"AutoMapper.Profile\" />\n    public class ScopeMapperProfile : Profile\n    {\n        /// <summary>\n        /// <see cref=\"ScopeMapperProfile\"/>\n        /// </summary>\n        public ScopeMapperProfile()\n        {\n            CreateMap<Entities.ApiScopeProperty, KeyValuePair<string, string>>()\n                .ReverseMap();\n\n            CreateMap<Entities.ApiScopeClaim, string>()\n               .ConstructUsing(x => x.Type)\n               .ReverseMap()\n               .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src));\n\n            CreateMap<Entities.ApiScope, Models.ApiScope>(MemberList.Destination)\n                .ConstructUsing(src => new Models.ApiScope())\n                .ForMember(x => x.Properties, opts => opts.MapFrom(x => x.Properties))\n                .ForMember(x => x.UserClaims, opts => opts.MapFrom(x => x.UserClaims))\n                .ReverseMap();\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Mappers/ScopeMappers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework.Mappers\n{\n    /// <summary>\n    /// Extension methods to map to/from entity/model for scopes.\n    /// </summary>\n    public static class ScopeMappers\n    {\n        static ScopeMappers()\n        {\n            Mapper = new MapperConfiguration(cfg => cfg.AddProfile<ScopeMapperProfile>())\n                .CreateMapper();\n        }\n\n        internal static IMapper Mapper { get; }\n\n        /// <summary>\n        /// Maps an entity to a model.\n        /// </summary>\n        /// <param name=\"entity\">The entity.</param>\n        /// <returns></returns>\n        public static Models.ApiScope ToModel(this ApiScope entity)\n        {\n            return entity == null ? null : Mapper.Map<Models.ApiScope>(entity);\n        }\n\n        /// <summary>\n        /// Maps a model to an entity.\n        /// </summary>\n        /// <param name=\"model\">The model.</param>\n        /// <returns></returns>\n        public static ApiScope ToEntity(this Models.ApiScope model)\n        {\n            return model == null ? null : Mapper.Map<ApiScope>(model);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Options/ConfigurationStoreOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Options\n{\n    /// <summary>\n    /// Options for configuring the configuration context.\n    /// </summary>\n    public class ConfigurationStoreOptions\n    {\n        /// <summary>\n        /// Callback to configure the EF DbContext.\n        /// </summary>\n        /// <value>\n        /// The configure database context.\n        /// </value>\n        public Action<DbContextOptionsBuilder> ConfigureDbContext { get; set; }\n\n        /// <summary>\n        /// Callback in DI resolve the EF DbContextOptions. If set, ConfigureDbContext will not be used.\n        /// </summary>\n        /// <value>\n        /// The configure database context.\n        /// </value>\n        public Action<IServiceProvider, DbContextOptionsBuilder> ResolveDbContextOptions { get; set; }\n\n        /// <summary>\n        /// Gets or sets the default schema.\n        /// </summary>\n        /// <value>\n        /// The default schema.\n        /// </value>\n        public string DefaultSchema { get; set; } = null;\n\n        /// <summary>\n        /// Gets or sets the identity resource table configuration.\n        /// </summary>\n        /// <value>\n        /// The identity resource.\n        /// </value>\n        public TableConfiguration IdentityResource { get; set; } = new TableConfiguration(\"IdentityResources\");\n        /// <summary>\n        /// Gets or sets the identity claim table configuration.\n        /// </summary>\n        /// <value>\n        /// The identity claim.\n        /// </value>\n        public TableConfiguration IdentityResourceClaim { get; set; } = new TableConfiguration(\"IdentityResourceClaims\");\n        /// <summary>\n        /// Gets or sets the identity resource property table configuration.\n        /// </summary>\n        /// <value>\n        /// The client property.\n        /// </value>\n        public TableConfiguration IdentityResourceProperty { get; set; } = new TableConfiguration(\"IdentityResourceProperties\");\n\n        /// <summary>\n        /// Gets or sets the API resource table configuration.\n        /// </summary>\n        /// <value>\n        /// The API resource.\n        /// </value>\n        public TableConfiguration ApiResource { get; set; } = new TableConfiguration(\"ApiResources\");\n        /// <summary>\n        /// Gets or sets the API secret table configuration.\n        /// </summary>\n        /// <value>\n        /// The API secret.\n        /// </value>\n        public TableConfiguration ApiResourceSecret { get; set; } = new TableConfiguration(\"ApiResourceSecrets\");\n        /// <summary>\n        /// Gets or sets the API scope table configuration.\n        /// </summary>\n        /// <value>\n        /// The API scope.\n        /// </value>\n        public TableConfiguration ApiResourceScope { get; set; } = new TableConfiguration(\"ApiResourceScopes\");\n        /// <summary>\n        /// Gets or sets the API claim table configuration.\n        /// </summary>\n        /// <value>\n        /// The API claim.\n        /// </value>\n        public TableConfiguration ApiResourceClaim { get; set; } = new TableConfiguration(\"ApiResourceClaims\");\n        /// <summary>\n        /// Gets or sets the API resource property table configuration.\n        /// </summary>\n        /// <value>\n        /// The client property.\n        /// </value>\n        public TableConfiguration ApiResourceProperty { get; set; } = new TableConfiguration(\"ApiResourceProperties\");\n\n        /// <summary>\n        /// Gets or sets the client table configuration.\n        /// </summary>\n        /// <value>\n        /// The client.\n        /// </value>\n        public TableConfiguration Client { get; set; } = new TableConfiguration(\"Clients\");\n        /// <summary>\n        /// Gets or sets the type of the client grant table configuration.\n        /// </summary>\n        /// <value>\n        /// The type of the client grant.\n        /// </value>\n        public TableConfiguration ClientGrantType { get; set; } = new TableConfiguration(\"ClientGrantTypes\");\n        /// <summary>\n        /// Gets or sets the client redirect URI table configuration.\n        /// </summary>\n        /// <value>\n        /// The client redirect URI.\n        /// </value>\n        public TableConfiguration ClientRedirectUri { get; set; } = new TableConfiguration(\"ClientRedirectUris\");\n        /// <summary>\n        /// Gets or sets the client post logout redirect URI table configuration.\n        /// </summary>\n        /// <value>\n        /// The client post logout redirect URI.\n        /// </value>\n        public TableConfiguration ClientPostLogoutRedirectUri { get; set; } = new TableConfiguration(\"ClientPostLogoutRedirectUris\");\n        /// <summary>\n        /// Gets or sets the client scopes table configuration.\n        /// </summary>\n        /// <value>\n        /// The client scopes.\n        /// </value>\n        public TableConfiguration ClientScopes { get; set; } = new TableConfiguration(\"ClientScopes\");\n        /// <summary>\n        /// Gets or sets the client secret table configuration.\n        /// </summary>\n        /// <value>\n        /// The client secret.\n        /// </value>\n        public TableConfiguration ClientSecret { get; set; } = new TableConfiguration(\"ClientSecrets\");\n        /// <summary>\n        /// Gets or sets the client claim table configuration.\n        /// </summary>\n        /// <value>\n        /// The client claim.\n        /// </value>\n        public TableConfiguration ClientClaim { get; set; } = new TableConfiguration(\"ClientClaims\");\n        /// <summary>\n        /// Gets or sets the client IdP restriction table configuration.\n        /// </summary>\n        /// <value>\n        /// The client IdP restriction.\n        /// </value>\n        public TableConfiguration ClientIdPRestriction { get; set; } = new TableConfiguration(\"ClientIdPRestrictions\");\n        /// <summary>\n        /// Gets or sets the client cors origin table configuration.\n        /// </summary>\n        /// <value>\n        /// The client cors origin.\n        /// </value>\n        public TableConfiguration ClientCorsOrigin { get; set; } = new TableConfiguration(\"ClientCorsOrigins\");\n        /// <summary>\n        /// Gets or sets the client property table configuration.\n        /// </summary>\n        /// <value>\n        /// The client property.\n        /// </value>\n        public TableConfiguration ClientProperty { get; set; } = new TableConfiguration(\"ClientProperties\");\n\n        /// <summary>\n        /// Gets or sets the scope table configuration.\n        /// </summary>\n        /// <value>\n        /// The API resource.\n        /// </value>\n        public TableConfiguration ApiScope { get; set; } = new TableConfiguration(\"ApiScopes\");\n        /// <summary>\n        /// Gets or sets the scope claim table configuration.\n        /// </summary>\n        /// <value>\n        /// The API scope claim.\n        /// </value>\n        public TableConfiguration ApiScopeClaim { get; set; } = new TableConfiguration(\"ApiScopeClaims\");\n        /// <summary>\n        /// Gets or sets the API resource property table configuration.\n        /// </summary>\n        /// <value>\n        /// The client property.\n        /// </value>\n        public TableConfiguration ApiScopeProperty { get; set; } = new TableConfiguration(\"ApiScopeProperties\");\n\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Options/OperationalStoreOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Options\n{\n    /// <summary>\n    /// Options for configuring the operational context.\n    /// </summary>\n    public class OperationalStoreOptions\n    {\n        /// <summary>\n        /// Callback to configure the EF DbContext.\n        /// </summary>\n        /// <value>\n        /// The configure database context.\n        /// </value>\n        public Action<DbContextOptionsBuilder> ConfigureDbContext { get; set; }\n\n        /// <summary>\n        /// Callback in DI resolve the EF DbContextOptions. If set, ConfigureDbContext will not be used.\n        /// </summary>\n        /// <value>\n        /// The configure database context.\n        /// </value>\n        public Action<IServiceProvider, DbContextOptionsBuilder> ResolveDbContextOptions { get; set; }\n\n        /// <summary>\n        /// Gets or sets the default schema.\n        /// </summary>\n        /// <value>\n        /// The default schema.\n        /// </value>\n        public string DefaultSchema { get; set; } = null;\n\n        /// <summary>\n        /// Gets or sets the persisted grants table configuration.\n        /// </summary>\n        /// <value>\n        /// The persisted grants.\n        /// </value>\n        public TableConfiguration PersistedGrants { get; set; } = new TableConfiguration(\"PersistedGrants\");\n\n        /// <summary>\n        /// Gets or sets the device flow codes table configuration.\n        /// </summary>\n        /// <value>\n        /// The device flow codes.\n        /// </value>\n        public TableConfiguration DeviceFlowCodes { get; set; } = new TableConfiguration(\"DeviceCodes\");\n\n        /// <summary>\n        /// Gets or sets a value indicating whether stale entries will be automatically cleaned up from the database.\n        /// This is implemented by periodically connecting to the database (according to the TokenCleanupInterval) from the hosting application.\n        /// Defaults to false.\n        /// </summary>\n        /// <value>\n        ///   <c>true</c> if [enable token cleanup]; otherwise, <c>false</c>.\n        /// </value>\n        public bool EnableTokenCleanup { get; set; } = false;\n\n        /// <summary>\n        /// Gets or sets the token cleanup interval (in seconds). The default is 3600 (1 hour).\n        /// </summary>\n        /// <value>\n        /// The token cleanup interval.\n        /// </value>\n        public int TokenCleanupInterval { get; set; } = 3600;\n\n        /// <summary>\n        /// Gets or sets the number of records to remove at a time. Defaults to 100.\n        /// </summary>\n        /// <value>\n        /// The size of the token cleanup batch.\n        /// </value>\n        public int TokenCleanupBatchSize { get; set; } = 100;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Options/TableConfiguration.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework.Options\n{\n    /// <summary>\n    /// Class to control a table's name and schema.\n    /// </summary>\n    public class TableConfiguration\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"TableConfiguration\"/> class.\n        /// </summary>\n        /// <param name=\"name\">The name.</param>\n        public TableConfiguration(string name)\n        {\n            Name = name;\n        }\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"TableConfiguration\"/> class.\n        /// </summary>\n        /// <param name=\"name\">The name.</param>\n        /// <param name=\"schema\">The schema.</param>\n        public TableConfiguration(string name, string schema)\n        {\n            Name = name;\n            Schema = schema;\n        }\n\n        /// <summary>\n        /// Gets or sets the name.\n        /// </summary>\n        /// <value>\n        /// The name.\n        /// </value>\n        public string Name { get; set; }\n\n        /// <summary>\n        /// Gets or sets the schema.\n        /// </summary>\n        /// <value>\n        /// The schema.\n        /// </value>\n        public string Schema { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Properties/AssemblyInfo.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Runtime.CompilerServices;\n\n[assembly: InternalsVisibleTo(\"IdentityServer8.EntityFramework.UnitTests, PublicKey = 002400000480000094000000060200000024000052534131000400000100010057b24455efc2a317afb0644a2169c05644e439985c42cf4eb98706779651801add1da073da8b5e253e8d4335d59b3197bb941ebe943c63f7efbc3005c428f0d69b809e86bdc828fa431fae4b71005f26b52a26a3ee5cf0f6fdf744d4534a7a503683123f58e1082828b018245d2e40d8542f72a623c01490d73a5d3ff94a88c5\")]\n[assembly: InternalsVisibleTo(\"IdentityServer8.EntityFramework.IntegrationTests, PublicKey = 002400000480000094000000060200000024000052534131000400000100010057b24455efc2a317afb0644a2169c05644e439985c42cf4eb98706779651801add1da073da8b5e253e8d4335d59b3197bb941ebe943c63f7efbc3005c428f0d69b809e86bdc828fa431fae4b71005f26b52a26a3ee5cf0f6fdf744d4534a7a503683123f58e1082828b018245d2e40d8542f72a623c01490d73a5d3ff94a88c5\")]\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Stores/ClientStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\n\nnamespace IdentityServer8.EntityFramework.Stores\n{\n    /// <summary>\n    /// Implementation of IClientStore thats uses EF.\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Stores.IClientStore\" />\n    public class ClientStore : IClientStore\n    {\n        /// <summary>\n        /// The DbContext.\n        /// </summary>\n        protected readonly IConfigurationDbContext Context;\n\n        /// <summary>\n        /// The logger.\n        /// </summary>\n        protected readonly ILogger<ClientStore> Logger;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ClientStore\"/> class.\n        /// </summary>\n        /// <param name=\"context\">The context.</param>\n        /// <param name=\"logger\">The logger.</param>\n        /// <exception cref=\"ArgumentNullException\">context</exception>\n        public ClientStore(IConfigurationDbContext context, ILogger<ClientStore> logger)\n        {\n            Context = context ?? throw new ArgumentNullException(nameof(context));\n            Logger = logger;\n        }\n\n        /// <summary>\n        /// Finds a client by id\n        /// </summary>\n        /// <param name=\"clientId\">The client id</param>\n        /// <returns>\n        /// The client\n        /// </returns>\n        public virtual async Task<Client> FindClientByIdAsync(string clientId)\n        {\n            IQueryable<Entities.Client> baseQuery = Context.Clients\n                .Where(x => x.ClientId == clientId);\n\n            var client = (await baseQuery.ToArrayAsync())\n                .SingleOrDefault(x => x.ClientId == clientId);\n            if (client == null) return null;\n\n            await baseQuery.Include(x => x.AllowedCorsOrigins).SelectMany(c => c.AllowedCorsOrigins).LoadAsync();\n            await baseQuery.Include(x => x.AllowedGrantTypes).SelectMany(c => c.AllowedGrantTypes).LoadAsync();\n            await baseQuery.Include(x => x.AllowedScopes).SelectMany(c => c.AllowedScopes).LoadAsync();\n            await baseQuery.Include(x => x.Claims).SelectMany(c => c.Claims).LoadAsync();\n            await baseQuery.Include(x => x.ClientSecrets).SelectMany(c => c.ClientSecrets).LoadAsync();\n            await baseQuery.Include(x => x.IdentityProviderRestrictions).SelectMany(c => c.IdentityProviderRestrictions).LoadAsync();\n            await baseQuery.Include(x => x.PostLogoutRedirectUris).SelectMany(c => c.PostLogoutRedirectUris).LoadAsync();\n            await baseQuery.Include(x => x.Properties).SelectMany(c => c.Properties).LoadAsync();\n            await baseQuery.Include(x => x.RedirectUris).SelectMany(c => c.RedirectUris).LoadAsync();\n\n            var model = client.ToModel();\n\n            Logger.LogDebug(\"{clientId} found in database: {clientIdFound}\", Ioc.Sanitizer.Log.Sanitize(clientId), model != null);\n\n            return model;\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Stores/DeviceFlowStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer8.EntityFramework.Stores\n{\n    /// <summary>\n    /// Implementation of IDeviceFlowStore thats uses EF.\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Stores.IDeviceFlowStore\" />\n    public class DeviceFlowStore : IDeviceFlowStore\n    {\n        /// <summary>\n        /// The DbContext.\n        /// </summary>\n        protected readonly IPersistedGrantDbContext Context;\n\n        /// <summary>\n        ///  The serializer.\n        /// </summary>\n        protected readonly IPersistentGrantSerializer Serializer;\n\n        /// <summary>\n        /// The logger.\n        /// </summary>\n        protected readonly ILogger Logger;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"DeviceFlowStore\"/> class.\n        /// </summary>\n        /// <param name=\"context\">The context.</param>\n        /// <param name=\"serializer\">The serializer</param>\n        /// <param name=\"logger\">The logger.</param>\n        public DeviceFlowStore(\n            IPersistedGrantDbContext context, \n            IPersistentGrantSerializer serializer, \n            ILogger<DeviceFlowStore> logger)\n        {\n            Context = context;\n            Serializer = serializer;\n            Logger = logger;\n        }\n\n        /// <summary>\n        /// Stores the device authorization request.\n        /// </summary>\n        /// <param name=\"deviceCode\">The device code.</param>\n        /// <param name=\"userCode\">The user code.</param>\n        /// <param name=\"data\">The data.</param>\n        /// <returns></returns>\n        public virtual async Task StoreDeviceAuthorizationAsync(string deviceCode, string userCode, DeviceCode data)\n        {\n            Context.DeviceFlowCodes.Add(ToEntity(data, deviceCode, userCode));\n\n            await Context.SaveChangesAsync();\n        }\n\n        /// <summary>\n        /// Finds device authorization by user code.\n        /// </summary>\n        /// <param name=\"userCode\">The user code.</param>\n        /// <returns></returns>\n        public virtual async Task<DeviceCode> FindByUserCodeAsync(string userCode)\n        {\n            var deviceFlowCodes = (await Context.DeviceFlowCodes.AsNoTracking().Where(x => x.UserCode == userCode).ToArrayAsync())\n                .SingleOrDefault(x => x.UserCode == userCode);\n            var model = ToModel(deviceFlowCodes?.Data);\n\n            Logger.LogDebug(\"{userCode} found in database: {userCodeFound}\", userCode, model != null);\n\n            return model;\n        }\n\n        /// <summary>\n        /// Finds device authorization by device code.\n        /// </summary>\n        /// <param name=\"deviceCode\">The device code.</param>\n        /// <returns></returns>\n        public virtual async Task<DeviceCode> FindByDeviceCodeAsync(string deviceCode)\n        {\n            var deviceFlowCodes = (await Context.DeviceFlowCodes.AsNoTracking().Where(x => x.DeviceCode == deviceCode).ToArrayAsync())\n                .SingleOrDefault(x => x.DeviceCode == deviceCode);\n            var model = ToModel(deviceFlowCodes?.Data);\n\n            Logger.LogDebug(\"{deviceCode} found in database: {deviceCodeFound}\", deviceCode, model != null);\n\n            return model;\n        }\n\n        /// <summary>\n        /// Updates device authorization, searching by user code.\n        /// </summary>\n        /// <param name=\"userCode\">The user code.</param>\n        /// <param name=\"data\">The data.</param>\n        /// <returns></returns>\n        public virtual async Task UpdateByUserCodeAsync(string userCode, DeviceCode data)\n        {\n            var existing = (await Context.DeviceFlowCodes.Where(x => x.UserCode == userCode).ToArrayAsync())\n                .SingleOrDefault(x => x.UserCode == userCode);\n            if (existing == null)\n            {\n                Logger.LogError(\"{userCode} not found in database\", userCode);\n                throw new InvalidOperationException(\"Could not update device code\");\n            }\n\n            var entity = ToEntity(data, existing.DeviceCode, userCode);\n            Logger.LogDebug(\"{userCode} found in database\", userCode);\n\n            existing.SubjectId = data.Subject?.FindFirst(JwtClaimTypes.Subject).Value;\n            existing.Data = entity.Data;\n\n            try\n            {\n                await Context.SaveChangesAsync();\n            }\n            catch (DbUpdateConcurrencyException ex)\n            {\n                Logger.LogWarning(\"exception updating {userCode} user code in database: {error}\", userCode, ex.Message);\n            }\n        }\n\n        /// <summary>\n        /// Removes the device authorization, searching by device code.\n        /// </summary>\n        /// <param name=\"deviceCode\">The device code.</param>\n        /// <returns></returns>\n        public virtual async Task RemoveByDeviceCodeAsync(string deviceCode)\n        {\n            var deviceFlowCodes = (await Context.DeviceFlowCodes.Where(x => x.DeviceCode == deviceCode).ToArrayAsync())\n                .SingleOrDefault(x => x.DeviceCode == deviceCode);\n\n            if(deviceFlowCodes != null)\n            {\n                Logger.LogDebug(\"removing {deviceCode} device code from database\", deviceCode);\n\n                Context.DeviceFlowCodes.Remove(deviceFlowCodes);\n\n                try\n                {\n                    await Context.SaveChangesAsync();\n                }\n                catch (DbUpdateConcurrencyException ex)\n                {\n                    Logger.LogInformation(\"exception removing {deviceCode} device code from database: {error}\", deviceCode, ex.Message);\n                }\n            }\n            else\n            {\n                Logger.LogDebug(\"no {deviceCode} device code found in database\", deviceCode);\n            }\n        }\n\n        /// <summary>\n        /// Converts a model to an entity.\n        /// </summary>\n        /// <param name=\"model\"></param>\n        /// <param name=\"deviceCode\"></param>\n        /// <param name=\"userCode\"></param>\n        /// <returns></returns>\n        protected DeviceFlowCodes ToEntity(DeviceCode model, string deviceCode, string userCode)\n        {\n            if (model == null || deviceCode == null || userCode == null) return null;\n\n            return new DeviceFlowCodes\n            {\n                DeviceCode = deviceCode,\n                UserCode = userCode,\n                ClientId = model.ClientId,\n                SubjectId = model.Subject?.FindFirst(JwtClaimTypes.Subject).Value,\n                CreationTime = model.CreationTime,\n                Expiration = model.CreationTime.AddSeconds(model.Lifetime),\n                Data = Serializer.Serialize(model)\n            };\n        }\n\n        /// <summary>\n        /// Converts a serialized DeviceCode to a model.\n        /// </summary>\n        /// <param name=\"entity\"></param>\n        /// <returns></returns>\n        protected DeviceCode ToModel(string entity)\n        {\n            if (entity == null) return null;\n\n            return Serializer.Deserialize<DeviceCode>(entity);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Stores/PersistedGrantStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\n\nnamespace IdentityServer8.EntityFramework.Stores\n{\n    /// <summary>\n    /// Implementation of IPersistedGrantStore thats uses EF.\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Stores.IPersistedGrantStore\" />\n    public class PersistedGrantStore : IPersistedGrantStore\n    {\n        /// <summary>\n        /// The DbContext.\n        /// </summary>\n        protected readonly IPersistedGrantDbContext Context;\n\n        /// <summary>\n        /// The logger.\n        /// </summary>\n        protected readonly ILogger Logger;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"PersistedGrantStore\"/> class.\n        /// </summary>\n        /// <param name=\"context\">The context.</param>\n        /// <param name=\"logger\">The logger.</param>\n        public PersistedGrantStore(IPersistedGrantDbContext context, ILogger<PersistedGrantStore> logger)\n        {\n            Context = context;\n            Logger = logger;\n        }\n\n        /// <inheritdoc/>\n        public virtual async Task StoreAsync(PersistedGrant token)\n        {\n            var existing = (await Context.PersistedGrants.Where(x => x.Key == token.Key).ToArrayAsync())\n                .SingleOrDefault(x => x.Key == token.Key);\n            if (existing == null)\n            {\n                Logger.LogDebug(\"{persistedGrantKey} not found in database\", token.Key);\n\n                var persistedGrant = token.ToEntity();\n                Context.PersistedGrants.Add(persistedGrant);\n            }\n            else\n            {\n                Logger.LogDebug(\"{persistedGrantKey} found in database\", token.Key);\n\n                token.UpdateEntity(existing);\n            }\n\n            try\n            {\n                await Context.SaveChangesAsync();\n            }\n            catch (DbUpdateConcurrencyException ex)\n            {\n                Logger.LogWarning(\"exception updating {persistedGrantKey} persisted grant in database: {error}\", token.Key, ex.Message);\n            }\n        }\n\n        /// <inheritdoc/>\n        public virtual async Task<PersistedGrant> GetAsync(string key)\n        {\n            var persistedGrant = (await Context.PersistedGrants.AsNoTracking().Where(x => x.Key == key).ToArrayAsync())\n                .SingleOrDefault(x => x.Key == key);\n            var model = persistedGrant?.ToModel();\n\n            Logger.LogDebug(\"{persistedGrantKey} found in database: {persistedGrantKeyFound}\", key, model != null);\n\n            return model;\n        }\n\n        /// <inheritdoc/>\n        public async Task<IEnumerable<PersistedGrant>> GetAllAsync(PersistedGrantFilter filter)\n        {\n            filter.Validate();\n\n            var persistedGrants = await Filter(Context.PersistedGrants.AsQueryable(), filter).ToArrayAsync();\n            persistedGrants = Filter(persistedGrants.AsQueryable(), filter).ToArray();\n            \n            var model = persistedGrants.Select(x => x.ToModel());\n\n            Logger.LogDebug(\"{persistedGrantCount} persisted grants found for {@filter}\", persistedGrants.Length, filter);\n\n            return model;\n        }\n\n        /// <inheritdoc/>\n        public virtual async Task RemoveAsync(string key)\n        {\n            var persistedGrant = (await Context.PersistedGrants.Where(x => x.Key == key).ToArrayAsync())\n                .SingleOrDefault(x => x.Key == key);\n            if (persistedGrant!= null)\n            {\n                Logger.LogDebug(\"removing {persistedGrantKey} persisted grant from database\", key);\n\n                Context.PersistedGrants.Remove(persistedGrant);\n\n                try\n                {\n                    await Context.SaveChangesAsync();\n                }\n                catch(DbUpdateConcurrencyException ex)\n                {\n                    Logger.LogInformation(\"exception removing {persistedGrantKey} persisted grant from database: {error}\", key, ex.Message);\n                }\n            }\n            else\n            {\n                Logger.LogDebug(\"no {persistedGrantKey} persisted grant found in database\", key);\n            }\n        }\n\n        /// <inheritdoc/>\n        public async Task RemoveAllAsync(PersistedGrantFilter filter)\n        {\n            filter.Validate();\n\n            var persistedGrants = await Filter(Context.PersistedGrants.AsQueryable(), filter).ToArrayAsync();\n            persistedGrants = Filter(persistedGrants.AsQueryable(), filter).ToArray();\n\n            Logger.LogDebug(\"removing {persistedGrantCount} persisted grants from database for {@filter}\", persistedGrants.Length, filter);\n\n            Context.PersistedGrants.RemoveRange(persistedGrants);\n\n            try\n            {\n                await Context.SaveChangesAsync();\n            }\n            catch (DbUpdateConcurrencyException ex)\n            {\n                Logger.LogInformation(\"removing {persistedGrantCount} persisted grants from database for subject {@filter}: {error}\", persistedGrants.Length, filter, ex.Message);\n            }\n        }\n\n\n        private IQueryable<Entities.PersistedGrant> Filter(IQueryable<Entities.PersistedGrant> query, PersistedGrantFilter filter)\n        {\n            if (!String.IsNullOrWhiteSpace(filter.ClientId))\n            {\n                query = query.Where(x => x.ClientId == filter.ClientId);\n            }\n            if (!String.IsNullOrWhiteSpace(filter.SessionId))\n            {\n                query = query.Where(x => x.SessionId == filter.SessionId);\n            }\n            if (!String.IsNullOrWhiteSpace(filter.SubjectId))\n            {\n                query = query.Where(x => x.SubjectId == filter.SubjectId);\n            }\n            if (!String.IsNullOrWhiteSpace(filter.Type))\n            {\n                query = query.Where(x => x.Type == filter.Type);\n            }\n\n            return query;\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/Stores/ResourceStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\n\nnamespace IdentityServer8.EntityFramework.Stores\n{\n    /// <summary>\n    /// Implementation of IResourceStore thats uses EF.\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Stores.IResourceStore\" />\n    public class ResourceStore : IResourceStore\n    {\n        /// <summary>\n        /// The DbContext.\n        /// </summary>\n        protected readonly IConfigurationDbContext Context;\n        \n        /// <summary>\n        /// The logger.\n        /// </summary>\n        protected readonly ILogger<ResourceStore> Logger;\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"ResourceStore\"/> class.\n        /// </summary>\n        /// <param name=\"context\">The context.</param>\n        /// <param name=\"logger\">The logger.</param>\n        /// <exception cref=\"ArgumentNullException\">context</exception>\n        public ResourceStore(IConfigurationDbContext context, ILogger<ResourceStore> logger)\n        {\n            Context = context ?? throw new ArgumentNullException(nameof(context));\n            Logger = logger;\n        }\n\n        /// <summary>\n        /// Finds the API resources by name.\n        /// </summary>\n        /// <param name=\"apiResourceNames\">The names.</param>\n        /// <returns></returns>\n        public virtual async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)\n        {\n            if (apiResourceNames == null) throw new ArgumentNullException(nameof(apiResourceNames));\n\n            var query =\n                from apiResource in Context.ApiResources\n                where apiResourceNames.Contains(apiResource.Name)\n                select apiResource;\n            \n            var apis = query\n                .Include(x => x.Secrets)\n                .Include(x => x.Scopes)\n                .Include(x => x.UserClaims)\n                .Include(x => x.Properties)\n                .AsNoTracking();\n\n            var result = (await apis.ToArrayAsync())\n                .Where(x => apiResourceNames.Contains(x.Name))\n                .Select(x => x.ToModel()).ToArray();\n\n            if (result.Any())\n            {\n                Logger.LogDebug(\"Found {apis} API resource in database\", result.Select(x => x.Name));\n            }\n            else\n            {\n                Logger.LogDebug(\"Did not find {apis} API resource in database\", apiResourceNames);\n            }\n\n            return result;\n        }\n\n        /// <summary>\n        /// Gets API resources by scope name.\n        /// </summary>\n        /// <param name=\"scopeNames\"></param>\n        /// <returns></returns>\n        public virtual async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)\n        {\n            var names = scopeNames.ToArray();\n\n            var query =\n                from api in Context.ApiResources\n                where api.Scopes.Where(x => names.Contains(x.Scope)).Any()\n                select api;\n\n            var apis = query\n                .Include(x => x.Secrets)\n                .Include(x => x.Scopes)\n                .Include(x => x.UserClaims)\n                .Include(x => x.Properties)\n                .AsNoTracking();\n\n            var results = (await apis.ToArrayAsync())\n                .Where(api => api.Scopes.Any(x => names.Contains(x.Scope)));\n            var models = results.Select(x => x.ToModel()).ToArray();\n\n            Logger.LogDebug(\"Found {apis} API resources in database\", models.Select(x => x.Name));\n\n            return models;\n        }\n\n        /// <summary>\n        /// Gets identity resources by scope name.\n        /// </summary>\n        /// <param name=\"scopeNames\"></param>\n        /// <returns></returns>\n        public virtual async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)\n        {\n            var scopes = scopeNames.ToArray();\n\n            var query =\n                from identityResource in Context.IdentityResources\n                where scopes.Contains(identityResource.Name)\n                select identityResource;\n\n            var resources = query\n                .Include(x => x.UserClaims)\n                .Include(x => x.Properties)\n                .AsNoTracking();\n\n            var results = (await resources.ToArrayAsync())\n                .Where(x => scopes.Contains(x.Name));\n\n            Logger.LogDebug(\"Found {scopes} identity scopes in database\", results.Select(x => x.Name));\n\n            return results.Select(x => x.ToModel()).ToArray();\n        }\n\n        /// <summary>\n        /// Gets scopes by scope name.\n        /// </summary>\n        /// <param name=\"scopeNames\"></param>\n        /// <returns></returns>\n        public virtual async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)\n        {\n            var scopes = scopeNames.ToArray();\n\n            var query =\n                from scope in Context.ApiScopes\n                where scopes.Contains(scope.Name)\n                select scope;\n\n            var resources = query\n                .Include(x => x.UserClaims)\n                .Include(x => x.Properties)\n                .AsNoTracking();\n\n            var results = (await resources.ToArrayAsync())\n                .Where(x => scopes.Contains(x.Name));\n\n            Logger.LogDebug(\"Found {scopes} scopes in database\", results.Select(x => x.Name));\n\n            return results.Select(x => x.ToModel()).ToArray();\n        }\n\n        /// <summary>\n        /// Gets all resources.\n        /// </summary>\n        /// <returns></returns>\n        public virtual async Task<Resources> GetAllResourcesAsync()\n        {\n            var identity = Context.IdentityResources\n              .Include(x => x.UserClaims)\n              .Include(x => x.Properties);\n\n            var apis = Context.ApiResources\n                .Include(x => x.Secrets)\n                .Include(x => x.Scopes)\n                .Include(x => x.UserClaims)\n                .Include(x => x.Properties)\n                .AsNoTracking();\n            \n            var scopes = Context.ApiScopes\n                .Include(x => x.UserClaims)\n                .Include(x => x.Properties)\n                .AsNoTracking();\n\n            var result = new Resources(\n                (await identity.ToArrayAsync()).Select(x => x.ToModel()),\n                (await apis.ToArrayAsync()).Select(x => x.ToModel()),\n                (await scopes.ToArrayAsync()).Select(x => x.ToModel())\n            );\n\n            Logger.LogDebug(\"Found {scopes} as all scopes, and {apis} as API resources\", \n                result.IdentityResources.Select(x=>x.Name).Union(result.ApiScopes.Select(x=>x.Name)),\n                result.ApiResources.Select(x=>x.Name));\n\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/TokenCleanup/IOperationalStoreNotification.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Entities;\n\nnamespace IdentityServer8.EntityFramework\n{\n    /// <summary>\n    /// Interface to model notifications from the TokenCleanup feature.\n    /// </summary>\n    public interface IOperationalStoreNotification\n    {\n        /// <summary>\n        /// Notification for persisted grants being removed.\n        /// </summary>\n        /// <param name=\"persistedGrants\"></param>\n        /// <returns></returns>\n        Task PersistedGrantsRemovedAsync(IEnumerable<PersistedGrant> persistedGrants);\n\n        /// <summary>\n        /// Notification for device codes being removed.\n        /// </summary>\n        /// <param name=\"deviceCodes\"></param>\n        /// <returns></returns>\n        Task DeviceCodesRemovedAsync(IEnumerable<DeviceFlowCodes> deviceCodes);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/src/TokenCleanup/TokenCleanupService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.EntityFramework\n{\n    /// <summary>\n    /// Helper to cleanup stale persisted grants and device codes.\n    /// </summary>\n    public class TokenCleanupService\n    {\n        private readonly OperationalStoreOptions _options;\n        private readonly IPersistedGrantDbContext _persistedGrantDbContext;\n        private readonly IOperationalStoreNotification _operationalStoreNotification;\n        private readonly ILogger<TokenCleanupService> _logger;\n\n        /// <summary>\n        /// Constructor for TokenCleanupService.\n        /// </summary>\n        /// <param name=\"options\"></param>\n        /// <param name=\"persistedGrantDbContext\"></param>\n        /// <param name=\"operationalStoreNotification\"></param>\n        /// <param name=\"logger\"></param>\n        public TokenCleanupService(\n            OperationalStoreOptions options,\n            IPersistedGrantDbContext persistedGrantDbContext, \n            ILogger<TokenCleanupService> logger,\n            IOperationalStoreNotification operationalStoreNotification = null)\n        {\n            _options = options ?? throw new ArgumentNullException(nameof(options));\n            if (_options.TokenCleanupBatchSize < 1) throw new ArgumentException(\"Token cleanup batch size interval must be at least 1\");\n\n            _persistedGrantDbContext = persistedGrantDbContext ?? throw new ArgumentNullException(nameof(persistedGrantDbContext));\n            _logger = logger ?? throw new ArgumentNullException(nameof(logger));\n\n            _operationalStoreNotification = operationalStoreNotification;\n        }\n\n        /// <summary>\n        /// Method to clear expired persisted grants.\n        /// </summary>\n        /// <returns></returns>\n        public async Task RemoveExpiredGrantsAsync()\n        {\n            try\n            {\n                _logger.LogTrace(\"Querying for expired grants to remove\");\n\n                await RemoveGrantsAsync();\n                await RemoveDeviceCodesAsync();\n            }\n            catch (Exception ex)\n            {\n                _logger.LogError(\"Exception removing expired grants: {exception}\", ex.Message);\n            }\n        }\n\n        /// <summary>\n        /// Removes the stale persisted grants.\n        /// </summary>\n        /// <returns></returns>\n        protected virtual async Task RemoveGrantsAsync()\n        {\n            var found = Int32.MaxValue;\n            \n            while (found >= _options.TokenCleanupBatchSize)\n            {\n                var expiredGrants = await _persistedGrantDbContext.PersistedGrants\n                    .Where(x => x.Expiration < DateTime.UtcNow)\n                    .OrderBy(x => x.Expiration)\n                    .Take(_options.TokenCleanupBatchSize)\n                    .ToArrayAsync();\n\n                found = expiredGrants.Length;\n                _logger.LogInformation(\"Removing {grantCount} grants\", found);\n\n                if (found > 0)\n                {\n                    _persistedGrantDbContext.PersistedGrants.RemoveRange(expiredGrants);\n                    await SaveChangesAsync();\n\n                    if (_operationalStoreNotification != null)\n                    {\n                        await _operationalStoreNotification.PersistedGrantsRemovedAsync(expiredGrants);\n                    }\n                }\n            }\n        }\n\n\n        /// <summary>\n        /// Removes the stale device codes.\n        /// </summary>\n        /// <returns></returns>\n        protected virtual async Task RemoveDeviceCodesAsync()\n        {\n            var found = Int32.MaxValue;\n\n            while (found >= _options.TokenCleanupBatchSize)\n            {\n                var expiredCodes = await _persistedGrantDbContext.DeviceFlowCodes\n                    .Where(x => x.Expiration < DateTime.UtcNow)\n                    .OrderBy(x => x.Expiration)\n                    .Take(_options.TokenCleanupBatchSize)\n                    .ToArrayAsync();\n\n                found = expiredCodes.Length;\n                _logger.LogInformation(\"Removing {deviceCodeCount} device flow codes\", found);\n\n                if (found > 0)\n                {\n                    _persistedGrantDbContext.DeviceFlowCodes.RemoveRange(expiredCodes);\n                    await SaveChangesAsync();\n\n                    if (_operationalStoreNotification != null)\n                    {\n                        await _operationalStoreNotification.DeviceCodesRemovedAsync(expiredCodes);\n                    }\n                }\n            }\n        }\n\n        private async Task SaveChangesAsync()\n        {\n            var count = 3;\n\n            while (count > 0)\n            {\n                try\n                {\n                    await _persistedGrantDbContext.SaveChangesAsync();\n                    return;\n                }\n                catch (DbUpdateConcurrencyException ex)\n                {\n                    count--;\n\n                    // we get this if/when someone else already deleted the records\n                    // we want to essentially ignore this, and keep working\n                    _logger.LogDebug(\"Concurrency exception removing expired grants: {exception}\", ex.Message);\n\n                    foreach (var entry in ex.Entries)\n                    {\n                        // mark this entry as not attached anymore so we don't try to re-delete\n                        entry.State = EntityState.Detached;\n                    }\n                }\n            }\n\n            _logger.LogDebug(\"Too many concurrency exceptions. Exiting.\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/DatabaseProviderBuilder.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\n/// <summary>\n/// Helper methods to initialize DbContextOptions for the specified database provider and context.\n/// </summary>\npublic class DatabaseProviderBuilder\n{\n    public static DbContextOptions<T> BuildInMemory<T>(string name) where T : DbContext\n    {\n        var builder = new DbContextOptionsBuilder<T>();\n        builder.UseInMemoryDatabase(name);\n        return builder.Options;\n    }\n\n    public static DbContextOptions<T> BuildSqlite<T>(string name) where T : DbContext\n    {\n        var builder = new DbContextOptionsBuilder<T>();\n        builder.UseSqlite($\"Filename=./Test.IdentityServer8.EntityFramework-3.1.0.{name}.db\");\n        return builder.Options;\n    }\n\n    public static DbContextOptions<T> BuildLocalDb<T>(string name) where T : DbContext\n    {\n        var builder = new DbContextOptionsBuilder<T>();\n        builder.UseSqlServer(\n            $@\"Data Source=(LocalDb)\\MSSQLLocalDB;database=Test.IdentityServer8.EntityFramework-3.1.0.{name};trusted_connection=yes;\");\n        return builder.Options;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/DatabaseProviderFixture.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\n/// <summary>\n/// xUnit ClassFixture for creating and deleting integration test databases.\n/// </summary>\n/// <typeparam name=\"T\">DbContext of Type T</typeparam>\npublic class DatabaseProviderFixture<T> : IDisposable where T : DbContext\n{\n    public object StoreOptions;\n    public List<DbContextOptions<T>> Options;\n\n    public void Dispose()\n    {\n        if (Options != null) // null check since fixtures are created even when tests are skipped\n        {\n            foreach (var option in Options.ToList())\n            {\n                using (var context = (T)Activator.CreateInstance(typeof(T), option, StoreOptions))\n                {\n                    context.Database.EnsureDeleted();\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/DbContexts/ClientDbContextTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.DbContexts;\nusing Microsoft.EntityFrameworkCore;\nusing System.Linq;\nusing IdentityServer8.EntityFramework.Entities;\nusing IdentityServer8.EntityFramework.Options;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests.DbContexts;\n\npublic class ClientDbContextTests : IntegrationTest<ClientDbContextTests, ConfigurationDbContext, ConfigurationStoreOptions>\n{\n    public ClientDbContextTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)\n    {\n        foreach (var options in TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<ConfigurationDbContext>)y)).ToList())\n        {\n            using (var context = new ConfigurationDbContext(options, StoreOptions))\n                context.Database.EnsureCreated();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public void CanAddAndDeleteClientScopes(DbContextOptions<ConfigurationDbContext> options)\n    {\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            db.Clients.Add(new Client\n            {\n                ClientId = \"test-client-scopes\",\n                ClientName = \"Test Client\"\n            });\n\n            db.SaveChanges();\n        }\n\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            // explicit include due to lack of EF Core lazy loading\n            var client = db.Clients.Include(x => x.AllowedScopes).First();\n\n            client.AllowedScopes.Add(new ClientScope\n            {\n                Scope = \"test\"\n            });\n\n            db.SaveChanges();\n        }\n\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var client = db.Clients.Include(x => x.AllowedScopes).First();\n            var scope = client.AllowedScopes.First();\n\n            client.AllowedScopes.Remove(scope);\n\n            db.SaveChanges();\n        }\n\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var client = db.Clients.Include(x => x.AllowedScopes).First();\n\n            Assert.Empty(client.AllowedScopes);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public void CanAddAndDeleteClientRedirectUri(DbContextOptions<ConfigurationDbContext> options)\n    {\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            db.Clients.Add(new Client\n            {\n                ClientId = \"test-client\",\n                ClientName = \"Test Client\"\n            });\n\n            db.SaveChanges();\n        }\n\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var client = db.Clients.Include(x => x.RedirectUris).First();\n\n            client.RedirectUris.Add(new ClientRedirectUri\n            {\n                RedirectUri = \"https://redirect-uri-1\"\n            });\n\n            db.SaveChanges();\n        }\n\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var client = db.Clients.Include(x => x.RedirectUris).First();\n            var redirectUri = client.RedirectUris.First();\n\n            client.RedirectUris.Remove(redirectUri);\n\n            db.SaveChanges();\n        }\n\n        using (var db = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var client = db.Clients.Include(x => x.RedirectUris).First();\n\n            Assert.Empty(client.RedirectUris);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/FakeLogger.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\npublic class FakeLogger<T> : FakeLogger, ILogger<T>\n{\n    public static ILogger<T> Create()\n    {\n        return new FakeLogger<T>();\n    }\n}\n\npublic class FakeLogger : ILogger, IDisposable\n{\n    public IDisposable BeginScope<TState>(TState state)\n    {\n        return this;\n    }\n\n    public void Dispose()\n    {\n    }\n\n    public bool IsEnabled(LogLevel logLevel)\n    {\n        return false;\n    }\n\n    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)\n    {\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/IdentityServer8.EntityFramework.IntegrationTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n\n    <AssemblyOriginatorKeyFile>../../../../key.snk</AssemblyOriginatorKeyFile>\n    <SignAssembly>true</SignAssembly>\n    <PublicSign Condition=\"'$(OS)' != 'Windows_NT'\">true</PublicSign>\n  </PropertyGroup>\n\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\..\\IdentityServer8\\src\\IdentityServer8.csproj\" />\n    <ProjectReference Include=\"..\\..\\..\\Storage\\src\\IdentityServer8.Storage.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.EntityFramework.Storage.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" />\n    <PackageReference Include=\"FluentAssertions\" />\n    <PackageReference Include=\"coverlet.collector\" GeneratePathProperty=\"true\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Sqlite\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.InMemory\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/IntegrationTest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.Configuration;\nusing System.Runtime.InteropServices;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests;\n\n/// <summary>\n/// Base class for integration tests, responsible for initializing test database providers & an xUnit class fixture\n/// </summary>\n/// <typeparam name=\"TClass\">The type of the class.</typeparam>\n/// <typeparam name=\"TDbContext\">The type of the database context.</typeparam>\n/// <typeparam name=\"TStoreOption\">The type of the store option.</typeparam>\n/// <seealso cref=\"DatabaseProviderFixture{T}\" />\npublic class IntegrationTest<TClass, TDbContext, TStoreOption> : IClassFixture<DatabaseProviderFixture<TDbContext>>\n    where TDbContext : DbContext\n{\n    public static readonly TheoryData<DbContextOptions<TDbContext>> TestDatabaseProviders;\n    protected readonly TStoreOption StoreOptions = Activator.CreateInstance<TStoreOption>();\n\n    static IntegrationTest()\n    {\n        var config = new ConfigurationBuilder()\n            .AddEnvironmentVariables()\n            .Build();\n\n        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))\n        {\n            Console.WriteLine($\"Running Local Tests for {typeof(TClass).Name}\");\n\n            TestDatabaseProviders = new TheoryData<DbContextOptions<TDbContext>>\n            {\n                DatabaseProviderBuilder.BuildInMemory<TDbContext>(typeof(TClass).Name),\n                //DatabaseProviderBuilder.BuildSqlite<TDbContext>(typeof(TClass).Name),\n                //DatabaseProviderBuilder.BuildLocalDb<TDbContext>(typeof(TClass).Name)\n            };\n        }\n        else\n        {\n            TestDatabaseProviders = new TheoryData<DbContextOptions<TDbContext>>\n            {\n                DatabaseProviderBuilder.BuildInMemory<TDbContext>(typeof(TClass).Name),\n                DatabaseProviderBuilder.BuildSqlite<TDbContext>(typeof(TClass).Name)\n            };\n            Console.WriteLine(\"Skipping DB integration tests on non-Windows\");\n        }\n    }\n\n    protected IntegrationTest(DatabaseProviderFixture<TDbContext> fixture)\n    {\n        fixture.Options = TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<TDbContext>)y)).ToList();\n        fixture.StoreOptions = StoreOptions;\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/Stores/ClientStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServer8.EntityFramework.Options;\nusing IdentityServer8.EntityFramework.Stores;\nusing IdentityServer8.Models;\nusing Microsoft.EntityFrameworkCore;\nusing Xunit;\nusing Xunit.Sdk;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests.Stores;\n\npublic class ClientStoreTests : IntegrationTest<ClientStoreTests, ConfigurationDbContext, ConfigurationStoreOptions>\n{\n    public ClientStoreTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)\n    {\n        foreach (var options in TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<ConfigurationDbContext>) y)).ToList())\n        {\n            using (var context = new ConfigurationDbContext(options, StoreOptions))\n            {\n                context.Database.EnsureCreated();\n            }\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindClientByIdAsync_WhenClientDoesNotExist_ExpectNull(DbContextOptions<ConfigurationDbContext> options)\n    {\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ClientStore(context, FakeLogger<ClientStore>.Create());\n            var client = await store.FindClientByIdAsync(Guid.NewGuid().ToString());\n            client.Should().BeNull();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindClientByIdAsync_WhenClientExists_ExpectClientRetured(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var testClient = new Client\n        {\n            ClientId = \"test_client\",\n            ClientName = \"Test Client\"\n        };\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.Clients.Add(testClient.ToEntity());\n            context.SaveChanges();\n        }\n\n        Client client;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ClientStore(context, FakeLogger<ClientStore>.Create());\n            client = await store.FindClientByIdAsync(testClient.ClientId);\n        }\n\n        client.Should().NotBeNull();\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindClientByIdAsync_WhenClientExistsWithCollections_ExpectClientReturnedCollections(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var testClient = new Client\n        {\n            ClientId = \"properties_test_client\",\n            ClientName = \"Properties Test Client\",\n            AllowedCorsOrigins = {\"https://localhost\"},\n            AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,\n            AllowedScopes = {\"openid\", \"profile\", \"api1\"},\n            Claims = {new ClientClaim(\"test\", \"value\")},\n            ClientSecrets = {new Secret(\"secret\".Sha256())},\n            IdentityProviderRestrictions = {\"AD\"},\n            PostLogoutRedirectUris = {\"https://locahost/signout-callback\"},\n            Properties = {{\"foo1\", \"bar1\"}, {\"foo2\", \"bar2\"},},\n            RedirectUris = {\"https://locahost/signin\"}\n        };\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.Clients.Add(testClient.ToEntity());\n            context.SaveChanges();\n        }\n\n        Client client;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ClientStore(context, FakeLogger<ClientStore>.Create());\n            client = await store.FindClientByIdAsync(testClient.ClientId);\n        }\n\n        client.Should().BeEquivalentTo(testClient);\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindClientByIdAsync_WhenClientsExistWithManyCollections_ExpectClientReturnedInUnderFiveSeconds(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var testClient = new Client\n        {\n            ClientId = \"test_client_with_uris\",\n            ClientName = \"Test client with URIs\",\n            AllowedScopes = {\"openid\", \"profile\", \"api1\"},\n            AllowedGrantTypes = GrantTypes.CodeAndClientCredentials\n        };\n\n        for (int i = 0; i < 50; i++)\n        {\n            testClient.RedirectUris.Add($\"https://localhost/{i}\");\n            testClient.PostLogoutRedirectUris.Add($\"https://localhost/{i}\");\n            testClient.AllowedCorsOrigins.Add($\"https://localhost:{i}\");\n        }\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.Clients.Add(testClient.ToEntity());\n\n            for (int i = 0; i < 50; i++)\n            {\n                context.Clients.Add(new Client\n                {\n                    ClientId = testClient.ClientId + i,\n                    ClientName = testClient.ClientName,\n                    AllowedScopes = testClient.AllowedScopes,\n                    AllowedGrantTypes = testClient.AllowedGrantTypes,\n                    RedirectUris = testClient.RedirectUris,\n                    PostLogoutRedirectUris = testClient.PostLogoutRedirectUris,\n                    AllowedCorsOrigins = testClient.AllowedCorsOrigins,\n                }.ToEntity());\n            }\n\n            context.SaveChanges();\n        }\n        \n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ClientStore(context, FakeLogger<ClientStore>.Create());\n\n            const int timeout = 5000;\n            var task = Task.Run(() => store.FindClientByIdAsync(testClient.ClientId));\n\n            if (await Task.WhenAny(task, Task.Delay(timeout)) == task)\n            {\n                var client = await task;\n                client.Should().BeEquivalentTo(testClient);\n            }\n            else\n            {\n                throw new TestTimeoutException(timeout);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/Stores/DeviceFlowStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Entities;\nusing IdentityServer8.EntityFramework.Options;\nusing IdentityServer8.EntityFramework.Stores;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores.Serialization;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.InMemory.Infrastructure.Internal;\nusing System.Security.Claims;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests.Stores;\n\npublic class DeviceFlowStoreTests : IntegrationTest<DeviceFlowStoreTests, PersistedGrantDbContext, OperationalStoreOptions>\n{\n    private readonly IPersistentGrantSerializer serializer = new PersistentGrantSerializer();\n\n    public DeviceFlowStoreTests(DatabaseProviderFixture<PersistedGrantDbContext> fixture) : base(fixture)\n    {\n        foreach (var options in TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<PersistedGrantDbContext>)y)).ToList())\n        {\n            using (var context = new PersistedGrantDbContext(options, StoreOptions))\n                context.Database.EnsureCreated();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task StoreDeviceAuthorizationAsync_WhenSuccessful_ExpectDeviceCodeAndUserCodeStored(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var deviceCode = Guid.NewGuid().ToString();\n        var userCode = Guid.NewGuid().ToString();\n        var data = new DeviceCode\n        {\n            ClientId = Guid.NewGuid().ToString(),\n            CreationTime = DateTime.UtcNow,\n            Lifetime = 300\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            await store.StoreDeviceAuthorizationAsync(deviceCode, userCode, data);\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundDeviceFlowCodes = context.DeviceFlowCodes.FirstOrDefault(x => x.DeviceCode == deviceCode);\n\n            foundDeviceFlowCodes.Should().NotBeNull();\n            foundDeviceFlowCodes?.DeviceCode.Should().Be(deviceCode);\n            foundDeviceFlowCodes?.UserCode.Should().Be(userCode);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task StoreDeviceAuthorizationAsync_WhenSuccessful_ExpectDataStored(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var deviceCode = Guid.NewGuid().ToString();\n        var userCode = Guid.NewGuid().ToString();\n        var data = new DeviceCode\n        {\n            ClientId = Guid.NewGuid().ToString(),\n            CreationTime = DateTime.UtcNow,\n            Lifetime = 300\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            await store.StoreDeviceAuthorizationAsync(deviceCode, userCode, data);\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundDeviceFlowCodes = context.DeviceFlowCodes.FirstOrDefault(x => x.DeviceCode == deviceCode);\n\n            foundDeviceFlowCodes.Should().NotBeNull();\n            var deserializedData = new PersistentGrantSerializer().Deserialize<DeviceCode>(foundDeviceFlowCodes?.Data);\n\n            deserializedData.CreationTime.Should().BeCloseTo(data.CreationTime, TimeSpan.FromMilliseconds(100));\n            deserializedData.ClientId.Should().Be(data.ClientId);\n            deserializedData.Lifetime.Should().Be(data.Lifetime);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task StoreDeviceAuthorizationAsync_WhenUserCodeAlreadyExists_ExpectException(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var existingUserCode = $\"user_{Guid.NewGuid().ToString()}\";\n        var deviceCodeData = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            RequestedScopes = new[] { \"openid\", \"api1\" },\n            CreationTime = new DateTime(2018, 10, 19, 16, 14, 29),\n            Lifetime = 300,\n            IsOpenId = true,\n            Subject = new ClaimsPrincipal(new ClaimsIdentity(\n                new List<Claim> { new Claim(JwtClaimTypes.Subject, $\"sub_{Guid.NewGuid().ToString()}\") }))\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(new DeviceFlowCodes\n            {\n                DeviceCode = $\"device_{Guid.NewGuid().ToString()}\",\n                UserCode = existingUserCode,\n                ClientId = deviceCodeData.ClientId,\n                SubjectId = deviceCodeData.Subject.FindFirst(JwtClaimTypes.Subject).Value,\n                CreationTime = deviceCodeData.CreationTime,\n                Expiration = deviceCodeData.CreationTime.AddSeconds(deviceCodeData.Lifetime),\n                Data = serializer.Serialize(deviceCodeData)\n            });\n            context.SaveChanges();\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n\n            // skip odd behaviour of in-memory provider\n            if (options.Extensions.All(x => x.GetType() != typeof(InMemoryOptionsExtension)))\n            {\n                await Assert.ThrowsAsync<DbUpdateException>(() =>\n                    store.StoreDeviceAuthorizationAsync($\"device_{Guid.NewGuid().ToString()}\", existingUserCode, deviceCodeData));\n            }\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task StoreDeviceAuthorizationAsync_WhenDeviceCodeAlreadyExists_ExpectException(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var existingDeviceCode = $\"device_{Guid.NewGuid().ToString()}\";\n        var deviceCodeData = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            RequestedScopes = new[] { \"openid\", \"api1\" },\n            CreationTime = new DateTime(2018, 10, 19, 16, 14, 29),\n            Lifetime = 300,\n            IsOpenId = true,\n            Subject = new ClaimsPrincipal(new ClaimsIdentity(\n                new List<Claim> { new Claim(JwtClaimTypes.Subject, $\"sub_{Guid.NewGuid().ToString()}\") }))\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(new DeviceFlowCodes\n            {\n                DeviceCode = existingDeviceCode,\n                UserCode = $\"user_{Guid.NewGuid().ToString()}\",\n                ClientId = deviceCodeData.ClientId,\n                SubjectId = deviceCodeData.Subject.FindFirst(JwtClaimTypes.Subject).Value,\n                CreationTime = deviceCodeData.CreationTime,\n                Expiration = deviceCodeData.CreationTime.AddSeconds(deviceCodeData.Lifetime),\n                Data = serializer.Serialize(deviceCodeData)\n            });\n            context.SaveChanges();\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n\n            // skip odd behaviour of in-memory provider\n            if (options.Extensions.All(x => x.GetType() != typeof(InMemoryOptionsExtension)))\n            {\n                await Assert.ThrowsAsync<DbUpdateException>(() =>\n                    store.StoreDeviceAuthorizationAsync(existingDeviceCode, $\"user_{Guid.NewGuid().ToString()}\", deviceCodeData));\n            }\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindByUserCodeAsync_WhenUserCodeExists_ExpectDataRetrievedCorrectly(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var testDeviceCode = $\"device_{Guid.NewGuid().ToString()}\";\n        var testUserCode = $\"user_{Guid.NewGuid().ToString()}\";\n\n        var expectedSubject = $\"sub_{Guid.NewGuid().ToString()}\";\n        var expectedDeviceCodeData = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            RequestedScopes = new[] { \"openid\", \"api1\" },\n            CreationTime = new DateTime(2018, 10, 19, 16, 14, 29),\n            Lifetime = 300,\n            IsOpenId = true,\n            Subject = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim(JwtClaimTypes.Subject, expectedSubject) }))\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(new DeviceFlowCodes\n            {\n                DeviceCode = testDeviceCode,\n                UserCode = testUserCode,\n                ClientId = expectedDeviceCodeData.ClientId,\n                SubjectId = expectedDeviceCodeData.Subject.FindFirst(JwtClaimTypes.Subject).Value,\n                CreationTime = expectedDeviceCodeData.CreationTime,\n                Expiration = expectedDeviceCodeData.CreationTime.AddSeconds(expectedDeviceCodeData.Lifetime),\n                Data = serializer.Serialize(expectedDeviceCodeData)\n            });\n            context.SaveChanges();\n        }\n\n        DeviceCode code;\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            code = await store.FindByUserCodeAsync(testUserCode);\n        }\n        \n        code.Should().BeEquivalentTo(expectedDeviceCodeData, \n            assertionOptions => assertionOptions.Excluding(x=> x.Subject));\n\n        code.Subject.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject && x.Value == expectedSubject).Should().NotBeNull();\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindByUserCodeAsync_WhenUserCodeDoesNotExist_ExpectNull(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            var code = await store.FindByUserCodeAsync($\"user_{Guid.NewGuid().ToString()}\");\n            code.Should().BeNull();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindByDeviceCodeAsync_WhenDeviceCodeExists_ExpectDataRetrievedCorrectly(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var testDeviceCode = $\"device_{Guid.NewGuid().ToString()}\";\n        var testUserCode = $\"user_{Guid.NewGuid().ToString()}\";\n\n        var expectedSubject = $\"sub_{Guid.NewGuid().ToString()}\";\n        var expectedDeviceCodeData = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            RequestedScopes = new[] { \"openid\", \"api1\" },\n            CreationTime = new DateTime(2018, 10, 19, 16, 14, 29),\n            Lifetime = 300,\n            IsOpenId = true,\n            Subject = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim(JwtClaimTypes.Subject, expectedSubject) }))\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(new DeviceFlowCodes\n            {\n                DeviceCode = testDeviceCode,\n                UserCode = testUserCode,\n                ClientId = expectedDeviceCodeData.ClientId,\n                SubjectId = expectedDeviceCodeData.Subject.FindFirst(JwtClaimTypes.Subject).Value,\n                CreationTime = expectedDeviceCodeData.CreationTime,\n                Expiration = expectedDeviceCodeData.CreationTime.AddSeconds(expectedDeviceCodeData.Lifetime),\n                Data = serializer.Serialize(expectedDeviceCodeData)\n            });\n            context.SaveChanges();\n        }\n\n        DeviceCode code;\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            code = await store.FindByDeviceCodeAsync(testDeviceCode);\n        }\n\n        code.Should().BeEquivalentTo(expectedDeviceCodeData,\n            assertionOptions => assertionOptions.Excluding(x => x.Subject));\n\n        code.Subject.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject && x.Value == expectedSubject).Should().NotBeNull();\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindByDeviceCodeAsync_WhenDeviceCodeDoesNotExist_ExpectNull(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            var code = await store.FindByDeviceCodeAsync($\"device_{Guid.NewGuid().ToString()}\");\n            code.Should().BeNull();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task UpdateByUserCodeAsync_WhenDeviceCodeAuthorized_ExpectSubjectAndDataUpdated(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var testDeviceCode = $\"device_{Guid.NewGuid().ToString()}\";\n        var testUserCode = $\"user_{Guid.NewGuid().ToString()}\";\n\n        var expectedSubject = $\"sub_{Guid.NewGuid().ToString()}\";\n        var unauthorizedDeviceCode = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            RequestedScopes = new[] {\"openid\", \"api1\"},\n            CreationTime = new DateTime(2018, 10, 19, 16, 14, 29),\n            Lifetime = 300,\n            IsOpenId = true\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(new DeviceFlowCodes\n            {\n                DeviceCode = testDeviceCode,\n                UserCode = testUserCode,\n                ClientId = unauthorizedDeviceCode.ClientId,\n                CreationTime = unauthorizedDeviceCode.CreationTime,\n                Expiration = unauthorizedDeviceCode.CreationTime.AddSeconds(unauthorizedDeviceCode.Lifetime),\n                Data = serializer.Serialize(unauthorizedDeviceCode)\n            });\n            context.SaveChanges();\n        }\n\n        var authorizedDeviceCode = new DeviceCode\n        {\n            ClientId = unauthorizedDeviceCode.ClientId,\n            RequestedScopes = unauthorizedDeviceCode.RequestedScopes,\n            AuthorizedScopes = unauthorizedDeviceCode.RequestedScopes,\n            Subject = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> { new Claim(JwtClaimTypes.Subject, expectedSubject) })),\n            IsAuthorized = true,\n            IsOpenId = true,\n            CreationTime = new DateTime(2018, 10, 19, 16, 14, 29),\n            Lifetime = 300\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            await store.UpdateByUserCodeAsync(testUserCode, authorizedDeviceCode);\n        }\n\n        DeviceFlowCodes updatedCodes;\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            updatedCodes = context.DeviceFlowCodes.Single(x => x.UserCode == testUserCode);\n        }\n\n        // should be unchanged\n        updatedCodes.DeviceCode.Should().Be(testDeviceCode);\n        updatedCodes.ClientId.Should().Be(unauthorizedDeviceCode.ClientId);\n        updatedCodes.CreationTime.Should().Be(unauthorizedDeviceCode.CreationTime);\n        updatedCodes.Expiration.Should().Be(unauthorizedDeviceCode.CreationTime.AddSeconds(authorizedDeviceCode.Lifetime));\n\n        // should be changed\n        var parsedCode = serializer.Deserialize<DeviceCode>(updatedCodes.Data);\n        parsedCode.Should().BeEquivalentTo(authorizedDeviceCode, assertionOptions => assertionOptions.Excluding(x => x.Subject));\n        parsedCode.Subject.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject && x.Value == expectedSubject).Should().NotBeNull();\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveByDeviceCodeAsync_WhenDeviceCodeExists_ExpectDeviceCodeDeleted(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var testDeviceCode = $\"device_{Guid.NewGuid().ToString()}\";\n        var testUserCode = $\"user_{Guid.NewGuid().ToString()}\";\n\n        var existingDeviceCode = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            RequestedScopes = new[] { \"openid\", \"api1\" },\n            CreationTime = new DateTime(2018, 10, 19, 16, 14, 29),\n            Lifetime = 300,\n            IsOpenId = true\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(new DeviceFlowCodes\n            {\n                DeviceCode = testDeviceCode,\n                UserCode = testUserCode,\n                ClientId = existingDeviceCode.ClientId,\n                CreationTime = existingDeviceCode.CreationTime,\n                Expiration = existingDeviceCode.CreationTime.AddSeconds(existingDeviceCode.Lifetime),\n                Data = serializer.Serialize(existingDeviceCode)\n            });\n            context.SaveChanges();\n        }\n        \n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            await store.RemoveByDeviceCodeAsync(testDeviceCode);\n        }\n        \n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.FirstOrDefault(x => x.UserCode == testUserCode).Should().BeNull();\n        }\n    }\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveByDeviceCodeAsync_WhenDeviceCodeDoesNotExists_ExpectSuccess(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new DeviceFlowStore(context, new PersistentGrantSerializer(), FakeLogger<DeviceFlowStore>.Create());\n            await store.RemoveByDeviceCodeAsync($\"device_{Guid.NewGuid().ToString()}\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/Stores/PersistedGrantStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServer8.EntityFramework.Options;\nusing IdentityServer8.EntityFramework.Stores;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Microsoft.EntityFrameworkCore;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests.Stores;\n\npublic class PersistedGrantStoreTests : IntegrationTest<PersistedGrantStoreTests, PersistedGrantDbContext, OperationalStoreOptions>\n{\n    public PersistedGrantStoreTests(DatabaseProviderFixture<PersistedGrantDbContext> fixture) : base(fixture)\n    {\n        foreach (var options in TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<PersistedGrantDbContext>)y)).ToList())\n        {\n            using (var context = new PersistedGrantDbContext(options, StoreOptions))\n                context.Database.EnsureCreated();\n        }\n    }\n\n    private static PersistedGrant CreateTestObject(string sub = null, string clientId = null, string sid = null, string type = null)\n    {\n        return new PersistedGrant\n        {\n            Key = Guid.NewGuid().ToString(),\n            Type = type ?? \"authorization_code\",\n            ClientId = clientId ?? Guid.NewGuid().ToString(),\n            SubjectId = sub ?? Guid.NewGuid().ToString(),\n            SessionId = sid ?? Guid.NewGuid().ToString(),\n            CreationTime = new DateTime(2016, 08, 01),\n            Expiration = new DateTime(2016, 08, 31),\n            Data = Guid.NewGuid().ToString()\n        };\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task StoreAsync_WhenPersistedGrantStored_ExpectSuccess(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            await store.StoreAsync(persistedGrant);\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundGrant = context.PersistedGrants.FirstOrDefault(x => x.Key == persistedGrant.Key);\n            Assert.NotNull(foundGrant);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task GetAsync_WithKeyAndPersistedGrantExists_ExpectPersistedGrantReturned(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(persistedGrant.ToEntity());\n            context.SaveChanges();\n        }\n\n        PersistedGrant foundPersistedGrant;\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            foundPersistedGrant = await store.GetAsync(persistedGrant.Key);\n        }\n\n        Assert.NotNull(foundPersistedGrant);\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task GetAllAsync_WithSubAndTypeAndPersistedGrantExists_ExpectPersistedGrantReturned(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(persistedGrant.ToEntity());\n            context.SaveChanges();\n        }\n\n        IList<PersistedGrant> foundPersistedGrants;\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            foundPersistedGrants = (await store.GetAllAsync(new PersistedGrantFilter { SubjectId = persistedGrant.SubjectId })).ToList();\n        }\n\n        Assert.NotNull(foundPersistedGrants);\n        Assert.NotEmpty(foundPersistedGrants);\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task GetAllAsync_Should_Filter(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s1\", type: \"t1\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s1\", type: \"t2\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s2\", type: \"t1\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s2\", type: \"t2\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s1\", type: \"t1\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s1\", type: \"t2\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s2\", type: \"t1\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s2\", type: \"t2\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c3\", sid: \"s3\", type: \"t3\").ToEntity());\n            context.PersistedGrants.Add(CreateTestObject().ToEntity());\n            context.SaveChanges();\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\"\n            })).ToList().Count.Should().Be(9);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\"\n            })).ToList().Count.Should().Be(0);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c1\"\n            })).ToList().Count.Should().Be(4);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c2\"\n            })).ToList().Count.Should().Be(4);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c3\"\n            })).ToList().Count.Should().Be(1);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c4\"\n            })).ToList().Count.Should().Be(0);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c1\",\n                SessionId = \"s1\"\n            })).ToList().Count.Should().Be(2);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c3\",\n                SessionId = \"s1\"\n            })).ToList().Count.Should().Be(0);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c1\",\n                SessionId = \"s1\",\n                Type = \"t1\"\n            })).ToList().Count.Should().Be(1);\n            (await store.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c1\",\n                SessionId = \"s1\",\n                Type = \"t3\"\n            })).ToList().Count.Should().Be(0);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveAsync_WhenKeyOfExistingReceived_ExpectGrantDeleted(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(persistedGrant.ToEntity());\n            context.SaveChanges();\n        }\n        \n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            await store.RemoveAsync(persistedGrant.Key);\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundGrant = context.PersistedGrants.FirstOrDefault(x => x.Key == persistedGrant.Key);\n            Assert.Null(foundGrant);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveAllAsync_WhenSubIdAndClientIdOfExistingReceived_ExpectGrantDeleted(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(persistedGrant.ToEntity());\n            context.SaveChanges();\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            await store.RemoveAllAsync(new PersistedGrantFilter { \n                SubjectId = persistedGrant.SubjectId, \n                ClientId = persistedGrant.ClientId \n            });\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundGrant = context.PersistedGrants.FirstOrDefault(x => x.Key == persistedGrant.Key);\n            Assert.Null(foundGrant);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveAllAsync_WhenSubIdClientIdAndTypeOfExistingReceived_ExpectGrantDeleted(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(persistedGrant.ToEntity());\n            context.SaveChanges();\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            await store.RemoveAllAsync(new PersistedGrantFilter { \n                SubjectId = persistedGrant.SubjectId, \n                ClientId = persistedGrant.ClientId, \n                Type = persistedGrant.Type });\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundGrant = context.PersistedGrants.FirstOrDefault(x => x.Key == persistedGrant.Key);\n            Assert.Null(foundGrant);\n        }\n    }\n\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveAllAsync_Should_Filter(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        void PopulateDb()\n        {\n            using (var context = new PersistedGrantDbContext(options, StoreOptions))\n            {\n                context.PersistedGrants.RemoveRange(context.PersistedGrants.ToArray());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s1\", type: \"t1\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s1\", type: \"t2\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s2\", type: \"t1\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c1\", sid: \"s2\", type: \"t2\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s1\", type: \"t1\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s1\", type: \"t2\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s2\", type: \"t1\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c2\", sid: \"s2\", type: \"t2\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject(sub: \"sub1\", clientId: \"c3\", sid: \"s3\", type: \"t3\").ToEntity());\n                context.PersistedGrants.Add(CreateTestObject().ToEntity());\n                context.SaveChanges();\n            }\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\"\n            });\n            context.PersistedGrants.Count().Should().Be(1);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\"\n            });\n            context.PersistedGrants.Count().Should().Be(10);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\", ClientId = \"c1\"\n            });\n            context.PersistedGrants.Count().Should().Be(6);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c2\"\n            });\n            context.PersistedGrants.Count().Should().Be(6);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c3\"\n            });\n            context.PersistedGrants.Count().Should().Be(9);\n        }\n\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c4\"\n            });\n            context.PersistedGrants.Count().Should().Be(10);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c1\", \n                SessionId = \"s1\"\n            });\n            context.PersistedGrants.Count().Should().Be(8);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c3\",\n                SessionId = \"s1\"\n            });\n            context.PersistedGrants.Count().Should().Be(10);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c1\",\n                SessionId = \"s1\", \n                Type = \"t1\"\n            });\n            context.PersistedGrants.Count().Should().Be(9);\n        }\n\n        PopulateDb();\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n\n            await store.RemoveAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"c1\",\n                SessionId = \"s1\",\n                Type = \"t3\"\n            });\n            context.PersistedGrants.Count().Should().Be(10);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task Store_should_create_new_record_if_key_does_not_exist(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundGrant = context.PersistedGrants.FirstOrDefault(x => x.Key == persistedGrant.Key);\n            Assert.Null(foundGrant);\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            await store.StoreAsync(persistedGrant);\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundGrant = context.PersistedGrants.FirstOrDefault(x => x.Key == persistedGrant.Key);\n            Assert.NotNull(foundGrant);\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task Store_should_update_record_if_key_already_exists(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var persistedGrant = CreateTestObject();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(persistedGrant.ToEntity());\n            context.SaveChanges();\n        }\n\n        var newDate = persistedGrant.Expiration.Value.AddHours(1);\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var store = new PersistedGrantStore(context, FakeLogger<PersistedGrantStore>.Create());\n            persistedGrant.Expiration = newDate;\n            await store.StoreAsync(persistedGrant);\n        }\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            var foundGrant = context.PersistedGrants.FirstOrDefault(x => x.Key == persistedGrant.Key);\n            Assert.NotNull(foundGrant);\n            Assert.Equal(newDate, persistedGrant.Expiration);\n        }\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/Stores/ResourceStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityModel;\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServer8.EntityFramework.Options;\nusing IdentityServer8.EntityFramework.Stores;\nusing IdentityServer8.Models;\nusing Microsoft.EntityFrameworkCore;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests.Stores;\n\npublic class ScopeStoreTests : IntegrationTest<ScopeStoreTests, ConfigurationDbContext, ConfigurationStoreOptions>\n{\n    public ScopeStoreTests(DatabaseProviderFixture<ConfigurationDbContext> fixture) : base(fixture)\n    {\n        foreach (var options in TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<ConfigurationDbContext>)y)).ToList())\n        {\n            using (var context = new ConfigurationDbContext(options, StoreOptions))\n                context.Database.EnsureCreated();\n        }\n    }\n\n    private static IdentityResource CreateIdentityTestResource()\n    {\n        return new IdentityResource()\n        {\n            Name = Guid.NewGuid().ToString(),\n            DisplayName = Guid.NewGuid().ToString(),\n            Description = Guid.NewGuid().ToString(),\n            ShowInDiscoveryDocument = true,\n            UserClaims = \n            {\n                JwtClaimTypes.Subject,\n                JwtClaimTypes.Name,\n            }\n        };\n    }\n\n    private static ApiResource CreateApiResourceTestResource()\n    {\n        return new ApiResource()\n        {\n            Name = Guid.NewGuid().ToString(),\n            ApiSecrets = new List<Secret> { new Secret(\"secret\".ToSha256()) },\n            Scopes = { Guid.NewGuid().ToString() },\n            UserClaims =\n            {\n                Guid.NewGuid().ToString(),\n                Guid.NewGuid().ToString(),\n            }\n        };\n    }\n    \n    private static ApiScope CreateApiScopeTestResource()\n    {\n        return new ApiScope()\n        {\n            Name = Guid.NewGuid().ToString(),\n            UserClaims =\n            {\n                Guid.NewGuid().ToString(),\n                Guid.NewGuid().ToString(),\n            }\n        };\n    }\n\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindApiResourcesByNameAsync_WhenResourceExists_ExpectResourceAndCollectionsReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var resource = CreateApiResourceTestResource();\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.ApiResources.Add(resource.ToEntity());\n            context.SaveChanges();\n        }\n\n        ApiResource foundResource;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            foundResource = (await store.FindApiResourcesByNameAsync(new[] { resource.Name })).SingleOrDefault();\n        }\n\n        Assert.NotNull(foundResource);\n        Assert.True(foundResource.Name == resource.Name);\n\n        Assert.NotNull(foundResource.UserClaims);\n        Assert.NotEmpty(foundResource.UserClaims);\n        Assert.NotNull(foundResource.ApiSecrets);\n        Assert.NotEmpty(foundResource.ApiSecrets);\n        Assert.NotNull(foundResource.Scopes);\n        Assert.NotEmpty(foundResource.Scopes);\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindApiResourcesByNameAsync_WhenResourcesExist_ExpectOnlyResourcesRequestedReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var resource = CreateApiResourceTestResource();\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.ApiResources.Add(resource.ToEntity());\n            context.ApiResources.Add(CreateApiResourceTestResource().ToEntity());\n            context.SaveChanges();\n        }\n\n        ApiResource foundResource;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            foundResource = (await store.FindApiResourcesByNameAsync(new[] { resource.Name })).SingleOrDefault();\n        }\n\n        Assert.NotNull(foundResource);\n        Assert.True(foundResource.Name == resource.Name);\n\n        Assert.NotNull(foundResource.UserClaims);\n        Assert.NotEmpty(foundResource.UserClaims);\n        Assert.NotNull(foundResource.ApiSecrets);\n        Assert.NotEmpty(foundResource.ApiSecrets);\n        Assert.NotNull(foundResource.Scopes);\n        Assert.NotEmpty(foundResource.Scopes);\n    }\n\n\n\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindApiResourcesByScopeNameAsync_WhenResourcesExist_ExpectResourcesReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var testApiResource = CreateApiResourceTestResource();\n        var testApiScope = CreateApiScopeTestResource();\n        testApiResource.Scopes.Add(testApiScope.Name);\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.ApiResources.Add(testApiResource.ToEntity());\n            context.ApiScopes.Add(testApiScope.ToEntity());\n            context.SaveChanges();\n        }\n\n        IEnumerable<ApiResource> resources;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            resources = await store.FindApiResourcesByScopeNameAsync(new List<string>\n            {\n                testApiScope.Name\n            });\n        }\n\n        Assert.NotNull(resources);\n        Assert.NotEmpty(resources);\n        Assert.NotNull(resources.Single(x => x.Name == testApiResource.Name));\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindApiResourcesByScopeNameAsync_WhenResourcesExist_ExpectOnlyResourcesRequestedReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var testIdentityResource = CreateIdentityTestResource();\n        var testApiResource = CreateApiResourceTestResource();\n        var testApiScope = CreateApiScopeTestResource();\n        testApiResource.Scopes.Add(testApiScope.Name);\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.IdentityResources.Add(testIdentityResource.ToEntity());\n            context.ApiResources.Add(testApiResource.ToEntity());\n            context.ApiScopes.Add(testApiScope.ToEntity());\n            context.IdentityResources.Add(CreateIdentityTestResource().ToEntity());\n            context.ApiResources.Add(CreateApiResourceTestResource().ToEntity());\n            context.ApiScopes.Add(CreateApiScopeTestResource().ToEntity());\n            context.SaveChanges();\n        }\n\n        IEnumerable<ApiResource> resources;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            resources = await store.FindApiResourcesByScopeNameAsync(new[] { testApiScope.Name });\n        }\n\n        Assert.NotNull(resources);\n        Assert.NotEmpty(resources);\n        Assert.NotNull(resources.Single(x => x.Name == testApiResource.Name));\n    }\n\n\n\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindIdentityResourcesByScopeNameAsync_WhenResourceExists_ExpectResourceAndCollectionsReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var resource = CreateIdentityTestResource();\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.IdentityResources.Add(resource.ToEntity());\n            context.SaveChanges();\n        }\n\n        IList<IdentityResource> resources;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            resources = (await store.FindIdentityResourcesByScopeNameAsync(new List<string>\n            {\n                resource.Name\n            })).ToList();\n        }\n\n        Assert.NotNull(resources);\n        Assert.NotEmpty(resources);\n        var foundScope = resources.Single();\n\n        Assert.Equal(resource.Name, foundScope.Name);\n        Assert.NotNull(foundScope.UserClaims);\n        Assert.NotEmpty(foundScope.UserClaims);\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindIdentityResourcesByScopeNameAsync_WhenResourcesExist_ExpectOnlyRequestedReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var resource = CreateIdentityTestResource();\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.IdentityResources.Add(resource.ToEntity());\n            context.IdentityResources.Add(CreateIdentityTestResource().ToEntity());\n            context.SaveChanges();\n        }\n\n        IList<IdentityResource> resources;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            resources = (await store.FindIdentityResourcesByScopeNameAsync(new List<string>\n            {\n                resource.Name\n            })).ToList();\n        }\n\n        Assert.NotNull(resources);\n        Assert.NotEmpty(resources);\n        Assert.NotNull(resources.Single(x => x.Name == resource.Name));\n    }\n\n\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindApiScopesByNameAsync_WhenResourceExists_ExpectResourceAndCollectionsReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var resource = CreateApiScopeTestResource();\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.ApiScopes.Add(resource.ToEntity());\n            context.SaveChanges();\n        }\n\n        IList<ApiScope> resources;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            resources = (await store.FindApiScopesByNameAsync(new List<string>\n            {\n                resource.Name\n            })).ToList();\n        }\n\n        Assert.NotNull(resources);\n        Assert.NotEmpty(resources);\n        var foundScope = resources.Single();\n\n        Assert.Equal(resource.Name, foundScope.Name);\n        Assert.NotNull(foundScope.UserClaims);\n        Assert.NotEmpty(foundScope.UserClaims);\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task FindApiScopesByNameAsync_WhenResourcesExist_ExpectOnlyRequestedReturned(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var resource = CreateApiScopeTestResource();\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.ApiScopes.Add(resource.ToEntity());\n            context.ApiScopes.Add(CreateApiScopeTestResource().ToEntity());\n            context.SaveChanges();\n        }\n\n        IList<ApiScope> resources;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            resources = (await store.FindApiScopesByNameAsync(new List<string>\n            {\n                resource.Name\n            })).ToList();\n        }\n\n        Assert.NotNull(resources);\n        Assert.NotEmpty(resources);\n        Assert.NotNull(resources.Single(x => x.Name == resource.Name));\n    }\n\n\n\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task GetAllResources_WhenAllResourcesRequested_ExpectAllResourcesIncludingHidden(DbContextOptions<ConfigurationDbContext> options)\n    {\n        var visibleIdentityResource = CreateIdentityTestResource();\n        var visibleApiResource = CreateApiResourceTestResource();\n        var visibleApiScope = CreateApiScopeTestResource();\n        var hiddenIdentityResource = new IdentityResource { Name = Guid.NewGuid().ToString(), ShowInDiscoveryDocument = false };\n        var hiddenApiResource = new ApiResource\n        {\n            Name = Guid.NewGuid().ToString(),\n            Scopes = { Guid.NewGuid().ToString() },\n            ShowInDiscoveryDocument = false\n        };\n        var hiddenApiScope = new ApiScope\n        {\n            Name = Guid.NewGuid().ToString(),\n            ShowInDiscoveryDocument = false\n        };\n\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            context.IdentityResources.Add(visibleIdentityResource.ToEntity());\n            context.ApiResources.Add(visibleApiResource.ToEntity());\n            context.ApiScopes.Add(visibleApiScope.ToEntity());\n\n            context.IdentityResources.Add(hiddenIdentityResource.ToEntity());\n            context.ApiResources.Add(hiddenApiResource.ToEntity());\n            context.ApiScopes.Add(hiddenApiScope.ToEntity());\n            \n            context.SaveChanges();\n        }\n\n        Resources resources;\n        using (var context = new ConfigurationDbContext(options, StoreOptions))\n        {\n            var store = new ResourceStore(context, FakeLogger<ResourceStore>.Create());\n            resources = await store.GetAllResourcesAsync();\n        }\n\n        Assert.NotNull(resources);\n        Assert.NotEmpty(resources.IdentityResources);\n        Assert.NotEmpty(resources.ApiResources);\n        Assert.NotEmpty(resources.ApiScopes);\n\n        Assert.Contains(resources.IdentityResources, x => x.Name == visibleIdentityResource.Name);\n        Assert.Contains(resources.IdentityResources, x => x.Name == hiddenIdentityResource.Name);\n\n        Assert.Contains(resources.ApiResources, x => x.Name == visibleApiResource.Name);\n        Assert.Contains(resources.ApiResources, x => x.Name == hiddenApiResource.Name);\n\n        Assert.Contains(resources.ApiScopes, x => x.Name == visibleApiScope.Name);\n        Assert.Contains(resources.ApiScopes, x => x.Name == hiddenApiScope.Name);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/IntegrationTests/TokenCleanup/TokenCleanupTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.EntityFramework.DbContexts;\nusing IdentityServer8.EntityFramework.Entities;\nusing IdentityServer8.EntityFramework.Interfaces;\nusing IdentityServer8.EntityFramework.Options;\nusing IdentityServer8.EntityFramework.Stores;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Test;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.IntegrationTests.TokenCleanup;\n\npublic class TokenCleanupTests : IntegrationTest<TokenCleanupTests, PersistedGrantDbContext, OperationalStoreOptions>\n{\n\n\n    public TokenCleanupTests(DatabaseProviderFixture<PersistedGrantDbContext> fixture) : base(fixture)\n    {\n        foreach (var options in TestDatabaseProviders.SelectMany(x => x.Select(y => (DbContextOptions<PersistedGrantDbContext>)y)).ToList())\n        {\n            using (var context = new PersistedGrantDbContext(options, StoreOptions))\n            {\n                context.Database.EnsureCreated();\n            }\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveExpiredGrantsAsync_WhenExpiredGrantsExist_ExpectExpiredGrantsRemoved(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var expiredGrant = new PersistedGrant\n        {\n            Key = Guid.NewGuid().ToString(),\n            ClientId = \"app1\",\n            Type = \"reference\",\n            SubjectId = \"123\",\n            Expiration = DateTime.UtcNow.AddDays(-3),\n            Data = \"{!}\"\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(expiredGrant);\n            context.SaveChanges();\n        }\n\n        await CreateSut(options).RemoveExpiredGrantsAsync();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.FirstOrDefault(x => x.Key == expiredGrant.Key).Should().BeNull();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveExpiredGrantsAsync_WhenValidGrantsExist_ExpectValidGrantsInDb(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var validGrant = new PersistedGrant\n        {\n            Key = Guid.NewGuid().ToString(),\n            ClientId = \"app1\",\n            Type = \"reference\",\n            SubjectId = \"123\",\n            Expiration = DateTime.UtcNow.AddDays(3),\n            Data = \"{!}\"\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.Add(validGrant);\n            context.SaveChanges();\n        }\n\n        await CreateSut(options).RemoveExpiredGrantsAsync();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.PersistedGrants.FirstOrDefault(x => x.Key == validGrant.Key).Should().NotBeNull();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveExpiredGrantsAsync_WhenExpiredDeviceGrantsExist_ExpectExpiredDeviceGrantsRemoved(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var expiredGrant = new DeviceFlowCodes\n        {\n            DeviceCode = Guid.NewGuid().ToString(),\n            UserCode = Guid.NewGuid().ToString(),\n            ClientId = \"app1\",\n            SubjectId = \"123\",\n            CreationTime = DateTime.UtcNow.AddDays(-4),\n            Expiration = DateTime.UtcNow.AddDays(-3),\n            Data = \"{!}\"\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(expiredGrant);\n            context.SaveChanges();\n        }\n\n        await CreateSut(options).RemoveExpiredGrantsAsync();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.FirstOrDefault(x => x.DeviceCode == expiredGrant.DeviceCode).Should().BeNull();\n        }\n    }\n\n    [Theory, MemberData(nameof(TestDatabaseProviders))]\n    public async Task RemoveExpiredGrantsAsync_WhenValidDeviceGrantsExist_ExpectValidDeviceGrantsInDb(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        var validGrant = new DeviceFlowCodes\n        {\n            DeviceCode = Guid.NewGuid().ToString(),\n            UserCode = \"2468\",\n            ClientId = \"app1\",\n            SubjectId = \"123\",\n            CreationTime = DateTime.UtcNow.AddDays(-4),\n            Expiration = DateTime.UtcNow.AddDays(3),\n            Data = \"{!}\"\n        };\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.Add(validGrant);\n            context.SaveChanges();\n        }\n\n        await CreateSut(options).RemoveExpiredGrantsAsync();\n\n        using (var context = new PersistedGrantDbContext(options, StoreOptions))\n        {\n            context.DeviceFlowCodes.FirstOrDefault(x => x.DeviceCode == validGrant.DeviceCode).Should().NotBeNull();\n        }\n    }\n\n    private EntityFramework.TokenCleanupService CreateSut(DbContextOptions<PersistedGrantDbContext> options)\n    {\n        IServiceCollection services = new ServiceCollection();\n        services.AddIdentityServer()\n            .AddTestUsers(new List<TestUser>())\n            .AddInMemoryClients(new List<Models.Client>())\n            .AddInMemoryIdentityResources(new List<Models.IdentityResource>())\n            .AddInMemoryApiResources(new List<Models.ApiResource>());\n\n        services.AddScoped<IPersistedGrantDbContext, PersistedGrantDbContext>(_ =>\n            new PersistedGrantDbContext(options, StoreOptions));\n        services.AddTransient<IPersistedGrantStore, PersistedGrantStore>();\n        services.AddTransient<IDeviceFlowStore, DeviceFlowStore>();\n        \n        services.AddTransient<EntityFramework.TokenCleanupService>();\n        services.AddSingleton(StoreOptions);\n\n        return services.BuildServiceProvider().GetRequiredService<EntityFramework.TokenCleanupService>();\n        //return new EntityFramework.TokenCleanupService(\n        //    services.BuildServiceProvider(),\n        //    new NullLogger<EntityFramework.TokenCleanup>(),\n        //    StoreOptions);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/UnitTests/IdentityServer8.EntityFramework.UnitTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <AssemblyOriginatorKeyFile>../../../../key.snk</AssemblyOriginatorKeyFile>\n    <SignAssembly>true</SignAssembly>\n    <PublicSign Condition=\"'$(OS)' != 'Windows_NT'\">true</PublicSign>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.EntityFramework.Storage.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"FluentAssertions\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" />\n    <PackageReference Include=\"coverlet.collector\" GeneratePathProperty=\"true\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Sqlite\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/UnitTests/Mappers/ApiResourceMappersTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Linq;\nusing FluentAssertions;\nusing IdentityServer8.EntityFramework.Mappers;\nusing Xunit;\nusing ApiResource = IdentityServer8.Models.ApiResource;\n\nnamespace IdentityServer8.EntityFramework.UnitTests.Mappers;\n\npublic class ApiResourceMappersTests\n{\n    [Fact]\n    public void AutomapperConfigurationIsValid()\n    {\n        ApiResourceMappers.Mapper.ConfigurationProvider.AssertConfigurationIsValid();\n    }\n\n    [Fact]\n    public void Can_Map()\n    {\n        var model = new ApiResource();\n        var mappedEntity = model.ToEntity();\n        var mappedModel = mappedEntity.ToModel();\n\n        Assert.NotNull(mappedModel);\n        Assert.NotNull(mappedEntity);\n    }\n\n    [Fact]\n    public void Properties_Map()\n    {\n        var model = new ApiResource()\n        {\n           Description = \"description\",\n           DisplayName = \"displayname\",\n           Name = \"foo\",\n           Scopes = { \"foo1\", \"foo2\" },\n           Enabled = false\n        };\n\n\n        var mappedEntity = model.ToEntity();\n\n        mappedEntity.Scopes.Count.Should().Be(2);\n        var foo1 = mappedEntity.Scopes.FirstOrDefault(x => x.Scope == \"foo1\");\n        foo1.Should().NotBeNull();\n        var foo2 = mappedEntity.Scopes.FirstOrDefault(x => x.Scope == \"foo2\");\n        foo2.Should().NotBeNull();\n        \n\n        var mappedModel = mappedEntity.ToModel();\n        \n        mappedModel.Description.Should().Be(\"description\");\n        mappedModel.DisplayName.Should().Be(\"displayname\");\n        mappedModel.Enabled.Should().BeFalse();\n        mappedModel.Name.Should().Be(\"foo\");\n    }\n\n    [Fact]\n    public void missing_values_should_use_defaults()\n    {\n        var entity = new IdentityServer8.EntityFramework.Entities.ApiResource\n        {\n            Secrets = new System.Collections.Generic.List<Entities.ApiResourceSecret>\n            {\n                new Entities.ApiResourceSecret\n                {\n                }\n            }\n        };\n\n        var def = new ApiResource\n        {\n            ApiSecrets = { new Models.Secret(\"foo\") }\n        };\n\n        var model = entity.ToModel();\n        model.ApiSecrets.First().Type.Should().Be(def.ApiSecrets.First().Type);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/UnitTests/Mappers/ClientMappersTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Linq;\nusing FluentAssertions;\nusing IdentityServer8.EntityFramework.Mappers;\nusing Xunit;\nusing Client = IdentityServer8.Models.Client;\n\nnamespace IdentityServer8.EntityFramework.UnitTests.Mappers;\n\npublic class ClientMappersTests\n{\n    [Fact]\n    public void AutomapperConfigurationIsValid()\n    {\n        ClientMappers.Mapper.ConfigurationProvider.AssertConfigurationIsValid();\n    }\n\n    [Fact]\n    public void Can_Map()\n    {\n        var model = new Client();\n        var mappedEntity = model.ToEntity();\n        var mappedModel = mappedEntity.ToModel();\n\n        Assert.NotNull(mappedModel);\n        Assert.NotNull(mappedEntity);\n    }\n\n    [Fact]\n    public void Properties_Map()\n    {\n        var model = new Client()\n        {\n            Properties =\n            {\n                {\"foo1\", \"bar1\"},\n                {\"foo2\", \"bar2\"},\n            }\n        };\n\n\n        var mappedEntity = model.ToEntity();\n\n        mappedEntity.Properties.Count.Should().Be(2);\n        var foo1 = mappedEntity.Properties.FirstOrDefault(x => x.Key == \"foo1\");\n        foo1.Should().NotBeNull();\n        foo1.Value.Should().Be(\"bar1\");\n        var foo2 = mappedEntity.Properties.FirstOrDefault(x => x.Key == \"foo2\");\n        foo2.Should().NotBeNull();\n        foo2.Value.Should().Be(\"bar2\");\n\n\n\n        var mappedModel = mappedEntity.ToModel();\n\n        mappedModel.Properties.Count.Should().Be(2);\n        mappedModel.Properties.ContainsKey(\"foo1\").Should().BeTrue();\n        mappedModel.Properties.ContainsKey(\"foo2\").Should().BeTrue();\n        mappedModel.Properties[\"foo1\"].Should().Be(\"bar1\");\n        mappedModel.Properties[\"foo2\"].Should().Be(\"bar2\");\n    }\n\n    [Fact]\n    public void duplicates_properties_in_db_map()\n    {\n        var entity = new IdentityServer8.EntityFramework.Entities.Client\n        {\n            Properties = new System.Collections.Generic.List<Entities.ClientProperty>()\n            {\n                new Entities.ClientProperty{Key = \"foo1\", Value = \"bar1\"},\n                new Entities.ClientProperty{Key = \"foo1\", Value = \"bar2\"},\n            }\n        };\n\n        Action modelAction = () => entity.ToModel();\n        modelAction.Should().Throw<Exception>();\n    }\n\n    [Fact]\n    public void missing_values_should_use_defaults()\n    {\n        var entity = new IdentityServer8.EntityFramework.Entities.Client\n        {\n            ClientSecrets = new System.Collections.Generic.List<Entities.ClientSecret>\n            {\n                new Entities.ClientSecret\n                {\n                }\n            }\n        };\n\n        var def = new Client\n        {\n            ClientSecrets = { new Models.Secret(\"foo\") }\n        };\n\n        var model = entity.ToModel();\n        model.ProtocolType.Should().Be(def.ProtocolType);\n        model.ClientSecrets.First().Type.Should().Be(def.ClientSecrets.First().Type);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/UnitTests/Mappers/IdentityResourcesMappersTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServer8.Models;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.UnitTests.Mappers;\n\npublic class IdentityResourcesMappersTests\n{\n    [Fact]\n    public void IdentityResourceAutomapperConfigurationIsValid()\n    {\n        IdentityResourceMappers.Mapper.ConfigurationProvider.AssertConfigurationIsValid();\n    }\n\n    [Fact]\n    public void CanMapIdentityResources()\n    {\n        var model = new IdentityResource();\n        var mappedEntity = model.ToEntity();\n        var mappedModel = mappedEntity.ToModel();\n\n        Assert.NotNull(mappedModel);\n        Assert.NotNull(mappedEntity);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/UnitTests/Mappers/PersistedGrantMappersTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServer8.Models;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.UnitTests.Mappers;\n\npublic class PersistedGrantMappersTests\n{\n    [Fact]\n    public void PersistedGrantAutomapperConfigurationIsValid()\n    {\n        PersistedGrantMappers.Mapper.ConfigurationProvider.AssertConfigurationIsValid();\n    }\n\n    [Fact]\n    public void CanMap()\n    {\n        var model = new PersistedGrant()\n        {\n            ConsumedTime = new System.DateTime(2020, 02, 03, 4, 5, 6)\n        };\n        \n        var mappedEntity = model.ToEntity();\n        mappedEntity.ConsumedTime.Value.Should().Be(new System.DateTime(2020, 02, 03, 4, 5, 6));\n        \n        var mappedModel = mappedEntity.ToModel();\n        mappedModel.ConsumedTime.Value.Should().Be(new System.DateTime(2020, 02, 03, 4, 5, 6));\n\n        Assert.NotNull(mappedModel);\n        Assert.NotNull(mappedEntity);\n    }\n}\n"
  },
  {
    "path": "src/EntityFramework.Storage/test/UnitTests/Mappers/ScopeMappersTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Linq;\nusing FluentAssertions;\nusing IdentityServer8.EntityFramework.Mappers;\nusing IdentityServer8.Models;\nusing Xunit;\n\nnamespace IdentityServer8.EntityFramework.UnitTests.Mappers;\n\npublic class ScopesMappersTests\n{\n    [Fact]\n    public void ScopeAutomapperConfigurationIsValid()\n    {\n        ScopeMappers.Mapper.ConfigurationProvider.AssertConfigurationIsValid();\n    }\n\n    [Fact]\n    public void CanMapScope()\n    {\n        var model = new ApiScope();\n        var mappedEntity = model.ToEntity();\n        var mappedModel = mappedEntity.ToModel();\n\n        Assert.NotNull(mappedModel);\n        Assert.NotNull(mappedEntity);\n    }\n\n    [Fact]\n    public void Properties_Map()\n    {\n        var model = new ApiScope()\n        {\n            Description = \"description\",\n            DisplayName = \"displayname\",\n            Name = \"foo\",\n            UserClaims = { \"c1\", \"c2\" },\n            Properties = {\n                { \"x\", \"xx\" },\n                { \"y\", \"yy\" },\n           },\n            Enabled = false\n        };\n\n\n        var mappedEntity = model.ToEntity();\n        mappedEntity.Description.Should().Be(\"description\");\n        mappedEntity.DisplayName.Should().Be(\"displayname\");\n        mappedEntity.Name.Should().Be(\"foo\");\n\n        mappedEntity.UserClaims.Count.Should().Be(2);\n        mappedEntity.UserClaims.Select(x => x.Type).Should().BeEquivalentTo(new[] { \"c1\", \"c2\" });\n        mappedEntity.Properties.Count.Should().Be(2);\n        mappedEntity.Properties.Should().Contain(x => x.Key == \"x\" && x.Value == \"xx\");\n        mappedEntity.Properties.Should().Contain(x => x.Key == \"y\" && x.Value == \"yy\");\n\n\n        var mappedModel = mappedEntity.ToModel();\n\n        mappedModel.Description.Should().Be(\"description\");\n        mappedModel.DisplayName.Should().Be(\"displayname\");\n        mappedModel.Enabled.Should().BeFalse();\n        mappedModel.Name.Should().Be(\"foo\");\n        mappedModel.UserClaims.Count.Should().Be(2);\n        mappedModel.UserClaims.Should().BeEquivalentTo(new[] { \"c1\", \"c2\" });\n        mappedModel.Properties.Count.Should().Be(2);\n        mappedModel.Properties[\"x\"].Should().Be(\"xx\");\n        mappedModel.Properties[\"y\"].Should().Be(\"yy\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/IdentityServer8/IdentityServer8.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{5461C61B-B06E-46BA-B206-925B660BE727}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"test\", \"test\", \"{45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8\", \"src\\IdentityServer8.csproj\", \"{407C030E-60E6-41F7-AF43-0AC48EDCC17D}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Host\", \"host\\Host.csproj\", \"{784B3C88-30FA-415D-B99E-584063064508}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer.UnitTests\", \"test\\IdentityServer.UnitTests\\IdentityServer.UnitTests.csproj\", \"{4291820C-735F-4776-8BC4-6527433BC683}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer.IntegrationTests\", \"test\\IdentityServer.IntegrationTests\\IdentityServer.IntegrationTests.csproj\", \"{94501373-478A-478D-8C17-6AC52E3438CF}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Files\", \"Solution Files\", \"{9CB027A4-3509-4E54-B9D7-AC8F2F648AA2}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\..\\.editorconfig = ..\\..\\.editorconfig\n\t\t..\\..\\.gitattributes = ..\\..\\.gitattributes\n\t\t..\\..\\.gitignore = ..\\..\\.gitignore\n\t\t..\\..\\Directory.Build.props = ..\\..\\Directory.Build.props\n\t\t..\\..\\Directory.Build.targets = ..\\..\\Directory.Build.targets\n\t\t..\\..\\Directory.Packages.props = ..\\..\\Directory.Packages.props\n\t\t..\\..\\global.json = ..\\..\\global.json\n\t\t..\\..\\IdentityServer8.DotNet.ruleset = ..\\..\\IdentityServer8.DotNet.ruleset\n\t\t..\\..\\LICENSE = ..\\..\\LICENSE\n\t\t..\\..\\NuGet.config = ..\\..\\NuGet.config\n\t\t..\\..\\README.md = ..\\..\\README.md\n\t\t..\\..\\SECURITY.MD = ..\\..\\SECURITY.MD\n\t\t..\\..\\SPONSORS.md = ..\\..\\SPONSORS.md\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{784B3C88-30FA-415D-B99E-584063064508} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{4291820C-735F-4776-8BC4-6527433BC683} = {45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF} = {45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {176723F7-4A9B-4F05-A9F3-3BA715E4BDC3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/IdentityServer8/build.cmd",
    "content": "@echo off\ndotnet run --project build -- %*"
  },
  {
    "path": "src/IdentityServer8/build.ps1",
    "content": "$ErrorActionPreference = \"Stop\";\ndotnet run --project build -- $args"
  },
  {
    "path": "src/IdentityServer8/build.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\ndotnet run --project build -- \"$@\""
  },
  {
    "path": "src/IdentityServer8/host/Configuration/Clients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class Clients\n{\n    public static IEnumerable<Client> Get()\n    {\n        var clients = new List<Client>();\n\n        clients.AddRange(ClientsConsole.Get());\n        clients.AddRange(ClientsWeb.Get());\n\n        return clients;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Configuration/ClientsConsole.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class ClientsConsole\n{\n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            ///////////////////////////////////////////\n            // Console Client Credentials Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes =\n                {\n                    \"resource1.scope1\", \"resource2.scope1\", IdentityServerConstants.LocalApi.ScopeName\n                }\n            },\n\n            ///////////////////////////////////////////\n            // Console Structured Scope Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"parameterized.client\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"transaction\" }\n            },\n\n            ///////////////////////////////////////////\n            // X509 mTLS Client\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mtls\",\n                ClientSecrets =\n                {\n                    // new Secret(@\"CN=mtls.test, OU=ROO\\ballen@roo, O=mkcert development certificate\", \"mtls.test\")\n                    // {\n                    //     Type = SecretTypes.X509CertificateName\n                    // },\n                    new Secret(\"5D9E9B6B333CD42C99D1DE6175CC0F3EF99DDF68\", \"mtls.test\")\n                    {\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateThumbprint\n                    },\n                },\n                AccessTokenType = AccessTokenType.Jwt,\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Console Client Credentials Flow with client JWT assertion\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client.jwt\",\n                ClientSecrets =\n                {\n                    new Secret\n                    {\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                        Value =\n                            \"MIIEgTCCAumgAwIBAgIQDMMu7l/umJhfEbzJMpcttzANBgkqhkiG9w0BAQsFADCBkzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMTQwMgYDVQQLDCtkb21pbmlja0Bkb21icDE2LmZyaXR6LmJveCAoRG9taW5pY2sgQmFpZXIpMTswOQYDVQQDDDJta2NlcnQgZG9taW5pY2tAZG9tYnAxNi5mcml0ei5ib3ggKERvbWluaWNrIEJhaWVyKTAeFw0xOTA2MDEwMDAwMDBaFw0zMDAxMDMxMjM0MDdaMHAxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTE0MDIGA1UECwwrZG9taW5pY2tAZG9tYnAxNi5mcml0ei5ib3ggKERvbWluaWNrIEJhaWVyKTEPMA0GA1UEAxMGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvNtpipaS8k1zA6w0Aoy8U4l+8zM4jHhhblExf3PULrMR6RauxniTki8p+P8CsZT4V8A4qo+JwsgpLIHrVQrbt9DEhHfBKzxwHqt+GoHt7byTfTtp8A/5nLhYc/5CW4HiR194gVx5+HAlvt+BriMTb1czvTf+H20dj41yUPsN7nMdyRLF+uXapQYMLYnq2BJIDq83mqGwojHk7d+N6GwoO95jlyas7KSoj8/FvfbaqkRNx0446hqPOzFHKc8er8K5VrLp6tVjh8ZJyY0F0dKgx6yWITsL54ctbj/cCyfuGjWEMbS2XXgc+x/xQMnmpfhK1qQAUn9jg5EzF9n6mQomOwIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUEMUlw41YsKZQVls3pEG6CrJk4O8wEQYDVR0RBAowCIIGY2xpZW50MA0GCSqGSIb3DQEBCwUAA4IBgQC0TjNY4Q3Wmw7ggamDImV6HUng3WbYGLYbbL2e3myBrjIxGd1Bi8ZyOu8qeUMIRAbZt2YsSX5S8kx0biaVg2zC+aO5eHhEWMwKB66huInXFjI4wtxZ22r+33fg1R0cLuEUePhftOWrbL0MS4YXVyn9HUMWO4WptG9PJdxNw1UbEB8nw3FkVOdAC9RGqiqalSK+E2UT/kUbTIQ1gPSdQ3nh52mre0H/T9+IRqiozJtNK/CQg4NuEV7rUXHnp7Fmigp6RIJ4TCozglspL341y0rV8M7npU1FYZC2UKNr4ed+GOO1n/sF3LbXDlPXwne99CVVn85wjDaevoR7Md0y2KwE9EggLYcViXNehx4YVv/BjfgqxW8NxiKAxP6kPOZE0XdBrZj2rmcDcGOXCzzYpcduKhFyTOpA0K5RNGC3j1KOUjPVlOtLvjASP7udBEYNfH3mgqXAgqNDOEKi2jG9LITv2IyGUsXhTAsKNJ6A6qiDBzDrvPAYDvsfabPq6tRTwjA=\"\n                    },\n                    new Secret\n                    {\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value =\n                            \"{'e':'AQAB','kid':'ZzAjSnraU3bkWGnnAqLapYGpTyNfLbjbzgAPbbW2GEA','kty':'RSA','n':'wWwQFtSzeRjjerpEM5Rmqz_DsNaZ9S1Bw6UbZkDLowuuTCjBWUax0vBMMxdy6XjEEK4Oq9lKMvx9JzjmeJf1knoqSNrox3Ka0rnxXpNAz6sATvme8p9mTXyp0cX4lF4U2J54xa2_S9NF5QWvpXvBeC4GAJx7QaSw4zrUkrc6XyaAiFnLhQEwKJCwUw4NOqIuYvYp_IXhw-5Ti_icDlZS-282PcccnBeOcX7vc21pozibIdmZJKqXNsL1Ibx5Nkx1F1jLnekJAmdaACDjYRLL_6n3W4wUp19UvzB1lGtXcJKLLkqB6YDiZNu16OSiSprfmrRXvYmvD8m6Fnl5aetgKw'}\"\n                    }\n                },\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Custom Grant Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client.custom\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n                AllowedGrantTypes = { \"custom\", \"custom.nosubject\" },\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Console Resource Owner Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    \"custom.profile\",\n                    \"resource1.scope1\",\n                    \"resource2.scope1\"\n                },\n                \n                RefreshTokenUsage = TokenUsage.OneTimeOnly,\n                AbsoluteRefreshTokenLifetime = 3600 * 24,\n                SlidingRefreshTokenLifetime = 10,\n                RefreshTokenExpiration = TokenExpiration.Sliding\n            },\n\n            ///////////////////////////////////////////\n            // Console Public Resource Owner Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient.public\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\",\n                    \"resource2.scope1\"\n                }\n            },\n\n            ///////////////////////////////////////////\n            // Console with PKCE Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"console.pkce\",\n                ClientName = \"Console with PKCE Sample\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n                RedirectUris = { \"http://127.0.0.1\" },\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\",\n                    \"resource2.scope1\"\n                }\n            },\n            ///////////////////////////////////////////\n            // WinConsole with PKCE Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"winconsole\",\n                ClientName = \"Windows Console with PKCE Sample\",\n                RequireClientSecret = false,\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n                RedirectUris = { \"sample-windows-client://callback\" },\n                RequireConsent = false,\n                AllowOfflineAccess = true,\n                AllowedIdentityTokenSigningAlgorithms = { \"ES256\" },\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\",\n                    \"resource2.scope1\"\n                }\n            },\n\n\n            ///////////////////////////////////////////\n            // Introspection Client Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient.reference\",\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowedScopes = { \"resource1.scope1\", \"resource2.scope1\", \"scope3\" },\n                AccessTokenType = AccessTokenType.Reference\n            },\n\n            ///////////////////////////////////////////\n            // Device Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"device\",\n                ClientName = \"Device Flow Client\",\n                AllowedGrantTypes = GrantTypes.DeviceFlow,\n                RequireClientSecret = false,\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Profile,\n                    IdentityServerConstants.StandardScopes.Email,\n                    \"resource1.scope1\",\n                    \"resource2.scope1\"\n                }\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Configuration/ClientsWeb.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic static class ClientsWeb\n{\n    static string[] allowedScopes = \n    {\n        IdentityServerConstants.StandardScopes.OpenId,\n        IdentityServerConstants.StandardScopes.Profile,\n        IdentityServerConstants.StandardScopes.Email,\n        \"resource1.scope1\", \n        \"resource2.scope1\",\n        \"transaction\"\n    };\n    \n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            ///////////////////////////////////////////\n            // JS OIDC Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"js_oidc\",\n                ClientName = \"JavaScript OIDC Client\",\n                ClientUri = \"http://identityserver8.io\",\n                \n                AllowedGrantTypes = GrantTypes.Code,\n                RequireClientSecret = false,\n                \n                RedirectUris = \n                {\n                    \"https://localhost:44300/index.html\",\n                    \"https://localhost:44300/callback.html\",\n                    \"https://localhost:44300/silent.html\",\n                    \"https://localhost:44300/popup.html\"\n                },\n\n                PostLogoutRedirectUris = { \"https://localhost:44300/index.html\" },\n                AllowedCorsOrigins = { \"https://localhost:44300\" },\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Automatic Token Management Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.tokenmanagement\",\n                \n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.Code,\n                RequirePkce = true,\n\n                AccessTokenLifetime = 75,\n\n                RedirectUris = { \"https://localhost:44301/signin-oidc\" },\n                FrontChannelLogoutUri = \"https://localhost:44301/signout-oidc\",\n                PostLogoutRedirectUris = { \"https://localhost:44301/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Code Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.code\",\n                ClientName = \"MVC Code Flow\",\n                ClientUri = \"http://identityserver8.io\",\n\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                RequireConsent = true,\n                AllowedGrantTypes = GrantTypes.Code,\n\n                RedirectUris = { \"https://localhost:44302/signin-oidc\" },\n                FrontChannelLogoutUri = \"https://localhost:44302/signout-oidc\",\n                PostLogoutRedirectUris = { \"https://localhost:44302/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            },\n            \n            ///////////////////////////////////////////\n            // MVC Hybrid Flow Sample (Back Channel logout)\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"mvc.hybrid.backchannel\",\n                ClientName = \"MVC Hybrid (with BackChannel logout)\",\n                ClientUri = \"http://identityserver8.io\",\n\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.Hybrid,\n                RequirePkce = false,\n\n                RedirectUris = { \"https://localhost:44303/signin-oidc\" },\n                BackChannelLogoutUri = \"https://localhost:44303/logout\",\n                PostLogoutRedirectUris = { \"https://localhost:44303/signout-callback-oidc\" },\n\n                AllowOfflineAccess = true,\n\n                AllowedScopes = allowedScopes\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Configuration/Resources.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Configuration;\n\npublic class Resources\n{\n    // identity resources represent identity data about a user that can be requested via the scope parameter (OpenID Connect)\n    public static readonly IEnumerable<IdentityResource> IdentityResources =\n        new[]\n        {\n            // some standard scopes from the OIDC spec\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email(),\n\n            // custom identity resource with some consolidated claims\n            new IdentityResource(\"custom.profile\", new[] { JwtClaimTypes.Name, JwtClaimTypes.Email, \"location\", JwtClaimTypes.Address })\n        };\n\n    // API scopes represent values that describe scope of access and can be requested by the scope parameter (OAuth)\n    public static readonly IEnumerable<ApiScope> ApiScopes =\n        new[]\n        {\n            // local API scope\n            new ApiScope(LocalApi.ScopeName),\n\n            // resource specific scopes\n            new ApiScope(\"resource1.scope1\"),\n            new ApiScope(\"resource2.scope1\"), \n            \n            // a scope without resource association\n            new ApiScope(\"scope3\"),\n            \n            // a scope shared by multiple resources\n            new ApiScope(\"shared.scope\"),\n\n            // a parameterized scope\n            new ApiScope(\"transaction\", \"Transaction\")\n            {\n                Description = \"Some Transaction\"\n            }\n        };\n\n    // API resources are more formal representation of a resource with processing rules and their scopes (if any)\n    public static readonly IEnumerable<ApiResource> ApiResources = \n        new[]\n        {\n            new ApiResource(\"resource1\", \"Resource 1\")\n            {\n                ApiSecrets = { new Secret(\"secret\".Sha256()) },\n\n                Scopes = { \"resource1.scope1\", \"shared.scope\" }\n            },\n            \n            new ApiResource(\"resource2\", \"Resource 2\")\n            {\n                ApiSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                // additional claims to put into access token\n                UserClaims =\n                {\n                    JwtClaimTypes.Name,\n                    JwtClaimTypes.Email\n                },\n\n                Scopes = { \"resource2.scope1\", \"shared.scope\" }\n            }\n        };\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Extensions/ExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Extensions;\n\npublic class ExtensionGrantValidator : IExtensionGrantValidator\n{\n    public Task ValidateAsync(ExtensionGrantValidationContext context)\n    {\n        var credential = context.Request.Raw.Get(\"custom_credential\");\n\n        if (credential != null)\n        {\n            context.Result = new GrantValidationResult(subject: \"818727\", authenticationMethod: \"custom\");\n        }\n        else\n        {\n            // custom error message\n            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, \"invalid custom credential\");\n        }\n\n        return Task.CompletedTask;\n    }\n\n    public string GrantType\n    {\n        get { return \"custom\"; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Extensions/HostProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Extensions;\n\npublic class HostProfileService : TestUserProfileService\n{\n    public HostProfileService(TestUserStore users, ILogger<TestUserProfileService> logger) : base(users, logger)\n    {\n    }\n\n    public override async Task GetProfileDataAsync(ProfileDataRequestContext context)\n    {\n        await base.GetProfileDataAsync(context);\n\n        var transaction = context.RequestedResources.ParsedScopes.FirstOrDefault(x => x.ParsedName == \"transaction\");\n        if (transaction?.ParsedParameter != null)\n        {\n            context.IssuedClaims.Add(new Claim(\"transaction_id\", transaction.ParsedParameter));\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Extensions/NoSubjectExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Extensions;\n\npublic class NoSubjectExtensionGrantValidator : IExtensionGrantValidator\n{\n    public Task ValidateAsync(ExtensionGrantValidationContext context)\n    {\n        var credential = context.Request.Raw.Get(\"custom_credential\");\n\n        if (credential != null)\n        {\n            context.Result = new GrantValidationResult();\n        }\n        else\n        {\n            // custom error message\n            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, \"invalid custom credential\");\n        }\n\n        return Task.CompletedTask;\n    }\n\n    public string GrantType\n    {\n        get { return \"custom.nosubject\"; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Extensions/ParameterizedScopeParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Extensions;\n\npublic class ParameterizedScopeParser : DefaultScopeParser\n{\n    public ParameterizedScopeParser(ILogger<DefaultScopeParser> logger) : base(logger)\n    {\n    }\n\n    public override void ParseScopeValue(ParseScopeContext scopeContext)\n    {\n        const string transactionScopeName = \"transaction\";\n        const string separator = \":\";\n        const string transactionScopePrefix = transactionScopeName + separator;\n\n        var scopeValue = scopeContext.RawValue;\n\n        if (scopeValue.StartsWith(transactionScopePrefix))\n        {\n            // we get in here with a scope like \"transaction:something\"\n            var parts = scopeValue.Split(separator, StringSplitOptions.RemoveEmptyEntries);\n            if (parts.Length == 2)\n            {\n                scopeContext.SetParsedValues(transactionScopeName, parts[1]);\n            }\n            else\n            {\n                scopeContext.SetError(\"transaction scope missing transaction parameter value\");\n            }\n        }\n        else if (scopeValue != transactionScopeName)\n        {\n            // we get in here with a scope not like \"transaction\"\n            base.ParseScopeValue(scopeContext);\n        }\n        else\n        {\n            // we get in here with a scope exactly \"transaction\", which is to say we're ignoring it \n            // and not including it in the results\n            scopeContext.SetIgnore();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Extensions/ParameterizedScopeTokenRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Extensions;\n\npublic class ParameterizedScopeTokenRequestValidator : ICustomTokenRequestValidator\n{\n    public Task ValidateAsync(CustomTokenRequestValidationContext context)\n    {\n        var transaction = context.Result.ValidatedRequest.ValidatedResources.ParsedScopes.FirstOrDefault(x => x.ParsedName == \"transaction\");\n        if (transaction?.ParsedParameter != null)\n        {\n            context.Result.ValidatedRequest.ClientClaims.Add(new Claim(transaction.ParsedName, transaction.ParsedParameter));\n        }\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Extensions/SameSiteHandlingExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Extensions;\n\n// copied from https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/\npublic static class SameSiteHandlingExtensions\n{\n    public static IServiceCollection AddSameSiteCookiePolicy(this IServiceCollection services)\n    {\n        services.Configure<CookiePolicyOptions>(options =>\n        {\n            options.MinimumSameSitePolicy = SameSiteMode.Unspecified;\n            options.OnAppendCookie = cookieContext => \n                CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);\n            options.OnDeleteCookie = cookieContext => \n                CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);\n        });\n\n        return services;\n    }\n    \n    private static void CheckSameSite(HttpContext httpContext, CookieOptions options)\n    {\n        if (options.SameSite == SameSiteMode.None)\n        {\n            var userAgent = httpContext.Request.Headers[\"User-Agent\"].ToString();\n            if (!httpContext.Request.IsHttps || DisallowsSameSiteNone(userAgent))\n            {\n                // For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)\n                options.SameSite = SameSiteMode.Unspecified;\n            }\n        }\n    }\n\n    private static bool DisallowsSameSiteNone(string userAgent)\n    {\n        // Cover all iOS based browsers here. This includes:\n        // - Safari on iOS 12 for iPhone, iPod Touch, iPad\n        // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad\n        // - Chrome on iOS 12 for iPhone, iPod Touch, iPad\n        // All of which are broken by SameSite=None, because they use the iOS networking stack\n        if (userAgent.Contains(\"CPU iPhone OS 12\") || userAgent.Contains(\"iPad; CPU OS 12\"))\n        {\n            return true;\n        }\n\n        // Cover Mac OS X based browsers that use the Mac OS networking stack. This includes:\n        // - Safari on Mac OS X.\n        // This does not include:\n        // - Chrome on Mac OS X\n        // Because they do not use the Mac OS networking stack.\n        if (userAgent.Contains(\"Macintosh; Intel Mac OS X 10_14\") && \n            userAgent.Contains(\"Version/\") && userAgent.Contains(\"Safari\"))\n        {\n            return true;\n        }\n\n        // Cover Chrome 50-69, because some versions are broken by SameSite=None, \n        // and none in this range require it.\n        // Note: this covers some pre-Chromium Edge versions, \n        // but pre-Chromium Edge does not require SameSite=None.\n        if (userAgent.Contains(\"Chrome/5\") || userAgent.Contains(\"Chrome/6\"))\n        {\n            return true;\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using IdentityServerHost.Configuration;\nglobal using IdentityServerHost.Extensions;\nglobal using IdentityServerHost.Quickstart.UI;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authentication.Certificate;\nglobal using Microsoft.AspNetCore.Authorization;\nglobal using Microsoft.AspNetCore.HttpOverrides;\nglobal using Microsoft.AspNetCore.Mvc;\nglobal using Microsoft.AspNetCore.Mvc.Filters;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.IdentityModel.Logging;\nglobal using Microsoft.IdentityModel.Tokens;\nglobal using Newtonsoft.Json;\nglobal using Serilog;\nglobal using Serilog.Events;\nglobal using Serilog.Sinks.SystemConsole.Themes;\nglobal using System.ComponentModel.DataAnnotations;\nglobal using System.Diagnostics;\nglobal using System.Security.Claims;\nglobal using System.Security.Cryptography.X509Certificates;\nglobal using System.Text;\nglobal using static IdentityServer8.IdentityServerConstants;\nglobal using ILogger = Microsoft.Extensions.Logging.ILogger;\nglobal using ClaimValueTypes = System.Security.Claims.ClaimValueTypes;\n"
  },
  {
    "path": "src/IdentityServer8/host/Host.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n\n\n  <ItemGroup>\n    <Content Remove=\"compilerconfig.json\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Include=\"compilerconfig.json\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.Certificate\" />\n    \n    <PackageReference Include=\"Serilog.AspNetCore\" />\n\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Sqlite\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"System.Security.Principal.Windows\" />\n    \n    <ProjectReference Include=\"..\\src\\IdentityServer8.csproj\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "src/IdentityServer8/host/LocalApiController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost;\n\n[Route(\"localApi\")]\n[Authorize(LocalApi.PolicyName)]\npublic class LocalApiController : ControllerBase\n{\n    public IActionResult Get()\n    {\n        var claims = from c in User.Claims select new { c.Type, c.Value };\n        return new JsonResult(claims);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost;\n\npublic class Program\n{\n    public static int Main(string[] args)\n    {\n        Console.Title = \"IdentityServer8\";\n        Activity.DefaultIdFormat = ActivityIdFormat.W3C;\n\n        Log.Logger = new LoggerConfiguration()\n            .MinimumLevel.Debug()\n            .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Warning)\n            .MinimumLevel.Override(\"Microsoft.Hosting.Lifetime\", LogEventLevel.Information)\n            .MinimumLevel.Override(\"System\", LogEventLevel.Warning)\n            .MinimumLevel.Override(\"Microsoft.AspNetCore.Authentication\", LogEventLevel.Information)\n            .Enrich.FromLogContext()\n            //.WriteTo.File(@\"IdentityServer8_log.txt\")\n            // uncomment to write to Azure diagnostics stream\n            //.WriteTo.File(\n            //    @\"D:\\home\\LogFiles\\Application\\identityserver.txt\",\n            //    fileSizeLimitBytes: 1_000_000,\n            //    rollOnFileSizeLimit: true,\n            //    shared: true,\n            //    flushToDiskInterval: TimeSpan.FromSeconds(1))\n            .WriteTo.Console(outputTemplate: \"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}\", theme: AnsiConsoleTheme.Code)\n            .CreateLogger();\n\n        try\n        {\n            Log.Information(\"Starting host...\");\n            CreateHostBuilder(args).Build().Run();\n            return 0;\n        }\n        catch (Exception ex)\n        {\n            Log.Fatal(ex, \"Host terminated unexpectedly.\");\n            return 1;\n        }\n        finally\n        {\n            Log.CloseAndFlush();\n        }\n    }\n\n    public static IHostBuilder CreateHostBuilder(string[] args) =>\n        Host.CreateDefaultBuilder(args)\n            .UseSerilog()\n            .ConfigureWebHostDefaults(webBuilder =>\n            {\n                webBuilder.UseStartup<Startup>();\n            });\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Host\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001;http://localhost:5000\"\n    },\n    \"Host (proxy)\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"https://identityserver.local\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"https://localhost:5001;http://localhost:5000\"\n    }\n  }\n}"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/AccountController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller implements a typical login/logout/provision workflow for local and external accounts.\n/// The login service encapsulates the interactions with the user data store. This data store is in-memory only and cannot be used for production!\n/// The interaction service provides a way for the UI to communicate with identityserver for validation and context retrieval\n/// </summary>\n[SecurityHeaders]\n[AllowAnonymous]\npublic class AccountController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly IAuthenticationSchemeProvider _schemeProvider;\n    private readonly IEventService _events;\n\n    public AccountController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IAuthenticationSchemeProvider schemeProvider,\n        IEventService events,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _schemeProvider = schemeProvider;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Entry point into the login workflow\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Login(string returnUrl)\n    {\n        // build a model so we know what to show on the login page\n        var vm = await BuildLoginViewModelAsync(returnUrl);\n\n        if (vm.IsExternalLoginOnly)\n        {\n            // we only have one option for logging in and it's an external provider\n            return returnUrl.IsAllowedRedirect() ? RedirectToAction(\"Challenge\", \"External\", new { scheme = vm.ExternalLoginScheme, returnUrl = returnUrl.SanitizeForRedirect() }) : Forbid();\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Login(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (ModelState.IsValid)\n        {\n            // validate username/password against in-memory store\n            if (_users.ValidateCredentials(model.Username, model.Password))\n            {\n                var user = _users.FindByUsername(model.Username);\n                await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId: context?.Client.ClientId));\n\n                // only set explicit expiration here if user chooses \"remember me\". \n                // otherwise we rely upon expiration configured in cookie middleware.\n                AuthenticationProperties props = null;\n                if (AccountOptions.AllowRememberLogin && model.RememberLogin)\n                {\n                    props = new AuthenticationProperties\n                    {\n                        IsPersistent = true,\n                        ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)\n                    };\n                };\n\n                // issue authentication cookie with subject ID and username\n                var isuser = new IdentityServerUser(user.SubjectId)\n                {\n                    DisplayName = user.Username\n                };\n\n                await HttpContext.SignInAsync(isuser, props);\n\n                if (context != null)\n                {\n                    if (context.IsNativeClient())\n                    {\n                        // The client is native, so this change in how to\n                        // return the response is for better UX for the end user.\n                        return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                    }\n\n                    // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n\n                // request for a local page\n                if (Url.IsLocalUrl(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n                }\n                else if (string.IsNullOrEmpty(model.ReturnUrl))\n                {\n                    return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n                }\n                else\n                {\n                    // user might have clicked on a malicious link - should be logged\n                    throw new Exception(\"invalid return URL\");\n                }\n            }\n\n            await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, \"invalid credentials\", clientId: context?.Client.ClientId));\n            ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);\n        }\n\n        // something went wrong, show form with error\n        var vm = await BuildLoginViewModelAsync(model);\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle postback from username/password login\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> LoginCancel(LoginInputModel model)\n    {\n        // check if we are in the context of an authorization request\n        var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n\n        if (context != null)\n        {\n            // if the user cancels, send a result back into IdentityServer as if they \n            // denied the consent (even if this client does not require consent).\n            // this will send back an access denied OIDC error response to the client.\n            await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);\n\n            // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return model.ReturnUrl.IsAllowedRedirect() ? this.LoadingPage(\"Redirect\", model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n            }\n\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(model.ReturnUrl.SanitizeForRedirect()) : Forbid();\n        }\n        else\n        {\n            // since we don't have a valid context, then we just go back to the home page\n            return model.ReturnUrl.IsAllowedRedirect() ? Redirect(\"~/\") : Forbid();\n        }\n\n    }\n\n    /// <summary>\n    /// Show logout page\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Logout(string logoutId)\n    {\n        // build a model so the logout page knows what to display\n        var vm = await BuildLogoutViewModelAsync(logoutId);\n\n        if (vm.ShowLogoutPrompt == false)\n        {\n            // if the request for logout was properly authenticated from IdentityServer, then\n            // we don't need to show the prompt and can just log the user out directly.\n            return await Logout(vm);\n        }\n\n        return View(vm);\n    }\n\n    /// <summary>\n    /// Handle logout page postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Logout(LogoutInputModel model)\n    {\n        // build a model so the logged out page knows what to display\n        var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            // delete local authentication cookie\n            await HttpContext.SignOutAsync();\n\n            // raise the logout event\n            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));\n        }\n\n        // check if we need to trigger sign-out at an upstream identity provider\n        if (vm.TriggerExternalSignout)\n        {\n            // build a return URL so the upstream provider will redirect back\n            // to us after the user has logged out. this allows us to then\n            // complete our single sign-out processing.\n            string url = Url.Action(\"Logout\", new { logoutId = vm.LogoutId });\n\n            // this triggers a redirect to the external provider for sign-out\n            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);\n        }\n\n        return View(\"LoggedOut\", vm);\n    }\n\n    [HttpGet]\n    public IActionResult AccessDenied()\n    {\n        return View();\n    }\n\n\n    /*****************************************/\n    /* helper APIs for the AccountController */\n    /*****************************************/\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)\n    {\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP) != null)\n        {\n            var local = context.IdP == IdentityServer8.IdentityServerConstants.LocalIdentityProvider;\n\n            // this is meant to short circuit the UI and only trigger the one external IdP\n            var vm = new LoginViewModel\n            {\n                EnableLocalLogin = local,\n                ReturnUrl = returnUrl,\n                Username = context?.LoginHint,\n            };\n\n            if (!local)\n            {\n                vm.ExternalProviders = new[] { new ExternalProvider { AuthenticationScheme = context.IdP } };\n            }\n\n            return vm;\n        }\n\n        var schemes = await _schemeProvider.GetAllSchemesAsync();\n\n        var providers = schemes\n            .Where(x => x.DisplayName != null)\n            .Select(x => new ExternalProvider\n            {\n                DisplayName = x.DisplayName ?? x.Name,\n                AuthenticationScheme = x.Name\n            }).ToList();\n\n        var allowLocal = true;\n        if (context?.Client.ClientId != null)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(context.Client.ClientId);\n            if (client != null)\n            {\n                allowLocal = client.EnableLocalLogin;\n\n                if (client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any())\n                {\n                    providers = providers.Where(provider => client.IdentityProviderRestrictions.Contains(provider.AuthenticationScheme)).ToList();\n                }\n            }\n        }\n\n        return new LoginViewModel\n        {\n            AllowRememberLogin = AccountOptions.AllowRememberLogin,\n            EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,\n            ReturnUrl = returnUrl,\n            Username = context?.LoginHint,\n            ExternalProviders = providers.ToArray()\n        };\n    }\n\n    private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)\n    {\n        var vm = await BuildLoginViewModelAsync(model.ReturnUrl);\n        vm.Username = model.Username;\n        vm.RememberLogin = model.RememberLogin;\n        return vm;\n    }\n\n    private async Task<LogoutViewModel> BuildLogoutViewModelAsync(string logoutId)\n    {\n        var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };\n\n        if (User?.Identity.IsAuthenticated != true)\n        {\n            // if the user is not authenticated, then just show logged out page\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        var context = await _interaction.GetLogoutContextAsync(logoutId);\n        if (context?.ShowSignoutPrompt == false)\n        {\n            // it's safe to automatically sign-out\n            vm.ShowLogoutPrompt = false;\n            return vm;\n        }\n\n        // show the logout prompt. this prevents attacks where the user\n        // is automatically signed out by another malicious web page.\n        return vm;\n    }\n\n    private async Task<LoggedOutViewModel> BuildLoggedOutViewModelAsync(string logoutId)\n    {\n        // get context information (client name, post logout redirect URI and iframe for federated signout)\n        var logout = await _interaction.GetLogoutContextAsync(logoutId);\n\n        var vm = new LoggedOutViewModel\n        {\n            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,\n            PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,\n            ClientName = string.IsNullOrEmpty(logout?.ClientName) ? logout?.ClientId : logout?.ClientName,\n            SignOutIframeUrl = logout?.SignOutIFrameUrl,\n            LogoutId = logoutId\n        };\n\n        if (User?.Identity.IsAuthenticated == true)\n        {\n            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;\n            if (idp != null && idp != IdentityServer8.IdentityServerConstants.LocalIdentityProvider)\n            {\n                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);\n                if (providerSupportsSignout)\n                {\n                    if (vm.LogoutId == null)\n                    {\n                        // if there's no current logout context, we need to create one\n                        // this captures necessary info from the current logged in user\n                        // before we signout and redirect away to the external IdP for signout\n                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();\n                    }\n\n                    vm.ExternalAuthenticationScheme = idp;\n                }\n            }\n        }\n\n        return vm;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/AccountOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class AccountOptions\n{\n    public static bool AllowLocalLogin = true;\n    public static bool AllowRememberLogin = true;\n    public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);\n\n    public static bool ShowLogoutPrompt = true;\n    public static bool AutomaticRedirectAfterSignOut = false;\n\n    public static string InvalidCredentialsErrorMessage = \"Invalid username or password\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/ExternalController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class ExternalController : Controller\n{\n    private readonly TestUserStore _users;\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clientStore;\n    private readonly ILogger<ExternalController> _logger;\n    private readonly IEventService _events;\n\n    public ExternalController(\n        IIdentityServerInteractionService interaction,\n        IClientStore clientStore,\n        IEventService events,\n        ILogger<ExternalController> logger,\n        TestUserStore users = null)\n    {\n        // if the TestUserStore is not in DI, then we'll just use the global users collection\n        // this is where you would plug in your own custom identity management library (e.g. ASP.NET Identity)\n        _users = users ?? new TestUserStore(TestUsers.Users);\n\n        _interaction = interaction;\n        _clientStore = clientStore;\n        _logger = logger;\n        _events = events;\n    }\n\n    /// <summary>\n    /// initiate roundtrip to external authentication provider\n    /// </summary>\n    [HttpGet]\n    public IActionResult Challenge(string scheme, string returnUrl)\n    {\n        if (string.IsNullOrEmpty(returnUrl)) returnUrl = \"~/\";\n\n        // validate returnUrl - either it is a valid OIDC URL or back to a local page\n        if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)\n        {\n            // user might have clicked on a malicious link - should be logged\n            throw new Exception(\"invalid return URL\");\n        }\n        \n        // start challenge and roundtrip the return URL and scheme \n        var props = new AuthenticationProperties\n        {\n            RedirectUri = Url.Action(nameof(Callback)), \n            Items =\n            {\n                { \"returnUrl\", returnUrl }, \n                { \"scheme\", scheme },\n            }\n        };\n\n        return Challenge(props, scheme);\n        \n    }\n\n    /// <summary>\n    /// Post processing of external authentication\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Callback()\n    {\n        // read external identity from the temporary cookie\n        var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n        if (result?.Succeeded != true)\n        {\n            throw new Exception(\"External authentication error\");\n        }\n\n        if (_logger.IsEnabled(LogLevel.Debug))\n        {\n            var externalClaims = result.Principal.Claims.Select(c => $\"{c.Type}: {c.Value}\");\n            _logger.LogDebug(\"External claims: {@claims}\", externalClaims);\n        }\n\n        // lookup our user and external provider info\n        var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);\n        if (user == null)\n        {\n            // this might be where you might initiate a custom workflow for user registration\n            // in this sample we don't show how that would be done, as our sample implementation\n            // simply auto-provisions new external user\n            user = AutoProvisionUser(provider, providerUserId, claims);\n        }\n\n        // this allows us to collect any additional claims or properties\n        // for the specific protocols used and store them in the local auth cookie.\n        // this is typically used to store data needed for signout from those protocols.\n        var additionalLocalClaims = new List<Claim>();\n        var localSignInProps = new AuthenticationProperties();\n        ProcessLoginCallback(result, additionalLocalClaims, localSignInProps);\n        \n        // issue authentication cookie for user\n        var isuser = new IdentityServerUser(user.SubjectId)\n        {\n            DisplayName = user.Username,\n            IdentityProvider = provider,\n            AdditionalClaims = additionalLocalClaims\n        };\n\n        await HttpContext.SignInAsync(isuser, localSignInProps);\n\n        // delete temporary cookie used during external authentication\n        await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        // retrieve return URL\n        var returnUrl = result.Properties.Items[\"returnUrl\"] ?? \"~/\";\n\n        // check if external login is in the context of an OIDC request\n        var context = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.Client.ClientId));\n\n        if (context != null)\n        {\n            if (context.IsNativeClient())\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", returnUrl);\n            }\n        }\n\n        return Redirect(returnUrl);\n    }\n\n    private (TestUser user, string provider, string providerUserId, IEnumerable<Claim> claims) FindUserFromExternalProvider(AuthenticateResult result)\n    {\n        var externalUser = result.Principal;\n\n        // try to determine the unique id of the external user (issued by the provider)\n        // the most common claim type for that are the sub claim and the NameIdentifier\n        // depending on the external provider, some other claim type might be used\n        var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ??\n                          externalUser.FindFirst(ClaimTypes.NameIdentifier) ??\n                          throw new Exception(\"Unknown userid\");\n\n        // remove the user id claim so we don't include it as an extra claim if/when we provision the user\n        var claims = externalUser.Claims.ToList();\n        claims.Remove(userIdClaim);\n\n        var provider = result.Properties.Items[\"scheme\"];\n        var providerUserId = userIdClaim.Value;\n\n        // find external user\n        var user = _users.FindByExternalProvider(provider, providerUserId);\n\n        return (user, provider, providerUserId, claims);\n    }\n\n    private TestUser AutoProvisionUser(string provider, string providerUserId, IEnumerable<Claim> claims)\n    {\n        var user = _users.AutoProvisionUser(provider, providerUserId, claims.ToList());\n        return user;\n    }\n\n    // if the external login is OIDC-based, there are certain things we need to preserve to make logout work\n    // this will be different for WS-Fed, SAML2p or other protocols\n    private void ProcessLoginCallback(AuthenticateResult externalResult, List<Claim> localClaims, AuthenticationProperties localSignInProps)\n    {\n        // if the external system sent a session id claim, copy it over\n        // so we can use it for single sign-out\n        var sid = externalResult.Principal.Claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);\n        if (sid != null)\n        {\n            localClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));\n        }\n\n        // if the external provider issued an id_token, we'll keep it for signout\n        var idToken = externalResult.Properties.GetTokenValue(\"id_token\");\n        if (idToken != null)\n        {\n            localSignInProps.StoreTokens(new[] { new AuthenticationToken { Name = \"id_token\", Value = idToken } });\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/ExternalProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ExternalProvider\n{\n    public string DisplayName { get; set; }\n    public string AuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/LoggedOutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoggedOutViewModel\n{\n    public string PostLogoutRedirectUri { get; set; }\n    public string ClientName { get; set; }\n    public string SignOutIframeUrl { get; set; }\n\n    public bool AutomaticRedirectAfterSignOut { get; set; }\n\n    public string LogoutId { get; set; }\n    public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;\n    public string ExternalAuthenticationScheme { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/LoginInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginInputModel\n{\n    [Required]\n    public string Username { get; set; }\n    [Required]\n    public string Password { get; set; }\n    public bool RememberLogin { get; set; }\n    public string ReturnUrl { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/LoginViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LoginViewModel : LoginInputModel\n{\n    public bool AllowRememberLogin { get; set; } = true;\n    public bool EnableLocalLogin { get; set; } = true;\n\n    public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();\n    public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));\n\n    public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;\n    public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/LogoutInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutInputModel\n{\n    public string LogoutId { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/LogoutViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class LogoutViewModel : LogoutInputModel\n{\n    public bool ShowLogoutPrompt { get; set; } = true;\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Account/RedirectViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class RedirectViewModel\n{\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Consent/ConsentController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This controller processes the consent UI\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class ConsentController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly ILogger<ConsentController> _logger;\n\n    public ConsentController(\n        IIdentityServerInteractionService interaction,\n        IEventService events,\n        ILogger<ConsentController> logger)\n    {\n        _interaction = interaction;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Shows the consent screen\n    /// </summary>\n    /// <param name=\"returnUrl\"></param>\n    /// <returns></returns>\n    [HttpGet]\n    public async Task<IActionResult> Index(string returnUrl)\n    {\n        var vm = await BuildViewModelAsync(returnUrl);\n        if (vm != null)\n        {\n            return View(\"Index\", vm);\n        }\n\n        return View(\"Error\");\n    }\n\n    /// <summary>\n    /// Handles the consent screen postback\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Index(ConsentInputModel model)\n    {\n        var result = await ProcessConsent(model);\n\n        if (result.IsRedirect)\n        {\n            var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n            if (context?.IsNativeClient() == true)\n            {\n                // The client is native, so this change in how to\n                // return the response is for better UX for the end user.\n                return this.LoadingPage(\"Redirect\", result.RedirectUri);\n            }\n            return result.RedirectUri.IsAllowedRedirect() ? Redirect(result.RedirectUri.SanitizeForRedirect()) : Forbid();\n        }\n\n        if (result.HasValidationError)\n        {\n            ModelState.AddModelError(string.Empty, result.ValidationError);\n        }\n\n        if (result.ShowView)\n        {\n            return View(\"Index\", result.ViewModel);\n        }\n\n        return View(\"Error\");\n    }\n\n    /*****************************************/\n    /* helper APIs for the ConsentController */\n    /*****************************************/\n    private async Task<ProcessConsentResult> ProcessConsent(ConsentInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        // validate return url is still valid\n        var request = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model?.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model?.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.GrantConsentAsync(request, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.ReturnUrl, model);\n        }\n\n        return result;\n    }\n\n    private async Task<ConsentViewModel> BuildViewModelAsync(string returnUrl, ConsentInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(returnUrl);\n        if (request != null)\n        {\n            return CreateConsentViewModel(model, returnUrl, request);\n        }\n        else\n        {\n            _logger.LogError(\"No consent request matching request: {0}\", returnUrl.SanitizeForLog());\n        }\n\n        return null;\n    }\n\n    private ConsentViewModel CreateConsentViewModel(\n        ConsentInputModel model, string returnUrl,\n        AuthorizationRequest request)\n    {\n        var vm = new ConsentViewModel\n        {\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n            Description = model?.Description,\n\n            ReturnUrl = returnUrl,\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach(var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        var displayName = apiScope.DisplayName ?? apiScope.Name;\n        if (!String.IsNullOrWhiteSpace(parsedScopeValue.ParsedParameter))\n        {\n            displayName += \":\" + parsedScopeValue.ParsedParameter;\n        }\n\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            DisplayName = displayName,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Consent/ConsentInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentInputModel\n{\n    public string Button { get; set; }\n    public IEnumerable<string> ScopesConsented { get; set; }\n    public bool RememberConsent { get; set; }\n    public string ReturnUrl { get; set; }\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Consent/ConsentOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentOptions\n{\n    public static bool EnableOfflineAccess = true;\n    public static string OfflineAccessDisplayName = \"Offline Access\";\n    public static string OfflineAccessDescription = \"Access to your applications and resources, even when you are offline\";\n\n    public static readonly string MustChooseOneErrorMessage = \"You must pick at least one permission\";\n    public static readonly string InvalidSelectionErrorMessage = \"Invalid selection\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Consent/ConsentViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ConsentViewModel : ConsentInputModel\n{\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public bool AllowRememberConsent { get; set; }\n\n    public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }\n    public IEnumerable<ScopeViewModel> ApiScopes { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Consent/ProcessConsentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ProcessConsentResult\n{\n    public bool IsRedirect => RedirectUri != null;\n    public string RedirectUri { get; set; }\n    public Client Client { get; set; }\n\n    public bool ShowView => ViewModel != null;\n    public ConsentViewModel ViewModel { get; set; }\n\n    public bool HasValidationError => ValidationError != null;\n    public string ValidationError { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Consent/ScopeViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ScopeViewModel\n{\n    public string Value { get; set; }\n    public string DisplayName { get; set; }\n    public string Description { get; set; }\n    public bool Emphasize { get; set; }\n    public bool Required { get; set; }\n    public bool Checked { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Device/DeviceAuthorizationInputModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationInputModel : ConsentInputModel\n{\n    public string UserCode { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Device/DeviceAuthorizationViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DeviceAuthorizationViewModel : ConsentViewModel\n{\n    public string UserCode { get; set; }\n    public bool ConfirmUserCode { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Device/DeviceController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[Authorize]\n[SecurityHeaders]\npublic class DeviceController : Controller\n{\n    private readonly IDeviceFlowInteractionService _interaction;\n    private readonly IEventService _events;\n    private readonly IOptions<IdentityServerOptions> _options;\n    private readonly ILogger<DeviceController> _logger;\n\n    public DeviceController(\n        IDeviceFlowInteractionService interaction,\n        IEventService eventService,\n        IOptions<IdentityServerOptions> options,\n        ILogger<DeviceController> logger)\n    {\n        _interaction = interaction;\n        _events = eventService;\n        _options = options;\n        _logger = logger;\n    }\n\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        string userCodeParamName = _options.Value.UserInteraction.DeviceVerificationUserCodeParameter;\n        string userCode = Request.Query[userCodeParamName];\n        if (string.IsNullOrWhiteSpace(userCode)) return View(\"UserCodeCapture\");\n\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        vm.ConfirmUserCode = true;\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> UserCodeCapture(string userCode)\n    {\n        var vm = await BuildViewModelAsync(userCode);\n        if (vm == null) return View(\"Error\");\n\n        return View(\"UserCodeConfirmation\", vm);\n    }\n\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Callback(DeviceAuthorizationInputModel model)\n    {\n        if (model == null) throw new ArgumentNullException(nameof(model));\n\n        var result = await ProcessConsent(model);\n        if (result.HasValidationError) return View(\"Error\");\n\n        return View(\"Success\");\n    }\n\n    private async Task<ProcessConsentResult> ProcessConsent(DeviceAuthorizationInputModel model)\n    {\n        var result = new ProcessConsentResult();\n\n        var request = await _interaction.GetAuthorizationContextAsync(model.UserCode);\n        if (request == null) return result;\n\n        ConsentResponse grantedConsent = null;\n\n        // user clicked 'no' - send back the standard 'access_denied' response\n        if (model.Button == \"no\")\n        {\n            grantedConsent = new ConsentResponse { Error = AuthorizationError.AccessDenied };\n\n            // emit event\n            await _events.RaiseAsync(new ConsentDeniedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues));\n        }\n        // user clicked 'yes' - validate the data\n        else if (model.Button == \"yes\")\n        {\n            // if the user consented to some scope, build the response model\n            if (model.ScopesConsented != null && model.ScopesConsented.Any())\n            {\n                var scopes = model.ScopesConsented;\n                if (ConsentOptions.EnableOfflineAccess == false)\n                {\n                    scopes = scopes.Where(x => x != IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n\n                grantedConsent = new ConsentResponse\n                {\n                    RememberConsent = model.RememberConsent,\n                    ScopesValuesConsented = scopes.ToArray(),\n                    Description = model.Description\n                };\n\n                // emit event\n                await _events.RaiseAsync(new ConsentGrantedEvent(User.GetSubjectId(), request.Client.ClientId, request.ValidatedResources.RawScopeValues, grantedConsent.ScopesValuesConsented, grantedConsent.RememberConsent));\n            }\n            else\n            {\n                result.ValidationError = ConsentOptions.MustChooseOneErrorMessage;\n            }\n        }\n        else\n        {\n            result.ValidationError = ConsentOptions.InvalidSelectionErrorMessage;\n        }\n\n        if (grantedConsent != null)\n        {\n            // communicate outcome of consent back to identityserver\n            await _interaction.HandleRequestAsync(model.UserCode, grantedConsent);\n\n            // indicate that's it ok to redirect back to authorization endpoint\n            result.RedirectUri = model.ReturnUrl;\n            result.Client = request.Client;\n        }\n        else\n        {\n            // we need to redisplay the consent UI\n            result.ViewModel = await BuildViewModelAsync(model.UserCode, model);\n        }\n\n        return result;\n    }\n\n    private async Task<DeviceAuthorizationViewModel> BuildViewModelAsync(string userCode, DeviceAuthorizationInputModel model = null)\n    {\n        var request = await _interaction.GetAuthorizationContextAsync(userCode);\n        if (request != null)\n        {\n            return CreateConsentViewModel(userCode, model, request);\n        }\n\n        return null;\n    }\n\n    private DeviceAuthorizationViewModel CreateConsentViewModel(string userCode, DeviceAuthorizationInputModel model, DeviceFlowAuthorizationRequest request)\n    {\n        var vm = new DeviceAuthorizationViewModel\n        {\n            UserCode = userCode,\n            Description = model?.Description,\n\n            RememberConsent = model?.RememberConsent ?? true,\n            ScopesConsented = model?.ScopesConsented ?? Enumerable.Empty<string>(),\n\n            ClientName = request.Client.ClientName ?? request.Client.ClientId,\n            ClientUrl = request.Client.ClientUri,\n            ClientLogoUrl = request.Client.LogoUri,\n            AllowRememberConsent = request.Client.AllowRememberConsent\n        };\n\n        vm.IdentityScopes = request.ValidatedResources.Resources.IdentityResources.Select(x => CreateScopeViewModel(x, vm.ScopesConsented.Contains(x.Name) || model == null)).ToArray();\n\n        var apiScopes = new List<ScopeViewModel>();\n        foreach (var parsedScope in request.ValidatedResources.ParsedScopes)\n        {\n            var apiScope = request.ValidatedResources.Resources.FindApiScope(parsedScope.ParsedName);\n            if (apiScope != null)\n            {\n                var scopeVm = CreateScopeViewModel(parsedScope, apiScope, vm.ScopesConsented.Contains(parsedScope.RawValue) || model == null);\n                apiScopes.Add(scopeVm);\n            }\n        }\n        if (ConsentOptions.EnableOfflineAccess && request.ValidatedResources.Resources.OfflineAccess)\n        {\n            apiScopes.Add(GetOfflineAccessScope(vm.ScopesConsented.Contains(IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess) || model == null));\n        }\n        vm.ApiScopes = apiScopes;\n\n        return vm;\n    }\n\n    private ScopeViewModel CreateScopeViewModel(IdentityResource identity, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = identity.Name,\n            DisplayName = identity.DisplayName ?? identity.Name,\n            Description = identity.Description,\n            Emphasize = identity.Emphasize,\n            Required = identity.Required,\n            Checked = check || identity.Required\n        };\n    }\n\n    public ScopeViewModel CreateScopeViewModel(ParsedScopeValue parsedScopeValue, ApiScope apiScope, bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = parsedScopeValue.RawValue,\n            // todo: use the parsed scope value in the display?\n            DisplayName = apiScope.DisplayName ?? apiScope.Name,\n            Description = apiScope.Description,\n            Emphasize = apiScope.Emphasize,\n            Required = apiScope.Required,\n            Checked = check || apiScope.Required\n        };\n    }\n    private ScopeViewModel GetOfflineAccessScope(bool check)\n    {\n        return new ScopeViewModel\n        {\n            Value = IdentityServer8.IdentityServerConstants.StandardScopes.OfflineAccess,\n            DisplayName = ConsentOptions.OfflineAccessDisplayName,\n            Description = ConsentOptions.OfflineAccessDescription,\n            Emphasize = true,\n            Checked = check\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Diagnostics/DiagnosticsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[Authorize]\npublic class DiagnosticsController : Controller\n{\n    public async Task<IActionResult> Index()\n    {\n        var localAddresses = new string[] { \"127.0.0.1\", \"::1\", HttpContext.Connection.LocalIpAddress.ToString() };\n        if (!localAddresses.Contains(HttpContext.Connection.RemoteIpAddress.ToString()))\n        {\n            return NotFound();\n        }\n\n        var model = new DiagnosticsViewModel(await HttpContext.AuthenticateAsync());\n        return View(model);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Diagnostics/DiagnosticsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class DiagnosticsViewModel\n{\n    public DiagnosticsViewModel(AuthenticateResult result)\n    {\n        AuthenticateResult = result;\n\n        if (result.Properties.Items.ContainsKey(\"client_list\"))\n        {\n            var encoded = result.Properties.Items[\"client_list\"];\n            var bytes = Base64Url.Decode(encoded);\n            var value = Encoding.UTF8.GetString(bytes);\n\n            Clients = JsonConvert.DeserializeObject<string[]>(value);\n        }\n    }\n\n    public AuthenticateResult AuthenticateResult { get; }\n    public IEnumerable<string> Clients { get; } = new List<string>();\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic static class Extensions\n{\n    /// <summary>\n    /// Checks if the redirect URI is for a native client.\n    /// </summary>\n    /// <returns></returns>\n    public static bool IsNativeClient(this AuthorizationRequest context)\n    {\n        return !context.RedirectUri.StartsWith(\"https\", StringComparison.Ordinal)\n           && !context.RedirectUri.StartsWith(\"http\", StringComparison.Ordinal);\n    }\n\n    public static IActionResult LoadingPage(this Controller controller, string viewName, string redirectUri)\n    {\n        controller.HttpContext.Response.StatusCode = 200;\n        controller.HttpContext.Response.Headers[\"Location\"] = \"\";\n        \n        return controller.View(viewName, new RedirectViewModel { RedirectUrl = redirectUri });\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Grants/GrantsController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n/// <summary>\n/// This sample controller allows a user to revoke grants given to clients\n/// </summary>\n[SecurityHeaders]\n[Authorize]\npublic class GrantsController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IClientStore _clients;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n\n    public GrantsController(IIdentityServerInteractionService interaction,\n        IClientStore clients,\n        IResourceStore resources,\n        IEventService events)\n    {\n        _interaction = interaction;\n        _clients = clients;\n        _resources = resources;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Show list of grants\n    /// </summary>\n    [HttpGet]\n    public async Task<IActionResult> Index()\n    {\n        return View(\"Index\", await BuildViewModelAsync());\n    }\n\n    /// <summary>\n    /// Handle postback to revoke a client\n    /// </summary>\n    [HttpPost]\n    [ValidateAntiForgeryToken]\n    public async Task<IActionResult> Revoke(string clientId)\n    {\n        await _interaction.RevokeUserConsentAsync(clientId);\n        await _events.RaiseAsync(new GrantsRevokedEvent(User.GetSubjectId(), clientId));\n\n        return RedirectToAction(\"Index\");\n    }\n\n    private async Task<GrantsViewModel> BuildViewModelAsync()\n    {\n        var grants = await _interaction.GetAllUserGrantsAsync();\n\n        var list = new List<GrantViewModel>();\n        foreach(var grant in grants)\n        {\n            var client = await _clients.FindClientByIdAsync(grant.ClientId);\n            if (client != null)\n            {\n                var resources = await _resources.FindResourcesByScopeAsync(grant.Scopes);\n\n                var item = new GrantViewModel()\n                {\n                    ClientId = client.ClientId,\n                    ClientName = client.ClientName ?? client.ClientId,\n                    ClientLogoUrl = client.LogoUri,\n                    ClientUrl = client.ClientUri,\n                    Description = grant.Description,\n                    Created = grant.CreationTime,\n                    Expires = grant.Expiration,\n                    IdentityGrantNames = resources.IdentityResources.Select(x => x.DisplayName ?? x.Name).ToArray(),\n                    ApiGrantNames = resources.ApiScopes.Select(x => x.DisplayName ?? x.Name).ToArray()\n                };\n\n                list.Add(item);\n            }\n        }\n\n        return new GrantsViewModel\n        {\n            Grants = list\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Grants/GrantsViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class GrantsViewModel\n{\n    public IEnumerable<GrantViewModel> Grants { get; set; }\n}\n\npublic class GrantViewModel\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string ClientUrl { get; set; }\n    public string ClientLogoUrl { get; set; }\n    public string Description { get; set; }\n    public DateTime Created { get; set; }\n    public DateTime? Expires { get; set; }\n    public IEnumerable<string> IdentityGrantNames { get; set; }\n    public IEnumerable<string> ApiGrantNames { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Home/ErrorViewModel.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class ErrorViewModel\n{\n    public ErrorViewModel()\n    {\n    }\n\n    public ErrorViewModel(string error)\n    {\n        Error = new ErrorMessage { Error = error };\n    }\n\n    public ErrorMessage Error { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/Home/HomeController.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\n[SecurityHeaders]\n[AllowAnonymous]\npublic class HomeController : Controller\n{\n    private readonly IIdentityServerInteractionService _interaction;\n    private readonly IWebHostEnvironment _environment;\n    private readonly ILogger _logger;\n\n    public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger<HomeController> logger)\n    {\n        _interaction = interaction;\n        _environment = environment;\n        _logger = logger;\n    }\n\n    public IActionResult Index()\n    {\n        if (_environment.IsDevelopment())\n        {\n            // only show in development\n            return View();\n        }\n\n        _logger.LogInformation(\"Homepage is disabled in production. Returning 404.\");\n        return NotFound();\n    }\n\n    /// <summary>\n    /// Shows the error page\n    /// </summary>\n    public async Task<IActionResult> Error(string errorId)\n    {\n        var vm = new ErrorViewModel();\n\n        // retrieve error details from identityserver\n        var message = await _interaction.GetErrorContextAsync(errorId);\n        if (message != null)\n        {\n            vm.Error = message;\n\n            if (!_environment.IsDevelopment())\n            {\n                // only show in development\n                message.ErrorDescription = null;\n            }\n        }\n\n        return View(\"Error\", vm);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/SecurityHeadersAttribute.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class SecurityHeadersAttribute : ActionFilterAttribute\n{\n    public override void OnResultExecuting(ResultExecutingContext context)\n    {\n        var result = context.Result;\n        if (result is ViewResult)\n        {\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Type-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Type-Options\", \"nosniff\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Frame-Options\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Frame-Options\", \"SAMEORIGIN\");\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n            var csp = \"default-src 'self'; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';\";\n            // also consider adding upgrade-insecure-requests once you have HTTPS in place for production\n            //csp += \"upgrade-insecure-requests;\";\n            // also an example if you need client images to be displayed from twitter\n            // csp += \"img-src 'self' https://pbs.twimg.com;\";\n\n            // once for standards compliant browsers\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Content-Security-Policy\", csp);\n            }\n            // and once again for IE\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"X-Content-Security-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"X-Content-Security-Policy\", csp);\n            }\n\n            // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy\n            var referrer_policy = \"no-referrer\";\n            if (!context.HttpContext.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n            {\n                context.HttpContext.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Quickstart/TestUsers.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonSerializer = System.Text.Json.JsonSerializer;\n\nnamespace IdentityServerHost.Quickstart.UI;\n\npublic class TestUsers\n{\n    public static List<TestUser> Users\n    {\n        get\n        {\n            var address = new\n            {\n                street_address = \"One Hacker Way\",\n                locality = \"Heidelberg\",\n                postal_code = 69118,\n                country = \"Germany\"\n            };\n            \n            return new List<TestUser>\n            {\n                new TestUser\n                {\n                    SubjectId = \"818727\",\n                    Username = \"alice\",\n                    Password = \"alice\",\n                    Claims =\n                    {\n                        new Claim(JwtClaimTypes.Name, \"Alice Smith\"),\n                        new Claim(JwtClaimTypes.GivenName, \"Alice\"),\n                        new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                        new Claim(JwtClaimTypes.Email, \"AliceSmith@email.com\"),\n                        new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                        new Claim(JwtClaimTypes.WebSite, \"http://alice.com\"),\n                        new Claim(JwtClaimTypes.Address, JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json)\n                    }\n                },\n                new TestUser\n                {\n                    SubjectId = \"88421113\",\n                    Username = \"bob\",\n                    Password = \"bob\",\n                    Claims =\n                    {\n                        new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                        new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                        new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                        new Claim(JwtClaimTypes.Email, \"BobSmith@email.com\"),\n                        new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                        new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                        new Claim(JwtClaimTypes.Address, JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json)\n                    }\n                }\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Resources = IdentityServerHost.Configuration.Resources;\nusing IdentityServerHost.Extensions;\n\nnamespace IdentityServerHost;\n\npublic class Startup\n{\n    private readonly IConfiguration _config;\n\n    public Startup(IConfiguration config)\n    {\n        _config = config;\n\n        IdentityModelEventSource.ShowPII = true;\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddControllersWithViews();\n        \n        // cookie policy to deal with temporary browser incompatibilities\n        services.AddSameSiteCookiePolicy();\n\n        var builder = services.AddIdentityServer(options =>\n            {\n                options.Events.RaiseSuccessEvents = true;\n                options.Events.RaiseFailureEvents = true;\n                options.Events.RaiseErrorEvents = true;\n                options.Events.RaiseInformationEvents = true;\n\n                options.EmitScopesAsSpaceDelimitedStringInJwt = true;\n\n                options.MutualTls.Enabled = true;\n                options.MutualTls.DomainName = \"mtls\";\n                //options.MutualTls.AlwaysEmitConfirmationClaim = true;\n            })\n            .AddInMemoryClients(Clients.Get())\n            .AddInMemoryIdentityResources(Resources.IdentityResources)\n            .AddInMemoryApiScopes(Resources.ApiScopes)\n            .AddInMemoryApiResources(Resources.ApiResources)\n            .AddSigningCredential()\n            .AddExtensionGrantValidator<Extensions.ExtensionGrantValidator>()\n            .AddExtensionGrantValidator<Extensions.NoSubjectExtensionGrantValidator>()\n            .AddJwtBearerClientAuthentication()\n            .AddAppAuthRedirectUriValidator()\n            .AddTestUsers(TestUsers.Users)\n            .AddProfileService<HostProfileService>()\n            .AddCustomTokenRequestValidator<ParameterizedScopeTokenRequestValidator>()\n            .AddScopeParser<ParameterizedScopeParser>()\n            .AddMutualTlsSecretValidators();\n\n        // use this for persisted grants store\n        // var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;\n        // const string connectionString = \"DataSource=identityserver.db\";\n        // builder.AddOperationalStore(options =>\n        // {\n        //     options.ConfigureDbContext = b => b.UseSqlite(connectionString,\n        //         sql => sql.MigrationsAssembly(migrationsAssembly));\n        // });\n            \n\n        services.AddExternalIdentityProviders();\n\n        services.AddAuthentication()\n            .AddCertificate(options =>\n            {\n                options.AllowedCertificateTypes = CertificateTypes.All;\n                options.RevocationMode = X509RevocationMode.NoCheck;\n            });\n        \n        services.AddCertificateForwardingForNginx();\n        \n        services.AddLocalApiAuthentication(principal =>\n        {\n            principal.Identities.First().AddClaim(new Claim(\"additional_claim\", \"additional_value\"));\n\n            return Task.FromResult(principal);\n        });\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        // use this for persisted grants store\n        // app.InitializePersistedGrantsStore();\n        \n        app.UseForwardedHeaders(new ForwardedHeadersOptions\n        {\n            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto\n        });\n\n        app.UseCertificateForwarding();\n        app.UseCookiePolicy();\n        \n        app.UseSerilogRequestLogging();\n\n        app.UseDeveloperExceptionPage();\n        app.UseStaticFiles();\n\n        app.UseRouting();\n        app.UseIdentityServer();\n\n        app.UseAuthorization();\n\n        app.UseEndpoints(endpoints =>\n        {\n            endpoints.MapDefaultControllerRoute();\n        });\n    }\n}\n\npublic static class BuilderExtensions\n{\n    public static IIdentityServerBuilder AddSigningCredential(this IIdentityServerBuilder builder)\n    {\n        // create random RS256 key\n        //builder.AddDeveloperSigningCredential();\n\n        // use an RSA-based certificate with RS256\n        var rsaCert = new X509Certificate2(\"./keys/identityserver.test.rsa.p12\", \"changeit\");\n        builder.AddSigningCredential(rsaCert, \"RS256\");\n\n        // ...and PS256\n        builder.AddSigningCredential(rsaCert, \"PS256\");\n\n        // or manually extract ECDSA key from certificate (directly using the certificate is not support by Microsoft right now)\n        var ecCert = new X509Certificate2(\"./keys/identityserver.test.ecdsa.p12\", \"changeit\");\n        var key = new ECDsaSecurityKey(ecCert.GetECDsaPrivateKey())\n        {\n            KeyId = CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex)\n        };\n\n        return builder.AddSigningCredential(\n            key,\n            IdentityServerConstants.ECDsaSigningAlgorithm.ES256);\n    }\n\n    // use this for persisted grants store\n    // public static void InitializePersistedGrantsStore(this IApplicationBuilder app)\n    // {\n    //     using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())\n    //     {\n    //         serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();\n    //     }\n    // }\n}\n\npublic static class ServiceExtensions\n{\n    public static IServiceCollection AddExternalIdentityProviders(this IServiceCollection services)\n    {\n        // configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache.\n        services.AddOidcStateDataFormatterCache(\"aad\", \"demoidsrv\");\n\n        services.AddAuthentication()\n            .AddOpenIdConnect(\"Google\", \"Google\", options =>\n             {\n                 options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n                 options.ForwardSignOut = IdentityServerConstants.DefaultCookieAuthenticationScheme;\n\n                 options.Authority = \"https://accounts.google.com/\";\n                 options.ClientId = \"708996912208-9m4dkjb5hscn7cjrn5u0r4tbgkbj1fko.apps.googleusercontent.com\";\n\n                 options.CallbackPath = \"/signin-google\";\n                 options.Scope.Add(\"email\");\n             })\n            .AddOpenIdConnect(\"demoidsrv\", \"IdentityServer\", options =>\n            {\n                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n                options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n\n                options.Authority = \"https://demo.identityserver8.io/\";\n                options.ClientId = \"login\";\n                options.ResponseType = \"id_token\";\n                options.SaveTokens = true;\n                options.CallbackPath = \"/signin-idsrv\";\n                options.SignedOutCallbackPath = \"/signout-callback-idsrv\";\n                options.RemoteSignOutPath = \"/signout-idsrv\";\n\n                options.TokenValidationParameters = new TokenValidationParameters\n                {\n                    NameClaimType = \"name\",\n                    RoleClaimType = \"role\"\n                };\n            })\n            .AddOpenIdConnect(\"aad\", \"Azure AD\", options =>\n            {\n                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n                options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n\n                options.Authority = \"https://login.windows.net/4ca9cb4c-5e5f-4be9-b700-c532992a3705\";\n                options.ClientId = \"96e3c53e-01cb-4244-b658-a42164cb67a9\";\n                options.ResponseType = \"id_token\";\n                options.CallbackPath = \"/signin-aad\";\n                options.SignedOutCallbackPath = \"/signout-callback-aad\";\n                options.RemoteSignOutPath = \"/signout-aad\";\n                options.TokenValidationParameters = new TokenValidationParameters\n                {\n                    NameClaimType = \"name\",\n                    RoleClaimType = \"role\"\n                };\n            })\n            .AddOpenIdConnect(\"adfs\", \"ADFS\", options =>\n            {\n                options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n                options.SignOutScheme = IdentityServerConstants.SignoutScheme;\n\n                options.Authority = \"https://adfs.leastprivilege.vm/adfs\";\n                options.ClientId = \"c0ea8d99-f1e7-43b0-a100-7dee3f2e5c3c\";\n                options.ResponseType = \"id_token\";\n\n                options.CallbackPath = \"/signin-adfs\";\n                options.SignedOutCallbackPath = \"/signout-callback-adfs\";\n                options.RemoteSignOutPath = \"/signout-adfs\";\n                options.TokenValidationParameters = new TokenValidationParameters\n                {\n                    NameClaimType = \"name\",\n                    RoleClaimType = \"role\"\n                };\n            });\n\n        return services;\n    }\n\n    public static void AddCertificateForwardingForNginx(this IServiceCollection services)\n    {\n        services.AddCertificateForwarding(options =>\n        {\n            options.CertificateHeader = \"X-SSL-CERT\";\n\n            options.HeaderConverter = (headerValue) =>\n            {\n                X509Certificate2 clientCertificate = null;\n\n                if(!string.IsNullOrWhiteSpace(headerValue))\n                {\n                    byte[] bytes = Encoding.UTF8.GetBytes(Uri.UnescapeDataString(headerValue));\n                    clientCertificate = new X509Certificate2(bytes);\n                }\n\n                return clientCertificate;\n            };\n        });\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Account/AccessDenied.cshtml",
    "content": "﻿\n<div class=\"container\">\n    <div class=\"lead\">\n        <h1>Access Denied</h1>\n        <p>You do not have access to that resource.</p>\n    </div>\n</div>"
  },
  {
    "path": "src/IdentityServer8/host/Views/Account/LoggedOut.cshtml",
    "content": "﻿@model LoggedOutViewModel\n\n@{ \n    // set this so the layout rendering sees an anonymous user\n    ViewData[\"signed-out\"] = true;\n}\n\n<div class=\"logged-out-page\">\n    <h1>\n        Logout\n        <small>You are now logged out</small>\n    </h1>\n\n    @if (Model.PostLogoutRedirectUri != null)\n    {\n        <div>\n            Click <a class=\"PostLogoutRedirectUri\" href=\"@Model.PostLogoutRedirectUri\">here</a> to return to the\n            <span>@Model.ClientName</span> application.\n        </div>\n    }\n\n    @if (Model.SignOutIframeUrl != null)\n    {\n        <iframe width=\"0\" height=\"0\" class=\"signout\" src=\"@Model.SignOutIframeUrl\"></iframe>\n    }\n</div>\n\n@section scripts\n{\n    @if (Model.AutomaticRedirectAfterSignOut)\n    {\n        <script src=\"~/js/signout-redirect.js\"></script>\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Account/Login.cshtml",
    "content": "@model LoginViewModel\n\n<div class=\"login-page\">\n    <div class=\"lead\">\n        <h1>Login</h1>\n        <p>Choose how to login</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n\n        @if (Model.EnableLocalLogin)\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>Local Account</h2>\n                    </div>\n\n                    <div class=\"card-body\">\n                        <form asp-route=\"Login\">\n                            <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n\n                            <div class=\"form-group\">\n                                <label asp-for=\"Username\"></label>\n                                <input class=\"form-control\" placeholder=\"Username\" asp-for=\"Username\" autofocus>\n                            </div>\n                            <div class=\"form-group\">\n                                <label asp-for=\"Password\"></label>\n                                <input type=\"password\" class=\"form-control\" placeholder=\"Password\" asp-for=\"Password\" autocomplete=\"off\">\n                            </div>\n                            @if (Model.AllowRememberLogin)\n                            {\n                                <div class=\"form-group\">\n                                    <div class=\"form-check\">\n                                        <input class=\"form-check-input\" asp-for=\"RememberLogin\">\n                                        <label class=\"form-check-label\" asp-for=\"RememberLogin\">\n                                            Remember My Login\n                                        </label>\n                                    </div>\n                                </div>\n                            }\n                            <button class=\"btn btn-primary\" name=\"button\" value=\"login\">Login</button>\n                            <button class=\"btn btn-secondary\" name=\"button\" value=\"cancel\" formaction=\"/Account/LoginCancel\">Cancel</button>\n                        </form>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"col-sm-6\">\n                <div class=\"card\">\n                    <div class=\"card-header\">\n                        <h2>External Account</h2>\n                    </div>\n                    <div class=\"card-body\">\n                        <ul class=\"list-inline\">\n                            @foreach (var provider in Model.VisibleExternalProviders)\n                            {\n                                <li class=\"list-inline-item\">\n                                    <a class=\"btn btn-secondary\"\n                                       asp-controller=\"External\"\n                                       asp-action=\"Challenge\"\n                                       asp-route-scheme=\"@provider.AuthenticationScheme\"\n                                       asp-route-returnUrl=\"@Model.ReturnUrl\">\n                                        @provider.DisplayName\n                                    </a>\n                                </li>\n                            }\n                        </ul>\n                    </div>\n                </div>\n            </div>\n        }\n\n        @if (!Model.EnableLocalLogin && !Model.VisibleExternalProviders.Any())\n        {\n            <div class=\"alert alert-warning\">\n                <strong>Invalid login request</strong>\n                There are no login schemes configured for this request.\n            </div>\n        }\n    </div>\n</div>"
  },
  {
    "path": "src/IdentityServer8/host/Views/Account/Logout.cshtml",
    "content": "﻿@model LogoutViewModel\n\n<div class=\"logout-page\">\n    <div class=\"lead\">\n        <h1>Logout</h1>\n        <p>Would you like to logout of IdentityServer?</p>\n    </div>\n\n    <form asp-action=\"Logout\">\n        <input type=\"hidden\" name=\"logoutId\" value=\"@Model.LogoutId\"  />\n        <div class=\"form-group\">\n            <button class=\"btn btn-primary\">Yes</button>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Consent/Index.cshtml",
    "content": "@model ConsentViewModel\n\n<div class=\"page-consent\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Index\">\n        <input type=\"hidden\" asp-for=\"ReturnUrl\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Device/Success.cshtml",
    "content": "\n<div class=\"page-device-success\">\n    <div class=\"lead\">\n        <h1>Success</h1>\n        <p>You have successfully authorized the device</p>\n    </div>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Device/UserCodeCapture.cshtml",
    "content": "@model string\n\n<div class=\"page-device-code\">\n    <div class=\"lead\">\n        <h1>User Code</h1>\n        <p>Please enter the code displayed on your device.</p>\n    </div>\n\n    <partial name=\"_ValidationSummary\" />\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <form asp-action=\"UserCodeCapture\">\n                <div class=\"form-group\">\n                    <label for=\"userCode\">User Code:</label>\n                    <input class=\"form-control\" for=\"userCode\" name=\"userCode\" autofocus />\n                </div>\n\n                <button class=\"btn btn-primary\" name=\"button\">Submit</button>\n            </form>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Device/UserCodeConfirmation.cshtml",
    "content": "@model DeviceAuthorizationViewModel\n\n<div class=\"page-device-confirmation\">\n    <div class=\"lead\">\n        @if (Model.ClientLogoUrl != null)\n        {\n            <div class=\"client-logo\"><img src=\"@Model.ClientLogoUrl\"></div>\n        }\n        <h1>\n            @Model.ClientName\n            <small class=\"text-muted\">is requesting your permission</small>\n        </h1>\n        @if (Model.ConfirmUserCode)\n        {\n            <p>Please confirm that the authorization request quotes the code: <strong>@Model.UserCode</strong>.</p>\n        }\n        <p>Uncheck the permissions you do not wish to grant.</p>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-8\">\n            <partial name=\"_ValidationSummary\" />\n        </div>\n    </div>\n\n    <form asp-action=\"Callback\">\n        <input asp-for=\"UserCode\" type=\"hidden\" value=\"@Model.UserCode\" />\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                @if (Model.IdentityScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                Personal Information\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.IdentityScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"@scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                @if (Model.ApiScopes.Any())\n                {\n                    <div class=\"form-group\">\n                        <div class=\"card\">\n                            <div class=\"card-header\">\n                                <span class=\"glyphicon glyphicon-tasks\"></span>\n                                Application Access\n                            </div>\n                            <ul class=\"list-group list-group-flush\">\n                                @foreach (var scope in Model.ApiScopes)\n                                {\n                                    <partial name=\"_ScopeListItem\" model=\"scope\" />\n                                }\n                            </ul>\n                        </div>\n                    </div>\n                }\n\n                <div class=\"form-group\">\n                    <div class=\"card\">\n                        <div class=\"card-header\">\n                            <span class=\"glyphicon glyphicon-tasks\"></span>\n                            Description\n                        </div>\n                        <div class=\"card-body\">\n                            <input class=\"form-control\" placeholder=\"Description or name of device\" asp-for=\"Description\" autofocus>\n                        </div>\n                    </div>\n                </div>\n\n                @if (Model.AllowRememberConsent)\n                {\n                    <div class=\"form-group\">\n                        <div class=\"form-check\">\n                            <input class=\"form-check-input\" asp-for=\"RememberConsent\">\n                            <label class=\"form-check-label\" asp-for=\"RememberConsent\">\n                                <strong>Remember My Decision</strong>\n                            </label>\n                        </div>\n                    </div>\n                }\n            </div>\n        </div>\n\n        <div class=\"row\">\n            <div class=\"col-sm-4\">\n                <button name=\"button\" value=\"yes\" class=\"btn btn-primary\" autofocus>Yes, Allow</button>\n                <button name=\"button\" value=\"no\" class=\"btn btn-secondary\">No, Do Not Allow</button>\n            </div>\n            <div class=\"col-sm-4 col-lg-auto\">\n                @if (Model.ClientUrl != null)\n                {\n                    <a class=\"btn btn-outline-info\" href=\"@Model.ClientUrl\">\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <strong>@Model.ClientName</strong>\n                    </a>\n                }\n            </div>\n        </div>\n    </form>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Diagnostics/Index.cshtml",
    "content": "@model DiagnosticsViewModel\n\n<div class=\"diagnostics-page\">\n    <div class=\"lead\">\n        <h1>Authentication Cookie</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Claims</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var claim in Model.AuthenticateResult.Principal.Claims)\n                        {\n                            <dt>@claim.Type</dt>\n                            <dd>@claim.Value</dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n        \n        <div class=\"col\">\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <h2>Properties</h2>\n                </div>\n                <div class=\"card-body\">\n                    <dl>\n                        @foreach (var prop in Model.AuthenticateResult.Properties.Items)\n                        {\n                            <dt>@prop.Key</dt>\n                            <dd>@prop.Value</dd>\n                        }\n                        @if (Model.Clients.Any())\n                        {\n                            <dt>Clients</dt>\n                            <dd>\n                            @{\n                                var clients = Model.Clients.ToArray();\n                                for(var i = 0; i < clients.Length; i++)\n                                {\n                                    <text>@clients[i]</text>\n                                    if (i < clients.Length - 1)\n                                    {\n                                        <text>, </text>\n                                    }\n                                }\n                            }\n                            </dd>\n                        }\n                    </dl>\n                </div>\n            </div>\n        </div>\n    </div>\n</div>\n\n\n\n\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Grants/Index.cshtml",
    "content": "﻿@model GrantsViewModel\n\n<div class=\"grants-page\">\n    <div class=\"lead\">\n        <h1>Client Application Permissions</h1>\n        <p>Below is the list of applications you have given permission to and the resources they have access to.</p>\n    </div>\n\n    @if (Model.Grants.Any() == false)\n    {\n        <div class=\"row\">\n            <div class=\"col-sm-8\">\n                <div class=\"alert alert-info\">\n                    You have not given access to any applications\n                </div>\n            </div>\n        </div>\n    }\n    else\n    {\n        foreach (var grant in Model.Grants)\n        {\n            <div class=\"card\">\n                <div class=\"card-header\">\n                    <div class=\"row\">\n                        <div class=\"col-sm-8 card-title\">\n                            @if (grant.ClientLogoUrl != null)\n                            {\n                                <img src=\"@grant.ClientLogoUrl\">\n                            }\n                            <strong>@grant.ClientName</strong>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <form asp-action=\"Revoke\">\n                                <input type=\"hidden\" name=\"clientId\" value=\"@grant.ClientId\">\n                                <button class=\"btn btn-danger\">Revoke Access</button>\n                            </form>\n                        </div>\n                    </div>\n                </div>\n                \n                <ul class=\"list-group list-group-flush\">\n                    @if (grant.Description != null)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Description:</label> @grant.Description\n                        </li>   \n                    }\n                    <li class=\"list-group-item\">\n                        <label>Created:</label> @grant.Created.ToString(\"yyyy-MM-dd\")\n                    </li>\n                    @if (grant.Expires.HasValue)\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Expires:</label> @grant.Expires.Value.ToString(\"yyyy-MM-dd\")\n                        </li>\n                    }\n                    @if (grant.IdentityGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>Identity Grants</label>\n                            <ul>\n                                @foreach (var name in grant.IdentityGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                    @if (grant.ApiGrantNames.Any())\n                    {\n                        <li class=\"list-group-item\">\n                            <label>API Grants</label>\n                            <ul>\n                                @foreach (var name in grant.ApiGrantNames)\n                                {\n                                    <li>@name</li>\n                                }\n                            </ul>\n                        </li>\n                    }\n                </ul>\n            </div>\n        }\n    }\n</div>"
  },
  {
    "path": "src/IdentityServer8/host/Views/Home/Index.cshtml",
    "content": "@using System.Diagnostics\n@using System.Reflection\n\n@{\n    var version = typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion.Split('+').First();\n}\n\n<div class=\"welcome-page\">\n    <h1>\n        <img src=\"~/icon.jpg\">\n        Welcome to IdentityServer8\n        <small class=\"text-muted\">(version @version)</small>\n    </h1>\n\n    <ul>\n        <li>\n            IdentityServer publishes a\n            <a href=\"~/.well-known/openid-configuration\">discovery document</a>\n            where you can find metadata and links to all the endpoints, key material, etc.\n        </li>\n        <li>\n            Click <a href=\"~/diagnostics\">here</a> to see the claims for your current session.\n        </li>\n        <li>\n            Click <a href=\"~/grants\">here</a> to manage your stored grants.\n        </li>\n        <li>\n            Here are links to the\n            <a href=\"https://github.com/alexhiggins732/IdentityServer8\">source code repository</a>,\n            and <a href=\"https://github.com/alexhiggins732/IdentityServer8/tree/main/samples\">ready to use samples</a>.\n        </li>\n    </ul>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Shared/Error.cshtml",
    "content": "@model ErrorViewModel\n\n@{\n    var error = Model?.Error?.Error;\n    var errorDescription = Model?.Error?.ErrorDescription;\n    var request_id = Model?.Error?.RequestId;\n}\n\n<div class=\"error-page\">\n    <div class=\"lead\">\n        <h1>Error</h1>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-sm-6\">\n            <div class=\"alert alert-danger\">\n                Sorry, there was an error\n\n                @if (error != null)\n                {\n                    <strong>\n                        <em>\n                            : @error\n                        </em>\n                    </strong>\n\n                    if (errorDescription != null)\n                    {\n                        <div>@errorDescription</div>\n                    }\n                }\n            </div>\n\n            @if (request_id != null)\n            {\n                <div class=\"request-id\">Request Id: @request_id</div>\n            }\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Shared/Redirect.cshtml",
    "content": "@model RedirectViewModel\n@using Microsoft.Extensions.DependencyInjection;\n<div class=\"redirect-page\">\n    <div class=\"lead\">\n        <h1>You are now being returned to the application</h1>\n        <p>Once complete, you may close this tab.</p>\n    </div>\n</div>\n\n<meta http-equiv=\"refresh\" content=\"0;url=@Model.RedirectUrl\" data-url=\"@Model.RedirectUrl\">\n<script>\n    var url = '@Model.RedirectUrl.SanitizeForUrl()';\n    window.location.href = url;\n</script>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Shared/_Layout.cshtml",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\" />\n\n    <title>IdentityServer8</title>\n    \n    <link rel=\"icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"~/favicon.ico\" />\n    \n    <link rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"~/css/site.css\" />\n</head>\n<body>\n    <partial name=\"_Nav\" />\n   \n    <div class=\"container body-container\">\n        @RenderBody()\n    </div>\n\n    <script src=\"~/lib/jquery/dist/jquery.slim.min.js\"></script>\n    <script src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"></script>\n\n    @RenderSection(\"scripts\", required: false)\n</body>\n</html>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Shared/_Nav.cshtml",
    "content": "@using IdentityServer8.Extensions\n\n@{\n    string name = null;\n    if (!true.Equals(ViewData[\"signed-out\"]))\n    {\n        name = Context.User?.GetDisplayName();\n    }\n}\n\n<div class=\"nav-page\">\n    <nav class=\"navbar navbar-expand-lg navbar-dark bg-dark\">\n\n        <a href=\"~/\" class=\"navbar-brand\">\n            <img src=\"~/icon.png\" class=\"icon-banner\">\n            IdentityServer8\n        </a>\n\n        @if (!string.IsNullOrWhiteSpace(name))\n        {\n            <ul class=\"navbar-nav mr-auto\">\n                <li class=\"nav-item dropdown\">\n                    <a href=\"#\" class=\"nav-link dropdown-toggle\" data-toggle=\"dropdown\">@name <b class=\"caret\"></b></a>\n                    \n                    <div class=\"dropdown-menu\">\n                        <a class=\"dropdown-item\" asp-action=\"Logout\" asp-controller=\"Account\">Logout</a>\n                    </div>\n              </li>\n            </ul>\n        }\n    \n    </nav>\n</div>\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/Shared/_ScopeListItem.cshtml",
    "content": "﻿@model ScopeViewModel\n\n<li class=\"list-group-item\">\n    <label>\n        <input class=\"consent-scopecheck\"\n               type=\"checkbox\"\n               name=\"ScopesConsented\"\n               id=\"scopes_@Model.Value\"\n               value=\"@Model.Value\"\n               checked=\"@Model.Checked\"\n               disabled=\"@Model.Required\" />\n        @if (Model.Required)\n        {\n            <input type=\"hidden\"\n                   name=\"ScopesConsented\"\n                   value=\"@Model.Value\" />\n        }\n        <strong>@Model.DisplayName</strong>\n        @if (Model.Emphasize)\n        {\n            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n        }\n    </label>\n    @if (Model.Required)\n    {\n        <span><em>(required)</em></span>\n    }\n    @if (Model.Description != null)\n    {\n        <div class=\"consent-description\">\n            <label for=\"scopes_@Model.Value\">@Model.Description</label>\n        </div>\n    }\n</li>"
  },
  {
    "path": "src/IdentityServer8/host/Views/Shared/_ValidationSummary.cshtml",
    "content": "﻿@if (ViewContext.ModelState.IsValid == false)\n{\n    <div class=\"alert alert-danger\">\n        <strong>Error</strong>\n        <div asp-validation-summary=\"All\" class=\"danger\"></div>\n    </div>\n}"
  },
  {
    "path": "src/IdentityServer8/host/Views/_ViewImports.cshtml",
    "content": "﻿@using IdentityServerHost.Quickstart.UI\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n"
  },
  {
    "path": "src/IdentityServer8/host/Views/_ViewStart.cshtml",
    "content": "﻿@{\n    Layout = \"_Layout\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/host/appsettings.json",
    "content": "﻿{\n  \"ApiScopes\": [\n    {\n      \"Name\": \"IdentityServerApi\"\n    },\n    {\n      \"Name\": \"resource1.scope1\"\n    },\n    {\n      \"Name\": \"resource2.scope1\"\n    },\n    {\n      \"Name\": \"scope3\"\n    },\n    {\n      \"Name\": \"shared.scope\"\n    },\n    {\n      \"Name\": \"transaction\",\n      \"DisplayName\": \"Transaction\",\n      \"Description\": \"A transaction\"\n    }\n  ],\n  \n  \"ApiResources\": [\n    {\n      \"Name\": \"resource1\",\n      \"DisplayName\": \"Resource #1\",\n\n      \"Scopes\": [\n        \"resource1.scope1\",\n        \"shared.scope\"\n      ]\n    },\n    {\n      \"Name\": \"resource2\",\n      \"DisplayName\": \"Resource #2\",\n      \n      \"UserClaims\": [\n        \"name\",\n        \"email\"\n      ],\n\n      \"Scopes\": [\n        \"resource2.scope1\",\n        \"shared.scope\"\n      ]\n    }\n  ],\n  \n  \"Clients\": [\n    {\n      \"ClientId\": \"machine_client\",\n      \"ClientSecrets\": [ { \"Value\": \"K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=\" } ],\n      \"AllowedGrantTypes\": [ \"client_credentials\" ],\n      \"AllowedScopes\": [ \"resource1.scope1\", \"resource1.scope2\" ],\n      \"Properties\": { \"foo\": \"bar\" },\n      \"Claims\": [\n        {\n          \"type\": \"c1\",\n          \"value\": \"c1value\"\n        },\n        {\n          \"type\": \"c2\",\n          \"value\": \"c2value\"\n        }\n      ]\n    },\n    {\n      \"ClientId\": \"interactive_client\",\n      \"ClientSecrets\": [ { \"Value\": \"K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=\" } ],\n      \"AllowedGrantTypes\": [ \"authorization_code\", \"client_credentials\" ],\n      \"AllowedScopes\": [ \"openid\", \"profile\", \"resource1.scope1\", \"resource1.scope2\" ]\n    }\n  ]\n}"
  },
  {
    "path": "src/IdentityServer8/host/compilerconfig.json",
    "content": "﻿[\n  {\n    \"outputFile\": \"wwwroot/css/site.css\",\n    \"inputFile\": \"wwwroot/css/site.scss\"\n  }\n]"
  },
  {
    "path": "src/IdentityServer8/host/compilerconfig.json.defaults",
    "content": "{\n  \"compilers\": {\n    \"less\": {\n      \"autoPrefix\": \"\",\n      \"cssComb\": \"none\",\n      \"ieCompat\": true,\n      \"strictMath\": false,\n      \"strictUnits\": false,\n      \"relativeUrls\": true,\n      \"rootPath\": \"\",\n      \"sourceMapRoot\": \"\",\n      \"sourceMapBasePath\": \"\",\n      \"sourceMap\": false\n    },\n    \"sass\": {\n      \"autoPrefix\": \"\",\n      \"includePath\": \"\",\n      \"indentType\": \"space\",\n      \"indentWidth\": 2,\n      \"outputStyle\": \"nested\",\n      \"Precision\": 5,\n      \"relativeUrls\": true,\n      \"sourceMapRoot\": \"\",\n      \"lineFeed\": \"\",\n      \"sourceMap\": false\n    },\n    \"stylus\": {\n      \"sourceMap\": false\n    },\n    \"babel\": {\n      \"sourceMap\": false\n    },\n    \"coffeescript\": {\n      \"bare\": false,\n      \"runtimeMode\": \"node\",\n      \"sourceMap\": false\n    },\n    \"handlebars\": {\n      \"root\": \"\",\n      \"noBOM\": false,\n      \"name\": \"\",\n      \"namespace\": \"\",\n      \"knownHelpersOnly\": false,\n      \"forcePartial\": false,\n      \"knownHelpers\": [],\n      \"commonjs\": \"\",\n      \"amd\": false,\n      \"sourceMap\": false\n    }\n  },\n  \"minifiers\": {\n    \"css\": {\n      \"enabled\": true,\n      \"termSemicolons\": true,\n      \"gzip\": false\n    },\n    \"javascript\": {\n      \"enabled\": true,\n      \"termSemicolons\": true,\n      \"gzip\": false\n    }\n  }\n}"
  },
  {
    "path": "src/IdentityServer8/host/libman.json",
    "content": "{\n  \"version\": \"1.0\",\n  \"defaultProvider\": \"cdnjs\",\n  \"libraries\": [\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery@3.7.1\",\n      \"destination\": \"wwwroot/lib/jquery/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"bootstrap@5.3.2\",\n      \"destination\": \"wwwroot/lib/bootstrap/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation@1.20.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation/\"\n    },\n    {\n      \"provider\": \"jsdelivr\",\n      \"library\": \"jquery-validation-unobtrusive@4.0.0\",\n      \"destination\": \"wwwroot/lib/jquery-validation-unobtrusive/\"\n    }\n  ]\n}"
  },
  {
    "path": "src/IdentityServer8/host/wwwroot/css/site.css",
    "content": "﻿.body-container {\n  margin-top: 60px;\n  padding-bottom: 40px; }\n\n.welcome-page li {\n  list-style: none;\n  padding: 4px; }\n\n.logged-out-page iframe {\n  display: none;\n  width: 0;\n  height: 0; }\n\n.grants-page .card {\n  margin-top: 20px;\n  border-bottom: 1px solid lightgray; }\n  .grants-page .card .card-title {\n    font-size: 120%;\n    font-weight: bold; }\n    .grants-page .card .card-title img {\n      width: 100px;\n      height: 100px; }\n  .grants-page .card label {\n    font-weight: bold; }\n"
  },
  {
    "path": "src/IdentityServer8/host/wwwroot/css/site.scss",
    "content": "﻿.body-container {\n    margin-top: 60px;\n    padding-bottom:40px;\n}\n\n.welcome-page {\n    li {\n        list-style: none;\n        padding: 4px;\n    }\n}\n\n.logged-out-page {\n    iframe {\n        display: none;\n        width: 0;\n        height: 0;\n    }\n}\n\n.grants-page {\n    .card {\n        margin-top: 20px;\n        border-bottom: 1px solid lightgray;\n\n        .card-title {\n            img {\n                width: 100px;\n                height: 100px;\n            }\n\n            font-size: 120%;\n            font-weight: bold;\n        }\n\n        label {\n            font-weight: bold;\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "src/IdentityServer8/host/wwwroot/js/signin-redirect.js",
    "content": "//window.location.href = document.querySelector(\"meta[http-equiv=refresh]\").getAttribute(\"data-url\");\n"
  },
  {
    "path": "src/IdentityServer8/host/wwwroot/js/signout-redirect.js",
    "content": "﻿window.addEventListener(\"load\", function () {\n    var a = document.querySelector(\"a.PostLogoutRedirectUri\");\n    if (a) {\n        window.location = a.href;\n    }\n});\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/CryptoHelper.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Crypto helper\n/// </summary>\npublic static class CryptoHelper\n{\n    /// <summary>\n    /// Creates a new RSA security key.\n    /// </summary>\n    /// <returns></returns>\n    public static RsaSecurityKey CreateRsaSecurityKey(int keySize = 2048)\n    {\n        return new RsaSecurityKey(RSA.Create(keySize))\n        {\n            KeyId = CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex)\n        };\n    }\n\n    /// <summary>\n    /// Creates a new ECDSA security key.\n    /// </summary>\n    /// <param name=\"curve\">The name of the curve as defined in\n    /// https://tools.ietf.org/html/rfc7518#section-6.2.1.1.</param>\n    /// <returns></returns>\n    public static ECDsaSecurityKey CreateECDsaSecurityKey(string curve = JsonWebKeyECTypes.P256)\n    {\n        return new ECDsaSecurityKey(ECDsa.Create(GetCurveFromCrvValue(curve)))\n        {\n            KeyId = CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex)\n        };\n    }\n\n    /// <summary>\n    /// Creates an RSA security key.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"id\">The identifier.</param>\n    /// <returns></returns>\n    public static RsaSecurityKey CreateRsaSecurityKey(RSAParameters parameters, string id)\n    {\n        var key = new RsaSecurityKey(parameters)\n        {\n            KeyId = id\n        };\n\n        return key;\n    }\n\n    /// <summary>\n    /// Creates the hash for the various hash claims (e.g. c_hash, at_hash or s_hash).\n    /// </summary>\n    /// <param name=\"value\">The value to hash.</param>\n    /// <param name=\"tokenSigningAlgorithm\">The token signing algorithm</param>\n    /// <returns></returns>\n    public static string CreateHashClaimValue(string value, string tokenSigningAlgorithm)\n    {\n        using (var sha = GetHashAlgorithmForSigningAlgorithm(tokenSigningAlgorithm))\n        {\n            var hash = sha.ComputeHash(Encoding.ASCII.GetBytes(value));\n            var size = (sha.HashSize / 8) / 2;\n\n            var leftPart = new byte[size];\n            Array.Copy(hash, leftPart, size);\n\n            return Base64Url.Encode(leftPart);\n        }\n    }\n\n    /// <summary>\n    /// Returns the matching hashing algorithm for a token signing algorithm\n    /// </summary>\n    /// <param name=\"signingAlgorithm\">The signing algorithm</param>\n    /// <returns></returns>\n    public static HashAlgorithm GetHashAlgorithmForSigningAlgorithm(string signingAlgorithm)\n    {\n        var signingAlgorithmBits = int.Parse(signingAlgorithm.Substring(signingAlgorithm.Length - 3));\n\n        return signingAlgorithmBits switch\n        {\n            256 => SHA256.Create(),\n            384 => SHA384.Create(),\n            512 => SHA512.Create(),\n            _ => throw new InvalidOperationException($\"Invalid signing algorithm: {signingAlgorithm}\"),\n        };\n    }\n\n    /// <summary>\n    /// Returns the matching named curve for RFC 7518 crv value\n    /// </summary>\n    internal static ECCurve GetCurveFromCrvValue(string crv)\n    {\n        return crv switch\n        {\n            JsonWebKeyECTypes.P256 => ECCurve.NamedCurves.nistP256,\n            JsonWebKeyECTypes.P384 => ECCurve.NamedCurves.nistP384,\n            JsonWebKeyECTypes.P521 => ECCurve.NamedCurves.nistP521,\n            _ => throw new InvalidOperationException($\"Unsupported curve type of {crv}\"),\n        };\n    }\n\n    /// <summary>\n    /// Return the matching RFC 7518 crv value for curve\n    /// </summary>\n    internal static string GetCrvValueFromCurve(ECCurve curve)\n    {\n        return curve.Oid.Value switch\n        {\n            Constants.CurveOids.P256 => JsonWebKeyECTypes.P256,\n            Constants.CurveOids.P384 => JsonWebKeyECTypes.P384,\n            Constants.CurveOids.P521 => JsonWebKeyECTypes.P521,\n            _ => throw new InvalidOperationException($\"Unsupported curve type of {curve.Oid.Value} - {curve.Oid.FriendlyName}\"),\n        };\n    }\n\n    internal static bool IsValidCurveForAlgorithm(ECDsaSecurityKey key, string algorithm)\n    {\n        var parameters = key.ECDsa.ExportParameters(false);\n\n        if (algorithm == SecurityAlgorithms.EcdsaSha256 && parameters.Curve.Oid.Value != Constants.CurveOids.P256\n            || algorithm == SecurityAlgorithms.EcdsaSha384 && parameters.Curve.Oid.Value != Constants.CurveOids.P384\n            || algorithm == SecurityAlgorithms.EcdsaSha512 && parameters.Curve.Oid.Value != Constants.CurveOids.P521)\n        {\n            return false;\n        }\n\n        return true;\n    }\n    internal static bool IsValidCrvValueForAlgorithm(string crv)\n    {\n        return crv == JsonWebKeyECTypes.P256 ||\n               crv == JsonWebKeyECTypes.P384 ||\n               crv == JsonWebKeyECTypes.P521;\n    }\n\n    internal static string GetRsaSigningAlgorithmValue(IdentityServerConstants.RsaSigningAlgorithm value)\n    {\n        return value switch\n        {\n            IdentityServerConstants.RsaSigningAlgorithm.RS256 => SecurityAlgorithms.RsaSha256,\n            IdentityServerConstants.RsaSigningAlgorithm.RS384 => SecurityAlgorithms.RsaSha384,\n            IdentityServerConstants.RsaSigningAlgorithm.RS512 => SecurityAlgorithms.RsaSha512,\n\n            IdentityServerConstants.RsaSigningAlgorithm.PS256 => SecurityAlgorithms.RsaSsaPssSha256,\n            IdentityServerConstants.RsaSigningAlgorithm.PS384 => SecurityAlgorithms.RsaSsaPssSha384,\n            IdentityServerConstants.RsaSigningAlgorithm.PS512 => SecurityAlgorithms.RsaSsaPssSha512,\n            _ => throw new ArgumentException(\"Invalid RSA signing algorithm value\", nameof(value)),\n        };\n    }\n\n    internal static string GetECDsaSigningAlgorithmValue(IdentityServerConstants.ECDsaSigningAlgorithm value)\n    {\n        return value switch\n        {\n            IdentityServerConstants.ECDsaSigningAlgorithm.ES256 => SecurityAlgorithms.EcdsaSha256,\n            IdentityServerConstants.ECDsaSigningAlgorithm.ES384 => SecurityAlgorithms.EcdsaSha384,\n            IdentityServerConstants.ECDsaSigningAlgorithm.ES512 => SecurityAlgorithms.EcdsaSha512,\n            _ => throw new ArgumentException(\"Invalid ECDsa signing algorithm value\", nameof(value)),\n        };\n    }\n\n    internal static X509Certificate2 FindCertificate(string name, StoreLocation location, NameType nameType)\n    {\n        X509Certificate2 certificate = null;\n\n        if (location == StoreLocation.LocalMachine)\n        {\n            if (nameType == NameType.SubjectDistinguishedName)\n            {\n                certificate = X509.LocalMachine.My.SubjectDistinguishedName.Find(name, validOnly: false).FirstOrDefault();\n            }\n            else if (nameType == NameType.Thumbprint)\n            {\n                certificate = X509.LocalMachine.My.Thumbprint.Find(name, validOnly: false).FirstOrDefault();\n            }\n        }\n        else\n        {\n            if (nameType == NameType.SubjectDistinguishedName)\n            {\n                certificate = X509.CurrentUser.My.SubjectDistinguishedName.Find(name, validOnly: false).FirstOrDefault();\n            }\n            else if (nameType == NameType.Thumbprint)\n            {\n                certificate = X509.CurrentUser.My.Thumbprint.Find(name, validOnly: false).FirstOrDefault();\n            }\n        }\n\n        return certificate;\n    }\n}\n\n/// <summary>\n/// Describes the string so we know what to search for in certificate store\n/// </summary>\npublic enum NameType\n{\n    /// <summary>\n    /// subject distinguished name\n    /// </summary>\n    SubjectDistinguishedName,\n\n    /// <summary>\n    /// thumbprint\n    /// </summary>\n    Thumbprint\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/BuilderExtensions/Additional.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Builder extension methods for registering additional services \n/// </summary>\npublic static class IdentityServerBuilderExtensionsAdditional\n{\n    /// <summary>\n    /// Adds the extension grant validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddExtensionGrantValidator<T>(this IIdentityServerBuilder builder)\n        where T : class, IExtensionGrantValidator\n    {\n        builder.Services.AddTransient<IExtensionGrantValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a redirect URI validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddRedirectUriValidator<T>(this IIdentityServerBuilder builder)\n        where T : class, IRedirectUriValidator\n    {\n        builder.Services.AddTransient<IRedirectUriValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a an \"AppAuth\" (OAuth 2.0 for Native Apps) compliant redirect URI validator (does strict validation but also allows http://127.0.0.1 with random port)\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddAppAuthRedirectUriValidator(this IIdentityServerBuilder builder)\n    {\n        return builder.AddRedirectUriValidator<StrictRedirectUriValidatorAppAuth>();\n    }\n\n    /// <summary>\n    /// Adds the resource owner validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddResourceOwnerValidator<T>(this IIdentityServerBuilder builder)\n       where T : class, IResourceOwnerPasswordValidator\n    {\n        builder.Services.AddTransient<IResourceOwnerPasswordValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the profile service.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddProfileService<T>(this IIdentityServerBuilder builder)\n       where T : class, IProfileService\n    {\n        builder.Services.AddTransient<IProfileService, T>();\n\n        return builder;\n    }\n    \n    /// <summary>\n    /// Adds a resource validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddResourceValidator<T>(this IIdentityServerBuilder builder)\n        where T : class, IResourceValidator\n    {\n        builder.Services.AddTransient<IResourceValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a scope parser.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddScopeParser<T>(this IIdentityServerBuilder builder)\n        where T : class, IScopeParser\n    {\n        builder.Services.AddTransient<IScopeParser, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a client store.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddClientStore<T>(this IIdentityServerBuilder builder)\n       where T : class, IClientStore\n    {\n        builder.Services.TryAddTransient(typeof(T));\n        builder.Services.AddTransient<IClientStore, ValidatingClientStore<T>>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a resource store.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddResourceStore<T>(this IIdentityServerBuilder builder)\n       where T : class, IResourceStore\n    {\n        builder.Services.AddTransient<IResourceStore, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a device flow store.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    public static IIdentityServerBuilder AddDeviceFlowStore<T>(this IIdentityServerBuilder builder)\n        where T : class, IDeviceFlowStore\n    {\n        builder.Services.AddTransient<IDeviceFlowStore, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a persisted grant store.\n    /// </summary>\n    /// <typeparam name=\"T\">The type of the concrete grant store that is registered in DI.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns>The builder.</returns>\n    public static IIdentityServerBuilder AddPersistedGrantStore<T>(this IIdentityServerBuilder builder)\n        where T : class, IPersistedGrantStore\n    {\n        builder.Services.AddTransient<IPersistedGrantStore, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a CORS policy service.\n    /// </summary>\n    /// <typeparam name=\"T\">The type of the concrete scope store class that is registered in DI.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddCorsPolicyService<T>(this IIdentityServerBuilder builder)\n        where T : class, ICorsPolicyService\n    {\n        builder.Services.AddTransient<ICorsPolicyService, T>();\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a CORS policy service cache.\n    /// </summary>\n    /// <typeparam name=\"T\">The type of the concrete CORS policy service that is registered in DI.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddCorsPolicyCache<T>(this IIdentityServerBuilder builder)\n        where T : class, ICorsPolicyService\n    {\n        builder.Services.TryAddTransient(typeof(T));\n        builder.Services.AddTransient<ICorsPolicyService, CachingCorsPolicyService<T>>();\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the secret parser.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddSecretParser<T>(this IIdentityServerBuilder builder)\n        where T : class, ISecretParser\n    {\n        builder.Services.AddTransient<ISecretParser, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the secret validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddSecretValidator<T>(this IIdentityServerBuilder builder)\n        where T : class, ISecretValidator\n    {\n        builder.Services.AddTransient<ISecretValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the client store cache.\n    /// </summary>\n    /// <typeparam name=\"T\">The type of the concrete client store class that is registered in DI.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddClientStoreCache<T>(this IIdentityServerBuilder builder)\n        where T : IClientStore\n    {\n        builder.Services.TryAddTransient(typeof(T));\n        builder.Services.AddTransient<ValidatingClientStore<T>>();\n        builder.Services.AddTransient<IClientStore, CachingClientStore<ValidatingClientStore<T>>>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the client store cache.\n    /// </summary>\n    /// <typeparam name=\"T\">The type of the concrete scope store class that is registered in DI.</typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddResourceStoreCache<T>(this IIdentityServerBuilder builder)\n        where T : IResourceStore\n    {\n        builder.Services.TryAddTransient(typeof(T));\n        builder.Services.AddTransient<IResourceStore, CachingResourceStore<T>>();\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the authorize interaction response generator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddAuthorizeInteractionResponseGenerator<T>(this IIdentityServerBuilder builder)\n        where T : class, IAuthorizeInteractionResponseGenerator\n    {\n        builder.Services.AddTransient<IAuthorizeInteractionResponseGenerator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the custom authorize request validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddCustomAuthorizeRequestValidator<T>(this IIdentityServerBuilder builder)\n       where T : class, ICustomAuthorizeRequestValidator\n    {\n        builder.Services.AddTransient<ICustomAuthorizeRequestValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the custom authorize request validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddCustomTokenRequestValidator<T>(this IIdentityServerBuilder builder)\n       where T : class, ICustomTokenRequestValidator\n    {\n        builder.Services.AddTransient<ICustomTokenRequestValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds support for client authentication using JWT bearer assertions.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddJwtBearerClientAuthentication(this IIdentityServerBuilder builder)\n    {\n        builder.Services.TryAddTransient<IReplayCache, DefaultReplayCache>();\n        builder.AddSecretParser<JwtBearerClientAssertionSecretParser>();\n        builder.AddSecretValidator<PrivateKeyJwtSecretValidator>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a client configuration validator.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddClientConfigurationValidator<T>(this IIdentityServerBuilder builder)\n        where T : class, IClientConfigurationValidator\n    {\n        builder.Services.AddTransient<IClientConfigurationValidator, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the X509 secret validators for mutual TLS.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddMutualTlsSecretValidators(this IIdentityServerBuilder builder)\n    {\n        builder.AddSecretParser<MutualTlsSecretParser>();\n        builder.AddSecretValidator<X509ThumbprintSecretValidator>();\n        builder.AddSecretValidator<X509NameSecretValidator>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a custom back-channel logout service.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddBackChannelLogoutService<T>(this IIdentityServerBuilder builder)\n        where T : class, IBackChannelLogoutService\n    {\n        builder.Services.AddTransient<IBackChannelLogoutService, T>();\n\n        return builder;\n    }\n\n    // todo: check with later previews of ASP.NET Core if this is still required\n    /// <summary>\n    /// Adds configuration for the HttpClient used for back-channel logout notifications.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"configureClient\">The configruation callback.</param>\n    /// <returns></returns>\n    public static IHttpClientBuilder AddBackChannelLogoutHttpClient(this IIdentityServerBuilder builder, Action<HttpClient> configureClient = null)\n    {\n        const string name = IdentityServerConstants.HttpClients.BackChannelLogoutHttpClient;\n        IHttpClientBuilder httpBuilder;\n\n        if (configureClient != null)\n        {\n            httpBuilder = builder.Services.AddHttpClient(name, configureClient);\n        }\n        else\n        {\n            httpBuilder = builder.Services.AddHttpClient(name)\n                .ConfigureHttpClient(client => {\n                    client.Timeout = TimeSpan.FromSeconds(IdentityServerConstants.HttpClients.DefaultTimeoutSeconds);\n                });\n        }\n\n        builder.Services.AddTransient<IBackChannelLogoutHttpClient>(s =>\n        {\n            var httpClientFactory = s.GetRequiredService<IHttpClientFactory>();\n            var httpClient = httpClientFactory.CreateClient(name);\n            var loggerFactory = s.GetRequiredService<ILoggerFactory>();\n            \n            return new DefaultBackChannelLogoutHttpClient(httpClient, loggerFactory);\n        });\n\n        return httpBuilder;\n    }\n\n\n    // todo: check with later previews of ASP.NET Core if this is still required\n    /// <summary>\n    /// Adds configuration for the HttpClient used for JWT request_uri requests.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"configureClient\">The configruation callback.</param>\n    /// <returns></returns>\n    public static IHttpClientBuilder AddJwtRequestUriHttpClient(this IIdentityServerBuilder builder, Action<HttpClient> configureClient = null)\n    {\n        const string name = IdentityServerConstants.HttpClients.JwtRequestUriHttpClient;\n        IHttpClientBuilder httpBuilder;\n\n        if (configureClient != null)\n        {\n            httpBuilder = builder.Services.AddHttpClient(name, configureClient);\n        }\n        else\n        {\n            httpBuilder = builder.Services.AddHttpClient(name)\n                .ConfigureHttpClient(client => {\n                    client.Timeout = TimeSpan.FromSeconds(IdentityServerConstants.HttpClients.DefaultTimeoutSeconds);\n                });\n        }\n        \n        builder.Services.AddTransient<IJwtRequestUriHttpClient, DefaultJwtRequestUriHttpClient>(s =>\n        {\n            var httpClientFactory = s.GetRequiredService<IHttpClientFactory>();\n            var httpClient = httpClientFactory.CreateClient(name);\n            var loggerFactory = s.GetRequiredService<ILoggerFactory>();\n            var options = s.GetRequiredService<IdentityServerOptions>();\n\n            return new DefaultJwtRequestUriHttpClient(httpClient, options, loggerFactory);\n        });\n\n        return httpBuilder;\n    }\n\n    /// <summary>\n    /// Adds a custom authorization request parameter store.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddAuthorizationParametersMessageStore<T>(this IIdentityServerBuilder builder)\n        where T : class, IAuthorizationParametersMessageStore\n    {\n        builder.Services.AddTransient<IAuthorizationParametersMessageStore, T>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds a custom user session.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddUserSession<T>(this IIdentityServerBuilder builder)\n        where T : class, IUserSession\n    {\n        // This is added as scoped due to the note regarding the AuthenticateAsync\n        // method in the IdentityServer8.Services.DefaultUserSession implementation.\n        builder.Services.AddScoped<IUserSession, T>();\n\n        return builder;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/BuilderExtensions/Core.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Builder extension methods for registering core services\n/// </summary>\npublic static class IdentityServerBuilderExtensionsCore\n{\n    /// <summary>\n    /// Adds the required platform services.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddRequiredPlatformServices(this IIdentityServerBuilder builder)\n    {\n        builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();            \n        builder.Services.AddOptions();\n        builder.Services.AddSingleton(\n            resolver => resolver.GetRequiredService<IOptions<IdentityServerOptions>>().Value);\n        builder.Services.AddHttpClient();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the default cookie handlers and corresponding configuration\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddCookieAuthentication(this IIdentityServerBuilder builder)\n    {\n        builder.Services.AddAuthentication(IdentityServerConstants.DefaultCookieAuthenticationScheme)\n            .AddCookie(IdentityServerConstants.DefaultCookieAuthenticationScheme)\n            .AddCookie(IdentityServerConstants.ExternalCookieAuthenticationScheme);\n\n        builder.Services.AddSingleton<IConfigureOptions<CookieAuthenticationOptions>, ConfigureInternalCookieOptions>();\n        builder.Services.AddSingleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureInternalCookieOptions>();\n        builder.Services.AddTransientDecorator<IAuthenticationService, IdentityServerAuthenticationService>();\n        builder.Services.AddTransientDecorator<IAuthenticationHandlerProvider, FederatedSignoutAuthenticationHandlerProvider>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the default endpoints.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddDefaultEndpoints(this IIdentityServerBuilder builder)\n    {\n        builder.Services.AddTransient<IEndpointRouter, EndpointRouter>();\n\n        builder.AddEndpoint<AuthorizeCallbackEndpoint>(EndpointNames.Authorize, ProtocolRoutePaths.AuthorizeCallback.EnsureLeadingSlash());\n        builder.AddEndpoint<AuthorizeEndpoint>(EndpointNames.Authorize, ProtocolRoutePaths.Authorize.EnsureLeadingSlash());\n        builder.AddEndpoint<CheckSessionEndpoint>(EndpointNames.CheckSession, ProtocolRoutePaths.CheckSession.EnsureLeadingSlash());\n        builder.AddEndpoint<DeviceAuthorizationEndpoint>(EndpointNames.DeviceAuthorization, ProtocolRoutePaths.DeviceAuthorization.EnsureLeadingSlash());\n        builder.AddEndpoint<DiscoveryKeyEndpoint>(EndpointNames.Discovery, ProtocolRoutePaths.DiscoveryWebKeys.EnsureLeadingSlash());\n        builder.AddEndpoint<DiscoveryEndpoint>(EndpointNames.Discovery, ProtocolRoutePaths.DiscoveryConfiguration.EnsureLeadingSlash());\n        builder.AddEndpoint<EndSessionCallbackEndpoint>(EndpointNames.EndSession, ProtocolRoutePaths.EndSessionCallback.EnsureLeadingSlash());\n        builder.AddEndpoint<EndSessionEndpoint>(EndpointNames.EndSession, ProtocolRoutePaths.EndSession.EnsureLeadingSlash());\n        builder.AddEndpoint<IntrospectionEndpoint>(EndpointNames.Introspection, ProtocolRoutePaths.Introspection.EnsureLeadingSlash());\n        builder.AddEndpoint<TokenRevocationEndpoint>(EndpointNames.Revocation, ProtocolRoutePaths.Revocation.EnsureLeadingSlash());\n        builder.AddEndpoint<TokenEndpoint>(EndpointNames.Token, ProtocolRoutePaths.Token.EnsureLeadingSlash());\n        builder.AddEndpoint<UserInfoEndpoint>(EndpointNames.UserInfo, ProtocolRoutePaths.UserInfo.EnsureLeadingSlash());\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the endpoint.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"path\">The path.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddEndpoint<T>(this IIdentityServerBuilder builder, string name, PathString path)\n        where T : class, IEndpointHandler\n    {\n        builder.Services.AddTransient<T>();\n        builder.Services.AddSingleton(new IdentityServer8.Hosting.Endpoint(name, path, typeof(T)));\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the core services.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddCoreServices(this IIdentityServerBuilder builder)\n    {\n        builder.Services.AddTransient<ISecretsListParser, SecretParser>();\n        builder.Services.AddTransient<ISecretsListValidator, SecretValidator>();\n        builder.Services.AddTransient<ExtensionGrantValidator>();\n        builder.Services.AddTransient<BearerTokenUsageValidator>();\n        builder.Services.AddTransient<JwtRequestValidator>();\n\n        builder.Services.AddTransient<ReturnUrlParser>();\n        builder.Services.AddTransient<IdentityServerTools>();\n\n        builder.Services.AddTransient<IReturnUrlParser, OidcReturnUrlParser>();\n        builder.Services.AddScoped<IUserSession, DefaultUserSession>();\n        builder.Services.AddTransient(typeof(MessageCookie<>));\n\n        builder.Services.AddCors();\n        builder.Services.AddTransientDecorator<ICorsPolicyProvider, CorsPolicyProvider>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the pluggable services.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddPluggableServices(this IIdentityServerBuilder builder)\n    {\n        builder.Services.TryAddTransient<IPersistedGrantService, DefaultPersistedGrantService>();\n        builder.Services.TryAddTransient<IKeyMaterialService, DefaultKeyMaterialService>();\n        builder.Services.TryAddTransient<ITokenService, DefaultTokenService>();\n        builder.Services.TryAddTransient<ITokenCreationService, DefaultTokenCreationService>();\n        builder.Services.TryAddTransient<IClaimsService, DefaultClaimsService>();\n        builder.Services.TryAddTransient<IRefreshTokenService, DefaultRefreshTokenService>();\n        builder.Services.TryAddTransient<IDeviceFlowCodeService, DefaultDeviceFlowCodeService>();\n        builder.Services.TryAddTransient<IConsentService, DefaultConsentService>();\n        builder.Services.TryAddTransient<ICorsPolicyService, DefaultCorsPolicyService>();\n        builder.Services.TryAddTransient<IProfileService, DefaultProfileService>();\n        builder.Services.TryAddTransient<IConsentMessageStore, ConsentMessageStore>();\n        builder.Services.TryAddTransient<IMessageStore<LogoutMessage>, ProtectedDataMessageStore<LogoutMessage>>();\n        builder.Services.TryAddTransient<IMessageStore<LogoutNotificationContext>, ProtectedDataMessageStore<LogoutNotificationContext>>();\n        builder.Services.TryAddTransient<IMessageStore<ErrorMessage>, ProtectedDataMessageStore<ErrorMessage>>();\n        builder.Services.TryAddTransient<IIdentityServerInteractionService, DefaultIdentityServerInteractionService>();\n        builder.Services.TryAddTransient<IDeviceFlowInteractionService, DefaultDeviceFlowInteractionService>();\n        builder.Services.TryAddTransient<IAuthorizationCodeStore, DefaultAuthorizationCodeStore>();\n        builder.Services.TryAddTransient<IRefreshTokenStore, DefaultRefreshTokenStore>();\n        builder.Services.TryAddTransient<IReferenceTokenStore, DefaultReferenceTokenStore>();\n        builder.Services.TryAddTransient<IUserConsentStore, DefaultUserConsentStore>();\n        builder.Services.TryAddTransient<IHandleGenerationService, DefaultHandleGenerationService>();\n        builder.Services.TryAddTransient<IPersistentGrantSerializer, PersistentGrantSerializer>();\n        builder.Services.TryAddTransient<IEventService, DefaultEventService>();\n        builder.Services.TryAddTransient<IEventSink, DefaultEventSink>();\n        builder.Services.TryAddTransient<IUserCodeService, DefaultUserCodeService>();\n        builder.Services.TryAddTransient<IUserCodeGenerator, NumericUserCodeGenerator>();\n        builder.Services.TryAddTransient<ILogoutNotificationService, LogoutNotificationService>();\n        builder.Services.TryAddTransient<IBackChannelLogoutService, DefaultBackChannelLogoutService>();\n        builder.Services.TryAddTransient<IResourceValidator, DefaultResourceValidator>();\n        builder.Services.TryAddTransient<IScopeParser, DefaultScopeParser>();\n\n        builder.AddJwtRequestUriHttpClient();\n        builder.AddBackChannelLogoutHttpClient();\n\n        builder.Services.AddTransient<IClientSecretValidator, ClientSecretValidator>();\n        builder.Services.AddTransient<IApiSecretValidator, ApiSecretValidator>();\n\n        builder.Services.TryAddTransient<IDeviceFlowThrottlingService, DistributedDeviceFlowThrottlingService>();\n        builder.Services.AddDistributedMemoryCache();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the validators.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddValidators(this IIdentityServerBuilder builder)\n    {\n        // core\n        builder.Services.TryAddTransient<IEndSessionRequestValidator, EndSessionRequestValidator>();\n        builder.Services.TryAddTransient<ITokenRevocationRequestValidator, TokenRevocationRequestValidator>();\n        builder.Services.TryAddTransient<IAuthorizeRequestValidator, AuthorizeRequestValidator>();\n        builder.Services.TryAddTransient<ITokenRequestValidator, TokenRequestValidator>();\n        builder.Services.TryAddTransient<IRedirectUriValidator, StrictRedirectUriValidator>();\n        builder.Services.TryAddTransient<ITokenValidator, TokenValidator>();\n        builder.Services.TryAddTransient<IIntrospectionRequestValidator, IntrospectionRequestValidator>();\n        builder.Services.TryAddTransient<IResourceOwnerPasswordValidator, NotSupportedResourceOwnerPasswordValidator>();\n        builder.Services.TryAddTransient<ICustomTokenRequestValidator, DefaultCustomTokenRequestValidator>();\n        builder.Services.TryAddTransient<IUserInfoRequestValidator, UserInfoRequestValidator>();\n        builder.Services.TryAddTransient<IClientConfigurationValidator, DefaultClientConfigurationValidator>();\n        builder.Services.TryAddTransient<IDeviceAuthorizationRequestValidator, DeviceAuthorizationRequestValidator>();\n        builder.Services.TryAddTransient<IDeviceCodeValidator, DeviceCodeValidator>();\n\n        // optional\n        builder.Services.TryAddTransient<ICustomTokenValidator, DefaultCustomTokenValidator>();\n        builder.Services.TryAddTransient<ICustomAuthorizeRequestValidator, DefaultCustomAuthorizeRequestValidator>();\n        \n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the response generators.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddResponseGenerators(this IIdentityServerBuilder builder)\n    {\n        builder.Services.TryAddTransient<ITokenResponseGenerator, TokenResponseGenerator>();\n        builder.Services.TryAddTransient<IUserInfoResponseGenerator, UserInfoResponseGenerator>();\n        builder.Services.TryAddTransient<IIntrospectionResponseGenerator, IntrospectionResponseGenerator>();\n        builder.Services.TryAddTransient<IAuthorizeInteractionResponseGenerator, AuthorizeInteractionResponseGenerator>();\n        builder.Services.TryAddTransient<IAuthorizeResponseGenerator, AuthorizeResponseGenerator>();\n        builder.Services.TryAddTransient<IDiscoveryResponseGenerator, DiscoveryResponseGenerator>();\n        builder.Services.TryAddTransient<ITokenRevocationResponseGenerator, TokenRevocationResponseGenerator>();\n        builder.Services.TryAddTransient<IDeviceAuthorizationResponseGenerator, DeviceAuthorizationResponseGenerator>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the default secret parsers.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddDefaultSecretParsers(this IIdentityServerBuilder builder)\n    {\n        builder.Services.AddTransient<ISecretParser, BasicAuthenticationSecretParser>();\n        builder.Services.AddTransient<ISecretParser, PostBodySecretParser>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the default secret validators.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddDefaultSecretValidators(this IIdentityServerBuilder builder)\n    {\n        builder.Services.AddTransient<ISecretValidator, HashedSharedSecretValidator>();\n\n        return builder;\n    }\n\n    internal static void AddTransientDecorator<TService, TImplementation>(this IServiceCollection services)\n        where TService : class\n        where TImplementation : class, TService\n    {\n        services.AddDecorator<TService>();\n        services.AddTransient<TService, TImplementation>();\n    }\n\n    internal static void AddDecorator<TService>(this IServiceCollection services)\n    {\n        var registration = services.LastOrDefault(x => x.ServiceType == typeof(TService));\n        if (registration == null)\n        {\n            throw new InvalidOperationException(\"Service type: \" + typeof(TService).Name + \" not registered.\");\n        }\n        if (services.Any(x => x.ServiceType == typeof(Decorator<TService>)))\n        {\n            throw new InvalidOperationException(\"Decorator already registered for type: \" + typeof(TService).Name + \".\");\n        }\n\n        services.Remove(registration);\n\n        if (registration.ImplementationInstance != null)\n        {\n            var type = registration.ImplementationInstance.GetType();\n            var innerType = typeof(Decorator<,>).MakeGenericType(typeof(TService), type);\n            services.Add(new ServiceDescriptor(typeof(Decorator<TService>), innerType, ServiceLifetime.Transient));\n            services.Add(new ServiceDescriptor(type, registration.ImplementationInstance));\n        }\n        else if (registration.ImplementationFactory != null)\n        {\n            services.Add(new ServiceDescriptor(typeof(Decorator<TService>), provider =>\n            {\n                return new DisposableDecorator<TService>((TService)registration.ImplementationFactory(provider));\n            }, registration.Lifetime));\n        }\n        else\n        {\n            var type = registration.ImplementationType;\n            var innerType = typeof(Decorator<,>).MakeGenericType(typeof(TService), registration.ImplementationType);\n            services.Add(new ServiceDescriptor(typeof(Decorator<TService>), innerType, ServiceLifetime.Transient));\n            services.Add(new ServiceDescriptor(type, type, registration.Lifetime));\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\nusing JsonWebKey = Microsoft.IdentityModel.Tokens.JsonWebKey;\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Builder extension methods for registering crypto services\n/// </summary>\npublic static class IdentityServerBuilderExtensionsCrypto\n{\n    /// <summary>\n    /// Sets the signing credential.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"credential\">The credential.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddSigningCredential(this IIdentityServerBuilder builder, SigningCredentials credential)\n    {\n        if (!(credential.Key is AsymmetricSecurityKey\n            || credential.Key is IdentityModel.Tokens.JsonWebKey && ((IdentityModel.Tokens.JsonWebKey)credential.Key).HasPrivateKey))\n        {\n            throw new InvalidOperationException(\"Signing key is not asymmetric\");\n        }\n\n        if (!IdentityServerConstants.SupportedSigningAlgorithms.Contains(credential.Algorithm, StringComparer.Ordinal))\n        {\n            throw new InvalidOperationException($\"Signing algorithm {credential.Algorithm} is not supported.\");\n        }\n\n        if (credential.Key is ECDsaSecurityKey key && !CryptoHelper.IsValidCurveForAlgorithm(key, credential.Algorithm))\n        {\n            throw new InvalidOperationException(\"Invalid curve for signing algorithm\");\n        }\n\n        if (credential.Key is IdentityModel.Tokens.JsonWebKey jsonWebKey)\n        {\n            if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve && !CryptoHelper.IsValidCrvValueForAlgorithm(jsonWebKey.Crv))\n                throw new InvalidOperationException(\"Invalid crv value for signing algorithm\");\n        }\n\n        builder.Services.AddSingleton<ISigningCredentialStore>(new InMemorySigningCredentialsStore(credential));\n\n        var keyInfo = new SecurityKeyInfo\n        {\n            Key = credential.Key,\n            SigningAlgorithm = credential.Algorithm\n        };\n\n        builder.Services.AddSingleton<IValidationKeysStore>(new InMemoryValidationKeysStore(new[] { keyInfo }));\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Sets the signing credential.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"certificate\">The certificate.</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm (defaults to RS256)</param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\"></exception>\n    /// <exception cref=\"InvalidOperationException\">X509 certificate does not have a private key.</exception>\n    public static IIdentityServerBuilder AddSigningCredential(this IIdentityServerBuilder builder, X509Certificate2 certificate, string signingAlgorithm = SecurityAlgorithms.RsaSha256)\n    {\n        if (certificate == null) throw new ArgumentNullException(nameof(certificate));\n\n        if (!certificate.HasPrivateKey)\n        {\n            throw new InvalidOperationException(\"X509 certificate does not have a private key.\");\n        }\n\n        // add signing algorithm name to key ID to allow using the same key for two different algorithms (e.g. RS256 and PS56);\n        var key = new X509SecurityKey(certificate);\n        key.KeyId += signingAlgorithm;\n\n        var credential = new SigningCredentials(key, signingAlgorithm);\n        return builder.AddSigningCredential(credential);\n    }\n\n    /// <summary>\n    /// Sets the signing credential.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"location\">The location.</param>\n    /// <param name=\"nameType\">Name parameter can be either a distinguished name or a thumbprint</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm (defaults to RS256)</param>\n    /// <exception cref=\"InvalidOperationException\">certificate: '{name}'</exception>\n    public static IIdentityServerBuilder AddSigningCredential(\n        this IIdentityServerBuilder builder,\n        string name,\n        StoreLocation location = StoreLocation.LocalMachine,\n        NameType nameType = NameType.SubjectDistinguishedName,\n        string signingAlgorithm = SecurityAlgorithms.RsaSha256)\n    {\n        var certificate = CryptoHelper.FindCertificate(name, location, nameType);\n        if (certificate == null) throw new InvalidOperationException($\"certificate: '{name}' not found in certificate store\");\n\n        return builder.AddSigningCredential(certificate, signingAlgorithm);\n    }\n\n    /// <summary>\n    /// Sets the signing credential.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"key\">The key.</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddSigningCredential(this IIdentityServerBuilder builder, SecurityKey key, string signingAlgorithm)\n    {\n        var credential = new SigningCredentials(key, signingAlgorithm);\n        return builder.AddSigningCredential(credential);\n    }\n\n    /// <summary>\n    /// Sets an RSA-based signing credential.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"key\">The RSA key.</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddSigningCredential(this IIdentityServerBuilder builder, RsaSecurityKey key, IdentityServerConstants.RsaSigningAlgorithm signingAlgorithm)\n    {\n        var credential = new SigningCredentials(key, CryptoHelper.GetRsaSigningAlgorithmValue(signingAlgorithm));\n        return builder.AddSigningCredential(credential);\n    }\n\n    /// <summary>\n    /// Sets an ECDsa-based signing credential.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"key\">The ECDsa key.</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddSigningCredential(this IIdentityServerBuilder builder, ECDsaSecurityKey key, IdentityServerConstants.ECDsaSigningAlgorithm signingAlgorithm)\n    {\n        var credential = new SigningCredentials(key, CryptoHelper.GetECDsaSigningAlgorithmValue(signingAlgorithm));\n        return builder.AddSigningCredential(credential);\n    }\n\n    /// <summary>\n    /// Sets the temporary signing credential.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"persistKey\">Specifies if the temporary key should be persisted to disk.</param>\n    /// <param name=\"filename\">The filename.</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm (defaults to RS256)</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddDeveloperSigningCredential(\n        this IIdentityServerBuilder builder,\n        bool persistKey = true,\n        string filename = null,\n        IdentityServerConstants.RsaSigningAlgorithm signingAlgorithm = IdentityServerConstants.RsaSigningAlgorithm.RS256)\n    {\n        if (filename == null)\n        {\n            filename = Path.Combine(Directory.GetCurrentDirectory(), \"tempkey.jwk\");\n        }\n\n        if (File.Exists(filename))\n        {\n            var json = File.ReadAllText(filename);\n            var jwk = new JsonWebKey(json);\n\n            return builder.AddSigningCredential(jwk, jwk.Alg);\n        }\n        else\n        {\n            var key = CryptoHelper.CreateRsaSecurityKey();\n            var jwk = JsonWebKeyConverter.ConvertFromRSASecurityKey(key);\n            jwk.Alg = signingAlgorithm.ToString();\n\n            if (persistKey)\n            {\n                File.WriteAllText(filename, JsonConvert.SerializeObject(jwk));\n            }\n\n            return builder.AddSigningCredential(key, signingAlgorithm);\n        }\n    }\n\n    /// <summary>\n    /// Adds the validation keys.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"keys\">The keys.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddValidationKey(this IIdentityServerBuilder builder, params SecurityKeyInfo[] keys)\n    {\n        builder.Services.AddSingleton<IValidationKeysStore>(new InMemoryValidationKeysStore(keys));\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds an RSA-based validation key.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"key\">The RSA key</param>\n    /// <param name=\"signingAlgorithm\">The RSA-based signing algorithm</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddValidationKey(\n        this IIdentityServerBuilder builder,\n        RsaSecurityKey key,\n        IdentityServerConstants.RsaSigningAlgorithm signingAlgorithm = IdentityServerConstants.RsaSigningAlgorithm.RS256)\n    {\n        var keyInfo = new SecurityKeyInfo\n        {\n            Key = key,\n            SigningAlgorithm = CryptoHelper.GetRsaSigningAlgorithmValue(signingAlgorithm)\n        };\n\n        return builder.AddValidationKey(keyInfo);\n    }\n\n    /// <summary>\n    /// Adds an ECDSA-based validation key.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"key\">The ECDSA key</param>\n    /// <param name=\"signingAlgorithm\">The ECDSA-based signing algorithm</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddValidationKey(\n        this IIdentityServerBuilder builder,\n        ECDsaSecurityKey key,\n        IdentityServerConstants.ECDsaSigningAlgorithm signingAlgorithm = IdentityServerConstants.ECDsaSigningAlgorithm.ES256)\n    {\n        var keyInfo = new SecurityKeyInfo\n        {\n            Key = key,\n            SigningAlgorithm = CryptoHelper.GetECDsaSigningAlgorithmValue(signingAlgorithm)\n        };\n\n        return builder.AddValidationKey(keyInfo);\n    }\n\n    /// <summary>\n    /// Adds the validation key.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"certificate\">The certificate.</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm</param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\"></exception>\n    public static IIdentityServerBuilder AddValidationKey(\n        this IIdentityServerBuilder builder,\n        X509Certificate2 certificate,\n        string signingAlgorithm = SecurityAlgorithms.RsaSha256)\n    {\n        if (certificate == null) throw new ArgumentNullException(nameof(certificate));\n\n        // add signing algorithm name to key ID to allow using the same key for two different algorithms (e.g. RS256 and PS56);\n        var key = new X509SecurityKey(certificate);\n        key.KeyId += signingAlgorithm;\n        \n        var keyInfo = new SecurityKeyInfo\n        {\n            Key = key,\n            SigningAlgorithm = signingAlgorithm\n        };\n\n        return builder.AddValidationKey(keyInfo);\n    }\n\n    /// <summary>\n    /// Adds the validation key from the certificate store.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"location\">The location.</param>\n    /// <param name=\"nameType\">Name parameter can be either a distinguished name or a thumbprint</param>\n    /// <param name=\"signingAlgorithm\">The signing algorithm</param>\n    public static IIdentityServerBuilder AddValidationKey(\n        this IIdentityServerBuilder builder,\n        string name,\n        StoreLocation location = StoreLocation.LocalMachine,\n        NameType nameType = NameType.SubjectDistinguishedName,\n        string signingAlgorithm = SecurityAlgorithms.RsaSha256)\n    {\n        var certificate = CryptoHelper.FindCertificate(name, location, nameType);\n        if (certificate == null) throw new InvalidOperationException($\"certificate: '{name}' not found in certificate store\");\n\n        return builder.AddValidationKey(certificate, signingAlgorithm);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/BuilderExtensions/InMemory.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Builder extension methods for registering in-memory services\n/// </summary>\npublic static class IdentityServerBuilderExtensionsInMemory\n{\n    /// <summary>\n    /// Adds the in memory caching.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryCaching(this IIdentityServerBuilder builder)\n    {\n        builder.Services.TryAddSingleton<IMemoryCache, MemoryCache>();\n        builder.Services.TryAddTransient(typeof(ICache<>), typeof(DefaultCache<>));\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the in memory identity resources.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"identityResources\">The identity resources.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryIdentityResources(this IIdentityServerBuilder builder, IEnumerable<IdentityResource> identityResources)\n    {\n        builder.Services.AddSingleton(identityResources);\n        builder.AddResourceStore<InMemoryResourcesStore>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the in memory identity resources.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"section\">The configuration section containing the configuration data.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryIdentityResources(this IIdentityServerBuilder builder, IConfigurationSection section)\n    {\n        var resources = new List<IdentityResource>();\n        section.Bind(resources);\n\n        return builder.AddInMemoryIdentityResources(resources);\n    }\n\n    /// <summary>\n    /// Adds the in memory API resources.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"apiResources\">The API resources.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryApiResources(this IIdentityServerBuilder builder, IEnumerable<ApiResource> apiResources)\n    {\n        builder.Services.AddSingleton(apiResources);\n        builder.AddResourceStore<InMemoryResourcesStore>();\n\n        return builder;\n    }\n    \n    /// <summary>\n    /// Adds the in memory API resources.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"section\">The configuration section containing the configuration data.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryApiResources(this IIdentityServerBuilder builder, IConfigurationSection section)\n    {\n        var resources = new List<ApiResource>();\n        section.Bind(resources);\n\n        return builder.AddInMemoryApiResources(resources);\n    }\n\n    /// <summary>\n    /// Adds the in memory API scopes.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"apiScopes\">The API scopes.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryApiScopes(this IIdentityServerBuilder builder, IEnumerable<ApiScope> apiScopes)\n    {\n        builder.Services.AddSingleton(apiScopes);\n        builder.AddResourceStore<InMemoryResourcesStore>();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds the in memory scopes.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"section\">The configuration section containing the configuration data.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryApiScopes(this IIdentityServerBuilder builder, IConfigurationSection section)\n    {\n        var resources = new List<ApiScope>();\n        section.Bind(resources);\n\n        return builder.AddInMemoryApiScopes(resources);\n    }\n\n    /// <summary>\n    /// Adds the in memory clients.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"clients\">The clients.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryClients(this IIdentityServerBuilder builder, IEnumerable<Client> clients)\n    {\n        builder.Services.AddSingleton(clients);\n\n        builder.AddClientStore<InMemoryClientStore>();\n\n        var existingCors = builder.Services.Where(x => x.ServiceType == typeof(ICorsPolicyService)).LastOrDefault();\n        if (existingCors != null && \n            existingCors.ImplementationType == typeof(DefaultCorsPolicyService) && \n            existingCors.Lifetime == ServiceLifetime.Transient)\n        {\n            // if our default is registered, then overwrite with the InMemoryCorsPolicyService\n            // otherwise don't overwrite with the InMemoryCorsPolicyService, which uses the custom one registered by the host\n            builder.Services.AddTransient<ICorsPolicyService, InMemoryCorsPolicyService>();\n        }\n\n        return builder;\n    }\n\n\n    /// <summary>\n    /// Adds the in memory clients.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"section\">The configuration section containing the configuration data.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryClients(this IIdentityServerBuilder builder, IConfigurationSection section)\n    {\n        var clients = new List<Client>();\n        section.Bind(clients);\n\n        return builder.AddInMemoryClients(clients);\n    }\n\n\n    /// <summary>\n    /// Adds the in memory stores.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddInMemoryPersistedGrants(this IIdentityServerBuilder builder)\n    {\n        builder.Services.TryAddSingleton<IPersistedGrantStore, InMemoryPersistedGrantStore>();\n        builder.Services.TryAddSingleton<IDeviceFlowStore, InMemoryDeviceFlowStore>();\n\n        return builder;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/ConfigureInternalCookieOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\ninternal class ConfigureInternalCookieOptions : IConfigureNamedOptions<CookieAuthenticationOptions>\n{\n    private readonly IdentityServerOptions _idsrv;\n\n    public ConfigureInternalCookieOptions(IdentityServerOptions idsrv)\n    {\n        _idsrv = idsrv;\n    }\n\n    public void Configure(CookieAuthenticationOptions options)\n    {\n    }\n\n    public void Configure(string name, CookieAuthenticationOptions options)\n    {\n        if (name == IdentityServerConstants.DefaultCookieAuthenticationScheme)\n        {\n            options.SlidingExpiration = _idsrv.Authentication.CookieSlidingExpiration;\n            options.ExpireTimeSpan = _idsrv.Authentication.CookieLifetime;\n            options.Cookie.Name = IdentityServerConstants.DefaultCookieAuthenticationScheme;\n            options.Cookie.IsEssential = true;\n            options.Cookie.SameSite = _idsrv.Authentication.CookieSameSiteMode;\n\n            options.LoginPath = ExtractLocalUrl(_idsrv.UserInteraction.LoginUrl);\n            options.LogoutPath = ExtractLocalUrl(_idsrv.UserInteraction.LogoutUrl);\n            if (_idsrv.UserInteraction.LoginReturnUrlParameter != null)\n            {\n                options.ReturnUrlParameter = _idsrv.UserInteraction.LoginReturnUrlParameter;\n            }\n        }\n\n        if (name == IdentityServerConstants.ExternalCookieAuthenticationScheme)\n        {\n            options.Cookie.Name = IdentityServerConstants.ExternalCookieAuthenticationScheme;\n            options.Cookie.IsEssential = true;\n            // https://github.com/alexhiggins732/IdentityServer8/issues/2595\n            // need to set None because iOS 12 safari considers the POST back to the client from the \n            // IdP as not safe, so cookies issued from response (with lax) then should not be honored.\n            // so we need to make those cookies issued without same-site, thus the browser will\n            // hold onto them and send on the next redirect to the callback page.\n            // see: https://brockallen.com/2019/01/11/same-site-cookies-asp-net-core-and-external-authentication-providers/\n            options.Cookie.SameSite = _idsrv.Authentication.CookieSameSiteMode;\n        }\n    }\n\n    private static string ExtractLocalUrl(string url)\n    {\n        if (url.IsLocalUrl())\n        {\n            if (url.StartsWith(\"~/\"))\n            {\n                url = url.Substring(1);\n            }\n\n            return url;\n        }\n\n        return null;\n    }\n}\n\ninternal class PostConfigureInternalCookieOptions : IPostConfigureOptions<CookieAuthenticationOptions>\n{\n    private readonly IdentityServerOptions _idsrv;\n    private readonly IOptions<Microsoft.AspNetCore.Authentication.AuthenticationOptions> _authOptions;\n    private readonly ILogger _logger;\n\n    public PostConfigureInternalCookieOptions(\n        IdentityServerOptions idsrv,\n        IOptions<Microsoft.AspNetCore.Authentication.AuthenticationOptions> authOptions,\n        ILoggerFactory loggerFactory)\n    {\n        _idsrv = idsrv;\n        _authOptions = authOptions;\n        _logger = loggerFactory.CreateLogger(\"IdentityServer8.Startup\");\n    }\n\n    public void PostConfigure(string name, CookieAuthenticationOptions options)\n    {\n        var scheme = _idsrv.Authentication.CookieAuthenticationScheme ??\n            _authOptions.Value.DefaultAuthenticateScheme ??\n            _authOptions.Value.DefaultScheme;\n\n        if (name == scheme)\n        {\n            _idsrv.UserInteraction.LoginUrl = _idsrv.UserInteraction.LoginUrl ?? options.LoginPath;\n            _idsrv.UserInteraction.LoginReturnUrlParameter = _idsrv.UserInteraction.LoginReturnUrlParameter ?? options.ReturnUrlParameter;\n            _idsrv.UserInteraction.LogoutUrl = _idsrv.UserInteraction.LogoutUrl ?? options.LogoutPath;\n\n            _logger.LogDebug(\"Login Url: {url}\", _idsrv.UserInteraction.LoginUrl);\n            _logger.LogDebug(\"Login Return Url Parameter: {param}\", _idsrv.UserInteraction.LoginReturnUrlParameter);\n            _logger.LogDebug(\"Logout Url: {url}\", _idsrv.UserInteraction.LogoutUrl);\n\n            _logger.LogDebug(\"ConsentUrl Url: {url}\", _idsrv.UserInteraction.ConsentUrl);\n            _logger.LogDebug(\"Consent Return Url Parameter: {param}\", _idsrv.UserInteraction.ConsentReturnUrlParameter);\n\n            _logger.LogDebug(\"Error Url: {url}\", _idsrv.UserInteraction.ErrorUrl);\n            _logger.LogDebug(\"Error Id Parameter: {param}\", _idsrv.UserInteraction.ErrorIdParameter);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/ConfigureOpenIdConnectOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\ninternal class ConfigureOpenIdConnectOptions : IPostConfigureOptions<OpenIdConnectOptions>\n{\n    private string[] _schemes;\n    private readonly IHttpContextAccessor _httpContextAccessor;\n\n    public ConfigureOpenIdConnectOptions(string[] schemes, IHttpContextAccessor httpContextAccessor)\n    {\n        _schemes = schemes ?? throw new ArgumentNullException(nameof(schemes));\n        _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));\n    }\n\n    public void PostConfigure(string name, OpenIdConnectOptions options)\n    {\n        // no schemes means configure them all\n        if (_schemes.Length == 0 || _schemes.Contains(name))\n        {\n            options.StateDataFormat = new DistributedCacheStateDataFormatter(_httpContextAccessor, name);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Decorator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration.DependencyInjection;\n\ninternal class Decorator<TService>\n{\n    public TService Instance { get; set; }\n\n    public Decorator(TService instance)\n    {\n        Instance = instance;\n    }\n}\n\ninternal class Decorator<TService, TImpl> : Decorator<TService>\n    where TImpl : class, TService\n{\n    public Decorator(TImpl instance) : base(instance)\n    {\n    }\n}\n\ninternal class DisposableDecorator<TService> : Decorator<TService>, IDisposable\n{\n    public DisposableDecorator(TService instance) : base(instance)\n    {\n    }\n\n    public void Dispose()\n    {\n        (Instance as IDisposable)?.Dispose();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/IIdentityServerBuilder.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// IdentityServer builder Interface\n/// </summary>\npublic interface IIdentityServerBuilder\n{\n    /// <summary>\n    /// Gets the services.\n    /// </summary>\n    /// <value>\n    /// The services.\n    /// </value>\n    IServiceCollection Services { get; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/IdentityServerBuilder.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// IdentityServer helper class for DI configuration\n/// </summary>\npublic class IdentityServerBuilder : IIdentityServerBuilder\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IdentityServerBuilder\"/> class.\n    /// </summary>\n    /// <param name=\"services\">The services.</param>\n    /// <exception cref=\"System.ArgumentNullException\">services</exception>\n    public IdentityServerBuilder(IServiceCollection services)\n    {\n        Services = services ?? throw new ArgumentNullException(nameof(services));\n    }\n\n    /// <summary>\n    /// Gets the services.\n    /// </summary>\n    /// <value>\n    /// The services.\n    /// </value>\n    public IServiceCollection Services { get; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/IdentityServerServiceCollectionExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// DI extension methods for adding IdentityServer\n/// </summary>\npublic static class IdentityServerServiceCollectionExtensions\n{\n    /// <summary>\n    /// Creates a builder.\n    /// </summary>\n    /// <param name=\"services\">The services.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddIdentityServerBuilder(this IServiceCollection services)\n    {\n        return new IdentityServerBuilder(services);\n    }\n\n    /// <summary>\n    /// Adds IdentityServer.\n    /// </summary>\n    /// <param name=\"services\">The services.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection services)\n    {\n        var builder = services.AddIdentityServerBuilder();\n\n        builder\n            .AddRequiredPlatformServices()\n            .AddCookieAuthentication()\n            .AddCoreServices()\n            .AddDefaultEndpoints()\n            .AddPluggableServices()\n            .AddValidators()\n            .AddResponseGenerators()\n            .AddDefaultSecretParsers()\n            .AddDefaultSecretValidators();\n\n        // provide default in-memory implementation, not suitable for most production scenarios\n        builder.AddInMemoryPersistedGrants();\n\n        return builder;\n    }\n\n    /// <summary>\n    /// Adds IdentityServer.\n    /// </summary>\n    /// <param name=\"services\">The services.</param>\n    /// <param name=\"setupAction\">The setup action.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection services, Action<IdentityServerOptions> setupAction)\n    {\n        services.Configure(setupAction);\n        return services.AddIdentityServer();\n    }\n\n    /// <summary>\n    /// Adds the IdentityServer.\n    /// </summary>\n    /// <param name=\"services\">The services.</param>\n    /// <param name=\"configuration\">The configuration.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection services, IConfiguration configuration)\n    {\n        services.Configure<IdentityServerOptions>(configuration);\n        return services.AddIdentityServer();\n    }\n\n    /// <summary>\n    /// Configures the OpenIdConnect handlers to persist the state parameter into the server-side IDistributedCache.\n    /// </summary>\n    /// <param name=\"services\">The services.</param>\n    /// <param name=\"schemes\">The schemes to configure. If none provided, then all OpenIdConnect schemes will use the cache.</param>\n    public static IServiceCollection AddOidcStateDataFormatterCache(this IServiceCollection services, params string[] schemes)\n    {\n        services.AddSingleton<IPostConfigureOptions<OpenIdConnectOptions>>(\n            svcs => new ConfigureOpenIdConnectOptions(\n                schemes,\n                svcs.GetRequiredService<IHttpContextAccessor>())\n        );\n\n        return services;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/AuthenticationOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Configures the login and logout views and behavior.\n/// </summary>\npublic class AuthenticationOptions\n{\n    /// <summary>\n    /// Sets the cookie authentication scheme configured by the host used for interactive users. If not set, the scheme will inferred from the host's default authentication scheme.\n    /// This setting is typically used when AddPolicyScheme is used in the host as the default scheme.\n    /// </summary>\n    public string CookieAuthenticationScheme { get; set; }\n\n    /// <summary>\n    /// Sets the cookie lifetime (only effective if the IdentityServer-provided cookie handler is used)\n    /// </summary>\n    public TimeSpan CookieLifetime { get; set; } = Constants.DefaultCookieTimeSpan;\n\n    /// <summary>\n    /// Specified if the cookie should be sliding or not (only effective if the built-in cookie middleware is used)\n    /// </summary>\n    public bool CookieSlidingExpiration { get; set; } = false;\n    \n    /// <summary>\n    /// Specifies the SameSite mode for the internal authentication and temp cookie\n    /// </summary>\n    public SameSiteMode CookieSameSiteMode { get; set; } = SameSiteMode.None;\n\n    /// <summary>\n    /// Indicates if user must be authenticated to accept parameters to end session endpoint. Defaults to false.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if required; otherwise, <c>false</c>.\n    /// </value>\n    public bool RequireAuthenticatedUserForSignOutMessage { get; set; } = false;\n\n    /// <summary>\n    /// Gets or sets the name of the cookie used for the check session endpoint.\n    /// </summary>\n    public string CheckSessionCookieName { get; set; } = IdentityServerConstants.DefaultCheckSessionCookieName;\n    \n    /// <summary>\n    /// Gets or sets the domain of the cookie used for the check session endpoint. Defaults to null.\n    /// </summary>\n    public string CheckSessionCookieDomain { get; set; }\n\n    /// <summary>\n    /// Gets or sets the SameSite mode of the cookie used for the check session endpoint. Defaults to SameSiteMode.None.\n    /// </summary>\n    public SameSiteMode CheckSessionCookieSameSiteMode { get; set; } = SameSiteMode.None;\n\n    /// <summary>\n    /// If set, will require frame-src CSP headers being emitting on the end session callback endpoint which renders iframes to clients for front-channel signout notification.\n    /// </summary>\n    public bool RequireCspFrameSrcForSignout { get; set; } = true;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/CachingOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Caching options.\n/// </summary>\npublic class CachingOptions\n{\n    private static readonly TimeSpan Default = TimeSpan.FromMinutes(15);\n\n    /// <summary>\n    /// Gets or sets the client store expiration.\n    /// </summary>\n    /// <value>\n    /// The client store expiration.\n    /// </value>\n    public TimeSpan ClientStoreExpiration { get; set; } = Default;\n\n    /// <summary>\n    /// Gets or sets the scope store expiration.\n    /// </summary>\n    /// <value>\n    /// The scope store expiration.\n    /// </value>\n    public TimeSpan ResourceStoreExpiration { get; set; } = Default;\n\n    /// <summary>\n    /// Gets or sets the CORS origin expiration.\n    /// </summary>\n    public TimeSpan CorsExpiration { get; set; } = Default;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/CorsOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Options for CORS\n/// </summary>\npublic class CorsOptions\n{\n    /// <summary>\n    /// Gets or sets the name of the cors policy.\n    /// </summary>\n    /// <value>\n    /// The name of the cors policy.\n    /// </value>\n    public string CorsPolicyName { get; set; } = Constants.IdentityServerName;\n\n    /// <summary>\n    /// The value to be used in the preflight `Access-Control-Max-Age` response header.\n    /// </summary>\n    public TimeSpan? PreflightCacheDuration { get; set; }\n\n    /// <summary>\n    /// Gets or sets the cors paths.\n    /// </summary>\n    /// <value>\n    /// The cors paths.\n    /// </value>\n    public ICollection<PathString> CorsPaths { get; set; } = Constants.ProtocolRoutePaths.CorsPaths.Select(x => new PathString(x.EnsureLeadingSlash())).ToList();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/CspOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Options for Content Security Policy\n/// </summary>\npublic class CspOptions\n{\n    /// <summary>\n    /// Gets or sets the minimum CSP level.\n    /// </summary>\n    public CspLevel Level { get; set; } = CspLevel.Two;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the deprected X-Content-Security-Policy header should be added.\n    /// </summary>\n    public bool AddDeprecatedHeader { get; set; } = true;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/DeviceFlowOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Configures device flow\n/// </summary>\npublic class DeviceFlowOptions\n{\n    /// <summary>\n    /// Gets or sets the default type of the user code.\n    /// </summary>\n    /// <value>\n    /// The default type of the user code.\n    /// </value>\n    public string DefaultUserCodeType { get; set; } = IdentityServerConstants.UserCodeTypes.Numeric;\n\n    /// <summary>\n    /// Gets or sets the polling interval in seconds.\n    /// </summary>\n    /// <value>\n    /// The interval in seconds.\n    /// </value>\n    public int Interval { get; set; } = 5;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/DiscoveryOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Options class to configure discovery endpoint\n/// </summary>\npublic class DiscoveryOptions\n{\n    /// <summary>\n    /// Show endpoints\n    /// </summary>\n    public bool ShowEndpoints { get; set; } = true;\n\n    /// <summary>\n    /// Show signing keys\n    /// </summary>\n    public bool ShowKeySet { get; set; } = true;\n\n    /// <summary>\n    /// Show identity scopes\n    /// </summary>\n    public bool ShowIdentityScopes { get; set; } = true;\n\n    /// <summary>\n    /// Show API scopes\n    /// </summary>\n    public bool ShowApiScopes { get; set; } = true;\n\n    /// <summary>\n    /// Show identity claims\n    /// </summary>\n    public bool ShowClaims { get; set; } = true;\n\n    /// <summary>\n    /// Show response types\n    /// </summary>\n    public bool ShowResponseTypes { get; set; } = true;\n\n    /// <summary>\n    /// Show response modes\n    /// </summary>\n    public bool ShowResponseModes { get; set; } = true;\n\n    /// <summary>\n    /// Show standard grant types\n    /// </summary>\n    public bool ShowGrantTypes { get; set; } = true;\n\n    /// <summary>\n    /// Show custom grant types\n    /// </summary>\n    public bool ShowExtensionGrantTypes { get; set; } = true;\n\n    /// <summary>\n    /// Show token endpoint authentication methods\n    /// </summary>\n    public bool ShowTokenEndpointAuthenticationMethods { get; set; } = true;\n\n    /// <summary>\n    /// Turns relative paths that start with ~/ into absolute paths\n    /// </summary>\n    public bool ExpandRelativePathsInCustomEntries { get; set; } = true;\n\n    /// <summary>\n    /// Sets the maxage value of the cache control header (in seconds) of the HTTP response. This gives clients a hint how often they should refresh their cached copy of the discovery document. If set to 0 no-cache headers will be set. Defaults to null, which does not set the header.\n    /// </summary>\n    /// <value>\n    /// The cache interval in seconds.\n    /// </value>\n    public int? ResponseCacheInterval { get; set; } = null;\n\n    /// <summary>\n    /// Adds custom entries to the discovery document\n    /// </summary>\n    public Dictionary<string, object> CustomEntries { get; set; } = new Dictionary<string, object>();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/EndpointOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Configures which endpoints are enabled or disabled.\n/// </summary>\npublic class EndpointsOptions\n{\n    /// <summary>\n    /// Gets or sets a value indicating whether the authorize endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the authorize endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableAuthorizeEndpoint { get; set; } = true;\n    \n    /// <summary>\n    /// Gets or sets if JWT request_uri processing is enabled on the authorize endpoint. \n    /// </summary>\n    public bool EnableJwtRequestUri { get; set; } = false;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the token endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the token endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableTokenEndpoint { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the user info endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the user info endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableUserInfoEndpoint { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the discovery document endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the disdovery document endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableDiscoveryEndpoint { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the end session endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the end session endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableEndSessionEndpoint { get; set; } = true;\n    \n    /// <summary>\n    /// Gets or sets a value indicating whether the check session endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the check session endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableCheckSessionEndpoint { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the token revocation endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the token revocation endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableTokenRevocationEndpoint { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the introspection endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the introspection endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableIntrospectionEndpoint { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the device authorization endpoint is enabled.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the device authorization endpoint is enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableDeviceAuthorizationEndpoint { get; set; } = true;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/EventsOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Configures events\n/// </summary>\npublic class EventsOptions\n{\n    /// <summary>\n    /// Gets or sets a value indicating whether to raise success events.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if success event should be raised; otherwise, <c>false</c>.\n    /// </value>\n    public bool RaiseSuccessEvents { get; set; } = false;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether to raise failure events.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if failure events should be raised; otherwise, <c>false</c>.\n    /// </value>\n    public bool RaiseFailureEvents { get; set; } = false;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether to raise information events.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if information events should be raised; otherwise, <c>false</c>.\n    /// </value>\n    public bool RaiseInformationEvents { get; set; } = false;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether to raise error events.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if error events should be raised; otherwise, <c>false</c>.\n    /// </value>\n    public bool RaiseErrorEvents { get; set; } = false;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/IdentityServerOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// The IdentityServerOptions class is the top level container for all configuration settings of IdentityServer.\n/// </summary>\npublic class IdentityServerOptions\n{\n    /// <summary>\n    /// Gets or sets the unique name of this server instance, e.g. https://myissuer.com.\n    /// If not set, the issuer name is inferred from the request\n    /// </summary>\n    /// <value>\n    /// Unique name of this server instance, e.g. https://myissuer.com\n    /// </value>\n    public string IssuerUri { get; set; }\n\n    /// <summary>\n    /// Set to false to preserve the original casing of the IssuerUri. Defaults to true.\n    /// </summary>\n    public bool LowerCaseIssuerUri { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets the value for the JWT typ header for access tokens.\n    /// </summary>\n    /// <value>\n    /// The JWT typ value.\n    /// </value>\n    public string AccessTokenJwtType { get; set; } = \"at+jwt\";\n\n    /// <summary>\n    /// Emits an aud claim with the format issuer/resources. That's needed for some older access token validation plumbing. Defaults to false.\n    /// </summary>\n    public bool EmitStaticAudienceClaim { get; set; } = false;\n\n    /// <summary>\n    /// Specifies whether scopes in JWTs are emitted as array or string\n    /// </summary>\n    public bool EmitScopesAsSpaceDelimitedStringInJwt { get; set; } = false;\n    \n    /// <summary>\n    /// Specifies whether the JWT typ and content-type for JWT secured authorization requests is checked according to IETF spec.\n    /// This might break older OIDC conformant request objects.\n    /// </summary>\n    public bool StrictJarValidation { get; set; } = false;\n\n    /// <summary>\n    /// Gets or sets the endpoint configuration.\n    /// </summary>\n    /// <value>\n    /// The endpoints configuration.\n    /// </value>\n    public EndpointsOptions Endpoints { get; set; } = new EndpointsOptions();\n\n    /// <summary>\n    /// Gets or sets the discovery endpoint configuration.\n    /// </summary>\n    /// <value>\n    /// The discovery endpoint configuration.\n    /// </value>\n    public DiscoveryOptions Discovery { get; set; } = new DiscoveryOptions();\n\n    /// <summary>\n    /// Gets or sets the authentication options.\n    /// </summary>\n    /// <value>\n    /// The authentication options.\n    /// </value>\n    public AuthenticationOptions Authentication { get; set; } = new AuthenticationOptions();\n\n    /// <summary>\n    /// Gets or sets the events options.\n    /// </summary>\n    /// <value>\n    /// The events options.\n    /// </value>\n    public EventsOptions Events { get; set; } = new EventsOptions();\n\n    /// <summary>\n    /// Gets or sets the max input length restrictions.\n    /// </summary>\n    /// <value>\n    /// The length restrictions.\n    /// </value>\n    public InputLengthRestrictions InputLengthRestrictions { get; set; } = new InputLengthRestrictions();\n\n    /// <summary>\n    /// Gets or sets the options for the user interaction.\n    /// </summary>\n    /// <value>\n    /// The user interaction options.\n    /// </value>\n    public UserInteractionOptions UserInteraction { get; set; } = new UserInteractionOptions();\n\n    /// <summary>\n    /// Gets or sets the caching options.\n    /// </summary>\n    /// <value>\n    /// The caching options.\n    /// </value>\n    public CachingOptions Caching { get; set; } = new CachingOptions();\n\n    /// <summary>\n    /// Gets or sets the cors options.\n    /// </summary>\n    /// <value>\n    /// The cors options.\n    /// </value>\n    public CorsOptions Cors { get; set; } = new CorsOptions();\n\n    /// <summary>\n    /// Gets or sets the Content Security Policy options.\n    /// </summary>\n    public CspOptions Csp { get; set; } = new CspOptions();\n\n    /// <summary>\n    /// Gets or sets the validation options.\n    /// </summary>\n    public ValidationOptions Validation { get; set; } = new ValidationOptions();\n\n    /// <summary>\n    /// Gets or sets the device flow options.\n    /// </summary>\n    public DeviceFlowOptions DeviceFlow { get; set; } = new DeviceFlowOptions();\n    \n    /// <summary>\n    /// Gets or sets the logging options\n    /// </summary>\n    public LoggingOptions Logging { get; set; } = new LoggingOptions();\n\n    /// <summary>\n    /// Gets or sets the mutual TLS options.\n    /// </summary>\n    public MutualTlsOptions MutualTls { get; set; } = new MutualTlsOptions();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/InputLengthRestrictions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// \n/// </summary>\npublic class InputLengthRestrictions\n{\n    private const int Default = 100;\n\n    /// <summary>\n    /// Max length for client_id\n    /// </summary>\n    public int ClientId { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for external client secrets\n    /// </summary>\n    public int ClientSecret { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for scope\n    /// </summary>\n    public int Scope { get; set; } = 300;\n\n    /// <summary>\n    /// Max length for redirect_uri\n    /// </summary>\n    public int RedirectUri { get; set; } = 400;\n\n    /// <summary>\n    /// Max length for nonce\n    /// </summary>\n    public int Nonce { get; set; } = 300;\n\n    /// <summary>\n    /// Max length for ui_locale\n    /// </summary>\n    public int UiLocale { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for login_hint\n    /// </summary>\n    public int LoginHint { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for acr_values\n    /// </summary>\n    public int AcrValues { get; set; } = 300;\n\n    /// <summary>\n    /// Max length for grant_type\n    /// </summary>\n    public int GrantType { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for username\n    /// </summary>\n    public int UserName { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for password\n    /// </summary>\n    public int Password { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for CSP reports\n    /// </summary>\n    public int CspReport { get; set; } = 2000;\n\n    /// <summary>\n    /// Max length for external identity provider name\n    /// </summary>\n    public int IdentityProvider { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for external identity provider errors\n    /// </summary>\n    public int ExternalError { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for authorization codes\n    /// </summary>\n    public int AuthorizationCode { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for device codes\n    /// </summary>\n    public int DeviceCode { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for refresh tokens\n    /// </summary>\n    public int RefreshToken { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for token handles\n    /// </summary>\n    public int TokenHandle { get; set; } = Default;\n\n    /// <summary>\n    /// Max length for JWTs\n    /// </summary>\n    public int Jwt { get; set; } = 51200;\n\n    /// <summary>\n    /// Min length for the code challenge\n    /// </summary>\n    public int CodeChallengeMinLength { get; } = 43;\n\n    /// <summary>\n    /// Max length for the code challenge\n    /// </summary>\n    public int CodeChallengeMaxLength { get; } = 128;\n\n    /// <summary>\n    /// Min length for the code verifier\n    /// </summary>\n    public int CodeVerifierMinLength { get; } = 43;\n\n    /// <summary>\n    /// Max length for the code verifier\n    /// </summary>\n    public int CodeVerifierMaxLength { get; } = 128;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/LoggingOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Options for configuring logging behavior\n/// </summary>\npublic class LoggingOptions\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public ICollection<string> TokenRequestSensitiveValuesFilter { get; set; } = \n        new HashSet<string>\n        {\n            OidcConstants.TokenRequest.ClientSecret,\n            OidcConstants.TokenRequest.Password,\n            OidcConstants.TokenRequest.ClientAssertion,\n            OidcConstants.TokenRequest.RefreshToken,\n            OidcConstants.TokenRequest.DeviceCode\n        };\n\n    /// <summary>\n    /// \n    /// </summary>\n    public ICollection<string> AuthorizeRequestSensitiveValuesFilter { get; set; } = \n        new HashSet<string>\n        {\n            OidcConstants.AuthorizeRequest.IdTokenHint\n        };\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/MtlsOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Options for Mutual TLS features\n/// </summary>\npublic class MutualTlsOptions\n{\n    /// <summary>\n    /// Specifies if MTLS support should be enabled\n    /// </summary>\n    public bool Enabled { get; set; }\n\n    /// <summary>\n    /// Specifies the name of the authentication handler for X.509 client certificates\n    /// </summary>\n    public string ClientCertificateAuthenticationScheme { get; set; } = \"Certificate\";\n\n    /// <summary>\n    /// Specifies a separate domain to run the MTLS endpoints on.\n    /// If the string does not contain any dots, a subdomain is assumed - e.g. main domain: identityserver.local, MTLS domain: mtls.identityserver.local\n    /// If the string contains dots, a completely separate domain is assumend, e.g. main domain: identity.app.com, MTLS domain: mtls.app.com. In this case you must set a static issuer name on the options.\n    /// </summary>\n    public string DomainName { get; set; }\n\n    /// <summary>\n    /// Specifies whether a cnf claim gets emitted for access tokens if a client certificate was present.\n    /// Normally the cnf claims only gets emitted if the client used the client certificate for authentication,\n    /// setting this to true, will set the claim regardless of the authentication method. (defaults to false).\n    /// </summary>\n    public bool AlwaysEmitConfirmationClaim { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/UserInteractionOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// Options for aspects of the user interface.\n/// </summary>\npublic class UserInteractionOptions\n{\n    /// <summary>\n    /// Gets or sets the login URL. If a local URL, the value must start with a leading slash.\n    /// </summary>\n    /// <value>\n    /// The login URL.\n    /// </value>\n    public string LoginUrl { get; set; } //= Constants.UIConstants.DefaultRoutePaths.Login.EnsureLeadingSlash();\n\n    /// <summary>\n    /// Gets or sets the login return URL parameter.\n    /// </summary>\n    /// <value>\n    /// The login return URL parameter.\n    /// </value>\n    public string LoginReturnUrlParameter { get; set; } //= Constants.UIConstants.DefaultRoutePathParams.Login;\n\n    /// <summary>\n    /// Gets or sets the logout URL. If a local URL, the value must start with a leading slash.\n    /// </summary>\n    /// <value>\n    /// The logout URL.\n    /// </value>\n    public string LogoutUrl { get; set; } //= Constants.UIConstants.DefaultRoutePaths.Logout.EnsureLeadingSlash();\n\n    /// <summary>\n    /// Gets or sets the logout identifier parameter.\n    /// </summary>\n    /// <value>\n    /// The logout identifier parameter.\n    /// </value>\n    public string LogoutIdParameter { get; set; } = Constants.UIConstants.DefaultRoutePathParams.Logout;\n\n    /// <summary>\n    /// Gets or sets the consent URL. If a local URL, the value must start with a leading slash.\n    /// </summary>\n    /// <value>\n    /// The consent URL.\n    /// </value>\n    public string ConsentUrl { get; set; } = Constants.UIConstants.DefaultRoutePaths.Consent.EnsureLeadingSlash();\n\n    /// <summary>\n    /// Gets or sets the consent return URL parameter.\n    /// </summary>\n    /// <value>\n    /// The consent return URL parameter.\n    /// </value>\n    public string ConsentReturnUrlParameter { get; set; } = Constants.UIConstants.DefaultRoutePathParams.Consent;\n\n    /// <summary>\n    /// Gets or sets the error URL. If a local URL, the value must start with a leading slash.\n    /// </summary>\n    /// <value>\n    /// The error URL.\n    /// </value>\n    public string ErrorUrl { get; set; } = Constants.UIConstants.DefaultRoutePaths.Error.EnsureLeadingSlash();\n\n    /// <summary>\n    /// Gets or sets the error identifier parameter.\n    /// </summary>\n    /// <value>\n    /// The error identifier parameter.\n    /// </value>\n    public string ErrorIdParameter { get; set; } = Constants.UIConstants.DefaultRoutePathParams.Error;\n\n    /// <summary>\n    /// Gets or sets the custom redirect return URL parameter.\n    /// </summary>\n    /// <value>\n    /// The custom redirect return URL parameter.\n    /// </value>\n    public string CustomRedirectReturnUrlParameter { get; set; } = Constants.UIConstants.DefaultRoutePathParams.Custom;\n\n    /// <summary>\n    /// Gets or sets the cookie message threshold. This limits how many cookies are created, and older ones will be purged.\n    /// </summary>\n    /// <value>\n    /// The cookie message threshold.\n    /// </value>\n    public int CookieMessageThreshold { get; set; } = Constants.UIConstants.CookieMessageThreshold;\n\n    /// <summary>\n    /// Gets or sets the device verification URL.  If a local URL, the value must start with a leading slash.\n    /// </summary>\n    /// <value>\n    /// The device verification URL.\n    /// </value>\n    public string DeviceVerificationUrl { get; set; } = Constants.UIConstants.DefaultRoutePaths.DeviceVerification;\n\n    /// <summary>\n    /// Gets or sets the device verification user code paramater.\n    /// </summary>\n    /// <value>\n    /// The device verification user code parameter.\n    /// </value>\n    public string DeviceVerificationUserCodeParameter { get; set; } = Constants.UIConstants.DefaultRoutePathParams.UserCode;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/DependencyInjection/Options/ValidationOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Configuration;\n\n/// <summary>\n/// The ValidationOptions contains settings that affect some of the default validation behavior.\n/// </summary>\npublic class ValidationOptions\n{\n    /// <summary>\n    ///  Collection of URI scheme prefixes that should never be used as custom URI schemes in the redirect_uri passed to tha authorize endpoint.\n    /// </summary>\n    public ICollection<string> InvalidRedirectUriPrefixes { get; } = new HashSet<string>\n    {\n        \"javascript:\",\n        \"file:\",\n        \"data:\",\n        \"mailto:\",\n        \"ftp:\",\n        \"blob:\",\n        \"about:\",\n        \"ssh:\",\n        \"tel:\",\n        \"view-source:\",\n        \"ws:\",\n        \"wss:\"\n    };\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/IdentityServerApplicationBuilderExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.AspNetCore.Builder;\n\n/// <summary>\n/// Pipeline extension methods for adding IdentityServer\n/// </summary>\npublic static class IdentityServerApplicationBuilderExtensions\n{\n    /// <summary>\n    /// Adds IdentityServer to the pipeline.\n    /// </summary>\n    /// <param name=\"app\">The application.</param>\n    /// <param name=\"options\">The options.</param>\n    /// <returns></returns>\n    public static IApplicationBuilder UseIdentityServer(this IApplicationBuilder app, IdentityServerMiddlewareOptions options = null)\n    {\n        app.Validate();\n\n        app.UseMiddleware<BaseUrlMiddleware>();\n\n        app.ConfigureCors();\n\n        // it seems ok if we have UseAuthentication more than once in the pipeline --\n        // this will just re-run the various callback handlers and the default authN \n        // handler, which just re-assigns the user on the context. claims transformation\n        // will run twice, since that's not cached (whereas the authN handler result is)\n        // related: https://github.com/aspnet/Security/issues/1399\n        if (options == null) options = new IdentityServerMiddlewareOptions();\n        options.AuthenticationMiddleware(app);\n\n        app.UseMiddleware<MutualTlsEndpointMiddleware>();\n        app.UseMiddleware<IdentityServerMiddleware>();\n\n        return app;\n    }\n\n    internal static void Validate(this IApplicationBuilder app)\n    {\n        var loggerFactory = app.ApplicationServices.GetService(typeof(ILoggerFactory)) as ILoggerFactory;\n        if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory));\n\n        var logger = loggerFactory.CreateLogger(\"IdentityServer8.Startup\");\n        logger.LogInformation(\"Starting IdentityServer8 version {version}\", typeof(IdentityServer8.Hosting.IdentityServerMiddleware).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion);\n\n        var scopeFactory = app.ApplicationServices.GetService<IServiceScopeFactory>();\n\n        using (var scope = scopeFactory.CreateScope())\n        {\n            var serviceProvider = scope.ServiceProvider;\n\n            TestService(serviceProvider, typeof(IPersistedGrantStore), logger, \"No storage mechanism for grants specified. Use the 'AddInMemoryPersistedGrants' extension method to register a development version.\");\n            TestService(serviceProvider, typeof(IClientStore), logger, \"No storage mechanism for clients specified. Use the 'AddInMemoryClients' extension method to register a development version.\");\n            TestService(serviceProvider, typeof(IResourceStore), logger, \"No storage mechanism for resources specified. Use the 'AddInMemoryIdentityResources' or 'AddInMemoryApiResources' extension method to register a development version.\");\n\n            var persistedGrants = serviceProvider.GetService(typeof(IPersistedGrantStore));\n            if (persistedGrants.GetType().FullName == typeof(InMemoryPersistedGrantStore).FullName)\n            {\n                logger.LogInformation(\"You are using the in-memory version of the persisted grant store. This will store consent decisions, authorization codes, refresh and reference tokens in memory only. If you are using any of those features in production, you want to switch to a different store implementation.\");\n            }\n\n            var options = serviceProvider.GetRequiredService<IdentityServerOptions>();\n            ValidateOptions(options, logger);\n\n            ValidateAsync(serviceProvider, logger).GetAwaiter().GetResult();\n        }\n    }\n\n    private static async Task ValidateAsync(IServiceProvider services, ILogger logger)\n    {\n        var options = services.GetRequiredService<IdentityServerOptions>();\n        var schemes = services.GetRequiredService<IAuthenticationSchemeProvider>();\n\n\n        if (await schemes.GetDefaultAuthenticateSchemeAsync() == null && options.Authentication.CookieAuthenticationScheme == null)\n        {\n            logger.LogWarning(\"No authentication scheme has been set. Setting either a default authentication scheme or a CookieAuthenticationScheme on IdentityServerOptions is required.\");\n        }\n        else\n        {\n            AuthenticationScheme authenticationScheme = null;\n\n            if (options.Authentication.CookieAuthenticationScheme != null)\n            {\n                authenticationScheme = await schemes.GetSchemeAsync(options.Authentication.CookieAuthenticationScheme);\n                logger.LogInformation(\"Using explicitly configured authentication scheme {scheme} for IdentityServer\", options.Authentication.CookieAuthenticationScheme);\n            }\n            else\n            {\n                authenticationScheme = await schemes.GetDefaultAuthenticateSchemeAsync();\n                logger.LogInformation(\"Using the default authentication scheme {scheme} for IdentityServer\", authenticationScheme.Name);\n            }\n\n            if (!typeof(IAuthenticationSignInHandler).IsAssignableFrom(authenticationScheme.HandlerType))\n            {\n                logger.LogInformation(\"Authentication scheme {scheme} is configured for IdentityServer, but it is not a scheme that supports signin (like cookies). If you support interactive logins via the browser, then a cookie-based scheme should be used.\", authenticationScheme.Name);\n            }\n\n            logger.LogDebug(\"Using {scheme} as default ASP.NET Core scheme for authentication\", (await schemes.GetDefaultAuthenticateSchemeAsync())?.Name);\n            logger.LogDebug(\"Using {scheme} as default ASP.NET Core scheme for sign-in\", (await schemes.GetDefaultSignInSchemeAsync())?.Name);\n            logger.LogDebug(\"Using {scheme} as default ASP.NET Core scheme for sign-out\", (await schemes.GetDefaultSignOutSchemeAsync())?.Name);\n            logger.LogDebug(\"Using {scheme} as default ASP.NET Core scheme for challenge\", (await schemes.GetDefaultChallengeSchemeAsync())?.Name);\n            logger.LogDebug(\"Using {scheme} as default ASP.NET Core scheme for forbid\", (await schemes.GetDefaultForbidSchemeAsync())?.Name);\n        }\n    }\n\n    private static void ValidateOptions(IdentityServerOptions options, ILogger logger)\n    {\n        if (options.IssuerUri.IsPresent()) logger.LogDebug(\"Custom IssuerUri set to {0}\", options.IssuerUri);\n        \n        // todo: perhaps different logging messages?\n        //if (options.UserInteraction.LoginUrl.IsMissing()) throw new InvalidOperationException(\"LoginUrl is not configured\");\n        //if (options.UserInteraction.LoginReturnUrlParameter.IsMissing()) throw new InvalidOperationException(\"LoginReturnUrlParameter is not configured\");\n        //if (options.UserInteraction.LogoutUrl.IsMissing()) throw new InvalidOperationException(\"LogoutUrl is not configured\");\n        if (options.UserInteraction.LogoutIdParameter.IsMissing()) throw new InvalidOperationException(\"LogoutIdParameter is not configured\");\n        if (options.UserInteraction.ErrorUrl.IsMissing()) throw new InvalidOperationException(\"ErrorUrl is not configured\");\n        if (options.UserInteraction.ErrorIdParameter.IsMissing()) throw new InvalidOperationException(\"ErrorIdParameter is not configured\");\n        if (options.UserInteraction.ConsentUrl.IsMissing()) throw new InvalidOperationException(\"ConsentUrl is not configured\");\n        if (options.UserInteraction.ConsentReturnUrlParameter.IsMissing()) throw new InvalidOperationException(\"ConsentReturnUrlParameter is not configured\");\n        if (options.UserInteraction.CustomRedirectReturnUrlParameter.IsMissing()) throw new InvalidOperationException(\"CustomRedirectReturnUrlParameter is not configured\");\n\n        if (options.Authentication.CheckSessionCookieName.IsMissing()) throw new InvalidOperationException(\"CheckSessionCookieName is not configured\");\n\n        if (options.Cors.CorsPolicyName.IsMissing()) throw new InvalidOperationException(\"CorsPolicyName is not configured\");\n    }\n\n    internal static object TestService(IServiceProvider serviceProvider, Type service, ILogger logger, string message = null, bool doThrow = true)\n    {\n        var appService = serviceProvider.GetService(service);\n\n        if (appService == null)\n        {\n            var error = message ?? $\"Required service {service.FullName} is not registered in the DI container. Aborting startup\";\n\n            logger.LogCritical(error);\n\n            if (doThrow)\n            {\n                throw new InvalidOperationException(error);\n            }\n        }\n\n        return appService;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Configuration/IdentityServerMiddlewareOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.AspNetCore.Builder;\n\n/// <summary>\n/// Options for the IdentityServer middleware\n/// </summary>\npublic class IdentityServerMiddlewareOptions\n{\n    /// <summary>\n    /// Callback to wire up an authentication middleware\n    /// </summary>\n    public Action<IApplicationBuilder> AuthenticationMiddleware { get; set; } = (app) => app.UseAuthentication();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Constants.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8;\n\ninternal static class Constants\n{\n    public const string IdentityServerName               = \"IdentityServer8\";\n    public const string IdentityServerAuthenticationType = IdentityServerName;\n    public const string ExternalAuthenticationMethod     = \"external\";\n    public const string DefaultHashAlgorithm             = \"SHA256\";\n\n    public static readonly TimeSpan DefaultCookieTimeSpan = TimeSpan.FromHours(10);\n    public static readonly TimeSpan DefaultCacheDuration  = TimeSpan.FromMinutes(60);\n\n    public static readonly List<string> SupportedResponseTypes = new List<string> \n    { \n        OidcConstants.ResponseTypes.Code,\n        OidcConstants.ResponseTypes.Token,\n        OidcConstants.ResponseTypes.IdToken,\n        OidcConstants.ResponseTypes.IdTokenToken,\n        OidcConstants.ResponseTypes.CodeIdToken,\n        OidcConstants.ResponseTypes.CodeToken,\n        OidcConstants.ResponseTypes.CodeIdTokenToken\n    };\n\n    public static readonly Dictionary<string, string> ResponseTypeToGrantTypeMapping = new Dictionary<string, string>\n    {\n        { OidcConstants.ResponseTypes.Code, GrantType.AuthorizationCode },\n        { OidcConstants.ResponseTypes.Token, GrantType.Implicit },\n        { OidcConstants.ResponseTypes.IdToken, GrantType.Implicit },\n        { OidcConstants.ResponseTypes.IdTokenToken, GrantType.Implicit },\n        { OidcConstants.ResponseTypes.CodeIdToken, GrantType.Hybrid },\n        { OidcConstants.ResponseTypes.CodeToken, GrantType.Hybrid },\n        { OidcConstants.ResponseTypes.CodeIdTokenToken, GrantType.Hybrid }\n    };\n\n    public static readonly List<string> AllowedGrantTypesForAuthorizeEndpoint = new List<string>\n    {\n        GrantType.AuthorizationCode,\n        GrantType.Implicit,\n        GrantType.Hybrid\n    };\n\n    public static readonly List<string> SupportedCodeChallengeMethods = new List<string>\n    {\n        OidcConstants.CodeChallengeMethods.Plain,\n        OidcConstants.CodeChallengeMethods.Sha256\n    };\n\n    public enum ScopeRequirement\n    {\n        None, \n        ResourceOnly, \n        IdentityOnly,\n        Identity\n    }\n\n    public static readonly Dictionary<string, ScopeRequirement> ResponseTypeToScopeRequirement = new Dictionary<string, ScopeRequirement>\n    {\n        { OidcConstants.ResponseTypes.Code, ScopeRequirement.None },\n        { OidcConstants.ResponseTypes.Token, ScopeRequirement.ResourceOnly },\n        { OidcConstants.ResponseTypes.IdToken, ScopeRequirement.IdentityOnly },\n        { OidcConstants.ResponseTypes.IdTokenToken, ScopeRequirement.Identity },\n        { OidcConstants.ResponseTypes.CodeIdToken, ScopeRequirement.Identity },\n        { OidcConstants.ResponseTypes.CodeToken, ScopeRequirement.Identity },\n        { OidcConstants.ResponseTypes.CodeIdTokenToken, ScopeRequirement.Identity }\n    };\n                        \n    public static readonly Dictionary<string, IEnumerable<string>> AllowedResponseModesForGrantType = new Dictionary<string, IEnumerable<string>>\n    {\n        { GrantType.AuthorizationCode, new[] { OidcConstants.ResponseModes.Query, OidcConstants.ResponseModes.FormPost, OidcConstants.ResponseModes.Fragment } },\n        { GrantType.Hybrid, new[] { OidcConstants.ResponseModes.Fragment, OidcConstants.ResponseModes.FormPost }},\n        { GrantType.Implicit, new[] { OidcConstants.ResponseModes.Fragment, OidcConstants.ResponseModes.FormPost }}\n    };\n\n    public static readonly List<string> SupportedResponseModes = new List<string>\n    {\n        OidcConstants.ResponseModes.FormPost,\n        OidcConstants.ResponseModes.Query,\n        OidcConstants.ResponseModes.Fragment\n    };\n\n    public static string[] SupportedSubjectTypes =\n    {\n        \"pairwise\", \"public\"\n    };\n\n    public static class SigningAlgorithms\n    {\n        public const string RSA_SHA_256 = \"RS256\";\n    }\n\n    public static readonly List<string> SupportedDisplayModes = new List<string>\n    {\n        OidcConstants.DisplayModes.Page,\n        OidcConstants.DisplayModes.Popup,\n        OidcConstants.DisplayModes.Touch,\n        OidcConstants.DisplayModes.Wap\n    };\n\n    public static readonly List<string> SupportedPromptModes = new List<string>\n    {\n        OidcConstants.PromptModes.None,\n        OidcConstants.PromptModes.Login,\n        OidcConstants.PromptModes.Consent,\n        OidcConstants.PromptModes.SelectAccount\n    };\n\n    public static class KnownAcrValues\n    {\n        public const string HomeRealm = \"idp:\";\n        public const string Tenant = \"tenant:\";\n\n        public static readonly string[] All = { HomeRealm, Tenant };\n    }\n\n    public static Dictionary<string, int> ProtectedResourceErrorStatusCodes = new Dictionary<string, int>\n    {\n        { OidcConstants.ProtectedResourceErrors.InvalidToken,      401 },\n        { OidcConstants.ProtectedResourceErrors.ExpiredToken,      401 },\n        { OidcConstants.ProtectedResourceErrors.InvalidRequest,    400 },\n        { OidcConstants.ProtectedResourceErrors.InsufficientScope, 403 }\n    };\n    \n    public static readonly Dictionary<string, IEnumerable<string>> ScopeToClaimsMapping = new Dictionary<string, IEnumerable<string>>\n    {\n        { IdentityServerConstants.StandardScopes.Profile, new[]\n                        { \n                            JwtClaimTypes.Name,\n                            JwtClaimTypes.FamilyName,\n                            JwtClaimTypes.GivenName,\n                            JwtClaimTypes.MiddleName,\n                            JwtClaimTypes.NickName,\n                            JwtClaimTypes.PreferredUserName,\n                            JwtClaimTypes.Profile,\n                            JwtClaimTypes.Picture,\n                            JwtClaimTypes.WebSite,\n                            JwtClaimTypes.Gender,\n                            JwtClaimTypes.BirthDate,\n                            JwtClaimTypes.ZoneInfo,\n                            JwtClaimTypes.Locale,\n                            JwtClaimTypes.UpdatedAt \n                        }},\n        { IdentityServerConstants.StandardScopes.Email, new[]\n                        { \n                            JwtClaimTypes.Email,\n                            JwtClaimTypes.EmailVerified \n                        }},\n        { IdentityServerConstants.StandardScopes.Address, new[]\n                        {\n                            JwtClaimTypes.Address\n                        }},\n        { IdentityServerConstants.StandardScopes.Phone, new[]\n                        {\n                            JwtClaimTypes.PhoneNumber,\n                            JwtClaimTypes.PhoneNumberVerified\n                        }},\n        { IdentityServerConstants.StandardScopes.OpenId, new[]\n                        {\n                            JwtClaimTypes.Subject\n                        }}\n    };\n\n    public static class UIConstants\n    {\n        // the limit after which old messages are purged\n        public const int CookieMessageThreshold = 2;\n\n        public static class DefaultRoutePathParams\n        {\n            public const string Error = \"errorId\";\n            public const string Login = \"returnUrl\";\n            public const string Consent = \"returnUrl\";\n            public const string Logout = \"logoutId\";\n            public const string EndSessionCallback = \"endSessionId\";\n            public const string Custom = \"returnUrl\";\n            public const string UserCode = \"userCode\";\n        }\n\n        public static class DefaultRoutePaths\n        {\n            public const string Login = \"/account/login\";\n            public const string Logout = \"/account/logout\";\n            public const string Consent = \"/consent\";\n            public const string Error = \"/home/error\";\n            public const string DeviceVerification = \"/device\";\n        }\n    }\n\n    public static class EndpointNames\n    {\n        public const string Authorize = \"Authorize\";\n        public const string Token = \"Token\";\n        public const string DeviceAuthorization = \"DeviceAuthorization\";\n        public const string Discovery = \"Discovery\";\n        public const string Introspection = \"Introspection\";\n        public const string Revocation = \"Revocation\";\n        public const string EndSession = \"Endsession\";\n        public const string CheckSession = \"Checksession\";\n        public const string UserInfo = \"Userinfo\";\n    }\n\n    public static class ProtocolRoutePaths\n    {\n        public const string ConnectPathPrefix       = \"connect\";\n\n        public const string Authorize               = ConnectPathPrefix + \"/authorize\";\n        public const string AuthorizeCallback       = Authorize + \"/callback\";\n        public const string DiscoveryConfiguration  = \".well-known/openid-configuration\";\n        public const string DiscoveryWebKeys        = DiscoveryConfiguration + \"/jwks\";\n        public const string Token                   = ConnectPathPrefix + \"/token\";\n        public const string Revocation              = ConnectPathPrefix + \"/revocation\";\n        public const string UserInfo                = ConnectPathPrefix + \"/userinfo\";\n        public const string Introspection           = ConnectPathPrefix + \"/introspect\";\n        public const string EndSession              = ConnectPathPrefix + \"/endsession\";\n        public const string EndSessionCallback      = EndSession + \"/callback\";\n        public const string CheckSession            = ConnectPathPrefix + \"/checksession\";\n        public const string DeviceAuthorization     = ConnectPathPrefix + \"/deviceauthorization\";\n\n        public const string MtlsPathPrefix          = ConnectPathPrefix + \"/mtls\";\n        public const string MtlsToken               = MtlsPathPrefix + \"/token\";\n        public const string MtlsRevocation          = MtlsPathPrefix + \"/revocation\";\n        public const string MtlsIntrospection       = MtlsPathPrefix + \"/introspect\";\n        public const string MtlsDeviceAuthorization = MtlsPathPrefix + \"/deviceauthorization\";\n\n        public static readonly string[] CorsPaths =\n        {\n            DiscoveryConfiguration,\n            DiscoveryWebKeys,\n            Token,\n            UserInfo,\n            Revocation\n        };\n    }\n\n    public static class EnvironmentKeys\n    {\n        public const string IdentityServerBasePath = \"idsvr:IdentityServerBasePath\";\n        [Obsolete(\"The IdentityServerOrigin constant is obsolete.\")]\n        public const string IdentityServerOrigin = \"idsvr:IdentityServerOrigin\"; // todo: deprecate\n        public const string SignOutCalled = \"idsvr:IdentityServerSignOutCalled\";\n    }\n\n    public static class TokenTypeHints\n    {\n        public const string RefreshToken = \"refresh_token\";\n        public const string AccessToken  = \"access_token\";\n    }\n\n    public static List<string> SupportedTokenTypeHints = new List<string>\n    {\n        TokenTypeHints.RefreshToken,\n        TokenTypeHints.AccessToken\n    };\n\n    public static class RevocationErrors\n    {\n        public const string UnsupportedTokenType = \"unsupported_token_type\";\n    }\n\n    public class Filters\n    {\n        // filter for claims from an incoming access token (e.g. used at the user profile endpoint)\n        public static readonly string[] ProtocolClaimsFilter = {\n            JwtClaimTypes.AccessTokenHash,\n            JwtClaimTypes.Audience,\n            JwtClaimTypes.AuthorizedParty,\n            JwtClaimTypes.AuthorizationCodeHash,\n            JwtClaimTypes.ClientId,\n            JwtClaimTypes.Expiration,\n            JwtClaimTypes.IssuedAt,\n            JwtClaimTypes.Issuer,\n            JwtClaimTypes.JwtId,\n            JwtClaimTypes.Nonce,\n            JwtClaimTypes.NotBefore,\n            JwtClaimTypes.ReferenceTokenId,\n            JwtClaimTypes.SessionId,\n            JwtClaimTypes.Scope\n        };\n\n        // filter list for claims returned from profile service prior to creating tokens\n        public static readonly string[] ClaimsServiceFilterClaimTypes = {\n            // TODO: consider JwtClaimTypes.AuthenticationContextClassReference,\n            JwtClaimTypes.AccessTokenHash,\n            JwtClaimTypes.Audience,\n            JwtClaimTypes.AuthenticationMethod,\n            JwtClaimTypes.AuthenticationTime,\n            JwtClaimTypes.AuthorizedParty,\n            JwtClaimTypes.AuthorizationCodeHash,\n            JwtClaimTypes.ClientId,\n            JwtClaimTypes.Expiration,\n            JwtClaimTypes.IdentityProvider,\n            JwtClaimTypes.IssuedAt,\n            JwtClaimTypes.Issuer,\n            JwtClaimTypes.JwtId,\n            JwtClaimTypes.Nonce,\n            JwtClaimTypes.NotBefore,\n            JwtClaimTypes.ReferenceTokenId,\n            JwtClaimTypes.SessionId,\n            JwtClaimTypes.Subject,\n            JwtClaimTypes.Scope,\n            JwtClaimTypes.Confirmation\n        };\n\n        public static readonly string[] JwtRequestClaimTypesFilter = {\n            JwtClaimTypes.Audience,\n            JwtClaimTypes.Expiration,\n            JwtClaimTypes.IssuedAt,\n            JwtClaimTypes.Issuer,\n            JwtClaimTypes.NotBefore,\n            JwtClaimTypes.JwtId\n        };\n    }\n\n    public static class WsFedSignOut\n    {\n        public const string LogoutUriParameterName = \"wa\";\n        public const string LogoutUriParameterValue = \"wsignoutcleanup1.0\";\n    }\n\n    public static class AuthorizationParamsStore\n    {\n        public const string MessageStoreIdParameterName = \"authzId\";\n    }\n\n    public static class CurveOids\n    {\n        public const string P256 = \"1.2.840.10045.3.1.7\";\n        public const string P384 = \"1.3.132.0.34\";\n        public const string P521 = \"1.3.132.0.35\";\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/AuthorizeCallbackEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal class AuthorizeCallbackEndpoint : AuthorizeEndpointBase\n{\n    private readonly IConsentMessageStore _consentResponseStore;\n    private readonly IAuthorizationParametersMessageStore _authorizationParametersMessageStore;\n\n    public AuthorizeCallbackEndpoint(\n        IEventService events,\n        ILogger<AuthorizeCallbackEndpoint> logger,\n        IdentityServerOptions options,\n        IAuthorizeRequestValidator validator,\n        IAuthorizeInteractionResponseGenerator interactionGenerator,\n        IAuthorizeResponseGenerator authorizeResponseGenerator,\n        IUserSession userSession,\n        IConsentMessageStore consentResponseStore,\n        IAuthorizationParametersMessageStore authorizationParametersMessageStore = null)\n        : base(events, logger, options, validator, interactionGenerator, authorizeResponseGenerator, userSession)\n    {\n        _consentResponseStore = consentResponseStore;\n        _authorizationParametersMessageStore = authorizationParametersMessageStore;\n    }\n\n    public override async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        if (!HttpMethods.IsGet(context.Request.Method))\n        {\n            Logger.LogWarning(\"Invalid HTTP method for authorize endpoint.\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        Logger.LogDebug(\"Start authorize callback request\");\n\n        var parameters = context.Request.Query.AsNameValueCollection();\n        if (_authorizationParametersMessageStore != null)\n        {\n            var messageStoreId = parameters[Constants.AuthorizationParamsStore.MessageStoreIdParameterName];\n            var entry = await _authorizationParametersMessageStore.ReadAsync(messageStoreId);\n            parameters = entry?.Data.FromFullDictionary() ?? new NameValueCollection();\n\n            await _authorizationParametersMessageStore.DeleteAsync(messageStoreId);\n        }\n\n        var user = await UserSession.GetUserAsync();\n        var consentRequest = new ConsentRequest(parameters, user?.GetSubjectId());\n        var consent = await _consentResponseStore.ReadAsync(consentRequest.Id);\n\n        if (consent != null && consent.Data == null)\n        {\n            return await CreateErrorResultAsync(\"consent message is missing data\");\n        }\n\n        try\n        {\n            var result = await ProcessAuthorizeRequestAsync(parameters, user, consent?.Data);\n\n            Logger.LogTrace(\"End Authorize Request. Result type: {0}\", result?.GetType().ToString() ?? \"-none-\");\n\n            return result;\n        }\n        finally\n        {\n            if (consent != null)\n            {\n                await _consentResponseStore.DeleteAsync(consentRequest.Id);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/AuthorizeEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal class AuthorizeEndpoint : AuthorizeEndpointBase\n{\n    public AuthorizeEndpoint(\n       IEventService events,\n       ILogger<AuthorizeEndpoint> logger,\n       IdentityServerOptions options,\n       IAuthorizeRequestValidator validator,\n       IAuthorizeInteractionResponseGenerator interactionGenerator,\n       IAuthorizeResponseGenerator authorizeResponseGenerator,\n       IUserSession userSession)\n        : base(events, logger, options, validator, interactionGenerator, authorizeResponseGenerator, userSession)\n    {\n    }\n\n    public override async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        Logger.LogDebug(\"Start authorize request\");\n\n        NameValueCollection values;\n\n        if (HttpMethods.IsGet(context.Request.Method))\n        {\n            values = context.Request.Query.AsNameValueCollection();\n        }\n        else if (HttpMethods.IsPost(context.Request.Method))\n        {\n            if (!context.Request.HasApplicationFormContentType())\n            {\n                return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType);\n            }\n\n            values = context.Request.Form.AsNameValueCollection();\n        }\n        else\n        {\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        var user = await UserSession.GetUserAsync();\n        var result = await ProcessAuthorizeRequestAsync(values, user, null);\n\n        Logger.LogTrace(\"End authorize request. result type: {0}\", result?.GetType().ToString() ?? \"-none-\");\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/AuthorizeEndpointBase.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal abstract class AuthorizeEndpointBase : IEndpointHandler\n{\n    private readonly IAuthorizeResponseGenerator _authorizeResponseGenerator;\n\n    private readonly IEventService _events;\n    private readonly IdentityServerOptions _options;\n\n    private readonly IAuthorizeInteractionResponseGenerator _interactionGenerator;\n\n    private readonly IAuthorizeRequestValidator _validator;\n\n    protected AuthorizeEndpointBase(\n        IEventService events,\n        ILogger<AuthorizeEndpointBase> logger,\n        IdentityServerOptions options,\n        IAuthorizeRequestValidator validator,\n        IAuthorizeInteractionResponseGenerator interactionGenerator,\n        IAuthorizeResponseGenerator authorizeResponseGenerator,\n        IUserSession userSession)\n    {\n        _events = events;\n        _options = options;\n        Logger = logger;\n        _validator = validator;\n        _interactionGenerator = interactionGenerator;\n        _authorizeResponseGenerator = authorizeResponseGenerator;\n        UserSession = userSession;\n    }\n\n    protected ILogger Logger { get; private set; }\n\n    protected IUserSession UserSession { get; private set; }\n\n    public abstract Task<IEndpointResult> ProcessAsync(HttpContext context);\n\n    internal async Task<IEndpointResult> ProcessAuthorizeRequestAsync(NameValueCollection parameters, ClaimsPrincipal user, ConsentResponse consent)\n    {\n        if (user != null)\n        {\n            Logger.LogDebug(\"User in authorize request: {subjectId}\", user.GetSubjectId());\n        }\n        else\n        {\n            Logger.LogDebug(\"No user present in authorize request\");\n        }\n\n        // validate request\n        var result = await _validator.ValidateAsync(parameters, user);\n        if (result.IsError)\n        {\n            return await CreateErrorResultAsync(\n                \"Request validation failed\",\n                result.ValidatedRequest,\n                result.Error,\n                result.ErrorDescription);\n        }\n\n        var request = result.ValidatedRequest;\n        LogRequest(request);\n\n        // determine user interaction\n        var interactionResult = await _interactionGenerator.ProcessInteractionAsync(request, consent);\n        if (interactionResult.IsError)\n        {\n            return await CreateErrorResultAsync(\"Interaction generator error\", request, interactionResult.Error, interactionResult.ErrorDescription, false);\n        }\n        if (interactionResult.IsLogin)\n        {\n            return new LoginPageResult(request);\n        }\n        if (interactionResult.IsConsent)\n        {\n            return new ConsentPageResult(request);\n        }\n        if (interactionResult.IsRedirect)\n        {\n            return new CustomRedirectResult(request, interactionResult.RedirectUrl);\n        }\n\n        var response = await _authorizeResponseGenerator.CreateResponseAsync(request);\n\n        await RaiseResponseEventAsync(response);\n\n        LogResponse(response);\n\n        return new AuthorizeResult(response);\n    }\n\n    protected async Task<IEndpointResult> CreateErrorResultAsync(\n        string logMessage,\n        ValidatedAuthorizeRequest request = null,\n        string error = OidcConstants.AuthorizeErrors.ServerError,\n        string errorDescription = null,\n        bool logError = true)\n    {\n        if (logError)\n        {\n            Logger.LogError(logMessage);\n        }\n\n        if (request != null)\n        {\n            var details = new AuthorizeRequestValidationLog(request, _options.Logging.AuthorizeRequestSensitiveValuesFilter);\n            Logger.LogInformation(\"{@validationDetails}\", details);\n        }\n\n        // TODO: should we raise a token failure event for all errors to the authorize endpoint?\n        await RaiseFailureEventAsync(request, error, errorDescription);\n\n        return new AuthorizeResult(new AuthorizeResponse\n        {\n            Request = request,\n            Error = error,\n            ErrorDescription = errorDescription,\n            SessionState = request?.GenerateSessionStateValue()\n        });\n    }\n\n    private void LogRequest(ValidatedAuthorizeRequest request)\n    {\n        var details = new AuthorizeRequestValidationLog(request, _options.Logging.AuthorizeRequestSensitiveValuesFilter);\n        Logger.LogDebug(nameof(ValidatedAuthorizeRequest) + Environment.NewLine + \"{@validationDetails}\", details);\n    }\n\n    private void LogResponse(AuthorizeResponse response)\n    {\n        var details = new AuthorizeResponseLog(response);\n        Logger.LogDebug(\"Authorize endpoint response\" + Environment.NewLine + \"{@details}\", details);\n    }\n\n    private void LogTokens(AuthorizeResponse response)\n    {\n        var clientId = $\"{response.Request.ClientId} ({response.Request.Client.ClientName ?? \"no name set\"})\";\n        var subjectId = response.Request.Subject.GetSubjectId();\n\n        if (response.IdentityToken != null)\n        {\n            Logger.LogTrace(\"Identity token issued for {clientId} / {subjectId}: {token}\", clientId, subjectId, response.IdentityToken);\n        }\n        if (response.Code != null)\n        {\n            Logger.LogTrace(\"Code issued for {clientId} / {subjectId}: {token}\", clientId, subjectId, response.Code);\n        }\n        if (response.AccessToken != null)\n        {\n            Logger.LogTrace(\"Access token issued for {clientId} / {subjectId}: {token}\", clientId, subjectId, response.AccessToken);\n        }\n    }\n\n    private Task RaiseFailureEventAsync(ValidatedAuthorizeRequest request, string error, string errorDescription)\n    {\n        return _events.RaiseAsync(new TokenIssuedFailureEvent(request, error, errorDescription));\n    }\n\n    private Task RaiseResponseEventAsync(AuthorizeResponse response)\n    {\n        if (!response.IsError)\n        {\n            LogTokens(response);\n            return _events.RaiseAsync(new TokenIssuedSuccessEvent(response));\n        }\n\n        return RaiseFailureEventAsync(response.Request, response.Error, response.ErrorDescription);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/CheckSessionEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal class CheckSessionEndpoint : IEndpointHandler\n{\n    private readonly ILogger _logger;\n\n    public CheckSessionEndpoint(ILogger<CheckSessionEndpoint> logger)\n    {\n        _logger = logger;\n    }\n\n    public Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        IEndpointResult result;\n\n        if (!HttpMethods.IsGet(context.Request.Method))\n        {\n            _logger.LogWarning(\"Invalid HTTP method for check session endpoint\");\n            result = new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n        else\n        {\n            _logger.LogDebug(\"Rendering check session result\");\n            result = new CheckSessionResult();\n        }\n\n        return Task.FromResult(result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/DeviceAuthorizationEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\n/// <summary>\n/// The device authorization endpoint\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointHandler\" />\ninternal class DeviceAuthorizationEndpoint : IEndpointHandler\n{\n    private readonly IClientSecretValidator _clientValidator;\n    private readonly IDeviceAuthorizationRequestValidator _requestValidator;\n    private readonly IDeviceAuthorizationResponseGenerator _responseGenerator;\n    private readonly IEventService _events;\n    private readonly ILogger<DeviceAuthorizationEndpoint> _logger;\n\n    public DeviceAuthorizationEndpoint(\n        IClientSecretValidator clientValidator,\n        IDeviceAuthorizationRequestValidator requestValidator,\n        IDeviceAuthorizationResponseGenerator responseGenerator,\n        IEventService events,\n        ILogger<DeviceAuthorizationEndpoint> logger)\n    {\n        _clientValidator = clientValidator;\n        _requestValidator = requestValidator;\n        _responseGenerator = responseGenerator;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Processes the request.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.NotImplementedException\"></exception>\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        _logger.LogTrace(\"Processing device authorize request.\");\n\n        // validate HTTP\n        if (!HttpMethods.IsPost(context.Request.Method) || !context.Request.HasApplicationFormContentType())\n        {\n            _logger.LogWarning(\"Invalid HTTP request for device authorize endpoint\");\n            return Error(OidcConstants.TokenErrors.InvalidRequest);\n        }\n\n        return await ProcessDeviceAuthorizationRequestAsync(context);\n    }\n\n    private async Task<IEndpointResult> ProcessDeviceAuthorizationRequestAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start device authorize request.\");\n\n        // validate client\n        var clientResult = await _clientValidator.ValidateAsync(context);\n        if (clientResult.Client == null) return Error(OidcConstants.TokenErrors.InvalidClient);\n\n        // validate request\n        var form = (await context.Request.ReadFormAsync()).AsNameValueCollection();\n        var requestResult = await _requestValidator.ValidateAsync(form, clientResult);\n\n        if (requestResult.IsError)\n        {\n            await _events.RaiseAsync(new DeviceAuthorizationFailureEvent(requestResult));\n            return Error(requestResult.Error, requestResult.ErrorDescription);\n        }\n\n        var baseUrl = context.GetIdentityServerBaseUrl().EnsureTrailingSlash();\n\n        // create response\n        _logger.LogTrace(\"Calling into device authorize response generator: {type}\", _responseGenerator.GetType().FullName);\n        var response = await _responseGenerator.ProcessAsync(requestResult, baseUrl);\n\n        await _events.RaiseAsync(new DeviceAuthorizationSuccessEvent(response, requestResult));\n\n        // return result\n        _logger.LogDebug(\"Device authorize request success.\");\n        return new DeviceAuthorizationResult(response);\n    }\n\n    private TokenErrorResult Error(string error, string errorDescription = null, Dictionary<string, object> custom = null)\n    {\n        var response = new TokenErrorResponse\n        {\n            Error = error,\n            ErrorDescription = errorDescription,\n            Custom = custom\n        };\n\n        _logger.LogError(\"Device authorization error: {error}:{errorDescriptions}\", error, error ?? \"-no message-\");\n\n        return new TokenErrorResult(response);\n    }\n\n    private void LogResponse(DeviceAuthorizationResponse response, DeviceAuthorizationRequestValidationResult requestResult)\n    {\n        var clientId = $\"{requestResult.ValidatedRequest.Client.ClientId} ({requestResult.ValidatedRequest.Client?.ClientName ?? \"no name set\"})\";\n\n        if (response.DeviceCode != null)\n        {\n            _logger.LogTrace(\"Device code issued for {clientId}: {deviceCode}\", clientId, response.DeviceCode);\n        }\n        if (response.UserCode != null)\n        {\n            _logger.LogTrace(\"User code issued for {clientId}: {userCode}\", clientId, response.UserCode);\n        }\n        if (response.VerificationUri != null)\n        {\n            _logger.LogTrace(\"Verification URI issued for {clientId}: {verificationUri}\", clientId, response.VerificationUri);\n        }\n        if (response.VerificationUriComplete != null)\n        {\n            _logger.LogTrace(\"Verification URI (Complete) issued for {clientId}: {verificationUriComplete}\", clientId, response.VerificationUriComplete);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/DiscoveryEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal class DiscoveryEndpoint : IEndpointHandler\n{\n    private readonly ILogger _logger;\n\n    private readonly IdentityServerOptions _options;\n\n    private readonly IDiscoveryResponseGenerator _responseGenerator;\n\n    public DiscoveryEndpoint(\n        IdentityServerOptions options,\n        IDiscoveryResponseGenerator responseGenerator,\n        ILogger<DiscoveryEndpoint> logger)\n    {\n        _logger = logger;\n        _options = options;\n        _responseGenerator = responseGenerator;\n    }\n\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        _logger.LogTrace(\"Processing discovery request.\");\n\n        // validate HTTP\n        if (!HttpMethods.IsGet(context.Request.Method))\n        {\n            _logger.LogWarning(\"Discovery endpoint only supports GET requests\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        _logger.LogDebug(\"Start discovery request\");\n\n        if (!_options.Endpoints.EnableDiscoveryEndpoint)\n        {\n            _logger.LogInformation(\"Discovery endpoint disabled. 404.\");\n            return new StatusCodeResult(HttpStatusCode.NotFound);\n        }\n\n        var baseUrl = context.GetIdentityServerBaseUrl().EnsureTrailingSlash();\n        var issuerUri = context.GetIdentityServerIssuerUri();\n\n        // generate response\n        _logger.LogTrace(\"Calling into discovery response generator: {type}\", _responseGenerator.GetType().FullName);\n        var response = await _responseGenerator.CreateDiscoveryDocumentAsync(baseUrl, issuerUri);\n\n        return new DiscoveryDocumentResult(response, _options.Discovery.ResponseCacheInterval);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/DiscoveryKeyEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal class DiscoveryKeyEndpoint : IEndpointHandler\n{\n    private readonly ILogger _logger;\n\n    private readonly IdentityServerOptions _options;\n\n    private readonly IDiscoveryResponseGenerator _responseGenerator;\n\n    public DiscoveryKeyEndpoint(\n        IdentityServerOptions options,\n        IDiscoveryResponseGenerator responseGenerator,\n        ILogger<DiscoveryKeyEndpoint> logger)\n    {\n        _logger = logger;\n        _options = options;\n        _responseGenerator = responseGenerator;\n    }\n\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        _logger.LogTrace(\"Processing discovery request.\");\n\n        // validate HTTP\n        if (!HttpMethods.IsGet(context.Request.Method))\n        {\n            _logger.LogWarning(\"Discovery endpoint only supports GET requests\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        _logger.LogDebug(\"Start key discovery request\");\n\n        if (_options.Discovery.ShowKeySet == false)\n        {\n            _logger.LogInformation(\"Key discovery disabled. 404.\");\n            return new StatusCodeResult(HttpStatusCode.NotFound);\n        }\n\n        // generate response\n        _logger.LogTrace(\"Calling into discovery response generator: {type}\", _responseGenerator.GetType().FullName);\n        var response = await _responseGenerator.CreateJwkDocumentAsync();\n\n        return new JsonWebKeysResult(response, _options.Discovery.ResponseCacheInterval);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/EndSessionCallbackEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal class EndSessionCallbackEndpoint : IEndpointHandler\n{\n    private readonly IEndSessionRequestValidator _endSessionRequestValidator;\n    private readonly ILogger _logger;\n\n    public EndSessionCallbackEndpoint(\n        IEndSessionRequestValidator endSessionRequestValidator,\n        ILogger<EndSessionCallbackEndpoint> logger)\n    {\n        _endSessionRequestValidator = endSessionRequestValidator;\n        _logger = logger;\n    }\n\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        if (!HttpMethods.IsGet(context.Request.Method))\n        {\n            _logger.LogWarning(\"Invalid HTTP method for end session callback endpoint.\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        _logger.LogDebug(\"Processing signout callback request\");\n\n        var parameters = context.Request.Query.AsNameValueCollection();\n        var result = await _endSessionRequestValidator.ValidateCallbackAsync(parameters);\n\n        if (!result.IsError)\n        {\n            _logger.LogInformation(\"Successful signout callback.\");\n        }\n        else\n        {\n            _logger.LogError(\"Error validating signout callback: {error}\", result.Error);\n        }\n        \n        return new EndSessionCallbackResult(result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/EndSessionEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\ninternal class EndSessionEndpoint : IEndpointHandler\n{\n    private readonly IEndSessionRequestValidator _endSessionRequestValidator;\n\n    private readonly ILogger _logger;\n\n    private readonly IUserSession _userSession;\n\n    public EndSessionEndpoint(\n        IEndSessionRequestValidator endSessionRequestValidator,\n        IUserSession userSession,\n        ILogger<EndSessionEndpoint> logger)\n    {\n        _endSessionRequestValidator = endSessionRequestValidator;\n        _userSession = userSession;\n        _logger = logger;\n    }\n\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        NameValueCollection parameters;\n        if (HttpMethods.IsGet(context.Request.Method))\n        {\n            parameters = context.Request.Query.AsNameValueCollection();\n        }\n        else if (HttpMethods.IsPost(context.Request.Method))\n        {\n            parameters = (await context.Request.ReadFormAsync()).AsNameValueCollection();\n        }\n        else\n        {\n            _logger.LogWarning(\"Invalid HTTP method for end session endpoint.\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        var user = await _userSession.GetUserAsync();\n\n        _logger.LogDebug(\"Processing signout request for {subjectId}\", user?.GetSubjectId() ?? \"anonymous\");\n\n        var result = await _endSessionRequestValidator.ValidateAsync(parameters, user);\n\n        if (result.IsError)\n        {\n            _logger.LogError(\"Error processing end session request {error}\", result.Error);\n        }\n        else\n        {\n            _logger.LogDebug(\"Success validating end session request from {clientId}\", result.ValidatedRequest?.Client?.ClientId);\n        }\n\n        return new EndSessionResult(result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/IntrospectionEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\n/// <summary>\n/// Introspection endpoint\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointHandler\" />\ninternal class IntrospectionEndpoint : IEndpointHandler\n{\n    private readonly IIntrospectionResponseGenerator _responseGenerator;\n    private readonly IEventService _events;\n    private readonly ILogger _logger;\n    private readonly IIntrospectionRequestValidator _requestValidator;\n    private readonly IApiSecretValidator _apiSecretValidator;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IntrospectionEndpoint\" /> class.\n    /// </summary>\n    /// <param name=\"apiSecretValidator\">The API secret validator.</param>\n    /// <param name=\"requestValidator\">The request validator.</param>\n    /// <param name=\"responseGenerator\">The generator.</param>\n    /// <param name=\"events\">The events.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public IntrospectionEndpoint(\n        IApiSecretValidator apiSecretValidator,\n        IIntrospectionRequestValidator requestValidator,\n        IIntrospectionResponseGenerator responseGenerator,\n        IEventService events,\n        ILogger<IntrospectionEndpoint> logger)\n    {\n        _apiSecretValidator = apiSecretValidator;\n        _requestValidator = requestValidator;\n        _responseGenerator = responseGenerator;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Processes the request.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        _logger.LogTrace(\"Processing introspection request.\");\n\n        // validate HTTP\n        if (!HttpMethods.IsPost(context.Request.Method))\n        {\n            _logger.LogWarning(\"Introspection endpoint only supports POST requests\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        if (!context.Request.HasApplicationFormContentType())\n        {\n            _logger.LogWarning(\"Invalid media type for introspection endpoint\");\n            return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType);\n        }\n\n        return await ProcessIntrospectionRequestAsync(context);\n    }\n\n    private async Task<IEndpointResult> ProcessIntrospectionRequestAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Starting introspection request.\");\n\n        // caller validation\n        var apiResult = await _apiSecretValidator.ValidateAsync(context);\n        if (apiResult.Resource == null)\n        {\n            _logger.LogError(\"API unauthorized to call introspection endpoint. aborting.\");\n            return new StatusCodeResult(HttpStatusCode.Unauthorized);\n        }\n\n        var body = await context.Request.ReadFormAsync();\n        if (body == null)\n        {\n            _logger.LogError(\"Malformed request body. aborting.\");\n            await _events.RaiseAsync(new TokenIntrospectionFailureEvent(apiResult.Resource.Name, \"Malformed request body\"));\n\n            return new StatusCodeResult(HttpStatusCode.BadRequest);\n        }\n\n        // request validation\n        _logger.LogTrace(\"Calling into introspection request validator: {type}\", _requestValidator.GetType().FullName);\n        var validationResult = await _requestValidator.ValidateAsync(body.AsNameValueCollection(), apiResult.Resource);\n        if (validationResult.IsError)\n        {\n            LogFailure(validationResult.Error, apiResult.Resource.Name);\n            await _events.RaiseAsync(new TokenIntrospectionFailureEvent(apiResult.Resource.Name, validationResult.Error));\n\n            return new BadRequestResult(validationResult.Error);\n        }\n\n        // response generation\n        _logger.LogTrace(\"Calling into introspection response generator: {type}\", _responseGenerator.GetType().FullName);\n        var response = await _responseGenerator.ProcessAsync(validationResult);\n\n        // render result\n        LogSuccess(validationResult.IsActive, validationResult.Api.Name);\n        return new IntrospectionResult(response);\n    }\n\n    private void LogSuccess(bool tokenActive, string apiName)\n    {\n        _logger.LogInformation(\"Success token introspection. Token active: {tokenActive}, for API name: {apiName}\", tokenActive, apiName);\n    }\n\n    private void LogFailure(string error, string apiName)\n    {\n        _logger.LogError(\"Failed token introspection: {error}, for API name: {apiName}\", error, apiName);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/AuthorizeResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class AuthorizeResult : IEndpointResult\n{\n    public AuthorizeResponse Response { get; }\n\n    public AuthorizeResult(AuthorizeResponse response)\n    {\n        Response = response ?? throw new ArgumentNullException(nameof(response));\n    }\n\n    internal AuthorizeResult(\n        AuthorizeResponse response,\n        IdentityServerOptions options,\n        IUserSession userSession,\n        IMessageStore<ErrorMessage> errorMessageStore,\n        ISystemClock clock)\n        : this(response)\n    {\n        _options = options;\n        _userSession = userSession;\n        _errorMessageStore = errorMessageStore;\n        _clock = clock;\n    }\n\n    private IdentityServerOptions _options;\n    private IUserSession _userSession;\n    private IMessageStore<ErrorMessage> _errorMessageStore;\n    private ISystemClock _clock;\n\n    private void Init(HttpContext context)\n    {\n        _options = _options ?? context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        _userSession = _userSession ?? context.RequestServices.GetRequiredService<IUserSession>();\n        _errorMessageStore = _errorMessageStore ?? context.RequestServices.GetRequiredService<IMessageStore<ErrorMessage>>();\n        _clock = _clock ?? context.RequestServices.GetRequiredService<ISystemClock>();\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        Init(context);\n\n        if (Response.IsError)\n        {\n            await ProcessErrorAsync(context);\n        }\n        else\n        {\n            await ProcessResponseAsync(context);\n        }\n    }\n\n    private async Task ProcessErrorAsync(HttpContext context)\n    {\n        // these are the conditions where we can send a response \n        // back directly to the client, otherwise we're only showing the error UI\n        var isSafeError =\n            Response.Error == OidcConstants.AuthorizeErrors.AccessDenied ||\n            Response.Error == OidcConstants.AuthorizeErrors.AccountSelectionRequired ||\n            Response.Error == OidcConstants.AuthorizeErrors.LoginRequired ||\n            Response.Error == OidcConstants.AuthorizeErrors.ConsentRequired ||\n            Response.Error == OidcConstants.AuthorizeErrors.InteractionRequired;\n\n        if (isSafeError)\n        {\n            // this scenario we can return back to the client\n            await ProcessResponseAsync(context);\n        }\n        else\n        {\n            // we now know we must show error page\n            await RedirectToErrorPageAsync(context);\n        }\n    }\n\n    protected async Task ProcessResponseAsync(HttpContext context)\n    {\n        if (!Response.IsError)\n        {\n            // success response -- track client authorization for sign-out\n            //_logger.LogDebug(\"Adding client {0} to client list cookie for subject {1}\", request.ClientId, request.Subject.GetSubjectId());\n            await _userSession.AddClientIdAsync(Response.Request.ClientId);\n        }\n\n        await RenderAuthorizeResponseAsync(context);\n    }\n\n    private async Task RenderAuthorizeResponseAsync(HttpContext context)\n    {\n        if (Response.Request.ResponseMode == OidcConstants.ResponseModes.Query ||\n            Response.Request.ResponseMode == OidcConstants.ResponseModes.Fragment)\n        {\n            context.Response.SetNoCache();\n            context.Response.Redirect(BuildRedirectUri());\n        }\n        else if (Response.Request.ResponseMode == OidcConstants.ResponseModes.FormPost)\n        {\n            context.Response.SetNoCache();\n            AddSecurityHeaders(context);\n            await context.Response.WriteHtmlAsync(GetFormPostHtml());\n        }\n        else\n        {\n            //_logger.LogError(\"Unsupported response mode.\");\n            throw new InvalidOperationException(\"Unsupported response mode\");\n        }\n    }\n\n    private void AddSecurityHeaders(HttpContext context)\n    {\n        context.Response.AddScriptCspHeaders(_options.Csp, \"sha256-orD0/VhH8hLqrLxKHD/HUEMdwqX6/0ve7c5hspX5VJ8=\");\n\n        var referrer_policy = \"no-referrer\";\n        if (!context.Response.Headers.ContainsKey(\"Referrer-Policy\"))\n        {\n            context.Response.Headers.Append(\"Referrer-Policy\", referrer_policy);\n        }\n    }\n\n    private string BuildRedirectUri()\n    {\n        var uri = Response.RedirectUri;\n        var query = Response.ToNameValueCollection().ToQueryString();\n\n        if (Response.Request.ResponseMode == OidcConstants.ResponseModes.Query)\n        {\n            uri = uri.AddQueryString(query);\n        }\n        else\n        {\n            uri = uri.AddHashFragment(query);\n        }\n\n        if (Response.IsError && !uri.Contains(\"#\"))\n        {\n            // https://tools.ietf.org/html/draft-bradley-oauth-open-redirector-00\n            uri += \"#_=_\";\n        }\n\n        return uri;\n    }\n\n    private const string FormPostHtml = \"<html><head><meta http-equiv='X-UA-Compatible' content='IE=edge' /><base target='_self'/></head><body><form method='post' action='{uri}'>{body}<noscript><button>Click to continue</button></noscript></form><script>window.addEventListener('load', function(){document.forms[0].submit();});</script></body></html>\";\n\n    private string GetFormPostHtml()\n    {\n        var html = FormPostHtml;\n\n        var url = Response.Request.RedirectUri;\n        url = HtmlEncoder.Default.Encode(url);\n        html = html.Replace(\"{uri}\", url);\n        html = html.Replace(\"{body}\", Response.ToNameValueCollection().ToFormPost());\n\n        return html;\n    }\n\n    private async Task RedirectToErrorPageAsync(HttpContext context)\n    {\n        var errorModel = new ErrorMessage\n        {\n            RequestId = context.TraceIdentifier,\n            Error = Response.Error,\n            ErrorDescription = Response.ErrorDescription,\n            UiLocales = Response.Request?.UiLocales,\n            DisplayMode = Response.Request?.DisplayMode,\n            ClientId = Response.Request?.ClientId\n        };\n\n        if (Response.RedirectUri != null && Response.Request?.ResponseMode != null)\n        {\n            // if we have a valid redirect uri, then include it to the error page\n            errorModel.RedirectUri = BuildRedirectUri();\n            errorModel.ResponseMode = Response.Request.ResponseMode;\n        }\n\n        var message = new Message<ErrorMessage>(errorModel, _clock.UtcNow.UtcDateTime);\n        var id = await _errorMessageStore.WriteAsync(message);\n\n        var errorUrl = _options.UserInteraction.ErrorUrl;\n\n        var url = errorUrl.AddQueryString(_options.UserInteraction.ErrorIdParameter, id);\n        context.Response.RedirectToAbsoluteUrl(url);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/BadRequestResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class BadRequestResult : IEndpointResult\n{\n    public string Error { get; set; }\n    public string ErrorDescription { get; set; }\n\n    public BadRequestResult(string error = null, string errorDescription = null)\n    {\n        Error = error;\n        ErrorDescription = errorDescription;\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.StatusCode = 400;\n        context.Response.SetNoCache();\n\n        if (Error.IsPresent())\n        {\n            var dto = new ResultDto\n            {\n                error = Error,\n                error_description = ErrorDescription\n            };\n\n            await context.Response.WriteJsonAsync(dto);\n        }\n    }\n\n    internal class ResultDto\n    {\n        public string error { get; set; }\n        public string error_description { get; set; }\n    }    \n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/CheckSessionResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class CheckSessionResult : IEndpointResult\n{\n    public CheckSessionResult()\n    {\n    }\n\n    internal CheckSessionResult(IdentityServerOptions options)\n    {\n        _options = options;\n    }\n\n    private IdentityServerOptions _options;\n    private static volatile string FormattedHtml;\n    private static readonly object Lock = new object();\n    private static volatile string LastCheckSessionCookieName;\n\n    private void Init(HttpContext context)\n    {\n        _options = _options ?? context.RequestServices.GetRequiredService<IdentityServerOptions>();\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        Init(context);\n\n        AddCspHeaders(context);\n\n        var html = GetHtml(_options.Authentication.CheckSessionCookieName);\n        await context.Response.WriteHtmlAsync(html);\n    }\n\n    private void AddCspHeaders(HttpContext context)\n    {\n        context.Response.AddScriptCspHeaders(_options.Csp, \"sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI=\");\n    }\n    private string GetHtml(string cookieName)\n    {\n        if (cookieName != LastCheckSessionCookieName)\n        {\n            lock (Lock)\n            {\n                if (cookieName != LastCheckSessionCookieName)\n                {\n                    FormattedHtml = Html.Replace(\"{cookieName}\", cookieName);\n                    LastCheckSessionCookieName = cookieName;\n                }\n            }\n        }\n        return FormattedHtml;\n    }\n\n    private const string Html = @\"\n<!DOCTYPE html>\n<!--Copyright (c) Brock Allen & Dominick Baier. All rights reserved.-->\n<!--Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.-->\n<html>\n<head>\n    <meta http-equiv='X-UA-Compatible' content='IE=edge' />\n    <title>Check Session IFrame</title>\n</head>\n<body>\n    <script id='cookie-name' type='application/json'>{cookieName}</script>\n    <script>\n/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n/*  SHA-256 implementation in JavaScript                (c) Chris Veness 2002-2014 / MIT Licence  */\n/*                                                                                                */\n/*  - see http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html                              */\n/*        http://csrc.nist.gov/groups/ST/toolkit/examples.html                                    */\n/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\n/* jshint node:true *//* global define, escape, unescape */\n'use strict';\n\n\n/**\n * SHA-256 hash function reference implementation.\n *\n * @namespace\n */\nvar Sha256 = {};\n\n\n/**\n * Generates SHA-256 hash of string.\n *\n * @param   {string} msg - String to be hashed\n * @returns {string} Hash of msg as hex character string\n */\nSha256.hash = function(msg) {\n    // convert string to UTF-8, as SHA only deals with byte-streams\n    msg = msg.utf8Encode();\n    \n    // constants [§4.2.2]\n    var K = [\n        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ];\n    // initial hash value [§5.3.1]\n    var H = [\n        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];\n\n    // PREPROCESSING \n \n    msg += String.fromCharCode(0x80);  // add trailing '1' bit (+ 0's padding) to string [§5.1.1]\n\n    // convert string msg into 512-bit/16-integer blocks arrays of ints [§5.2.1]\n    var l = msg.length/4 + 2; // length (in 32-bit integers) of msg + ‘1’ + appended length\n    var N = Math.ceil(l/16);  // number of 16-integer-blocks required to hold 'l' ints\n    var M = new Array(N);\n\n    for (var i=0; i<N; i++) {\n        M[i] = new Array(16);\n        for (var j=0; j<16; j++) {  // encode 4 chars per integer, big-endian encoding\n            M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) | \n                      (msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));\n        } // note running off the end of msg is ok 'cos bitwise ops on NaN return 0\n    }\n    // add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1]\n    // note: most significant word would be (len-1)*8 >>> 32, but since JS converts\n    // bitwise-op args to 32 bits, we need to simulate this by arithmetic operators\n    M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14]);\n    M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;\n\n\n    // HASH COMPUTATION [§6.1.2]\n\n    var W = new Array(64); var a, b, c, d, e, f, g, h;\n    for (var i=0; i<N; i++) {\n\n        // 1 - prepare message schedule 'W'\n        for (var t=0;  t<16; t++) W[t] = M[i][t];\n        for (var t=16; t<64; t++) W[t] = (Sha256.σ1(W[t-2]) + W[t-7] + Sha256.σ0(W[t-15]) + W[t-16]) & 0xffffffff;\n\n        // 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value\n        a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; f = H[5]; g = H[6]; h = H[7];\n\n        // 3 - main loop (note 'addition modulo 2^32')\n        for (var t=0; t<64; t++) {\n            var T1 = h + Sha256.Σ1(e) + Sha256.Ch(e, f, g) + K[t] + W[t];\n            var T2 =     Sha256.Σ0(a) + Sha256.Maj(a, b, c);\n            h = g;\n            g = f;\n            f = e;\n            e = (d + T1) & 0xffffffff;\n            d = c;\n            c = b;\n            b = a;\n            a = (T1 + T2) & 0xffffffff;\n        }\n         // 4 - compute the new intermediate hash value (note 'addition modulo 2^32')\n        H[0] = (H[0]+a) & 0xffffffff;\n        H[1] = (H[1]+b) & 0xffffffff; \n        H[2] = (H[2]+c) & 0xffffffff; \n        H[3] = (H[3]+d) & 0xffffffff; \n        H[4] = (H[4]+e) & 0xffffffff;\n        H[5] = (H[5]+f) & 0xffffffff;\n        H[6] = (H[6]+g) & 0xffffffff; \n        H[7] = (H[7]+h) & 0xffffffff; \n    }\n\n    return Sha256.toHexStr(H[0]) + Sha256.toHexStr(H[1]) + Sha256.toHexStr(H[2]) + Sha256.toHexStr(H[3]) + \n           Sha256.toHexStr(H[4]) + Sha256.toHexStr(H[5]) + Sha256.toHexStr(H[6]) + Sha256.toHexStr(H[7]);\n};\n\n\n/**\n * Rotates right (circular right shift) value x by n positions [§3.2.4].\n * @private\n */\nSha256.ROTR = function(n, x) {\n    return (x >>> n) | (x << (32-n));\n};\n\n/**\n * Logical functions [§4.1.2].\n * @private\n */\nSha256.Σ0  = function(x) { return Sha256.ROTR(2,  x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); };\nSha256.Σ1  = function(x) { return Sha256.ROTR(6,  x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); };\nSha256.σ0  = function(x) { return Sha256.ROTR(7,  x) ^ Sha256.ROTR(18, x) ^ (x>>>3);  };\nSha256.σ1  = function(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x>>>10); };\nSha256.Ch  = function(x, y, z) { return (x & y) ^ (~x & z); };\nSha256.Maj = function(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); };\n\n\n/**\n * Hexadecimal representation of a number.\n * @private\n */\nSha256.toHexStr = function(n) {\n    // note can't use toString(16) as it is implementation-dependant,\n    // and in IE returns signed numbers when used on full words\n    var s='', v;\n    for (var i=7; i>=0; i--) { v = (n>>>(i*4)) & 0xf; s += v.toString(16); }\n    return s;\n};\n\n\n/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\n\n\n/** Extend String object with method to encode multi-byte string to utf8\n *  - monsur.hossa.in/2012/07/20/utf-8-in-javascript.html */\nif (typeof String.prototype.utf8Encode == 'undefined') {\n    String.prototype.utf8Encode = function() {\n        return unescape( encodeURIComponent( this ) );\n    };\n}\n\n/** Extend String object with method to decode utf8 string to multi-byte */\nif (typeof String.prototype.utf8Decode == 'undefined') {\n    String.prototype.utf8Decode = function() {\n        try {\n            return decodeURIComponent( escape( this ) );\n        } catch (e) {\n            return this; // invalid UTF-8? return as-is\n        }\n    };\n}\n\n\n/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */\nif (typeof module != 'undefined' && module.exports) module.exports = Sha256; // CommonJs export\nif (typeof define == 'function' && define.amd) define([], function() { return Sha256; }); // AMD\n\n////////////////////////////////////////////////////////////////////\n///////////// IdentityServer JS Code Starts here ///////////////////\n////////////////////////////////////////////////////////////////////\n\n        function getCookies() {\n            var allCookies = document.cookie;\n            var cookies = allCookies.split(';');\n            return cookies.map(function(value) {\n                var parts = value.trim().split('=');\n                if (parts.length === 2) {\n                    return {\n                        name: parts[0].trim(),\n                        value: parts[1].trim()\n                    };\n                }\n            }).filter(function(item) {\n                return item && item.name && item.value;\n            });\n        }\n\n        function getBrowserSessionId() {\n            var cookies = getCookies().filter(function(cookie) {\n                return (cookie.name === cookieName);\n            });\n            // empty string represents anonymous sid\n            return (cookies[0] && cookies[0].value) || '';\n        }\n\n        /*! (c) Tom Wu | http://www-cs-students.stanford.edu/~tjw/jsbn/ */\n        var b64map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n        var b64pad = '=';\n\n        function hex2b64(h) {\n            var i;\n            var c;\n            var ret = '';\n            for (i = 0; i + 3 <= h.length; i += 3) {\n                c = parseInt(h.substring(i, i + 3), 16);\n                ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);\n            }\n            if (i + 1 == h.length) {\n                c = parseInt(h.substring(i, i + 1), 16);\n                ret += b64map.charAt(c << 2);\n            }\n            else if (i + 2 == h.length) {\n                c = parseInt(h.substring(i, i + 2), 16);\n                ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);\n            }\n            if (b64pad) while ((ret.length & 3) > 0) ret += b64pad;\n            return ret;\n        }\n\n        function base64UrlEncode(s){\n            var val = hex2b64(s);\n\n            val = val.replace(/=/g, ''); // Remove any trailing '='s\n            val = val.replace(/\\+/g, '-'); // '+' => '-'\n            val = val.replace(/\\//g, '_'); // '/' => '_'\n\n            return val;\n        }\n\n        function hash(value) {\n            var hash = Sha256.hash(value);\n            return base64UrlEncode(hash);\n        }\n\n        function computeSessionStateHash(clientId, origin, sessionId, salt) {\n            return hash(clientId + origin + sessionId + salt);\n        }\n\n        function calculateSessionStateResult(origin, message) {\n            try {\n                if (!origin || !message) {\n                    return 'error';\n                }\n\n                var idx = message.lastIndexOf(' ');\n                if (idx < 0 || idx >= message.length) {\n                    return 'error';\n                }\n\n                var clientId = message.substring(0, idx);\n                var sessionState = message.substring(idx + 1);\n\n                if (!clientId || !sessionState) {\n                    return 'error';\n                }\n\n                var sessionStateParts = sessionState.split('.');\n                if (sessionStateParts.length !== 2) {\n                    return 'error';\n                }\n\n                var clientHash = sessionStateParts[0];\n                var salt = sessionStateParts[1];\n                if (!clientHash || !salt) {\n                    return 'error';\n                }\n\n                var currentSessionId = getBrowserSessionId();\n                var expectedHash = computeSessionStateHash(clientId, origin, currentSessionId, salt);\n                return clientHash === expectedHash ? 'unchanged' : 'changed';\n            }\n            catch (e) {\n                return 'error';\n            }\n        }\n\n        var cookieNameElem = document.getElementById('cookie-name');\n        if (cookieNameElem) {\n            var cookieName = cookieNameElem.textContent.trim();\n        }\n\n        if (cookieName && window.parent !== window) {\n            window.addEventListener('message', function(e) {\n                if (window === e.source) {\n                    // ignore browser extensions that are sending messages.\n                    return;\n                }\n\n                if (typeof e.data !== 'string') {\n                    return;\n                }\n\n                var result = calculateSessionStateResult(e.origin, e.data);\n                e.source.postMessage(result, e.origin);\n            }, false);\n        }\n    </script>\n</body>\n</html>\n\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/ConsentPageResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for consent page\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class ConsentPageResult : IEndpointResult\n{\n    private readonly ValidatedAuthorizeRequest _request;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ConsentPageResult\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <exception cref=\"System.ArgumentNullException\">request</exception>\n    public ConsentPageResult(ValidatedAuthorizeRequest request)\n    {\n        _request = request ?? throw new ArgumentNullException(nameof(request));\n    }\n\n    internal ConsentPageResult(\n        ValidatedAuthorizeRequest request,\n        IdentityServerOptions options,\n        IAuthorizationParametersMessageStore authorizationParametersMessageStore = null) \n        : this(request)\n    {\n        _options = options;\n        _authorizationParametersMessageStore = authorizationParametersMessageStore;\n    }\n\n    private IdentityServerOptions _options;\n    private IAuthorizationParametersMessageStore _authorizationParametersMessageStore;\n\n    private void Init(HttpContext context)\n    {\n        _options = _options ?? context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        _authorizationParametersMessageStore = _authorizationParametersMessageStore ?? context.RequestServices.GetService<IAuthorizationParametersMessageStore>();\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        Init(context);\n\n        var returnUrl = context.GetIdentityServerBasePath().EnsureTrailingSlash() + Constants.ProtocolRoutePaths.AuthorizeCallback;\n        if (_authorizationParametersMessageStore != null)\n        {\n            var msg = new Message<IDictionary<string, string[]>>(_request.Raw.ToFullDictionary());\n            var id = await _authorizationParametersMessageStore.WriteAsync(msg);\n            returnUrl = returnUrl.AddQueryString(Constants.AuthorizationParamsStore.MessageStoreIdParameterName, id);\n        }\n        else\n        {\n            returnUrl = returnUrl.AddQueryString(_request.Raw.ToQueryString());\n        }\n\n        var consentUrl = _options.UserInteraction.ConsentUrl;\n        if (!consentUrl.IsLocalUrl())\n        {\n            // this converts the relative redirect path to an absolute one if we're \n            // redirecting to a different server\n            returnUrl = context.GetIdentityServerHost().EnsureTrailingSlash() + returnUrl.RemoveLeadingSlash();\n        }\n\n        var url = consentUrl.AddQueryString(_options.UserInteraction.ConsentReturnUrlParameter, returnUrl);\n        context.Response.RedirectToAbsoluteUrl(url);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/CustomRedirectResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for a custom redirect\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class CustomRedirectResult : IEndpointResult\n{\n    private readonly ValidatedAuthorizeRequest _request;\n    private readonly string _url;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"CustomRedirectResult\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"url\">The URL.</param>\n    /// <exception cref=\"System.ArgumentNullException\">\n    /// request\n    /// or\n    /// url\n    /// </exception>\n    public CustomRedirectResult(ValidatedAuthorizeRequest request, string url)\n    {\n        if (request == null) throw new ArgumentNullException(nameof(request));\n        if (url.IsMissing()) throw new ArgumentNullException(nameof(url));\n\n        _request = request;\n        _url = url;\n    }\n\n    internal CustomRedirectResult(\n        ValidatedAuthorizeRequest request,\n        string url,\n        IdentityServerOptions options) \n        : this(request, url)\n    {\n        _options = options;\n    }\n\n    private IdentityServerOptions _options;\n\n    private void Init(HttpContext context)\n    {\n        _options = _options ?? context.RequestServices.GetRequiredService<IdentityServerOptions>();\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public Task ExecuteAsync(HttpContext context)\n    {\n        Init(context);\n\n        var returnUrl = context.GetIdentityServerBasePath().EnsureTrailingSlash() + Constants.ProtocolRoutePaths.Authorize;\n        returnUrl = returnUrl.AddQueryString(_request.Raw.ToQueryString());\n\n        if (!_url.IsLocalUrl())\n        {\n            // this converts the relative redirect path to an absolute one if we're \n            // redirecting to a different server\n            returnUrl = context.GetIdentityServerBaseUrl().EnsureTrailingSlash() + returnUrl.RemoveLeadingSlash();\n        }\n\n        var url = _url.AddQueryString(_options.UserInteraction.CustomRedirectReturnUrlParameter, returnUrl);\n        context.Response.RedirectToAbsoluteUrl(url);\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/DeviceAuthorizationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class DeviceAuthorizationResult : IEndpointResult\n{\n    public DeviceAuthorizationResponse Response { get; }\n\n    public DeviceAuthorizationResult(DeviceAuthorizationResponse response)\n    {\n        Response = response ?? throw new ArgumentNullException(nameof(response));\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.SetNoCache();\n\n        var dto = new ResultDto\n        {\n            device_code = Response.DeviceCode,\n            user_code = Response.UserCode,\n            verification_uri = Response.VerificationUri,\n            verification_uri_complete = Response.VerificationUriComplete,\n            expires_in = Response.DeviceCodeLifetime,\n            interval = Response.Interval\n        };\n\n        await context.Response.WriteJsonAsync(dto);\n    }\n\n    internal class ResultDto\n    {\n        public string device_code { get; set; }\n        public string user_code { get; set; }\n        public string verification_uri { get; set; }\n        public string verification_uri_complete { get; set; }\n        public int expires_in { get; set; }\n        public int interval { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/DiscoveryDocumentResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for a discovery document\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class DiscoveryDocumentResult : IEndpointResult\n{\n    /// <summary>\n    /// Gets the entries.\n    /// </summary>\n    /// <value>\n    /// The entries.\n    /// </value>\n    public Dictionary<string, object> Entries { get; }\n\n    /// <summary>\n    /// Gets the maximum age.\n    /// </summary>\n    /// <value>\n    /// The maximum age.\n    /// </value>\n    public int? MaxAge { get; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DiscoveryDocumentResult\" /> class.\n    /// </summary>\n    /// <param name=\"entries\">The entries.</param>\n    /// <param name=\"maxAge\">The maximum age.</param>\n    /// <exception cref=\"System.ArgumentNullException\">entries</exception>\n    public DiscoveryDocumentResult(Dictionary<string, object> entries, int? maxAge)\n    {\n        Entries = entries ?? throw new ArgumentNullException(nameof(entries));\n        MaxAge = maxAge;\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public Task ExecuteAsync(HttpContext context)\n    {\n        if (MaxAge.HasValue && MaxAge.Value >= 0)\n        {\n            context.Response.SetCache(MaxAge.Value, \"Origin\");\n        }\n\n        return context.Response.WriteJsonAsync(Entries);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/EndSessionCallbackResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class EndSessionCallbackResult : IEndpointResult\n{\n    private readonly EndSessionCallbackValidationResult _result;\n\n    public EndSessionCallbackResult(EndSessionCallbackValidationResult result)\n    {\n        _result = result ?? throw new ArgumentNullException(nameof(result));\n    }\n\n    internal EndSessionCallbackResult(\n        EndSessionCallbackValidationResult result,\n        IdentityServerOptions options)\n        : this(result)\n    {\n        _options = options;\n    }\n\n    private IdentityServerOptions _options;\n\n    private void Init(HttpContext context)\n    {\n        _options = _options ?? context.RequestServices.GetRequiredService<IdentityServerOptions>();\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        Init(context);\n\n        if (_result.IsError)\n        {\n            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;\n        }\n        else\n        {\n            context.Response.SetNoCache();\n            AddCspHeaders(context);\n\n            var html = GetHtml();\n            await context.Response.WriteHtmlAsync(html);\n        }\n    }\n\n    private void AddCspHeaders(HttpContext context)\n    {\n        if (_options.Authentication.RequireCspFrameSrcForSignout)\n        {\n            string frameSources = null;\n            var origins = _result.FrontChannelLogoutUrls?.Select(x => x.GetOrigin());\n            if (origins != null && origins.Any())\n            {\n                frameSources = origins.Distinct().Aggregate((x, y) => $\"{x} {y}\");\n            }\n\n            // the hash matches the embedded style element being used below\n            context.Response.AddStyleCspHeaders(_options.Csp, \"sha256-u+OupXgfekP+x/f6rMdoEAspPCYUtca912isERnoEjY=\", frameSources);\n        }\n    }\n\n    private string GetHtml()\n    {\n        string framesHtml = null;\n\n        if (_result.FrontChannelLogoutUrls != null && _result.FrontChannelLogoutUrls.Any())\n        {\n            var frameUrls = _result.FrontChannelLogoutUrls.Select(url => $\"<iframe src='{HtmlEncoder.Default.Encode(url)}'></iframe>\");\n            framesHtml = frameUrls.Aggregate((x, y) => x + y);\n        }\n\n        return $\"<!DOCTYPE html><html><style>iframe{{display:none;width:0;height:0;}}</style><body>{framesHtml}</body></html>\";\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/EndSessionResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for endsession\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class EndSessionResult : IEndpointResult\n{\n    private readonly EndSessionValidationResult _result;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"EndSessionResult\"/> class.\n    /// </summary>\n    /// <param name=\"result\">The result.</param>\n    /// <exception cref=\"System.ArgumentNullException\">result</exception>\n    public EndSessionResult(EndSessionValidationResult result)\n    {\n        _result = result ?? throw new ArgumentNullException(nameof(result));\n    }\n\n    internal EndSessionResult(\n        EndSessionValidationResult result,\n        IdentityServerOptions options,\n        ISystemClock clock,\n        IMessageStore<LogoutMessage> logoutMessageStore)\n        : this(result)\n    {\n        _options = options;\n        _clock = clock;\n        _logoutMessageStore = logoutMessageStore;\n    }\n\n    private IdentityServerOptions _options;\n    private ISystemClock _clock;\n    private IMessageStore<LogoutMessage> _logoutMessageStore;\n\n    private void Init(HttpContext context)\n    {\n        _options = _options ?? context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        _clock = _clock ?? context.RequestServices.GetRequiredService<ISystemClock>();\n        _logoutMessageStore = _logoutMessageStore ?? context.RequestServices.GetRequiredService<IMessageStore<LogoutMessage>>();\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        Init(context);\n\n        var validatedRequest = _result.IsError ? null : _result.ValidatedRequest;\n\n        string id = null;\n\n        if (validatedRequest != null)\n        {\n            var logoutMessage = new LogoutMessage(validatedRequest);\n            if (logoutMessage.ContainsPayload)\n            {\n                var msg = new Message<LogoutMessage>(logoutMessage, _clock.UtcNow.UtcDateTime);\n                id = await _logoutMessageStore.WriteAsync(msg);\n            }\n        }\n\n        var redirect = _options.UserInteraction.LogoutUrl;\n\n        if (redirect.IsLocalUrl())\n        {\n            redirect = context.GetIdentityServerRelativeUrl(redirect);\n        }\n\n        if (id != null)\n        {\n            redirect = redirect.AddQueryString(_options.UserInteraction.LogoutIdParameter, id);\n        }\n\n        context.Response.RedirectIfAllowed(redirect);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/IntrospectionResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for introspection\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class IntrospectionResult : IEndpointResult\n{\n    /// <summary>\n    /// Gets the result.\n    /// </summary>\n    /// <value>\n    /// The result.\n    /// </value>\n    public Dictionary<string, object> Entries { get; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IntrospectionResult\"/> class.\n    /// </summary>\n    /// <param name=\"entries\">The result.</param>\n    /// <exception cref=\"System.ArgumentNullException\">result</exception>\n    public IntrospectionResult(Dictionary<string, object> entries)\n    {\n        Entries = entries ?? throw new ArgumentNullException(nameof(entries));\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.SetNoCache();\n        \n        return context.Response.WriteJsonAsync(Entries);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/JsonWebKeysResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for the jwks document\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class JsonWebKeysResult : IEndpointResult\n{\n    /// <summary>\n    /// Gets the web keys.\n    /// </summary>\n    /// <value>\n    /// The web keys.\n    /// </value>\n    public IEnumerable<JsonWebKey> WebKeys { get; }\n\n    /// <summary>\n    /// Gets the maximum age.\n    /// </summary>\n    /// <value>\n    /// The maximum age.\n    /// </value>\n    public int? MaxAge { get; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"JsonWebKeysResult\" /> class.\n    /// </summary>\n    /// <param name=\"webKeys\">The web keys.</param>\n    /// <param name=\"maxAge\">The maximum age.</param>\n    public JsonWebKeysResult(IEnumerable<JsonWebKey> webKeys, int? maxAge)\n    {\n        WebKeys = webKeys ?? throw new ArgumentNullException(nameof(webKeys));\n        MaxAge = maxAge;\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public Task ExecuteAsync(HttpContext context)\n    {\n        if (MaxAge.HasValue && MaxAge.Value >= 0)\n        {\n            context.Response.SetCache(MaxAge.Value, \"Origin\");\n        }\n\n        return context.Response.WriteJsonAsync(new { keys = WebKeys }, \"application/json; charset=UTF-8\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/LoginPageResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for login page\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class LoginPageResult : IEndpointResult\n{\n    private readonly ValidatedAuthorizeRequest _request;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"LoginPageResult\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <exception cref=\"System.ArgumentNullException\">request</exception>\n    public LoginPageResult(ValidatedAuthorizeRequest request)\n    {\n        _request = request ?? throw new ArgumentNullException(nameof(request));\n    }\n\n    internal LoginPageResult(\n        ValidatedAuthorizeRequest request,\n        IdentityServerOptions options,\n        IAuthorizationParametersMessageStore authorizationParametersMessageStore = null) \n        : this(request)\n    {\n        _options = options;\n        _authorizationParametersMessageStore = authorizationParametersMessageStore;\n    }\n\n    private IdentityServerOptions _options;\n    private IAuthorizationParametersMessageStore _authorizationParametersMessageStore;\n\n    private void Init(HttpContext context)\n    {\n        _options = _options ?? context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        _authorizationParametersMessageStore = _authorizationParametersMessageStore ?? context.RequestServices.GetService<IAuthorizationParametersMessageStore>();\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        Init(context);\n\n        var returnUrl = context.GetIdentityServerBasePath().EnsureTrailingSlash() + Constants.ProtocolRoutePaths.AuthorizeCallback;\n        if (_authorizationParametersMessageStore != null)\n        {\n            var msg = new Message<IDictionary<string, string[]>>(_request.Raw.ToFullDictionary());\n            var id = await _authorizationParametersMessageStore.WriteAsync(msg);\n            returnUrl = returnUrl.AddQueryString(Constants.AuthorizationParamsStore.MessageStoreIdParameterName, id);\n        }\n        else\n        {\n            returnUrl = returnUrl.AddQueryString(_request.Raw.ToQueryString());\n        }\n\n        var loginUrl = _options.UserInteraction.LoginUrl;\n        if (!loginUrl.IsLocalUrl())\n        {\n            // this converts the relative redirect path to an absolute one if we're \n            // redirecting to a different server\n            returnUrl = context.GetIdentityServerHost().EnsureTrailingSlash() + returnUrl.RemoveLeadingSlash();\n        }\n\n        var url = loginUrl.AddQueryString(_options.UserInteraction.LoginReturnUrlParameter, returnUrl);\n        context.Response.RedirectToAbsoluteUrl(url);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/ProtectedResourceErrorResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.Net.Http.Headers;\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class ProtectedResourceErrorResult : IEndpointResult\n{\n    public string Error;\n    public string ErrorDescription;\n\n    public ProtectedResourceErrorResult(string error, string errorDescription = null)\n    {\n        Error = error;\n        ErrorDescription = errorDescription;\n    }\n\n    public Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.StatusCode = 401;\n        context.Response.SetNoCache();\n\n        if (Constants.ProtectedResourceErrorStatusCodes.ContainsKey(Error))\n        {\n            context.Response.StatusCode = Constants.ProtectedResourceErrorStatusCodes[Error];\n        }\n\n        if (Error == OidcConstants.ProtectedResourceErrors.ExpiredToken)\n        {\n            Error = OidcConstants.ProtectedResourceErrors.InvalidToken;\n            ErrorDescription = \"The access token expired\";\n        }\n\n        var errorString = string.Format($\"error=\\\"{Error}\\\"\");\n        if (ErrorDescription.IsMissing())\n        {\n            context.Response.Headers.Append(HeaderNames.WWWAuthenticate, new StringValues(new[] { \"Bearer realm=\\\"IdentityServer\\\"\", errorString }).ToString());\n        }\n        else\n        {\n            var errorDescriptionString = string.Format($\"error_description=\\\"{ErrorDescription}\\\"\");\n            context.Response.Headers.Append(HeaderNames.WWWAuthenticate, new StringValues(new[] { \"Bearer realm=\\\"IdentityServer\\\"\", errorString, errorDescriptionString }).ToString());\n        }\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/StatusCodeResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for a raw HTTP status code\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class StatusCodeResult : IEndpointResult\n{\n    /// <summary>\n    /// Gets the status code.\n    /// </summary>\n    /// <value>\n    /// The status code.\n    /// </value>\n    public int StatusCode { get; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"StatusCodeResult\"/> class.\n    /// </summary>\n    /// <param name=\"statusCode\">The status code.</param>\n    public StatusCodeResult(HttpStatusCode statusCode)\n    {\n        StatusCode = (int)statusCode;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"StatusCodeResult\"/> class.\n    /// </summary>\n    /// <param name=\"statusCode\">The status code.</param>\n    public StatusCodeResult(int statusCode)\n    {\n        StatusCode = statusCode;\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.StatusCode = StatusCode;\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/TokenErrorResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonExtensionDataAttribute = System.Text.Json.Serialization.JsonExtensionDataAttribute;\n\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class TokenErrorResult : IEndpointResult\n{\n    public TokenErrorResponse Response { get; }\n\n    public TokenErrorResult(TokenErrorResponse error)\n    {\n        if (error.Error.IsMissing()) throw new ArgumentNullException(nameof(error.Error), \"Error must be set\");\n\n        Response = error;\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.StatusCode = 400;\n        context.Response.SetNoCache();\n\n        var dto = new ResultDto\n        {\n            error = Response.Error,\n            error_description = Response.ErrorDescription,\n            \n            custom = Response.Custom\n        };\n\n        await context.Response.WriteJsonAsync(dto);\n    }\n\n    internal class ResultDto\n    {\n        public string error { get; set; }\n        public string error_description { get; set; }\n\n        [JsonExtensionData]\n        public Dictionary<string, object> custom { get; set; }\n    }    \n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/TokenResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonExtensionDataAttribute = System.Text.Json.Serialization.JsonExtensionDataAttribute;\nusing JsonSerializer = System.Text.Json.JsonSerializer;\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class TokenResult : IEndpointResult\n{\n    public TokenResponse Response { get; set; }\n\n    public TokenResult(TokenResponse response)\n    {\n        Response = response ?? throw new ArgumentNullException(nameof(response));\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.SetNoCache();\n\n        var dto = new ResultDto\n        {\n            id_token = Response.IdentityToken,\n            access_token = Response.AccessToken,\n            refresh_token = Response.RefreshToken,\n            expires_in = Response.AccessTokenLifetime,\n            token_type = OidcConstants.TokenResponse.BearerTokenType,\n            scope = Response.Scope,\n\n            Custom = Response.Custom\n        };\n\n        await context.Response.WriteJsonAsync(dto);\n    }\n\n    internal class ResultDto\n    {\n        public string id_token { get; set; }\n        public string access_token { get; set; }\n        public int expires_in { get; set; }\n        public string token_type { get; set; }\n        public string refresh_token { get; set; }\n        public string scope { get; set; }\n\n        [JsonExtensionData]\n        public Dictionary<string, object>? Custom { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/TokenRevocationErrorResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\n/// <summary>\n/// Result for revocation error\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointResult\" />\npublic class TokenRevocationErrorResult : IEndpointResult\n{\n    /// <summary>\n    /// Gets or sets the error.\n    /// </summary>\n    /// <value>\n    /// The error.\n    /// </value>\n    public string Error { get; set; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRevocationErrorResult\"/> class.\n    /// </summary>\n    /// <param name=\"error\">The error.</param>\n    public TokenRevocationErrorResult(string error)\n    {\n        Error = error;\n    }\n\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;\n        return context.Response.WriteJsonAsync(new { error = Error });\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/Results/UserInfoResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints.Results;\n\ninternal class UserInfoResult : IEndpointResult\n{\n    public Dictionary<string, object> Claims;\n\n    public UserInfoResult(Dictionary<string, object> claims)\n    {\n        Claims = claims;\n    }\n\n    public async Task ExecuteAsync(HttpContext context)\n    {\n        context.Response.SetNoCache();\n        await context.Response.WriteJsonAsync(Claims);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/TokenEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\n/// <summary>\n/// The token endpoint\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointHandler\" />\ninternal class TokenEndpoint : IEndpointHandler\n{\n    private readonly IClientSecretValidator _clientValidator;\n    private readonly ITokenRequestValidator _requestValidator;\n    private readonly ITokenResponseGenerator _responseGenerator;\n    private readonly IEventService _events;\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenEndpoint\" /> class.\n    /// </summary>\n    /// <param name=\"clientValidator\">The client validator.</param>\n    /// <param name=\"requestValidator\">The request validator.</param>\n    /// <param name=\"responseGenerator\">The response generator.</param>\n    /// <param name=\"events\">The events.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public TokenEndpoint(\n        IClientSecretValidator clientValidator, \n        ITokenRequestValidator requestValidator, \n        ITokenResponseGenerator responseGenerator, \n        IEventService events, \n        ILogger<TokenEndpoint> logger)\n    {\n        _clientValidator = clientValidator;\n        _requestValidator = requestValidator;\n        _responseGenerator = responseGenerator;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Processes the request.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        _logger.LogTrace(\"Processing token request.\");\n\n        // validate HTTP\n        if (!HttpMethods.IsPost(context.Request.Method) || !context.Request.HasApplicationFormContentType())\n        {\n            _logger.LogWarning(\"Invalid HTTP request for token endpoint\");\n            return Error(OidcConstants.TokenErrors.InvalidRequest);\n        }\n\n        return await ProcessTokenRequestAsync(context);\n    }\n\n    private async Task<IEndpointResult> ProcessTokenRequestAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start token request.\");\n\n        // validate client\n        var clientResult = await _clientValidator.ValidateAsync(context);\n\n        if (clientResult.Client == null)\n        {\n            return Error(OidcConstants.TokenErrors.InvalidClient);\n        }\n\n        // validate request\n        var form = (await context.Request.ReadFormAsync()).AsNameValueCollection();\n        _logger.LogTrace(\"Calling into token request validator: {type}\", _requestValidator.GetType().FullName);\n        var requestResult = await _requestValidator.ValidateRequestAsync(form, clientResult);\n\n        if (requestResult.IsError)\n        {\n            await _events.RaiseAsync(new TokenIssuedFailureEvent(requestResult));\n            return Error(requestResult.Error, requestResult.ErrorDescription, requestResult.CustomResponse);\n        }\n\n        // create response\n        _logger.LogTrace(\"Calling into token request response generator: {type}\", _responseGenerator.GetType().FullName);\n        var response = await _responseGenerator.ProcessAsync(requestResult);\n\n        await _events.RaiseAsync(new TokenIssuedSuccessEvent(response, requestResult));\n        LogTokens(response, requestResult);\n\n        // return result\n        _logger.LogDebug(\"Token request success.\");\n        return new TokenResult(response);\n    }\n\n    private TokenErrorResult Error(string error, string errorDescription = null, Dictionary<string, object> custom = null)\n    {\n        var response = new TokenErrorResponse\n        {\n            Error = error,\n            ErrorDescription = errorDescription,\n            Custom = custom\n        };\n\n        return new TokenErrorResult(response);\n    }\n\n    private void LogTokens(TokenResponse response, TokenRequestValidationResult requestResult)\n    {\n        var clientId = $\"{requestResult.ValidatedRequest.Client.ClientId} ({requestResult.ValidatedRequest.Client?.ClientName ?? \"no name set\"})\";\n        var subjectId = requestResult.ValidatedRequest.Subject?.GetSubjectId() ?? \"no subject\";\n\n        if (response.IdentityToken != null)\n        {\n            _logger.LogTrace(\"Identity token issued for {clientId} / {subjectId}: {token}\", clientId, subjectId, response.IdentityToken);\n        }\n        if (response.RefreshToken != null)\n        {\n            _logger.LogTrace(\"Refresh token issued for {clientId} / {subjectId}: {token}\", clientId, subjectId, response.RefreshToken);\n        }\n        if (response.AccessToken != null)\n        {\n            _logger.LogTrace(\"Access token issued for {clientId} / {subjectId}: {token}\", clientId, subjectId, response.AccessToken);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/TokenRevocationEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\n/// <summary>\n/// The revocation endpoint\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointHandler\" />\ninternal class TokenRevocationEndpoint : IEndpointHandler\n{\n    private readonly ILogger _logger;\n    private readonly IClientSecretValidator _clientValidator;\n    private readonly ITokenRevocationRequestValidator _requestValidator;\n    private readonly ITokenRevocationResponseGenerator _responseGenerator;\n    private readonly IEventService _events;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRevocationEndpoint\" /> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    /// <param name=\"clientValidator\">The client validator.</param>\n    /// <param name=\"requestValidator\">The request validator.</param>\n    /// <param name=\"responseGenerator\">The response generator.</param>\n    /// <param name=\"events\">The events.</param>\n    public TokenRevocationEndpoint(ILogger<TokenRevocationEndpoint> logger,\n        IClientSecretValidator clientValidator,\n        ITokenRevocationRequestValidator requestValidator,\n        ITokenRevocationResponseGenerator responseGenerator,\n        IEventService events)\n    {\n        _logger = logger;\n        _clientValidator = clientValidator;\n        _requestValidator = requestValidator;\n        _responseGenerator = responseGenerator;\n\n        _events = events;\n    }\n\n    /// <summary>\n    /// Processes the request.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        _logger.LogTrace(\"Processing revocation request.\");\n\n        if (!HttpMethods.IsPost(context.Request.Method))\n        {\n            _logger.LogWarning(\"Invalid HTTP method\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        if (!context.Request.HasApplicationFormContentType())\n        {\n            _logger.LogWarning(\"Invalid media type\");\n            return new StatusCodeResult(HttpStatusCode.UnsupportedMediaType);\n        }\n\n        var response = await ProcessRevocationRequestAsync(context);\n\n        return response;\n    }\n\n    private async Task<IEndpointResult> ProcessRevocationRequestAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start revocation request.\");\n\n        // validate client\n        var clientValidationResult = await _clientValidator.ValidateAsync(context);\n\n        if (clientValidationResult.IsError)\n        {\n            return new TokenRevocationErrorResult(OidcConstants.TokenErrors.InvalidClient);\n        }\n\n        _logger.LogTrace(\"Client validation successful\");\n\n        // validate the token request\n        var form = (await context.Request.ReadFormAsync()).AsNameValueCollection();\n\n        _logger.LogTrace(\"Calling into token revocation request validator: {type}\", _requestValidator.GetType().FullName);\n        var requestValidationResult = await _requestValidator.ValidateRequestAsync(form, clientValidationResult.Client);\n\n        if (requestValidationResult.IsError)\n        {\n            return new TokenRevocationErrorResult(requestValidationResult.Error);\n        }\n\n        _logger.LogTrace(\"Calling into token revocation response generator: {type}\", _responseGenerator.GetType().FullName);\n        var response = await _responseGenerator.ProcessAsync(requestValidationResult);\n\n        if (response.Success)\n        {\n            _logger.LogInformation(\"Token revocation complete\");\n            await _events.RaiseAsync(new TokenRevokedSuccessEvent(requestValidationResult, requestValidationResult.Client));\n        }\n        else\n        {\n            _logger.LogInformation(\"No matching token found\");\n        }\n\n        if (response.Error.IsPresent()) return new TokenRevocationErrorResult(response.Error);\n\n        return new StatusCodeResult(HttpStatusCode.OK);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Endpoints/UserInfoEndpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Endpoints;\n\n/// <summary>\n/// The userinfo endpoint\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Hosting.IEndpointHandler\" />\ninternal class UserInfoEndpoint : IEndpointHandler\n{\n    private readonly BearerTokenUsageValidator _tokenUsageValidator;\n    private readonly IUserInfoRequestValidator _requestValidator;\n    private readonly IUserInfoResponseGenerator _responseGenerator;\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UserInfoEndpoint\" /> class.\n    /// </summary>\n    /// <param name=\"tokenUsageValidator\">The token usage validator.</param>\n    /// <param name=\"requestValidator\">The request validator.</param>\n    /// <param name=\"responseGenerator\">The response generator.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public UserInfoEndpoint(\n        BearerTokenUsageValidator tokenUsageValidator, \n        IUserInfoRequestValidator requestValidator, \n        IUserInfoResponseGenerator responseGenerator, \n        ILogger<UserInfoEndpoint> logger)\n    {\n        _tokenUsageValidator = tokenUsageValidator;\n        _requestValidator = requestValidator;\n        _responseGenerator = responseGenerator;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Processes the request.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task<IEndpointResult> ProcessAsync(HttpContext context)\n    {\n        if (!HttpMethods.IsGet(context.Request.Method) && !HttpMethods.IsPost(context.Request.Method))\n        {\n            _logger.LogWarning(\"Invalid HTTP method for userinfo endpoint.\");\n            return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);\n        }\n\n        return await ProcessUserInfoRequestAsync(context);\n    }\n\n    private async Task<IEndpointResult> ProcessUserInfoRequestAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start userinfo request\");\n\n        // userinfo requires an access token on the request\n        var tokenUsageResult = await _tokenUsageValidator.ValidateAsync(context);\n        if (tokenUsageResult.TokenFound == false)\n        {\n            var error = \"No access token found.\";\n\n            _logger.LogError(error);\n            return Error(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        // validate the request\n        _logger.LogTrace(\"Calling into userinfo request validator: {type}\", _requestValidator.GetType().FullName);\n        var validationResult = await _requestValidator.ValidateRequestAsync(tokenUsageResult.Token);\n\n        if (validationResult.IsError)\n        {\n            //_logger.LogError(\"Error validating  validationResult.Error);\n            return Error(validationResult.Error);\n        }\n\n        // generate response\n        _logger.LogTrace(\"Calling into userinfo response generator: {type}\", _responseGenerator.GetType().FullName);\n        var response = await _responseGenerator.ProcessAsync(validationResult);\n\n        _logger.LogDebug(\"End userinfo request\");\n        return new UserInfoResult(response);\n    }\n\n    private IEndpointResult Error(string error, string description = null)\n    {\n        return new ProtectedResourceErrorResult(error, description);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/ApiAuthenticationFailureEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for failed API authentication\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class ApiAuthenticationFailureEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiAuthenticationFailureEvent\"/> class.\n    /// </summary>\n    /// <param name=\"apiName\">Name of the API.</param>\n    /// <param name=\"message\">The message.</param>\n    public ApiAuthenticationFailureEvent(string apiName, string message)\n        : base(EventCategories.Authentication, \n              \"API Authentication Failure\",\n              EventTypes.Failure, \n              EventIds.ApiAuthenticationFailure, \n              message)\n    {\n        ApiName = apiName;\n    }\n\n    /// <summary>\n    /// Gets or sets the name of the API.\n    /// </summary>\n    /// <value>\n    /// The name of the API.\n    /// </value>\n    public string ApiName { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/ApiAuthenticationSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for successful API authentication\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class ApiAuthenticationSuccessEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiAuthenticationSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"apiName\">Name of the API.</param>\n    /// <param name=\"authenticationMethod\">The authentication method.</param>\n    public ApiAuthenticationSuccessEvent(string apiName, string authenticationMethod)\n        : base(EventCategories.Authentication, \n              \"API Authentication Success\",\n              EventTypes.Success, \n              EventIds.ApiAuthenticationSuccess)\n    {\n        ApiName = apiName;\n        AuthenticationMethod = authenticationMethod;\n    }\n\n    /// <summary>\n    /// Gets or sets the name of the API.\n    /// </summary>\n    /// <value>\n    /// The name of the API.\n    /// </value>\n    public string ApiName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the authentication method.\n    /// </summary>\n    /// <value>\n    /// The authentication method.\n    /// </value>\n    public string AuthenticationMethod { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/ClientAuthenticationFailureEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for failed client authentication\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class ClientAuthenticationFailureEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ClientAuthenticationFailureEvent\"/> class.\n    /// </summary>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"message\">The message.</param>\n    public ClientAuthenticationFailureEvent(string clientId, string message)\n        : base(EventCategories.Authentication, \n              \"Client Authentication Failure\",\n              EventTypes.Failure, \n              EventIds.ClientAuthenticationFailure, \n              message)\n    {\n        ClientId = clientId;\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/ClientAuthenticationSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for successful client authentication\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class ClientAuthenticationSuccessEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ClientAuthenticationSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"authenticationMethod\">The authentication method.</param>\n    public ClientAuthenticationSuccessEvent(string clientId, string authenticationMethod)\n        : base(EventCategories.Authentication, \n              \"Client Authentication Success\",\n              EventTypes.Success, \n              EventIds.ClientAuthenticationSuccess)\n    {\n        ClientId = clientId;\n        AuthenticationMethod = authenticationMethod;\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the authentication method.\n    /// </summary>\n    /// <value>\n    /// The authentication method.\n    /// </value>\n    public string AuthenticationMethod { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/ConsentDeniedEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for denied consent.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class ConsentDeniedEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ConsentDeniedEvent\" /> class.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"requestedScopes\">The requested scopes.</param>\n    public ConsentDeniedEvent(string subjectId, string clientId, IEnumerable<string> requestedScopes)\n        : base(EventCategories.Grants,\n              \"Consent denied\",\n              EventTypes.Information,\n              EventIds.ConsentDenied)\n    {\n        SubjectId = subjectId;\n        ClientId = clientId;\n        RequestedScopes = requestedScopes;\n    }\n\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client ID.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the requested scopes.\n    /// </summary>\n    /// <value>\n    /// The requested scopes.\n    /// </value>\n    public IEnumerable<string> RequestedScopes { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/ConsentGrantedEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for granted consent.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class ConsentGrantedEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ConsentGrantedEvent\" /> class.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"requestedScopes\">The requested scopes.</param>\n    /// <param name=\"grantedScopes\">The granted scopes.</param>\n    /// <param name=\"consentRemembered\">if set to <c>true</c> consent was remembered.</param>\n    public ConsentGrantedEvent(string subjectId, string clientId, IEnumerable<string> requestedScopes, IEnumerable<string> grantedScopes, bool consentRemembered)\n        : base(EventCategories.Grants,\n              \"Consent granted\",\n              EventTypes.Information,\n              EventIds.ConsentGranted)\n    {\n        SubjectId = subjectId;\n        ClientId = clientId;\n        RequestedScopes = requestedScopes;\n        GrantedScopes = grantedScopes;\n        ConsentRemembered = consentRemembered;\n    }\n\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client ID.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the requested scopes.\n    /// </summary>\n    /// <value>\n    /// The requested scopes.\n    /// </value>\n    public IEnumerable<string> RequestedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the granted scopes.\n    /// </summary>\n    /// <value>\n    /// The granted scopes.\n    /// </value>\n    public IEnumerable<string> GrantedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether consent was remembered.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if consent was remembered; otherwise, <c>false</c>.\n    /// </value>\n    public bool ConsentRemembered { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/DeviceAuthorizationFailureEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for device authorization failure\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class DeviceAuthorizationFailureEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceAuthorizationFailureEvent\"/> class.\n    /// </summary>\n    /// <param name=\"result\">The result.</param>\n    public DeviceAuthorizationFailureEvent(DeviceAuthorizationRequestValidationResult result)\n        : this()\n    {\n        if (result.ValidatedRequest != null)\n        {\n            ClientId = result.ValidatedRequest.Client?.ClientId;\n            ClientName = result.ValidatedRequest.Client?.ClientName;\n            Scopes = result.ValidatedRequest.RequestedScopes?.ToSpaceSeparatedString();\n            \n        }\n\n        Endpoint = Constants.EndpointNames.DeviceAuthorization;\n        Error = result.Error;\n        ErrorDescription = result.ErrorDescription;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceAuthorizationFailureEvent\"/> class.\n    /// </summary>\n    public DeviceAuthorizationFailureEvent()\n        : base(EventCategories.DeviceFlow,\n            \"Device Authorization Failure\",\n            EventTypes.Failure,\n            EventIds.DeviceAuthorizationFailure)\n    {\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the name of the client.\n    /// </summary>\n    /// <value>\n    /// The name of the client.\n    /// </value>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the endpoint.\n    /// </summary>\n    /// <value>\n    /// The endpoint.\n    /// </value>\n    public string Endpoint { get; set; }\n\n    /// <summary>\n    /// Gets or sets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public string Scopes { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the error.\n    /// </summary>\n    /// <value>\n    /// The error.\n    /// </value>\n    public string Error { get; set; }\n\n    /// <summary>\n    /// Gets or sets the error description.\n    /// </summary>\n    /// <value>\n    /// The error description.\n    /// </value>\n    public string ErrorDescription { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/DeviceAuthorizationSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for device authorization failure\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class DeviceAuthorizationSuccessEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceAuthorizationSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"response\">The response.</param>\n    /// <param name=\"request\">The request.</param>\n    public DeviceAuthorizationSuccessEvent(DeviceAuthorizationResponse response, DeviceAuthorizationRequestValidationResult request)\n        : this()\n    {\n        ClientId = request.ValidatedRequest.Client?.ClientId;\n        ClientName = request.ValidatedRequest.Client?.ClientName;\n        Endpoint = Constants.EndpointNames.DeviceAuthorization;\n        Scopes = request.ValidatedRequest.ValidatedResources?.RawScopeValues.ToSpaceSeparatedString();\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceAuthorizationSuccessEvent\"/> class.\n    /// </summary>\n    protected DeviceAuthorizationSuccessEvent()\n        : base(EventCategories.DeviceFlow,\n            \"Device Authorization Success\",\n            EventTypes.Success,\n            EventIds.DeviceAuthorizationSuccess)\n    {\n    }\n\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the name of the client.\n    /// </summary>\n    /// <value>\n    /// The name of the client.\n    /// </value>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the endpoint.\n    /// </summary>\n    /// <value>\n    /// The endpoint.\n    /// </value>\n    public string Endpoint { get; set; }\n\n    /// <summary>\n    /// Gets or sets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public string Scopes { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/GrantsRevokedEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for revoked grants.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class GrantsRevokedEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"GrantsRevokedEvent\" /> class.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    public GrantsRevokedEvent(string subjectId, string clientId)\n        : base(EventCategories.Grants,\n              \"Grants revoked\",\n              EventTypes.Information,\n              EventIds.GrantsRevoked)\n    {\n        SubjectId = subjectId;\n        ClientId = clientId;\n    }\n\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client ID.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/Infrastructure/Event.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Models base class for events raised from IdentityServer.\n/// </summary>\npublic abstract class Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Event\" /> class.\n    /// </summary>\n    /// <param name=\"category\">The category.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"type\">The type.</param>\n    /// <param name=\"id\">The identifier.</param>\n    /// <param name=\"message\">The message.</param>\n    /// <exception cref=\"System.ArgumentNullException\">category</exception>\n    protected Event(string category, string name, EventTypes type, int id, string message = null)\n    {\n        Category = category ?? throw new ArgumentNullException(nameof(category));\n        Name = name ?? throw new ArgumentNullException(nameof(name));\n\n        EventType = type;\n        Id = id;\n        Message = message;\n    }\n\n    /// <summary>\n    /// Allows implementing custom initialization logic.\n    /// </summary>\n    /// <returns></returns>\n    protected internal virtual Task PrepareAsync()\n    {\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Gets or sets the category.\n    /// </summary>\n    /// <value>\n    /// The category.\n    /// </value>\n    public string Category { get; set; }\n\n    /// <summary>\n    /// Gets or sets the name.\n    /// </summary>\n    /// <value>\n    /// The name.\n    /// </value>\n    public string Name { get; set; }\n\n    /// <summary>\n    /// Gets or sets the event type.\n    /// </summary>\n    /// <value>\n    /// The type of the event.\n    /// </value>\n    public EventTypes EventType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the identifier.\n    /// </summary>\n    /// <value>\n    /// The identifier.\n    /// </value>\n    public int Id { get; set; }\n\n    /// <summary>\n    /// Gets or sets the event message.\n    /// </summary>\n    /// <value>\n    /// The message.\n    /// </value>\n    public string Message { get; set; }\n\n    /// <summary>\n    /// Gets or sets the per-request activity identifier.\n    /// </summary>\n    /// <value>\n    /// The activity identifier.\n    /// </value>\n    public string ActivityId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the time stamp when the event was raised.\n    /// </summary>\n    /// <value>\n    /// The time stamp.\n    /// </value>\n    public DateTime TimeStamp { get; set; }\n\n    /// <summary>\n    /// Gets or sets the server process identifier.\n    /// </summary>\n    /// <value>\n    /// The process identifier.\n    /// </value>\n    public int ProcessId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the local ip address of the current request.\n    /// </summary>\n    /// <value>\n    /// The local ip address.\n    /// </value>\n    public string LocalIpAddress { get; set; }\n\n    /// <summary>\n    /// Gets or sets the remote ip address of the current request.\n    /// </summary>\n    /// <value>\n    /// The remote ip address.\n    /// </value>\n    public string RemoteIpAddress { get; set; }\n\n    /// <summary>\n    /// Obfuscates a token.\n    /// </summary>\n    /// <param name=\"value\">The token.</param>\n    /// <returns></returns>\n    protected static string Obfuscate(string value)\n    {\n        var last4Chars = \"****\";\n        if (value.IsPresent() && value.Length > 4)\n        {\n            last4Chars = value.Substring(value.Length - 4);\n        }\n\n        return \"****\" + last4Chars;\n    }\n\n    /// <inheritdoc/>\n    public override string ToString()\n    {\n        return LogSerializer.Serialize(this);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/Infrastructure/EventCategories.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Categories for events\n/// </summary>\npublic static class EventCategories\n{\n    /// <summary>\n    /// Authentication related events\n    /// </summary>\n    public const string Authentication = \"Authentication\";\n\n    /// <summary>\n    /// Token related events\n    /// </summary>\n    public const string Token = \"Token\";\n\n    /// <summary>\n    /// Grants related events\n    /// </summary>\n    public const string Grants = \"Grants\";\n\n    /// <summary>\n    /// Error related events\n    /// </summary>\n    public const string Error = \"Error\";\n\n    /// <summary>\n    /// Device flow related events\n    /// </summary>\n    public const string DeviceFlow = \"Device\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/Infrastructure/EventIds.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Events;\n\npublic static class EventIds\n{\n    //////////////////////////////////////////////////////\n    /// Authentication related events\n    //////////////////////////////////////////////////////\n    private const int AuthenticationEventsStart = 1000;\n\n    public const int UserLoginSuccess = AuthenticationEventsStart + 0;\n    public const int UserLoginFailure = AuthenticationEventsStart + 1;\n    public const int UserLogoutSuccess = AuthenticationEventsStart + 2;\n\n    public const int ClientAuthenticationSuccess = AuthenticationEventsStart + 10;\n    public const int ClientAuthenticationFailure = AuthenticationEventsStart + 11;\n    \n    public const int ApiAuthenticationSuccess = AuthenticationEventsStart + 20;\n    public const int ApiAuthenticationFailure = AuthenticationEventsStart + 21;\n\n    //////////////////////////////////////////////////////\n    /// Token related events\n    //////////////////////////////////////////////////////\n    private const int TokenEventsStart = 2000;\n\n    public const int TokenIssuedSuccess = TokenEventsStart + 0;\n    public const int TokenIssuedFailure = TokenEventsStart + 1;\n\n    public const int TokenRevokedSuccess = TokenEventsStart + 10;\n\n    public const int TokenIntrospectionSuccess = TokenEventsStart + 20;\n    public const int TokenIntrospectionFailure = TokenEventsStart + 21;\n    \n    //////////////////////////////////////////////////////\n    /// Error related events\n    //////////////////////////////////////////////////////\n    private const int ErrorEventsStart = 3000;\n\n    public const int UnhandledException = ErrorEventsStart + 0;\n    public const int InvalidClientConfiguration = ErrorEventsStart + 1;\n\n    //////////////////////////////////////////////////////\n    /// Grants related events\n    //////////////////////////////////////////////////////\n    private const int GrantsEventsStart = 4000;\n\n    public const int ConsentGranted = GrantsEventsStart + 0;\n    public const int ConsentDenied = GrantsEventsStart + 1;\n    public const int GrantsRevoked = GrantsEventsStart + 2;\n\n    private const int DeviceFlowEventsStart = 5000;\n\n    public const int DeviceAuthorizationSuccess = DeviceFlowEventsStart + 0;\n    public const int DeviceAuthorizationFailure = DeviceFlowEventsStart + 1;\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/Infrastructure/EventType.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Indicates if the event is a success or fail event.\n/// </summary>\npublic enum EventTypes\n{\n    /// <summary>\n    /// Success event\n    /// </summary>\n    Success = 1,\n\n    /// <summary>\n    /// Failure event\n    /// </summary>\n    Failure = 2,\n\n    /// <summary>\n    /// Information event\n    /// </summary>\n    Information = 3,\n    \n    /// <summary>\n    /// Error event\n    /// </summary>\n    Error = 4\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/InvalidClientConfiguration.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for unhandled exceptions\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class InvalidClientConfigurationEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UnhandledExceptionEvent\" /> class.\n    /// </summary>\n    /// <param name=\"client\">The client.</param>\n    /// <param name=\"errorMessage\">The error message.</param>\n    public InvalidClientConfigurationEvent(Client client, string errorMessage)\n        : base(EventCategories.Error,\n              \"Invalid Client Configuration\",\n              EventTypes.Error, \n              EventIds.InvalidClientConfiguration,\n              errorMessage)\n    {\n        ClientId = client.ClientId;\n        ClientName = client.ClientName ?? \"unknown name\";\n    }\n\n    /// <summary>\n    /// Gets or sets the client ID.\n    /// </summary>\n    /// <value>\n    /// The details.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the name of the client.\n    /// </summary>\n    /// <value>\n    /// The name of the client.\n    /// </value>\n    public string ClientName { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/TokenIntrospectionFailureEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for failed token introspection\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class TokenIntrospectionFailureEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIntrospectionSuccessEvent\" /> class.\n    /// </summary>\n    /// <param name=\"apiName\">Name of the API.</param>\n    /// <param name=\"errorMessage\">The error message.</param>\n    /// <param name=\"token\">The token.</param>\n    /// <param name=\"apiScopes\">The API scopes.</param>\n    /// <param name=\"tokenScopes\">The token scopes.</param>\n    public TokenIntrospectionFailureEvent(string apiName, string errorMessage, string token = null, IEnumerable<string> apiScopes = null, IEnumerable<string> tokenScopes = null)\n        : base(EventCategories.Token,\n              \"Token Introspection Failure\",\n              EventTypes.Failure,\n              EventIds.TokenIntrospectionFailure,\n              errorMessage)\n    {\n        ApiName = apiName;\n\n        if (token.IsPresent())\n        {\n            Token = Obfuscate(token);\n        }\n\n        if (apiScopes != null)\n        {\n            ApiScopes = apiScopes;\n        }\n\n        if (tokenScopes != null)\n        {\n            TokenScopes = tokenScopes;\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets the name of the API.\n    /// </summary>\n    /// <value>\n    /// The name of the API.\n    /// </value>\n    public string ApiName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the token.\n    /// </summary>\n    /// <value>\n    /// The token.\n    /// </value>\n    public string Token { get; set; }\n\n    /// <summary>\n    /// Gets or sets the API scopes.\n    /// </summary>\n    /// <value>\n    /// The API scopes.\n    /// </value>\n    public IEnumerable<string> ApiScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the token scopes.\n    /// </summary>\n    /// <value>\n    /// The token scopes.\n    /// </value>\n    public IEnumerable<string> TokenScopes { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/TokenIntrospectionSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for successful token introspection\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class TokenIntrospectionSuccessEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIntrospectionSuccessEvent\" /> class.\n    /// </summary>\n    /// <param name=\"result\">The result.</param>\n    public TokenIntrospectionSuccessEvent(IntrospectionRequestValidationResult result)\n        : base(EventCategories.Token,\n              \"Token Introspection Success\",\n              EventTypes.Success,\n              EventIds.TokenIntrospectionSuccess)\n    {\n        ApiName = result.Api.Name;\n        IsActive = result.IsActive;\n\n        if (result.Token.IsPresent())\n        {\n            Token = Obfuscate(result.Token);\n        }\n        \n        if (!result.Claims.EnumerableIsNullOrEmpty())\n        {\n            ClaimTypes = result.Claims.Select(c => c.Type).Distinct();\n            TokenScopes = result.Claims.Where(c => c.Type == \"scope\").Select(c => c.Value);\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets the name of the API.\n    /// </summary>\n    /// <value>\n    /// The name of the API.\n    /// </value>\n    public string ApiName { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether this instance is active.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is active; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsActive { get; set; }\n\n    /// <summary>\n    /// Gets or sets the token.\n    /// </summary>\n    /// <value>\n    /// The token.\n    /// </value>\n    public string Token { get; set; }\n\n    /// <summary>\n    /// Gets or sets the claim types.\n    /// </summary>\n    /// <value>\n    /// The claim types.\n    /// </value>\n    public IEnumerable<string> ClaimTypes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the token scopes.\n    /// </summary>\n    /// <value>\n    /// The token scopes.\n    /// </value>\n    public IEnumerable<string> TokenScopes { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/TokenIssuedFailureEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for failed token issuance\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class TokenIssuedFailureEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIssuedFailureEvent\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"error\">The error.</param>\n    /// <param name=\"description\">The description.</param>\n    public TokenIssuedFailureEvent(ValidatedAuthorizeRequest request, string error, string description)\n        : this()\n    {\n        if (request != null)\n        {\n            ClientId = request.ClientId;\n            ClientName = request.Client?.ClientName;\n            RedirectUri = request.RedirectUri;\n            Scopes = request.RequestedScopes?.ToSpaceSeparatedString();\n            GrantType = request.GrantType;\n\n            if (request.Subject != null && request.Subject.Identity.IsAuthenticated)\n            {\n                SubjectId = request.Subject?.GetSubjectId();\n            }\n        }\n\n        Endpoint = EndpointNames.Authorize;\n        Error = error;\n        ErrorDescription = description;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIssuedFailureEvent\"/> class.\n    /// </summary>\n    /// <param name=\"result\">The result.</param>\n    public TokenIssuedFailureEvent(TokenRequestValidationResult result)\n        : this()\n    {\n        if (result.ValidatedRequest != null)\n        {\n            ClientId = result.ValidatedRequest.Client.ClientId;\n            ClientName = result.ValidatedRequest.Client.ClientName;\n            GrantType = result.ValidatedRequest.GrantType;\n            Scopes = result.ValidatedRequest.RequestedScopes?.ToSpaceSeparatedString();\n\n            if (result.ValidatedRequest.Subject != null && result.ValidatedRequest.Subject.Identity.IsAuthenticated)\n            {\n                SubjectId = result.ValidatedRequest.Subject.GetSubjectId();\n            }\n        }\n\n        Endpoint = EndpointNames.Token;\n        Error = result.Error;\n        ErrorDescription = result.ErrorDescription;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIssuedFailureEvent\"/> class.\n    /// </summary>\n    protected TokenIssuedFailureEvent()\n        : base(EventCategories.Token,\n              \"Token Issued Failure\",\n              EventTypes.Failure,\n              EventIds.TokenIssuedFailure)\n    {\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the name of the client.\n    /// </summary>\n    /// <value>\n    /// The name of the client.\n    /// </value>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the redirect URI.\n    /// </summary>\n    /// <value>\n    /// The redirect URI.\n    /// </value>\n    public string RedirectUri { get; set; }\n\n    /// <summary>\n    /// Gets or sets the endpoint.\n    /// </summary>\n    /// <value>\n    /// The endpoint.\n    /// </value>\n    public string Endpoint { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public string Scopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the grant type.\n    /// </summary>\n    /// <value>\n    /// The grant type.\n    /// </value>\n    public string GrantType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the error.\n    /// </summary>\n    /// <value>\n    /// The error.\n    /// </value>\n    public string Error { get; set; }\n\n    /// <summary>\n    /// Gets or sets the error description.\n    /// </summary>\n    /// <value>\n    /// The error description.\n    /// </value>\n    public string ErrorDescription { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/TokenIssuedSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for successful token issuance\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class TokenIssuedSuccessEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIssuedSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"response\">The response.</param>\n    public TokenIssuedSuccessEvent(AuthorizeResponse response)\n        : this()\n    {\n        ClientId = response.Request.ClientId;\n        ClientName = response.Request.Client.ClientName;\n        RedirectUri = response.RedirectUri;\n        Endpoint = EndpointNames.Authorize;\n        SubjectId = response.Request.Subject.GetSubjectId();\n        Scopes = response.Scope;\n        GrantType = response.Request.GrantType;\n\n        var tokens = new List<Token>();\n        if (response.IdentityToken != null)\n        {\n            tokens.Add(new Token(OidcConstants.TokenTypes.IdentityToken, response.IdentityToken));\n        }\n        if (response.Code != null)\n        {\n            tokens.Add(new Token(OidcConstants.ResponseTypes.Code, response.Code));\n        }\n        if (response.AccessToken != null)\n        {\n            tokens.Add(new Token(OidcConstants.TokenTypes.AccessToken, response.AccessToken));\n        }\n        Tokens = tokens;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIssuedSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"response\">The response.</param>\n    /// <param name=\"request\">The request.</param>\n    public TokenIssuedSuccessEvent(TokenResponse response, TokenRequestValidationResult request)\n        : this()\n    {\n        ClientId = request.ValidatedRequest.Client.ClientId;\n        ClientName = request.ValidatedRequest.Client.ClientName;\n        Endpoint = EndpointNames.Token;\n        SubjectId = request.ValidatedRequest.Subject?.GetSubjectId();\n        GrantType = request.ValidatedRequest.GrantType;\n\n        if (GrantType == OidcConstants.GrantTypes.RefreshToken)\n        {\n            Scopes = request.ValidatedRequest.RefreshToken.AccessToken.Scopes.ToSpaceSeparatedString();\n        }\n        else if (GrantType == OidcConstants.GrantTypes.AuthorizationCode)\n        {\n            Scopes = request.ValidatedRequest.AuthorizationCode.RequestedScopes.ToSpaceSeparatedString();\n        }\n        else\n        {\n            Scopes = request.ValidatedRequest.ValidatedResources?.RawScopeValues.ToSpaceSeparatedString();\n        }\n\n        var tokens = new List<Token>();\n        if (response.IdentityToken != null)\n        {\n            tokens.Add(new Token(OidcConstants.TokenTypes.IdentityToken, response.IdentityToken));\n        }\n        if (response.RefreshToken != null)\n        {\n            tokens.Add(new Token(OidcConstants.TokenTypes.RefreshToken, response.RefreshToken));\n        }\n        if (response.AccessToken != null)\n        {\n            tokens.Add(new Token(OidcConstants.TokenTypes.AccessToken, response.AccessToken));\n        }\n        Tokens = tokens;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenIssuedSuccessEvent\"/> class.\n    /// </summary>\n    protected TokenIssuedSuccessEvent()\n        : base(EventCategories.Token,\n              \"Token Issued Success\",\n              EventTypes.Success,\n              EventIds.TokenIssuedSuccess)\n    {\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the name of the client.\n    /// </summary>\n    /// <value>\n    /// The name of the client.\n    /// </value>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the redirect URI.\n    /// </summary>\n    /// <value>\n    /// The redirect URI.\n    /// </value>\n    public string RedirectUri { get; set; }\n\n    /// <summary>\n    /// Gets or sets the endpoint.\n    /// </summary>\n    /// <value>\n    /// The endpoint.\n    /// </value>\n    public string Endpoint { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public string Scopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the grant type.\n    /// </summary>\n    /// <value>\n    /// The grant type.\n    /// </value>\n    public string GrantType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the tokens.\n    /// </summary>\n    /// <value>\n    /// The tokens.\n    /// </value>\n    public IEnumerable<Token> Tokens { get; set; }\n\n    /// <summary>\n    /// Data structure serializing issued tokens\n    /// </summary>\n    public class Token\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"Token\"/> class.\n        /// </summary>\n        /// <param name=\"type\">The type.</param>\n        /// <param name=\"value\">The value.</param>\n        public Token(string type, string value)\n        {\n            TokenType = type;\n            TokenValue = Obfuscate(value);\n        }\n\n        /// <summary>\n        /// Gets the type of the token.\n        /// </summary>\n        /// <value>\n        /// The type of the token.\n        /// </value>\n        public string TokenType { get; }\n\n        /// <summary>\n        /// Gets the token value.\n        /// </summary>\n        /// <value>\n        /// The token value.\n        /// </value>\n        public string TokenValue { get; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/TokenRevokedSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for successful token revocation\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class TokenRevokedSuccessEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRevokedSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"requestResult\">The request result.</param>\n    /// <param name=\"client\">The client.</param>\n    public TokenRevokedSuccessEvent(TokenRevocationRequestValidationResult requestResult, Client client)\n        : base(EventCategories.Token,\n              \"Token Revoked Success\",\n              EventTypes.Success,\n              EventIds.TokenRevokedSuccess)\n    {\n        ClientId = client.ClientId;\n        ClientName = client.ClientName;\n        TokenType = requestResult.TokenTypeHint;\n        Token = Obfuscate(requestResult.Token);\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the name of the client.\n    /// </summary>\n    /// <value>\n    /// The name of the client.\n    /// </value>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the type of the token.\n    /// </summary>\n    /// <value>\n    /// The type of the token.\n    /// </value>\n    public string TokenType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the token.\n    /// </summary>\n    /// <value>\n    /// The token.\n    /// </value>\n    public string Token { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/UnhandledExceptionEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for unhandled exceptions\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class UnhandledExceptionEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UnhandledExceptionEvent\"/> class.\n    /// </summary>\n    /// <param name=\"ex\">The ex.</param>\n    public UnhandledExceptionEvent(Exception ex)\n        : base(EventCategories.Error,\n              \"Unhandled Exception\",\n              EventTypes.Error, \n              EventIds.UnhandledException,\n              ex.Message)\n    {\n        Details = ex.ToString();\n    }\n\n    /// <summary>\n    /// Gets or sets the details.\n    /// </summary>\n    /// <value>\n    /// The details.\n    /// </value>\n    public string Details { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/UserLoginFailureEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for failed user authentication\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class UserLoginFailureEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"T:IdentityServer8.Events.UserLoginFailureEvent\" /> class.\n    /// </summary>\n    /// <param name=\"username\">The username.</param>\n    /// <param name=\"error\">The error.</param>\n    /// <param name=\"interactive\">Specifies if login was interactive</param>\n    /// <param name=\"clientId\">The client id</param>\n    public UserLoginFailureEvent(string username, string error, bool interactive = true, string clientId = null)\n        : base(EventCategories.Authentication,\n              \"User Login Failure\",\n              EventTypes.Failure, \n              EventIds.UserLoginFailure,\n              error)\n    {\n        Username = username;\n        ClientId = clientId;\n\n        if (interactive)\n        {\n            Endpoint = \"UI\";\n        }\n        else\n        {\n            Endpoint = EndpointNames.Token;\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets the username.\n    /// </summary>\n    /// <value>\n    /// The username.\n    /// </value>\n    public string Username { get; set; }\n\n    /// <summary>\n    /// Gets or sets the endpoint.\n    /// </summary>\n    /// <value>\n    /// The endpoint.\n    /// </value>\n    public string Endpoint { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client id.\n    /// </summary>\n    /// <value>\n    /// The client id.\n    /// </value>\n    public string ClientId { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/UserLoginSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for successful user authentication\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class UserLoginSuccessEvent : Event\n{\n    // todo: consolidate ctors in 3.0\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UserLoginSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"provider\">The provider.</param>\n    /// <param name=\"providerUserId\">The provider user identifier.</param>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"interactive\">if set to <c>true</c> [interactive].</param>\n    /// <param name=\"clientId\">The client id.</param>\n    public UserLoginSuccessEvent(string provider, string providerUserId, string subjectId, string name, bool interactive = true, string clientId = null)\n        : this()\n    {\n        Provider = provider;\n        ProviderUserId = providerUserId;\n        SubjectId = subjectId;\n        DisplayName = name;\n        if (interactive)\n        {\n            Endpoint = \"UI\";\n        }\n        else\n        {\n            Endpoint = EndpointNames.Token;\n        }\n        ClientId = clientId;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UserLoginSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"username\">The username.</param>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"interactive\">if set to <c>true</c> [interactive].</param>\n    /// <param name=\"clientId\">The client id.</param>\n    public UserLoginSuccessEvent(string username, string subjectId, string name, bool interactive = true, string clientId = null)\n        : this()\n    {\n        Username = username;\n        SubjectId = subjectId;\n        DisplayName = name;\n        ClientId = clientId;\n\n        if (interactive)\n        {\n            Endpoint = \"UI\";\n        }\n        else\n        {\n            Endpoint = EndpointNames.Token;\n        }\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UserLoginSuccessEvent\"/> class.\n    /// </summary>\n    protected UserLoginSuccessEvent()\n        : base(EventCategories.Authentication,\n              \"User Login Success\",\n              EventTypes.Success,\n              EventIds.UserLoginSuccess)\n    {\n    }\n\n    /// <summary>\n    /// Gets or sets the username.\n    /// </summary>\n    /// <value>\n    /// The username.\n    /// </value>\n    public string Username { get; set; }\n\n    /// <summary>\n    /// Gets or sets the provider.\n    /// </summary>\n    /// <value>\n    /// The provider.\n    /// </value>\n    public string Provider { get; set; }\n\n    /// <summary>\n    /// Gets or sets the provider user identifier.\n    /// </summary>\n    /// <value>\n    /// The provider user identifier.\n    /// </value>\n    public string ProviderUserId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the display name.\n    /// </summary>\n    /// <value>\n    /// The display name.\n    /// </value>\n    public string DisplayName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the endpoint.\n    /// </summary>\n    /// <value>\n    /// The endpoint.\n    /// </value>\n    public string Endpoint { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the client id.\n    /// </summary>\n    /// <value>\n    /// The client id.\n    /// </value>\n    public string ClientId { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Events/UserLogoutSuccessEvent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// Event for successful user logout\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Events.Event\" />\npublic class UserLogoutSuccessEvent : Event\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UserLogoutSuccessEvent\"/> class.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"name\">The name.</param>\n    public UserLogoutSuccessEvent(string subjectId, string name)\n        : base(EventCategories.Authentication, \n              \"User Logout Success\",\n              EventTypes.Success, \n              EventIds.UserLogoutSuccess)\n    {\n        SubjectId = subjectId;\n        DisplayName = name;\n    }\n\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the display name.\n    /// </summary>\n    /// <value>\n    /// The display name.\n    /// </value>\n    public string DisplayName { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/AuthenticationPropertiesExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\n/// <summary>\n/// Extensions for AuthenticationProperties\n/// </summary>\npublic static class AuthenticationPropertiesExtensions\n{\n    internal const string SessionIdKey = \"session_id\";\n    internal const string ClientListKey = \"client_list\";\n\n    /// <summary>\n    /// Gets the user's session identifier.\n    /// </summary>\n    /// <param name=\"properties\"></param>\n    /// <returns></returns>\n    public static string GetSessionId(this AuthenticationProperties properties)\n    {\n        if (properties?.Items.ContainsKey(SessionIdKey) == true)\n        {\n            return properties.Items[SessionIdKey];\n        }\n\n        return null;\n    }\n\n    /// <summary>\n    /// Sets the user's session identifier.\n    /// </summary>\n    /// <param name=\"properties\"></param>\n    /// <param name=\"sid\">The session id</param>\n    /// <returns></returns>\n    public static void SetSessionId(this AuthenticationProperties properties, string sid)\n    {\n        properties.Items[SessionIdKey] = sid;\n    }\n\n    /// <summary>\n    /// Gets the list of client ids the user has signed into during their session.\n    /// </summary>\n    /// <param name=\"properties\"></param>\n    /// <returns></returns>\n    public static IEnumerable<string> GetClientList(this AuthenticationProperties properties)\n    {\n        if (properties?.Items.ContainsKey(ClientListKey) == true)\n        {\n            var value = properties.Items[ClientListKey];\n            return DecodeList(value);\n        }\n\n        return Enumerable.Empty<string>();\n    }\n\n    /// <summary>\n    /// Removes the list of client ids.\n    /// </summary>\n    /// <param name=\"properties\"></param>\n    public static void RemoveClientList(this AuthenticationProperties properties)\n    {\n        properties?.Items.Remove(ClientListKey);\n    }\n\n    /// <summary>\n    /// Adds a client to the list of clients the user has signed into during their session.\n    /// </summary>\n    /// <param name=\"properties\"></param>\n    /// <param name=\"clientId\"></param>\n    public static void AddClientId(this AuthenticationProperties properties, string clientId)\n    {\n        if (clientId == null) throw new ArgumentNullException(nameof(clientId));\n\n        var clients = properties.GetClientList();\n        if (!clients.Contains(clientId))\n        {\n            var update = clients.ToList();\n            update.Add(clientId);\n\n            var value = EncodeList(update);\n            if (value == null)\n            {\n                properties.Items.Remove(ClientListKey);\n            }\n            else\n            {\n                properties.Items[ClientListKey] = value;\n            }\n        }\n    }\n\n\n    private static IEnumerable<string> DecodeList(string value)\n    {\n        if (value.IsPresent())\n        {\n            var bytes = Base64Url.Decode(value);\n            value = Encoding.UTF8.GetString(bytes);\n            return ObjectSerializer.FromString<string[]>(value);\n        }\n\n        return Enumerable.Empty<string>();\n    }\n\n    private static string EncodeList(IEnumerable<string> list)\n    {\n        if (list != null && list.Any())\n        {\n            var value = ObjectSerializer.ToString(list);\n            var bytes = Encoding.UTF8.GetBytes(value);\n            value = Base64Url.Encode(bytes);\n            return value;\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/AuthorizeResponseExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\ninternal static class AuthorizeResponseExtensions\n{\n    public static NameValueCollection ToNameValueCollection(this AuthorizeResponse response)\n    {\n        var collection = new NameValueCollection();\n\n        if (response.IsError)\n        {\n            if (response.Error.IsPresent())\n            {\n                collection.Add(\"error\", response.Error);\n            }\n            if (response.ErrorDescription.IsPresent())\n            {\n                collection.Add(\"error_description\", response.ErrorDescription);\n            }\n        }\n        else\n        {\n            if (response.Code.IsPresent())\n            {\n                collection.Add(\"code\", response.Code);\n            }\n\n            if (response.IdentityToken.IsPresent())\n            {\n                collection.Add(\"id_token\", response.IdentityToken);\n            }\n\n            if (response.AccessToken.IsPresent())\n            {\n                collection.Add(\"access_token\", response.AccessToken);\n                collection.Add(\"token_type\", \"Bearer\");\n                collection.Add(\"expires_in\", response.AccessTokenLifetime.ToString());\n            }\n\n            if (response.Scope.IsPresent())\n            {\n                collection.Add(\"scope\", response.Scope);\n            }\n        }\n\n        if (response.State.IsPresent())\n        {\n            collection.Add(\"state\", response.State);\n        }\n        \n        if (response.SessionState.IsPresent())\n        {\n            collection.Add(\"session_state\", response.SessionState);\n        }\n\n        return collection;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/ClaimsExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\ninternal static class ClaimsExtensions\n{\n    public static Dictionary<string, object> ToClaimsDictionary(this IEnumerable<Claim> claims)\n    {\n        var d = new Dictionary<string, object>();\n\n        if (claims == null)\n        {\n            return d;\n        }\n\n        var distinctClaims = claims.Distinct(new ClaimComparer());\n\n        foreach (var claim in distinctClaims)\n        {\n            if (!d.ContainsKey(claim.Type))\n            {\n                d.Add(claim.Type, GetValue(claim));\n            }\n            else\n            {\n                var value = d[claim.Type];\n\n                if (value is List<object> list)\n                {\n                    list.Add(GetValue(claim));\n                }\n                else\n                {\n                    d.Remove(claim.Type);\n                    d.Add(claim.Type, new List<object> { value, GetValue(claim) });\n                }\n            }\n        }\n\n        return d;\n    }\n\n    private static object GetValue(Claim claim)\n    {\n        if (claim.ValueType == ClaimValueTypes.Integer ||\n            claim.ValueType == ClaimValueTypes.Integer32)\n        {\n            if (Int32.TryParse(claim.Value, out int value))\n            {\n                return value;\n            }\n        }\n\n        if (claim.ValueType == ClaimValueTypes.Integer64)\n        {\n            if (Int64.TryParse(claim.Value, out long value))\n            {\n                return value;\n            }\n        }\n\n        if (claim.ValueType == ClaimValueTypes.Boolean)\n        {\n            if (bool.TryParse(claim.Value, out bool value))\n            {\n                return value;\n            }\n        }\n\n        if (claim.ValueType == IdentityServerConstants.ClaimValueTypes.Json)\n        {\n            try\n            {\n                return System.Text.Json.JsonSerializer.Deserialize<JsonElement>(claim.Value);\n            }\n            catch { }\n        }\n\n        return claim.Value;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/ClientExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Extension methods for client.\n/// </summary>\npublic static class ClientExtensions\n{\n    /// <summary>\n    /// Returns true if the client is an implicit-only client.\n    /// </summary>\n    public static bool IsImplicitOnly(this Client client)\n    {\n        return client != null &&\n            client.AllowedGrantTypes != null &&\n            client.AllowedGrantTypes.Count == 1 &&\n            client.AllowedGrantTypes.First() == GrantType.Implicit;\n    }\n\n    /// <summary>\n    /// Constructs a list of SecurityKey from a Secret collection\n    /// </summary>\n    /// <param name=\"secrets\">The secrets</param>\n    /// <returns></returns>\n    public static Task<List<SecurityKey>> GetKeysAsync(this IEnumerable<Secret> secrets)\n    {\n        var secretList = secrets.ToList().AsReadOnly();\n        var keys = new List<SecurityKey>();\n\n        var certificates = GetCertificates(secretList)\n                            .Select(c => (SecurityKey)new X509SecurityKey(c))\n                            .ToList();\n        keys.AddRange(certificates);\n\n        var jwks = secretList\n                    .Where(s => s.Type == IdentityServerConstants.SecretTypes.JsonWebKey)\n                    .Select(s => new Microsoft.IdentityModel.Tokens.JsonWebKey(s.Value))\n                    .ToList();\n        keys.AddRange(jwks);\n\n        return Task.FromResult(keys);\n    }\n\n    private static List<X509Certificate2> GetCertificates(IEnumerable<Secret> secrets)\n    {\n        return secrets\n            .Where(s => s.Type == IdentityServerConstants.SecretTypes.X509CertificateBase64)\n            .Select(s => new X509Certificate2(Convert.FromBase64String(s.Value)))\n            .Where(c => c != null)\n            .ToList();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/DateTimeExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\ninternal static class DateTimeExtensions\n{\n    [DebuggerStepThrough]\n    public static bool HasExceeded(this DateTime creationTime, int seconds, DateTime now)\n    {\n        return (now > creationTime.AddSeconds(seconds));\n    }\n\n    [DebuggerStepThrough]\n    public static int GetLifetimeInSeconds(this DateTime creationTime, DateTime now)\n    {\n        return ((int)(now - creationTime).TotalSeconds);\n    }\n\n    [DebuggerStepThrough]\n    public static bool HasExpired(this DateTime? expirationTime, DateTime now)\n    {\n        if (expirationTime.HasValue &&\n            expirationTime.Value.HasExpired(now))\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    [DebuggerStepThrough]\n    public static bool HasExpired(this DateTime expirationTime, DateTime now)\n    {\n        if (now > expirationTime)\n        {\n            return true;\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/EndpointOptionsExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Endpoint = IdentityServer8.Hosting.Endpoint;\n\nnamespace IdentityServer8.Extensions;\n\ninternal static class EndpointOptionsExtensions\n{\n    public static bool IsEndpointEnabled(this EndpointsOptions options, Endpoint endpoint)\n    {\n        return endpoint?.Name switch\n        {\n            EndpointNames.Authorize => options.EnableAuthorizeEndpoint,\n            EndpointNames.CheckSession => options.EnableCheckSessionEndpoint,\n            EndpointNames.DeviceAuthorization => options.EnableDeviceAuthorizationEndpoint,\n            EndpointNames.Discovery => options.EnableDiscoveryEndpoint,\n            EndpointNames.EndSession => options.EnableEndSessionEndpoint,\n            EndpointNames.Introspection => options.EnableIntrospectionEndpoint,\n            EndpointNames.Revocation => options.EnableTokenRevocationEndpoint,\n            EndpointNames.Token => options.EnableTokenEndpoint,\n            EndpointNames.UserInfo => options.EnableUserInfoEndpoint,\n            _ => true\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/HashExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Extension methods for hashing strings\n/// </summary>\npublic static class HashExtensions\n{\n    /// <summary>\n    /// Creates a SHA256 hash of the specified input.\n    /// </summary>\n    /// <param name=\"input\">The input.</param>\n    /// <returns>A hash</returns>\n    public static string Sha256(this string input)\n    {\n        if (input.IsMissing()) return string.Empty;\n\n        using (var sha = SHA256.Create())\n        {\n            var bytes = Encoding.UTF8.GetBytes(input);\n            var hash = sha.ComputeHash(bytes);\n\n            return Convert.ToBase64String(hash);\n        }\n    }\n\n    /// <summary>\n    /// Creates a SHA256 hash of the specified input.\n    /// </summary>\n    /// <param name=\"input\">The input.</param>\n    /// <returns>A hash.</returns>\n    public static byte[] Sha256(this byte[] input)\n    {\n        if (input == null)\n        {\n            return null;\n        }\n\n        using (var sha = SHA256.Create())\n        {\n            return sha.ComputeHash(input);\n        }\n    }\n\n    /// <summary>\n    /// Creates a SHA512 hash of the specified input.\n    /// </summary>\n    /// <param name=\"input\">The input.</param>\n    /// <returns>A hash</returns>\n    public static string Sha512(this string input)\n    {\n        if (input.IsMissing()) return string.Empty;\n\n        using (var sha = SHA512.Create())\n        {\n            var bytes = Encoding.UTF8.GetBytes(input);\n            var hash = sha.ComputeHash(bytes);\n\n            return Convert.ToBase64String(hash);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/HttpContextAuthenticationExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.AspNetCore.Http;\n\n/// <summary>\n/// Extension methods for signin/out using the IdentityServer authentication scheme.\n/// </summary>\npublic static class AuthenticationManagerExtensions\n{\n    /// <summary>\n    /// Signs the user in.\n    /// </summary>\n    /// <param name=\"context\">The manager.</param>\n    /// <param name=\"user\">The IdentityServer user.</param>\n    /// <returns></returns>\n    public static async Task SignInAsync(this HttpContext context, IdentityServerUser user)\n    {\n        await context.SignInAsync(await context.GetCookieAuthenticationSchemeAsync(), user.CreatePrincipal());\n    }\n\n    /// <summary>\n    /// Signs the user in.\n    /// </summary>\n    /// <param name=\"context\">The manager.</param>\n    /// <param name=\"user\">The IdentityServer user.</param>\n    /// <param name=\"properties\">The authentication properties.</param>\n    /// <returns></returns>\n    public static async Task SignInAsync(this HttpContext context, IdentityServerUser user, AuthenticationProperties properties)\n    {\n        await context.SignInAsync(await context.GetCookieAuthenticationSchemeAsync(), user.CreatePrincipal(), properties);\n    }\n\n    internal static ISystemClock GetClock(this HttpContext context)\n    {\n        return context.RequestServices.GetRequiredService<ISystemClock>();\n    }\n\n    internal static async Task<string> GetCookieAuthenticationSchemeAsync(this HttpContext context)\n    {\n        var options = context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        if (options.Authentication.CookieAuthenticationScheme != null)\n        {\n            return options.Authentication.CookieAuthenticationScheme;\n        }\n\n        var schemes = context.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();\n        var scheme = await schemes.GetDefaultAuthenticateSchemeAsync();\n        if (scheme == null)\n        {\n            throw new InvalidOperationException(\"No DefaultAuthenticateScheme found or no CookieAuthenticationScheme configured on IdentityServerOptions.\");\n        }\n\n        return scheme.Name;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/HttpContextExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\n\nnamespace IdentityServer8.Extensions;\n\npublic static class HttpContextExtensions\n{\n    public static async Task<bool> GetSchemeSupportsSignOutAsync(this HttpContext context, string scheme)\n    {\n        var provider = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();\n        var handler = await provider.GetHandlerAsync(context, scheme);\n        return (handler is IAuthenticationSignOutHandler);\n    }\n\n    public static void SetIdentityServerOrigin(this HttpContext context, string value)\n    {\n        if (context == null) throw new ArgumentNullException(nameof(context));\n        if (value == null) throw new ArgumentNullException(nameof(value));\n\n        var split = value.Split(new[] { \"://\" }, StringSplitOptions.RemoveEmptyEntries);\n\n        var request = context.Request;\n        request.Scheme = split.First();\n        request.Host = new HostString(split.Last());\n    }\n\n    public static void SetIdentityServerBasePath(this HttpContext context, string value)\n    {\n        if (context == null) throw new ArgumentNullException(nameof(context));\n\n        context.Items[Constants.EnvironmentKeys.IdentityServerBasePath] = value;\n    }\n\n    public static string GetIdentityServerOrigin(this HttpContext context)\n    {\n        var options = context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        var request = context.Request;\n        \n        if (options.MutualTls.Enabled && options.MutualTls.DomainName.IsPresent())\n        {\n            if (!options.MutualTls.DomainName.Contains(\".\"))\n            {\n                if (request.Host.Value.StartsWith(options.MutualTls.DomainName, StringComparison.OrdinalIgnoreCase))\n                {\n                    return request.Scheme + \"://\" +\n                           request.Host.Value.Substring(options.MutualTls.DomainName.Length + 1);\n                }\n            }\n        }\n        \n        return request.Scheme + \"://\" + request.Host.Value;\n    }\n\n\n    internal static void SetSignOutCalled(this HttpContext context)\n    {\n        if (context == null) throw new ArgumentNullException(nameof(context));\n        context.Items[Constants.EnvironmentKeys.SignOutCalled] = \"true\";\n    }\n\n    internal static bool GetSignOutCalled(this HttpContext context)\n    {\n        return context.Items.ContainsKey(Constants.EnvironmentKeys.SignOutCalled);\n    }\n\n    /// <summary>\n    /// Gets the host name of IdentityServer.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public static string GetIdentityServerHost(this HttpContext context)\n    {\n        var request = context.Request;\n        return request.Scheme + \"://\" + request.Host.ToUriComponent();\n    }\n\n    /// <summary>\n    /// Gets the base path of IdentityServer.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public static string GetIdentityServerBasePath(this HttpContext context)\n    {\n        return context.Items[Constants.EnvironmentKeys.IdentityServerBasePath] as string;\n    }\n\n    /// <summary>\n    /// Gets the public base URL for IdentityServer.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public static string GetIdentityServerBaseUrl(this HttpContext context)\n    {\n        return context.GetIdentityServerHost() + context.GetIdentityServerBasePath();\n    }\n\n    /// <summary>\n    /// Gets the identity server relative URL.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"path\">The path.</param>\n    /// <returns></returns>\n    public static string GetIdentityServerRelativeUrl(this HttpContext context, string path)\n    {\n        if (!path.IsLocalUrl())\n        {\n            return null;\n        }\n\n        if (path.StartsWith(\"~/\")) path = path.Substring(1);\n        path = context.GetIdentityServerBaseUrl().EnsureTrailingSlash() + path.RemoveLeadingSlash();\n        return path;\n    }\n\n    /// <summary>\n    /// Gets the identity server issuer URI.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">context</exception>\n    public static string GetIdentityServerIssuerUri(this HttpContext context)\n    {\n        if (context == null) throw new ArgumentNullException(nameof(context));\n\n        // if they've explicitly configured a URI then use it,\n        // otherwise dynamically calculate it\n        var options = context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        var uri = options.IssuerUri;\n        if (uri.IsMissing())\n        {\n            uri = context.GetIdentityServerOrigin() + context.GetIdentityServerBasePath();\n            if (uri.EndsWith(\"/\")) uri = uri.Substring(0, uri.Length - 1);\n            if (options.LowerCaseIssuerUri)\n            {\n                uri = uri.ToLowerInvariant();\n            }\n        }\n\n        return uri;\n    }\n\n    internal static async Task<string> GetIdentityServerSignoutFrameCallbackUrlAsync(this HttpContext context, LogoutMessage logoutMessage = null)\n    {\n        var userSession = context.RequestServices.GetRequiredService<IUserSession>();\n        var user = await userSession.GetUserAsync();\n        var currentSubId = user?.GetSubjectId();\n\n        LogoutNotificationContext endSessionMsg = null;\n\n        // if we have a logout message, then that take precedence over the current user\n        if (logoutMessage?.ClientIds?.Any() == true)\n        {\n            var clientIds = logoutMessage?.ClientIds;\n\n            // check if current user is same, since we might have new clients (albeit unlikely)\n            if (currentSubId == logoutMessage?.SubjectId)\n            {\n                clientIds = clientIds.Union(await userSession.GetClientListAsync());\n                clientIds = clientIds.Distinct();\n            }\n\n            endSessionMsg = new LogoutNotificationContext\n            {\n                SubjectId = logoutMessage.SubjectId,\n                SessionId = logoutMessage.SessionId,\n                ClientIds = clientIds\n            };\n        }\n        else if (currentSubId != null)\n        {\n            // see if current user has any clients they need to signout of \n            var clientIds = await userSession.GetClientListAsync();\n            if (clientIds.Any())\n            {\n                endSessionMsg = new LogoutNotificationContext\n                {\n                    SubjectId = currentSubId,\n                    SessionId = await userSession.GetSessionIdAsync(),\n                    ClientIds = clientIds\n                };\n            }\n        }\n\n        if (endSessionMsg != null)\n        {\n            var clock = context.RequestServices.GetRequiredService<ISystemClock>();\n            var msg = new Message<LogoutNotificationContext>(endSessionMsg, clock.UtcNow.UtcDateTime);\n\n            var endSessionMessageStore = context.RequestServices.GetRequiredService<IMessageStore<LogoutNotificationContext>>();\n            var id = await endSessionMessageStore.WriteAsync(msg);\n\n            var signoutIframeUrl = context.GetIdentityServerBaseUrl().EnsureTrailingSlash() + Constants.ProtocolRoutePaths.EndSessionCallback;\n            signoutIframeUrl = signoutIframeUrl.AddQueryString(Constants.UIConstants.DefaultRoutePathParams.EndSessionCallback, id);\n\n            return signoutIframeUrl;\n        }\n\n        // no sessions, so nothing to cleanup\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/HttpRequestExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\n\nusing System.Net.Http.Headers;\n\nnamespace IdentityServer8.Extensions;\n\npublic static class HttpRequestExtensions\n{\n    public static string GetCorsOrigin(this HttpRequest request)\n    {\n        var origin = request.Headers[\"Origin\"].FirstOrDefault();\n        var thisOrigin = request.Scheme + \"://\" + request.Host;\n\n        // see if the Origin is different than this server's origin. if so\n        // that indicates a proper CORS request. some browsers send Origin\n        // on POST requests.\n        if (origin != null && origin != thisOrigin)\n        {\n            return origin;\n        }\n\n        return null;\n    }\n    \n    internal static bool HasApplicationFormContentType(this HttpRequest request)\n    {\n        if (request.ContentType is null) return false;\n        \n        if (MediaTypeHeaderValue.TryParse(request.ContentType, out var header))\n        {\n            // Content-Type: application/x-www-form-urlencoded; charset=utf-8\n            return header.MediaType.Equals(\"application/x-www-form-urlencoded\", StringComparison.OrdinalIgnoreCase);\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/HttpResponseExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\n\nnamespace IdentityServer8.Extensions;\n\npublic static class HttpResponseExtensions\n{\n    public static async Task WriteJsonAsync(this HttpResponse response, object o, string contentType = null)\n    {\n        var json = ObjectSerializer.ToString(o);\n        await response.WriteJsonAsync(json, contentType);\n        await response.Body.FlushAsync();\n    }\n\n    public static async Task WriteJsonAsync(this HttpResponse response, string json, string contentType = null)\n    {\n        response.ContentType = contentType ?? \"application/json; charset=UTF-8\";\n        await response.WriteAsync(json);\n        await response.Body.FlushAsync();\n    }\n\n    public static void SetCache(this HttpResponse response, int maxAge, params string[] varyBy)\n    {\n        if (maxAge == 0)\n        {\n            SetNoCache(response);\n        }\n        else if (maxAge > 0)\n        {\n            if (!response.Headers.ContainsKey(\"Cache-Control\"))\n            {\n                response.Headers.Append(\"Cache-Control\", $\"max-age={maxAge}\");\n            }\n\n            if (varyBy?.Any() == true)\n            {\n                var vary = varyBy.Aggregate((x, y) => x + \",\" + y);\n                if (response.Headers.ContainsKey(\"Vary\"))\n                {\n                    vary = response.Headers[\"Vary\"].ToString() + \",\" + vary;\n                }\n                response.Headers[\"Vary\"] = vary;\n            }\n        }\n    }\n\n    public static void SetNoCache(this HttpResponse response)\n    {\n        if (!response.Headers.ContainsKey(\"Cache-Control\"))\n        {\n            response.Headers.Append(\"Cache-Control\", \"no-store, no-cache, max-age=0\");\n        }\n        else\n        {\n            response.Headers[\"Cache-Control\"] = \"no-store, no-cache, max-age=0\";\n        }\n\n        if (!response.Headers.ContainsKey(\"Pragma\"))\n        {\n            response.Headers.Append(\"Pragma\", \"no-cache\");\n        }\n    }\n\n    public static async Task WriteHtmlAsync(this HttpResponse response, string html)\n    {\n        response.ContentType = \"text/html; charset=UTF-8\";\n        await response.WriteAsync(html, Encoding.UTF8);\n        await response.Body.FlushAsync();\n    }\n\n    public static void RedirectToAbsoluteUrl(this HttpResponse response, string url)\n    {\n        if (url.IsLocalUrl())\n        {\n            if (url.StartsWith(\"~/\")) url = url.Substring(1);\n            url = response.HttpContext.GetIdentityServerBaseUrl().EnsureTrailingSlash() + url.RemoveLeadingSlash();\n        }\n        response.RedirectIfAllowed(url);\n    }\n\n    public static void AddScriptCspHeaders(this HttpResponse response, CspOptions options, string hash)\n    {\n        var csp1part = options.Level == CspLevel.One ? \"'unsafe-inline' \" : string.Empty;\n        var cspHeader = $\"default-src 'none'; script-src {csp1part}'{hash}'\";\n\n        AddCspHeaders(response.Headers, options, cspHeader);\n    }\n\n    public static void AddStyleCspHeaders(this HttpResponse response, CspOptions options, string hash, string frameSources)\n    {\n        var csp1part = options.Level == CspLevel.One ? \"'unsafe-inline' \" : string.Empty;\n        var cspHeader = $\"default-src 'none'; style-src {csp1part}'{hash}'\";\n\n        if (!string.IsNullOrEmpty(frameSources))\n        {\n            cspHeader += $\"; frame-src {frameSources}\";\n        }\n\n        AddCspHeaders(response.Headers, options, cspHeader);\n    }\n\n    public static void AddCspHeaders(IHeaderDictionary headers, CspOptions options, string cspHeader)\n    {\n        if (!headers.ContainsKey(\"Content-Security-Policy\"))\n        {\n            headers.Append(\"Content-Security-Policy\", cspHeader);\n        }\n        if (options.AddDeprecatedHeader && !headers.ContainsKey(\"X-Content-Security-Policy\"))\n        {\n            headers.Append(\"X-Content-Security-Policy\", cspHeader);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/ICacheExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\n/// <summary>\n/// Extensions for ICache\n/// </summary>\npublic static class ICacheExtensions\n{\n    /// <summary>\n    /// Attempts to get an item from the cache. If the item is not found, the <c>get</c> function is used to\n    /// obtain the item and populate the cache.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"cache\">The cache.</param>\n    /// <param name=\"key\">The key.</param>\n    /// <param name=\"duration\">The duration.</param>\n    /// <param name=\"get\">The get function.</param>\n    /// <param name=\"logger\">The logger.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">cache\n    /// or\n    /// get</exception>\n    /// <exception cref=\"ArgumentNullException\">cache\n    /// or\n    /// get</exception>\n    public static async Task<T> GetAsync<T>(this ICache<T> cache, string key, TimeSpan duration, Func<Task<T>> get, ILogger logger)\n        where T : class\n    {\n        if (cache == null) throw new ArgumentNullException(nameof(cache));\n        if (get == null) throw new ArgumentNullException(nameof(get));\n        if (key == null) return null;\n\n        var item = await cache.GetAsync(key);\n\n        if (item == null)\n        {\n            logger.LogTrace(\"Cache miss for {cacheKey}\", Ioc.Sanitizer.Log.Sanitize(key));\n\n            item = await get();\n\n            if (item != null)\n            {\n                logger.LogTrace(\"Setting item in cache for {cacheKey}\", Ioc.Sanitizer.Log.Sanitize(key));\n                await cache.SetAsync(key, item, duration);\n            }\n        }\n        else\n        {\n            logger.LogTrace(\"Cache hit for {cacheKey}\", Ioc.Sanitizer.Log.Sanitize(key));\n        }\n\n        return item;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/IClientStoreExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Extension for IClientStore\n/// </summary>\npublic static class IClientStoreExtensions\n{\n    /// <summary>\n    /// Finds the enabled client by identifier.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    public static async Task<Client> FindEnabledClientByIdAsync(this IClientStore store, string clientId)\n    {\n        var client = await store.FindClientByIdAsync(clientId);\n        if (client != null && client.Enabled) return client;\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/IEnumerableExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Extensions;\n\npublic static class IEnumerableExtensions\n{\n    [DebuggerStepThrough]\n    public static bool EnumerableIsNullOrEmpty<T>(this IEnumerable<T> list)\n    {\n        if (list == null)\n        {\n            return true;\n        }\n\n        if (!list.Any())\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    public static bool HasDuplicates<T, TProp>(this IEnumerable<T> list, Func<T, TProp> selector)\n    {\n        var d = new HashSet<TProp>();\n        foreach (var t in list)\n        {\n            if (!d.Add(selector(t)))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/IReadableStringCollectionExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Extensions;\n\npublic static class IReadableStringCollectionExtensions\n{\n    [DebuggerStepThrough]\n    public static NameValueCollection AsNameValueCollection(this IEnumerable<KeyValuePair<string, StringValues>> collection)\n    {\n        var nv = new NameValueCollection();\n\n        foreach (var field in collection)\n        {\n            nv.Add(field.Key, field.Value.First());\n        }\n\n        return nv;\n    }\n\n    [DebuggerStepThrough]\n    public static NameValueCollection AsNameValueCollection(this IDictionary<string, StringValues> collection)\n    {\n        var nv = new NameValueCollection();\n\n        foreach (var field in collection)\n        {\n            nv.Add(field.Key, field.Value.First());\n        }\n\n        return nv;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/IResourceStoreExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Extensions for IResourceStore\n/// </summary>\npublic static class IResourceStoreExtensions\n{\n    /// <summary>\n    /// Finds the resources by scope.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"scopeNames\">The scope names.</param>\n    /// <returns></returns>\n    public static async Task<Resources> FindResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames)\n    {\n        var identity = await store.FindIdentityResourcesByScopeNameAsync(scopeNames);\n        var apiResources = await store.FindApiResourcesByScopeNameAsync(scopeNames);\n        var scopes = await store.FindApiScopesByNameAsync(scopeNames);\n\n        Validate(identity, apiResources, scopes);\n\n        var resources = new Resources(identity, apiResources, scopes)\n        {\n            OfflineAccess = scopeNames.Contains(IdentityServerConstants.StandardScopes.OfflineAccess)\n        };\n\n        return resources;\n    }\n\n    private static void Validate(IEnumerable<IdentityResource> identity, IEnumerable<ApiResource> apiResources, IEnumerable<ApiScope> apiScopes)\n    {\n        // attempt to detect invalid configuration. this is about the only place\n        // we can do this, since it's hard to get the values in the store.\n        var identityScopeNames = identity.Select(x => x.Name).ToArray();\n        var dups = GetDuplicates(identityScopeNames);\n        if (dups.Any())\n        {\n            var names = dups.Aggregate((x, y) => x + \", \" + y);\n            throw new Exception(\n                $\"Duplicate identity scopes found. This is an invalid configuration. Use different names for identity scopes. Scopes found: {names}\");\n        }\n\n        var apiNames = apiResources.Select(x => x.Name);\n        dups = GetDuplicates(apiNames);\n        if (dups.Any())\n        {\n            var names = dups.Aggregate((x, y) => x + \", \" + y);\n            throw new Exception(\n                $\"Duplicate api resources found. This is an invalid configuration. Use different names for API resources. Names found: {names}\");\n        }\n        \n        var scopesNames = apiScopes.Select(x => x.Name);\n        dups = GetDuplicates(scopesNames);\n        if (dups.Any())\n        {\n            var names = dups.Aggregate((x, y) => x + \", \" + y);\n            throw new Exception(\n                $\"Duplicate scopes found. This is an invalid configuration. Use different names for scopes. Names found: {names}\");\n        }\n\n        var overlap = identityScopeNames.Intersect(scopesNames).ToArray();\n        if (overlap.Any())\n        {\n            var names = overlap.Aggregate((x, y) => x + \", \" + y);\n            throw new Exception(\n                $\"Found identity scopes and API scopes that use the same names. This is an invalid configuration. Use different names for identity scopes and API scopes. Scopes found: {names}\");\n        }\n    }\n\n    private static IEnumerable<string> GetDuplicates(IEnumerable<string> names)\n    {\n        var duplicates = names\n                        .GroupBy(x => x)\n                        .Where(g => g.Count() > 1)\n                        .Select(y => y.Key)\n                        .ToArray();\n        return duplicates.ToArray();\n    }\n\n    /// <summary>\n    /// Finds the enabled resources by scope.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"scopeNames\">The scope names.</param>\n    /// <returns></returns>\n    public static async Task<Resources> FindEnabledResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames)\n    {\n        return (await store.FindResourcesByScopeAsync(scopeNames)).FilterEnabled();\n    }\n\n    /// <summary>\n    /// Creates a resource validation result.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"parsedScopesResult\">The parsed scopes.</param>\n    /// <returns></returns>\n    public static async Task<ResourceValidationResult> CreateResourceValidationResult(this IResourceStore store, ParsedScopesResult parsedScopesResult)\n    {\n        var validScopeValues = parsedScopesResult.ParsedScopes;\n        var scopes = validScopeValues.Select(x => x.ParsedName).ToArray();\n        var resources = await store.FindEnabledResourcesByScopeAsync(scopes);\n        return new ResourceValidationResult(resources, validScopeValues);\n    }\n\n    /// <summary>\n    /// Gets all enabled resources.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <returns></returns>\n    public static async Task<Resources> GetAllEnabledResourcesAsync(this IResourceStore store)\n    {\n        var resources = await store.GetAllResourcesAsync();\n        Validate(resources.IdentityResources, resources.ApiResources, resources.ApiScopes);\n\n        return resources.FilterEnabled();\n    }\n\n    /// <summary>\n    /// Finds the enabled identity resources by scope.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"scopeNames\">The scope names.</param>\n    /// <returns></returns>\n    public static async Task<IEnumerable<IdentityResource>> FindEnabledIdentityResourcesByScopeAsync(this IResourceStore store, IEnumerable<string> scopeNames)\n    {\n        return (await store.FindIdentityResourcesByScopeNameAsync(scopeNames)).Where(x => x.Enabled).ToArray();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/IUserSessionExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Extension for IUserSession.\n/// </summary>\npublic static class IUserSessionExtensions\n{\n    /// <summary>\n    /// Creates a LogoutNotificationContext for the current user session.\n    /// </summary>\n    /// <returns></returns>\n    public static async Task<LogoutNotificationContext> GetLogoutNotificationContext(this IUserSession session)\n    {\n        var clientIds = await session.GetClientListAsync();\n\n        if (clientIds.Any())\n        {\n            var user = await session.GetUserAsync();\n            var sub = user.GetSubjectId();\n            var sid = await session.GetSessionIdAsync();\n\n            return new LogoutNotificationContext\n            {\n                SubjectId = sub,\n                SessionId = sid,\n                ClientIds = clientIds\n            };\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/IdentityServerToolsExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8;\n\n/// <summary>\n/// Extensions for IdentityServerTools\n/// </summary>\npublic static class IdentityServerToolsExtensions\n{\n    /// <summary>\n    /// Issues the client JWT.\n    /// </summary>\n    /// <param name=\"tools\">The tools.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"lifetime\">The lifetime.</param>\n    /// <param name=\"scopes\">The scopes.</param>\n    /// <param name=\"audiences\">The audiences.</param>\n    /// <param name=\"additionalClaims\">Additional claims</param>\n    /// <returns></returns>\n    public static async Task<string> IssueClientJwtAsync(this IdentityServerTools tools,\n        string clientId,\n        int lifetime,\n        IEnumerable<string> scopes = null,\n        IEnumerable<string> audiences = null,\n        IEnumerable<Claim> additionalClaims = null)\n    {\n        var claims = new HashSet<Claim>(new ClaimComparer());\n        var context = tools.ContextAccessor.HttpContext;\n        var options = context.RequestServices.GetRequiredService<IdentityServerOptions>();\n        \n        if (additionalClaims != null)\n        {\n            foreach (var claim in additionalClaims)\n            {\n                claims.Add(claim);\n            }\n        }\n\n        claims.Add(new Claim(JwtClaimTypes.ClientId, clientId));\n\n        if (!scopes.EnumerableIsNullOrEmpty())\n        {\n            foreach (var scope in scopes)\n            {\n                claims.Add(new Claim(JwtClaimTypes.Scope, scope));\n            }\n        }\n\n        if (options.EmitStaticAudienceClaim)\n        {\n            claims.Add(new Claim(JwtClaimTypes.Audience, string.Format(IdentityServerConstants.AccessTokenAudience, tools.ContextAccessor.HttpContext.GetIdentityServerIssuerUri().EnsureTrailingSlash())));\n        }\n        \n        if (!audiences.EnumerableIsNullOrEmpty())\n        {\n            foreach (var audience in audiences)\n            {\n                claims.Add(new Claim(JwtClaimTypes.Audience, audience));\n            }\n        }\n\n        return await tools.IssueJwtAsync(lifetime, claims);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/JsonExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonSerializer = System.Text.Json.JsonSerializer;\n\nnamespace IdentityServer8.Extensions;\n\ninternal static partial class JsonExtensions\n{\n    [DebuggerStepThrough]\n    public static T ToObject<T>(this JsonElement element, JsonSerializerOptions options = null)\n    {\n        var bufferWriter = new ArrayBufferWriter<byte>();\n        using (var writer = new Utf8JsonWriter(bufferWriter))\n            element.WriteTo(writer);\n        return JsonSerializer.Deserialize<T>(bufferWriter.WrittenSpan, options);\n    }\n\n    [DebuggerStepThrough]\n    public static T ToObject<T>(this JsonDocument document, JsonSerializerOptions options = null)\n    {\n        if (document == null)\n            throw new ArgumentNullException(nameof(document));\n        return document.RootElement.ToObject<T>(options);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/NameValueCollectionExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\ninternal static class NameValueCollectionExtensions\n{\n    public static IDictionary<string, string[]> ToFullDictionary(this NameValueCollection source)\n    {\n        return source.AllKeys.ToDictionary(k => k, k => source.GetValues(k));\n    }\n\n    public static NameValueCollection FromFullDictionary(this IDictionary<string, string[]> source)\n    {\n        var nvc = new NameValueCollection();\n\n        foreach ((string key, string[] strings) in source)\n        {\n            foreach (var value in strings)\n            {\n                nvc.Add(key, value);\n            }\n        }\n\n        return nvc;\n    }\n    \n    public static string ToQueryString(this NameValueCollection collection)\n    {\n        if (collection.Count == 0)\n        {\n            return String.Empty;\n        }\n\n        var builder = new StringBuilder(128);\n        var first = true;\n        foreach (string name in collection)\n        {\n            var values = collection.GetValues(name);\n            if (values == null || values.Length == 0)\n            {\n                first = AppendNameValuePair(builder, first, true, name, String.Empty);\n            }\n            else\n            {\n                foreach (var value in values)\n                {\n                    first = AppendNameValuePair(builder, first, true, name, value);\n                }\n            }\n        }\n\n        return builder.ToString();\n    }\n\n    public static string ToFormPost(this NameValueCollection collection)\n    {\n        var builder = new StringBuilder(128);\n        const string inputFieldFormat = \"<input type='hidden' name='{0}' value='{1}' />\\n\";\n\n        foreach (string name in collection)\n        {\n            var values = collection.GetValues(name);\n            var value = values.First();\n            value = HtmlEncoder.Default.Encode(value);\n            builder.AppendFormat(inputFieldFormat, name, value);\n        }\n\n        return builder.ToString();\n    }\n\n    public static NameValueCollection ToNameValueCollection(this Dictionary<string, string> data)\n    {\n        var result = new NameValueCollection();\n\n        if (data == null || data.Count == 0)\n        {\n            return result;\n        }\n\n        foreach (var name in data.Keys)\n        {\n            var value = data[name];\n            if (value != null)\n            {\n                result.Add(name, value);\n            }\n        }\n\n        return result;\n    }\n\n    public static Dictionary<string, string> ToDictionary(this NameValueCollection collection)\n    {\n        return collection.ToScrubbedDictionary();\n    }\n\n    public static Dictionary<string, string> ToScrubbedDictionary(this NameValueCollection collection, params string[] nameFilter)\n    {\n        var dict = new Dictionary<string, string>();\n\n        if (collection == null || collection.Count == 0)\n        {\n            return dict;\n        }\n\n        foreach (string name in collection)\n        {\n            var value = collection.Get(name);\n            if (value != null)\n            {\n                if (nameFilter.Contains(name, StringComparer.OrdinalIgnoreCase))\n                {\n                    value = \"***REDACTED***\";\n                }\n                dict.Add(name, value);\n            }\n        }\n\n        return dict;\n    }\n\n    internal static string ConvertFormUrlEncodedSpacesToUrlEncodedSpaces(string str)\n    {\n        if ((str != null) && (str.IndexOf('+') >= 0))\n        {\n            str = str.Replace(\"+\", \"%20\");\n        }\n        return str;\n    }\n\n    private static bool AppendNameValuePair(StringBuilder builder, bool first, bool urlEncode, string name, string value)\n    {\n        var effectiveName = name ?? String.Empty;\n        var encodedName = urlEncode ? UrlEncoder.Default.Encode(effectiveName) : effectiveName;\n\n        var effectiveValue = value ?? String.Empty;\n        var encodedValue = urlEncode ? UrlEncoder.Default.Encode(effectiveValue) : effectiveValue;\n        encodedValue = ConvertFormUrlEncodedSpacesToUrlEncodedSpaces(encodedValue);\n\n        if (first)\n        {\n            first = false;\n        }\n        else\n        {\n            builder.Append(\"&\");\n        }\n\n        builder.Append(encodedName);\n        if (!String.IsNullOrEmpty(encodedValue))\n        {\n            builder.Append(\"=\");\n            builder.Append(encodedValue);\n        }\n        return first;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/PrincipalExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\n/// <summary>\n/// Extension methods for <see cref=\"System.Security.Principal.IPrincipal\"/> and <see cref=\"System.Security.Principal.IIdentity\"/> .\n/// </summary>\npublic static class PrincipalExtensions\n{\n    /// <summary>\n    /// Gets the authentication time.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static DateTime GetAuthenticationTime(this IPrincipal principal)\n    {\n        return DateTimeOffset.FromUnixTimeSeconds(principal.GetAuthenticationTimeEpoch()).UtcDateTime;\n    }\n\n    /// <summary>\n    /// Gets the authentication epoch time.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static long GetAuthenticationTimeEpoch(this IPrincipal principal)\n    {\n        return principal.Identity.GetAuthenticationTimeEpoch();\n    }\n\n    /// <summary>\n    /// Gets the authentication epoch time.\n    /// </summary>\n    /// <param name=\"identity\">The identity.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static long GetAuthenticationTimeEpoch(this IIdentity identity)\n    {\n        var id = identity as ClaimsIdentity;\n        var claim = id.FindFirst(JwtClaimTypes.AuthenticationTime);\n\n        if (claim == null) throw new InvalidOperationException(\"auth_time is missing.\");\n       \n        return long.Parse(claim.Value);\n    }\n\n    /// <summary>\n    /// Gets the subject identifier.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static string GetSubjectId(this IPrincipal principal)\n    {\n        return principal.Identity.GetSubjectId();\n    }\n\n    /// <summary>\n    /// Gets the subject identifier.\n    /// </summary>\n    /// <param name=\"identity\">The identity.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">sub claim is missing</exception>\n    [DebuggerStepThrough]\n    public static string GetSubjectId(this IIdentity identity)\n    {\n        var id = identity as ClaimsIdentity;\n        var claim = id.FindFirst(JwtClaimTypes.Subject);\n\n        if (claim == null) throw new InvalidOperationException(\"sub claim is missing\");\n        return claim.Value;\n    }\n\n    /// <summary>\n    /// Gets the name.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    [Obsolete(\"This method will be removed in a future version. Use GetDisplayName instead.\")]\n    public static string GetName(this IPrincipal principal)\n    {\n        return principal.Identity.GetName();\n    }\n\n    /// <summary>\n    /// Gets the name.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static string GetDisplayName(this ClaimsPrincipal principal)\n    {\n        var name = principal.Identity.Name;\n        if (name.IsPresent()) return name;\n\n        var sub = principal.FindFirst(JwtClaimTypes.Subject);\n        if (sub != null) return sub.Value;\n\n        return string.Empty;\n    }\n\n    /// <summary>\n    /// Gets the name.\n    /// </summary>\n    /// <param name=\"identity\">The identity.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">name claim is missing</exception>\n    [DebuggerStepThrough]\n    [Obsolete(\"This method will be removed in a future version. Use GetDisplayName instead.\")]\n    public static string GetName(this IIdentity identity)\n    {\n        var id = identity as ClaimsIdentity;\n        var claim = id.FindFirst(JwtClaimTypes.Name);\n\n        if (claim == null) throw new InvalidOperationException(\"name claim is missing\");\n        return claim.Value;\n    }\n\n    /// <summary>\n    /// Gets the authentication method.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static string GetAuthenticationMethod(this IPrincipal principal)\n    {\n        return principal.Identity.GetAuthenticationMethod();\n    }\n\n    /// <summary>\n    /// Gets the authentication method claims.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static IEnumerable<Claim> GetAuthenticationMethods(this IPrincipal principal)\n    {\n        return principal.Identity.GetAuthenticationMethods();\n    }\n\n    /// <summary>\n    /// Gets the authentication method.\n    /// </summary>\n    /// <param name=\"identity\">The identity.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">amr claim is missing</exception>\n    [DebuggerStepThrough]\n    public static string GetAuthenticationMethod(this IIdentity identity)\n    {\n        var id = identity as ClaimsIdentity;\n        var claim = id.FindFirst(JwtClaimTypes.AuthenticationMethod);\n\n        if (claim == null) throw new InvalidOperationException(\"amr claim is missing\");\n        return claim.Value;\n    }\n\n    /// <summary>\n    /// Gets the authentication method claims.\n    /// </summary>\n    /// <param name=\"identity\">The identity.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static IEnumerable<Claim> GetAuthenticationMethods(this IIdentity identity)\n    {\n        var id = identity as ClaimsIdentity;\n        return id.FindAll(JwtClaimTypes.AuthenticationMethod);\n    }\n\n    /// <summary>\n    /// Gets the identity provider.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns></returns>\n    [DebuggerStepThrough]\n    public static string GetIdentityProvider(this IPrincipal principal)\n    {\n        return principal.Identity.GetIdentityProvider();\n    }\n\n    /// <summary>\n    /// Gets the identity provider.\n    /// </summary>\n    /// <param name=\"identity\">The identity.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">idp claim is missing</exception>\n    [DebuggerStepThrough]\n    public static string GetIdentityProvider(this IIdentity identity)\n    {\n        var id = identity as ClaimsIdentity;\n        var claim = id.FindFirst(JwtClaimTypes.IdentityProvider);\n\n        if (claim == null) throw new InvalidOperationException(\"idp claim is missing\");\n        return claim.Value;\n    }\n\n    /// <summary>\n    /// Determines whether this instance is authenticated.\n    /// </summary>\n    /// <param name=\"principal\">The principal.</param>\n    /// <returns>\n    ///   <c>true</c> if the specified principal is authenticated; otherwise, <c>false</c>.\n    /// </returns>\n    [DebuggerStepThrough]\n    public static bool IsAuthenticated(this IPrincipal principal)\n    {\n        return principal != null && principal.Identity != null && principal.Identity.IsAuthenticated;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/ProfileDataRequestContextExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Extensions for ProfileDataRequestContext\n/// </summary>\npublic static class ProfileDataRequestContextExtensions\n{\n    /// <summary>\n    /// Filters the claims based on requested claim types.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"claims\">The claims.</param>\n    /// <returns></returns>\n    public static List<Claim> FilterClaims(this ProfileDataRequestContext context, IEnumerable<Claim> claims)\n    {\n        if (context == null) throw new ArgumentNullException(nameof(context));\n        if (claims == null) throw new ArgumentNullException(nameof(claims));\n\n        return claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToList();\n    }\n\n    /// <summary>\n    /// Filters the claims based on the requested claim types and then adds them to the IssuedClaims collection.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"claims\">The claims.</param>\n    public static void AddRequestedClaims(this ProfileDataRequestContext context, IEnumerable<Claim> claims)\n    {\n        if (context.RequestedClaimTypes.Any())\n        {\n            context.IssuedClaims.AddRange(context.FilterClaims(claims));\n        }\n    }\n\n    /// <summary>\n    /// Logs the profile request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public static void LogProfileRequest(this ProfileDataRequestContext context, ILogger logger)\n    {\n        logger.LogDebug(\"Get profile called for subject {subject} from client {client} with claim types {claimTypes} via {caller}\",\n            context.Subject.GetSubjectId(),\n            context.Client.ClientName ?? context.Client.ClientId,\n            context.RequestedClaimTypes,\n            context.Caller);\n    }\n\n    /// <summary>\n    /// Logs the issued claims.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public static void LogIssuedClaims(this ProfileDataRequestContext context, ILogger logger)\n    {\n        logger.LogDebug(\"Issued claims: {claims}\", context.IssuedClaims.Select(c => c.Type));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/ResourceExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Extensions for Resource\n/// </summary>\npublic static class ResourceExtensions\n{\n    /// <summary>\n    /// Returns the collection of scope values that are required.\n    /// </summary>\n    /// <param name=\"resourceValidationResult\"></param>\n    /// <returns></returns>\n    public static IEnumerable<string> GetRequiredScopeValues(this ResourceValidationResult resourceValidationResult)\n    {\n        var names = resourceValidationResult.Resources.IdentityResources.Where(x => x.Required).Select(x => x.Name).ToList();\n        names.AddRange(resourceValidationResult.Resources.ApiScopes.Where(x => x.Required).Select(x => x.Name));\n\n        var values = resourceValidationResult.ParsedScopes.Where(x => names.Contains(x.ParsedName)).Select(x => x.RawValue);\n        return values;\n    }\n\n    /// <summary>\n    /// Converts to scope names.\n    /// </summary>\n    /// <param name=\"resources\">The resources.</param>\n    /// <returns></returns>\n    public static IEnumerable<string> ToScopeNames(this Resources resources)\n    {\n        var names = resources.IdentityResources.Select(x => x.Name).ToList();\n        names.AddRange(resources.ApiScopes.Select(x => x.Name));\n        if (resources.OfflineAccess)\n        {\n            names.Add(IdentityServerConstants.StandardScopes.OfflineAccess);\n        }\n        \n        return names;\n    }\n\n    /// <summary>\n    /// Finds the IdentityResource that matches the scope.\n    /// </summary>\n    /// <param name=\"resources\">The resources.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <returns></returns>\n    public static IdentityResource FindIdentityResourcesByScope(this Resources resources, string name)\n    {\n        var q = from id in resources.IdentityResources\n                where id.Name == name\n                select id;\n        return q.FirstOrDefault();\n    }\n\n    /// <summary>\n    /// Finds the API resources that contain the scope.\n    /// </summary>\n    /// <param name=\"resources\">The resources.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <returns></returns>\n    public static IEnumerable<ApiResource> FindApiResourcesByScope(this Resources resources, string name)\n    {\n        var q = from api in resources.ApiResources\n                where api.Scopes != null && api.Scopes.Contains(name)\n                select api;\n        return q.ToArray();\n    }\n\n    /// <summary>\n    /// Finds the API scope.\n    /// </summary>\n    /// <param name=\"resources\">The resources.</param>\n    /// <param name=\"name\">The name.</param>\n    /// <returns></returns>\n    public static ApiScope FindApiScope(this Resources resources, string name)\n    {\n        var q = from scope in resources.ApiScopes\n                where scope.Name == name\n                select scope;\n        return q.FirstOrDefault();\n    }\n\n    internal static Resources FilterEnabled(this Resources resources)\n    {\n        if (resources == null) return new Resources();\n\n        return new Resources(\n            resources.IdentityResources.Where(x => x.Enabled),\n            resources.ApiResources.Where(x => x.Enabled),\n            resources.ApiScopes.Where(x => x.Enabled))\n        {\n            OfflineAccess = resources.OfflineAccess\n        };\n    }\n\n    internal static ICollection<string> FindMatchingSigningAlgorithms(this IEnumerable<ApiResource> apiResources)\n    {\n        var apis = apiResources.ToList();\n\n        if (apis.EnumerableIsNullOrEmpty())\n        {\n            return new List<string>();\n        }\n\n        // only one API resource request, forward the allowed signing algorithms (if any)\n        if (apis.Count == 1)\n        {\n            return apis.First().AllowedAccessTokenSigningAlgorithms;\n        }\n        \n        var allAlgorithms = apis.Where(r => r.AllowedAccessTokenSigningAlgorithms.Any()).Select(r => r.AllowedAccessTokenSigningAlgorithms).ToList();\n\n        // resources need to agree on allowed signing algorithms\n        if (allAlgorithms.Any())\n        {\n            var allowedAlgorithms = IntersectLists(allAlgorithms);\n\n            if (allowedAlgorithms.Any())\n            {\n                return allowedAlgorithms.ToHashSet();\n            }\n\n            throw new InvalidOperationException(\"Signing algorithms requirements for requested resources are not compatible.\");\n        }\n\n        return new List<string>();\n    }\n\n    private static IEnumerable<T> IntersectLists<T>(IEnumerable<IEnumerable<T>> lists)\n    {\n        return lists.Aggregate((l1, l2) => l1.Intersect(l2));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/ScopeExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\ninternal static class ScopeExtensions\n{\n    [DebuggerStepThrough]\n    public static string ToSpaceSeparatedString(this IEnumerable<ApiScope> apiScopes)\n    {\n        var scopeNames = from s in apiScopes\n                         select s.Name;\n\n        return string.Join(\" \", scopeNames.ToArray());\n    }\n\n    [DebuggerStepThrough]\n    public static IEnumerable<string> ToStringList(this IEnumerable<ApiScope> apiScopes)\n    {\n        var scopeNames = from s in apiScopes\n                         select s.Name;\n\n        return scopeNames;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/StringsExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\n\ninternal static class StringExtensions\n{\n    [DebuggerStepThrough]\n    public static string ToSpaceSeparatedString(this IEnumerable<string> list)\n    {\n        if (list == null)\n        {\n            return string.Empty;\n        }\n\n        var sb = new StringBuilder(100);\n\n        foreach (var element in list)\n        {\n            sb.Append(element + \" \");\n        }\n\n        return sb.ToString().Trim();\n    }\n\n    [DebuggerStepThrough]\n    public static IEnumerable<string> FromSpaceSeparatedString(this string input)\n    {\n        input = input.Trim();\n        return input.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();\n    }\n\n    public static List<string> ParseScopesString(this string scopes)\n    {\n        if (scopes.IsMissing())\n        {\n            return null;\n        }\n\n        scopes = scopes.Trim();\n        var parsedScopes = scopes.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToList();\n\n        if (parsedScopes.Any())\n        {\n            parsedScopes.Sort();\n            return parsedScopes;\n        }\n\n        return null;\n    }\n\n    [DebuggerStepThrough]\n    public static bool IsMissing(this string value)\n    {\n        return string.IsNullOrWhiteSpace(value);\n    }\n\n    [DebuggerStepThrough]\n    public static bool IsMissingOrTooLong(this string value, int maxLength)\n    {\n        if (string.IsNullOrWhiteSpace(value))\n        {\n            return true;\n        }\n        if (value.Length > maxLength)\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    [DebuggerStepThrough]\n    public static bool IsPresent(this string value)\n    {\n        return !string.IsNullOrWhiteSpace(value);\n    }\n\n    [DebuggerStepThrough]\n    public static string EnsureLeadingSlash(this string url)\n    {\n        if (url != null && !url.StartsWith(\"/\"))\n        {\n            return \"/\" + url;\n        }\n\n        return url;\n    }\n\n    [DebuggerStepThrough]\n    public static string EnsureTrailingSlash(this string url)\n    {\n        if (url != null && !url.EndsWith(\"/\"))\n        {\n            return url + \"/\";\n        }\n\n        return url;\n    }\n\n    [DebuggerStepThrough]\n    public static string RemoveLeadingSlash(this string url)\n    {\n        if (url != null && url.StartsWith(\"/\"))\n        {\n            url = url.Substring(1);\n        }\n\n        return url;\n    }\n\n    [DebuggerStepThrough]\n    public static string RemoveTrailingSlash(this string url)\n    {\n        if (url != null && url.EndsWith(\"/\"))\n        {\n            url = url.Substring(0, url.Length - 1);\n        }\n\n        return url;\n    }\n\n    [DebuggerStepThrough]\n    public static string CleanUrlPath(this string url)\n    {\n        if (String.IsNullOrWhiteSpace(url)) url = \"/\";\n\n        if (url != \"/\" && url.EndsWith(\"/\"))\n        {\n            url = url.Substring(0, url.Length - 1);\n        }\n\n        return url;\n    }\n\n    [DebuggerStepThrough]\n    public static bool IsLocalUrl(this string url)\n    {\n        if (string.IsNullOrEmpty(url))\n        {\n            return false;\n        }\n\n        // Allows \"/\" or \"/foo\" but not \"//\" or \"/\\\".\n        if (url[0] == '/')\n        {\n            // url is exactly \"/\"\n            if (url.Length == 1)\n            {\n                return true;\n            }\n\n            // url doesn't start with \"//\" or \"/\\\"\n            if (url[1] != '/' && url[1] != '\\\\')\n            {\n                return true;\n            }\n\n            return false;\n        }\n\n        // Allows \"~/\" or \"~/foo\" but not \"~//\" or \"~/\\\".\n        if (url[0] == '~' && url.Length > 1 && url[1] == '/')\n        {\n            // url is exactly \"~/\"\n            if (url.Length == 2)\n            {\n                return true;\n            }\n\n            // url doesn't start with \"~//\" or \"~/\\\"\n            if (url[2] != '/' && url[2] != '\\\\')\n            {\n                return true;\n            }\n\n            return false;\n        }\n\n        return false;\n    }\n\n    [DebuggerStepThrough]\n    public static string AddQueryString(this string url, string query)\n    {\n        if (!url.Contains(\"?\"))\n        {\n            url += \"?\";\n        }\n        else if (!url.EndsWith(\"&\"))\n        {\n            url += \"&\";\n        }\n\n        return url + query;\n    }\n\n    [DebuggerStepThrough]\n    public static string AddQueryString(this string url, string name, string value)\n    {\n        return url.AddQueryString(name + \"=\" + UrlEncoder.Default.Encode(value));\n    }\n\n    [DebuggerStepThrough]\n    public static string AddHashFragment(this string url, string query)\n    {\n        if (!url.Contains(\"#\"))\n        {\n            url += \"#\";\n        }\n\n        return url + query;\n    }\n\n    [DebuggerStepThrough]\n    public static NameValueCollection ReadQueryStringAsNameValueCollection(this string url)\n    {\n        if (url != null)\n        {\n            var idx = url.IndexOf('?');\n            if (idx >= 0)\n            {\n                url = url.Substring(idx + 1);\n            }\n            var query = QueryHelpers.ParseNullableQuery(url);\n            if (query != null)\n            {\n                return query.AsNameValueCollection();\n            }\n        }\n\n        return new NameValueCollection();\n    }\n\n    public static string GetOrigin(this string url)\n    {\n        if (url != null)\n        {\n            Uri uri;\n            try\n            {\n                uri = new Uri(url);\n            }\n            catch (Exception)\n            {\n                return null;\n            }\n\n            if (uri.Scheme == \"http\" || uri.Scheme == \"https\")\n            {\n                return $\"{uri.Scheme}://{uri.Authority}\";\n            }\n        }\n\n        return null;\n    }\n\n    public static string Obfuscate(this string value)\n    {\n        var last4Chars = \"****\";\n        if (value.IsPresent() && value.Length > 4)\n        {\n            last4Chars = value.Substring(value.Length - 4);\n        }\n\n        return \"****\" + last4Chars;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/TokenExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\n/// <summary>\n/// Extensions for Token\n/// </summary>\npublic static class TokenExtensions\n{\n    /// <summary>\n    /// Creates the default JWT payload.\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"options\">The options</param>\n    /// <param name=\"logger\">The logger.</param>\n    /// <returns></returns>\n    /// <exception cref=\"Exception\">\n    /// </exception>\n    public static JwtPayload CreateJwtPayload(this Token token, ISystemClock clock, IdentityServerOptions options, ILogger logger)\n    {\n        var payload = new JwtPayload(\n            token.Issuer,\n            null,\n            null,\n            clock.UtcNow.UtcDateTime,\n            clock.UtcNow.UtcDateTime.AddSeconds(token.Lifetime));\n\n        foreach (var aud in token.Audiences)\n        {\n            payload.AddClaim(new Claim(JwtClaimTypes.Audience, aud));\n        }\n\n        var amrClaims = token.Claims.Where(x => x.Type == JwtClaimTypes.AuthenticationMethod).ToArray();\n        var scopeClaims = token.Claims.Where(x => x.Type == JwtClaimTypes.Scope).ToArray();\n        var jsonClaims = token.Claims.Where(x => x.ValueType == IdentityServerConstants.ClaimValueTypes.Json).ToList();\n        \n        // add confirmation claim if present (it's JSON valued)\n        if (token.Confirmation.IsPresent())\n        {\n            jsonClaims.Add(new Claim(JwtClaimTypes.Confirmation, token.Confirmation, IdentityServerConstants.ClaimValueTypes.Json));\n        }\n\n        var normalClaims = token.Claims\n            .Except(amrClaims)\n            .Except(jsonClaims)\n            .Except(scopeClaims);\n\n        payload.AddClaims(normalClaims);\n\n        // scope claims\n        if (!scopeClaims.EnumerableIsNullOrEmpty())\n        {\n            var scopeValues = scopeClaims.Select(x => x.Value).ToArray();\n\n            if (options.EmitScopesAsSpaceDelimitedStringInJwt)\n            {\n                payload.Add(JwtClaimTypes.Scope, string.Join(\" \", scopeValues));\n            }\n            else\n            {\n                payload.Add(JwtClaimTypes.Scope, scopeValues);\n            }\n        }\n\n        // amr claims\n        if (!amrClaims.EnumerableIsNullOrEmpty())\n        {\n            var amrValues = amrClaims.Select(x => x.Value).Distinct().ToArray();\n            payload.Add(JwtClaimTypes.AuthenticationMethod, amrValues);\n        }\n        \n        // deal with json types\n        // calling ToArray() to trigger JSON parsing once and so later \n        // collection identity comparisons work for the anonymous type\n        try\n        {\n            var jsonTokens = jsonClaims.Select(x => new { x.Type, JsonValue = JRaw.Parse(x.Value) }).ToArray();\n\n            var jsonObjects = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Object).ToArray();\n            var jsonObjectGroups = jsonObjects.GroupBy(x => x.Type).ToArray();\n            foreach (var group in jsonObjectGroups)\n            {\n                if (payload.ContainsKey(group.Key))\n                {\n                    throw new Exception($\"Can't add two claims where one is a JSON object and the other is not a JSON object ({group.Key})\");\n                }\n\n                if (group.Skip(1).Any())\n                {\n                    // add as array\n                    payload.Add(group.Key, group.Select(x => x.JsonValue).ToArray());\n                }\n                else\n                {\n                    // add just one\n                    payload.Add(group.Key, group.First().JsonValue);\n                }\n            }\n\n            var jsonArrays = jsonTokens.Where(x => x.JsonValue.Type == JTokenType.Array).ToArray();\n            var jsonArrayGroups = jsonArrays.GroupBy(x => x.Type).ToArray();\n            foreach (var group in jsonArrayGroups)\n            {\n                if (payload.ContainsKey(group.Key))\n                {\n                    throw new Exception(\n                        $\"Can't add two claims where one is a JSON array and the other is not a JSON array ({group.Key})\");\n                }\n\n                var newArr = new List<JToken>();\n                foreach (var arrays in group)\n                {\n                    var arr = (JArray)arrays.JsonValue;\n                    newArr.AddRange(arr);\n                }\n\n                // add just one array for the group/key/claim type\n                payload.Add(group.Key, newArr.ToArray());\n            }\n\n            var unsupportedJsonTokens = jsonTokens.Except(jsonObjects).Except(jsonArrays).ToArray();\n            var unsupportedJsonClaimTypes = unsupportedJsonTokens.Select(x => x.Type).Distinct().ToArray();\n            if (unsupportedJsonClaimTypes.Any())\n            {\n                throw new Exception(\n                    $\"Unsupported JSON type for claim types: {unsupportedJsonClaimTypes.Aggregate((x, y) => x + \", \" + y)}\");\n            }\n\n            return payload;\n        }\n        catch (Exception ex)\n        {\n            logger.LogCritical(ex, \"Error creating a JSON valued claim\");\n            throw;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/ValidatedAuthorizeRequestExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Validation;\n\npublic static class ValidatedAuthorizeRequestExtensions\n{\n    public static void RemovePrompt(this ValidatedAuthorizeRequest request)\n    {\n        request.PromptModes = Enumerable.Empty<string>();\n        request.Raw.Remove(OidcConstants.AuthorizeRequest.Prompt);\n    }\n\n    public static string GetPrefixedAcrValue(this ValidatedAuthorizeRequest request, string prefix)\n    {\n        var value = request.AuthenticationContextReferenceClasses\n            .FirstOrDefault(x => x.StartsWith(prefix));\n\n        if (value != null)\n        {\n            value = value.Substring(prefix.Length);\n        }\n\n        return value;\n    }\n\n    public static void RemovePrefixedAcrValue(this ValidatedAuthorizeRequest request, string prefix)\n    {\n        request.AuthenticationContextReferenceClasses.RemoveAll(acr => acr.StartsWith(prefix, StringComparison.Ordinal));\n        var acr_values = request.AuthenticationContextReferenceClasses.ToSpaceSeparatedString();\n        if (acr_values.IsPresent())\n        {\n            request.Raw[OidcConstants.AuthorizeRequest.AcrValues] = acr_values;\n        }\n        else\n        {\n            request.Raw.Remove(OidcConstants.AuthorizeRequest.AcrValues);\n        }\n    }\n\n    public static string GetIdP(this ValidatedAuthorizeRequest request)\n    {\n        return request.GetPrefixedAcrValue(Constants.KnownAcrValues.HomeRealm);\n    }\n\n    public static void RemoveIdP(this ValidatedAuthorizeRequest request)\n    {\n        request.RemovePrefixedAcrValue(Constants.KnownAcrValues.HomeRealm);\n    }\n\n    public static string GetTenant(this ValidatedAuthorizeRequest request)\n    {\n        return request.GetPrefixedAcrValue(Constants.KnownAcrValues.Tenant);\n    }\n\n    public static IEnumerable<string> GetAcrValues(this ValidatedAuthorizeRequest request)\n    {\n        return request\n            .AuthenticationContextReferenceClasses\n            .Where(acr => !Constants.KnownAcrValues.All.Any(well_known => acr.StartsWith(well_known)))\n            .Distinct()\n            .ToArray();\n    }\n\n    public static void RemoveAcrValue(this ValidatedAuthorizeRequest request, string value)\n    {\n        request.AuthenticationContextReferenceClasses.RemoveAll(x => x.Equals(value, StringComparison.Ordinal));\n        var acr_values = request.AuthenticationContextReferenceClasses.ToSpaceSeparatedString();\n        if (acr_values.IsPresent())\n        {\n            request.Raw[OidcConstants.AuthorizeRequest.AcrValues] = acr_values;\n        }\n        else\n        {\n            request.Raw.Remove(OidcConstants.AuthorizeRequest.AcrValues);\n        }\n    }\n\n    public static void AddAcrValue(this ValidatedAuthorizeRequest request, string value)\n    {\n        if (String.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(nameof(value));\n\n        request.AuthenticationContextReferenceClasses.Add(value);\n        var acr_values = request.AuthenticationContextReferenceClasses.ToSpaceSeparatedString();\n        request.Raw[OidcConstants.AuthorizeRequest.AcrValues] = acr_values;\n    }\n\n    public static string GenerateSessionStateValue(this ValidatedAuthorizeRequest request)\n    {\n        if (request == null) return null;\n        if (!request.IsOpenIdRequest) return null;\n        \n        if (request.SessionId == null) return null;\n\n        if (request.ClientId.IsMissing()) return null;\n        if (request.RedirectUri.IsMissing()) return null;\n\n        var clientId = request.ClientId;\n        var sessionId = request.SessionId;\n        var salt = CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex);\n\n        var uri = new Uri(request.RedirectUri);\n        var origin = uri.Scheme + \"://\" + uri.Host;\n        if (!uri.IsDefaultPort)\n        {\n            origin += \":\" + uri.Port;\n        }\n\n        var bytes = Encoding.UTF8.GetBytes(clientId + origin + sessionId + salt);\n        byte[] hash;\n\n        using (var sha = SHA256.Create())\n        {\n            hash = sha.ComputeHash(bytes);\n        }\n\n        return Base64Url.Encode(hash) + \".\" + salt;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Extensions/X509CertificateExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonSerializer = System.Text.Json.JsonSerializer;\n\nnamespace IdentityServer8.Extensions;\n\n/// <summary>\n/// Extensions methods for X509Certificate2\n/// </summary>\npublic static class X509CertificateExtensions\n{\n    /// <summary>\n    /// Create the value of a thumbprint-based cnf claim\n    /// </summary>\n    /// <param name=\"certificate\"></param>\n    /// <returns></returns>\n    public static string CreateThumbprintCnf(this X509Certificate2 certificate)\n    {\n        var hash = certificate.GetCertHash(HashAlgorithmName.SHA256);\n                        \n        var values = new Dictionary<string, string>\n        {\n            { \"x5t#S256\", Base64Url.Encode(hash) }\n        };\n\n        return JsonSerializer.Serialize(values);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8;\nglobal using IdentityServer8.Configuration;\nglobal using IdentityServer8.Configuration.DependencyInjection;\nglobal using IdentityServer8.Endpoints;\nglobal using IdentityServer8.Endpoints.Results;\nglobal using IdentityServer8.Events;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Hosting;\nglobal using IdentityServer8.Hosting.FederatedSignOut;\nglobal using IdentityServer8.Hosting.LocalApiAuthentication;\nglobal using IdentityServer8.Infrastructure;\nglobal using IdentityServer8.Logging;\nglobal using IdentityServer8.Logging.Models;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.ResponseHandling;\nglobal using IdentityServer8.Services;\nglobal using IdentityServer8.Services.Default;\nglobal using IdentityServer8.Stores;\nglobal using IdentityServer8.Stores.Serialization;\nglobal using IdentityServer8.Test;\nglobal using IdentityServer8.Validation;\nglobal using Microsoft.AspNetCore.Authentication;\nglobal using Microsoft.AspNetCore.Authentication.Cookies;\nglobal using Microsoft.AspNetCore.Authentication.OpenIdConnect;\nglobal using Microsoft.AspNetCore.Builder;\nglobal using Microsoft.AspNetCore.Cors.Infrastructure;\n//global using Microsoft.AspNetCore.DataProtection;\nglobal using Microsoft.AspNetCore.Http;\nglobal using Microsoft.AspNetCore.WebUtilities;\nglobal using Microsoft.Extensions.Caching.Distributed;\nglobal using Microsoft.Extensions.Caching.Memory;\nglobal using Microsoft.Extensions.Configuration;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.DependencyInjection.Extensions;\nglobal using Microsoft.Extensions.Logging;\nglobal using Microsoft.Extensions.Options;\nglobal using Microsoft.Extensions.Primitives;\n//global using Microsoft.IdentityModel.Tokens;\n//global using Microsoft.Net.Http.Headers;\nglobal using Newtonsoft.Json;\nglobal using Newtonsoft.Json.Linq;\nglobal using System.Buffers;\nglobal using System.Collections.Concurrent;\nglobal using System.Collections.Specialized;\nglobal using System.Diagnostics;\nglobal using System.Globalization;\nglobal using System.IdentityModel.Tokens.Jwt;\nglobal using System.Net;\nglobal using System.Reflection;\nglobal using System.Runtime.CompilerServices;\nglobal using System.Security.Claims;\nglobal using System.Security.Cryptography;\nglobal using System.Security.Cryptography.X509Certificates;\nglobal using System.Security.Principal;\nglobal using System.Text;\nglobal using System.Text.Encodings.Web;\nglobal using System.Text.Json;\nglobal using System.Text.Json.Serialization;\nglobal using static IdentityServer8.Constants;\nglobal using static IdentityServer8.IdentityServerConstants;\nglobal using ClaimValueTypes = System.Security.Claims.ClaimValueTypes;\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/BaseUrlMiddleware.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Hosting;\n\npublic class BaseUrlMiddleware\n{\n    private readonly RequestDelegate _next;\n    private readonly IdentityServerOptions _options;\n\n    public BaseUrlMiddleware(RequestDelegate next, IdentityServerOptions options)\n    {\n        _next = next;\n        _options = options;\n    }\n\n    public async Task Invoke(HttpContext context)\n    {\n        var request = context.Request;\n        \n        context.SetIdentityServerBasePath(request.PathBase.Value.RemoveTrailingSlash());\n\n        await _next(context);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/CorsMiddleware.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Hosting;\n\npublic static class CorsMiddlewareExtensions\n{\n    public static void ConfigureCors(this IApplicationBuilder app)\n    {\n        var options = app.ApplicationServices.GetRequiredService<IdentityServerOptions>();\n        app.UseCors(options.Cors.CorsPolicyName);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/CorsPolicyProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\ninternal class CorsPolicyProvider : ICorsPolicyProvider\n{\n    private readonly ILogger _logger;\n    private readonly ICorsPolicyProvider _inner;\n    private readonly IdentityServerOptions _options;\n    private readonly IHttpContextAccessor _httpContext;\n\n    public CorsPolicyProvider(\n        ILogger<CorsPolicyProvider> logger,\n        Decorator<ICorsPolicyProvider> inner,\n        IdentityServerOptions options,\n        IHttpContextAccessor httpContext)\n    {\n        _logger = logger;\n        _inner = inner.Instance;\n        _options = options;\n        _httpContext = httpContext;\n    }\n\n    public Task<CorsPolicy> GetPolicyAsync(HttpContext context, string policyName)\n    {\n        if (_options.Cors.CorsPolicyName == policyName)\n        {\n            return ProcessAsync(context);\n        }\n        else\n        {\n            return _inner.GetPolicyAsync(context, policyName);\n        }\n    }\n    private async Task<CorsPolicy> ProcessAsync(HttpContext context)\n    {\n        var origin = context.Request.GetCorsOrigin();\n        if (origin != null)\n        {\n            var path = context.Request.Path;\n            if (IsPathAllowed(path))\n            {\n                var sanitizedOrigin = origin.SanitizeForLog();\n                _logger.LogDebug(\"CORS request made for path: {path} from origin: {origin}\", path.SanitizeForLog(), sanitizedOrigin);\n\n                // manually resolving this from DI because this: \n                // https://github.com/aspnet/CORS/issues/105\n                var corsPolicyService = _httpContext.HttpContext.RequestServices.GetRequiredService<ICorsPolicyService>();\n\n                if (await corsPolicyService.IsOriginAllowedAsync(origin))\n                {\n                    _logger.LogDebug(\"CorsPolicyService allowed origin: {origin}\", sanitizedOrigin);\n                    return Allow(origin);\n                }\n                else\n                {\n                    _logger.LogWarning(\"CorsPolicyService did not allow origin: {origin}\", sanitizedOrigin);\n                }\n            }\n            else\n            {\n                _logger.LogDebug(\"CORS request made for path: {path} from origin: {origin} but was ignored because path was not for an allowed IdentityServer CORS endpoint\", Ioc.Sanitizer.Log.Sanitize(path), Ioc.Sanitizer.Log.Sanitize(origin));\n            }\n        }\n\n        return null;\n    }\n\n    private CorsPolicy Allow(string origin)\n    {\n        var policyBuilder = new CorsPolicyBuilder()\n            .WithOrigins(origin)\n            .AllowAnyHeader()\n            .AllowAnyMethod();\n\n        if (_options.Cors.PreflightCacheDuration.HasValue)\n        {\n            policyBuilder.SetPreflightMaxAge(_options.Cors.PreflightCacheDuration.Value);\n        }\n\n        return policyBuilder.Build();\n    }\n\n    private bool IsPathAllowed(PathString path)\n    {\n        return _options.Cors.CorsPaths.Any(x => path == x);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/Endpoint.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\n\nnamespace IdentityServer8.Hosting;\n\npublic class Endpoint\n{\n    public Endpoint(string name, string path, Type handlerType)\n    {\n        Name = name;\n        Path = path;\n        Handler = handlerType;\n    }\n\n    /// <summary>\n    /// Gets or sets the name.\n    /// </summary>\n    /// <value>\n    /// The name.\n    /// </value>\n    public string Name { get; set; }\n\n    /// <summary>\n    /// Gets or sets the path.\n    /// </summary>\n    /// <value>\n    /// The path.\n    /// </value>\n    public PathString Path { get; set; }\n\n    /// <summary>\n    /// Gets or sets the handler.\n    /// </summary>\n    /// <value>\n    /// The handler.\n    /// </value>\n    public Type Handler { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/EndpointRouter.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\ninternal class EndpointRouter : IEndpointRouter\n{\n    private readonly IEnumerable<Endpoint> _endpoints;\n    private readonly IdentityServerOptions _options;\n    private readonly ILogger _logger;\n\n    public EndpointRouter(IEnumerable<Endpoint> endpoints, IdentityServerOptions options, ILogger<EndpointRouter> logger)\n    {\n        _endpoints = endpoints;\n        _options = options;\n        _logger = logger;\n    }\n\n    public IEndpointHandler Find(HttpContext context)\n    {\n        if (context == null) throw new ArgumentNullException(nameof(context));\n\n        foreach(var endpoint in _endpoints)\n        {\n            var path = endpoint.Path;\n            if (context.Request.Path.Equals(path, StringComparison.OrdinalIgnoreCase))\n            {\n                var endpointName = endpoint.Name;\n                _logger.LogDebug(\"Request path {path} matched to endpoint type {endpoint}\", Ioc.Sanitizer.Log.Sanitize(context.Request.Path), endpointName);\n\n                return GetEndpointHandler(endpoint, context);\n            }\n        }\n\n        _logger.LogTrace(\"No endpoint entry found for request path: {path}\", Ioc.Sanitizer.Log.Sanitize(context.Request.Path));\n\n        return null;\n    }\n\n    private IEndpointHandler GetEndpointHandler(Endpoint endpoint, HttpContext context)\n    {\n        if (_options.Endpoints.IsEndpointEnabled(endpoint))\n        {\n            if (context.RequestServices.GetService(endpoint.Handler) is IEndpointHandler handler)\n            {\n                _logger.LogDebug(\"Endpoint enabled: {endpoint}, successfully created handler: {endpointHandler}\", endpoint.Name, endpoint.Handler.FullName);\n                return handler;\n            }\n\n            _logger.LogDebug(\"Endpoint enabled: {endpoint}, failed to create handler: {endpointHandler}\", endpoint.Name, endpoint.Handler.FullName);\n        }\n        else\n        {\n            _logger.LogWarning(\"Endpoint disabled: {endpoint}\", endpoint.Name);\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/FederatedSignOut/AuthenticationRequestHandlerWrapper.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting.FederatedSignOut;\n\ninternal class AuthenticationRequestHandlerWrapper : IAuthenticationRequestHandler\n{\n    private const string IframeHtml = \"<iframe style='display:none' width='0' height='0' src='{0}'></iframe>\";\n\n    private readonly IAuthenticationRequestHandler _inner;\n    private readonly HttpContext _context;\n    private readonly ILogger _logger;\n\n    public AuthenticationRequestHandlerWrapper(IAuthenticationRequestHandler inner, IHttpContextAccessor httpContextAccessor)\n    {\n        _inner = inner;\n        _context = httpContextAccessor.HttpContext;\n\n        var factory = (ILoggerFactory)_context.RequestServices.GetService(typeof(ILoggerFactory));\n        _logger = factory?.CreateLogger(GetType());\n    }\n\n    public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)\n    {\n        return _inner.InitializeAsync(scheme, context);\n    }\n\n    public async Task<bool> HandleRequestAsync()\n    {\n        var result = await _inner.HandleRequestAsync();\n\n        if (result && _context.GetSignOutCalled() && _context.Response.StatusCode == 200)\n        {\n            // given that this runs prior to the authentication middleware running\n            // we need to explicitly trigger authentication so we can have our \n            // session service populated with the current user info\n            await _context.AuthenticateAsync();\n\n            // now we can do our processing to render the iframe (if needed)\n            await ProcessFederatedSignOutRequestAsync();\n        }\n\n        return result;\n    }\n\n    public Task<AuthenticateResult> AuthenticateAsync()\n    {\n        return _inner.AuthenticateAsync();\n    }\n\n    public Task ChallengeAsync(AuthenticationProperties properties)\n    {\n        return _inner.ChallengeAsync(properties);\n    }\n\n    public Task ForbidAsync(AuthenticationProperties properties)\n    {\n        return _inner.ForbidAsync(properties);\n    }\n\n    private async Task ProcessFederatedSignOutRequestAsync()\n    {\n        _logger?.LogDebug(\"Processing federated signout\");\n\n        var iframeUrl = await _context.GetIdentityServerSignoutFrameCallbackUrlAsync();\n        if (iframeUrl != null)\n        {\n            _logger?.LogDebug(\"Rendering signout callback iframe\");\n            await RenderResponseAsync(iframeUrl);\n        }\n        else\n        {\n            _logger?.LogDebug(\"No signout callback iframe to render\");\n        }\n    }\n\n    private async Task RenderResponseAsync(string iframeUrl)\n    {\n        _context.Response.SetNoCache();\n\n        if (_context.Response.Body.CanWrite)\n        {\n            var iframe = String.Format(IframeHtml, iframeUrl);\n            _context.Response.ContentType = \"text/html\";\n            await _context.Response.WriteAsync(iframe);\n            await _context.Response.Body.FlushAsync();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/FederatedSignOut/AuthenticationRequestSignInHandlerWrapper.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting.FederatedSignOut;\n\ninternal class AuthenticationRequestSignInHandlerWrapper : AuthenticationRequestSignOutHandlerWrapper, IAuthenticationSignInHandler\n{\n    private readonly IAuthenticationSignInHandler _inner;\n\n    public AuthenticationRequestSignInHandlerWrapper(IAuthenticationSignInHandler inner, IHttpContextAccessor httpContextAccessor)\n        : base(inner, httpContextAccessor)\n    {\n        _inner = inner;\n    }\n\n    public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)\n    {\n        return _inner.SignInAsync(user, properties);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/FederatedSignOut/AuthenticationRequestSignOutHandlerWrapper.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting.FederatedSignOut;\n\ninternal class AuthenticationRequestSignOutHandlerWrapper : AuthenticationRequestHandlerWrapper, IAuthenticationSignOutHandler\n{\n    private readonly IAuthenticationSignOutHandler _inner;\n\n    public AuthenticationRequestSignOutHandlerWrapper(IAuthenticationSignOutHandler inner, IHttpContextAccessor httpContextAccessor)\n        : base((IAuthenticationRequestHandler)inner, httpContextAccessor)\n    {\n        _inner = inner;\n    }\n\n    public Task SignOutAsync(AuthenticationProperties properties)\n    {\n        return _inner.SignOutAsync(properties);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/FederatedSignOut/FederatedSignoutAuthenticationHandlerProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting.FederatedSignOut;\n\n// this intercepts IAuthenticationRequestHandler authentication handlers\n// to detect when they are handling federated signout. when they are invoked,\n// call signout on the default authentication scheme, and return 200 then \n// we assume they are handling the federated signout in an iframe. \n// based on this assumption, we then render our federated signout iframes \n// to any current clients.\ninternal class FederatedSignoutAuthenticationHandlerProvider : IAuthenticationHandlerProvider\n{\n    private readonly IAuthenticationHandlerProvider _provider;\n    private readonly IHttpContextAccessor _httpContextAccessor;\n\n    public FederatedSignoutAuthenticationHandlerProvider(\n        Decorator<IAuthenticationHandlerProvider> decorator, \n        IHttpContextAccessor httpContextAccessor)\n    {\n        _provider = decorator.Instance;\n        _httpContextAccessor = httpContextAccessor;\n    }\n\n    public async Task<IAuthenticationHandler> GetHandlerAsync(HttpContext context, string authenticationScheme)\n    {\n        var handler = await _provider.GetHandlerAsync(context, authenticationScheme);\n        if (handler is IAuthenticationRequestHandler requestHandler)\n        {\n            if (requestHandler is IAuthenticationSignInHandler signinHandler)\n            {\n                return new AuthenticationRequestSignInHandlerWrapper(signinHandler, _httpContextAccessor);\n            }\n\n            if (requestHandler is IAuthenticationSignOutHandler signoutHandler)\n            {\n                return new AuthenticationRequestSignOutHandlerWrapper(signoutHandler, _httpContextAccessor);\n            }\n\n            return new AuthenticationRequestHandlerWrapper(requestHandler, _httpContextAccessor);\n        }\n\n        return handler;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/IEndpointHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\n/// <summary>\n/// Endpoint handler\n/// </summary>\npublic interface IEndpointHandler\n{\n    /// <summary>\n    /// Processes the request.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    Task<IEndpointResult> ProcessAsync(HttpContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/IEndpointResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\n/// <summary>\n/// Endpoint result\n/// </summary>\npublic interface IEndpointResult\n{\n    /// <summary>\n    /// Executes the result.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    Task ExecuteAsync(HttpContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/IEndpointRouter.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\n/// <summary>\n/// The endpoint router\n/// </summary>\npublic interface IEndpointRouter\n{\n    /// <summary>\n    /// Finds a matching endpoint.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    IEndpointHandler Find(HttpContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/IdentityServerAuthenticationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\n// this decorates the real authentication service to detect when the \n// user is being signed in. this allows us to ensure the user has\n// the claims needed for identity server to do its job. it also allows\n// us to track signin/signout so we can issue/remove the session id\n// cookie used for check session iframe for session management spec.\n// finally, we track if signout is called to collaborate with the \n// FederatedSignoutAuthenticationHandlerProvider for federated signout.\ninternal class IdentityServerAuthenticationService : IAuthenticationService\n{\n    private readonly IAuthenticationService _inner;\n    private readonly IAuthenticationSchemeProvider _schemes;\n    private readonly ISystemClock _clock;\n    private readonly IUserSession _session;\n    private readonly IBackChannelLogoutService _backChannelLogoutService;\n    private readonly IdentityServerOptions _options;\n    private readonly ILogger<IdentityServerAuthenticationService> _logger;\n\n    public IdentityServerAuthenticationService(\n        Decorator<IAuthenticationService> decorator,\n        IAuthenticationSchemeProvider schemes,\n        ISystemClock clock,\n        IUserSession session,\n        IBackChannelLogoutService backChannelLogoutService,\n        IdentityServerOptions options,\n        ILogger<IdentityServerAuthenticationService> logger)\n    {\n        _inner = decorator.Instance;\n        \n        _schemes = schemes;\n        _clock = clock;\n        _session = session;\n        _backChannelLogoutService = backChannelLogoutService;\n        _options = options;\n        _logger = logger;\n    }\n\n    public async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)\n    {\n        var defaultScheme = await _schemes.GetDefaultSignInSchemeAsync();\n        var cookieScheme = await context.GetCookieAuthenticationSchemeAsync();\n\n        if ((scheme == null && defaultScheme?.Name == cookieScheme) || scheme == cookieScheme)\n        {\n            AugmentPrincipal(principal);\n\n            properties ??= new AuthenticationProperties();\n            await _session.CreateSessionIdAsync(principal, properties);\n        }\n\n        await _inner.SignInAsync(context, scheme, principal, properties);\n    }\n\n    private void AugmentPrincipal(ClaimsPrincipal principal)\n    {\n        _logger.LogDebug(\"Augmenting SignInContext\");\n\n        AssertRequiredClaims(principal);\n        AugmentMissingClaims(principal, _clock.UtcNow.UtcDateTime);\n    }\n\n    public async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties)\n    {\n        var defaultScheme = await _schemes.GetDefaultSignOutSchemeAsync();\n        var cookieScheme = await context.GetCookieAuthenticationSchemeAsync();\n\n        if ((scheme == null && defaultScheme?.Name == cookieScheme) || scheme == cookieScheme)\n        {\n            // this sets a flag used by middleware to do post-signout work.\n            context.SetSignOutCalled();\n        }\n\n        await _inner.SignOutAsync(context, scheme, properties);\n    }\n\n    public Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme)\n    {\n        return _inner.AuthenticateAsync(context, scheme);\n    }\n\n    public Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)\n    {\n        return _inner.ChallengeAsync(context, scheme, properties);\n    }\n\n    public Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties)\n    {\n        return _inner.ForbidAsync(context, scheme, properties);\n    }\n\n    private void AssertRequiredClaims(ClaimsPrincipal principal)\n    {\n        // for now, we don't allow more than one identity in the principal/cookie\n        if (principal.Identities.Count() != 1) throw new InvalidOperationException(\"only a single identity supported\");\n        if (principal.FindFirst(JwtClaimTypes.Subject) == null) throw new InvalidOperationException(\"sub claim is missing\");\n    }\n\n    private void AugmentMissingClaims(ClaimsPrincipal principal, DateTime authTime)\n    {\n        var identity = principal.Identities.First();\n\n        // ASP.NET Identity issues this claim type and uses the authentication middleware name\n        // such as \"Google\" for the value. this code is trying to correct/convert that for\n        // our scenario. IOW, we take their old AuthenticationMethod value of \"Google\"\n        // and issue it as the idp claim. we then also issue a amr with \"external\"\n        var amr = identity.FindFirst(ClaimTypes.AuthenticationMethod);\n        if (amr != null &&\n            identity.FindFirst(JwtClaimTypes.IdentityProvider) == null &&\n            identity.FindFirst(JwtClaimTypes.AuthenticationMethod) == null)\n        {\n            _logger.LogDebug(\"Removing amr claim with value: {value}\", amr.Value);\n            identity.RemoveClaim(amr);\n\n            _logger.LogDebug(\"Adding idp claim with value: {value}\", amr.Value);\n            identity.AddClaim(new Claim(JwtClaimTypes.IdentityProvider, amr.Value));\n\n            _logger.LogDebug(\"Adding amr claim with value: {value}\", Constants.ExternalAuthenticationMethod);\n            identity.AddClaim(new Claim(JwtClaimTypes.AuthenticationMethod, Constants.ExternalAuthenticationMethod));\n        }\n\n        if (identity.FindFirst(JwtClaimTypes.IdentityProvider) == null)\n        {\n            _logger.LogDebug(\"Adding idp claim with value: {value}\", IdentityServerConstants.LocalIdentityProvider);\n            identity.AddClaim(new Claim(JwtClaimTypes.IdentityProvider, IdentityServerConstants.LocalIdentityProvider));\n        }\n\n        if (identity.FindFirst(JwtClaimTypes.AuthenticationMethod) == null)\n        {\n            if (identity.FindFirst(JwtClaimTypes.IdentityProvider).Value == IdentityServerConstants.LocalIdentityProvider)\n            {\n                _logger.LogDebug(\"Adding amr claim with value: {value}\", OidcConstants.AuthenticationMethods.Password);\n                identity.AddClaim(new Claim(JwtClaimTypes.AuthenticationMethod, OidcConstants.AuthenticationMethods.Password));\n            }\n            else\n            {\n                _logger.LogDebug(\"Adding amr claim with value: {value}\", Constants.ExternalAuthenticationMethod);\n                identity.AddClaim(new Claim(JwtClaimTypes.AuthenticationMethod, Constants.ExternalAuthenticationMethod));\n            }\n        }\n\n        if (identity.FindFirst(JwtClaimTypes.AuthenticationTime) == null)\n        {\n            var time = new DateTimeOffset(authTime).ToUnixTimeSeconds().ToString();\n\n            _logger.LogDebug(\"Adding auth_time claim with value: {value}\", time);\n            identity.AddClaim(new Claim(JwtClaimTypes.AuthenticationTime, time, ClaimValueTypes.Integer64));\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/IdentityServerMiddleware.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\n/// <summary>\n/// IdentityServer middleware\n/// </summary>\npublic class IdentityServerMiddleware\n{\n    private readonly RequestDelegate _next;\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IdentityServerMiddleware\"/> class.\n    /// </summary>\n    /// <param name=\"next\">The next.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public IdentityServerMiddleware(RequestDelegate next, ILogger<IdentityServerMiddleware> logger)\n    {\n        _next = next;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Invokes the middleware.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"router\">The router.</param>\n    /// <param name=\"session\">The user session.</param>\n    /// <param name=\"events\">The event service.</param>\n    /// <param name=\"backChannelLogoutService\"></param>\n    /// <returns></returns>\n    public async Task Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService)\n    {\n        // this will check the authentication session and from it emit the check session\n        // cookie needed from JS-based signout clients.\n        await session.EnsureSessionIdCookieAsync();\n\n        context.Response.OnStarting(async () =>\n        {\n            if (context.GetSignOutCalled())\n            {\n                _logger.LogDebug(\"SignOutCalled set; processing post-signout session cleanup.\");\n\n                // this clears our session id cookie so JS clients can detect the user has signed out\n                await session.RemoveSessionIdCookieAsync();\n\n                // back channel logout\n                var logoutContext = await session.GetLogoutNotificationContext();\n                if (logoutContext != null)\n                {\n                    await backChannelLogoutService.SendLogoutNotificationsAsync(logoutContext);\n                }\n            }\n        });\n\n        try\n        {\n            var endpoint = router.Find(context);\n            if (endpoint != null)\n            {\n                _logger.LogInformation(\"Invoking IdentityServer endpoint: {endpointType} for {url}\", endpoint.GetType().FullName, context.Request.Path.ToString());\n\n                var result = await endpoint.ProcessAsync(context);\n\n                if (result != null)\n                {\n                    _logger.LogTrace(\"Invoking result: {type}\", result.GetType().FullName);\n                    await result.ExecuteAsync(context);\n                }\n\n                return;\n            }\n        }\n        catch (Exception ex)\n        {\n            await events.RaiseAsync(new UnhandledExceptionEvent(ex));\n            _logger.LogCritical(ex, \"Unhandled exception: {exception}\", ex.Message);\n            throw;\n        }\n\n        await _next(context);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/LocalApiAuthentication/LocalApiAuthenticationEvents.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting.LocalApiAuthentication;\n\n/// <summary>\n/// Events for local API authentication\n/// </summary>\npublic class LocalApiAuthenticationEvents\n{\n    /// <summary>\n    /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated.\n    /// </summary>\n    public Func<ClaimsTransformationContext, Task> OnClaimsTransformation { get; set; } = context => Task.CompletedTask;\n\n    /// <summary>\n    /// Invoked after the security token has passed validation and a ClaimsIdentity has been generated.\n    /// </summary>\n    public virtual Task ClaimsTransformation(ClaimsTransformationContext context) => OnClaimsTransformation(context);\n\n}\n\n/// <summary>\n/// Context class for local API claims transformation\n/// </summary>\npublic class ClaimsTransformationContext\n{\n    /// <summary>\n    /// The principal\n    /// </summary>\n    public ClaimsPrincipal Principal { get; set; }\n\n    /// <summary>\n    /// the HTTP context\n    /// </summary>\n    public HttpContext HttpContext { get; internal set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/LocalApiAuthentication/LocalApiAuthenticationExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Extensions for registering the local access token authentication handler\n/// </summary>\npublic static class LocalApiAuthenticationExtensions\n{\n    /// <summary>\n    /// Adds support for local APIs\n    /// </summary>\n    /// <param name=\"services\">The service collection</param>\n    /// <param name=\"transformationFunc\">Function to transform the resulting principal</param>\n    /// <returns></returns>\n    public static IServiceCollection AddLocalApiAuthentication(this IServiceCollection services, Func<ClaimsPrincipal, Task<ClaimsPrincipal>> transformationFunc = null)\n    {\n        services.AddAuthentication()\n            .AddLocalApi(options =>\n            {\n                options.ExpectedScope = IdentityServerConstants.LocalApi.ScopeName;\n\n                if (transformationFunc != null)\n                {\n                    options.Events = new LocalApiAuthenticationEvents\n                    {\n                        OnClaimsTransformation = async e =>\n                        {\n                            e.Principal = await transformationFunc(e.Principal);\n                        }\n                    };\n                }\n            });\n\n        services.AddAuthorization(options =>\n        {\n            options.AddPolicy(IdentityServerConstants.LocalApi.PolicyName, policy =>\n            {\n                policy.AddAuthenticationSchemes(IdentityServerConstants.LocalApi.AuthenticationScheme);\n                policy.RequireAuthenticatedUser();\n            });\n        });\n\n        return services;\n    }\n\n    /// <summary>\n    /// Registers the authentication handler for local APIs.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <returns></returns>\n    public static AuthenticationBuilder AddLocalApi(this AuthenticationBuilder builder)\n        => builder.AddLocalApi(IdentityServerConstants.LocalApi.AuthenticationScheme, _ => { });\n\n    /// <summary>\n    /// Registers the authentication handler for local APIs.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"configureOptions\">The configure options.</param>\n    /// <returns></returns>\n    public static AuthenticationBuilder AddLocalApi(this AuthenticationBuilder builder, Action<LocalApiAuthenticationOptions> configureOptions)\n        => builder.AddLocalApi(IdentityServerConstants.LocalApi.AuthenticationScheme, configureOptions);\n\n    /// <summary>\n    /// Registers the authentication handler for local APIs.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"authenticationScheme\">The authentication scheme.</param>\n    /// <param name=\"configureOptions\">The configure options.</param>\n    /// <returns></returns>\n    public static AuthenticationBuilder AddLocalApi(this AuthenticationBuilder builder, string authenticationScheme, Action<LocalApiAuthenticationOptions> configureOptions)\n        => builder.AddLocalApi(authenticationScheme, displayName: null, configureOptions: configureOptions);\n\n    /// <summary>\n    /// Registers the authentication handler for local APIs.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"authenticationScheme\">The authentication scheme.</param>\n    /// <param name=\"displayName\">The display name of this scheme.</param>\n    /// <param name=\"configureOptions\">The configure options.</param>\n    /// <returns></returns>\n    public static AuthenticationBuilder AddLocalApi(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<LocalApiAuthenticationOptions> configureOptions)\n    {\n        return builder.AddScheme<LocalApiAuthenticationOptions, LocalApiAuthenticationHandler>(authenticationScheme, displayName, configureOptions);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/LocalApiAuthentication/LocalApiAuthenticationHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting.LocalApiAuthentication;\n\n/// <summary>\n/// Authentication handler for validating access token from the local IdentityServer\n/// </summary>\npublic class LocalApiAuthenticationHandler : AuthenticationHandler<LocalApiAuthenticationOptions>\n{\n    private readonly ITokenValidator _tokenValidator;\n    private readonly ILogger _logger;\n\n    /// <inheritdoc />\n    public LocalApiAuthenticationHandler(IOptionsMonitor<LocalApiAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, ITokenValidator tokenValidator)\n        : base(options, logger, encoder, clock)\n    {\n        _tokenValidator = tokenValidator;\n        _logger = logger.CreateLogger<LocalApiAuthenticationHandler>();\n    }\n\n    /// <summary>\n    /// The handler calls methods on the events which give the application control at certain points where processing is occurring. \n    /// If it is not provided a default instance is supplied which does nothing when the methods are called.\n    /// </summary>\n    protected new LocalApiAuthenticationEvents Events\n    {\n        get => (LocalApiAuthenticationEvents)base.Events;\n        set => base.Events = value;\n    }\n\n    /// <inheritdoc/>\n    protected override Task<object> CreateEventsAsync() => Task.FromResult<object>(new LocalApiAuthenticationEvents());\n\n    /// <inheritdoc />\n    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()\n    {\n        _logger.LogTrace(\"HandleAuthenticateAsync called\");\n\n        string token = null;\n\n        string authorization = Request.Headers[\"Authorization\"];\n\n        if (string.IsNullOrEmpty(authorization))\n        {\n            return AuthenticateResult.NoResult();\n        }\n\n        if (authorization.StartsWith(\"Bearer \", StringComparison.OrdinalIgnoreCase))\n        {\n            token = authorization.Substring(\"Bearer \".Length).Trim();\n        }\n\n        if (string.IsNullOrEmpty(token))\n        {\n            return AuthenticateResult.Fail(\"No Access Token is sent.\");\n        }\n\n        _logger.LogTrace(\"Token found: {token}\", Ioc.Sanitizer.Log.Sanitize(token));\n\n        TokenValidationResult result = await _tokenValidator.ValidateAccessTokenAsync(token, Options.ExpectedScope);\n\n        if (result.IsError)\n        {\n            _logger.LogTrace(\"Failed to validate the token\");\n\n            return AuthenticateResult.Fail(result.Error);\n        }\n\n        _logger.LogTrace(\"Successfully validated the token.\");\n\n        ClaimsIdentity claimsIdentity = new ClaimsIdentity(result.Claims, Scheme.Name, JwtClaimTypes.Name, JwtClaimTypes.Role);\n        ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(claimsIdentity);\n        AuthenticationProperties authenticationProperties = new AuthenticationProperties();\n\n        if (Options.SaveToken)\n        {\n            authenticationProperties.StoreTokens(new[]\n            {\n                new AuthenticationToken { Name = \"access_token\", Value = token }\n            });\n        }\n\n        var claimsTransformationContext = new ClaimsTransformationContext\n        {\n            Principal = claimsPrincipal,\n            HttpContext = Context\n        };\n\n        await Events.ClaimsTransformation(claimsTransformationContext);\n\n        AuthenticationTicket authenticationTicket = new AuthenticationTicket(claimsTransformationContext.Principal, authenticationProperties, Scheme.Name);\n        return AuthenticateResult.Success(authenticationTicket);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/LocalApiAuthentication/LocalApiAuthenticationOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting.LocalApiAuthentication;\n\n/// <summary>\n/// Options for local API authentication\n/// </summary>\n/// <seealso cref=\"Microsoft.AspNetCore.Authentication.AuthenticationSchemeOptions\" />\npublic class LocalApiAuthenticationOptions : AuthenticationSchemeOptions\n{\n    /// <summary>\n    /// Allows setting a specific required scope (optional)\n    /// </summary>\n    public string ExpectedScope { get; set; }\n\n    /// <summary>\n    /// Specifies whether the token should be saved in the authentication properties\n    /// </summary>\n    public bool SaveToken { get; set; } = true;\n\n    /// <summary>\n    /// Allows implementing events\n    /// </summary>\n    public new LocalApiAuthenticationEvents Events\n    {\n        get { return (LocalApiAuthenticationEvents)base.Events; }\n        set { base.Events = value; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Hosting/MutualTlsEndpointMiddleware.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Hosting;\n\n/// <summary>\n///     Middleware for re-writing the MTLS enabled endpoints to the standard protocol endpoints\n/// </summary>\npublic class MutualTlsEndpointMiddleware\n{\n    private readonly ILogger<MutualTlsEndpointMiddleware> _logger;\n    private readonly RequestDelegate _next;\n    private readonly IdentityServerOptions _options;\n\n    /// <summary>\n    ///     ctor\n    /// </summary>\n    /// <param name=\"next\"></param>\n    /// <param name=\"options\"></param>\n    /// <param name=\"logger\"></param>\n    public MutualTlsEndpointMiddleware(RequestDelegate next, IdentityServerOptions options,\n        ILogger<MutualTlsEndpointMiddleware> logger)\n    {\n        _next = next;\n        _options = options;\n        _logger = logger;\n    }\n\n    /// <inheritdoc />\n    public async Task Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)\n    {\n        if (_options.MutualTls.Enabled)\n        {\n            // domain-based MTLS\n            if (_options.MutualTls.DomainName.IsPresent())\n            {\n                // separate domain\n                if (_options.MutualTls.DomainName.Contains(\".\"))\n                {\n                    if (context.Request.Host.Host.Equals(_options.MutualTls.DomainName,\n                        StringComparison.OrdinalIgnoreCase))\n                    {\n                        var result = await TriggerCertificateAuthentication(context);\n                        if (!result.Succeeded)\n                        {\n                            return;\n                        }\n                    }\n                }\n                // sub-domain\n                else\n                {\n                    if (context.Request.Host.Host.StartsWith(_options.MutualTls.DomainName + \".\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        var result = await TriggerCertificateAuthentication(context);\n                        if (!result.Succeeded)\n                        {\n                            return;\n                        }\n                    }\n                }\n            }\n            // path based MTLS\n            else if (context.Request.Path.StartsWithSegments(Constants.ProtocolRoutePaths.MtlsPathPrefix.EnsureLeadingSlash(), out var subPath))\n            {\n                var result = await TriggerCertificateAuthentication(context);\n\n                if (result.Succeeded)\n                {\n                    var path = Constants.ProtocolRoutePaths.ConnectPathPrefix +\n                               subPath.ToString().EnsureLeadingSlash();\n                    path = path.EnsureLeadingSlash();\n\n                    _logger.LogDebug(\"Rewriting MTLS request from: {oldPath} to: {newPath}\",\n                        context.Request.Path.ToString(), path);\n                    context.Request.Path = path;\n                }\n                else\n                {\n                    return;\n                }\n            }\n        }\n        \n        await _next(context);\n    }\n\n    private async Task<AuthenticateResult> TriggerCertificateAuthentication(HttpContext context)\n    {\n        var x509AuthResult =\n            await context.AuthenticateAsync(_options.MutualTls.ClientCertificateAuthenticationScheme);\n\n        if (!x509AuthResult.Succeeded)\n        {\n            _logger.LogDebug(\"MTLS authentication failed, error: {error}.\",\n                x509AuthResult.Failure?.Message);\n            await context.ForbidAsync(_options.MutualTls.ClientCertificateAuthenticationScheme);\n        }\n\n        return x509AuthResult;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/IdentityServer8.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <IsPackable>true</IsPackable>\n        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n    </PropertyGroup>\n\n    <PropertyGroup>\n        <ContinuousIntegrationBuild Condition=\"'$(TF_BUILD)' == 'true'\">True</ContinuousIntegrationBuild>\n        <ContinuousIntegrationBuild Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">True</ContinuousIntegrationBuild>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <PackageReference Include=\"IdentityModel\" />\n        <PackageReference Include=\"Microsoft.IdentityModel.Protocols.OpenIdConnect\" />\n        <PackageReference Include=\"Microsoft.AspNetCore.Authentication.OpenIdConnect\" />\n    </ItemGroup>\n\n    <ItemGroup>\n        <ProjectReference Include=\"..\\..\\Security\\IdentityServer8.Security\\IdentityServer8.Security.csproj\" />\n        <ProjectReference Include=\"..\\..\\Storage\\src\\IdentityServer8.Storage.csproj\" />\n    </ItemGroup>\n</Project>"
  },
  {
    "path": "src/IdentityServer8/src/IdentityServerConstants.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8;\n\npublic static class IdentityServerConstants\n{\n    public const string LocalIdentityProvider = \"local\";\n    public const string DefaultCookieAuthenticationScheme = \"idsrv\";\n    public const string SignoutScheme = \"idsrv\";\n    public const string ExternalCookieAuthenticationScheme = \"idsrv.external\";\n    public const string DefaultCheckSessionCookieName = \"idsrv.session\";\n    public const string AccessTokenAudience = \"{0}resources\";\n\n    public const string JwtRequestClientKey = \"idsrv.jwtrequesturi.client\";\n\n    /// <summary>\n    /// Constants for local IdentityServer access token authentication.\n    /// </summary>\n    public static class LocalApi\n    {\n        /// <summary>\n        /// The authentication scheme when using the AddLocalApi helper.\n        /// </summary>\n        public const string AuthenticationScheme = \"IdentityServerAccessToken\";\n\n        /// <summary>\n        /// The API scope name when using the AddLocalApiAuthentication helper.\n        /// </summary>\n        public const string ScopeName = \"IdentityServerApi\";\n\n        /// <summary>\n        /// The authorization policy name when using the AddLocalApiAuthentication helper.\n        /// </summary>\n        public const string PolicyName = AuthenticationScheme;\n    }\n\n    public static class ProtocolTypes\n    {\n        public const string OpenIdConnect = \"oidc\";\n        public const string WsFederation = \"wsfed\";\n        public const string Saml2p = \"saml2p\";\n    }\n\n    public static class TokenTypes\n    {\n        public const string IdentityToken = \"id_token\";\n        public const string AccessToken = \"access_token\";\n    }\n\n    public static class ClaimValueTypes\n    {\n        public const string Json = \"json\";\n    }\n\n    public static class ParsedSecretTypes\n    {\n        public const string NoSecret = \"NoSecret\";\n        public const string SharedSecret = \"SharedSecret\";\n        public const string X509Certificate = \"X509Certificate\";\n        public const string JwtBearer = \"urn:ietf:params:oauth:client-assertion-type:jwt-bearer\";\n    }\n\n    public static class SecretTypes\n    {\n        public const string SharedSecret = \"SharedSecret\";\n        public const string X509CertificateThumbprint = \"X509Thumbprint\";\n        public const string X509CertificateName = \"X509Name\";\n        public const string X509CertificateBase64 = \"X509CertificateBase64\";\n        public const string JsonWebKey = \"JWK\";\n    }\n\n    public static class ProfileDataCallers\n    {\n        public const string UserInfoEndpoint = \"UserInfoEndpoint\";\n        public const string ClaimsProviderIdentityToken = \"ClaimsProviderIdentityToken\";\n        public const string ClaimsProviderAccessToken = \"ClaimsProviderAccessToken\";\n    }\n\n    public static class ProfileIsActiveCallers\n    {\n        public const string AuthorizeEndpoint = \"AuthorizeEndpoint\";\n        public const string IdentityTokenValidation = \"IdentityTokenValidation\";\n        public const string AccessTokenValidation = \"AccessTokenValidation\";\n        public const string ResourceOwnerValidation = \"ResourceOwnerValidation\";\n        public const string ExtensionGrantValidation = \"ExtensionGrantValidation\";\n        public const string RefreshTokenValidation = \"RefreshTokenValidation\";\n        public const string AuthorizationCodeValidation = \"AuthorizationCodeValidation\";\n        public const string UserInfoRequestValidation = \"UserInfoRequestValidation\";\n        public const string DeviceCodeValidation = \"DeviceCodeValidation\";\n    }\n\n    public static IEnumerable<string> SupportedSigningAlgorithms = new List<string>\n    {\n        SecurityAlgorithms.RsaSha256,\n        SecurityAlgorithms.RsaSha384,\n        SecurityAlgorithms.RsaSha512,\n\n        SecurityAlgorithms.RsaSsaPssSha256,\n        SecurityAlgorithms.RsaSsaPssSha384,\n        SecurityAlgorithms.RsaSsaPssSha512,\n\n        SecurityAlgorithms.EcdsaSha256,\n        SecurityAlgorithms.EcdsaSha384,\n        SecurityAlgorithms.EcdsaSha512\n    };\n\n    public enum RsaSigningAlgorithm\n    {\n        RS256,\n        RS384,\n        RS512,\n\n        PS256,\n        PS384,\n        PS512\n    }\n\n    public enum ECDsaSigningAlgorithm\n    {\n        ES256,\n        ES384,\n        ES512\n    }\n\n    public static class StandardScopes\n    {\n        /// <summary>REQUIRED. Informs the Authorization Server that the Client is making an OpenID Connect request. If the <c>openid</c> scope value is not present, the behavior is entirely unspecified.</summary>\n        public const string OpenId = \"openid\";\n        /// <summary>OPTIONAL. This scope value requests access to the End-User's default profile Claims, which are: <c>name</c>, <c>family_name</c>, <c>given_name</c>, <c>middle_name</c>, <c>nickname</c>, <c>preferred_username</c>, <c>profile</c>, <c>picture</c>, <c>website</c>, <c>gender</c>, <c>birthdate</c>, <c>zoneinfo</c>, <c>locale</c>, and <c>updated_at</c>.</summary>\n        public const string Profile = \"profile\";\n        /// <summary>OPTIONAL. This scope value requests access to the <c>email</c> and <c>email_verified</c> Claims.</summary>\n        public const string Email = \"email\";\n        /// <summary>OPTIONAL. This scope value requests access to the <c>address</c> Claim.</summary>\n        public const string Address = \"address\";\n        /// <summary>OPTIONAL. This scope value requests access to the <c>phone_number</c> and <c>phone_number_verified</c> Claims.</summary>\n        public const string Phone = \"phone\";\n        /// <summary>This scope value MUST NOT be used with the OpenID Connect Implicit Client Implementer's Guide 1.0. See the OpenID Connect Basic Client Implementer's Guide 1.0 (http://openid.net/specs/openid-connect-implicit-1_0.html#OpenID.Basic) for its usage in that subset of OpenID Connect.</summary>\n        public const string OfflineAccess = \"offline_access\";\n    }\n\n    public static class PersistedGrantTypes\n    {\n        public const string AuthorizationCode = \"authorization_code\";\n        public const string ReferenceToken = \"reference_token\";\n        public const string RefreshToken = \"refresh_token\";\n        public const string UserConsent = \"user_consent\";\n        public const string DeviceCode = \"device_code\";\n        public const string UserCode = \"user_code\";\n    }\n\n    public static class UserCodeTypes\n    {\n        public const string Numeric = \"Numeric\";\n    }\n\n    public static class HttpClients\n    {\n        public const int DefaultTimeoutSeconds = 10;\n        public const string JwtRequestUriHttpClient = \"IdentityServer:JwtRequestUriClient\";\n        public const string BackChannelLogoutHttpClient = \"IdentityServer:BackChannelLogoutClient\";\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/IdentityServerTools.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8;\n\n/// <summary>\n/// Class for useful helpers for interacting with IdentityServer\n/// </summary>\npublic class IdentityServerTools\n{\n    internal readonly IHttpContextAccessor ContextAccessor;\n    private readonly ITokenCreationService _tokenCreation;\n    private readonly ISystemClock _clock;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IdentityServerTools\" /> class.\n    /// </summary>\n    /// <param name=\"contextAccessor\">The context accessor.</param>\n    /// <param name=\"tokenCreation\">The token creation service.</param>\n    /// <param name=\"clock\">The clock.</param>\n    public IdentityServerTools(IHttpContextAccessor contextAccessor, ITokenCreationService tokenCreation, ISystemClock clock)\n    {\n        ContextAccessor = contextAccessor;\n        _tokenCreation = tokenCreation;\n        _clock = clock;\n    }\n\n    /// <summary>\n    /// Issues a JWT.\n    /// </summary>\n    /// <param name=\"lifetime\">The lifetime.</param>\n    /// <param name=\"claims\">The claims.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">claims</exception>\n    public virtual async Task<string> IssueJwtAsync(int lifetime, IEnumerable<Claim> claims)\n    {\n        if (claims == null) throw new ArgumentNullException(nameof(claims));\n\n        var issuer = ContextAccessor.HttpContext.GetIdentityServerIssuerUri();\n\n        var token = new Token\n        {\n            CreationTime = _clock.UtcNow.UtcDateTime,\n            Issuer = issuer,\n            Lifetime = lifetime,\n\n            Claims = new HashSet<Claim>(claims, new ClaimComparer())\n        };\n\n        return await _tokenCreation.CreateTokenAsync(token);\n    }\n\n    /// <summary>\n    /// Issues a JWT.\n    /// </summary>\n    /// <param name=\"lifetime\">The lifetime.</param>\n    /// <param name=\"issuer\">The issuer.</param>\n    /// <param name=\"claims\">The claims.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">claims</exception>\n    public virtual async Task<string> IssueJwtAsync(int lifetime, string issuer, IEnumerable<Claim> claims)\n    {\n        if (String.IsNullOrWhiteSpace(issuer)) throw new ArgumentNullException(nameof(issuer));\n        if (claims == null) throw new ArgumentNullException(nameof(claims));\n\n        var token = new Token\n        {\n            CreationTime = _clock.UtcNow.UtcDateTime,\n            Issuer = issuer,\n            Lifetime = lifetime,\n\n            Claims = new HashSet<Claim>(claims, new ClaimComparer())\n        };\n\n        return await _tokenCreation.CreateTokenAsync(token);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/IdentityServerUser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8;\n\n/// <summary>\n/// Model properties of an IdentityServer user\n/// </summary>\npublic class IdentityServerUser\n{\n    /// <summary>\n    /// Subject ID (mandatory)\n    /// </summary>\n    public string SubjectId { get; }\n\n    /// <summary>\n    /// Display name (optional)\n    /// </summary>\n    public string DisplayName { get; set; }\n\n    /// <summary>\n    /// Identity provider (optional)\n    /// </summary>\n    public string IdentityProvider { get; set; }\n\n    /// <summary>\n    /// Authentication methods\n    /// </summary>\n    public ICollection<string> AuthenticationMethods { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Authentication time\n    /// </summary>\n    public DateTime? AuthenticationTime { get; set; }\n\n    /// <summary>\n    /// Additional claims\n    /// </summary>\n    public ICollection<Claim> AdditionalClaims { get; set; } = new HashSet<Claim>(new ClaimComparer());\n\n    /// <summary>\n    /// Initializes a user identity\n    /// </summary>\n    /// <param name=\"subjectId\">The subject ID</param>\n    public IdentityServerUser(string subjectId)\n    {\n        if (subjectId.IsMissing()) throw new ArgumentException(\"SubjectId is mandatory\", nameof(subjectId));\n\n        SubjectId = subjectId;\n    }\n\n    /// <summary>\n    /// Creates an IdentityServer claims principal\n    /// </summary>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\"></exception>\n    public ClaimsPrincipal CreatePrincipal()\n    {\n        if (SubjectId.IsMissing()) throw new ArgumentException(\"SubjectId is mandatory\", nameof(SubjectId));\n        var claims = new List<Claim> { new Claim(JwtClaimTypes.Subject, SubjectId) };\n\n        if (DisplayName.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.Name, DisplayName));\n        }\n\n        if (IdentityProvider.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.IdentityProvider, IdentityProvider));\n        }\n\n        if (AuthenticationTime.HasValue)\n        {\n            claims.Add(new Claim(JwtClaimTypes.AuthenticationTime, new DateTimeOffset(AuthenticationTime.Value).ToUnixTimeSeconds().ToString()));\n        }\n\n        if (AuthenticationMethods.Any())\n        {\n            foreach (var amr in AuthenticationMethods)\n            {\n                claims.Add(new Claim(JwtClaimTypes.AuthenticationMethod, amr));\n            }\n        }\n\n        claims.AddRange(AdditionalClaims);\n\n        var id = new ClaimsIdentity(claims.Distinct(new ClaimComparer()), Constants.IdentityServerAuthenticationType, JwtClaimTypes.Name, JwtClaimTypes.Role);\n        return new ClaimsPrincipal(id);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Infrastructure/DistributedCacheStateDataFormatter.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.DataProtection;\n\nnamespace IdentityServer8.Infrastructure;\n\n/// <summary>\n/// State formatter using IDistributedCache\n/// </summary>\npublic class DistributedCacheStateDataFormatter : ISecureDataFormat<AuthenticationProperties>\n{\n    private readonly IHttpContextAccessor _httpContext;\n    private readonly string _name;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DistributedCacheStateDataFormatter\"/> class.\n    /// </summary>\n    /// <param name=\"httpContext\">The HTTP context accessor.</param>\n    /// <param name=\"name\">The scheme name.</param>\n    public DistributedCacheStateDataFormatter(IHttpContextAccessor httpContext, string name)\n    {\n        _httpContext = httpContext;\n        _name = name;\n    }\n\n    private string CacheKeyPrefix => \"DistributedCacheStateDataFormatter\";\n\n    private IDistributedCache Cache => _httpContext.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();\n    private IDataProtector Protector => _httpContext.HttpContext.RequestServices.GetRequiredService<IDataProtectionProvider>().CreateProtector(CacheKeyPrefix, _name);\n\n    /// <summary>\n    /// Protects the specified data.\n    /// </summary>\n    /// <param name=\"data\">The data.</param>\n    /// <returns></returns>\n    public string Protect(AuthenticationProperties data)\n    {\n        return Protect(data, null);\n    }\n\n    /// <summary>\n    /// Protects the specified data.\n    /// </summary>\n    /// <param name=\"data\">The data.</param>\n    /// <param name=\"purpose\">The purpose.</param>\n    /// <returns></returns>\n    public string Protect(AuthenticationProperties data, string purpose)\n    {\n        var key = Guid.NewGuid().ToString();\n        var cacheKey = $\"{CacheKeyPrefix}-{_name}-{purpose}-{key}\";\n        var json = ObjectSerializer.ToString(data.Items);\n\n        var options = new DistributedCacheEntryOptions();\n        if (data.ExpiresUtc.HasValue)\n        {\n            options.SetAbsoluteExpiration(data.ExpiresUtc.Value);\n        }\n        else\n        {\n            options.SetSlidingExpiration(Constants.DefaultCacheDuration);\n        }\n        \n        // Rather than encrypt the full AuthenticationProperties\n        // cache the data and encrypt the key that points to the data\n        Cache.SetString(cacheKey, json, options);\n\n        return Protector.Protect(key);\n    }\n\n    /// <summary>\n    /// Unprotects the specified protected text.\n    /// </summary>\n    /// <param name=\"protectedText\">The protected text.</param>\n    /// <returns></returns>\n    public AuthenticationProperties Unprotect(string protectedText)\n    {\n        return Unprotect(protectedText, null);\n    }\n\n    /// <summary>\n    /// Unprotects the specified protected text.\n    /// </summary>\n    /// <param name=\"protectedText\">The protected text.</param>\n    /// <param name=\"purpose\">The purpose.</param>\n    /// <returns></returns>\n    public AuthenticationProperties Unprotect(string protectedText, string purpose)\n    {\n        if (String.IsNullOrWhiteSpace(protectedText))\n        {\n            return null;\n        }\n\n        // Decrypt the key and retrieve the data from the cache.\n        var key = Protector.Unprotect(protectedText);\n        var cacheKey = $\"{CacheKeyPrefix}-{_name}-{purpose}-{key}\";\n        var json = Cache.GetString(cacheKey);\n\n        if (json == null)\n        {\n            return null;\n        }\n\n        var items = ObjectSerializer.FromString<Dictionary<string, string>>(json);\n        var props = new AuthenticationProperties(items);\n        return props;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Infrastructure/MessageCookie.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.DataProtection;\n\nnamespace IdentityServer8;\n\ninternal class MessageCookie<TModel>\n{\n    private readonly ILogger _logger;\n    private readonly IdentityServerOptions _options;\n    private readonly IHttpContextAccessor _context;\n    private readonly IDataProtector _protector;\n\n    public MessageCookie(\n        ILogger<MessageCookie<TModel>> logger, \n        IdentityServerOptions options,\n        IHttpContextAccessor context, \n        IDataProtectionProvider provider)\n    {\n        _logger = logger;\n        _options = options;\n        _context = context;\n        _protector = provider.CreateProtector(MessageType);\n    }\n\n    private string MessageType => typeof(TModel).Name;\n\n    private string Protect(Message<TModel> message)\n    {\n        var json = ObjectSerializer.ToString(message);\n        _logger.LogTrace(\"Protecting message: {0}\", json);\n\n        return _protector.Protect(json);\n    }\n\n    private Message<TModel> Unprotect(string data)\n    {\n        var json = _protector.Unprotect(data);\n        var message = ObjectSerializer.FromString<Message<TModel>>(json);\n        return message;\n    }\n\n    private string CookiePrefix => MessageType + \".\";\n\n    private string GetCookieFullName(string id)\n    {\n        return CookiePrefix + id;\n    }\n\n    private string CookiePath => _context.HttpContext.GetIdentityServerBasePath().CleanUrlPath();\n\n    private IEnumerable<string> GetCookieNames()\n    {\n        var key = CookiePrefix;\n        foreach ((string name, var _) in _context.HttpContext.Request.Cookies)\n        {\n            if (name.StartsWith(key))\n            {\n                yield return name;\n            }\n        }\n    }\n\n    private bool Secure => _context.HttpContext.Request.IsHttps;\n\n    public void Write(string id, Message<TModel> message)\n    {\n        ClearOverflow();\n\n        if (message == null) throw new ArgumentNullException(nameof(message));\n\n        var name = GetCookieFullName(id);\n        var data = Protect(message);\n\n        _context.HttpContext.Response.Cookies.Append(\n            name,\n            data,\n            new CookieOptions\n            {\n                HttpOnly = true,\n                Secure = Secure,\n                Path = CookiePath,\n                IsEssential = true\n                // don't need to set same-site since cookie is expected to be sent\n                // to only another page in this host. \n            });\n    }\n\n    public Message<TModel> Read(string id)\n    {\n        if (id.IsMissing()) return null;\n\n        var name = GetCookieFullName(id);\n        return ReadByCookieName(name);\n    }\n\n    private Message<TModel> ReadByCookieName(string name)\n    {\n        var data = _context.HttpContext.Request.Cookies[name];\n        if (data.IsPresent())\n        {\n            try\n            {\n                return Unprotect(data);\n            }\n            catch(Exception ex)\n            {\n                _logger.LogError(ex, \"Error unprotecting message cookie\");\n                ClearByCookieName(name);\n            }\n        }\n        return null;\n    }\n\n    protected internal void Clear(string id)\n    {\n        var name = GetCookieFullName(id);\n        ClearByCookieName(name);\n    }\n\n    private void ClearByCookieName(string name)\n    {\n        _context.HttpContext.Response.Cookies.Append(\n            name,\n            \".\",\n            new CookieOptions\n            {\n                Expires = new DateTime(2000, 1, 1),\n                HttpOnly = true,\n                Secure = Secure,\n                Path = CookiePath,\n                IsEssential = true\n            });\n    }\n\n    private long GetCookieRank(string name)\n    {   \n        // empty and invalid cookies are considered to be the oldest:\n        var rank = DateTime.MinValue.Ticks;\n\n        try\n        {\n            var message = ReadByCookieName(name);\n            if (message != null)\n            {\n                // valid cookies are ranked based on their creation time:\n                rank = message.Created;\n            }\n        }\n        catch (CryptographicException e)\n        {   \n            // cookie was protected with a different key/algorithm\n            _logger.LogDebug(e, \"Unable to unprotect cookie {0}\", name);\n        }\n        \n        return rank;\n    }\n\n    private void ClearOverflow()\n    {\n        var names = GetCookieNames();\n        var toKeep = _options.UserInteraction.CookieMessageThreshold;\n\n        if (names.Count() >= toKeep)\n        {\n            var rankedCookieNames =\n                from name in names\n                let rank = GetCookieRank(name)\n                orderby rank descending\n                select name;\n\n            var purge = rankedCookieNames.Skip(Math.Max(0, toKeep - 1));\n            foreach (var name in purge)\n            {\n                _logger.LogTrace(\"Purging stale cookie: {cookieName}\", name);\n                ClearByCookieName(name);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Infrastructure/ObjectSerializer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonSerializer = System.Text.Json.JsonSerializer;\n\nnamespace IdentityServer8;\n\ninternal static class ObjectSerializer\n{\n    private static readonly JsonSerializerOptions Options = new JsonSerializerOptions\n    {\n        IgnoreNullValues = true\n    };\n    \n    public static string ToString(object o)\n    {\n        return JsonSerializer.Serialize(o, Options);\n    }\n\n    public static T FromString<T>(string value)\n    {\n        return JsonSerializer.Deserialize<T>(value, Options);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Logging/LogSerializer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing JsonSerializer = System.Text.Json.JsonSerializer;\n\nnamespace IdentityServer8.Logging;\n\n/// <summary>\n/// Helper to JSON serialize object data for logging.\n/// </summary>\ninternal static class LogSerializer\n{\n    static readonly JsonSerializerOptions Options = new JsonSerializerOptions\n    {\n        IgnoreNullValues = true,\n        WriteIndented = true\n    };\n\n    static LogSerializer()\n    {\n        Options.Converters.Add(new JsonStringEnumConverter());\n    }\n\n    /// <summary>\n    /// Serializes the specified object.\n    /// </summary>\n    /// <param name=\"logObject\">The object.</param>\n    /// <returns></returns>\n    public static string Serialize(object logObject)\n    {\n        return JsonSerializer.Serialize(logObject, Options);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Logging/Models/AuthorizeRequestValidationLog.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Logging.Models;\n\ninternal class AuthorizeRequestValidationLog\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string RedirectUri { get; set; }\n    public IEnumerable<string> AllowedRedirectUris { get; set; }\n    public string SubjectId { get; set; }\n\n    public string ResponseType { get; set; }\n    public string ResponseMode { get; set; }\n    public string GrantType { get; set; }\n    public string RequestedScopes { get; set; }\n\n    public string State { get; set; }\n    public string UiLocales { get; set; }\n    public string Nonce { get; set; }\n    public IEnumerable<string> AuthenticationContextReferenceClasses { get; set; }\n    public string DisplayMode { get; set; }\n    public string PromptMode { get; set; }\n    public int? MaxAge { get; set; }\n    public string LoginHint { get; set; }\n    public string SessionId { get; set; }\n\n    public Dictionary<string, string> Raw { get; set; }\n\n    public AuthorizeRequestValidationLog(ValidatedAuthorizeRequest request, IEnumerable<string> sensitiveValuesFilter)\n    {\n        Raw = request.Raw.ToScrubbedDictionary(sensitiveValuesFilter.ToArray());\n\n        if (request.Client != null)\n        {\n            ClientId = request.Client.ClientId;\n            ClientName = request.Client.ClientName;\n\n            AllowedRedirectUris = request.Client.RedirectUris;\n        }\n\n        if (request.Subject != null)\n        {\n            var subjectClaim = request.Subject.FindFirst(JwtClaimTypes.Subject);\n            if (subjectClaim != null)\n            {\n                SubjectId = subjectClaim.Value;\n            }\n            else\n            {\n                SubjectId = \"anonymous\";\n            }\n        }\n\n        if (request.AuthenticationContextReferenceClasses.Any())\n        {\n            AuthenticationContextReferenceClasses = request.AuthenticationContextReferenceClasses;\n        }\n\n        RedirectUri = request.RedirectUri;\n        ResponseType = request.ResponseType;\n        ResponseMode = request.ResponseMode;\n        GrantType = request.GrantType;\n        RequestedScopes = request.RequestedScopes.ToSpaceSeparatedString();\n        State = request.State;\n        UiLocales = request.UiLocales;\n        Nonce = request.Nonce;\n\n        DisplayMode = request.DisplayMode;\n        PromptMode = request.PromptModes.ToSpaceSeparatedString();\n        LoginHint = request.LoginHint;\n        MaxAge = request.MaxAge;\n        SessionId = request.SessionId;\n    }\n\n    public override string ToString()\n    {\n        return LogSerializer.Serialize(this);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Logging/Models/AuthorizeResponseLog.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Logging.Models;\n\ninternal class AuthorizeResponseLog\n{\n    public string SubjectId { get; set; }\n    public string ClientId { get; set; }\n    public string RedirectUri { get; set; }\n    public string State { get; set; }\n\n    public string Scope { get; set; }\n    public string Error { get; set; }\n    public string ErrorDescription { get; set; }\n\n\n    public AuthorizeResponseLog(AuthorizeResponse response)\n    {\n        ClientId = response.Request?.Client?.ClientId;\n        SubjectId = response.Request?.Subject?.GetSubjectId();\n        RedirectUri = response.RedirectUri;\n        State = response.State;\n        Scope = response.Scope;\n        Error = response.Error;\n        ErrorDescription = response.ErrorDescription;\n    }\n\n    public override string ToString()\n    {\n        return LogSerializer.Serialize(this);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Logging/Models/DeviceAuthorizationRequestValidationLog.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Logging;\n\ninternal class DeviceAuthorizationRequestValidationLog\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string Scopes { get; set; }\n\n    public Dictionary<string, string> Raw { get; set; }\n\n    private static readonly string[] SensitiveValuesFilter = {\n        OidcConstants.TokenRequest.ClientSecret,\n        OidcConstants.TokenRequest.ClientAssertion\n    };\n\n    public DeviceAuthorizationRequestValidationLog(ValidatedDeviceAuthorizationRequest request)\n    {\n        Raw = request.Raw.ToScrubbedDictionary(SensitiveValuesFilter);\n\n        if (request.Client != null)\n        {\n            ClientId = request.Client.ClientId;\n            ClientName = request.Client.ClientName;\n        }\n\n        if (request.RequestedScopes != null)\n        {\n            Scopes = request.RequestedScopes.ToSpaceSeparatedString();\n        }\n    }\n\n    public override string ToString()\n    {\n        return LogSerializer.Serialize(this);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Logging/Models/EndSessionRequestValidationLog.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Logging.Models;\n\ninternal class EndSessionRequestValidationLog\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string SubjectId { get; set; }\n\n    public string PostLogOutUri { get; set; }\n    public string State { get; set; }\n\n    public Dictionary<string, string> Raw { get; set; }\n\n    public EndSessionRequestValidationLog(ValidatedEndSessionRequest request)\n    {\n        Raw = request.Raw.ToScrubbedDictionary(OidcConstants.EndSessionRequest.IdTokenHint);\n\n        SubjectId = \"unknown\";\n        \n        var subjectClaim = request.Subject?.FindFirst(JwtClaimTypes.Subject);\n        if (subjectClaim != null)\n        {\n            SubjectId = subjectClaim.Value;\n        }\n\n        if (request.Client != null)\n        {\n            ClientId = request.Client.ClientId;\n            ClientName = request.Client.ClientName;\n        }\n\n        PostLogOutUri = request.PostLogOutUri;\n        State = request.State;\n    }\n\n    public override string ToString()\n    {\n        return LogSerializer.Serialize(this);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Logging/Models/TokenRequestValidationLog.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Logging.Models;\n\ninternal class TokenRequestValidationLog\n{\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public string GrantType { get; set; }\n    public string Scopes { get; set; }\n\n    public string AuthorizationCode { get; set; }\n    public string RefreshToken { get; set; }\n\n    public string UserName { get; set; }\n    public IEnumerable<string> AuthenticationContextReferenceClasses { get; set; }\n    public string Tenant { get; set; }\n    public string IdP { get; set; }\n\n    public Dictionary<string, string> Raw { get; set; }\n\n    public TokenRequestValidationLog(ValidatedTokenRequest request, IEnumerable<string> sensitiveValuesFilter)\n    {\n        Raw = request.Raw.ToScrubbedDictionary(sensitiveValuesFilter.ToArray());\n\n        if (request.Client != null)\n        {\n            ClientId = request.Client.ClientId;\n            ClientName = request.Client.ClientName;\n        }\n\n        if (request.RequestedScopes != null)\n        {\n            Scopes = request.RequestedScopes.ToSpaceSeparatedString();\n        }\n\n        GrantType = request.GrantType;\n        AuthorizationCode = request.AuthorizationCodeHandle.Obfuscate();\n        RefreshToken = request.RefreshTokenHandle.Obfuscate();\n        UserName = request.UserName;\n    }\n\n    public override string ToString()\n    {\n        return LogSerializer.Serialize(this);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Logging/Models/TokenValidationLog.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Logging.Models;\n\ninternal class TokenValidationLog\n{\n    // identity token\n    public string ClientId { get; set; }\n    public string ClientName { get; set; }\n    public bool ValidateLifetime { get; set; }\n\n    // access token\n    public string AccessTokenType { get; set; }\n    public string ExpectedScope { get; set; }\n    public string TokenHandle { get; set; }\n    public string JwtId { get; set; }\n\n    // both\n    public Dictionary<string, object> Claims { get; set; }\n\n    public override string ToString()\n    {\n        return LogSerializer.Serialize(this);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Contexts/IsActiveContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Context describing the is-active check\n/// </summary>\npublic class IsActiveContext\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IsActiveContext\"/> class.\n    /// </summary>\n    public IsActiveContext(ClaimsPrincipal subject, Client client, string caller)\n    {\n        if (subject == null) throw new ArgumentNullException(nameof(subject));\n        if (client == null) throw new ArgumentNullException(nameof(client));\n        if (caller.IsMissing()) throw new ArgumentNullException(nameof(caller));\n\n        Subject = subject;\n        Client = client;\n        Caller = caller;\n        \n        IsActive = true;\n    }\n\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client.\n    /// </summary>\n    /// <value>\n    /// The client.\n    /// </value>\n    public Client Client { get; set; }\n\n    /// <summary>\n    /// Gets or sets the caller.\n    /// </summary>\n    /// <value>\n    /// The caller.\n    /// </value>\n    public string Caller { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the subject is active and can recieve tokens.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if the subject is active; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsActive { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Contexts/LogoutNotificationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Provides the context necessary to construct a logout notificaiton.\n/// </summary>\npublic class LogoutNotificationContext\n{\n    /// <summary>\n    ///  The SubjectId of the user.\n    /// </summary>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// The session Id of the user's authentication session.\n    /// </summary>\n    public string SessionId { get; set; }\n\n    /// <summary>\n    /// The list of client Ids that the user has authenticated to.\n    /// </summary>\n    public IEnumerable<string> ClientIds { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Contexts/ProfileDataRequestContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Class describing the profile data request\n/// </summary>\npublic class ProfileDataRequestContext\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ProfileDataRequestContext\"/> class.\n    /// </summary>\n    public ProfileDataRequestContext()\n    { }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ProfileDataRequestContext\" /> class.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <param name=\"caller\">The caller.</param>\n    /// <param name=\"requestedClaimTypes\">The requested claim types.</param>\n    public ProfileDataRequestContext(ClaimsPrincipal subject, Client client, string caller, IEnumerable<string> requestedClaimTypes)\n    {\n        Subject = subject ?? throw new ArgumentNullException(nameof(subject));\n        Client = client ?? throw new ArgumentNullException(nameof(client));\n        Caller = caller ?? throw new ArgumentNullException(nameof(caller));\n        RequestedClaimTypes = requestedClaimTypes ?? throw new ArgumentNullException(nameof(requestedClaimTypes));\n    }\n\n    /// <summary>\n    /// Gets or sets the validatedRequest.\n    /// </summary>\n    /// <value>\n    /// The validatedRequest.\n    /// </value>\n    public ValidatedRequest ValidatedRequest { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n\n    /// <summary>\n    /// Gets or sets the requested claim types.\n    /// </summary>\n    /// <value>\n    /// The requested claim types.\n    /// </value>\n    public IEnumerable<string> RequestedClaimTypes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client id.\n    /// </summary>\n    /// <value>\n    /// The client id.\n    /// </value>\n    public Client Client { get; set; }\n\n    /// <summary>\n    /// Gets or sets the caller.\n    /// </summary>\n    /// <value>\n    /// The caller.\n    /// </value>\n    public string Caller { get; set; }\n\n    /// <summary>\n    /// Gets or sets the requested resources (if available).\n    /// </summary>\n    /// <value>\n    /// The resources.\n    /// </value>\n    public ResourceValidationResult RequestedResources { get; set; }\n\n    /// <summary>\n    /// Gets or sets the issued claims.\n    /// </summary>\n    /// <value>\n    /// The issued claims.\n    /// </value>\n    public List<Claim> IssuedClaims { get; set; } = new List<Claim>();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/DeviceFlowAuthorizationRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Represents contextual information about a device flow authorization request.\n/// </summary>\npublic class DeviceFlowAuthorizationRequest\n{\n    /// <summary>\n    /// Gets or sets the client.\n    /// </summary>\n    /// <value>\n    /// The client.\n    /// </value>\n    public Client Client { get; set; }\n\n    /// <summary>\n    /// Gets or sets the validated resources.\n    /// </summary>\n    /// <value>\n    /// The scopes requested.\n    /// </value>\n    public ResourceValidationResult ValidatedResources { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/DeviceFlowInteractionResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Request object for device flow interaction\n/// </summary>\npublic class DeviceFlowInteractionResult\n{\n    /// <summary>\n    /// Gets or sets the error description.\n    /// </summary>\n    /// <value>\n    /// The error description.\n    /// </value>\n    public string ErrorDescription { get; private set; }\n\n    /// <summary>\n    /// Gets a value indicating whether this instance is error.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is error; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsError { get; private set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether this instance is access denied.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is access denied; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsAccessDenied { get; set; }\n\n    /// <summary>\n    /// Create failure result\n    /// </summary>\n    /// <param name=\"errorDescription\">The error description.</param>\n    /// <returns></returns>\n    public static DeviceFlowInteractionResult Failure(string errorDescription = null)\n    {\n        return new DeviceFlowInteractionResult\n        {\n            IsError = true,\n            ErrorDescription = errorDescription\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/DiscoveryDocument.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Models;\n\npublic class DiscoveryDocument\n{\n    public string issuer { get; set; }\n    public string jwks_uri { get; set; }\n    public string authorization_endpoint { get; set; }\n    public string token_endpoint { get; set; }\n    public string userinfo_endpoint { get; set; }\n    public string end_session_endpoint { get; set; }\n    public string check_session_iframe { get; set; }\n    public string revocation_endpoint { get; set; }\n    public string introspection_endpoint { get; set; }\n    public bool? frontchannel_logout_supported { get; set; }\n    public bool? frontchannel_logout_session_supported { get; set; }\n    public string[] scopes_supported { get; set; }\n    public string[] claims_supported { get; set; }\n    public string[] response_types_supported { get; set; }\n    public string[] response_modes_supported { get; set; }\n    public string[] grant_types_supported { get; set; }\n    public string[] subject_types_supported { get; set; }\n    public string[] id_token_signing_alg_values_supported { get; set; }\n    public string[] token_endpoint_auth_methods_supported { get; set; }\n    public string[] code_challenge_methods_supported { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Grant.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models a grant the user has given.\n/// </summary>\npublic class Grant\n{\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Gets or sets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public IEnumerable<string> Scopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the creation time.\n    /// </summary>\n    /// <value>\n    /// The creation time.\n    /// </value>\n    public DateTime CreationTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the expiration.\n    /// </summary>\n    /// <value>\n    /// The expiration.\n    /// </value>\n    public DateTime? Expiration { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/GrantTypes.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Models;\n\npublic class GrantTypes\n{\n    public static ICollection<string> Implicit =>\n        new[] { GrantType.Implicit };\n\n    public static ICollection<string> ImplicitAndClientCredentials =>\n        new[]  { GrantType.Implicit, GrantType.ClientCredentials };\n\n    public static ICollection<string> Code =>\n        new[] { GrantType.AuthorizationCode };\n\n    public static ICollection<string> CodeAndClientCredentials =>\n        new[] { GrantType.AuthorizationCode, GrantType.ClientCredentials };\n\n    public static ICollection<string> Hybrid =>\n        new[] { GrantType.Hybrid };\n\n    public static ICollection<string> HybridAndClientCredentials =>\n        new[] { GrantType.Hybrid, GrantType.ClientCredentials };\n\n    public static ICollection<string> ClientCredentials =>\n        new[] { GrantType.ClientCredentials };\n\n    public static ICollection<string> ResourceOwnerPassword =>\n        new[] { GrantType.ResourceOwnerPassword };\n\n    public static ICollection<string> ResourceOwnerPasswordAndClientCredentials =>\n        new[] { GrantType.ResourceOwnerPassword, GrantType.ClientCredentials };\n\n    public static ICollection<string> DeviceFlow =>\n        new[] { GrantType.DeviceFlow };\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/IdentityResources.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Convenience class that defines standard identity resources.\n/// </summary>\npublic static class IdentityResources\n{\n    /// <summary>\n    /// Models the standard openid scope\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Models.IdentityResource\" />\n    public class OpenId : IdentityResource\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"OpenId\"/> class.\n        /// </summary>\n        public OpenId()\n        {\n            Name = IdentityServerConstants.StandardScopes.OpenId;\n            DisplayName = \"Your user identifier\";\n            Required = true;\n            UserClaims.Add(JwtClaimTypes.Subject);\n        }\n    }\n\n    /// <summary>\n    /// Models the standard profile scope\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Models.IdentityResource\" />\n    public class Profile : IdentityResource\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"Profile\"/> class.\n        /// </summary>\n        public Profile()\n        {\n            Name = IdentityServerConstants.StandardScopes.Profile;\n            DisplayName = \"User profile\";\n            Description = \"Your user profile information (first name, last name, etc.)\";\n            Emphasize = true;\n            UserClaims = Constants.ScopeToClaimsMapping[IdentityServerConstants.StandardScopes.Profile].ToList();\n        }\n    }\n\n    /// <summary>\n    /// Models the standard email scope\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Models.IdentityResource\" />\n    public class Email : IdentityResource\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"Email\"/> class.\n        /// </summary>\n        public Email()\n        {\n            Name = IdentityServerConstants.StandardScopes.Email;\n            DisplayName = \"Your email address\";\n            Emphasize = true;\n            UserClaims = (Constants.ScopeToClaimsMapping[IdentityServerConstants.StandardScopes.Email].ToList());\n        }\n    }\n\n    /// <summary>\n    /// Models the standard phone scope\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Models.IdentityResource\" />\n    public class Phone : IdentityResource\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"Phone\"/> class.\n        /// </summary>\n        public Phone()\n        {\n            Name = IdentityServerConstants.StandardScopes.Phone;\n            DisplayName = \"Your phone number\";\n            Emphasize = true;\n            UserClaims = Constants.ScopeToClaimsMapping[IdentityServerConstants.StandardScopes.Phone].ToList();\n        }\n    }\n\n    /// <summary>\n    /// Models the standard address scope\n    /// </summary>\n    /// <seealso cref=\"IdentityServer8.Models.IdentityResource\" />\n    public class Address : IdentityResource\n    {\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"Address\"/> class.\n        /// </summary>\n        public Address()\n        {\n            Name = IdentityServerConstants.StandardScopes.Address;\n            DisplayName = \"Your postal address\";\n            Emphasize = true;\n            UserClaims = Constants.ScopeToClaimsMapping[IdentityServerConstants.StandardScopes.Address].ToList();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/JsonWebKey.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Models;\n\npublic class JsonWebKey\n{\n    public string kty { get; set; }\n    public string use { get; set; }\n    public string kid { get; set; }\n    public string x5t { get; set; }\n    public string e { get; set; }\n    public string n { get; set; }\n    public string[] x5c { get; set; }\n    public string alg { get; set; }\n\n    public string x { get; set; }\n    public string y { get; set; }\n    public string crv { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Messages/AuthorizationRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Represents contextual information about a authorization request.\n/// </summary>\npublic class AuthorizationRequest\n{\n    /// <summary>\n    /// The client.\n    /// </summary>\n    public Client Client { get; set; }\n\n    /// <summary>\n    /// The display mode passed from the authorization request.\n    /// </summary>\n    /// <value>\n    /// The display mode.\n    /// </value>\n    public string DisplayMode { get; set; }\n\n    /// <summary>\n    /// Gets or sets the redirect URI.\n    /// </summary>\n    /// <value>\n    /// The redirect URI.\n    /// </value>\n    public string RedirectUri { get; set; }\n\n    /// <summary>\n    /// The UI locales passed from the authorization request.\n    /// </summary>\n    /// <value>\n    /// The UI locales.\n    /// </value>\n    public string UiLocales { get; set; }\n\n    /// <summary>\n    /// The external identity provider requested. This is used to bypass home realm \n    /// discovery (HRD). This is provided via the <c>\"idp:\"</c> prefix to the <c>acr</c> \n    /// parameter on the authorize request.\n    /// </summary>\n    /// <value>\n    /// The external identity provider identifier.\n    /// </value>\n    public string IdP { get; set; }\n\n    /// <summary>\n    /// The tenant requested. This is provided via the <c>\"tenant:\"</c> prefix to \n    /// the <c>acr</c> parameter on the authorize request.\n    /// </summary>\n    /// <value>\n    /// The tenant.\n    /// </value>\n    public string Tenant { get; set; }\n\n    /// <summary>\n    /// The expected username the user will use to login. This is requested from the client \n    /// via the <c>login_hint</c> parameter on the authorize request.\n    /// </summary>\n    /// <value>\n    /// The LoginHint.\n    /// </value>\n    public string LoginHint { get; set; }\n\n    /// <summary>\n    /// Gets or sets the collection of prompt modes.\n    /// </summary>\n    /// <value>\n    /// The collection of prompt modes.\n    /// </value>\n    public IEnumerable<string> PromptModes { get; set; } = Enumerable.Empty<string>();\n\n    /// <summary>\n    /// The acr values passed from the authorization request.\n    /// </summary>\n    /// <value>\n    /// The acr values.\n    /// </value>\n    public IEnumerable<string> AcrValues { get; set; }\n\n    /// <summary>\n    /// The validated resources.\n    /// </summary>\n    public ResourceValidationResult ValidatedResources { get; set; }\n\n    /// <summary>\n    /// Gets the entire parameter collection.\n    /// </summary>\n    /// <value>\n    /// The parameters.\n    /// </value>\n    public NameValueCollection Parameters { get; }\n\n    /// <summary>\n    /// Gets the validated contents of the request object (if present)\n    /// </summary>\n    /// <value>\n    /// The request object values\n    /// </value>\n    public Dictionary<string, string> RequestObjectValues { get; } = new Dictionary<string, string>();\n\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"AuthorizationRequest\"/> class.\n    /// </summary>\n    public AuthorizationRequest()\n    {\n        // public for testing\n        Parameters = new NameValueCollection();\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"AuthorizationRequest\"/> class.\n    /// </summary>\n    internal AuthorizationRequest(ValidatedAuthorizeRequest request)\n    {\n        Client = request.Client;\n        RedirectUri = request.RedirectUri;\n        DisplayMode = request.DisplayMode;\n        UiLocales = request.UiLocales;\n        IdP = request.GetIdP();\n        Tenant = request.GetTenant();\n        LoginHint = request.LoginHint;\n        PromptModes = request.PromptModes;\n        AcrValues = request.GetAcrValues();\n        ValidatedResources = request.ValidatedResources;\n        Parameters = request.Raw;\n        RequestObjectValues = request.RequestObjectValues;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Messages/ConsentRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models the parameters to identify a request for consent.\n/// </summary>\npublic class ConsentRequest\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ConsentRequest\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"subject\">The subject.</param>\n    public ConsentRequest(AuthorizationRequest request, string subject)\n    {\n        ClientId = request.Client.ClientId;\n        Nonce = request.Parameters[OidcConstants.AuthorizeRequest.Nonce];\n        ScopesRequested = request.Parameters[OidcConstants.AuthorizeRequest.Scope].ParseScopesString();\n        Subject = subject;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ConsentRequest\"/> class.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"subject\">The subject.</param>\n    public ConsentRequest(NameValueCollection parameters, string subject)\n    {\n        ClientId = parameters[OidcConstants.AuthorizeRequest.ClientId];\n        Nonce = parameters[OidcConstants.AuthorizeRequest.Nonce];\n        ScopesRequested = parameters[OidcConstants.AuthorizeRequest.Scope].ParseScopesString();\n        Subject = subject;\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the nonce.\n    /// </summary>\n    /// <value>\n    /// The nonce.\n    /// </value>\n    public string Nonce { get; set; }\n\n    /// <summary>\n    /// Gets or sets the scopes requested.\n    /// </summary>\n    /// <value>\n    /// The scopes requested.\n    /// </value>\n    public IEnumerable<string> ScopesRequested { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public string Subject { get; set; }\n\n    /// <summary>\n    /// Gets the identifier.\n    /// </summary>\n    /// <value>\n    /// The identifier.\n    /// </value>\n    public string Id\n    {\n        get\n        {\n            var normalizedScopes = ScopesRequested?.OrderBy(x => x).Distinct().Aggregate((x, y) => x + \",\" + y);\n            var value = $\"{ClientId}:{Subject}:{Nonce}:{normalizedScopes}\";\n\n            using (var sha = SHA256.Create())\n            {\n                var bytes = Encoding.UTF8.GetBytes(value);\n                var hash = sha.ComputeHash(bytes);\n\n                return Base64Url.Encode(hash);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Messages/ConsentResponse.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models the user's response to the consent screen.\n/// </summary>\npublic class ConsentResponse\n{\n    /// <summary>\n    /// Error, if any, for the consent response.\n    /// </summary>\n    public AuthorizationError? Error { get; set; }\n\n    /// <summary>\n    /// Error description.\n    /// </summary>\n    public string ErrorDescription { get; set; }\n\n    /// <summary>\n    /// Gets if consent was granted.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if consent was granted; otherwise, <c>false</c>.\n    /// </value>\n    public bool Granted => ScopesValuesConsented != null && ScopesValuesConsented.Any() && Error == null;\n\n    /// <summary>\n    /// Gets or sets the scope values consented to.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public IEnumerable<string> ScopesValuesConsented { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the user wishes the consent to be remembered.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if consent is to be remembered; otherwise, <c>false</c>.\n    /// </value>\n    public bool RememberConsent { get; set; }\n\n    /// <summary>\n    /// Gets the description of the device.\n    /// </summary>\n    /// <value>\n    /// The description of the device.\n    /// </value>\n    public string Description { get; set; }\n}\n\n/// <summary>\n/// Enum to model interaction authorization errors.\n/// </summary>\npublic enum AuthorizationError\n{\n    /// <summary>\n    /// Access denied\n    /// </summary>\n    AccessDenied,\n\n    /// <summary>\n    /// Interaction required\n    /// </summary>\n    InteractionRequired,\n\n    /// <summary>\n    /// Login required\n    /// </summary>\n    LoginRequired,\n\n    /// <summary>\n    /// Account selection required\n    /// </summary>\n    AccountSelectionRequired,\n\n    /// <summary>\n    /// Consent required\n    /// </summary>\n    ConsentRequired\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Messages/ErrorMessage.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models the data for the error page.\n/// </summary>\npublic class ErrorMessage\n{\n    /// <summary>\n    /// The display mode passed from the authorization request.\n    /// </summary>\n    /// <value>\n    /// The display mode.\n    /// </value>\n    public string DisplayMode { get; set; }\n\n    /// <summary>\n    /// The UI locales passed from the authorization request.\n    /// </summary>\n    /// <value>\n    /// The UI locales.\n    /// </value>\n    public string UiLocales { get; set; }\n\n    /// <summary>\n    /// Gets or sets the error code.\n    /// </summary>\n    /// <value>\n    /// The error code.\n    /// </value>\n    public string Error { get; set; }\n\n    /// <summary>\n    /// Gets or sets the error description.\n    /// </summary>\n    /// <value>\n    /// The error description.\n    /// </value>\n    public string ErrorDescription { get; set; }\n\n    /// <summary>\n    /// The per-request identifier. This can be used to display to the end user and can be used in diagnostics.\n    /// </summary>\n    /// <value>\n    /// The request identifier.\n    /// </value>\n    public string RequestId { get; set; }\n\n    /// <summary>\n    /// The redirect URI.\n    /// </summary>\n    public string RedirectUri { get; set; }\n    \n    /// <summary>\n    /// The response mode.\n    /// </summary>\n    public string ResponseMode { get; set; }\n\n    /// <summary>\n    /// The client id making the request (if available).\n    /// </summary>\n    public string ClientId { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Messages/LogoutRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models the validated singout context.\n/// </summary>\npublic class LogoutMessage\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"LogoutMessage\"/> class.\n    /// </summary>\n    public LogoutMessage()\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"LogoutMessage\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    public LogoutMessage(ValidatedEndSessionRequest request)\n    {\n        if (request != null)\n        {\n            if (request.Raw != null)\n            {\n                Parameters = request.Raw.ToFullDictionary();\n            }\n\n            // optimize params sent to logout page, since we'd like to send them in URL (not as cookie)\n            Parameters.Remove(OidcConstants.EndSessionRequest.IdTokenHint);\n            Parameters.Remove(OidcConstants.EndSessionRequest.PostLogoutRedirectUri);\n            Parameters.Remove(OidcConstants.EndSessionRequest.State);\n\n            ClientId = request.Client?.ClientId;\n            ClientName = request.Client?.ClientName;\n            SubjectId = request.Subject?.GetSubjectId();\n            SessionId = request.SessionId;\n            ClientIds = request.ClientIds;\n\n            if (request.PostLogOutUri != null)\n            {\n                PostLogoutRedirectUri = request.PostLogOutUri;\n                if (request.State != null)\n                {\n                    PostLogoutRedirectUri = PostLogoutRedirectUri.AddQueryString(OidcConstants.EndSessionRequest.State, request.State);\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client name.\n    /// </summary>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the post logout redirect URI.\n    /// </summary>\n    public string PostLogoutRedirectUri { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject identifier for the user at logout time.\n    /// </summary>\n    public string SubjectId { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the session identifier for the user at logout time.\n    /// </summary>\n    public string SessionId { get; set; }\n\n    /// <summary>\n    ///  Ids of clients known to have an authentication session for user at end session time\n    /// </summary>\n    public IEnumerable<string> ClientIds { get; set; }\n\n    /// <summary>\n    /// Gets the entire parameter collection.\n    /// </summary>\n    public IDictionary<string, string[]> Parameters { get; set; } = new Dictionary<string, string[]>();\n\n    /// <summary>\n    ///  Flag to indicate if the payload contains useful information or not to avoid serailization.\n    /// </summary>\n    internal bool ContainsPayload => ClientId.IsPresent() || ClientIds?.Any() == true;\n}\n\n/// <summary>\n/// Models the request from a client to sign the user out.\n/// </summary>\npublic class LogoutRequest\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"LogoutRequest\"/> class.\n    /// </summary>\n    /// <param name=\"iframeUrl\">The iframe URL.</param>\n    /// <param name=\"message\">The message.</param>\n    public LogoutRequest(string iframeUrl, LogoutMessage message)\n    {\n        if (message != null)\n        {\n            ClientId = message.ClientId;\n            ClientName = message.ClientName;\n            PostLogoutRedirectUri = message.PostLogoutRedirectUri;\n            SubjectId = message.SubjectId;\n            SessionId = message.SessionId;\n            ClientIds = message.ClientIds;\n            Parameters = message.Parameters.FromFullDictionary();\n        }\n\n        SignOutIFrameUrl = iframeUrl;\n    }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client name.\n    /// </summary>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the post logout redirect URI.\n    /// </summary>\n    public string PostLogoutRedirectUri { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject identifier for the user at logout time.\n    /// </summary>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the session identifier for the user at logout time.\n    /// </summary>\n    public string SessionId { get; set; }\n\n    /// <summary>\n    ///  Ids of clients known to have an authentication session for user at end session time\n    /// </summary>\n    public IEnumerable<string> ClientIds { get; set; }\n\n    /// <summary>\n    /// Gets the entire parameter collection.\n    /// </summary>\n    public NameValueCollection Parameters { get; } = new NameValueCollection();\n\n    /// <summary>\n    /// Gets or sets the sign out iframe URL.\n    /// </summary>\n    /// <value>\n    /// The sign out iframe URL.\n    /// </value>\n    public string SignOutIFrameUrl { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the user should be prompted for signout.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if the signout prompt should be shown; otherwise, <c>false</c>.\n    /// </value>\n    public bool ShowSignoutPrompt => ClientId.IsMissing();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/Messages/Message.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Base class for data that needs to be written out as cookies.\n/// </summary>\npublic class Message<TModel>\n{\n    /// <summary>\n    /// Should only be used from unit tests\n    /// </summary>\n    /// <param name=\"data\"></param>\n    internal Message(TModel data) : this(data, DateTime.UtcNow)\n    {\n    }\n\n    /// <summary>\n    /// For JSON serializer. \n    /// System.Text.Json.JsonSerializer requires public, parameterless constructor\n    /// </summary>\n    public Message()\n    {\n    }\n    \n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Message{TModel}\"/> class.\n    /// </summary>\n    /// <param name=\"data\">The data.</param>\n    /// <param name=\"now\">The current UTC date/time.</param>\n    public Message(TModel data, DateTime now)\n    {\n        Created = now.Ticks;\n        Data = data;\n    }\n\n    /// <summary>\n    /// Gets or sets the UTC ticks the <see cref=\"Message{TModel}\" /> was created.\n    /// </summary>\n    /// <value>\n    /// The created UTC ticks.\n    /// </value>\n    public long Created { get; set; }\n\n    /// <summary>\n    /// Gets or sets the data.\n    /// </summary>\n    /// <value>\n    /// The data.\n    /// </value>\n    public TModel Data { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/ParsedSecret.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Represents a secret extracted from the HttpContext\n/// </summary>\npublic class ParsedSecret\n{\n    /// <summary>\n    /// Gets or sets the identifier associated with this secret\n    /// </summary>\n    /// <value>\n    /// The identifier.\n    /// </value>\n    public string Id { get; set; }\n\n    /// <summary>\n    /// Gets or sets the credential to verify the secret\n    /// </summary>\n    /// <value>\n    /// The credential.\n    /// </value>\n    public object Credential { get; set; }\n\n    /// <summary>\n    /// Gets or sets the type of the secret\n    /// </summary>\n    /// <value>\n    /// The type.\n    /// </value>\n    public string Type { get; set; }\n\n    /// <summary>\n    /// Gets or sets additional properties.\n    /// </summary>\n    /// <value>\n    /// The properties.\n    /// </value>\n    public Dictionary<string, string> Properties { get; set; } = new Dictionary<string, string>();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/SecurityKeyInfo.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Information about a security key\n/// </summary>\npublic class SecurityKeyInfo\n{\n    /// <summary>\n    /// The key\n    /// </summary>\n    public SecurityKey Key { get; set; }\n\n    /// <summary>\n    /// The signing algorithm\n    /// </summary>\n    public string SigningAlgorithm { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/TokenCreationRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models the data to create a token from a validated request.\n/// </summary>\npublic class TokenCreationRequest\n{\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n\n    /// <summary>\n    /// Gets or sets the validated resources.\n    /// </summary>\n    /// <value>\n    /// The resources.\n    /// </value>\n    public ResourceValidationResult ValidatedResources { get; set; }\n\n    /// <summary>\n    /// Gets or sets the validated request.\n    /// </summary>\n    /// <value>\n    /// The validated request.\n    /// </value>\n    public ValidatedRequest ValidatedRequest { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether [include all identity claims].\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if [include all identity claims]; otherwise, <c>false</c>.\n    /// </value>\n    public bool IncludeAllIdentityClaims { get; set; }\n\n    /// <summary>\n    /// Gets or sets the access token to hash.\n    /// </summary>\n    /// <value>\n    /// The access token to hash.\n    /// </value>\n    public string AccessTokenToHash { get; set; }\n\n    /// <summary>\n    /// Gets or sets the authorization code to hash.\n    /// </summary>\n    /// <value>\n    /// The authorization code to hash.\n    /// </value>\n    public string AuthorizationCodeToHash { get; set; }\n\n    /// <summary>\n    /// Gets or sets pre-hashed state\n    /// </summary>\n    /// <value>\n    /// The pre-hashed state\n    /// </value>\n    public string StateHash { get; set; }\n\n    /// <summary>\n    /// Gets or sets the nonce.\n    /// </summary>\n    /// <value>\n    /// The nonce.\n    /// </value>\n    public string Nonce { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Called to validate the <see cref=\"TokenCreationRequest\"/> before it is processed.\n    /// </summary>\n    public void Validate()\n    {\n        if (ValidatedResources == null) throw new ArgumentNullException(nameof(ValidatedResources));\n        if (ValidatedRequest == null) throw new ArgumentNullException(nameof(ValidatedRequest));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Models/TokenRequestErrors.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Token request errors\n/// </summary>\npublic enum TokenRequestErrors\n{\n    /// <summary>\n    /// invalid_request\n    /// </summary>\n    InvalidRequest,\n\n    /// <summary>\n    /// invalid_client\n    /// </summary>\n    InvalidClient,\n\n    /// <summary>\n    /// invalid_grant\n    /// </summary>\n    InvalidGrant,\n\n    /// <summary>\n    /// unauthorized_client\n    /// </summary>\n    UnauthorizedClient,\n\n    /// <summary>\n    /// unsupported_grant_type\n    /// </summary>\n    UnsupportedGrantType,\n\n    /// <summary>\n    /// invalid_scope\n    /// </summary>\n    InvalidScope,\n\n    /// <summary>\n    /// invalid_target\n    /// </summary>\n    InvalidTarget\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Properties/AssemblyInfo.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n[assembly: InternalsVisibleTo(\"IdentityServer.UnitTests, PublicKey = 002400000480000094000000060200000024000052534131000400000100010057b24455efc2a317afb0644a2169c05644e439985c42cf4eb98706779651801add1da073da8b5e253e8d4335d59b3197bb941ebe943c63f7efbc3005c428f0d69b809e86bdc828fa431fae4b71005f26b52a26a3ee5cf0f6fdf744d4534a7a503683123f58e1082828b018245d2e40d8542f72a623c01490d73a5d3ff94a88c5\")]\n[assembly: InternalsVisibleTo(\"IdentityServer.IntegrationTests, PublicKey = 002400000480000094000000060200000024000052534131000400000100010057b24455efc2a317afb0644a2169c05644e439985c42cf4eb98706779651801add1da073da8b5e253e8d4335d59b3197bb941ebe943c63f7efbc3005c428f0d69b809e86bdc828fa431fae4b71005f26b52a26a3ee5cf0f6fdf744d4534a7a503683123f58e1082828b018245d2e40d8542f72a623c01490d73a5d3ff94a88c5\")]\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/AuthorizeInteractionResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Default logic for determining if user must login or consent when making requests to the authorization endpoint.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.IAuthorizeInteractionResponseGenerator\" />\npublic class AuthorizeInteractionResponseGenerator : IAuthorizeInteractionResponseGenerator\n{\n    /// <summary>\n    /// The logger.\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The consent service.\n    /// </summary>\n    protected readonly IConsentService Consent;\n\n    /// <summary>\n    /// The profile service.\n    /// </summary>\n    protected readonly IProfileService Profile;\n\n    /// <summary>\n    /// The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"AuthorizeInteractionResponseGenerator\"/> class.\n    /// </summary>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"logger\">The logger.</param>\n    /// <param name=\"consent\">The consent.</param>\n    /// <param name=\"profile\">The profile.</param>\n    public AuthorizeInteractionResponseGenerator(\n        ISystemClock clock,\n        ILogger<AuthorizeInteractionResponseGenerator> logger,\n        IConsentService consent, \n        IProfileService profile)\n    {\n        Clock = clock;\n        Logger = logger;\n        Consent = consent;\n        Profile = profile;\n    }\n\n    /// <summary>\n    /// Processes the interaction logic.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"consent\">The consent.</param>\n    /// <returns></returns>\n    public virtual async Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)\n    {\n        Logger.LogTrace(\"ProcessInteractionAsync\");\n\n        if (consent != null && consent.Granted == false && consent.Error.HasValue && request.Subject.IsAuthenticated() == false)\n        {\n            // special case when anonymous user has issued an error prior to authenticating\n            Logger.LogInformation(\"Error: User consent result: {error}\", consent.Error);\n\n            var error = consent.Error switch\n            {\n                AuthorizationError.AccountSelectionRequired => OidcConstants.AuthorizeErrors.AccountSelectionRequired,\n                AuthorizationError.ConsentRequired => OidcConstants.AuthorizeErrors.ConsentRequired,\n                AuthorizationError.InteractionRequired => OidcConstants.AuthorizeErrors.InteractionRequired,\n                AuthorizationError.LoginRequired => OidcConstants.AuthorizeErrors.LoginRequired,\n                _ => OidcConstants.AuthorizeErrors.AccessDenied\n            };\n            \n            return new InteractionResponse\n            {\n                Error = error,\n                ErrorDescription = consent.ErrorDescription\n            };\n        }\n\n        var result = await ProcessLoginAsync(request);\n        \n        if (!result.IsLogin && !result.IsError && !result.IsRedirect)\n        {\n            result = await ProcessConsentAsync(request, consent);\n        }\n\n        if ((result.IsLogin || result.IsConsent || result.IsRedirect) && request.PromptModes.Contains(OidcConstants.PromptModes.None))\n        {\n            // prompt=none means do not show the UI\n            Logger.LogInformation(\"Changing response to LoginRequired: prompt=none was requested\");\n            result = new InteractionResponse\n            {\n                Error = result.IsLogin ? OidcConstants.AuthorizeErrors.LoginRequired :\n                            result.IsConsent ? OidcConstants.AuthorizeErrors.ConsentRequired : \n                                OidcConstants.AuthorizeErrors.InteractionRequired\n            };\n        }\n\n        return result;\n    }\n\n    /// <summary>\n    /// Processes the login logic.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    protected internal virtual async Task<InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request)\n    {\n        if (request.PromptModes.Contains(OidcConstants.PromptModes.Login) ||\n            request.PromptModes.Contains(OidcConstants.PromptModes.SelectAccount))\n        {\n            Logger.LogInformation(\"Showing login: request contains prompt={0}\", request.PromptModes.ToSpaceSeparatedString());\n\n            // remove prompt so when we redirect back in from login page\n            // we won't think we need to force a prompt again\n            request.RemovePrompt();\n            \n            return new InteractionResponse { IsLogin = true };\n        }\n\n        // unauthenticated user\n        var isAuthenticated = request.Subject.IsAuthenticated();\n        \n        // user de-activated\n        bool isActive = false;\n\n        if (isAuthenticated)\n        {\n            var isActiveCtx = new IsActiveContext(request.Subject, request.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizeEndpoint);\n            await Profile.IsActiveAsync(isActiveCtx);\n            \n            isActive = isActiveCtx.IsActive;\n        }\n\n        if (!isAuthenticated || !isActive)\n        {\n            if (!isAuthenticated)\n            {\n                Logger.LogInformation(\"Showing login: User is not authenticated\");\n            }\n            else if (!isActive)\n            {\n                Logger.LogInformation(\"Showing login: User is not active\");\n            }\n\n            return new InteractionResponse { IsLogin = true };\n        }\n\n        // check current idp\n        var currentIdp = request.Subject.GetIdentityProvider();\n\n        // check if idp login hint matches current provider\n        var idp = request.GetIdP();\n        if (idp.IsPresent())\n        {\n            if (idp != currentIdp)\n            {\n                Logger.LogInformation(\"Showing login: Current IdP ({currentIdp}) is not the requested IdP ({idp})\", currentIdp, idp);\n                return new InteractionResponse { IsLogin = true };\n            }\n        }\n\n        // check authentication freshness\n        if (request.MaxAge.HasValue)\n        {\n            var authTime = request.Subject.GetAuthenticationTime();\n            if (Clock.UtcNow > authTime.AddSeconds(request.MaxAge.Value))\n            {\n                Logger.LogInformation(\"Showing login: Requested MaxAge exceeded.\");\n\n                return new InteractionResponse { IsLogin = true };\n            }\n        }\n\n        // check local idp restrictions\n        if (currentIdp == IdentityServerConstants.LocalIdentityProvider)\n        {\n            if (!request.Client.EnableLocalLogin)\n            {\n                Logger.LogInformation(\"Showing login: User logged in locally, but client does not allow local logins\");\n                return new InteractionResponse { IsLogin = true };\n            }\n        }\n        // check external idp restrictions if user not using local idp\n        else if (request.Client.IdentityProviderRestrictions != null && \n            request.Client.IdentityProviderRestrictions.Any() &&\n            !request.Client.IdentityProviderRestrictions.Contains(currentIdp))\n        {\n            Logger.LogInformation(\"Showing login: User is logged in with idp: {idp}, but idp not in client restriction list.\", currentIdp);\n            return new InteractionResponse { IsLogin = true };\n        }\n\n        // check client's user SSO timeout\n        if (request.Client.UserSsoLifetime.HasValue)\n        {\n            var authTimeEpoch = request.Subject.GetAuthenticationTimeEpoch();\n            var nowEpoch = Clock.UtcNow.ToUnixTimeSeconds();\n\n            var diff = nowEpoch - authTimeEpoch;\n            if (diff > request.Client.UserSsoLifetime.Value)\n            {\n                Logger.LogInformation(\"Showing login: User's auth session duration: {sessionDuration} exceeds client's user SSO lifetime: {userSsoLifetime}.\", diff, request.Client.UserSsoLifetime);\n                return new InteractionResponse { IsLogin = true };\n            }\n        }\n\n        return new InteractionResponse();\n    }\n\n    /// <summary>\n    /// Processes the consent logic.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"consent\">The consent.</param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\"></exception>\n    /// <exception cref=\"ArgumentException\">Invalid PromptMode</exception>\n    protected internal virtual async Task<InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)\n    {\n        if (request == null) throw new ArgumentNullException(nameof(request));\n\n        if (request.PromptModes.Any() &&\n            !request.PromptModes.Contains(OidcConstants.PromptModes.None) &&\n            !request.PromptModes.Contains(OidcConstants.PromptModes.Consent))\n        {\n            Logger.LogError(\"Invalid prompt mode: {promptMode}\", request.PromptModes.ToSpaceSeparatedString());\n            throw new ArgumentException(\"Invalid PromptMode\");\n        }\n\n        var consentRequired = await Consent.RequiresConsentAsync(request.Subject, request.Client, request.ValidatedResources.ParsedScopes);\n\n        if (consentRequired && request.PromptModes.Contains(OidcConstants.PromptModes.None))\n        {\n            Logger.LogInformation(\"Error: prompt=none requested, but consent is required.\");\n\n            return new InteractionResponse\n            {\n                Error = OidcConstants.AuthorizeErrors.ConsentRequired\n            };\n        }\n\n        if (request.PromptModes.Contains(OidcConstants.PromptModes.Consent) || consentRequired)\n        {\n            var response = new InteractionResponse();\n\n            // did user provide consent\n            if (consent == null)\n            {\n                // user was not yet shown conset screen\n                response.IsConsent = true;\n                Logger.LogInformation(\"Showing consent: User has not yet consented\");\n            }\n            else\n            {\n                request.WasConsentShown = true;\n                Logger.LogTrace(\"Consent was shown to user\");\n\n                // user was shown consent -- did they say yes or no\n                if (consent.Granted == false)\n                {\n                    // no need to show consent screen again\n                    // build error to return to client\n                    Logger.LogInformation(\"Error: User consent result: {error}\", consent.Error);\n\n                    var error = consent.Error switch\n                    {\n                        AuthorizationError.AccountSelectionRequired => OidcConstants.AuthorizeErrors.AccountSelectionRequired,\n                        AuthorizationError.ConsentRequired => OidcConstants.AuthorizeErrors.ConsentRequired,\n                        AuthorizationError.InteractionRequired => OidcConstants.AuthorizeErrors.InteractionRequired,\n                        AuthorizationError.LoginRequired => OidcConstants.AuthorizeErrors.LoginRequired,\n                        _ => OidcConstants.AuthorizeErrors.AccessDenied\n                    };\n                    \n                    response.Error = error;\n                    response.ErrorDescription = consent.ErrorDescription;\n                }\n                else\n                {\n                    // double check that required scopes are in the list of consented scopes\n                    var requiredScopes = request.ValidatedResources.GetRequiredScopeValues();\n                    var valid = requiredScopes.All(x => consent.ScopesValuesConsented.Contains(x));\n                    if (valid == false)\n                    {\n                        response.Error = OidcConstants.AuthorizeErrors.AccessDenied;\n                        Logger.LogInformation(\"Error: User denied consent to required scopes\");\n                    }\n                    else\n                    {\n                        // they said yes, set scopes they chose\n                        request.Description = consent.Description;\n                        request.ValidatedResources = request.ValidatedResources.Filter(consent.ScopesValuesConsented);\n                        Logger.LogInformation(\"User consented to scopes: {scopes}\", consent.ScopesValuesConsented);\n\n                        if (request.Client.AllowRememberConsent)\n                        {\n                            // remember consent\n                            var parsedScopes = Enumerable.Empty<ParsedScopeValue>();\n                            if (consent.RememberConsent)\n                            {\n                                // remember what user actually selected\n                                parsedScopes = request.ValidatedResources.ParsedScopes;\n                                Logger.LogDebug(\"User indicated to remember consent for scopes: {scopes}\", request.ValidatedResources.RawScopeValues);\n                            }\n\n                            await Consent.UpdateConsentAsync(request.Subject, request.Client, parsedScopes);\n                        }\n                    }\n                }\n            }\n\n            return response;\n        }\n\n        return new InteractionResponse();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/AuthorizeResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// The authorize response generator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.IAuthorizeResponseGenerator\" />\npublic class AuthorizeResponseGenerator : IAuthorizeResponseGenerator\n{\n    /// <summary>\n    /// The token service\n    /// </summary>\n    protected readonly ITokenService TokenService;\n\n    /// <summary>\n    /// The authorization code store\n    /// </summary>\n    protected readonly IAuthorizationCodeStore AuthorizationCodeStore;\n\n    /// <summary>\n    /// The event service\n    /// </summary>\n    protected readonly IEventService Events;\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// The key material service\n    /// </summary>\n    protected readonly IKeyMaterialService KeyMaterialService;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"AuthorizeResponseGenerator\"/> class.\n    /// </summary>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"logger\">The logger.</param>\n    /// <param name=\"tokenService\">The token service.</param>\n    /// <param name=\"keyMaterialService\"></param>\n    /// <param name=\"authorizationCodeStore\">The authorization code store.</param>\n    /// <param name=\"events\">The events.</param>\n    public AuthorizeResponseGenerator(\n        ISystemClock clock,\n        ITokenService tokenService,\n        IKeyMaterialService keyMaterialService,\n        IAuthorizationCodeStore authorizationCodeStore,\n        ILogger<AuthorizeResponseGenerator> logger,\n        IEventService events)\n    {\n        Clock = clock;\n        TokenService = tokenService;\n        KeyMaterialService = keyMaterialService;\n        AuthorizationCodeStore = authorizationCodeStore;\n        Events = events;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Creates the response\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">invalid grant type: \" + request.GrantType</exception>\n    public virtual async Task<AuthorizeResponse> CreateResponseAsync(ValidatedAuthorizeRequest request)\n    {\n        if (request.GrantType == GrantType.AuthorizationCode)\n        {\n            return await CreateCodeFlowResponseAsync(request);\n        }\n        if (request.GrantType == GrantType.Implicit)\n        {\n            return await CreateImplicitFlowResponseAsync(request);\n        }\n        if (request.GrantType == GrantType.Hybrid)\n        {\n            return await CreateHybridFlowResponseAsync(request);\n        }\n\n        Logger.LogError(\"Unsupported grant type: \" + request.GrantType);\n        throw new InvalidOperationException(\"invalid grant type: \" + request.GrantType);\n    }\n\n    /// <summary>\n    /// Creates the response for a hybrid flow request\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <returns></returns>\n    protected virtual async Task<AuthorizeResponse> CreateHybridFlowResponseAsync(ValidatedAuthorizeRequest request)\n    {\n        Logger.LogDebug(\"Creating Hybrid Flow response.\");\n\n        var code = await CreateCodeAsync(request);\n        var id = await AuthorizationCodeStore.StoreAuthorizationCodeAsync(code);\n\n        var response = await CreateImplicitFlowResponseAsync(request, id);\n        response.Code = id;\n\n        return response;\n    }\n\n    /// <summary>\n    /// Creates the response for a code flow request\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <returns></returns>\n    protected virtual async Task<AuthorizeResponse> CreateCodeFlowResponseAsync(ValidatedAuthorizeRequest request)\n    {\n        Logger.LogDebug(\"Creating Authorization Code Flow response.\");\n\n        var code = await CreateCodeAsync(request);\n        var id = await AuthorizationCodeStore.StoreAuthorizationCodeAsync(code);\n\n        var response = new AuthorizeResponse\n        {\n            Request = request,\n            Code = id,\n            SessionState = request.GenerateSessionStateValue()\n        };\n\n        return response;\n    }\n\n    /// <summary>\n    /// Creates the response for a implicit flow request\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <param name=\"authorizationCode\"></param>\n    /// <returns></returns>\n    protected virtual async Task<AuthorizeResponse> CreateImplicitFlowResponseAsync(ValidatedAuthorizeRequest request, string authorizationCode = null)\n    {\n        Logger.LogDebug(\"Creating Implicit Flow response.\");\n\n        string accessTokenValue = null;\n        int accessTokenLifetime = 0;\n\n        var responseTypes = request.ResponseType.FromSpaceSeparatedString();\n\n        if (responseTypes.Contains(OidcConstants.ResponseTypes.Token))\n        {\n            var tokenRequest = new TokenCreationRequest\n            {\n                Subject = request.Subject,\n                ValidatedResources = request.ValidatedResources,\n\n                ValidatedRequest = request\n            };\n\n            var accessToken = await TokenService.CreateAccessTokenAsync(tokenRequest);\n            accessTokenLifetime = accessToken.Lifetime;\n\n            accessTokenValue = await TokenService.CreateSecurityTokenAsync(accessToken);\n        }\n\n        string jwt = null;\n        if (responseTypes.Contains(OidcConstants.ResponseTypes.IdToken))\n        {\n            string stateHash = null;\n            if (request.State.IsPresent())\n            {\n                var credential = await KeyMaterialService.GetSigningCredentialsAsync(request.Client.AllowedIdentityTokenSigningAlgorithms);\n                if (credential == null)\n                {\n                    throw new InvalidOperationException(\"No signing credential is configured.\");\n                }\n\n                var algorithm = credential.Algorithm;\n                stateHash = CryptoHelper.CreateHashClaimValue(request.State, algorithm);\n            }\n\n            var tokenRequest = new TokenCreationRequest\n            {\n                ValidatedRequest = request,\n                Subject = request.Subject,\n                ValidatedResources = request.ValidatedResources,\n                Nonce = request.Raw.Get(OidcConstants.AuthorizeRequest.Nonce),\n                IncludeAllIdentityClaims = !request.AccessTokenRequested,\n                AccessTokenToHash = accessTokenValue,\n                AuthorizationCodeToHash = authorizationCode,\n                StateHash = stateHash\n            };\n\n            var idToken = await TokenService.CreateIdentityTokenAsync(tokenRequest);\n            jwt = await TokenService.CreateSecurityTokenAsync(idToken);\n        }\n\n        var response = new AuthorizeResponse\n        {\n            Request = request,\n            AccessToken = accessTokenValue,\n            AccessTokenLifetime = accessTokenLifetime,\n            IdentityToken = jwt,\n            SessionState = request.GenerateSessionStateValue()\n        };\n\n        return response;\n    }\n\n    /// <summary>\n    /// Creates an authorization code\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <returns></returns>\n    protected virtual async Task<AuthorizationCode> CreateCodeAsync(ValidatedAuthorizeRequest request)\n    {\n        string stateHash = null;\n        if (request.State.IsPresent())\n        {\n            var credential = await KeyMaterialService.GetSigningCredentialsAsync(request.Client.AllowedIdentityTokenSigningAlgorithms);\n            if (credential == null)\n            {\n                throw new InvalidOperationException(\"No signing credential is configured.\");\n            }\n\n            var algorithm = credential.Algorithm;\n            stateHash = CryptoHelper.CreateHashClaimValue(request.State, algorithm);\n        }\n\n        var code = new AuthorizationCode\n        {\n            CreationTime = Clock.UtcNow.UtcDateTime,\n            ClientId = request.Client.ClientId,\n            Lifetime = request.Client.AuthorizationCodeLifetime,\n            Subject = request.Subject,\n            SessionId = request.SessionId,\n            Description = request.Description,\n            CodeChallenge = request.CodeChallenge.Sha256(),\n            CodeChallengeMethod = request.CodeChallengeMethod,\n\n            IsOpenId = request.IsOpenIdRequest,\n            RequestedScopes = request.ValidatedResources.RawScopeValues,\n            RedirectUri = request.RedirectUri,\n            Nonce = request.Nonce,\n            StateHash = stateHash,\n\n            WasConsentShown = request.WasConsentShown\n        };\n\n        return code;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/DeviceAuthorizationResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// The device authorizaiton response generator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.IDeviceAuthorizationResponseGenerator\" />\npublic class DeviceAuthorizationResponseGenerator : IDeviceAuthorizationResponseGenerator\n{\n    /// <summary>\n    /// The options\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// The user code service\n    /// </summary>\n    protected readonly IUserCodeService UserCodeService;\n\n    /// <summary>\n    /// The device flow code service\n    /// </summary>\n    protected readonly IDeviceFlowCodeService DeviceFlowCodeService;\n\n    /// <summary>\n    /// The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceAuthorizationResponseGenerator\"/> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"userCodeService\">The user code service.</param>\n    /// <param name=\"deviceFlowCodeService\">The device flow code service.</param>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DeviceAuthorizationResponseGenerator(IdentityServerOptions options, IUserCodeService userCodeService, IDeviceFlowCodeService deviceFlowCodeService, ISystemClock clock, ILogger<DeviceAuthorizationResponseGenerator> logger)\n    {\n        Options = options;\n        UserCodeService = userCodeService;\n        DeviceFlowCodeService = deviceFlowCodeService;\n        Clock = clock;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Processes the response.\n    /// </summary>\n    /// <param name=\"validationResult\">The validation result.</param>\n    /// <param name=\"baseUrl\">The base URL.</param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\">validationResult or Client</exception>\n    /// <exception cref=\"ArgumentException\">Value cannot be null or whitespace. - baseUrl</exception>\n    public virtual async Task<DeviceAuthorizationResponse> ProcessAsync(DeviceAuthorizationRequestValidationResult validationResult, string baseUrl)\n    {\n        if (validationResult == null) throw new ArgumentNullException(nameof(validationResult));\n        if (validationResult.ValidatedRequest.Client == null) throw new ArgumentNullException(nameof(validationResult.ValidatedRequest.Client));\n        if (string.IsNullOrWhiteSpace(baseUrl)) throw new ArgumentException(\"Value cannot be null or whitespace.\", nameof(baseUrl));\n\n        Logger.LogTrace(\"Creating response for device authorization request\");\n\n        var response = new DeviceAuthorizationResponse();\n        \n        // generate user_code\n        var userCodeGenerator = await UserCodeService.GetGenerator(\n            validationResult.ValidatedRequest.Client.UserCodeType ??\n            Options.DeviceFlow.DefaultUserCodeType);\n        \n        var retryCount = 0;\n\n        while (retryCount < userCodeGenerator.RetryLimit)\n        {\n            var userCode = await userCodeGenerator.GenerateAsync();\n            \n            var deviceCode = await DeviceFlowCodeService.FindByUserCodeAsync(userCode);\n            if (deviceCode == null)\n            {\n                response.UserCode = userCode;\n                break;\n            }\n\n            retryCount++;\n        }\n\n        if (response.UserCode == null)\n        {\n            throw new InvalidOperationException(\"Unable to create unique device flow user code\");\n        }\n\n        // generate verification URIs\n        response.VerificationUri = Options.UserInteraction.DeviceVerificationUrl;\n        if (response.VerificationUri.IsLocalUrl())\n        {\n            // if url is relative, parse absolute URL\n            response.VerificationUri = baseUrl.RemoveTrailingSlash() + Options.UserInteraction.DeviceVerificationUrl;\n        }\n        \n        if (!string.IsNullOrWhiteSpace(Options.UserInteraction.DeviceVerificationUserCodeParameter))\n        {\n            response.VerificationUriComplete =\n                $\"{response.VerificationUri}?{Options.UserInteraction.DeviceVerificationUserCodeParameter}={response.UserCode}\";\n        }\n\n        // expiration\n        response.DeviceCodeLifetime = validationResult.ValidatedRequest.Client.DeviceCodeLifetime;\n\n        // interval\n        response.Interval = Options.DeviceFlow.Interval;\n\n        // store device request (device code & user code)\n        response.DeviceCode = await DeviceFlowCodeService.StoreDeviceAuthorizationAsync(response.UserCode, new DeviceCode\n        {\n            Description = validationResult.ValidatedRequest.Description,\n            ClientId = validationResult.ValidatedRequest.Client.ClientId,\n            IsOpenId = validationResult.ValidatedRequest.IsOpenIdRequest,\n            Lifetime = response.DeviceCodeLifetime,\n            CreationTime = Clock.UtcNow.UtcDateTime,\n            RequestedScopes = validationResult.ValidatedRequest.ValidatedResources.RawScopeValues\n        });\n\n        return response;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/DiscoveryResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\nusing JsonWebKey = Microsoft.IdentityModel.Tokens.JsonWebKey;\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Default implementation of the discovery endpoint response generator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.IDiscoveryResponseGenerator\" />\npublic class DiscoveryResponseGenerator : IDiscoveryResponseGenerator\n{\n    /// <summary>\n    /// The options\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// The extension grants validator\n    /// </summary>\n    protected readonly ExtensionGrantValidator ExtensionGrants;\n\n    /// <summary>\n    /// The key material service\n    /// </summary>\n    protected readonly IKeyMaterialService Keys;\n\n    /// <summary>\n    /// The resource owner validator\n    /// </summary>\n    protected readonly IResourceOwnerPasswordValidator ResourceOwnerValidator;\n\n    /// <summary>\n    /// The resource store\n    /// </summary>\n    protected readonly IResourceStore ResourceStore;\n\n    /// <summary>\n    /// The secret parsers\n    /// </summary>\n    protected readonly ISecretsListParser SecretParsers;\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DiscoveryResponseGenerator\"/> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"resourceStore\">The resource store.</param>\n    /// <param name=\"keys\">The keys.</param>\n    /// <param name=\"extensionGrants\">The extension grants.</param>\n    /// <param name=\"secretParsers\">The secret parsers.</param>\n    /// <param name=\"resourceOwnerValidator\">The resource owner validator.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DiscoveryResponseGenerator(\n        IdentityServerOptions options,\n        IResourceStore resourceStore,\n        IKeyMaterialService keys,\n        ExtensionGrantValidator extensionGrants,\n        ISecretsListParser secretParsers,\n        IResourceOwnerPasswordValidator resourceOwnerValidator,\n        ILogger<DiscoveryResponseGenerator> logger)\n    {\n        Options = options;\n        ResourceStore = resourceStore;\n        Keys = keys;\n        ExtensionGrants = extensionGrants;\n        SecretParsers = secretParsers;\n        ResourceOwnerValidator = resourceOwnerValidator;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Creates the discovery document.\n    /// </summary>\n    /// <param name=\"baseUrl\">The base URL.</param>\n    /// <param name=\"issuerUri\">The issuer URI.</param>\n    public virtual async Task<Dictionary<string, object>> CreateDiscoveryDocumentAsync(string baseUrl, string issuerUri)\n    {\n        var entries = new Dictionary<string, object>\n        {\n            { OidcConstants.Discovery.Issuer, issuerUri }\n        };\n\n        // jwks\n        if (Options.Discovery.ShowKeySet)\n        {\n            if ((await Keys.GetValidationKeysAsync()).Any())\n            {\n                entries.Add(OidcConstants.Discovery.JwksUri, baseUrl + Constants.ProtocolRoutePaths.DiscoveryWebKeys);\n            }\n        }\n\n        // endpoints\n        if (Options.Discovery.ShowEndpoints)\n        {\n            if (Options.Endpoints.EnableAuthorizeEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.AuthorizationEndpoint, baseUrl + Constants.ProtocolRoutePaths.Authorize);\n            }\n\n            if (Options.Endpoints.EnableTokenEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.TokenEndpoint, baseUrl + Constants.ProtocolRoutePaths.Token);\n            }\n\n            if (Options.Endpoints.EnableUserInfoEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.UserInfoEndpoint, baseUrl + Constants.ProtocolRoutePaths.UserInfo);\n            }\n\n            if (Options.Endpoints.EnableEndSessionEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.EndSessionEndpoint, baseUrl + Constants.ProtocolRoutePaths.EndSession);\n            }\n\n            if (Options.Endpoints.EnableCheckSessionEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.CheckSessionIframe, baseUrl + Constants.ProtocolRoutePaths.CheckSession);\n            }\n\n            if (Options.Endpoints.EnableTokenRevocationEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.RevocationEndpoint, baseUrl + Constants.ProtocolRoutePaths.Revocation);\n            }\n\n            if (Options.Endpoints.EnableIntrospectionEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.IntrospectionEndpoint, baseUrl + Constants.ProtocolRoutePaths.Introspection);\n            }\n\n            if (Options.Endpoints.EnableDeviceAuthorizationEndpoint)\n            {\n                entries.Add(OidcConstants.Discovery.DeviceAuthorizationEndpoint, baseUrl + Constants.ProtocolRoutePaths.DeviceAuthorization);\n            }\n\n            if (Options.MutualTls.Enabled)\n            {\n                var mtlsEndpoints = new Dictionary<string, string>();\n\n                if (Options.Endpoints.EnableTokenEndpoint)\n                {\n                    mtlsEndpoints.Add(OidcConstants.Discovery.TokenEndpoint, ConstructMtlsEndpoint(Constants.ProtocolRoutePaths.Token));\n                }\n                if (Options.Endpoints.EnableTokenRevocationEndpoint)\n                {\n                    mtlsEndpoints.Add(OidcConstants.Discovery.RevocationEndpoint, ConstructMtlsEndpoint(Constants.ProtocolRoutePaths.Revocation));\n                }\n                if (Options.Endpoints.EnableIntrospectionEndpoint)\n                {\n                    mtlsEndpoints.Add(OidcConstants.Discovery.IntrospectionEndpoint, ConstructMtlsEndpoint(Constants.ProtocolRoutePaths.Introspection));\n                }\n                if (Options.Endpoints.EnableDeviceAuthorizationEndpoint)\n                {\n                    mtlsEndpoints.Add(OidcConstants.Discovery.DeviceAuthorizationEndpoint, ConstructMtlsEndpoint(Constants.ProtocolRoutePaths.DeviceAuthorization));\n                }\n\n                if (mtlsEndpoints.Any())\n                {\n                    entries.Add(OidcConstants.Discovery.MtlsEndpointAliases, mtlsEndpoints);\n                }\n\n                string ConstructMtlsEndpoint(string endpoint)\n                {\n                    // path based\n                    if (Options.MutualTls.DomainName.IsMissing())\n                    {\n                        return baseUrl + endpoint.Replace(Constants.ProtocolRoutePaths.ConnectPathPrefix, Constants.ProtocolRoutePaths.MtlsPathPrefix);\n                    }\n\n                    // domain based\n                    if (Options.MutualTls.DomainName.Contains(\".\"))\n                    {\n                        return $\"https://{Options.MutualTls.DomainName}/{endpoint}\";\n                    }\n                    // sub-domain based\n                    else\n                    {\n                        var parts = baseUrl.Split(\"://\");\n                        return $\"https://{Options.MutualTls.DomainName}.{parts[1]}{endpoint}\";\n                    }\n                }\n            }\n        }\n\n        // logout\n        if (Options.Endpoints.EnableEndSessionEndpoint)\n        {\n            entries.Add(OidcConstants.Discovery.FrontChannelLogoutSupported, true);\n            entries.Add(OidcConstants.Discovery.FrontChannelLogoutSessionSupported, true);\n            entries.Add(OidcConstants.Discovery.BackChannelLogoutSupported, true);\n            entries.Add(OidcConstants.Discovery.BackChannelLogoutSessionSupported, true);\n        }\n\n        // scopes and claims\n        if (Options.Discovery.ShowIdentityScopes ||\n            Options.Discovery.ShowApiScopes ||\n            Options.Discovery.ShowClaims)\n        {\n            var resources = await ResourceStore.GetAllEnabledResourcesAsync();\n            var scopes = new List<string>();\n\n            // scopes\n            if (Options.Discovery.ShowIdentityScopes)\n            {\n                scopes.AddRange(resources.IdentityResources.Where(x => x.ShowInDiscoveryDocument).Select(x => x.Name));\n            }\n\n            if (Options.Discovery.ShowApiScopes)\n            {\n                var apiScopes = from scope in resources.ApiScopes\n                                where scope.ShowInDiscoveryDocument\n                                select scope.Name;\n\n                scopes.AddRange(apiScopes);\n                scopes.Add(IdentityServerConstants.StandardScopes.OfflineAccess);\n            }\n\n            if (scopes.Any())\n            {\n                entries.Add(OidcConstants.Discovery.ScopesSupported, scopes.ToArray());\n            }\n\n            // claims\n            if (Options.Discovery.ShowClaims)\n            {\n                var claims = new List<string>();\n\n                // add non-hidden identity scopes related claims\n                claims.AddRange(resources.IdentityResources.Where(x => x.ShowInDiscoveryDocument).SelectMany(x => x.UserClaims));\n                claims.AddRange(resources.ApiResources.Where(x => x.ShowInDiscoveryDocument).SelectMany(x => x.UserClaims));\n                claims.AddRange(resources.ApiScopes.Where(x => x.ShowInDiscoveryDocument).SelectMany(x => x.UserClaims));\n\n                entries.Add(OidcConstants.Discovery.ClaimsSupported, claims.Distinct().ToArray());\n            }\n        }\n\n        // grant types\n        if (Options.Discovery.ShowGrantTypes)\n        {\n            var standardGrantTypes = new List<string>\n            {\n                OidcConstants.GrantTypes.AuthorizationCode,\n                OidcConstants.GrantTypes.ClientCredentials,\n                OidcConstants.GrantTypes.RefreshToken,\n                OidcConstants.GrantTypes.Implicit\n            };\n\n            if (!(ResourceOwnerValidator is NotSupportedResourceOwnerPasswordValidator))\n            {\n                standardGrantTypes.Add(OidcConstants.GrantTypes.Password);\n            }\n\n            if (Options.Endpoints.EnableDeviceAuthorizationEndpoint)\n            {\n                standardGrantTypes.Add(OidcConstants.GrantTypes.DeviceCode);\n            }\n\n            var showGrantTypes = new List<string>(standardGrantTypes);\n\n            if (Options.Discovery.ShowExtensionGrantTypes)\n            {\n                showGrantTypes.AddRange(ExtensionGrants.GetAvailableGrantTypes());\n            }\n\n            entries.Add(OidcConstants.Discovery.GrantTypesSupported, showGrantTypes.ToArray());\n        }\n\n        // response types\n        if (Options.Discovery.ShowResponseTypes)\n        {\n            entries.Add(OidcConstants.Discovery.ResponseTypesSupported, Constants.SupportedResponseTypes.ToArray());\n        }\n\n        // response modes\n        if (Options.Discovery.ShowResponseModes)\n        {\n            entries.Add(OidcConstants.Discovery.ResponseModesSupported, Constants.SupportedResponseModes.ToArray());\n        }\n\n        // misc\n        if (Options.Discovery.ShowTokenEndpointAuthenticationMethods)\n        {\n            var types = SecretParsers.GetAvailableAuthenticationMethods().ToList();\n            if (Options.MutualTls.Enabled)\n            {\n                types.Add(OidcConstants.EndpointAuthenticationMethods.TlsClientAuth);\n                types.Add(OidcConstants.EndpointAuthenticationMethods.SelfSignedTlsClientAuth);\n            }\n\n            entries.Add(OidcConstants.Discovery.TokenEndpointAuthenticationMethodsSupported, types);\n        }\n\n        var signingCredentials = await Keys.GetAllSigningCredentialsAsync();\n        if (signingCredentials.Any())\n        {\n            var signingAlgorithms = signingCredentials.Select(c => c.Algorithm).Distinct();\n            entries.Add(OidcConstants.Discovery.IdTokenSigningAlgorithmsSupported, signingAlgorithms);\n        }\n\n        entries.Add(OidcConstants.Discovery.SubjectTypesSupported, new[] { \"public\" });\n        entries.Add(OidcConstants.Discovery.CodeChallengeMethodsSupported, new[] { OidcConstants.CodeChallengeMethods.Plain, OidcConstants.CodeChallengeMethods.Sha256 });\n\n        if (Options.Endpoints.EnableAuthorizeEndpoint)\n        {\n            entries.Add(OidcConstants.Discovery.RequestParameterSupported, true);\n\n            if (Options.Endpoints.EnableJwtRequestUri)\n            {\n                entries.Add(OidcConstants.Discovery.RequestUriParameterSupported, true);\n            }\n        }\n\n        if (Options.MutualTls.Enabled)\n        {\n            entries.Add(OidcConstants.Discovery.TlsClientCertificateBoundAccessTokens, true);\n        }\n\n        // custom entries\n        if (!Options.Discovery.CustomEntries.EnumerableIsNullOrEmpty())\n        {\n            foreach ((string key, object value) in Options.Discovery.CustomEntries)\n            {\n                if (entries.ContainsKey(key))\n                {\n                    Logger.LogError(\"Discovery custom entry {key} cannot be added, because it already exists.\", key);\n                }\n                else\n                {\n                    if (value is string customValueString)\n                    {\n                        if (customValueString.StartsWith(\"~/\") && Options.Discovery.ExpandRelativePathsInCustomEntries)\n                        {\n                            entries.Add(key, baseUrl + customValueString.Substring(2));\n                            continue;\n                        }\n                    }\n\n                    entries.Add(key, value);\n                }\n            }\n        }\n\n        return entries;\n    }\n\n    /// <summary>\n    /// Creates the JWK document.\n    /// </summary>\n    public virtual async Task<IEnumerable<Models.JsonWebKey>> CreateJwkDocumentAsync()\n    {\n        var webKeys = new List<Models.JsonWebKey>();\n\n        foreach (var key in await Keys.GetValidationKeysAsync())\n        {\n            if (key.Key is X509SecurityKey x509Key)\n            {\n                var cert64 = Convert.ToBase64String(x509Key.Certificate.RawData);\n                var thumbprint = Base64Url.Encode(x509Key.Certificate.GetCertHash());\n\n                if (x509Key.PublicKey is RSA rsa)\n                {\n                    var parameters = rsa.ExportParameters(false);\n                    var exponent = Base64Url.Encode(parameters.Exponent);\n                    var modulus = Base64Url.Encode(parameters.Modulus);\n\n                    var rsaJsonWebKey = new Models.JsonWebKey\n                    {\n                        kty = \"RSA\",\n                        use = \"sig\",\n                        kid = x509Key.KeyId,\n                        x5t = thumbprint,\n                        e = exponent,\n                        n = modulus,\n                        x5c = new[] { cert64 },\n                        alg = key.SigningAlgorithm\n                    };\n                    webKeys.Add(rsaJsonWebKey);\n                }\n                else if (x509Key.PublicKey is ECDsa ecdsa)\n                {\n                    var parameters = ecdsa.ExportParameters(false);\n                    var x = Base64Url.Encode(parameters.Q.X);\n                    var y = Base64Url.Encode(parameters.Q.Y);\n\n                    var ecdsaJsonWebKey = new Models.JsonWebKey\n                    {\n                        kty = \"EC\",\n                        use = \"sig\",\n                        kid = x509Key.KeyId,\n                        x5t = thumbprint,\n                        x = x,\n                        y = y,\n                        crv = CryptoHelper.GetCrvValueFromCurve(parameters.Curve),\n                        x5c = new[] { cert64 },\n                        alg = key.SigningAlgorithm\n                    };\n                    webKeys.Add(ecdsaJsonWebKey);\n                }\n                else\n                {\n                    throw new InvalidOperationException($\"key type: {x509Key.PublicKey.GetType().Name} not supported.\");\n                }\n            }\n            else if (key.Key is RsaSecurityKey rsaKey)\n            {\n                var parameters = rsaKey.Rsa?.ExportParameters(false) ?? rsaKey.Parameters;\n                var exponent = Base64Url.Encode(parameters.Exponent);\n                var modulus = Base64Url.Encode(parameters.Modulus);\n\n                var webKey = new Models.JsonWebKey\n                {\n                    kty = \"RSA\",\n                    use = \"sig\",\n                    kid = rsaKey.KeyId,\n                    e = exponent,\n                    n = modulus,\n                    alg = key.SigningAlgorithm\n                };\n\n                webKeys.Add(webKey);\n            }\n            else if (key.Key is ECDsaSecurityKey ecdsaKey)\n            {\n                var parameters = ecdsaKey.ECDsa.ExportParameters(false);\n                var x = Base64Url.Encode(parameters.Q.X);\n                var y = Base64Url.Encode(parameters.Q.Y);\n\n                var ecdsaJsonWebKey = new Models.JsonWebKey\n                {\n                    kty = \"EC\",\n                    use = \"sig\",\n                    kid = ecdsaKey.KeyId,\n                    x = x,\n                    y = y,\n                    crv = CryptoHelper.GetCrvValueFromCurve(parameters.Curve),\n                    alg = key.SigningAlgorithm\n                };\n                webKeys.Add(ecdsaJsonWebKey);\n            }\n            else if (key.Key is JsonWebKey jsonWebKey)\n            {\n                var webKey = new Models.JsonWebKey\n                {\n                    kty = jsonWebKey.Kty,\n                    use = jsonWebKey.Use ?? \"sig\",\n                    kid = jsonWebKey.Kid,\n                    x5t = jsonWebKey.X5t,\n                    e = jsonWebKey.E,\n                    n = jsonWebKey.N,\n                    x5c = jsonWebKey.X5c?.Count == 0 ? null : jsonWebKey.X5c.ToArray(),\n                    alg = jsonWebKey.Alg,\n                    crv = jsonWebKey.Crv,\n                    x = jsonWebKey.X,\n                    y = jsonWebKey.Y\n                };\n\n                webKeys.Add(webKey);\n            }\n        }\n\n        return webKeys;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/IntrospectionResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// The introspection response generator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.IIntrospectionResponseGenerator\" />\npublic class IntrospectionResponseGenerator : IIntrospectionResponseGenerator\n{\n    /// <summary>\n    /// Gets the events.\n    /// </summary>\n    /// <value>\n    /// The events.\n    /// </value>\n    protected readonly IEventService Events;\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IntrospectionResponseGenerator\" /> class.\n    /// </summary>\n    /// <param name=\"events\">The events.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public IntrospectionResponseGenerator(IEventService events, ILogger<IntrospectionResponseGenerator> logger)\n    {\n        Events = events;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Processes the response.\n    /// </summary>\n    /// <param name=\"validationResult\">The validation result.</param>\n    /// <returns></returns>\n    public virtual async Task<Dictionary<string, object>> ProcessAsync(IntrospectionRequestValidationResult validationResult)\n    {\n        Logger.LogTrace(\"Creating introspection response\");\n\n        // standard response\n        var response = new Dictionary<string, object>\n        {\n            { \"active\", false }\n        };\n\n        // token is invalid\n        if (validationResult.IsActive == false)\n        {\n            Logger.LogDebug(\"Creating introspection response for inactive token.\");\n            await Events.RaiseAsync(new TokenIntrospectionSuccessEvent(validationResult));\n\n            return response;\n        }\n\n        // expected scope not present\n        if (await AreExpectedScopesPresentAsync(validationResult) == false)\n        {\n            return response;\n        }\n\n        Logger.LogDebug(\"Creating introspection response for active token.\");\n\n        // get all claims (without scopes)\n        response = validationResult.Claims.Where(c => c.Type != JwtClaimTypes.Scope).ToClaimsDictionary();\n\n        // add active flag\n        response.Add(\"active\", true);\n\n        // calculate scopes the caller is allowed to see\n        var allowedScopes = validationResult.Api.Scopes;\n        var scopes = validationResult.Claims.Where(c => c.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n        scopes = scopes.Where(x => allowedScopes.Contains(x));\n        response.Add(\"scope\", scopes.ToSpaceSeparatedString());\n\n        await Events.RaiseAsync(new TokenIntrospectionSuccessEvent(validationResult));\n        return response;\n    }\n\n    /// <summary>\n    /// Checks if the API resource is allowed to introspect the scopes.\n    /// </summary>\n    /// <param name=\"validationResult\">The validation result.</param>\n    /// <returns></returns>\n    protected virtual async Task<bool> AreExpectedScopesPresentAsync(IntrospectionRequestValidationResult validationResult)\n    {\n        var apiScopes = validationResult.Api.Scopes;\n        var tokenScopes = validationResult.Claims.Where(c => c.Type == JwtClaimTypes.Scope);\n\n        var tokenScopesThatMatchApi = tokenScopes.Where(c => apiScopes.Contains(c.Value));\n\n        var result = false;\n\n        if (tokenScopesThatMatchApi.Any())\n        {\n            // at least one of the scopes the API supports is in the token\n            result = true;\n        }\n        else\n        {\n            // no scopes for this API are found in the token\n            Logger.LogError(\"Expected scope {scopes} is missing in token\", apiScopes);\n            await Events.RaiseAsync(new TokenIntrospectionFailureEvent(validationResult.Api.Name, \"Expected scopes are missing\", validationResult.Token, apiScopes, tokenScopes.Select(s => s.Value)));\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/TokenResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// The default token response generator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.ITokenResponseGenerator\" />\npublic class TokenResponseGenerator : ITokenResponseGenerator\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The token service\n    /// </summary>\n    protected readonly ITokenService TokenService;\n\n    /// <summary>\n    /// The refresh token service\n    /// </summary>\n    protected readonly IRefreshTokenService RefreshTokenService;\n\n    /// <summary>\n    /// The scope parser\n    /// </summary>\n    public IScopeParser ScopeParser { get; }\n\n    /// <summary>\n    /// The resource store\n    /// </summary>\n    protected readonly IResourceStore Resources;\n\n    /// <summary>\n    /// The clients store\n    /// </summary>\n    protected readonly IClientStore Clients;\n\n    /// <summary>\n    ///  The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenResponseGenerator\" /> class.\n    /// </summary>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"tokenService\">The token service.</param>\n    /// <param name=\"refreshTokenService\">The refresh token service.</param>\n    /// <param name=\"scopeParser\">The scope parser.</param>\n    /// <param name=\"resources\">The resources.</param>\n    /// <param name=\"clients\">The clients.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public TokenResponseGenerator(ISystemClock clock, ITokenService tokenService, IRefreshTokenService refreshTokenService, IScopeParser scopeParser, IResourceStore resources, IClientStore clients, ILogger<TokenResponseGenerator> logger)\n    {\n        Clock = clock;\n        TokenService = tokenService;\n        RefreshTokenService = refreshTokenService;\n        ScopeParser = scopeParser;\n        Resources = resources;\n        Clients = clients;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Processes the response.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    public virtual async Task<TokenResponse> ProcessAsync(TokenRequestValidationResult request)\n    {\n        switch (request.ValidatedRequest.GrantType)\n        {\n            case OidcConstants.GrantTypes.ClientCredentials:\n                return await ProcessClientCredentialsRequestAsync(request);\n            case OidcConstants.GrantTypes.Password:\n                return await ProcessPasswordRequestAsync(request);\n            case OidcConstants.GrantTypes.AuthorizationCode:\n                return await ProcessAuthorizationCodeRequestAsync(request);\n            case OidcConstants.GrantTypes.RefreshToken:\n                return await ProcessRefreshTokenRequestAsync(request);\n            case OidcConstants.GrantTypes.DeviceCode:\n                return await ProcessDeviceCodeRequestAsync(request);\n            default:\n                return await ProcessExtensionGrantRequestAsync(request);\n        }\n    }\n\n    /// <summary>\n    /// Creates the response for an client credentials request.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    protected virtual Task<TokenResponse> ProcessClientCredentialsRequestAsync(TokenRequestValidationResult request)\n    {\n        Logger.LogTrace(\"Creating response for client credentials request\");\n\n        return ProcessTokenRequestAsync(request);\n    }\n\n    /// <summary>\n    /// Creates the response for a password request.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    protected virtual Task<TokenResponse> ProcessPasswordRequestAsync(TokenRequestValidationResult request)\n    {\n        Logger.LogTrace(\"Creating response for password request\");\n\n        return ProcessTokenRequestAsync(request);\n    }\n\n    /// <summary>\n    /// Creates the response for an authorization code request.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">Client does not exist anymore.</exception>\n    protected virtual async Task<TokenResponse> ProcessAuthorizationCodeRequestAsync(TokenRequestValidationResult request)\n    {\n        Logger.LogTrace(\"Creating response for authorization code request\");\n\n        //////////////////////////\n        // access token\n        /////////////////////////\n        var (accessToken, refreshToken) = await CreateAccessTokenAsync(request.ValidatedRequest);\n        var response = new TokenResponse\n        {\n            AccessToken = accessToken,\n            AccessTokenLifetime = request.ValidatedRequest.AccessTokenLifetime,\n            Custom = request.CustomResponse,\n            Scope = request.ValidatedRequest.AuthorizationCode.RequestedScopes.ToSpaceSeparatedString()\n        };\n\n        //////////////////////////\n        // refresh token\n        /////////////////////////\n        if (refreshToken.IsPresent())\n        {\n            response.RefreshToken = refreshToken;\n        }\n\n        //////////////////////////\n        // id token\n        /////////////////////////\n        if (request.ValidatedRequest.AuthorizationCode.IsOpenId)\n        {\n            // load the client that belongs to the authorization code\n            Client client = null;\n            if (request.ValidatedRequest.AuthorizationCode.ClientId != null)\n            {\n                client = await Clients.FindEnabledClientByIdAsync(request.ValidatedRequest.AuthorizationCode.ClientId);\n            }\n            if (client == null)\n            {\n                throw new InvalidOperationException(\"Client does not exist anymore.\");\n            }\n\n            var parsedScopesResult = ScopeParser.ParseScopeValues(request.ValidatedRequest.AuthorizationCode.RequestedScopes);\n            var validatedResources = await Resources.CreateResourceValidationResult(parsedScopesResult);\n\n            var tokenRequest = new TokenCreationRequest\n            {\n                Subject = request.ValidatedRequest.AuthorizationCode.Subject,\n                ValidatedResources = validatedResources,\n                Nonce = request.ValidatedRequest.AuthorizationCode.Nonce,\n                AccessTokenToHash = response.AccessToken,\n                StateHash = request.ValidatedRequest.AuthorizationCode.StateHash,\n                ValidatedRequest = request.ValidatedRequest\n            };\n\n            var idToken = await TokenService.CreateIdentityTokenAsync(tokenRequest);\n            var jwt = await TokenService.CreateSecurityTokenAsync(idToken);\n            response.IdentityToken = jwt;\n        }\n\n        return response;\n    }\n\n    /// <summary>\n    /// Creates the response for a refresh token request.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    protected virtual async Task<TokenResponse> ProcessRefreshTokenRequestAsync(TokenRequestValidationResult request)\n    {\n        Logger.LogTrace(\"Creating response for refresh token request\");\n\n        var oldAccessToken = request.ValidatedRequest.RefreshToken.AccessToken;\n        string accessTokenString;\n\n        if (request.ValidatedRequest.Client.UpdateAccessTokenClaimsOnRefresh)\n        {\n            var subject = request.ValidatedRequest.RefreshToken.Subject;\n\n            // todo: do we want to just parse here and build up validated result\n            // or do we want to fully re-run validation here.\n            var parsedScopesResult = ScopeParser.ParseScopeValues(oldAccessToken.Scopes);\n            var validatedResources = await Resources.CreateResourceValidationResult(parsedScopesResult);\n\n            var creationRequest = new TokenCreationRequest\n            {\n                Subject = subject,\n                Description = request.ValidatedRequest.RefreshToken.Description,\n                ValidatedRequest = request.ValidatedRequest,\n                ValidatedResources = validatedResources\n            };\n\n            var newAccessToken = await TokenService.CreateAccessTokenAsync(creationRequest);\n            accessTokenString = await TokenService.CreateSecurityTokenAsync(newAccessToken);\n        }\n        else\n        {\n            oldAccessToken.CreationTime = Clock.UtcNow.UtcDateTime;\n            oldAccessToken.Lifetime = request.ValidatedRequest.AccessTokenLifetime;\n\n            accessTokenString = await TokenService.CreateSecurityTokenAsync(oldAccessToken);\n        }\n\n        var handle = await RefreshTokenService.UpdateRefreshTokenAsync(request.ValidatedRequest.RefreshTokenHandle, request.ValidatedRequest.RefreshToken, request.ValidatedRequest.Client);\n\n        return new TokenResponse\n        {\n            IdentityToken = await CreateIdTokenFromRefreshTokenRequestAsync(request.ValidatedRequest, accessTokenString),\n            AccessToken = accessTokenString,\n            AccessTokenLifetime = request.ValidatedRequest.AccessTokenLifetime,\n            RefreshToken = handle,\n            Custom = request.CustomResponse,\n            Scope = request.ValidatedRequest.RefreshToken.Scopes.ToSpaceSeparatedString()\n        };\n    }\n\n    /// <summary>\n    /// Processes the response for device code grant request.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    protected virtual async Task<TokenResponse> ProcessDeviceCodeRequestAsync(TokenRequestValidationResult request)\n    {\n        Logger.LogTrace(\"Creating response for device code request\");\n\n        //////////////////////////\n        // access token\n        /////////////////////////\n        var (accessToken, refreshToken) = await CreateAccessTokenAsync(request.ValidatedRequest);\n        var response = new TokenResponse\n        {\n            AccessToken = accessToken,\n            AccessTokenLifetime = request.ValidatedRequest.AccessTokenLifetime,\n            Custom = request.CustomResponse,\n            Scope = request.ValidatedRequest.DeviceCode.AuthorizedScopes.ToSpaceSeparatedString()\n        };\n\n        //////////////////////////\n        // refresh token\n        /////////////////////////\n        if (refreshToken.IsPresent())\n        {\n            response.RefreshToken = refreshToken;\n        }\n\n        //////////////////////////\n        // id token\n        /////////////////////////\n        if (request.ValidatedRequest.DeviceCode.IsOpenId)\n        {\n            // load the client that belongs to the device code\n            Client client = null;\n            if (request.ValidatedRequest.DeviceCode.ClientId != null)\n            {\n                client = await Clients.FindEnabledClientByIdAsync(request.ValidatedRequest.DeviceCode.ClientId);\n            }\n            if (client == null)\n            {\n                throw new InvalidOperationException(\"Client does not exist anymore.\");\n            }\n\n            var parsedScopesResult = ScopeParser.ParseScopeValues(request.ValidatedRequest.DeviceCode.AuthorizedScopes);\n            var validatedResources = await Resources.CreateResourceValidationResult(parsedScopesResult);\n            \n            var tokenRequest = new TokenCreationRequest\n            {\n                Subject = request.ValidatedRequest.DeviceCode.Subject,\n                ValidatedResources = validatedResources,\n                AccessTokenToHash = response.AccessToken,\n                ValidatedRequest = request.ValidatedRequest\n            };\n\n            var idToken = await TokenService.CreateIdentityTokenAsync(tokenRequest);\n            var jwt = await TokenService.CreateSecurityTokenAsync(idToken);\n            response.IdentityToken = jwt;\n        }\n\n        return response;\n    }\n\n    /// <summary>\n    /// Creates the response for an extension grant request.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    protected virtual Task<TokenResponse> ProcessExtensionGrantRequestAsync(TokenRequestValidationResult request)\n    {\n        Logger.LogTrace(\"Creating response for extension grant request\");\n\n        return ProcessTokenRequestAsync(request);\n    }\n\n    /// <summary>\n    /// Creates the response for a token request.\n    /// </summary>\n    /// <param name=\"validationResult\">The validation result.</param>\n    /// <returns></returns>\n    protected virtual async Task<TokenResponse> ProcessTokenRequestAsync(TokenRequestValidationResult validationResult)\n    {\n        (var accessToken, var refreshToken) = await CreateAccessTokenAsync(validationResult.ValidatedRequest);\n        var response = new TokenResponse\n        {\n            AccessToken = accessToken,\n            AccessTokenLifetime = validationResult.ValidatedRequest.AccessTokenLifetime,\n            Custom = validationResult.CustomResponse,\n            Scope = validationResult.ValidatedRequest.ValidatedResources.RawScopeValues.ToSpaceSeparatedString()\n        };\n\n        if (refreshToken.IsPresent())\n        {\n            response.RefreshToken = refreshToken;\n        }\n\n        return response;\n    }\n\n    /// <summary>\n    /// Creates the access/refresh token.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">Client does not exist anymore.</exception>\n    protected virtual async Task<(string accessToken, string refreshToken)> CreateAccessTokenAsync(ValidatedTokenRequest request)\n    {\n        TokenCreationRequest tokenRequest;\n        bool createRefreshToken;\n\n        if (request.AuthorizationCode != null)\n        {\n            createRefreshToken = request.AuthorizationCode.RequestedScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess);\n\n            // load the client that belongs to the authorization code\n            Client client = null;\n            if (request.AuthorizationCode.ClientId != null)\n            {\n                client = await Clients.FindEnabledClientByIdAsync(request.AuthorizationCode.ClientId);\n            }\n            if (client == null)\n            {\n                throw new InvalidOperationException(\"Client does not exist anymore.\");\n            }\n\n            var parsedScopesResult = ScopeParser.ParseScopeValues(request.AuthorizationCode.RequestedScopes);\n            var validatedResources = await Resources.CreateResourceValidationResult(parsedScopesResult);\n\n            tokenRequest = new TokenCreationRequest\n            {\n                Subject = request.AuthorizationCode.Subject,\n                Description = request.AuthorizationCode.Description,\n                ValidatedResources = validatedResources,\n                ValidatedRequest = request\n            };\n        }\n        else if (request.DeviceCode != null)\n        {\n            createRefreshToken = request.DeviceCode.AuthorizedScopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess);\n\n            Client client = null;\n            if (request.DeviceCode.ClientId != null)\n            {\n                client = await Clients.FindEnabledClientByIdAsync(request.DeviceCode.ClientId);\n            }\n            if (client == null)\n            {\n                throw new InvalidOperationException(\"Client does not exist anymore.\");\n            }\n\n            var parsedScopesResult = ScopeParser.ParseScopeValues(request.DeviceCode.AuthorizedScopes);\n            var validatedResources = await Resources.CreateResourceValidationResult(parsedScopesResult);\n\n            tokenRequest = new TokenCreationRequest\n            {\n                Subject = request.DeviceCode.Subject,\n                Description = request.DeviceCode.Description,\n                ValidatedResources = validatedResources,\n                ValidatedRequest = request\n            };\n        }\n        else\n        {\n            createRefreshToken = request.ValidatedResources.Resources.OfflineAccess;\n\n            tokenRequest = new TokenCreationRequest\n            {\n                Subject = request.Subject,\n                ValidatedResources = request.ValidatedResources,\n                ValidatedRequest = request\n            };\n        }\n\n        var at = await TokenService.CreateAccessTokenAsync(tokenRequest);\n        var accessToken = await TokenService.CreateSecurityTokenAsync(at);\n\n        if (createRefreshToken)\n        {\n            var refreshToken = await RefreshTokenService.CreateRefreshTokenAsync(tokenRequest.Subject, at, request.Client);\n            return (accessToken, refreshToken);\n        }\n\n        return (accessToken, null);\n    }\n\n    /// <summary>\n    /// Creates an id_token for a refresh token request if identity resources have been requested.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"newAccessToken\">The new access token.</param>\n    /// <returns></returns>\n    protected virtual async Task<string> CreateIdTokenFromRefreshTokenRequestAsync(ValidatedTokenRequest request, string newAccessToken)\n    {\n        // todo: can we just check for \"openid\" scope?\n        //var identityResources = await Resources.FindEnabledIdentityResourcesByScopeAsync(request.RefreshToken.Scopes);\n        //if (identityResources.Any())\n        \n        if (request.RefreshToken.Scopes.Contains(OidcConstants.StandardScopes.OpenId))\n        {\n            var oldAccessToken = request.RefreshToken.AccessToken;\n\n            var parsedScopesResult = ScopeParser.ParseScopeValues(oldAccessToken.Scopes);\n            var validatedResources = await Resources.CreateResourceValidationResult(parsedScopesResult);\n\n            var tokenRequest = new TokenCreationRequest\n            {\n                Subject = request.RefreshToken.Subject,\n                ValidatedResources = validatedResources,\n                ValidatedRequest = request,\n                AccessTokenToHash = newAccessToken\n            };\n\n            var idToken = await TokenService.CreateIdentityTokenAsync(tokenRequest);\n            return await TokenService.CreateSecurityTokenAsync(idToken);\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/TokenRevocationResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Default revocation response generator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.ITokenRevocationResponseGenerator\" />\npublic class TokenRevocationResponseGenerator : ITokenRevocationResponseGenerator\n{\n    /// <summary>\n    /// Gets the reference token store.\n    /// </summary>\n    /// <value>\n    /// The reference token store.\n    /// </value>\n    protected readonly IReferenceTokenStore ReferenceTokenStore;\n\n    /// <summary>\n    /// Gets the refresh token store.\n    /// </summary>\n    /// <value>\n    /// The refresh token store.\n    /// </value>\n    protected readonly IRefreshTokenStore RefreshTokenStore;\n\n    /// <summary>\n    /// Gets the logger.\n    /// </summary>\n    /// <value>\n    /// The logger.\n    /// </value>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRevocationResponseGenerator\" /> class.\n    /// </summary>\n    /// <param name=\"referenceTokenStore\">The reference token store.</param>\n    /// <param name=\"refreshTokenStore\">The refresh token store.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public TokenRevocationResponseGenerator(IReferenceTokenStore referenceTokenStore, IRefreshTokenStore refreshTokenStore, ILogger<TokenRevocationResponseGenerator> logger)\n    {\n        ReferenceTokenStore = referenceTokenStore;\n        RefreshTokenStore = refreshTokenStore;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Creates the revocation endpoint response and processes the revocation request.\n    /// </summary>\n    /// <param name=\"validationResult\">The userinfo request validation result.</param>\n    /// <returns></returns>\n    public virtual async Task<TokenRevocationResponse> ProcessAsync(TokenRevocationRequestValidationResult validationResult)\n    {\n        var response = new TokenRevocationResponse\n        {\n            Success = false,\n            TokenType = validationResult.TokenTypeHint\n        };\n\n        // revoke tokens\n        if (validationResult.TokenTypeHint == Constants.TokenTypeHints.AccessToken)\n        {\n            Logger.LogTrace(\"Hint was for access token\");\n            response.Success = await RevokeAccessTokenAsync(validationResult);\n        }\n        else if (validationResult.TokenTypeHint == Constants.TokenTypeHints.RefreshToken)\n        {\n            Logger.LogTrace(\"Hint was for refresh token\");\n            response.Success = await RevokeRefreshTokenAsync(validationResult);\n        }\n        else\n        {\n            Logger.LogTrace(\"No hint for token type\");\n\n            response.Success = await RevokeAccessTokenAsync(validationResult);\n\n            if (!response.Success)\n            {\n                response.Success = await RevokeRefreshTokenAsync(validationResult);\n                response.TokenType = Constants.TokenTypeHints.RefreshToken;\n            }\n            else\n            {\n                response.TokenType = Constants.TokenTypeHints.AccessToken;\n            }\n        }\n\n        return response;\n    }\n\n    /// <summary>\n    /// Revoke access token only if it belongs to client doing the request.\n    /// </summary>\n    protected virtual async Task<bool> RevokeAccessTokenAsync(TokenRevocationRequestValidationResult validationResult)\n    {\n        var token = await ReferenceTokenStore.GetReferenceTokenAsync(validationResult.Token);\n\n        if (token != null)\n        {\n            if (token.ClientId == validationResult.Client.ClientId)\n            {\n                Logger.LogDebug(\"Access token revoked\");\n                await ReferenceTokenStore.RemoveReferenceTokenAsync(validationResult.Token);\n            }\n            else\n            {\n                Logger.LogWarning(\"Client {clientId} denied from revoking access token belonging to Client {tokenClientId}\", validationResult.Client.ClientId, token.ClientId);\n            }\n\n            return true;\n        }\n\n        return false;\n    }\n\n    /// <summary>\n    /// Revoke refresh token only if it belongs to client doing the request\n    /// </summary>\n    protected virtual async Task<bool> RevokeRefreshTokenAsync(TokenRevocationRequestValidationResult validationResult)\n    {\n        var token = await RefreshTokenStore.GetRefreshTokenAsync(validationResult.Token);\n\n        if (token != null)\n        {\n            if (token.ClientId == validationResult.Client.ClientId)\n            {\n                Logger.LogDebug(\"Refresh token revoked\");\n                await RefreshTokenStore.RemoveRefreshTokenAsync(validationResult.Token);\n                await ReferenceTokenStore.RemoveReferenceTokensAsync(token.SubjectId, token.ClientId);\n            }\n            else\n            {\n                Logger.LogWarning(\"Client {clientId} denied from revoking a refresh token belonging to Client {tokenClientId}\", validationResult.Client.ClientId, token.ClientId);\n            }\n\n            return true;\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Default/UserInfoResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// The userinfo response generator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.ResponseHandling.IUserInfoResponseGenerator\" />\npublic class UserInfoResponseGenerator : IUserInfoResponseGenerator\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The profile service\n    /// </summary>\n    protected readonly IProfileService Profile;\n\n    /// <summary>\n    /// The resource store\n    /// </summary>\n    protected readonly IResourceStore Resources;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UserInfoResponseGenerator\"/> class.\n    /// </summary>\n    /// <param name=\"profile\">The profile.</param>\n    /// <param name=\"resourceStore\">The resource store.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public UserInfoResponseGenerator(IProfileService profile, IResourceStore resourceStore, ILogger<UserInfoResponseGenerator> logger)\n    {\n        Profile = profile;\n        Resources = resourceStore;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Creates the response.\n    /// </summary>\n    /// <param name=\"validationResult\">The userinfo request validation result.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.InvalidOperationException\">Profile service returned incorrect subject value</exception>\n    public virtual async Task<Dictionary<string, object>> ProcessAsync(UserInfoRequestValidationResult validationResult)\n    {\n        Logger.LogDebug(\"Creating userinfo response\");\n\n        // extract scopes and turn into requested claim types\n        var scopes = validationResult.TokenValidationResult.Claims.Where(c => c.Type == JwtClaimTypes.Scope).Select(c => c.Value);\n\n        var validatedResources = await GetRequestedResourcesAsync(scopes);\n        var requestedClaimTypes = await GetRequestedClaimTypesAsync(validatedResources);\n\n        Logger.LogDebug(\"Requested claim types: {claimTypes}\", requestedClaimTypes.ToSpaceSeparatedString());\n\n        // call profile service\n        var context = new ProfileDataRequestContext(\n            validationResult.Subject,\n            validationResult.TokenValidationResult.Client,\n            IdentityServerConstants.ProfileDataCallers.UserInfoEndpoint,\n            requestedClaimTypes);\n        context.RequestedResources = validatedResources;\n\n        await Profile.GetProfileDataAsync(context);\n        var profileClaims = context.IssuedClaims;\n\n        // construct outgoing claims\n        var outgoingClaims = new List<Claim>();\n\n        if (profileClaims == null)\n        {\n            Logger.LogInformation(\"Profile service returned no claims (null)\");\n        }\n        else\n        {\n            outgoingClaims.AddRange(profileClaims);\n            Logger.LogInformation(\"Profile service returned the following claim types: {types}\", profileClaims.Select(c => c.Type).ToSpaceSeparatedString());\n        }\n\n        var subClaim = outgoingClaims.SingleOrDefault(x => x.Type == JwtClaimTypes.Subject);\n        if (subClaim == null)\n        {\n            outgoingClaims.Add(new Claim(JwtClaimTypes.Subject, validationResult.Subject.GetSubjectId()));\n        }\n        else if (subClaim.Value != validationResult.Subject.GetSubjectId())\n        {\n            Logger.LogError(\"Profile service returned incorrect subject value: {sub}\", subClaim);\n            throw new InvalidOperationException(\"Profile service returned incorrect subject value\");\n        }\n\n        return outgoingClaims.ToClaimsDictionary();\n    }\n\n    /// <summary>\n    ///  Gets the identity resources from the scopes.\n    /// </summary>\n    /// <param name=\"scopes\"></param>\n    /// <returns></returns>\n    protected internal virtual async Task<ResourceValidationResult> GetRequestedResourcesAsync(IEnumerable<string> scopes)\n    {\n        if (scopes == null || !scopes.Any())\n        {\n            return null;\n        }\n\n        var scopeString = string.Join(\" \", scopes);\n        Logger.LogDebug(\"Scopes in access token: {scopes}\", scopeString);\n\n        // if we ever parameterize identity scopes, then we would need to invoke the resource validator's parse API here\n        var identityResources = await Resources.FindEnabledIdentityResourcesByScopeAsync(scopes);\n        \n        var resources = new Resources(identityResources, Enumerable.Empty<ApiResource>(), Enumerable.Empty<ApiScope>());\n        var result = new ResourceValidationResult(resources);\n        \n        return result;\n    }\n\n    /// <summary>\n    /// Gets the requested claim types.\n    /// </summary>\n    /// <param name=\"resourceValidationResult\"></param>\n    /// <returns></returns>\n    protected internal virtual Task<IEnumerable<string>> GetRequestedClaimTypesAsync(ResourceValidationResult resourceValidationResult)\n    {\n        IEnumerable<string> result = null;\n\n        if (resourceValidationResult == null)\n        {\n            result = Enumerable.Empty<string>();\n        }\n        else\n        {\n            var identityResources = resourceValidationResult.Resources.IdentityResources;\n            result = identityResources.SelectMany(x => x.UserClaims).Distinct();\n        }\n\n        return Task.FromResult(result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/IAuthorizeInteractionResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface for determining if user must login or consent when making requests to the authorization endpoint.\n/// </summary>\npublic interface IAuthorizeInteractionResponseGenerator\n{\n    /// <summary>\n    /// Processes the interaction logic.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"consent\">The consent.</param>\n    /// <returns></returns>\n    Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/IAuthorizeResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface for the authorize response generator\n/// </summary>\npublic interface IAuthorizeResponseGenerator\n{\n    /// <summary>\n    /// Creates the response\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    Task<AuthorizeResponse> CreateResponseAsync(ValidatedAuthorizeRequest request);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/IDeviceAuthorizationResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface for the device authorization response generator\n/// </summary>\npublic interface IDeviceAuthorizationResponseGenerator\n{\n    /// <summary>\n    /// Processes the response.\n    /// </summary>\n    /// <param name=\"validationResult\">The validation result.</param>\n    /// <param name=\"baseUrl\">The base URL.</param>\n    /// <returns></returns>\n    Task<DeviceAuthorizationResponse> ProcessAsync(DeviceAuthorizationRequestValidationResult validationResult, string baseUrl);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/IDiscoveryResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface for discovery endpoint response generator\n/// </summary>\npublic interface IDiscoveryResponseGenerator\n{\n    /// <summary>\n    /// Creates the discovery document.\n    /// </summary>\n    /// <param name=\"baseUrl\">The base URL.</param>\n    /// <param name=\"issuerUri\">The issuer URI.</param>\n    Task<Dictionary<string, object>> CreateDiscoveryDocumentAsync(string baseUrl, string issuerUri);\n\n    /// <summary>\n    /// Creates the JWK document.\n    /// </summary>\n    Task<IEnumerable<JsonWebKey>> CreateJwkDocumentAsync();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/IIntrospectionResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface for introspection response generator\n/// </summary>\npublic interface IIntrospectionResponseGenerator\n{\n    /// <summary>\n    /// Processes the response.\n    /// </summary>\n    /// <param name=\"validationResult\">The validation result.</param>\n    /// <returns></returns>\n    Task<Dictionary<string, object>> ProcessAsync(IntrospectionRequestValidationResult validationResult);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/ITokenResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface the token response generator\n/// </summary>\npublic interface ITokenResponseGenerator\n{\n    /// <summary>\n    /// Processes the response.\n    /// </summary>\n    /// <param name=\"validationResult\">The validation result.</param>\n    /// <returns></returns>\n    Task<TokenResponse> ProcessAsync(TokenRequestValidationResult validationResult);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/ITokenRevocationResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface for the userinfo response generator\n/// </summary>\npublic interface ITokenRevocationResponseGenerator\n{\n    /// <summary>\n    /// Creates the revocation endpoint response and processes the revocation request.\n    /// </summary>\n    /// <param name=\"validationResult\">The userinfo request validation result.</param>\n    /// <returns></returns>\n    Task<TokenRevocationResponse> ProcessAsync(TokenRevocationRequestValidationResult validationResult);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/IUserInfoResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Interface for the userinfo response generator\n/// </summary>\npublic interface IUserInfoResponseGenerator\n{\n    /// <summary>\n    /// Creates the response.\n    /// </summary>\n    /// <param name=\"validationResult\">The userinfo request validation result.</param>\n    /// <returns></returns>\n    Task<Dictionary<string, object>> ProcessAsync(UserInfoRequestValidationResult validationResult);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Models/AuthorizeResponse.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.ResponseHandling;\n\npublic class AuthorizeResponse\n{\n    public ValidatedAuthorizeRequest Request { get; set; }\n    public string RedirectUri => Request?.RedirectUri;\n    public string State => Request?.State;\n    public string Scope => Request?.ValidatedResources?.RawScopeValues.ToSpaceSeparatedString();\n\n    public string IdentityToken { get; set; }\n    public string AccessToken { get; set; }\n    public int AccessTokenLifetime { get; set; }\n    public string Code { get; set; }\n    public string SessionState { get; set; }\n\n    public string Error { get; set; }\n    public string ErrorDescription { get; set; }\n    public bool IsError => Error.IsPresent();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Models/DeviceAuthorizationResponse.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.ResponseHandling;\n\npublic class DeviceAuthorizationResponse\n{\n    public string DeviceCode { get; set; }\n    public string UserCode { get; set; }\n    public string VerificationUri { get; set; }\n\n    public string VerificationUriComplete { get; set; }\n    public int DeviceCodeLifetime { get; set; }\n    public int Interval { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Models/InteractionResponse.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Indicates interaction outcome for user on authorization endpoint.\n/// </summary>\npublic class InteractionResponse\n{\n    /// <summary>\n    /// Gets or sets a value indicating whether the user must login.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is login; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsLogin { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the user must consent.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if this instance is consent; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsConsent { get; set; }\n\n    /// <summary>\n    /// Gets a value indicating whether the result is an error.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is error; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsError => Error != null;\n\n    /// <summary>\n    /// Gets or sets the error.\n    /// </summary>\n    /// <value>\n    /// The error.\n    /// </value>\n    public string Error { get; set; }\n\n    /// <summary>\n    /// Gets or sets the error description.\n    /// </summary>\n    /// <value>\n    /// The error description.\n    /// </value>\n    public string ErrorDescription { get; set; }\n\n    /// <summary>\n    /// Gets a value indicating whether the user must be redirected to a custom page.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if this instance is redirect; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsRedirect => RedirectUrl.IsPresent();\n\n    /// <summary>\n    /// Gets or sets the URL for the custom page.\n    /// </summary>\n    /// <value>\n    /// The redirect URL.\n    /// </value>\n    public string RedirectUrl { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Models/TokenErrorResponse.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Models a token error response\n/// </summary>\npublic class TokenErrorResponse\n{\n    /// <summary>\n    /// Gets or sets the error.\n    /// </summary>\n    /// <value>\n    /// The error.\n    /// </value>\n    public string Error { get; set; } = OidcConstants.TokenErrors.InvalidRequest;\n\n    /// <summary>\n    /// Gets or sets the error description.\n    /// </summary>\n    /// <value>\n    /// The error description.\n    /// </value>\n    public string ErrorDescription { get; set; }\n\n    /// <summary>\n    /// Gets or sets the custom entries.\n    /// </summary>\n    /// <value>\n    /// The custom.\n    /// </value>\n    public Dictionary<string, object> Custom { get; set; } = new Dictionary<string, object>();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Models/TokenResponse.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Models a token response\n/// </summary>\npublic class TokenResponse\n{\n    /// <summary>\n    /// Gets or sets the identity token.\n    /// </summary>\n    /// <value>\n    /// The identity token.\n    /// </value>\n    public string IdentityToken { get; set; }\n\n    /// <summary>\n    /// Gets or sets the access token.\n    /// </summary>\n    /// <value>\n    /// The access token.\n    /// </value>\n    public string AccessToken { get; set; }\n\n    /// <summary>\n    /// Gets or sets the access token lifetime.\n    /// </summary>\n    /// <value>\n    /// The access token lifetime.\n    /// </value>\n    public int AccessTokenLifetime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the refresh token.\n    /// </summary>\n    /// <value>\n    /// The refresh token.\n    /// </value>\n    public string RefreshToken { get; set; }\n\n    /// <summary>\n    /// Gets or sets the scope.\n    /// </summary>\n    /// <value>\n    /// The scope.\n    /// </value>\n    public string Scope { get; set; }\n\n    /// <summary>\n    /// Gets or sets the custom entries.\n    /// </summary>\n    /// <value>\n    /// The custom entries.\n    /// </value>\n    public Dictionary<string, object> Custom { get; set; } = new Dictionary<string, object>();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/ResponseHandling/Models/TokenRevocationResponse.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.ResponseHandling;\n\n/// <summary>\n/// Models a token revocation response\n/// </summary>\npublic class TokenRevocationResponse\n{\n    /// <summary>\n    /// Gets or sets a value indicating whether the token revocation was successful.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if success; otherwise, <c>false</c>.\n    /// </value>\n    public bool Success { get; set; }\n\n    /// <summary>\n    /// Gets or sets the type of the token that was revoked.\n    /// </summary>\n    /// <value>\n    /// The type of the token.\n    /// </value>\n    public string TokenType { get; set; }\n\n    /// <summary>\n    /// Gets or sets an error (if present).\n    /// </summary>\n    /// <value>\n    /// The error.\n    /// </value>\n    public string Error { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/BackChannelLogoutHttpClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Models making HTTP requests for back-channel logout notification.\n/// </summary>\npublic class DefaultBackChannelLogoutHttpClient : IBackChannelLogoutHttpClient\n{\n    private readonly HttpClient _client;\n    private readonly ILogger<DefaultBackChannelLogoutHttpClient> _logger;\n\n    /// <summary>\n    /// Constructor for BackChannelLogoutHttpClient.\n    /// </summary>\n    /// <param name=\"client\"></param>\n    /// <param name=\"loggerFactory\"></param>\n    public DefaultBackChannelLogoutHttpClient(HttpClient client, ILoggerFactory loggerFactory)\n    {\n        _client = client;\n        _logger = loggerFactory.CreateLogger<DefaultBackChannelLogoutHttpClient>();\n    }\n\n    /// <summary>\n    /// Posts the payload to the url.\n    /// </summary>\n    /// <param name=\"url\"></param>\n    /// <param name=\"payload\"></param>\n    /// <returns></returns>\n    public async Task PostAsync(string url, Dictionary<string, string> payload)\n    {\n        try\n        {\n            var response = await _client.PostAsync(url, new FormUrlEncodedContent(payload));\n            if (response.IsSuccessStatusCode)\n            {\n                _logger.LogDebug(\"Response from back-channel logout endpoint: {url} status code: {status}\", url, (int)response.StatusCode);\n            }\n            else\n            {\n                _logger.LogWarning(\"Response from back-channel logout endpoint: {url} status code: {status}\", url, (int)response.StatusCode);\n            }\n        }\n        catch (Exception ex)\n        {\n            _logger.LogError(ex, \"Exception invoking back-channel logout for url: {url}\", url);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultBackChannelLogoutService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default back-channel logout notification implementation.\n/// </summary>\npublic class DefaultBackChannelLogoutService : IBackChannelLogoutService\n{\n    /// <summary>\n    /// Default value for the back-channel JWT lifetime.\n    /// </summary>\n    protected const int DefaultLogoutTokenLifetime = 5 * 60;\n\n    /// <summary>\n    /// The system clock;\n    /// </summary>\n    protected ISystemClock Clock { get; }\n    \n    /// <summary>\n    /// The IdentityServerTools used to create and the JWT.\n    /// </summary>\n    protected IdentityServerTools Tools { get; }\n\n    /// <summary>\n    /// The ILogoutNotificationService to build the back channel logout requests.\n    /// </summary>\n    public ILogoutNotificationService LogoutNotificationService { get; }\n\n    /// <summary>\n    /// HttpClient to make the outbound HTTP calls.\n    /// </summary>\n    protected IBackChannelLogoutHttpClient HttpClient { get; }\n\n    /// <summary>\n    /// The logger.\n    /// </summary>\n    protected ILogger<IBackChannelLogoutService> Logger { get; }\n\n    /// <summary>\n    /// Constructor.\n    /// </summary>\n    /// <param name=\"clock\"></param>\n    /// <param name=\"tools\"></param>\n    /// <param name=\"logoutNotificationService\"></param>\n    /// <param name=\"backChannelLogoutHttpClient\"></param>\n    /// <param name=\"logger\"></param>\n    public DefaultBackChannelLogoutService(\n        ISystemClock clock,\n        IdentityServerTools tools,\n        ILogoutNotificationService logoutNotificationService,\n        IBackChannelLogoutHttpClient backChannelLogoutHttpClient,\n        ILogger<IBackChannelLogoutService> logger)\n    {\n        Clock = clock;\n        Tools = tools;\n        LogoutNotificationService = logoutNotificationService;\n        HttpClient = backChannelLogoutHttpClient;\n        Logger = logger;\n    }\n\n    /// <inheritdoc/>\n    public virtual async Task SendLogoutNotificationsAsync(LogoutNotificationContext context)\n    {\n        var backChannelRequests = await LogoutNotificationService.GetBackChannelLogoutNotificationsAsync(context);\n        if (backChannelRequests.Any())\n        {\n            await SendLogoutNotificationsAsync(backChannelRequests);\n        }\n    }\n\n    /// <summary>\n    /// Sends the logout notifications for the collection of clients.\n    /// </summary>\n    /// <param name=\"requests\"></param>\n    /// <returns></returns>\n    protected virtual Task SendLogoutNotificationsAsync(IEnumerable<BackChannelLogoutRequest> requests)\n    {\n        requests = requests ?? Enumerable.Empty<BackChannelLogoutRequest>();\n        var tasks = requests.Select(SendLogoutNotificationAsync).ToArray();\n        return Task.WhenAll(tasks);\n    }\n\n    /// <summary>\n    /// Performs the back-channel logout for a single client.\n    /// </summary>\n    /// <param name=\"request\"></param>\n    protected virtual async Task SendLogoutNotificationAsync(BackChannelLogoutRequest request)\n    {\n        var data = await CreateFormPostPayloadAsync(request);\n        await PostLogoutJwt(request, data);\n    }\n\n    /// <summary>\n    /// Performs the HTTP POST of the logout payload to the client.\n    /// </summary>\n    /// <param name=\"client\"></param>\n    /// <param name=\"data\"></param>\n    /// <returns></returns>\n    protected virtual Task PostLogoutJwt(BackChannelLogoutRequest client, Dictionary<string, string> data)\n    {\n        return HttpClient.PostAsync(client.LogoutUri, data);\n    }\n\n    /// <summary>\n    /// Creates the form-url-encoded payload (as a dictionary) to send to the client.\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <returns></returns>\n    protected async Task<Dictionary<string, string>> CreateFormPostPayloadAsync(BackChannelLogoutRequest request)\n    {\n        var token = await CreateTokenAsync(request);\n\n        var data = new Dictionary<string, string>\n        {\n            { OidcConstants.BackChannelLogoutRequest.LogoutToken, token }\n        };\n        return data;\n    }\n\n    /// <summary>\n    /// Creates the JWT used for the back-channel logout notification.\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <returns>The token.</returns>\n    protected virtual async Task<string> CreateTokenAsync(BackChannelLogoutRequest request)\n    {\n        var claims = await CreateClaimsForTokenAsync(request);\n        if (claims.Any(x => x.Type == JwtClaimTypes.Nonce))\n        {\n            throw new InvalidOperationException(\"nonce claim is not allowed in the back-channel signout token.\");\n        }\n\n        return await Tools.IssueJwtAsync(DefaultLogoutTokenLifetime, claims);\n    }\n\n    /// <summary>\n    /// Create the claims to be used in the back-channel logout token.\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <returns>The claims to include in the token.</returns>\n    protected Task<IEnumerable<Claim>> CreateClaimsForTokenAsync(BackChannelLogoutRequest request)\n    {\n        if (request.SessionIdRequired && request.SessionId == null)\n        {\n            throw new ArgumentException(\"Client requires SessionId\", nameof(request.SessionId));\n        }\n\n        var json = \"{\\\"\" + OidcConstants.Events.BackChannelLogout + \"\\\":{} }\";\n\n        var claims = new List<Claim>\n        {\n            new Claim(JwtClaimTypes.Subject, request.SubjectId),\n            new Claim(JwtClaimTypes.Audience, request.ClientId),\n            new Claim(JwtClaimTypes.IssuedAt, Clock.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64),\n            new Claim(JwtClaimTypes.JwtId, CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex)),\n            new Claim(JwtClaimTypes.Events, json, IdentityServerConstants.ClaimValueTypes.Json)\n        };\n\n        if (request.SessionId != null)\n        {\n            claims.Add(new Claim(JwtClaimTypes.SessionId, request.SessionId));\n        }\n\n        return Task.FromResult(claims.AsEnumerable());\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultCache.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// IMemoryCache-based implementation of the cache\n/// </summary>\n/// <typeparam name=\"T\"></typeparam>\n/// <seealso cref=\"IdentityServer8.Services.ICache{T}\" />\npublic class DefaultCache<T> : ICache<T>\n    where T : class\n{\n    private const string KeySeparator = \":\";\n\n    private readonly IMemoryCache _cache;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultCache{T}\"/> class.\n    /// </summary>\n    /// <param name=\"cache\">The cache.</param>\n    public DefaultCache(IMemoryCache cache)\n    {\n        _cache = cache;\n    }\n\n    private string GetKey(string key)\n    {\n        return typeof(T).FullName + KeySeparator + key;\n    }\n\n    /// <summary>\n    /// Gets the cached data based upon a key index.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <returns>\n    /// The cached item, or <c>null</c> if no item matches the key.\n    /// </returns>\n    public Task<T> GetAsync(string key)\n    {\n        key = GetKey(key);\n        var item = _cache.Get<T>(key);\n        return Task.FromResult(item);\n    }\n\n    /// <summary>\n    /// Caches the data based upon a key\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <param name=\"item\">The item.</param>\n    /// <param name=\"expiration\">The expiration.</param>\n    /// <returns></returns>\n    public Task SetAsync(string key, T item, TimeSpan expiration)\n    {\n        key = GetKey(key);\n        _cache.Set(key, item, expiration);\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultClaimsService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default claims provider implementation\n/// </summary>\npublic class DefaultClaimsService : IClaimsService\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The user service\n    /// </summary>\n    protected readonly IProfileService Profile;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultClaimsService\"/> class.\n    /// </summary>\n    /// <param name=\"profile\">The profile service</param>\n    /// <param name=\"logger\">The logger</param>\n    public DefaultClaimsService(IProfileService profile, ILogger<DefaultClaimsService> logger)\n    {\n        Logger = logger;\n        Profile = profile;\n    }\n\n    /// <summary>\n    /// Returns claims for an identity token\n    /// </summary>\n    /// <param name=\"subject\">The subject</param>\n    /// <param name=\"resources\">The requested resources</param>\n    /// <param name=\"includeAllIdentityClaims\">Specifies if all claims should be included in the token, or if the userinfo endpoint can be used to retrieve them</param>\n    /// <param name=\"request\">The raw request</param>\n    /// <returns>\n    /// Claims for the identity token\n    /// </returns>\n    public virtual async Task<IEnumerable<Claim>> GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, ResourceValidationResult resources, bool includeAllIdentityClaims, ValidatedRequest request)\n    {\n        Logger.LogDebug(\"Getting claims for identity token for subject: {subject} and client: {clientId}\",\n            subject.GetSubjectId(),\n            request.Client.ClientId);\n\n        var outputClaims = new List<Claim>(GetStandardSubjectClaims(subject));\n        outputClaims.AddRange(GetOptionalClaims(subject));\n\n        // fetch all identity claims that need to go into the id token\n        if (includeAllIdentityClaims || request.Client.AlwaysIncludeUserClaimsInIdToken)\n        {\n            var additionalClaimTypes = new List<string>();\n\n            foreach (var identityResource in resources.Resources.IdentityResources)\n            {\n                foreach (var userClaim in identityResource.UserClaims)\n                {\n                    additionalClaimTypes.Add(userClaim);\n                }\n            }\n\n            // filter so we don't ask for claim types that we will eventually filter out\n            additionalClaimTypes = FilterRequestedClaimTypes(additionalClaimTypes).ToList();\n\n            var context = new ProfileDataRequestContext(\n                subject,\n                request.Client,\n                IdentityServerConstants.ProfileDataCallers.ClaimsProviderIdentityToken,\n                additionalClaimTypes)\n            {\n                RequestedResources = resources,\n                ValidatedRequest = request\n            };\n\n            await Profile.GetProfileDataAsync(context);\n\n            var claims = FilterProtocolClaims(context.IssuedClaims);\n            if (claims != null)\n            {\n                outputClaims.AddRange(claims);\n            }\n        }\n        else\n        {\n            Logger.LogDebug(\"In addition to an id_token, an access_token was requested. No claims other than sub are included in the id_token. To obtain more user claims, either use the user info endpoint or set AlwaysIncludeUserClaimsInIdToken on the client configuration.\");\n        }\n\n        return outputClaims;\n    }\n\n    /// <summary>\n    /// Returns claims for an access token.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <param name=\"resourceResult\">The validated resource result</param>\n    /// <param name=\"request\">The raw request.</param>\n    /// <returns>\n    /// Claims for the access token\n    /// </returns>\n    public virtual async Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, ResourceValidationResult resourceResult, ValidatedRequest request)\n    {\n        Logger.LogDebug(\"Getting claims for access token for client: {clientId}\", request.Client.ClientId);\n\n        var outputClaims = new List<Claim>\n        {\n            new Claim(JwtClaimTypes.ClientId, request.ClientId)\n        };\n\n        // log if client ID is overwritten\n        if (!string.Equals(request.ClientId, request.Client.ClientId))\n        {\n            Logger.LogDebug(\"Client {clientId} is impersonating {impersonatedClientId}\", request.Client.ClientId, request.ClientId);\n        }\n\n        // check for client claims\n        if (request.ClientClaims != null && request.ClientClaims.Any())\n        {\n            if (subject == null || request.Client.AlwaysSendClientClaims)\n            {\n                foreach (var claim in request.ClientClaims)\n                {\n                    var claimType = claim.Type;\n\n                    if (request.Client.ClientClaimsPrefix.IsPresent())\n                    {\n                        claimType = request.Client.ClientClaimsPrefix + claimType;\n                    }\n\n                    outputClaims.Add(new Claim(claimType, claim.Value, claim.ValueType));\n                }\n            }\n        }\n\n        // add scopes (filter offline_access)\n        // we use the ScopeValues collection rather than the Resources.Scopes because we support dynamic scope values \n        // from the request, so this issues those in the token.\n        foreach (var scope in resourceResult.RawScopeValues.Where(x => x != IdentityServerConstants.StandardScopes.OfflineAccess))\n        {\n            outputClaims.Add(new Claim(JwtClaimTypes.Scope, scope));\n        }\n\n        // a user is involved\n        if (subject != null)\n        {\n            if (resourceResult.Resources.OfflineAccess)\n            {\n                outputClaims.Add(new Claim(JwtClaimTypes.Scope, IdentityServerConstants.StandardScopes.OfflineAccess));\n            }\n\n            Logger.LogDebug(\"Getting claims for access token for subject: {subject}\", subject.GetSubjectId());\n\n            outputClaims.AddRange(GetStandardSubjectClaims(subject));\n            outputClaims.AddRange(GetOptionalClaims(subject));\n\n            // fetch all resource claims that need to go into the access token\n            var additionalClaimTypes = new List<string>();\n            foreach (var api in resourceResult.Resources.ApiResources)\n            {\n                // add claims configured on api resource\n                if (api.UserClaims != null)\n                {\n                    foreach (var claim in api.UserClaims)\n                    {\n                        additionalClaimTypes.Add(claim);\n                    }\n                }\n            }\n\n            foreach(var scope in resourceResult.Resources.ApiScopes)\n            {\n                // add claims configured on scopes\n                if (scope.UserClaims != null)\n                {\n                    foreach (var claim in scope.UserClaims)\n                    {\n                        additionalClaimTypes.Add(claim);\n                    }\n                }\n            }\n\n            // filter so we don't ask for claim types that we will eventually filter out\n            additionalClaimTypes = FilterRequestedClaimTypes(additionalClaimTypes).ToList();\n\n            var context = new ProfileDataRequestContext(\n                subject,\n                request.Client,\n                IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken,\n                additionalClaimTypes.Distinct())\n            {\n                RequestedResources = resourceResult,\n                ValidatedRequest = request\n            };\n\n            await Profile.GetProfileDataAsync(context);\n\n            var claims = FilterProtocolClaims(context.IssuedClaims);\n            if (claims != null)\n            {\n                outputClaims.AddRange(claims);\n            }\n        }\n\n        return outputClaims;\n    }\n\n    /// <summary>\n    /// Gets the standard subject claims.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <returns>A list of standard claims</returns>\n    protected virtual IEnumerable<Claim> GetStandardSubjectClaims(ClaimsPrincipal subject)\n    {\n        var claims = new List<Claim>\n        {\n            new Claim(JwtClaimTypes.Subject, subject.GetSubjectId()),\n            new Claim(JwtClaimTypes.AuthenticationTime, subject.GetAuthenticationTimeEpoch().ToString(), ClaimValueTypes.Integer64),\n            new Claim(JwtClaimTypes.IdentityProvider, subject.GetIdentityProvider())\n        };\n\n        claims.AddRange(subject.GetAuthenticationMethods());\n\n        return claims;\n    }\n\n    /// <summary>\n    /// Gets additional (and optional) claims from the cookie or incoming subject.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <returns>Additional claims</returns>\n    protected virtual IEnumerable<Claim> GetOptionalClaims(ClaimsPrincipal subject)\n    {\n        var claims = new List<Claim>();\n\n        var acr = subject.FindFirst(JwtClaimTypes.AuthenticationContextClassReference);\n        if (acr != null) claims.Add(acr);\n\n        return claims;\n    }\n\n    /// <summary>\n    /// Filters out protocol claims like amr, nonce etc..\n    /// </summary>\n    /// <param name=\"claims\">The claims.</param>\n    /// <returns></returns>\n    protected virtual IEnumerable<Claim> FilterProtocolClaims(IEnumerable<Claim> claims)\n    {\n        var claimsToFilter = claims.Where(x => Constants.Filters.ClaimsServiceFilterClaimTypes.Contains(x.Type));\n        if (claimsToFilter.Any())\n        {\n            var types = claimsToFilter.Select(x => x.Type);\n            Logger.LogDebug(\"Claim types from profile service that were filtered: {claimTypes}\", types);\n        }\n        return claims.Except(claimsToFilter);\n    }\n\n    /// <summary>\n    /// Filters out protocol claims like amr, nonce etc..\n    /// </summary>\n    /// <param name=\"claimTypes\">The claim types.</param>\n    protected virtual IEnumerable<string> FilterRequestedClaimTypes(IEnumerable<string> claimTypes)\n    {\n        var claimTypesToFilter = claimTypes.Where(x => Constants.Filters.ClaimsServiceFilterClaimTypes.Contains(x));\n        return claimTypes.Except(claimTypesToFilter);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultConsentService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default consent service\n/// </summary>\npublic class DefaultConsentService : IConsentService\n{\n    /// <summary>\n    /// The user consent store\n    /// </summary>\n    protected readonly IUserConsentStore UserConsentStore;\n\n    /// <summary>\n    ///  The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger<DefaultConsentService> Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultConsentService\" /> class.\n    /// </summary>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"userConsentStore\">The user consent store.</param>\n    /// <param name=\"logger\">The logger.</param>\n    /// <exception cref=\"System.ArgumentNullException\">store</exception>\n    public DefaultConsentService(ISystemClock clock, IUserConsentStore userConsentStore, ILogger<DefaultConsentService> logger)\n    {\n        Clock = clock;\n        UserConsentStore = userConsentStore;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Checks if consent is required.\n    /// </summary>\n    /// <param name=\"subject\">The user.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <param name=\"parsedScopes\">The parsed scopes.</param>\n    /// <returns>\n    /// Boolean if consent is required.\n    /// </returns>\n    /// <exception cref=\"System.ArgumentNullException\">\n    /// client\n    /// or\n    /// subject\n    /// </exception>\n    public virtual async Task<bool> RequiresConsentAsync(ClaimsPrincipal subject, Client client, IEnumerable<ParsedScopeValue> parsedScopes)\n    {\n        if (client == null) throw new ArgumentNullException(nameof(client));\n        if (subject == null) throw new ArgumentNullException(nameof(subject));\n\n        if (!client.RequireConsent)\n        {\n            Logger.LogDebug(\"Client is configured to not require consent, no consent is required\");\n            return false;\n        }\n\n        if (parsedScopes == null || !parsedScopes.Any())\n        {\n            Logger.LogDebug(\"No scopes being requested, no consent is required\");\n            return false;\n        }\n\n        if (!client.AllowRememberConsent)\n        {\n            Logger.LogDebug(\"Client is configured to not allow remembering consent, consent is required\");\n            return true;\n        }\n        \n        if (parsedScopes.Any(x => x.ParsedName != x.RawValue))\n        {\n            Logger.LogDebug(\"Scopes contains parameterized values, consent is required\");\n            return true;\n        }\n\n        var scopes = parsedScopes.Select(x => x.RawValue).ToArray();\n\n        // we always require consent for offline access if\n        // the client has not disabled RequireConsent \n        if (scopes.Contains(IdentityServerConstants.StandardScopes.OfflineAccess))\n        {\n            Logger.LogDebug(\"Scopes contains offline_access, consent is required\");\n            return true;\n        }\n\n        var consent = await UserConsentStore.GetUserConsentAsync(subject.GetSubjectId(), client.ClientId);\n\n        if (consent == null)\n        {\n            Logger.LogDebug(\"Found no prior consent from consent store, consent is required\");\n            return true;\n        }\n\n        if (consent.Expiration.HasExpired(Clock.UtcNow.UtcDateTime))\n        {\n            Logger.LogDebug(\"Consent found in consent store is expired, consent is required\");\n            await UserConsentStore.RemoveUserConsentAsync(consent.SubjectId, consent.ClientId);\n            return true;\n        }\n\n        if (consent.Scopes != null)\n        {\n            var intersect = scopes.Intersect(consent.Scopes);\n            var different = scopes.Count() != intersect.Count();\n\n            if (different)\n            {\n                Logger.LogDebug(\"Consent found in consent store is different than current request, consent is required\");\n            }\n            else\n            {\n                Logger.LogDebug(\"Consent found in consent store is same as current request, consent is not required\");\n            }\n\n            return different;\n        }\n\n        Logger.LogDebug(\"Consent found in consent store has no scopes, consent is required\");\n\n        return true;\n    }\n\n    /// <summary>\n    /// Updates the consent asynchronous.\n    /// </summary>\n    /// <param name=\"client\">The client.</param>\n    /// <param name=\"subject\">The subject.</param>\n    /// <param name=\"parsedScopes\">The parsed scopes.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">\n    /// client\n    /// or\n    /// subject\n    /// </exception>\n    public virtual async Task UpdateConsentAsync(ClaimsPrincipal subject, Client client, IEnumerable<ParsedScopeValue> parsedScopes)\n    {\n        if (client == null) throw new ArgumentNullException(nameof(client));\n        if (subject == null) throw new ArgumentNullException(nameof(subject));\n\n        if (client.AllowRememberConsent)\n        {\n            var subjectId = subject.GetSubjectId();\n            var clientId = client.ClientId;\n\n            var scopes = parsedScopes?.Select(x => x.RawValue).ToArray();\n            if (scopes != null && scopes.Any())\n            {\n                Logger.LogDebug(\"Client allows remembering consent, and consent given. Updating consent store for subject: {subject}\", subject.GetSubjectId());\n\n                var consent = new Consent\n                {\n                    CreationTime = Clock.UtcNow.UtcDateTime,\n                    SubjectId = subjectId,\n                    ClientId = clientId,\n                    Scopes = scopes\n                };\n\n                if (client.ConsentLifetime.HasValue)\n                {\n                    consent.Expiration = consent.CreationTime.AddSeconds(client.ConsentLifetime.Value);\n                }\n\n                await UserConsentStore.StoreUserConsentAsync(consent);\n            }\n            else\n            {\n                Logger.LogDebug(\"Client allows remembering consent, and no scopes provided. Removing consent from consent store for subject: {subject}\", subject.GetSubjectId());\n\n                await UserConsentStore.RemoveUserConsentAsync(subjectId, clientId);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultCorsPolicyService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default CORS policy service.\n/// </summary>\npublic class DefaultCorsPolicyService : ICorsPolicyService\n{\n    /// <summary>\n    /// Logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultCorsPolicyService\"/> class.\n    /// </summary>\n    public DefaultCorsPolicyService(ILogger<DefaultCorsPolicyService> logger)\n    {\n        Logger = logger;\n        AllowedOrigins = new HashSet<string>();\n    }\n\n    /// <summary>\n    /// The list allowed origins that are allowed.\n    /// </summary>\n    /// <value>\n    /// The allowed origins.\n    /// </value>\n    public ICollection<string> AllowedOrigins { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether all origins are allowed.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if allow all; otherwise, <c>false</c>.\n    /// </value>\n    public bool AllowAll { get; set; }\n\n    /// <summary>\n    /// Determines whether the origin allowed.\n    /// </summary>\n    /// <param name=\"origin\">The origin.</param>\n    /// <returns></returns>\n    public virtual Task<bool> IsOriginAllowedAsync(string origin)\n    {\n        if (!String.IsNullOrWhiteSpace(origin))\n        {\n            if (AllowAll)\n            {\n                Logger.LogDebug(\"AllowAll true, so origin: {0} is allowed\", Ioc.Sanitizer.Log.Sanitize(origin));\n                return Task.FromResult(true);\n            }\n\n            if (AllowedOrigins != null)\n            {\n                if (AllowedOrigins.Contains(origin, StringComparer.OrdinalIgnoreCase))\n                {\n                    Logger.LogDebug(\"AllowedOrigins configured and origin {0} is allowed\", Ioc.Sanitizer.Log.Sanitize(origin));\n                    return Task.FromResult(true);\n                }\n                else\n                {\n                    Logger.LogDebug(\"AllowedOrigins configured and origin {0} is not allowed\", Ioc.Sanitizer.Log.Sanitize(origin));\n                }\n            }\n\n            Logger.LogDebug(\"Exiting; origin {0} is not allowed\", Ioc.Sanitizer.Log.Sanitize(origin));\n        }\n\n        return Task.FromResult(false);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultDeviceFlowCodeService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services.Default;\n\n/// <summary>\n/// Default wrapper service for IDeviceFlowStore, handling key hashing\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IDeviceFlowCodeService\" />\npublic class DefaultDeviceFlowCodeService : IDeviceFlowCodeService\n{\n    private readonly IDeviceFlowStore _store;\n    private readonly IHandleGenerationService _handleGenerationService;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultDeviceFlowCodeService\"/> class.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"handleGenerationService\">The handle generation service.</param>\n    public DefaultDeviceFlowCodeService(IDeviceFlowStore store,\n        IHandleGenerationService handleGenerationService)\n    {\n        _store = store;\n        _handleGenerationService = handleGenerationService;\n    }\n\n    /// <summary>\n    /// Stores the device authorization request.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    /// <returns></returns>\n    public async Task<string> StoreDeviceAuthorizationAsync(string userCode, DeviceCode data)\n    {\n        var deviceCode = await _handleGenerationService.GenerateAsync();\n\n        await _store.StoreDeviceAuthorizationAsync(deviceCode.Sha256(), userCode.Sha256(), data);\n\n        return deviceCode;\n    }\n\n    /// <summary>\n    /// Finds device authorization by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <returns></returns>\n    public Task<DeviceCode> FindByUserCodeAsync(string userCode)\n    {\n        return _store.FindByUserCodeAsync(userCode.Sha256());\n    }\n\n    /// <summary>\n    /// Finds device authorization by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    /// <returns></returns>\n    public Task<DeviceCode> FindByDeviceCodeAsync(string deviceCode)\n    {\n        return _store.FindByDeviceCodeAsync(deviceCode.Sha256());\n    }\n\n    /// <summary>\n    /// Updates device authorization, searching by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    /// <returns></returns>\n    public Task UpdateByUserCodeAsync(string userCode, DeviceCode data)\n    {\n        return _store.UpdateByUserCodeAsync(userCode.Sha256(), data);\n    }\n\n    /// <summary>\n    /// Removes the device authorization, searching by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    /// <returns></returns>\n    public Task RemoveByDeviceCodeAsync(string deviceCode)\n    {\n        return _store.RemoveByDeviceCodeAsync(deviceCode.Sha256());\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultDeviceFlowInteractionService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\ninternal class DefaultDeviceFlowInteractionService : IDeviceFlowInteractionService\n{\n    private readonly IClientStore _clients;\n    private readonly IUserSession _session;\n    private readonly IDeviceFlowCodeService _devices;\n    private readonly IResourceStore _resourceStore;\n    private readonly IScopeParser _scopeParser;\n    private readonly ILogger<DefaultDeviceFlowInteractionService> _logger;\n\n    public DefaultDeviceFlowInteractionService(\n        IClientStore clients,\n        IUserSession session,\n        IDeviceFlowCodeService devices,\n        IResourceStore resourceStore,\n        IScopeParser scopeParser,\n        ILogger<DefaultDeviceFlowInteractionService> logger)\n    {\n        _clients = clients;\n        _session = session;\n        _devices = devices;\n        _resourceStore = resourceStore;\n        _scopeParser = scopeParser;\n        _logger = logger;\n    }\n\n    public async Task<DeviceFlowAuthorizationRequest> GetAuthorizationContextAsync(string userCode)\n    {\n        var deviceAuth = await _devices.FindByUserCodeAsync(userCode);\n        if (deviceAuth == null) return null;\n\n        var client = await _clients.FindClientByIdAsync(deviceAuth.ClientId);\n        if (client == null) return null;\n\n        var parsedScopesResult = _scopeParser.ParseScopeValues(deviceAuth.RequestedScopes);\n        var validatedResources = await _resourceStore.CreateResourceValidationResult(parsedScopesResult);\n\n        return new DeviceFlowAuthorizationRequest\n        {\n            Client = client,\n            ValidatedResources = validatedResources\n        };\n    }\n\n    public async Task<DeviceFlowInteractionResult> HandleRequestAsync(string userCode, ConsentResponse consent)\n    {\n        if (userCode == null) throw new ArgumentNullException(nameof(userCode));\n        if (consent == null) throw new ArgumentNullException(nameof(consent));\n        \n        var deviceAuth = await _devices.FindByUserCodeAsync(userCode);\n        if (deviceAuth == null) return LogAndReturnError(\"Invalid user code\", \"Device authorization failure - user code is invalid\");\n\n        var client = await _clients.FindClientByIdAsync(deviceAuth.ClientId);\n        if (client == null) return LogAndReturnError(\"Invalid client\", \"Device authorization failure - requesting client is invalid\");\n\n        var subject = await _session.GetUserAsync();\n        if (subject == null) return LogAndReturnError(\"No user present in device flow request\", \"Device authorization failure - no user found\");\n        \n        var sid = await _session.GetSessionIdAsync();\n\n        deviceAuth.IsAuthorized = true;\n        deviceAuth.Subject = subject;\n        deviceAuth.SessionId = sid;\n        deviceAuth.Description = consent.Description;\n        deviceAuth.AuthorizedScopes = consent.ScopesValuesConsented;\n\n        // TODO: Device Flow - Record consent template\n        if (consent.RememberConsent)\n        {\n            //var consentRequest = new ConsentRequest(request, subject);\n            //await _consentMessageStore.WriteAsync(consentRequest.Id, new Message<ConsentResponse>(consent, _clock.UtcNow.UtcDateTime));\n        }\n\n        await _devices.UpdateByUserCodeAsync(userCode, deviceAuth);\n\n        return new DeviceFlowInteractionResult();\n    }\n\n    private DeviceFlowInteractionResult LogAndReturnError(string error, string errorDescription = null)\n    {\n        _logger.LogError(errorDescription);\n        return DeviceFlowInteractionResult.Failure(error);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultEventService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Events;\n\n/// <summary>\n/// The default event service\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IEventService\" />\npublic class DefaultEventService : IEventService\n{\n    /// <summary>\n    /// The options\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// The context\n    /// </summary>\n    protected readonly IHttpContextAccessor Context;\n\n    /// <summary>\n    /// The sink\n    /// </summary>\n    protected readonly IEventSink Sink;\n\n    /// <summary>\n    /// The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultEventService\"/> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"context\">The context.</param>\n    /// <param name=\"sink\">The sink.</param>\n    /// <param name=\"clock\">The clock.</param>\n    public DefaultEventService(IdentityServerOptions options, IHttpContextAccessor context, IEventSink sink, ISystemClock clock)\n    {\n        Options = options;\n        Context = context;\n        Sink = sink;\n        Clock = clock;\n    }\n\n    /// <summary>\n    /// Raises the specified event.\n    /// </summary>\n    /// <param name=\"evt\">The event.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">evt</exception>\n    public async Task RaiseAsync(Event evt)\n    {\n        if (evt == null) throw new ArgumentNullException(nameof(evt));\n\n        if (CanRaiseEvent(evt))\n        {\n            await PrepareEventAsync(evt);\n            await Sink.PersistAsync(evt);\n        }\n    }\n\n    /// <summary>\n    /// Indicates if the type of event will be persisted.\n    /// </summary>\n    /// <param name=\"evtType\"></param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentOutOfRangeException\"></exception>\n    public bool CanRaiseEventType(EventTypes evtType)\n    {\n        switch (evtType)\n        {\n            case EventTypes.Failure:\n                return Options.Events.RaiseFailureEvents;\n            case EventTypes.Information:\n                return Options.Events.RaiseInformationEvents;\n            case EventTypes.Success:\n                return Options.Events.RaiseSuccessEvents;\n            case EventTypes.Error:\n                return Options.Events.RaiseErrorEvents;\n            default:\n                throw new ArgumentOutOfRangeException(nameof(evtType));\n        }\n    }\n\n    /// <summary>\n    /// Determines whether this event would be persisted.\n    /// </summary>\n    /// <param name=\"evt\">The evt.</param>\n    /// <returns>\n    ///   <c>true</c> if this event would be persisted; otherwise, <c>false</c>.\n    /// </returns>\n    protected virtual bool CanRaiseEvent(Event evt)\n    {\n        return CanRaiseEventType(evt.EventType);\n    }\n\n    /// <summary>\n    /// Prepares the event.\n    /// </summary>\n    /// <param name=\"evt\">The evt.</param>\n    /// <returns></returns>\n    protected virtual async Task PrepareEventAsync(Event evt)\n    {\n        evt.ActivityId = Context.HttpContext.TraceIdentifier;\n        evt.TimeStamp = Clock.UtcNow.UtcDateTime;\n        evt.ProcessId = Process.GetCurrentProcess().Id;\n\n        if (Context.HttpContext.Connection.LocalIpAddress != null)\n        {\n            evt.LocalIpAddress = Context.HttpContext.Connection.LocalIpAddress.ToString() + \":\" + Context.HttpContext.Connection.LocalPort;\n        }\n        else\n        {\n            evt.LocalIpAddress = \"unknown\";\n        }\n\n        if (Context.HttpContext.Connection.RemoteIpAddress != null)\n        {\n            evt.RemoteIpAddress = Context.HttpContext.Connection.RemoteIpAddress.ToString();\n        }\n        else\n        {\n            evt.RemoteIpAddress = \"unknown\";\n        }\n\n        await evt.PrepareAsync();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultEventSink.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default implementation of the event service. Write events raised to the log.\n/// </summary>\npublic class DefaultEventSink : IEventSink\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultEventSink\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultEventSink(ILogger<DefaultEventService> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Raises the specified event.\n    /// </summary>\n    /// <param name=\"evt\">The event.</param>\n    /// <exception cref=\"System.ArgumentNullException\">evt</exception>\n    public virtual Task PersistAsync(Event evt)\n    {\n        if (evt == null) throw new ArgumentNullException(nameof(evt));\n\n        _logger.LogInformation(\"{@event}\", evt);\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultHandleGenerationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default handle generation service\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IHandleGenerationService\" />\npublic class DefaultHandleGenerationService : IHandleGenerationService\n{\n    /// <summary>\n    /// Generates a handle.\n    /// </summary>\n    /// <param name=\"length\">The length.</param>\n    /// <returns></returns>\n    public Task<string> GenerateAsync(int length)\n    {\n        return Task.FromResult(CryptoRandom.CreateUniqueId(length, CryptoRandom.OutputFormat.Hex));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultIdentityServerInteractionService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\ninternal class DefaultIdentityServerInteractionService : IIdentityServerInteractionService\n{\n    private readonly ISystemClock _clock;\n    private readonly IHttpContextAccessor _context;\n    private readonly IMessageStore<LogoutMessage> _logoutMessageStore;\n    private readonly IMessageStore<ErrorMessage> _errorMessageStore;\n    private readonly IConsentMessageStore _consentMessageStore;\n    private readonly IPersistedGrantService _grants;\n    private readonly IUserSession _userSession;\n    private readonly ILogger _logger;\n    private readonly ReturnUrlParser _returnUrlParser;\n\n    public DefaultIdentityServerInteractionService(\n        ISystemClock clock,\n        IHttpContextAccessor context,\n        IMessageStore<LogoutMessage> logoutMessageStore,\n        IMessageStore<ErrorMessage> errorMessageStore,\n        IConsentMessageStore consentMessageStore,\n        IPersistedGrantService grants,\n        IUserSession userSession,\n        ReturnUrlParser returnUrlParser,\n        ILogger<DefaultIdentityServerInteractionService> logger)\n    {\n        _clock = clock;\n        _context = context;\n        _logoutMessageStore = logoutMessageStore;\n        _errorMessageStore = errorMessageStore;\n        _consentMessageStore = consentMessageStore;\n        _grants = grants;\n        _userSession = userSession;\n        _returnUrlParser = returnUrlParser;\n        _logger = logger;\n    }\n\n    public async Task<AuthorizationRequest> GetAuthorizationContextAsync(string returnUrl)\n    {\n        var result = await _returnUrlParser.ParseAsync(returnUrl);\n\n        if (result != null)\n        {\n            _logger.LogTrace(\"AuthorizationRequest being returned\");\n        }\n        else\n        {\n            _logger.LogTrace(\"No AuthorizationRequest being returned\");\n        }\n\n        return result;\n    }\n\n    public async Task<LogoutRequest> GetLogoutContextAsync(string logoutId)\n    {\n        var msg = await _logoutMessageStore.ReadAsync(logoutId);\n        var iframeUrl = await _context.HttpContext.GetIdentityServerSignoutFrameCallbackUrlAsync(msg?.Data);\n        return new LogoutRequest(iframeUrl, msg?.Data);\n    }\n\n    public async Task<string> CreateLogoutContextAsync()\n    {\n        var user = await _userSession.GetUserAsync();\n        if (user != null)\n        {\n            var clientIds = await _userSession.GetClientListAsync();\n            if (clientIds.Any())\n            {\n                var sid = await _userSession.GetSessionIdAsync();\n                var msg = new Message<LogoutMessage>(new LogoutMessage\n                {\n                    SubjectId = user?.GetSubjectId(),\n                    SessionId = sid,\n                    ClientIds = clientIds\n                }, _clock.UtcNow.UtcDateTime);\n                var id = await _logoutMessageStore.WriteAsync(msg);\n                return id;\n            }\n        }\n\n        return null;\n    }\n\n    public async Task<ErrorMessage> GetErrorContextAsync(string errorId)\n    {\n        if (errorId != null)\n        { \n            var result = await _errorMessageStore.ReadAsync(errorId);\n            var data = result?.Data;\n            if (data != null)\n            {\n                _logger.LogTrace(\"Error context loaded\");\n            }\n            else\n            {\n                _logger.LogTrace(\"No error context found\");\n            }\n            return data;\n        }\n\n        _logger.LogTrace(\"No error context found\");\n\n        return null;\n    }\n\n    public async Task GrantConsentAsync(AuthorizationRequest request, ConsentResponse consent, string subject = null)\n    {\n        if (subject == null)\n        {\n            var user = await _userSession.GetUserAsync();\n            subject = user?.GetSubjectId();\n        }\n\n        if (subject == null && consent.Granted)\n        {\n            throw new ArgumentNullException(nameof(subject), \"User is not currently authenticated, and no subject id passed\");\n        }\n\n        var consentRequest = new ConsentRequest(request, subject);\n        await _consentMessageStore.WriteAsync(consentRequest.Id, new Message<ConsentResponse>(consent, _clock.UtcNow.UtcDateTime));\n    }\n\n    public Task DenyAuthorizationAsync(AuthorizationRequest request, AuthorizationError error, string errorDescription = null)\n    {\n        var response = new ConsentResponse \n        {\n            Error = error,\n            ErrorDescription = errorDescription\n        };\n        return GrantConsentAsync(request, response);\n    }\n\n    public bool IsValidReturnUrl(string returnUrl)\n    {\n        var result = _returnUrlParser.IsValidReturnUrl(returnUrl);\n\n        if (result)\n        {\n            _logger.LogTrace(\"IsValidReturnUrl true\");\n        }\n        else\n        {\n            _logger.LogTrace(\"IsValidReturnUrl false\");\n        }\n\n        return result;\n    }\n\n    public async Task<IEnumerable<Grant>> GetAllUserGrantsAsync()\n    {\n        var user = await _userSession.GetUserAsync();\n        if (user != null)\n        {\n            var subject = user.GetSubjectId();\n            return await _grants.GetAllGrantsAsync(subject);\n        }\n\n        return Enumerable.Empty<Grant>();\n    }\n\n    public async Task RevokeUserConsentAsync(string clientId)\n    {\n        var user = await _userSession.GetUserAsync();\n        if (user != null)\n        {\n            var subject = user.GetSubjectId();\n            await _grants.RemoveAllGrantsAsync(subject, clientId);\n        }\n    }\n\n    public async Task RevokeTokensForCurrentSessionAsync()\n    {\n        var user = await _userSession.GetUserAsync();\n        if (user != null)\n        {\n            var subject = user.GetSubjectId();\n            var sessionId = await _userSession.GetSessionIdAsync();\n            await _grants.RemoveAllGrantsAsync(subject, sessionId: sessionId);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultJwtRequestUriHttpClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default JwtRequest client\n/// </summary>\npublic class DefaultJwtRequestUriHttpClient : IJwtRequestUriHttpClient\n{\n    private readonly HttpClient _client;\n    private readonly IdentityServerOptions _options;\n    private readonly ILogger<DefaultJwtRequestUriHttpClient> _logger;\n\n    /// <summary>\n    /// ctor\n    /// </summary>\n    /// <param name=\"client\">An HTTP client</param>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"loggerFactory\">The logger factory</param>\n    public DefaultJwtRequestUriHttpClient(HttpClient client, IdentityServerOptions options, ILoggerFactory loggerFactory)\n    {\n        _client = client;\n        _options = options;\n        _logger = loggerFactory.CreateLogger<DefaultJwtRequestUriHttpClient>();\n    }\n\n\n    /// <inheritdoc />\n    public async Task<string> GetJwtAsync(string url, Client client)\n    {\n        var req = new HttpRequestMessage(HttpMethod.Get, url);\n        req.Properties.Add(IdentityServerConstants.JwtRequestClientKey, client);\n\n        var response = await _client.SendAsync(req);\n        if (response.StatusCode == System.Net.HttpStatusCode.OK)\n        {\n            if (_options.StrictJarValidation)\n            {\n                if (!string.Equals(response.Content.Headers.ContentType.MediaType,\n                    $\"application/{JwtClaimTypes.JwtTypes.AuthorizationRequest}\", StringComparison.Ordinal))\n                {\n                    _logger.LogError(\"Invalid content type {type} from jwt url {url}\", response.Content.Headers.ContentType.MediaType, url);\n                    return null;\n                }\n            }\n\n            _logger.LogDebug(\"Success http response from jwt url {url}\", url);\n            \n            var json = await response.Content.ReadAsStringAsync();\n            return json;\n        }\n            \n        _logger.LogError(\"Invalid http status code {status} from jwt url {url}\", response.StatusCode, url);\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultKeyMaterialService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// The default key material service\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IKeyMaterialService\" />\npublic class DefaultKeyMaterialService : IKeyMaterialService\n{\n    private readonly IEnumerable<ISigningCredentialStore> _signingCredentialStores;\n    private readonly IEnumerable<IValidationKeysStore> _validationKeysStores;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultKeyMaterialService\"/> class.\n    /// </summary>\n    /// <param name=\"validationKeysStores\">The validation keys stores.</param>\n    /// <param name=\"signingCredentialStores\">The signing credential store.</param>\n    public DefaultKeyMaterialService(IEnumerable<IValidationKeysStore> validationKeysStores, IEnumerable<ISigningCredentialStore> signingCredentialStores)\n    {\n        _signingCredentialStores = signingCredentialStores;\n        _validationKeysStores = validationKeysStores;\n    }\n\n    /// <inheritdoc/>\n    public async Task<SigningCredentials> GetSigningCredentialsAsync(IEnumerable<string> allowedAlgorithms = null)\n    {\n        if (_signingCredentialStores.Any())\n        {\n            if (allowedAlgorithms.EnumerableIsNullOrEmpty())\n            {\n                return await _signingCredentialStores.First().GetSigningCredentialsAsync();\n            }\n\n            var credential = (await GetAllSigningCredentialsAsync()).FirstOrDefault(c => allowedAlgorithms.Contains(c.Algorithm));\n            if (credential is null)\n            {\n                throw new InvalidOperationException($\"No signing credential for algorithms ({allowedAlgorithms.ToSpaceSeparatedString()}) registered.\");\n            }\n\n            return credential;\n        }\n\n        return null;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<SigningCredentials>> GetAllSigningCredentialsAsync()\n    {\n        var credentials = new List<SigningCredentials>();\n\n        foreach (var store in _signingCredentialStores)\n        {\n            credentials.Add(await store.GetSigningCredentialsAsync());\n        }\n\n        return credentials;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<SecurityKeyInfo>> GetValidationKeysAsync()\n    {\n        var keys = new List<SecurityKeyInfo>();\n\n        foreach (var store in _validationKeysStores)\n        {\n            keys.AddRange(await store.GetValidationKeysAsync());\n        }\n\n        return keys;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultPersistedGrantService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default persisted grant service\n/// </summary>\npublic class DefaultPersistedGrantService : IPersistedGrantService\n{\n    private readonly ILogger _logger;\n    private readonly IPersistedGrantStore _store;\n    private readonly IPersistentGrantSerializer _serializer;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultPersistedGrantService\"/> class.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"serializer\">The serializer.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultPersistedGrantService(IPersistedGrantStore store, \n        IPersistentGrantSerializer serializer,\n        ILogger<DefaultPersistedGrantService> logger)\n    {\n        _store = store;\n        _serializer = serializer;\n        _logger = logger;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<Grant>> GetAllGrantsAsync(string subjectId)\n    {\n        if (String.IsNullOrWhiteSpace(subjectId)) throw new ArgumentNullException(nameof(subjectId));\n        \n        var grants = (await _store.GetAllAsync(new PersistedGrantFilter { SubjectId = subjectId })).ToArray();\n\n        try\n        {\n            var consents = grants.Where(x => x.Type == IdentityServerConstants.PersistedGrantTypes.UserConsent)\n                .Select(x => _serializer.Deserialize<Consent>(x.Data))\n                .Select(x => new Grant \n                {\n                    ClientId = x.ClientId,\n                    SubjectId = subjectId,\n                    Scopes = x.Scopes,\n                    CreationTime = x.CreationTime,\n                    Expiration = x.Expiration\n                });\n\n            var codes = grants.Where(x => x.Type == IdentityServerConstants.PersistedGrantTypes.AuthorizationCode)\n                .Select(x => _serializer.Deserialize<AuthorizationCode>(x.Data))\n                .Select(x => new Grant\n                {\n                    ClientId = x.ClientId,\n                    SubjectId = subjectId,\n                    Description = x.Description,\n                    Scopes = x.RequestedScopes,\n                    CreationTime = x.CreationTime,\n                    Expiration = x.CreationTime.AddSeconds(x.Lifetime)\n                });\n\n            var refresh = grants.Where(x => x.Type == IdentityServerConstants.PersistedGrantTypes.RefreshToken)\n                .Select(x => _serializer.Deserialize<RefreshToken>(x.Data))\n                .Select(x => new Grant\n                {\n                    ClientId = x.ClientId,\n                    SubjectId = subjectId,\n                    Description = x.Description,\n                    Scopes = x.Scopes,\n                    CreationTime = x.CreationTime,\n                    Expiration = x.CreationTime.AddSeconds(x.Lifetime)\n                });\n\n            var access = grants.Where(x => x.Type == IdentityServerConstants.PersistedGrantTypes.ReferenceToken)\n                .Select(x => _serializer.Deserialize<Token>(x.Data))\n                .Select(x => new Grant\n                {\n                    ClientId = x.ClientId,\n                    SubjectId = subjectId,\n                    Description = x.Description,\n                    Scopes = x.Scopes,\n                    CreationTime = x.CreationTime,\n                    Expiration = x.CreationTime.AddSeconds(x.Lifetime)\n                });\n\n            consents = Join(consents, codes);\n            consents = Join(consents, refresh);\n            consents = Join(consents, access);\n\n            return consents.ToArray();\n        }\n        catch (Exception ex)\n        {\n            _logger.LogError(ex, \"Failed processing results from grant store.\");\n        }\n\n        return Enumerable.Empty<Grant>();\n    }\n\n    private IEnumerable<Grant> Join(IEnumerable<Grant> first, IEnumerable<Grant> second)\n    {\n        var list = first.ToList();\n\n        foreach(var other in second)\n        {\n            var match = list.FirstOrDefault(x => x.ClientId == other.ClientId);\n            if (match != null)\n            {\n                match.Scopes = match.Scopes.Union(other.Scopes).Distinct();\n\n                if (match.CreationTime > other.CreationTime)\n                {\n                    // show the earlier creation time\n                    match.CreationTime = other.CreationTime;\n                }\n\n                if (match.Expiration == null || other.Expiration == null)\n                {\n                    // show that there is no expiration to one of the grants\n                    match.Expiration = null;\n                }\n                else if (match.Expiration < other.Expiration)\n                {\n                    // show the latest expiration\n                    match.Expiration = other.Expiration;\n                }\n\n                match.Description = match.Description ?? other.Description;\n            }\n            else\n            {\n                list.Add(other);\n            }\n        }\n\n        return list;\n    }\n\n    /// <inheritdoc/>\n    public Task RemoveAllGrantsAsync(string subjectId, string clientId = null, string sessionId = null)\n    {\n        if (String.IsNullOrWhiteSpace(subjectId)) throw new ArgumentNullException(nameof(subjectId));\n\n        return _store.RemoveAllAsync(new PersistedGrantFilter {\n            SubjectId = subjectId,\n            ClientId = clientId,\n            SessionId = sessionId\n        });\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default profile service implementation.\n/// This implementation sources all claims from the current subject (e.g. the cookie).\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IProfileService\" />\npublic class DefaultProfileService : IProfileService\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultProfileService\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultProfileService(ILogger<DefaultProfileService> logger)\n    {\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint)\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public virtual Task GetProfileDataAsync(ProfileDataRequestContext context)\n    {\n        context.LogProfileRequest(Logger);\n        context.AddRequestedClaims(context.Subject.Claims);\n        context.LogIssuedClaims(Logger);\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// This method gets called whenever identity server needs to determine if the user is valid or active (e.g. if the user's account has been deactivated since they logged in).\n    /// (e.g. during token issuance or validation).\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public virtual Task IsActiveAsync(IsActiveContext context)\n    {\n        Logger.LogDebug(\"IsActive called from: {caller}\", context.Caller);\n\n        context.IsActive = true;\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultRefreshTokenService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default refresh token service\n/// </summary>\npublic class DefaultRefreshTokenService : IRefreshTokenService\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The refresh token store\n    /// </summary>\n    protected IRefreshTokenStore RefreshTokenStore { get; }\n\n    /// <summary>\n    /// The profile service\n    /// </summary>\n    protected IProfileService Profile { get; }\n\n    /// <summary>\n    /// The clock\n    /// </summary>\n    protected ISystemClock Clock { get; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultRefreshTokenService\" /> class.\n    /// </summary>\n    /// <param name=\"refreshTokenStore\">The refresh token store</param>\n    /// <param name=\"profile\"></param>\n    /// <param name=\"clock\">The clock</param>\n    /// <param name=\"logger\">The logger</param>\n    public DefaultRefreshTokenService(IRefreshTokenStore refreshTokenStore, IProfileService profile,\n        ISystemClock clock,\n        ILogger<DefaultRefreshTokenService> logger)\n    {\n        RefreshTokenStore = refreshTokenStore;\n        Profile = profile;\n        Clock = clock;\n\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Validates a refresh token\n    /// </summary>\n    /// <param name=\"tokenHandle\">The token handle.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns></returns>\n    public virtual async Task<TokenValidationResult> ValidateRefreshTokenAsync(string tokenHandle, Client client)\n    {\n        var invalidGrant = new TokenValidationResult\n        {\n            IsError = true, Error = OidcConstants.TokenErrors.InvalidGrant\n        };\n\n        Logger.LogTrace(\"Start refresh token validation\");\n\n        /////////////////////////////////////////////\n        // check if refresh token is valid\n        /////////////////////////////////////////////\n        var refreshToken = await RefreshTokenStore.GetRefreshTokenAsync(tokenHandle);\n        if (refreshToken == null)\n        {\n            Logger.LogWarning(\"Invalid refresh token\");\n            return invalidGrant;\n        }\n\n        /////////////////////////////////////////////\n        // check if refresh token has expired\n        /////////////////////////////////////////////\n        if (refreshToken.CreationTime.HasExceeded(refreshToken.Lifetime, Clock.UtcNow.DateTime))\n        {\n            Logger.LogWarning(\"Refresh token has expired.\");\n            return invalidGrant;\n        }\n        \n        /////////////////////////////////////////////\n        // check if client belongs to requested refresh token\n        /////////////////////////////////////////////\n        if (client.ClientId != refreshToken.ClientId)\n        {\n            Logger.LogError(\"{0} tries to refresh token belonging to {1}\", client.ClientId, refreshToken.ClientId);\n            return invalidGrant;\n        }\n\n        /////////////////////////////////////////////\n        // check if client still has offline_access scope\n        /////////////////////////////////////////////\n        if (!client.AllowOfflineAccess)\n        {\n            Logger.LogError(\"{clientId} does not have access to offline_access scope anymore\", client.ClientId);\n            return invalidGrant;\n        }\n        \n        /////////////////////////////////////////////\n        // check if refresh token has been consumed\n        /////////////////////////////////////////////\n        if (refreshToken.ConsumedTime.HasValue)\n        {\n            if ((await AcceptConsumedTokenAsync(refreshToken)) == false)\n            {\n                Logger.LogWarning(\"Rejecting refresh token because it has been consumed already.\");\n                return invalidGrant;\n            }\n        }\n        \n        /////////////////////////////////////////////\n        // make sure user is enabled\n        /////////////////////////////////////////////\n        var isActiveCtx = new IsActiveContext(\n            refreshToken.Subject,\n            client,\n            IdentityServerConstants.ProfileIsActiveCallers.RefreshTokenValidation);\n\n        await Profile.IsActiveAsync(isActiveCtx);\n\n        if (isActiveCtx.IsActive == false)\n        {\n            Logger.LogError(\"{subjectId} has been disabled\", refreshToken.Subject.GetSubjectId());\n            return invalidGrant;\n        }\n        \n        return new TokenValidationResult\n        {\n            IsError = false, \n            RefreshToken = refreshToken, \n            Client = client\n        };\n    }\n\n    /// <summary>\n    /// Callback to decide if an already consumed token should be accepted.\n    /// </summary>\n    /// <param name=\"refreshToken\"></param>\n    /// <returns></returns>\n    protected virtual Task<bool> AcceptConsumedTokenAsync(RefreshToken refreshToken)\n    {\n        // by default we will not accept consumed tokens\n        // change the behavior here to implement a time window\n        // you can also implement additional revocation logic here\n        return Task.FromResult(false);\n    }\n\n    /// <summary>\n    /// Creates the refresh token.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <param name=\"accessToken\">The access token.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    /// The refresh token handle\n    /// </returns>\n    public virtual async Task<string> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken,\n        Client client)\n    {\n        Logger.LogDebug(\"Creating refresh token\");\n\n        int lifetime;\n        if (client.RefreshTokenExpiration == TokenExpiration.Absolute)\n        {\n            Logger.LogDebug(\"Setting an absolute lifetime: {absoluteLifetime}\",\n                client.AbsoluteRefreshTokenLifetime);\n            lifetime = client.AbsoluteRefreshTokenLifetime;\n        }\n        else\n        {\n            lifetime = client.SlidingRefreshTokenLifetime;\n            if (client.AbsoluteRefreshTokenLifetime > 0 && lifetime > client.AbsoluteRefreshTokenLifetime)\n            {\n                Logger.LogWarning(\n                    \"Client {clientId}'s configured \" + nameof(client.SlidingRefreshTokenLifetime) +\n                    \" of {slidingLifetime} exceeds its \" + nameof(client.AbsoluteRefreshTokenLifetime) +\n                    \" of {absoluteLifetime}. The refresh_token's sliding lifetime will be capped to the absolute lifetime\",\n                    client.ClientId, lifetime, client.AbsoluteRefreshTokenLifetime);\n                lifetime = client.AbsoluteRefreshTokenLifetime;\n            }\n\n            Logger.LogDebug(\"Setting a sliding lifetime: {slidingLifetime}\", lifetime);\n        }\n\n        var refreshToken = new RefreshToken\n        {\n            CreationTime = Clock.UtcNow.UtcDateTime, Lifetime = lifetime, AccessToken = accessToken\n        };\n\n        var handle = await RefreshTokenStore.StoreRefreshTokenAsync(refreshToken);\n        return handle;\n    }\n\n    /// <summary>\n    /// Updates the refresh token.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <param name=\"refreshToken\">The refresh token.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    /// The refresh token handle\n    /// </returns>\n    public virtual async Task<string> UpdateRefreshTokenAsync(string handle, RefreshToken refreshToken,\n        Client client)\n    {\n        Logger.LogDebug(\"Updating refresh token\");\n\n        bool needsCreate = false;\n        bool needsUpdate = false;\n\n        if (client.RefreshTokenUsage == TokenUsage.OneTimeOnly)\n        {\n            Logger.LogDebug(\"Token usage is one-time only. Setting current handle as consumed, and generating new handle\");\n\n            // flag as consumed\n            if (refreshToken.ConsumedTime == null)\n            {\n                refreshToken.ConsumedTime = Clock.UtcNow.UtcDateTime;\n                await RefreshTokenStore.UpdateRefreshTokenAsync(handle, refreshToken);\n            }\n\n            // create new one\n            needsCreate = true;\n        }\n\n        if (client.RefreshTokenExpiration == TokenExpiration.Sliding)\n        {\n            Logger.LogDebug(\"Refresh token expiration is sliding - extending lifetime\");\n\n            // if absolute exp > 0, make sure we don't exceed absolute exp\n            // if absolute exp = 0, allow indefinite slide\n            var currentLifetime = refreshToken.CreationTime.GetLifetimeInSeconds(Clock.UtcNow.UtcDateTime);\n            Logger.LogDebug(\"Current lifetime: {currentLifetime}\", currentLifetime.ToString());\n\n            var newLifetime = currentLifetime + client.SlidingRefreshTokenLifetime;\n            Logger.LogDebug(\"New lifetime: {slidingLifetime}\", newLifetime.ToString());\n\n            // zero absolute refresh token lifetime represents unbounded absolute lifetime\n            // if absolute lifetime > 0, cap at absolute lifetime\n            if (client.AbsoluteRefreshTokenLifetime > 0 && newLifetime > client.AbsoluteRefreshTokenLifetime)\n            {\n                newLifetime = client.AbsoluteRefreshTokenLifetime;\n                Logger.LogDebug(\"New lifetime exceeds absolute lifetime, capping it to {newLifetime}\",\n                    newLifetime.ToString());\n            }\n\n            refreshToken.Lifetime = newLifetime;\n            needsUpdate = true;\n        }\n\n        if (needsCreate)\n        {\n            // set it to null so that we save non-consumed token\n            refreshToken.ConsumedTime = null;\n            handle = await RefreshTokenStore.StoreRefreshTokenAsync(refreshToken);\n            Logger.LogDebug(\"Created refresh token in store\");\n        }\n        else if (needsUpdate)\n        {\n            await RefreshTokenStore.UpdateRefreshTokenAsync(handle, refreshToken);\n            Logger.LogDebug(\"Updated refresh token in store\");\n        }\n        else\n        {\n            Logger.LogDebug(\"No updates to refresh token done\");\n        }\n\n        return handle;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultReplayCache.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default implementation of the replay cache using IDistributedCache\n/// </summary>\npublic class DefaultReplayCache : IReplayCache\n{\n    private const string Prefix = nameof(DefaultReplayCache) + \":\";\n    \n    private readonly IDistributedCache _cache;\n    \n    /// <summary>\n    /// ctor\n    /// </summary>\n    /// <param name=\"cache\"></param>\n    public DefaultReplayCache(IDistributedCache cache)\n    {\n        _cache = cache;\n    }\n    \n    /// <inheritdoc />\n    public async Task AddAsync(string purpose, string handle, DateTimeOffset expiration)\n    {\n        var options = new DistributedCacheEntryOptions\n        {\n            AbsoluteExpiration = expiration\n        };\n        \n        await _cache.SetAsync(Prefix + purpose + handle, new byte[] { }, options);\n    }\n\n    /// <inheritdoc />\n    public async Task<bool> ExistsAsync(string purpose, string handle)\n    {\n        return (await _cache.GetAsync(Prefix + purpose + handle, default)) != null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultTokenCreationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default token creation service\n/// </summary>\npublic class DefaultTokenCreationService : ITokenCreationService\n{\n    /// <summary>\n    /// The key service\n    /// </summary>\n    protected readonly IKeyMaterialService Keys;\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    ///  The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// The options\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultTokenCreationService\"/> class.\n    /// </summary>\n    /// <param name=\"clock\">The options.</param>\n    /// <param name=\"keys\">The keys.</param>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultTokenCreationService(\n        ISystemClock clock,\n        IKeyMaterialService keys,\n        IdentityServerOptions options,\n        ILogger<DefaultTokenCreationService> logger)\n    {\n        Clock = clock;\n        Keys = keys;\n        Options = options;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Creates the token.\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <returns>\n    /// A protected and serialized security token\n    /// </returns>\n    public virtual async Task<string> CreateTokenAsync(Token token)\n    {\n        var header = await CreateHeaderAsync(token);\n        var payload = await CreatePayloadAsync(token);\n\n        return await CreateJwtAsync(new JwtSecurityToken(header, payload));\n    }\n\n    /// <summary>\n    /// Creates the JWT header\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <returns>The JWT header</returns>\n    protected virtual async Task<JwtHeader> CreateHeaderAsync(Token token)\n    {\n        var credential = await Keys.GetSigningCredentialsAsync(token.AllowedSigningAlgorithms);\n\n        if (credential == null)\n        {\n            throw new InvalidOperationException(\"No signing credential is configured. Can't create JWT token\");\n        }\n\n        var header = new JwtHeader(credential);\n\n        // emit x5t claim for backwards compatibility with v4 of MS JWT library\n        if (credential.Key is X509SecurityKey x509Key)\n        {\n            var cert = x509Key.Certificate;\n            if (Clock.UtcNow.UtcDateTime > cert.NotAfter)\n            {\n                Logger.LogWarning(\"Certificate {subjectName} has expired on {expiration}\", cert.Subject, cert.NotAfter.ToString(CultureInfo.InvariantCulture));\n            }\n\n            header[\"x5t\"] = Base64Url.Encode(cert.GetCertHash());\n        }\n\n        if (token.Type == TokenTypes.AccessToken)\n        {\n            if (Options.AccessTokenJwtType.IsPresent())\n            {\n                header[\"typ\"] = Options.AccessTokenJwtType;\n            }\n        }\n\n        return header;\n    }\n\n    /// <summary>\n    /// Creates the JWT payload\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <returns>The JWT payload</returns>\n    protected virtual Task<JwtPayload> CreatePayloadAsync(Token token)\n    {\n        var payload = token.CreateJwtPayload(Clock, Options, Logger);\n        return Task.FromResult(payload);\n    }\n\n    /// <summary>\n    /// Applies the signature to the JWT\n    /// </summary>\n    /// <param name=\"jwt\">The JWT object.</param>\n    /// <returns>The signed JWT</returns>\n    protected virtual Task<string> CreateJwtAsync(JwtSecurityToken jwt)\n    {\n        var handler = new JwtSecurityTokenHandler();\n        return Task.FromResult(handler.WriteToken(jwt));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultTokenService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default token service\n/// </summary>\npublic class DefaultTokenService : ITokenService\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The HTTP context accessor\n    /// </summary>\n    protected readonly IHttpContextAccessor ContextAccessor;\n\n    /// <summary>\n    /// The claims provider\n    /// </summary>\n    protected readonly IClaimsService ClaimsProvider;\n\n    /// <summary>\n    /// The reference token store\n    /// </summary>\n    protected readonly IReferenceTokenStore ReferenceTokenStore;\n\n    /// <summary>\n    /// The signing service\n    /// </summary>\n    protected readonly ITokenCreationService CreationService;\n\n    /// <summary>\n    /// The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// The key material service\n    /// </summary>\n    protected readonly IKeyMaterialService KeyMaterialService;\n\n    /// <summary>\n    /// The IdentityServer options\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultTokenService\" /> class.\n    /// </summary>\n    /// <param name=\"claimsProvider\">The claims provider.</param>\n    /// <param name=\"referenceTokenStore\">The reference token store.</param>\n    /// <param name=\"creationService\">The signing service.</param>\n    /// <param name=\"contextAccessor\">The HTTP context accessor.</param>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"keyMaterialService\"></param>\n    /// <param name=\"options\">The IdentityServer options</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultTokenService(\n        IClaimsService claimsProvider,\n        IReferenceTokenStore referenceTokenStore,\n        ITokenCreationService creationService,\n        IHttpContextAccessor contextAccessor,\n        ISystemClock clock,\n        IKeyMaterialService keyMaterialService,\n        IdentityServerOptions options,\n        ILogger<DefaultTokenService> logger)\n    {\n        ContextAccessor = contextAccessor;\n        ClaimsProvider = claimsProvider;\n        ReferenceTokenStore = referenceTokenStore;\n        CreationService = creationService;\n        Clock = clock;\n        KeyMaterialService = keyMaterialService;\n        Options = options;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Creates an identity token.\n    /// </summary>\n    /// <param name=\"request\">The token creation request.</param>\n    /// <returns>\n    /// An identity token\n    /// </returns>\n    public virtual async Task<Token> CreateIdentityTokenAsync(TokenCreationRequest request)\n    {\n        Logger.LogTrace(\"Creating identity token\");\n        request.Validate();\n\n        // todo: Dom, add a test for this. validate the at and c hashes are correct for the id_token when the client's alg doesn't match the server default.\n        var credential = await KeyMaterialService.GetSigningCredentialsAsync(request.ValidatedRequest.Client.AllowedIdentityTokenSigningAlgorithms);\n        if (credential == null)\n        {\n            throw new InvalidOperationException(\"No signing credential is configured.\");\n        }\n\n        var signingAlgorithm = credential.Algorithm;\n\n        // host provided claims\n        var claims = new List<Claim>();\n\n        // if nonce was sent, must be mirrored in id token\n        if (request.Nonce.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.Nonce, request.Nonce));\n        }\n\n        // add iat claim\n        claims.Add(new Claim(JwtClaimTypes.IssuedAt, Clock.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64));\n\n        // add at_hash claim\n        if (request.AccessTokenToHash.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.AccessTokenHash, CryptoHelper.CreateHashClaimValue(request.AccessTokenToHash, signingAlgorithm)));\n        }\n\n        // add c_hash claim\n        if (request.AuthorizationCodeToHash.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.AuthorizationCodeHash, CryptoHelper.CreateHashClaimValue(request.AuthorizationCodeToHash, signingAlgorithm)));\n        }\n\n        // add s_hash claim\n        if (request.StateHash.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.StateHash, request.StateHash));\n        }\n\n        // add sid if present\n        if (request.ValidatedRequest.SessionId.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.SessionId, request.ValidatedRequest.SessionId));\n        }\n\n        claims.AddRange(await ClaimsProvider.GetIdentityTokenClaimsAsync(\n            request.Subject,\n            request.ValidatedResources,\n            request.IncludeAllIdentityClaims,\n            request.ValidatedRequest));\n\n        var issuer = ContextAccessor.HttpContext.GetIdentityServerIssuerUri();\n\n        var token = new Token(OidcConstants.TokenTypes.IdentityToken)\n        {\n            CreationTime = Clock.UtcNow.UtcDateTime,\n            Audiences = { request.ValidatedRequest.Client.ClientId },\n            Issuer = issuer,\n            Lifetime = request.ValidatedRequest.Client.IdentityTokenLifetime,\n            Claims = claims.Distinct(new ClaimComparer()).ToList(),\n            ClientId = request.ValidatedRequest.Client.ClientId,\n            AccessTokenType = request.ValidatedRequest.AccessTokenType,\n            AllowedSigningAlgorithms = request.ValidatedRequest.Client.AllowedIdentityTokenSigningAlgorithms\n        };\n\n        return token;\n    }\n\n    /// <summary>\n    /// Creates an access token.\n    /// </summary>\n    /// <param name=\"request\">The token creation request.</param>\n    /// <returns>\n    /// An access token\n    /// </returns>\n    public virtual async Task<Token> CreateAccessTokenAsync(TokenCreationRequest request)\n    {\n        Logger.LogTrace(\"Creating access token\");\n        request.Validate();\n\n        var claims = new List<Claim>();\n        claims.AddRange(await ClaimsProvider.GetAccessTokenClaimsAsync(\n            request.Subject,\n            request.ValidatedResources,\n            request.ValidatedRequest));\n\n        if (request.ValidatedRequest.Client.IncludeJwtId)\n        {\n            claims.Add(new Claim(JwtClaimTypes.JwtId, CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex)));\n        }\n\n        if (request.ValidatedRequest.SessionId.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.SessionId, request.ValidatedRequest.SessionId));\n        }\n        \n        // iat claim as required by JWT profile\n        claims.Add(new Claim(JwtClaimTypes.IssuedAt, Clock.UtcNow.ToUnixTimeSeconds().ToString(),\n            ClaimValueTypes.Integer64));\n\n        var issuer = ContextAccessor.HttpContext.GetIdentityServerIssuerUri();\n        var token = new Token(OidcConstants.TokenTypes.AccessToken)\n        {\n            CreationTime = Clock.UtcNow.UtcDateTime,\n            Issuer = issuer,\n            Lifetime = request.ValidatedRequest.AccessTokenLifetime,\n            Claims = claims.Distinct(new ClaimComparer()).ToList(),\n            ClientId = request.ValidatedRequest.Client.ClientId,\n            Description = request.Description,\n            AccessTokenType = request.ValidatedRequest.AccessTokenType,\n            AllowedSigningAlgorithms = request.ValidatedResources.Resources.ApiResources.FindMatchingSigningAlgorithms()\n        };\n\n        // add aud based on ApiResources in the validated request\n        foreach (var aud in request.ValidatedResources.Resources.ApiResources.Select(x => x.Name).Distinct())\n        {\n            token.Audiences.Add(aud);\n        }\n\n        if (Options.EmitStaticAudienceClaim)\n        {\n            token.Audiences.Add(string.Format(IdentityServerConstants.AccessTokenAudience, issuer.EnsureTrailingSlash()));\n        }\n\n        // add cnf if present\n        if (request.ValidatedRequest.Confirmation.IsPresent())\n        {\n            token.Confirmation = request.ValidatedRequest.Confirmation;\n        }\n        else\n        {\n            if (Options.MutualTls.AlwaysEmitConfirmationClaim)\n            {\n                var clientCertificate = await ContextAccessor.HttpContext.Connection.GetClientCertificateAsync();\n                if (clientCertificate != null)\n                {\n                    token.Confirmation = clientCertificate.CreateThumbprintCnf();\n                }\n            }\n        }\n        \n        return token;\n    }\n\n    /// <summary>\n    /// Creates a serialized and protected security token.\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <returns>\n    /// A security token in serialized form\n    /// </returns>\n    /// <exception cref=\"System.InvalidOperationException\">Invalid token type.</exception>\n    public virtual async Task<string> CreateSecurityTokenAsync(Token token)\n    {\n        string tokenResult;\n\n        if (token.Type == OidcConstants.TokenTypes.AccessToken)\n        {\n            if (token.AccessTokenType == AccessTokenType.Jwt)\n            {\n                Logger.LogTrace(\"Creating JWT access token\");\n\n                tokenResult = await CreationService.CreateTokenAsync(token);\n            }\n            else\n            {\n                Logger.LogTrace(\"Creating reference access token\");\n\n                var handle = await ReferenceTokenStore.StoreReferenceTokenAsync(token);\n\n                tokenResult = handle;\n            }\n        }\n        else if (token.Type == OidcConstants.TokenTypes.IdentityToken)\n        {\n            Logger.LogTrace(\"Creating JWT identity token\");\n\n            tokenResult = await CreationService.CreateTokenAsync(token);\n        }\n        else\n        {\n            throw new InvalidOperationException(\"Invalid token type.\");\n        }\n\n        return tokenResult;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultUserCodeService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default user code service implementation.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IUserCodeService\" />\npublic class DefaultUserCodeService : IUserCodeService\n{\n    private readonly IEnumerable<IUserCodeGenerator> _generators;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultUserCodeService\"/> class.\n    /// </summary>\n    /// <param name=\"generators\">The generators.</param>\n    /// <exception cref=\"ArgumentNullException\">generators</exception>\n    public DefaultUserCodeService(IEnumerable<IUserCodeGenerator> generators)\n    {\n        _generators = generators ?? throw new ArgumentNullException(nameof(generators));\n    }\n\n    /// <summary>\n    /// Gets the user code generator.\n    /// </summary>\n    /// <param name=\"userCodeType\">Type of user code.</param>\n    /// <returns></returns>\n    public Task<IUserCodeGenerator> GetGenerator(string userCodeType) =>\n        Task.FromResult(_generators.FirstOrDefault(x => x.UserCodeType == userCodeType));\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DefaultUserSession.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Cookie-based session implementation\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IUserSession\" />\npublic class DefaultUserSession : IUserSession\n{\n    /// <summary>\n    /// The HTTP context accessor\n    /// </summary>\n    protected readonly IHttpContextAccessor HttpContextAccessor;\n\n    /// <summary>\n    /// The handlers\n    /// </summary>\n    protected readonly IAuthenticationHandlerProvider Handlers;\n\n    /// <summary>\n    /// The options\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// The clock\n    /// </summary>\n    protected readonly ISystemClock Clock;\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Gets the HTTP context.\n    /// </summary>\n    /// <value>\n    /// The HTTP context.\n    /// </value>\n    protected HttpContext HttpContext => HttpContextAccessor.HttpContext;\n\n    /// <summary>\n    /// Gets the name of the check session cookie.\n    /// </summary>\n    /// <value>\n    /// The name of the check session cookie.\n    /// </value>\n    protected string CheckSessionCookieName => Options.Authentication.CheckSessionCookieName;\n    \n    /// <summary>\n    /// Gets the domain of the check session cookie.\n    /// </summary>\n    /// <value>\n    /// The domain of the check session cookie.\n    /// </value>\n    protected string CheckSessionCookieDomain => Options.Authentication.CheckSessionCookieDomain;\n\n    /// <summary>\n    /// Gets the SameSite mode of the check session cookie.\n    /// </summary>\n    /// <value>\n    /// The SameSite mode of the check session cookie.\n    /// </value>\n    protected SameSiteMode CheckSessionCookieSameSiteMode => Options.Authentication.CheckSessionCookieSameSiteMode;\n\n    /// <summary>\n    /// The principal\n    /// </summary>\n    protected ClaimsPrincipal Principal;\n\n    /// <summary>\n    /// The properties\n    /// </summary>\n    protected AuthenticationProperties Properties;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultUserSession\"/> class.\n    /// </summary>\n    /// <param name=\"httpContextAccessor\">The HTTP context accessor.</param>\n    /// <param name=\"handlers\">The handlers.</param>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultUserSession(\n        IHttpContextAccessor httpContextAccessor,\n        IAuthenticationHandlerProvider handlers,\n        IdentityServerOptions options,\n        ISystemClock clock,\n        ILogger<IUserSession> logger)\n    {\n        HttpContextAccessor = httpContextAccessor;\n        Handlers = handlers;\n        Options = options;\n        Clock = clock;\n        Logger = logger;\n    }\n\n    // we need this helper (and can't call HttpContext.AuthenticateAsync) so we don't run\n    // claims transformation when we get the principal. this also ensures that we don't\n    // re-issue a cookie that includes the claims from claims transformation.\n    //\n    // also, by caching the _principal/_properties it allows someone to issue a new\n    // cookie (via HttpContext.SignInAsync) and we'll use those new values, rather than\n    // just reading the incoming cookie\n    //\n    // this design requires this to be in DI as scoped\n\n    /// <summary>\n    /// Authenticates the authentication cookie for the current HTTP request and caches the user and properties results.\n    /// </summary>\n    protected virtual async Task AuthenticateAsync()\n    {\n        if (Principal == null || Properties == null)\n        {\n            var scheme = await HttpContext.GetCookieAuthenticationSchemeAsync();\n\n            var handler = await Handlers.GetHandlerAsync(HttpContext, scheme);\n            if (handler == null)\n            {\n                throw new InvalidOperationException($\"No authentication handler is configured to authenticate for the scheme: {scheme}\");\n            }\n\n            var result = await handler.AuthenticateAsync();\n            if (result != null && result.Succeeded)\n            {\n                Principal = result.Principal;\n                Properties = result.Properties;\n            }\n        }\n    }\n\n    /// <summary>\n    /// Creates a session identifier for the signin context and issues the session id cookie.\n    /// </summary>\n    /// <param name=\"principal\"></param>\n    /// <param name=\"properties\"></param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\">\n    /// principal\n    /// or\n    /// properties\n    /// </exception>\n    public virtual async Task<string> CreateSessionIdAsync(ClaimsPrincipal principal, AuthenticationProperties properties)\n    {\n        if (principal == null) throw new ArgumentNullException(nameof(principal));\n        if (properties == null) throw new ArgumentNullException(nameof(properties));\n\n        var currentSubjectId = (await GetUserAsync())?.GetSubjectId();\n        var newSubjectId = principal.GetSubjectId();\n\n        if (properties.GetSessionId() == null || currentSubjectId != newSubjectId)\n        {\n            properties.SetSessionId(CryptoRandom.CreateUniqueId(16, CryptoRandom.OutputFormat.Hex));\n        }\n\n        var sid = properties.GetSessionId();\n        IssueSessionIdCookie(sid);\n\n        Principal = principal;\n        Properties = properties;\n\n        return sid;\n    }\n\n    /// <summary>\n    /// Gets the current authenticated user.\n    /// </summary>\n    /// <returns></returns>\n    public virtual async Task<ClaimsPrincipal> GetUserAsync()\n    {\n        await AuthenticateAsync();\n\n        return Principal;\n    }\n\n    /// <summary>\n    /// Gets the current session identifier.\n    /// </summary>\n    /// <returns></returns>\n    public virtual async Task<string> GetSessionIdAsync()\n    {\n        await AuthenticateAsync();\n\n        return Properties?.GetSessionId();\n    }\n\n    /// <summary>\n    /// Ensures the session identifier cookie asynchronous.\n    /// </summary>\n    /// <returns></returns>\n    public virtual async Task EnsureSessionIdCookieAsync()\n    {\n        var sid = await GetSessionIdAsync();\n        if (sid != null)\n        {\n            IssueSessionIdCookie(sid);\n        }\n        else\n        {\n            await RemoveSessionIdCookieAsync();\n        }\n    }\n\n    /// <summary>\n    /// Removes the session identifier cookie.\n    /// </summary>\n    /// <returns></returns>\n    public virtual Task RemoveSessionIdCookieAsync()\n    {\n        if (HttpContext.Request.Cookies.ContainsKey(CheckSessionCookieName))\n        {\n            // only remove it if we have it in the request\n            var options = CreateSessionIdCookieOptions();\n            options.Expires = Clock.UtcNow.UtcDateTime.AddYears(-1);\n\n            HttpContext.Response.Cookies.Append(CheckSessionCookieName, \".\", options);\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Creates the options for the session cookie.\n    /// </summary>\n    public virtual CookieOptions CreateSessionIdCookieOptions()\n    {\n        var secure = HttpContext.Request.IsHttps;\n        var path = HttpContext.GetIdentityServerBasePath().CleanUrlPath();\n\n        var options = new CookieOptions\n        {\n            HttpOnly = false,\n            Secure = secure,\n            Path = path,\n            IsEssential = true,\n            Domain = CheckSessionCookieDomain,\n            SameSite = CheckSessionCookieSameSiteMode\n        };\n\n        return options;\n    }\n\n    /// <summary>\n    /// Issues the cookie that contains the session id.\n    /// </summary>\n    /// <param name=\"sid\"></param>\n    public virtual void IssueSessionIdCookie(string sid)\n    {\n        if (Options.Endpoints.EnableCheckSessionEndpoint)\n        {\n            if (HttpContext.Request.Cookies[CheckSessionCookieName] != sid)\n            {\n                HttpContext.Response.Cookies.Append(\n                    Options.Authentication.CheckSessionCookieName,\n                    sid,\n                    CreateSessionIdCookieOptions());\n            }\n        }\n    }\n\n    /// <summary>\n    /// Adds a client to the list of clients the user has signed into during their session.\n    /// </summary>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\">clientId</exception>\n    public virtual async Task AddClientIdAsync(string clientId)\n    {\n        if (clientId == null) throw new ArgumentNullException(nameof(clientId));\n\n        await AuthenticateAsync();\n        if (Properties != null)\n        {\n            var clientIds = Properties.GetClientList();\n            if (!clientIds.Contains(clientId))\n            {\n                Properties.AddClientId(clientId);\n                await UpdateSessionCookie();\n            }\n        }\n    }\n\n    /// <summary>\n    /// Gets the list of clients the user has signed into during their session.\n    /// </summary>\n    /// <returns></returns>\n    public virtual async Task<IEnumerable<string>> GetClientListAsync()\n    {\n        await AuthenticateAsync();\n\n        if (Properties != null)\n        {\n            try\n            {\n                return Properties.GetClientList();\n            }\n            catch (Exception ex)\n            {\n                Logger.LogError(ex, \"Error decoding client list\");\n                // clear so we don't keep failing\n                Properties.RemoveClientList();\n                await UpdateSessionCookie();\n            }\n        }\n\n        return Enumerable.Empty<string>();\n    }\n\n    // client list helpers\n    private async Task UpdateSessionCookie()\n    {\n        await AuthenticateAsync();\n\n        if (Principal == null || Properties == null) throw new InvalidOperationException(\"User is not currently authenticated\");\n\n        var scheme = await HttpContext.GetCookieAuthenticationSchemeAsync();\n        await HttpContext.SignInAsync(scheme, Principal, Properties);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/DistributedDeviceFlowThrottlingService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// The default device flow throttling service using IDistributedCache.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IDeviceFlowThrottlingService\" />\npublic class DistributedDeviceFlowThrottlingService : IDeviceFlowThrottlingService\n{\n    private readonly IDistributedCache _cache;\n    private readonly ISystemClock _clock;\n    private readonly IdentityServerOptions _options;\n\n    private const string KeyPrefix = \"devicecode_\";\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DistributedDeviceFlowThrottlingService\"/> class.\n    /// </summary>\n    /// <param name=\"cache\">The cache.</param>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"options\">The options.</param>\n    public DistributedDeviceFlowThrottlingService(\n        IDistributedCache cache,\n        ISystemClock clock,\n        IdentityServerOptions options)\n    {\n        _cache = cache;\n        _clock = clock;\n        _options = options;\n    }\n\n    /// <summary>\n    /// Decides if the requesting client and device code needs to slow down.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    /// <param name=\"details\">The device code details.</param>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\">deviceCode</exception>\n    public async Task<bool> ShouldSlowDown(string deviceCode, DeviceCode details)\n    {\n        if (deviceCode == null) throw new ArgumentNullException(nameof(deviceCode));\n        \n        var key = KeyPrefix + deviceCode;\n        var options = new DistributedCacheEntryOptions {AbsoluteExpiration = _clock.UtcNow.AddSeconds(details.Lifetime)};\n\n        var lastSeenAsString = await _cache.GetStringAsync(key);\n\n        // record new\n        if (lastSeenAsString == null)\n        {\n            await _cache.SetStringAsync(key, _clock.UtcNow.ToString(\"O\"), options);\n            return false;\n        }\n\n        // check interval\n        if (DateTime.TryParse(lastSeenAsString, out var lastSeen))\n        {\n            if (_clock.UtcNow < lastSeen.AddSeconds(_options.DeviceFlow.Interval))\n            {\n                await _cache.SetStringAsync(key, _clock.UtcNow.ToString(\"O\"), options);\n                return true;\n            }\n        }\n\n        // store current and continue\n        await _cache.SetStringAsync(key, _clock.UtcNow.ToString(\"O\"), options);\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/LogoutNotificationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Default implementation of logout notification service.\n/// </summary>\npublic class LogoutNotificationService : ILogoutNotificationService\n{\n    private readonly IClientStore _clientStore;\n    private readonly IHttpContextAccessor _httpContextAccessor;\n    private readonly ILogger<LogoutNotificationService> _logger;\n\n\n    /// <summary>\n    /// Ctor.\n    /// </summary>\n    public LogoutNotificationService(\n        IClientStore clientStore,\n        IHttpContextAccessor httpContextAccessor, \n        ILogger<LogoutNotificationService> logger)\n    {\n        _clientStore = clientStore;\n        _httpContextAccessor = httpContextAccessor;\n        _logger = logger;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<string>> GetFrontChannelLogoutNotificationsUrlsAsync(LogoutNotificationContext context)\n    {\n        var frontChannelUrls = new List<string>();\n        foreach (var clientId in context.ClientIds)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(clientId);\n            if (client != null)\n            {\n                if (client.FrontChannelLogoutUri.IsPresent())\n                {\n                    var url = client.FrontChannelLogoutUri;\n\n                    // add session id if required\n                    if (client.ProtocolType == IdentityServerConstants.ProtocolTypes.OpenIdConnect)\n                    {\n                        if (client.FrontChannelLogoutSessionRequired)\n                        {\n                            url = url.AddQueryString(OidcConstants.EndSessionRequest.Sid, context.SessionId);\n                            url = url.AddQueryString(OidcConstants.EndSessionRequest.Issuer, _httpContextAccessor.HttpContext.GetIdentityServerIssuerUri());\n                        }\n                    }\n                    else if (client.ProtocolType == IdentityServerConstants.ProtocolTypes.WsFederation)\n                    {\n                        url = url.AddQueryString(Constants.WsFedSignOut.LogoutUriParameterName, Constants.WsFedSignOut.LogoutUriParameterValue);\n                    }\n\n                    frontChannelUrls.Add(url);\n                }\n            }\n        }\n\n        if (frontChannelUrls.Any())\n        {\n            var msg = frontChannelUrls.Aggregate((x, y) => x + \", \" + y);\n            _logger.LogDebug(\"Client front-channel logout URLs: {0}\", Ioc.Sanitizer.Log.Sanitize(msg));\n        }\n        else\n        {\n            _logger.LogDebug(\"No client front-channel logout URLs\");\n        }\n\n        return frontChannelUrls;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<BackChannelLogoutRequest>> GetBackChannelLogoutNotificationsAsync(LogoutNotificationContext context)\n    {\n        var backChannelLogouts = new List<BackChannelLogoutRequest>();\n        foreach (var clientId in context.ClientIds)\n        {\n            var client = await _clientStore.FindEnabledClientByIdAsync(clientId);\n            if (client != null)\n            {\n                if (client.BackChannelLogoutUri.IsPresent())\n                {\n                    var back = new BackChannelLogoutRequest\n                    {\n                        ClientId = clientId,\n                        LogoutUri = client.BackChannelLogoutUri,\n                        SubjectId = context.SubjectId,\n                        SessionId = context.SessionId,\n                        SessionIdRequired = client.BackChannelLogoutSessionRequired\n                    };\n\n                    backChannelLogouts.Add(back);\n                }\n            }\n        }\n\n        if (backChannelLogouts.Any())\n        {\n            var msg = backChannelLogouts.Select(x => x.LogoutUri).Aggregate((x, y) => x + \", \" + y);\n            _logger.LogDebug(\"Client back-channel logout URLs: {0}\", msg);\n        }\n        else\n        {\n            _logger.LogDebug(\"No client back-channel logout URLs\");\n        }\n\n        return backChannelLogouts;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/NumericUserCodeGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// User code generator using 9 digit number\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IUserCodeGenerator\" />\npublic class NumericUserCodeGenerator : IUserCodeGenerator\n{\n    /// <summary>\n    /// Gets the type of the user code.\n    /// </summary>\n    /// <value>\n    /// The type of the user code.\n    /// </value>\n    public string UserCodeType => IdentityServerConstants.UserCodeTypes.Numeric;\n\n    /// <summary>\n    /// Gets the retry limit.\n    /// </summary>\n    /// <value>\n    /// The retry limit for getting a unique value.\n    /// </value>\n    public int RetryLimit => 5;\n\n    /// <summary>\n    /// Generates the user code.\n    /// </summary>\n    /// <returns></returns>\n    public Task<string> GenerateAsync()\n    {\n        var next = Next(100000000, 999999999);\n        return Task.FromResult(next.ToString());\n    }\n\n    private int Next(int minValue, int maxValue)\n    {\n        if (minValue > maxValue) throw new ArgumentOutOfRangeException(nameof(minValue));\n        if (minValue == maxValue) return minValue;\n        long diff = maxValue - minValue;\n\n        var uint32Buffer = new byte[8];\n\n        using (var rng = new RNGCryptoServiceProvider())\n        {\n            while (true)\n            {\n                rng.GetBytes(uint32Buffer);\n                var rand = BitConverter.ToUInt32(uint32Buffer, 0);\n\n                const long max = 1 + (long)uint.MaxValue;\n                var remainder = max % diff;\n                if (rand < max - remainder)\n                {\n                    return (int)(minValue + rand % diff);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/OidcReturnUrlParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\ninternal class OidcReturnUrlParser : IReturnUrlParser\n{\n    private readonly IAuthorizeRequestValidator _validator;\n    private readonly IUserSession _userSession;\n    private readonly ILogger _logger;\n    private readonly IAuthorizationParametersMessageStore _authorizationParametersMessageStore;\n\n    public OidcReturnUrlParser(\n        IAuthorizeRequestValidator validator,\n        IUserSession userSession,\n        ILogger<OidcReturnUrlParser> logger,\n        IAuthorizationParametersMessageStore authorizationParametersMessageStore = null)\n    {\n        _validator = validator;\n        _userSession = userSession;\n        _logger = logger;\n        _authorizationParametersMessageStore = authorizationParametersMessageStore;\n    }\n\n    public async Task<AuthorizationRequest> ParseAsync(string returnUrl)\n    {\n        if (IsValidReturnUrl(returnUrl))\n        {\n            var parameters = returnUrl.ReadQueryStringAsNameValueCollection();\n            if (_authorizationParametersMessageStore != null)\n            {\n                var messageStoreId = parameters[Constants.AuthorizationParamsStore.MessageStoreIdParameterName];\n                var entry = await _authorizationParametersMessageStore.ReadAsync(messageStoreId);\n                parameters = entry?.Data.FromFullDictionary() ?? new NameValueCollection();\n            }\n\n            var user = await _userSession.GetUserAsync();\n            var result = await _validator.ValidateAsync(parameters, user);\n            if (!result.IsError)\n            {\n                _logger.LogTrace(\"AuthorizationRequest being returned\");\n                return new AuthorizationRequest(result.ValidatedRequest);\n            }\n        }\n\n        _logger.LogTrace(\"No AuthorizationRequest being returned\");\n        return null;\n    }\n\n    public bool IsValidReturnUrl(string returnUrl)\n    {\n        if (returnUrl.IsLocalUrl())\n        {\n            var index = returnUrl.IndexOf('?');\n            if (index >= 0)\n            {\n                returnUrl = returnUrl.Substring(0, index);\n            }\n\n            if (returnUrl.EndsWith(Constants.ProtocolRoutePaths.Authorize, StringComparison.Ordinal) ||\n                returnUrl.EndsWith(Constants.ProtocolRoutePaths.AuthorizeCallback, StringComparison.Ordinal))\n            {\n                _logger.LogTrace(\"returnUrl is valid\");\n                return true;\n            }\n        }\n\n        _logger.LogTrace(\"returnUrl is not valid\");\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/Default/ReturnUrlParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Parses a return URL using all registered URL parsers\n/// </summary>\npublic class ReturnUrlParser\n{\n    private readonly IEnumerable<IReturnUrlParser> _parsers;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ReturnUrlParser\"/> class.\n    /// </summary>\n    /// <param name=\"parsers\">The parsers.</param>\n    public ReturnUrlParser(IEnumerable<IReturnUrlParser> parsers)\n    {\n        _parsers = parsers;\n    }\n\n    /// <summary>\n    /// Parses the return URL.\n    /// </summary>\n    /// <param name=\"returnUrl\">The return URL.</param>\n    /// <returns></returns>\n    public virtual async Task<AuthorizationRequest> ParseAsync(string returnUrl)\n    {\n        foreach (var parser in _parsers)\n        {\n            var result = await parser.ParseAsync(returnUrl);\n            if (result != null)\n            {\n                return result;\n            }\n        }\n\n        return null;            \n    }\n\n    /// <summary>\n    /// Determines whether a return URL is valid.\n    /// </summary>\n    /// <param name=\"returnUrl\">The return URL.</param>\n    /// <returns>\n    ///   <c>true</c> if the return URL is valid; otherwise, <c>false</c>.\n    /// </returns>\n    public virtual bool IsValidReturnUrl(string returnUrl)\n    {\n        foreach (var parser in _parsers)\n        {\n            if (parser.IsValidReturnUrl(returnUrl))\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IBackChannelLogoutHttpClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Models making HTTP requests for back-channel logout notification.\n/// </summary>\npublic interface IBackChannelLogoutHttpClient\n{\n    /// <summary>\n    /// Performs HTTP POST.\n    /// </summary>\n    /// <param name=\"url\"></param>\n    /// <param name=\"payload\"></param>\n    /// <returns></returns>\n    Task PostAsync(string url, Dictionary<string, string> payload);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IBackChannelLogoutService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// The service responsible for performing back-channel logout notification.\n/// </summary>\npublic interface IBackChannelLogoutService\n{\n    /// <summary>\n    /// Performs http back-channel logout notification.\n    /// </summary>\n    /// <param name=\"context\">The context of the back channel logout notification.</param>\n    Task SendLogoutNotificationsAsync(LogoutNotificationContext context);\n}\n\n\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/ICache.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Abstract interface to model data caching\n/// </summary>\n/// <typeparam name=\"T\">The data type to be cached</typeparam>\npublic interface ICache<T>\n    where T : class\n{\n    /// <summary>\n    /// Gets the cached data based upon a key index.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <returns>The cached item, or <c>null</c> if no item matches the key.</returns>\n    Task<T> GetAsync(string key);\n\n    /// <summary>\n    /// Caches the data based upon a key\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <param name=\"item\">The item.</param>\n    /// <param name=\"expiration\">The expiration.</param>\n    /// <returns></returns>\n    Task SetAsync(string key, T item, TimeSpan expiration);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IClaimsService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// The claims service is responsible for determining which claims to include in tokens\n/// </summary>\npublic interface IClaimsService\n{\n    /// <summary>\n    /// Returns claims for an identity token\n    /// </summary>\n    /// <param name=\"subject\">The subject</param>\n    /// <param name=\"resources\">The resources.</param>\n    /// <param name=\"includeAllIdentityClaims\">Specifies if all claims should be included in the token, or if the userinfo endpoint can be used to retrieve them</param>\n    /// <param name=\"request\">The raw request</param>\n    /// <returns>\n    /// Claims for the identity token\n    /// </returns>\n    Task<IEnumerable<Claim>> GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, ResourceValidationResult resources, bool includeAllIdentityClaims, ValidatedRequest request);\n\n    /// <summary>\n    /// Returns claims for an access token.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <param name=\"resources\">The resources.</param>\n    /// <param name=\"request\">The raw request.</param>\n    /// <returns>\n    /// Claims for the access token\n    /// </returns>\n    Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, ResourceValidationResult resources, ValidatedRequest request);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IConsentService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Service to retrieve and update consent.\n/// </summary>\npublic interface IConsentService\n{\n    /// <summary>\n    /// Checks if consent is required.\n    /// </summary>\n    /// <param name=\"subject\">The user.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <param name=\"parsedScopes\">The parsed scopes.</param>\n    /// <returns>\n    /// Boolean if consent is required.\n    /// </returns>\n    Task<bool> RequiresConsentAsync(ClaimsPrincipal subject, Client client, IEnumerable<ParsedScopeValue> parsedScopes);\n\n    /// <summary>\n    /// Updates the consent.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <param name=\"parsedScopes\">The parsed scopes.</param>\n    /// <returns></returns>\n    Task UpdateConsentAsync(ClaimsPrincipal subject, Client client, IEnumerable<ParsedScopeValue> parsedScopes);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IDeviceFlowCodeService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Wrapper service for IDeviceFlowStore.\n/// </summary>\npublic interface IDeviceFlowCodeService\n{\n    /// <summary>\n    /// Stores the device authorization request.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    Task<string> StoreDeviceAuthorizationAsync(string userCode, DeviceCode data);\n\n    /// <summary>\n    /// Finds device authorization by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <returns></returns>\n    Task<DeviceCode> FindByUserCodeAsync(string userCode);\n\n    /// <summary>\n    /// Finds device authorization by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    Task<DeviceCode> FindByDeviceCodeAsync(string deviceCode);\n\n    /// <summary>\n    /// Updates device authorization, searching by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    Task UpdateByUserCodeAsync(string userCode, DeviceCode data);\n\n    /// <summary>\n    /// Removes the device authorization, searching by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    Task RemoveByDeviceCodeAsync(string deviceCode);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IDeviceFlowInteractionService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n///  Provide services be used by the user interface to communicate with IdentityServer.\n/// </summary>\npublic interface IDeviceFlowInteractionService\n{\n    /// <summary>\n    /// Gets the authorization context asynchronous.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <returns></returns>\n    Task<DeviceFlowAuthorizationRequest> GetAuthorizationContextAsync(string userCode);\n\n    /// <summary>\n    /// Handles the request asynchronous.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"consent\">The consent.</param>\n    /// <returns></returns>\n    Task<DeviceFlowInteractionResult> HandleRequestAsync(string userCode, ConsentResponse consent);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IDeviceFlowThrottlingService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// The device flow throttling service.\n/// </summary>\npublic interface IDeviceFlowThrottlingService\n{\n    /// <summary>\n    /// Decides if the requesting client and device code needs to slow down.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    /// <param name=\"details\">The device code details.</param>\n    /// <returns></returns>\n    Task<bool> ShouldSlowDown(string deviceCode, DeviceCode details);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IEventService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Interface for the event service\n/// </summary>\npublic interface IEventService\n{\n    /// <summary>\n    /// Raises the specified event.\n    /// </summary>\n    /// <param name=\"evt\">The event.</param>\n    Task RaiseAsync(Event evt);\n\n    /// <summary>\n    /// Indicates if the type of event will be persisted.\n    /// </summary>\n    bool CanRaiseEventType(EventTypes evtType);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IEventSink.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Models persistence of events\n/// </summary>\npublic interface IEventSink\n{\n    /// <summary>\n    /// Raises the specified event.\n    /// </summary>\n    /// <param name=\"evt\">The event.</param>\n    Task PersistAsync(Event evt);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IHandleGenerationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Interface for the handle generation service\n/// </summary>\npublic interface IHandleGenerationService\n{\n    /// <summary>\n    /// Generates a handle.\n    /// </summary>\n    /// <param name=\"length\">The length.</param>\n    /// <returns></returns>\n    Task<string> GenerateAsync(int length = 32);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IIdentityServerInteractionService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n///  Provide services be used by the user interface to communicate with IdentityServer.\n/// </summary>\npublic interface IIdentityServerInteractionService\n{\n    /// <summary>\n    /// Gets the authorization context.\n    /// </summary>\n    /// <param name=\"returnUrl\">The return URL.</param>\n    Task<AuthorizationRequest> GetAuthorizationContextAsync(string returnUrl);\n\n    /// <summary>\n    /// Indicates if the returnUrl is a valid URL for redirect after login or consent.\n    /// </summary>\n    /// <param name=\"returnUrl\">The return URL.</param>\n    bool IsValidReturnUrl(string returnUrl);\n\n    /// <summary>\n    /// Gets the error context.\n    /// </summary>\n    /// <param name=\"errorId\">The error identifier.</param>\n    Task<ErrorMessage> GetErrorContextAsync(string errorId);\n\n    /// <summary>\n    /// Gets the logout context.\n    /// </summary>\n    /// <param name=\"logoutId\">The logout identifier.</param>\n    Task<LogoutRequest> GetLogoutContextAsync(string logoutId);\n\n    /// <summary>\n    /// Used to create a logoutId if there is not one presently.\n    /// </summary>\n    /// <returns></returns>\n    Task<string> CreateLogoutContextAsync();\n\n    /// <summary>\n    /// Informs IdentityServer of the user's consent.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"consent\">The consent.</param>\n    /// <param name=\"subject\">The subject.</param>\n    Task GrantConsentAsync(AuthorizationRequest request, ConsentResponse consent, string subject = null);\n\n    /// <summary>\n    /// Triggers error back to the client for the authorization request.\n    /// This API is a simpler helper on top of GrantConsentAsync.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"error\"></param>\n    /// <param name=\"errorDescription\"></param>\n    Task DenyAuthorizationAsync(AuthorizationRequest request, AuthorizationError error, string errorDescription = null);\n\n    /// <summary>\n    /// Returns a collection representing all of the user's consents and grants.\n    /// </summary>\n    Task<IEnumerable<Grant>> GetAllUserGrantsAsync();\n\n    /// <summary>\n    /// Revokes all a user's consents and grants for a client.\n    /// </summary>\n    /// <param name=\"clientId\">The client identifier.</param>\n    Task RevokeUserConsentAsync(string clientId);\n\n    /// <summary>\n    /// Revokes all of a user's consents and grants for clients the user has signed into during their current session.\n    /// </summary>\n    Task RevokeTokensForCurrentSessionAsync();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IJwtRequestUriHttpClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Models making HTTP requests for JWTs from the authorize endpoint.\n/// </summary>\npublic interface IJwtRequestUriHttpClient\n{\n    /// <summary>\n    /// Gets a JWT from the url.\n    /// </summary>\n    /// <param name=\"url\"></param>\n    /// <param name=\"client\"></param>\n    /// <returns></returns>\n    Task<string> GetJwtAsync(string url, Client client);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IKeyMaterialService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Interface for the key material service\n/// </summary>\npublic interface IKeyMaterialService\n{\n    /// <summary>\n    /// Gets all validation keys.\n    /// </summary>\n    /// <returns></returns>\n    Task<IEnumerable<SecurityKeyInfo>> GetValidationKeysAsync();\n\n    /// <summary>\n    /// Gets the signing credentials.\n    /// </summary>\n    /// <param name=\"allowedAlgorithms\">Collection of algorithms used to filter the server supported algorithms. \n    /// A value of null or empty indicates that the server default should be returned.</param>\n    /// <returns></returns>\n    Task<SigningCredentials> GetSigningCredentialsAsync(IEnumerable<string> allowedAlgorithms = null);\n\n    /// <summary>\n    /// Gets all signing credentials.\n    /// </summary>\n    /// <returns></returns>\n    Task<IEnumerable<SigningCredentials>> GetAllSigningCredentialsAsync();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/ILogoutNotificationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Provides features for OIDC signout notifications.\n/// </summary>\npublic interface ILogoutNotificationService\n{\n    /// <summary>\n    /// Builds the URLs needed for front-channel logout notification.\n    /// </summary>\n    /// <param name=\"context\">The context for the logout notification.</param>\n    Task<IEnumerable<string>> GetFrontChannelLogoutNotificationsUrlsAsync(LogoutNotificationContext context);\n\n    /// <summary>\n    /// Builds the http back-channel logout request data for the collection of clients.\n    /// </summary>\n    /// <param name=\"context\">The context for the logout notification.</param>\n    Task<IEnumerable<BackChannelLogoutRequest>> GetBackChannelLogoutNotificationsAsync(LogoutNotificationContext context);\n}\n\n/// <summary>\n/// Information necessary to make a back-channel logout request to a client.\n/// </summary>\npublic class BackChannelLogoutRequest\n{\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets the subject identifier.\n    /// </summary>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the session identifier.\n    /// </summary>\n    public string SessionId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the back channel logout URI.\n    /// </summary>\n    public string LogoutUri { get; set; }\n\n    /// <summary>\n    /// Gets a value indicating whether the session identifier is required.\n    /// </summary>\n    public bool SessionIdRequired { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IPersistedGrantService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Implements persisted grant logic\n/// </summary>\npublic interface IPersistedGrantService\n{\n    /// <summary>\n    /// Gets all grants for a given subject ID.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <returns></returns>\n    Task<IEnumerable<Grant>> GetAllGrantsAsync(string subjectId);\n\n    /// <summary>\n    /// Removes all grants for a given subject id, and optionally client id and session id combination.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier (optional).</param>\n    /// <param name=\"sessionId\">The sesion id (optional).</param>\n    /// <returns></returns>\n    Task RemoveAllGrantsAsync(string subjectId, string clientId = null, string sessionId = null);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// This interface allows IdentityServer to connect to your user and profile store.\n/// </summary>\npublic interface IProfileService\n{\n    /// <summary>\n    /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint)\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    Task GetProfileDataAsync(ProfileDataRequestContext context);\n\n    /// <summary>\n    /// This method gets called whenever identity server needs to determine if the user is valid or active (e.g. if the user's account has been deactivated since they logged in).\n    /// (e.g. during token issuance or validation).\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    Task IsActiveAsync(IsActiveContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IRefreshTokenService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Implements refresh token creation and validation\n/// </summary>\npublic interface IRefreshTokenService\n{\n    /// <summary>\n    /// Validates a refresh token.\n    /// </summary>\n    /// <param name=\"token\">The refresh token.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns></returns>\n    Task<TokenValidationResult> ValidateRefreshTokenAsync(string token, Client client);\n    \n    /// <summary>\n    /// Creates the refresh token.\n    /// </summary>\n    /// <param name=\"subject\">The subject.</param>\n    /// <param name=\"accessToken\">The access token.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    /// The refresh token handle\n    /// </returns>\n    Task<string> CreateRefreshTokenAsync(ClaimsPrincipal subject, Token accessToken, Client client);\n\n    /// <summary>\n    /// Updates the refresh token.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <param name=\"refreshToken\">The refresh token.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    /// The refresh token handle\n    /// </returns>\n    Task<string> UpdateRefreshTokenAsync(string handle, RefreshToken refreshToken, Client client);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IReplayCache.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Interface for replay cache implementations\n/// </summary>\npublic interface IReplayCache\n{\n    /// <summary>\n    /// Adds a handle to the cache \n    /// </summary>\n    /// <param name=\"purpose\"></param>\n    /// <param name=\"handle\"></param>\n    /// <param name=\"expiration\"></param>\n    /// <returns></returns>\n    Task AddAsync(string purpose, string handle, DateTimeOffset expiration);\n\n\n    /// <summary>\n    /// Checks if a cached handle exists \n    /// </summary>\n    /// <param name=\"purpose\"></param>\n    /// <param name=\"handle\"></param>\n    /// <returns></returns>\n    Task<bool> ExistsAsync(string purpose, string handle);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IReturnUrlParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Interface for the return URL parser\n/// </summary>\npublic interface IReturnUrlParser\n{\n    /// <summary>\n    /// Parses a return URL.\n    /// </summary>\n    /// <param name=\"returnUrl\">The return URL.</param>\n    /// <returns></returns>\n    Task<AuthorizationRequest> ParseAsync(string returnUrl);\n\n    /// <summary>\n    /// Determines whether the return URL is valid.\n    /// </summary>\n    /// <param name=\"returnUrl\">The return URL.</param>\n    /// <returns>\n    ///   <c>true</c> if the return URL is valid; otherwise, <c>false</c>.\n    /// </returns>\n    bool IsValidReturnUrl(string returnUrl);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/ITokenCreationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Logic for creating security tokens\n/// </summary>\npublic interface ITokenCreationService\n{\n    /// <summary>\n    /// Creates a token.\n    /// </summary>\n    /// <param name=\"token\">The token description.</param>\n    /// <returns>A protected and serialized security token</returns>\n    Task<string> CreateTokenAsync(Token token);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/ITokenService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Logic for creating security tokens\n/// </summary>\npublic interface ITokenService\n{\n    /// <summary>\n    /// Creates an identity token.\n    /// </summary>\n    /// <param name=\"request\">The token creation request.</param>\n    /// <returns>An identity token</returns>\n    Task<Token> CreateIdentityTokenAsync(TokenCreationRequest request);\n\n    /// <summary>\n    /// Creates an access token.\n    /// </summary>\n    /// <param name=\"request\">The token creation request.</param>\n    /// <returns>An access token</returns>\n    Task<Token> CreateAccessTokenAsync(TokenCreationRequest request);\n\n    /// <summary>\n    /// Creates a serialized and protected security token.\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <returns>A security token in serialized form</returns>\n    Task<string> CreateSecurityTokenAsync(Token token);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IUserCodeGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Implements device flow user code generation\n/// </summary>\npublic interface IUserCodeGenerator\n{\n    /// <summary>\n    /// Gets the type of the user code.\n    /// </summary>\n    /// <value>\n    /// The type of the user code.\n    /// </value>\n    string UserCodeType { get; }\n\n    /// <summary>\n    /// Gets the retry limit.\n    /// </summary>\n    /// <value>\n    /// The retry limit for getting a unique value.\n    /// </value>\n    int RetryLimit { get; }\n\n    /// <summary>\n    /// Generates the user code.\n    /// </summary>\n    /// <returns></returns>\n    Task<string> GenerateAsync();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IUserCodeService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Implements user code generation\n/// </summary>\npublic interface IUserCodeService\n{\n    /// <summary>\n    /// Gets the user code generator.\n    /// </summary>\n    /// <param name=\"userCodeType\">Type of user code.</param>\n    /// <returns></returns>\n    Task<IUserCodeGenerator> GetGenerator(string userCodeType);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/IUserSession.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Models a user's authentication session\n/// </summary>\npublic interface IUserSession\n{\n    /// <summary>\n    /// Creates a session identifier for the signin context and issues the session id cookie.\n    /// </summary>\n    Task<string> CreateSessionIdAsync(ClaimsPrincipal principal, AuthenticationProperties properties);\n\n    /// <summary>\n    /// Gets the current authenticated user.\n    /// </summary>\n    Task<ClaimsPrincipal> GetUserAsync();\n\n    /// <summary>\n    /// Gets the current session identifier.\n    /// </summary>\n    /// <returns></returns>\n    Task<string> GetSessionIdAsync();\n\n    /// <summary>\n    /// Ensures the session identifier cookie asynchronous.\n    /// </summary>\n    /// <returns></returns>\n    Task EnsureSessionIdCookieAsync();\n\n    /// <summary>\n    /// Removes the session identifier cookie.\n    /// </summary>\n    Task RemoveSessionIdCookieAsync();\n\n    /// <summary>\n    /// Adds a client to the list of clients the user has signed into during their session.\n    /// </summary>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    Task AddClientIdAsync(string clientId);\n\n    /// <summary>\n    /// Gets the list of clients the user has signed into during their session.\n    /// </summary>\n    /// <returns></returns>\n    Task<IEnumerable<string>> GetClientListAsync();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Services/InMemory/InMemoryCorsPolicyService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// CORS policy service that configures the allowed origins from a list of clients' redirect URLs.\n/// </summary>\npublic class InMemoryCorsPolicyService : ICorsPolicyService\n{\n    /// <summary>\n    /// Logger\n    /// </summary>\n    protected readonly ILogger Logger;\n    /// <summary>\n    /// Clients applications list\n    /// </summary>\n    protected readonly IEnumerable<Client> Clients;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"InMemoryCorsPolicyService\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger</param>\n    /// <param name=\"clients\">The clients.</param>\n    public InMemoryCorsPolicyService(ILogger<InMemoryCorsPolicyService> logger, IEnumerable<Client> clients)\n    {\n        Logger = logger;\n        Clients = clients ?? Enumerable.Empty<Client>();\n    }\n\n    /// <summary>\n    /// Determines whether origin is allowed.\n    /// </summary>\n    /// <param name=\"origin\">The origin.</param>\n    /// <returns></returns>\n    public virtual Task<bool> IsOriginAllowedAsync(string origin)\n    {\n        var query =\n            from client in Clients\n            from url in client.AllowedCorsOrigins\n            select url.GetOrigin();\n\n        var result = query.Contains(origin, StringComparer.OrdinalIgnoreCase);\n\n        if (result)\n        {\n            Logger.LogDebug(\"Client list checked and origin: {0} is allowed\", Ioc.Sanitizer.Log.Sanitize(origin));\n        }\n        else\n        {\n            Logger.LogDebug(\"Client list checked and origin: {0} is not allowed\", Ioc.Sanitizer.Log.Sanitize(origin));\n        }\n\n        return Task.FromResult(result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Caching/CachingClientStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Cache decorator for IClientStore\n/// </summary>\n/// <typeparam name=\"T\"></typeparam>\n/// <seealso cref=\"IdentityServer8.Stores.IClientStore\" />\npublic class CachingClientStore<T> : IClientStore\n    where T : IClientStore\n{\n    private readonly IdentityServerOptions _options;\n    private readonly ICache<Client> _cache;\n    private readonly IClientStore _inner;\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"CachingClientStore{T}\"/> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"inner\">The inner.</param>\n    /// <param name=\"cache\">The cache.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public CachingClientStore(IdentityServerOptions options, T inner, ICache<Client> cache, ILogger<CachingClientStore<T>> logger)\n    {\n        _options = options;\n        _inner = inner;\n        _cache = cache;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Finds a client by id\n    /// </summary>\n    /// <param name=\"clientId\">The client id</param>\n    /// <returns>\n    /// The client\n    /// </returns>\n    public async Task<Client> FindClientByIdAsync(string clientId)\n    {\n        var client = await _cache.GetAsync(clientId,\n            _options.Caching.ClientStoreExpiration,\n            async () => await _inner.FindClientByIdAsync(clientId),\n            _logger);\n\n        return client;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Caching/CachingCorsPolicyService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Caching decorator for ICorsPolicyService\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.ICorsPolicyService\" />\npublic class CachingCorsPolicyService<T> : ICorsPolicyService\n    where T : ICorsPolicyService\n{\n    /// <summary>\n    /// Class to model entries in CORS origin cache.\n    /// </summary>\n    public class CorsCacheEntry\n    {\n        /// <summary>\n        /// Ctor.\n        /// </summary>\n        public CorsCacheEntry(bool allowed)\n        {\n            Allowed = allowed;\n        }\n\n        /// <summary>\n        /// Is origin allowed.\n        /// </summary>\n        public bool Allowed { get; }\n    }\n\n    private readonly IdentityServerOptions Options;\n    private readonly ICache<CorsCacheEntry> CorsCache;\n    private readonly ICorsPolicyService Inner;\n    private readonly ILogger Logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"CachingResourceStore{T}\"/> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"inner\">The inner.</param>\n    /// <param name=\"corsCache\">The CORS origin cache.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public CachingCorsPolicyService(IdentityServerOptions options,\n        T inner,\n        ICache<CorsCacheEntry> corsCache,\n        ILogger<CachingCorsPolicyService<T>> logger)\n    {\n        Options = options;\n        Inner = inner;\n        CorsCache = corsCache;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Determines whether origin is allowed.\n    /// </summary>\n    /// <param name=\"origin\">The origin.</param>\n    /// <returns></returns>\n    public virtual async Task<bool> IsOriginAllowedAsync(string origin)\n    {\n        var entry = await CorsCache.GetAsync(origin,\n                      Options.Caching.CorsExpiration,\n                      async () => new CorsCacheEntry(await Inner.IsOriginAllowedAsync(origin)),\n                      Logger);\n\n        return entry.Allowed;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Caching/CachingResourceStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Caching decorator for IResourceStore\n/// </summary>\n/// <typeparam name=\"T\"></typeparam>\n/// <seealso cref=\"IdentityServer8.Stores.IResourceStore\" />\npublic class CachingResourceStore<T> : IResourceStore\n    where T : IResourceStore\n{\n    private const string AllKey = \"__all__\";\n\n    private readonly IdentityServerOptions _options;\n    \n    private readonly ICache<IEnumerable<IdentityResource>> _identityCache;\n    private readonly ICache<IEnumerable<ApiResource>> _apiByScopeCache;\n    private readonly ICache<IEnumerable<ApiScope>> _apiScopeCache;\n    private readonly ICache<IEnumerable<ApiResource>> _apiResourceCache;\n    private readonly ICache<Resources> _allCache;\n    \n    private readonly IResourceStore _inner;\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"CachingResourceStore{T}\"/> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"inner\">The inner.</param>\n    /// <param name=\"identityCache\">The identity cache.</param>\n    /// <param name=\"apiByScopeCache\">The API by scope cache.</param>\n    /// <param name=\"apisCache\">The API cache.</param>\n    /// <param name=\"scopeCache\"></param>\n    /// <param name=\"allCache\">All cache.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public CachingResourceStore(IdentityServerOptions options, T inner, \n        ICache<IEnumerable<IdentityResource>> identityCache, \n        ICache<IEnumerable<ApiResource>> apiByScopeCache,\n        ICache<IEnumerable<ApiResource>> apisCache,\n        ICache<IEnumerable<ApiScope>> scopeCache,\n        ICache<Resources> allCache,\n        ILogger<CachingResourceStore<T>> logger)\n    {\n        _options = options;\n        _inner = inner;\n        _identityCache = identityCache;\n        _apiByScopeCache = apiByScopeCache;\n        _apiResourceCache = apisCache;\n        _apiScopeCache = scopeCache;\n        _allCache = allCache;\n        _logger = logger;\n    }\n\n    private string GetKey(IEnumerable<string> names)\n    {\n        if (names == null || !names.Any()) return string.Empty;\n        return names.OrderBy(x => x).Aggregate((x, y) => x + \",\" + y);\n    }\n\n    /// <inheritdoc/>\n    public async Task<Resources> GetAllResourcesAsync()\n    {\n        var key = AllKey;\n\n        var all = await _allCache.GetAsync(key,\n            _options.Caching.ResourceStoreExpiration,\n            async () => await _inner.GetAllResourcesAsync(),\n            _logger);\n\n        return all;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)\n    {\n        var key = GetKey(apiResourceNames);\n\n        var apis = await _apiResourceCache.GetAsync(key,\n            _options.Caching.ResourceStoreExpiration,\n            async () => await _inner.FindApiResourcesByNameAsync(apiResourceNames),\n            _logger);\n\n        return apis;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> names)\n    {\n        var key = GetKey(names);\n\n        var identities = await _identityCache.GetAsync(key,\n            _options.Caching.ResourceStoreExpiration,\n            async () => await _inner.FindIdentityResourcesByScopeNameAsync(names),\n            _logger);\n\n        return identities;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> names)\n    {\n        var key = GetKey(names);\n\n        var apis = await _apiByScopeCache.GetAsync(key,\n            _options.Caching.ResourceStoreExpiration,\n            async () => await _inner.FindApiResourcesByScopeNameAsync(names),\n            _logger);\n\n        return apis;\n    }\n\n    /// <inheritdoc/>\n    public async Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)\n    {\n        var key = GetKey(scopeNames);\n\n        var apis = await _apiScopeCache.GetAsync(key,\n            _options.Caching.ResourceStoreExpiration,\n            async () => await _inner.FindApiScopesByNameAsync(scopeNames),\n            _logger);\n\n        return apis;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/ConsentMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\ninternal class ConsentMessageStore : IConsentMessageStore\n{\n    protected readonly MessageCookie<ConsentResponse> Cookie;\n\n    public ConsentMessageStore(MessageCookie<ConsentResponse> cookie)\n    {\n        Cookie = cookie;\n    }\n\n    public virtual Task DeleteAsync(string id)\n    {\n        Cookie.Clear(id);\n        return Task.CompletedTask;\n    }\n\n    public virtual Task<Message<ConsentResponse>> ReadAsync(string id)\n    {\n        return Task.FromResult(Cookie.Read(id));\n    }\n\n    public virtual Task WriteAsync(string id, Message<ConsentResponse> message)\n    {\n        Cookie.Write(id, message);\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/DefaultAuthorizationCodeStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Default authorization code store.\n/// </summary>\npublic class DefaultAuthorizationCodeStore : DefaultGrantStore<AuthorizationCode>, IAuthorizationCodeStore\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultAuthorizationCodeStore\"/> class.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"serializer\">The serializer.</param>\n    /// <param name=\"handleGenerationService\">The handle generation service.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultAuthorizationCodeStore(\n        IPersistedGrantStore store,\n        IPersistentGrantSerializer serializer,\n        IHandleGenerationService handleGenerationService,\n        ILogger<DefaultAuthorizationCodeStore> logger)\n        : base(IdentityServerConstants.PersistedGrantTypes.AuthorizationCode, store, serializer, handleGenerationService, logger)\n    {\n    }\n\n    /// <summary>\n    /// Stores the authorization code asynchronous.\n    /// </summary>\n    /// <param name=\"code\">The code.</param>\n    /// <returns></returns>\n    public Task<string> StoreAuthorizationCodeAsync(AuthorizationCode code)\n    {\n        return CreateItemAsync(code, code.ClientId, code.Subject.GetSubjectId(), code.SessionId, code.Description, code.CreationTime, code.Lifetime);\n    }\n\n    /// <summary>\n    /// Gets the authorization code asynchronous.\n    /// </summary>\n    /// <param name=\"code\">The code.</param>\n    /// <returns></returns>\n    public Task<AuthorizationCode> GetAuthorizationCodeAsync(string code)\n    {\n        return GetItemAsync(code);\n    }\n\n    /// <summary>\n    /// Removes the authorization code asynchronous.\n    /// </summary>\n    /// <param name=\"code\">The code.</param>\n    /// <returns></returns>\n    public Task RemoveAuthorizationCodeAsync(string code)\n    {\n        return RemoveItemAsync(code);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/DefaultGrantStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Base class for persisting grants using the IPersistedGrantStore.\n/// </summary>\n/// <typeparam name=\"T\"></typeparam>\npublic class DefaultGrantStore<T>\n{\n    /// <summary>\n    /// The grant type being stored.\n    /// </summary>\n    protected string GrantType { get; }\n\n    /// <summary>\n    /// The logger.\n    /// </summary>\n    protected ILogger Logger { get; }\n\n    /// <summary>\n    /// The PersistedGrantStore.\n    /// </summary>\n    protected IPersistedGrantStore Store { get; }\n\n    /// <summary>\n    /// The PersistentGrantSerializer;\n    /// </summary>\n    protected IPersistentGrantSerializer Serializer { get; }\n\n    /// <summary>\n    /// The HandleGenerationService.\n    /// </summary>\n    protected IHandleGenerationService HandleGenerationService { get; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultGrantStore{T}\"/> class.\n    /// </summary>\n    /// <param name=\"grantType\">Type of the grant.</param>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"serializer\">The serializer.</param>\n    /// <param name=\"handleGenerationService\">The handle generation service.</param>\n    /// <param name=\"logger\">The logger.</param>\n    /// <exception cref=\"System.ArgumentNullException\">grantType</exception>\n    protected DefaultGrantStore(string grantType,\n        IPersistedGrantStore store,\n        IPersistentGrantSerializer serializer,\n        IHandleGenerationService handleGenerationService,\n        ILogger logger)\n    {\n        if (grantType.IsMissing()) throw new ArgumentNullException(nameof(grantType));\n\n        GrantType = grantType;\n        Store = store;\n        Serializer = serializer;\n        HandleGenerationService = handleGenerationService;\n        Logger = logger;\n    }\n\n    private const string KeySeparator = \":\";\n\n    /// <summary>\n    /// Gets the hashed key.\n    /// </summary>\n    /// <param name=\"value\">The value.</param>\n    /// <returns></returns>\n    protected virtual string GetHashedKey(string value)\n    {\n        return (value + KeySeparator + GrantType).Sha256();\n    }\n\n    /// <summary>\n    /// Gets the item.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <returns></returns>\n    protected virtual async Task<T> GetItemAsync(string key)\n    {\n        var hashedKey = GetHashedKey(key);\n\n        var grant = await Store.GetAsync(hashedKey);\n        if (grant != null && grant.Type == GrantType)\n        {\n            try\n            {\n                return Serializer.Deserialize<T>(grant.Data);\n            }\n            catch (Exception ex)\n            {\n                Logger.LogError(ex, \"Failed to deserialize JSON from grant store.\");\n            }\n        }\n        else\n        {\n            Logger.LogDebug(\"{grantType} grant with value: {key} not found in store.\", GrantType, Ioc.Sanitizer.Log.Sanitize(key));\n        }\n\n        return default;\n    }\n\n    /// <summary>\n    /// Creates the item.\n    /// </summary>\n    /// <param name=\"item\">The item.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"sessionId\">The session identifier.</param>\n    /// <param name=\"description\">The description.</param>\n    /// <param name=\"created\">The created.</param>\n    /// <param name=\"lifetime\">The lifetime.</param>\n    /// <returns></returns>\n    protected virtual async Task<string> CreateItemAsync(T item, string clientId, string subjectId, string sessionId, string description, DateTime created, int lifetime)\n    {\n        var handle = await HandleGenerationService.GenerateAsync();\n        await StoreItemAsync(handle, item, clientId, subjectId, sessionId, description, created, created.AddSeconds(lifetime));\n        return handle;\n    }\n\n    /// <summary>\n    /// Stores the item.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <param name=\"item\">The item.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"sessionId\">The session identifier.</param>\n    /// <param name=\"description\">The description.</param>\n    /// <param name=\"created\">The created time.</param>\n    /// <param name=\"expiration\">The expiration.</param>\n    /// <param name=\"consumedTime\">The consumed time.</param>\n    /// <returns></returns>\n    protected virtual async Task StoreItemAsync(string key, T item, string clientId, string subjectId, string sessionId, string description, DateTime created, DateTime? expiration, DateTime? consumedTime = null)\n    {\n        key = GetHashedKey(key);\n\n        var json = Serializer.Serialize(item);\n\n        var grant = new PersistedGrant\n        {\n            Key = key,\n            Type = GrantType,\n            ClientId = clientId,\n            SubjectId = subjectId,\n            SessionId = sessionId,\n            Description = description,\n            CreationTime = created,\n            Expiration = expiration,\n            ConsumedTime = consumedTime,\n            Data = json\n        };\n\n        await Store.StoreAsync(grant);\n    }\n\n    /// <summary>\n    /// Removes the item.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <returns></returns>\n    protected virtual async Task RemoveItemAsync(string key)\n    {\n        key = GetHashedKey(key);\n        await Store.RemoveAsync(key);\n    }\n\n    /// <summary>\n    /// Removes all items for a subject id / cliend id combination.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    protected virtual async Task RemoveAllAsync(string subjectId, string clientId)\n    {\n        await Store.RemoveAllAsync(new PersistedGrantFilter\n        {\n            SubjectId = subjectId,\n            ClientId = clientId,\n            Type = GrantType\n        });\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/DefaultReferenceTokenStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Default reference token store.\n/// </summary>\npublic class DefaultReferenceTokenStore : DefaultGrantStore<Token>, IReferenceTokenStore\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultReferenceTokenStore\"/> class.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"serializer\">The serializer.</param>\n    /// <param name=\"handleGenerationService\">The handle generation service.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultReferenceTokenStore(\n        IPersistedGrantStore store, \n        IPersistentGrantSerializer serializer,\n        IHandleGenerationService handleGenerationService,\n        ILogger<DefaultReferenceTokenStore> logger) \n        : base(IdentityServerConstants.PersistedGrantTypes.ReferenceToken, store, serializer, handleGenerationService, logger)\n    {\n    }\n\n    /// <summary>\n    /// Stores the reference token asynchronous.\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <returns></returns>\n    public Task<string> StoreReferenceTokenAsync(Token token)\n    {\n        return CreateItemAsync(token, token.ClientId, token.SubjectId, token.SessionId, token.Description, token.CreationTime, token.Lifetime);\n    }\n\n    /// <summary>\n    /// Gets the reference token asynchronous.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <returns></returns>\n    public Task<Token> GetReferenceTokenAsync(string handle)\n    {\n        return GetItemAsync(handle);\n    }\n\n    /// <summary>\n    /// Removes the reference token asynchronous.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <returns></returns>\n    public Task RemoveReferenceTokenAsync(string handle)\n    {\n        return RemoveItemAsync(handle);\n    }\n\n    /// <summary>\n    /// Removes the reference tokens asynchronous.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    public Task RemoveReferenceTokensAsync(string subjectId, string clientId)\n    {\n        return RemoveAllAsync(subjectId, clientId);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/DefaultRefreshTokenStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Default refresh token store.\n/// </summary>\npublic class DefaultRefreshTokenStore : DefaultGrantStore<RefreshToken>, IRefreshTokenStore\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultRefreshTokenStore\"/> class.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"serializer\">The serializer.</param>\n    /// <param name=\"handleGenerationService\">The handle generation service.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultRefreshTokenStore(\n        IPersistedGrantStore store, \n        IPersistentGrantSerializer serializer, \n        IHandleGenerationService handleGenerationService,\n        ILogger<DefaultRefreshTokenStore> logger) \n        : base(IdentityServerConstants.PersistedGrantTypes.RefreshToken, store, serializer, handleGenerationService, logger)\n    {\n    }\n\n    /// <summary>\n    /// Stores the refresh token.\n    /// </summary>\n    /// <param name=\"refreshToken\">The refresh token.</param>\n    /// <returns></returns>\n    public async Task<string> StoreRefreshTokenAsync(RefreshToken refreshToken)\n    {\n        return await CreateItemAsync(refreshToken, refreshToken.ClientId, refreshToken.SubjectId, refreshToken.SessionId, refreshToken.Description, refreshToken.CreationTime, refreshToken.Lifetime);\n    }\n\n    /// <summary>\n    /// Updates the refresh token.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <param name=\"refreshToken\">The refresh token.</param>\n    /// <returns></returns>\n    public Task UpdateRefreshTokenAsync(string handle, RefreshToken refreshToken)\n    {\n        return StoreItemAsync(handle, refreshToken, refreshToken.ClientId, refreshToken.SubjectId, refreshToken.SessionId, refreshToken.Description, refreshToken.CreationTime, refreshToken.CreationTime.AddSeconds(refreshToken.Lifetime), refreshToken.ConsumedTime);\n    }\n\n    /// <summary>\n    /// Gets the refresh token.\n    /// </summary>\n    /// <param name=\"refreshTokenHandle\">The refresh token handle.</param>\n    /// <returns></returns>\n    public Task<RefreshToken> GetRefreshTokenAsync(string refreshTokenHandle)\n    {\n        return GetItemAsync(refreshTokenHandle);\n    }\n\n    /// <summary>\n    /// Removes the refresh token.\n    /// </summary>\n    /// <param name=\"refreshTokenHandle\">The refresh token handle.</param>\n    /// <returns></returns>\n    public Task RemoveRefreshTokenAsync(string refreshTokenHandle)\n    {\n        return RemoveItemAsync(refreshTokenHandle);\n    }\n\n    /// <summary>\n    /// Removes the refresh tokens.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    public Task RemoveRefreshTokensAsync(string subjectId, string clientId)\n    {\n        return RemoveAllAsync(subjectId, clientId);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/DefaultUserConsentStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Default user consent store.\n/// </summary>\npublic class DefaultUserConsentStore : DefaultGrantStore<Consent>, IUserConsentStore\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultUserConsentStore\"/> class.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"serializer\">The serializer.</param>\n    /// <param name=\"handleGenerationService\">The handle generation service.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultUserConsentStore(\n        IPersistedGrantStore store, \n        IPersistentGrantSerializer serializer,\n        IHandleGenerationService handleGenerationService,\n        ILogger<DefaultUserConsentStore> logger) \n        : base(IdentityServerConstants.PersistedGrantTypes.UserConsent, store, serializer, handleGenerationService, logger)\n    {\n    }\n\n    private string GetConsentKey(string subjectId, string clientId)\n    {\n        return clientId + \"|\" + subjectId;\n    }\n\n    /// <summary>\n    /// Stores the user consent asynchronous.\n    /// </summary>\n    /// <param name=\"consent\">The consent.</param>\n    /// <returns></returns>\n    public Task StoreUserConsentAsync(Consent consent)\n    {\n        var key = GetConsentKey(consent.SubjectId, consent.ClientId);\n        return StoreItemAsync(key, consent, consent.ClientId, consent.SubjectId, null, null, consent.CreationTime, consent.Expiration);\n    }\n\n    /// <summary>\n    /// Gets the user consent asynchronous.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    public Task<Consent> GetUserConsentAsync(string subjectId, string clientId)\n    {\n        var key = GetConsentKey(subjectId, clientId);\n        return GetItemAsync(key);\n    }\n\n    /// <summary>\n    /// Removes the user consent asynchronous.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    public Task RemoveUserConsentAsync(string subjectId, string clientId)\n    {\n        var key = GetConsentKey(subjectId, clientId);\n        return RemoveItemAsync(key);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/DistributedCacheAuthorizationParametersMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores.Default;\n\n/// <summary>\n/// Implementation of IAuthorizationParametersMessageStore that uses the IDistributedCache.\n/// </summary>\npublic class DistributedCacheAuthorizationParametersMessageStore : IAuthorizationParametersMessageStore\n{\n    private readonly IDistributedCache _distributedCache;\n    private readonly IHandleGenerationService _handleGenerationService;\n\n    /// <summary>\n    /// Ctor.\n    /// </summary>\n    /// <param name=\"distributedCache\"></param>\n    /// <param name=\"handleGenerationService\"></param>\n    public DistributedCacheAuthorizationParametersMessageStore(IDistributedCache distributedCache, IHandleGenerationService handleGenerationService)\n    {\n        _distributedCache = distributedCache;\n        _handleGenerationService = handleGenerationService;\n    }\n\n    private string CacheKeyPrefix => \"DistributedCacheAuthorizationParametersMessageStore\";\n    \n    /// <inheritdoc/>\n    public async Task<string> WriteAsync(Message<IDictionary<string, string[]>> message)\n    {\n        // since this store is trusted and the JWT request processing has provided redundant entries\n        // in the NameValueCollection, we are removing the JWT \"request_uri\" param so that when they\n        // are reloaded/revalidated we don't re-trigger outbound requests. we could possibly do the\n        // same for the \"request\" param, but it's less of a concern (as it's just a signature check).\n        message.Data.Remove(OidcConstants.AuthorizeRequest.RequestUri);\n\n        var key = await _handleGenerationService.GenerateAsync();\n        var cacheKey = $\"{CacheKeyPrefix}-{key}\";\n        \n        var json = ObjectSerializer.ToString(message);\n\n        var options = new DistributedCacheEntryOptions();\n        options.SetSlidingExpiration(Constants.DefaultCacheDuration);\n\n        await _distributedCache.SetStringAsync(cacheKey, json, options);\n\n        return key;\n    }\n\n    /// <inheritdoc/>\n    public async Task<Message<IDictionary<string, string[]>>> ReadAsync(string id)\n    {\n        var cacheKey = $\"{CacheKeyPrefix}-{id}\";\n        var json = await _distributedCache.GetStringAsync(cacheKey);\n\n        if (json == null)\n        {\n            return new Message<IDictionary<string, string[]>>(new Dictionary<string, string[]>());\n        }\n\n        return ObjectSerializer.FromString<Message<IDictionary<string, string[]>>>(json);\n    }\n\n    /// <inheritdoc/>\n    public Task DeleteAsync(string id)\n    {\n        return _distributedCache.RemoveAsync(id);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/ProtectedDataMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.DataProtection;\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// IMessageStore implementation that uses data protection to protect message.\n/// </summary>\n/// <typeparam name=\"TModel\"></typeparam>\npublic class ProtectedDataMessageStore<TModel> : IMessageStore<TModel>\n{\n    private const string Purpose = \"IdentityServer8.Stores.ProtectedDataMessageStore\";\n\n    /// <summary>\n    /// The data protector.\n    /// </summary>\n    protected readonly IDataProtector Protector;\n\n    /// <summary>\n    /// The logger.\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    /// <param name=\"provider\"></param>\n    /// <param name=\"logger\"></param>\n    public ProtectedDataMessageStore(IDataProtectionProvider provider, ILogger<ProtectedDataMessageStore<TModel>> logger)\n    {\n        Protector = provider.CreateProtector(Purpose);\n        Logger = logger;\n    }\n\n    /// <inheritdoc />\n    public virtual Task<Message<TModel>> ReadAsync(string value)\n    {\n        Message<TModel> result = null;\n\n        if (!String.IsNullOrWhiteSpace(value))\n        {\n            try\n            {\n                var bytes = Base64Url.Decode(value);\n                bytes = Protector.Unprotect(bytes);\n                var json = Encoding.UTF8.GetString(bytes);\n                result = ObjectSerializer.FromString<Message<TModel>>(json);\n            }\n            catch(Exception ex)\n            {\n                Logger.LogError(ex, \"Exception reading protected message\");\n            }\n        }\n\n        return Task.FromResult(result);\n    }\n\n    /// <inheritdoc />\n    public virtual Task<string> WriteAsync(Message<TModel> message)\n    {\n        string value = null;\n\n        try\n        {\n            var json = ObjectSerializer.ToString(message);\n            var bytes = Encoding.UTF8.GetBytes(json);\n            bytes = Protector.Protect(bytes);\n            value = Base64Url.Encode(bytes);\n        }\n        catch(Exception ex)\n        {\n            Logger.LogError(ex, \"Exception writing protected message\");\n        }\n\n        return Task.FromResult(value);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/Default/QueryStringAuthorizationParametersMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n// internal just for testing\ninternal class QueryStringAuthorizationParametersMessageStore : IAuthorizationParametersMessageStore\n{\n    public Task<string> WriteAsync(Message<IDictionary<string, string[]>> message)\n    {\n        var queryString = message.Data.FromFullDictionary().ToQueryString();\n        return Task.FromResult(queryString);\n    }\n\n    public Task<Message<IDictionary<string, string[]>>> ReadAsync(string id)\n    {\n        var values = id.ReadQueryStringAsNameValueCollection();\n        var msg = new Message<IDictionary<string, string[]>>(values.ToFullDictionary());\n        return Task.FromResult(msg);\n    }\n\n    public Task DeleteAsync(string id)\n    {\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/IAuthorizationParametersMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for authorization request messages that are sent from the authorization endpoint to the login and consent UI.\n/// </summary>\npublic interface IAuthorizationParametersMessageStore\n{\n    /// <summary>\n    /// Writes the authorization parameters.\n    /// </summary>\n    /// <param name=\"message\">The message.</param>\n    /// <returns>The identifier for the stored message.</returns>\n    Task<string> WriteAsync(Message<IDictionary<string, string[]>> message);\n\n    /// <summary>\n    /// Reads the authorization parameters.\n    /// </summary>\n    /// <param name=\"id\">The identifier.</param>\n    /// <returns></returns>\n    Task<Message<IDictionary<string, string[]>>> ReadAsync(string id);\n\n    /// <summary>\n    /// Deletes the authorization parameters.\n    /// </summary>\n    /// <param name=\"id\">The identifier.</param>\n    /// <returns></returns>\n    Task DeleteAsync(string id);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/IConsentMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for consent messages that are sent from the consent UI to the authorization endpoint.\n/// </summary>\npublic interface IConsentMessageStore\n{\n    /// <summary>\n    /// Writes the consent response message.\n    /// </summary>\n    /// <param name=\"id\">The id for the message.</param>\n    /// <param name=\"message\">The message.</param>\n    Task WriteAsync(string id, Message<ConsentResponse> message);\n\n    /// <summary>\n    /// Reads the consent response message.\n    /// </summary>\n    /// <param name=\"id\">The identifier.</param>\n    /// <returns></returns>\n    Task<Message<ConsentResponse>> ReadAsync(string id);\n\n    /// <summary>\n    /// Deletes the consent response message.\n    /// </summary>\n    /// <param name=\"id\">The identifier.</param>\n    /// <returns></returns>\n    Task DeleteAsync(string id);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/IMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for a message store\n/// </summary>\n/// <typeparam name=\"TModel\">The type of the model.</typeparam>\npublic interface IMessageStore<TModel>\n{\n    /// <summary>\n    /// Writes the message.\n    /// </summary>\n    /// <param name=\"message\">The message.</param>\n    /// <returns>An identifier for the message</returns>\n    Task<string> WriteAsync(Message<TModel> message);\n\n    /// <summary>\n    /// Reads the message.\n    /// </summary>\n    /// <param name=\"id\">The identifier.</param>\n    /// <returns></returns>\n    Task<Message<TModel>> ReadAsync(string id);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/ISigningCredentialStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for a signing credential store\n/// </summary>\npublic interface ISigningCredentialStore\n{\n    /// <summary>\n    /// Gets the signing credentials.\n    /// </summary>\n    /// <returns></returns>\n    Task<SigningCredentials> GetSigningCredentialsAsync();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/IValidationKeysStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for the validation key store\n/// </summary>\npublic interface IValidationKeysStore\n{\n    /// <summary>\n    /// Gets all validation keys.\n    /// </summary>\n    /// <returns></returns>\n    Task<IEnumerable<SecurityKeyInfo>> GetValidationKeysAsync();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/InMemory/InMemoryClientStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// In-memory client store\n/// </summary>\npublic class InMemoryClientStore : IClientStore\n{\n    private readonly IEnumerable<Client> _clients;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"InMemoryClientStore\"/> class.\n    /// </summary>\n    /// <param name=\"clients\">The clients.</param>\n    public InMemoryClientStore(IEnumerable<Client> clients)\n    {\n        if (clients.HasDuplicates(m => m.ClientId))\n        {\n            throw new ArgumentException(\"Clients must not contain duplicate ids\");\n        }\n        _clients = clients;\n    }\n\n    /// <summary>\n    /// Finds a client by id\n    /// </summary>\n    /// <param name=\"clientId\">The client id</param>\n    /// <returns>\n    /// The client\n    /// </returns>\n    public Task<Client> FindClientByIdAsync(string clientId)\n    {\n        var query =\n            from client in _clients\n            where client.ClientId == clientId\n            select client;\n        \n        return Task.FromResult(query.SingleOrDefault());\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/InMemory/InMemoryDeviceFlowStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// In-memory device flow store\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Stores.IDeviceFlowStore\" />\npublic class InMemoryDeviceFlowStore : IDeviceFlowStore\n{\n    private readonly List<InMemoryDeviceAuthorization> _repository = new List<InMemoryDeviceAuthorization>();\n\n    /// <summary>\n    /// Stores the device authorization request.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    /// <returns></returns>\n    public Task StoreDeviceAuthorizationAsync(string deviceCode, string userCode, DeviceCode data)\n    {\n        lock (_repository)\n        {\n            _repository.Add(new InMemoryDeviceAuthorization(deviceCode, userCode, data));\n        }\n        \n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Finds device authorization by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    public Task<DeviceCode> FindByUserCodeAsync(string userCode)\n    {\n        DeviceCode foundDeviceCode;\n\n        lock (_repository)\n        {\n            foundDeviceCode = _repository.FirstOrDefault(x => x.UserCode == userCode)?.Data;\n        }\n\n        return Task.FromResult(foundDeviceCode);\n    }\n\n    /// <summary>\n    /// Finds device authorization by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    public Task<DeviceCode> FindByDeviceCodeAsync(string deviceCode)\n    {\n        DeviceCode foundDeviceCode;\n\n        lock (_repository)\n        {\n            foundDeviceCode = _repository.FirstOrDefault(x => x.DeviceCode == deviceCode)?.Data;\n        }\n\n        return Task.FromResult(foundDeviceCode);\n    }\n\n    /// <summary>\n    /// Updates device authorization, searching by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    public Task UpdateByUserCodeAsync(string userCode, DeviceCode data)\n    {\n        lock (_repository)\n        {\n            var foundData = _repository.FirstOrDefault(x => x.UserCode == userCode);\n\n            if (foundData != null)\n            {\n                foundData.Data = data;\n            }\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Removes the device authorization, searching by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    /// <returns></returns>\n    public Task RemoveByDeviceCodeAsync(string deviceCode)\n    {\n        lock (_repository)\n        {\n            var foundData = _repository.FirstOrDefault(x => x.DeviceCode == deviceCode);\n\n            if (foundData != null)\n            {\n                _repository.Remove(foundData);\n            }\n        }\n\n\n        return Task.CompletedTask;\n    }\n\n    private class InMemoryDeviceAuthorization\n    {\n        public InMemoryDeviceAuthorization(string deviceCode, string userCode, DeviceCode data)\n        {\n            DeviceCode = deviceCode;\n            UserCode = userCode;\n            Data = data;\n        }\n\n        public string DeviceCode { get; }\n        public string UserCode { get; }\n        public DeviceCode Data { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/InMemory/InMemoryPersistedGrantStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// In-memory persisted grant store\n/// </summary>\npublic class InMemoryPersistedGrantStore : IPersistedGrantStore\n{\n    private readonly ConcurrentDictionary<string, PersistedGrant> _repository = new ConcurrentDictionary<string, PersistedGrant>();\n\n    /// <inheritdoc/>\n    public Task StoreAsync(PersistedGrant grant)\n    {\n        _repository[grant.Key] = grant;\n\n        return Task.CompletedTask;\n    }\n\n    /// <inheritdoc/>\n    public Task<PersistedGrant> GetAsync(string key)\n    {\n        if (_repository.TryGetValue(key, out PersistedGrant token))\n        {\n            return Task.FromResult(token);\n        }\n\n        return Task.FromResult<PersistedGrant>(null);\n    }\n\n    /// <inheritdoc/>\n    public Task<IEnumerable<PersistedGrant>> GetAllAsync(PersistedGrantFilter filter)\n    {\n        filter.Validate();\n        \n        var items = Filter(filter);\n        \n        return Task.FromResult(items);\n    }\n\n    /// <inheritdoc/>\n    public Task RemoveAsync(string key)\n    {\n        _repository.TryRemove(key, out _);\n\n        return Task.CompletedTask;\n    }\n\n    /// <inheritdoc/>\n    public Task RemoveAllAsync(PersistedGrantFilter filter)\n    {\n        filter.Validate();\n\n        var items = Filter(filter);\n        \n        foreach (var item in items)\n        {\n            _repository.TryRemove(item.Key, out _);\n        }\n\n        return Task.CompletedTask;\n    }\n\n    private IEnumerable<PersistedGrant> Filter(PersistedGrantFilter filter)\n    {\n        var query =\n            from item in _repository\n            select item.Value;\n\n        if (!String.IsNullOrWhiteSpace(filter.ClientId))\n        {\n            query = query.Where(x => x.ClientId == filter.ClientId);\n        }\n        if (!String.IsNullOrWhiteSpace(filter.SessionId))\n        {\n            query = query.Where(x => x.SessionId == filter.SessionId);\n        }\n        if (!String.IsNullOrWhiteSpace(filter.SubjectId))\n        {\n            query = query.Where(x => x.SubjectId == filter.SubjectId);\n        }\n        if (!String.IsNullOrWhiteSpace(filter.Type))\n        {\n            query = query.Where(x => x.Type == filter.Type);\n        }\n\n        var items = query.ToArray().AsEnumerable();\n        return items;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/InMemory/InMemoryResourcesStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// In-memory resource store\n/// </summary>\npublic class InMemoryResourcesStore : IResourceStore\n{\n    private readonly IEnumerable<IdentityResource> _identityResources;\n    private readonly IEnumerable<ApiResource> _apiResources;\n    private readonly IEnumerable<ApiScope> _apiScopes;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"InMemoryResourcesStore\" /> class.\n    /// </summary>\n    public InMemoryResourcesStore(\n        IEnumerable<IdentityResource> identityResources = null, \n        IEnumerable<ApiResource> apiResources = null, \n        IEnumerable<ApiScope> apiScopes = null)\n    {\n        if (identityResources?.HasDuplicates(m => m.Name) == true)\n        {\n            throw new ArgumentException(\"Identity resources must not contain duplicate names\");\n        }\n\n        if (apiResources?.HasDuplicates(m => m.Name) == true)\n        {\n            throw new ArgumentException(\"Api resources must not contain duplicate names\");\n        }\n        \n        if (apiScopes?.HasDuplicates(m => m.Name) == true)\n        {\n            throw new ArgumentException(\"Scopes must not contain duplicate names\");\n        }\n\n        _identityResources = identityResources ?? Enumerable.Empty<IdentityResource>();\n        _apiResources = apiResources ?? Enumerable.Empty<ApiResource>();\n        _apiScopes = apiScopes ?? Enumerable.Empty<ApiScope>();\n    }\n\n    /// <inheritdoc/>\n    public Task<Resources> GetAllResourcesAsync()\n    {\n        var result = new Resources(_identityResources, _apiResources, _apiScopes);\n        return Task.FromResult(result);\n    }\n\n    /// <inheritdoc/>\n    public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames)\n    {\n        if (apiResourceNames == null) throw new ArgumentNullException(nameof(apiResourceNames));\n\n        var query = from a in _apiResources\n                    where apiResourceNames.Contains(a.Name)\n                    select a;\n        return Task.FromResult(query);\n    }\n\n    /// <inheritdoc/>\n    public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)\n    {\n        if (scopeNames == null) throw new ArgumentNullException(nameof(scopeNames));\n\n        var identity = from i in _identityResources\n                       where scopeNames.Contains(i.Name)\n                       select i;\n\n        return Task.FromResult(identity);\n    }\n\n    /// <inheritdoc/>\n    public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)\n    {\n        if (scopeNames == null) throw new ArgumentNullException(nameof(scopeNames));\n\n        var query = from a in _apiResources\n                    where a.Scopes.Any(x => scopeNames.Contains(x))\n                    select a;\n\n        return Task.FromResult(query);\n    }\n\n    /// <inheritdoc/>\n    public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)\n    {\n        if (scopeNames == null) throw new ArgumentNullException(nameof(scopeNames));\n\n        var query =\n            from x in _apiScopes\n            where scopeNames.Contains(x.Name)\n            select x;\n        \n        return Task.FromResult(query);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/InMemory/InMemorySigningCredentialsStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Default signing credentials store\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Stores.ISigningCredentialStore\" />\npublic class InMemorySigningCredentialsStore : ISigningCredentialStore\n{\n    private readonly SigningCredentials _credential;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"InMemorySigningCredentialsStore\"/> class.\n    /// </summary>\n    /// <param name=\"credential\">The credential.</param>\n    public InMemorySigningCredentialsStore(SigningCredentials credential)\n    {\n        _credential = credential;\n    }\n\n    /// <summary>\n    /// Gets the signing credentials.\n    /// </summary>\n    /// <returns></returns>\n    public Task<SigningCredentials> GetSigningCredentialsAsync()\n    {\n        return Task.FromResult(_credential);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/InMemory/InMemoryValidationKeysStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// The default validation key store\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Stores.IValidationKeysStore\" />\npublic class InMemoryValidationKeysStore : IValidationKeysStore\n{\n    private readonly IEnumerable<SecurityKeyInfo> _keys;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"InMemoryValidationKeysStore\"/> class.\n    /// </summary>\n    /// <param name=\"keys\">The keys.</param>\n    /// <exception cref=\"System.ArgumentNullException\">keys</exception>\n    public InMemoryValidationKeysStore(IEnumerable<SecurityKeyInfo> keys)\n    {\n        _keys = keys ?? throw new ArgumentNullException(nameof(keys));\n    }\n\n    /// <summary>\n    /// Gets all validation keys.\n    /// </summary>\n    /// <returns></returns>\n    public Task<IEnumerable<SecurityKeyInfo>> GetValidationKeysAsync()\n    {\n        return Task.FromResult(_keys);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Stores/ValidatingClientStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Client store decorator for running runtime configuration validation checks\n/// </summary>\npublic class ValidatingClientStore<T> : IClientStore\n    where T : IClientStore\n{\n    private readonly IClientStore _inner;\n    private readonly IClientConfigurationValidator _validator;\n    private readonly IEventService _events;\n    private readonly ILogger<ValidatingClientStore<T>> _logger;\n    private readonly string _validatorType;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ValidatingClientStore{T}\" /> class.\n    /// </summary>\n    /// <param name=\"inner\">The inner.</param>\n    /// <param name=\"validator\">The validator.</param>\n    /// <param name=\"events\">The events.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public ValidatingClientStore(T inner, IClientConfigurationValidator validator, IEventService events, ILogger<ValidatingClientStore<T>> logger)\n    {\n        _inner = inner;\n        _validator = validator;\n        _events = events;\n        _logger = logger;\n\n        _validatorType = validator.GetType().FullName;\n    }\n\n    /// <summary>\n    /// Finds a client by id (and runs the validation logic)\n    /// </summary>\n    /// <param name=\"clientId\">The client id</param>\n    /// <returns>\n    /// The client or an InvalidOperationException\n    /// </returns>\n    public async Task<Client> FindClientByIdAsync(string clientId)\n    {\n        var client = await _inner.FindClientByIdAsync(clientId);\n\n        if (client != null)\n        {\n            _logger.LogTrace(\"Calling into client configuration validator: {validatorType}\", _validatorType);\n\n            var context = new ClientConfigurationValidationContext(client);\n            await _validator.ValidateAsync(context);\n\n            if (context.IsValid)\n            {\n                _logger.LogDebug(\"client configuration validation for client {clientId} succeeded.\", client.ClientId);\n                return client;\n            }\n\n            _logger.LogError(\"Invalid client configuration for client {clientId}: {errorMessage}\", client.ClientId, context.ErrorMessage);\n            await _events.RaiseAsync(new InvalidClientConfigurationEvent(client, context.ErrorMessage));\n                \n            return null;\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Test/IdentityServerBuilderExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\n/// <summary>\n/// Extension methods for the IdentityServer builder\n/// </summary>\npublic static class IdentityServerBuilderExtensions\n{\n    /// <summary>\n    /// Adds test users.\n    /// </summary>\n    /// <param name=\"builder\">The builder.</param>\n    /// <param name=\"users\">The users.</param>\n    /// <returns></returns>\n    public static IIdentityServerBuilder AddTestUsers(this IIdentityServerBuilder builder, List<TestUser> users)\n    {\n        builder.Services.AddSingleton(new TestUserStore(users));\n        builder.AddProfileService<TestUserProfileService>();\n        builder.AddResourceOwnerValidator<TestUserResourceOwnerPasswordValidator>();\n\n        return builder;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Test/TestUser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Test;\n\n/// <summary>\n/// In-memory user object for testing. Not intended for modeling users in production.\n/// </summary>\npublic class TestUser\n{\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the username.\n    /// </summary>\n    public string Username { get; set; }\n\n    /// <summary>\n    /// Gets or sets the password.\n    /// </summary>\n    public string Password { get; set; }\n\n    /// <summary>\n    /// Gets or sets the provider name.\n    /// </summary>\n    public string ProviderName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the provider subject identifier.\n    /// </summary>\n    public string ProviderSubjectId { get; set; }\n\n    /// <summary>\n    /// Gets or sets if the user is active.\n    /// </summary>\n    public bool IsActive { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets the claims.\n    /// </summary>\n    public ICollection<Claim> Claims { get; set; } = new HashSet<Claim>(new ClaimComparer());\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Test/TestUserProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Test;\n\n/// <summary>\n/// Profile service for test users\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Services.IProfileService\" />\npublic class TestUserProfileService : IProfileService\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n    \n    /// <summary>\n    /// The users\n    /// </summary>\n    protected readonly TestUserStore Users;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TestUserProfileService\"/> class.\n    /// </summary>\n    /// <param name=\"users\">The users.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public TestUserProfileService(TestUserStore users, ILogger<TestUserProfileService> logger)\n    {\n        Users = users;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// This method is called whenever claims about the user are requested (e.g. during token creation or via the userinfo endpoint)\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public virtual Task GetProfileDataAsync(ProfileDataRequestContext context)\n    {\n        context.LogProfileRequest(Logger);\n\n        if (context.RequestedClaimTypes.Any())\n        {\n            var user = Users.FindBySubjectId(context.Subject.GetSubjectId());\n            if (user != null)\n            {\n                context.AddRequestedClaims(user.Claims);\n            }\n        }\n\n        context.LogIssuedClaims(Logger);\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// This method gets called whenever identity server needs to determine if the user is valid or active (e.g. if the user's account has been deactivated since they logged in).\n    /// (e.g. during token issuance or validation).\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public virtual Task IsActiveAsync(IsActiveContext context)\n    {\n        Logger.LogDebug(\"IsActive called from: {caller}\", context.Caller);\n\n        var user = Users.FindBySubjectId(context.Subject.GetSubjectId());\n        context.IsActive = user?.IsActive == true;\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Test/TestUserResourceOwnerPasswordValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Test;\n\n/// <summary>\n/// Resource owner password validator for test users\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.IResourceOwnerPasswordValidator\" />\npublic class TestUserResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator\n{\n    private readonly TestUserStore _users;\n    private readonly ISystemClock _clock;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TestUserResourceOwnerPasswordValidator\"/> class.\n    /// </summary>\n    /// <param name=\"users\">The users.</param>\n    /// <param name=\"clock\">The clock.</param>\n    public TestUserResourceOwnerPasswordValidator(TestUserStore users, ISystemClock clock)\n    {\n        _users = users;\n        _clock = clock;\n    }\n\n    /// <summary>\n    /// Validates the resource owner password credential\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)\n    {\n        if (_users.ValidateCredentials(context.UserName, context.Password))\n        {\n            var user = _users.FindByUsername(context.UserName);\n            context.Result = new GrantValidationResult(\n                user.SubjectId ?? throw new ArgumentException(\"Subject ID not set\", nameof(user.SubjectId)), \n                OidcConstants.AuthenticationMethods.Password, _clock.UtcNow.UtcDateTime, \n                user.Claims);\n        }\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Test/TestUserStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Test;\n\n/// <summary>\n/// Store for test users\n/// </summary>\npublic class TestUserStore\n{\n    private readonly List<TestUser> _users;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TestUserStore\"/> class.\n    /// </summary>\n    /// <param name=\"users\">The users.</param>\n    public TestUserStore(List<TestUser> users)\n    {\n        _users = users;\n    }\n\n    /// <summary>\n    /// Validates the credentials.\n    /// </summary>\n    /// <param name=\"username\">The username.</param>\n    /// <param name=\"password\">The password.</param>\n    /// <returns></returns>\n    public bool ValidateCredentials(string username, string password)\n    {\n        var user = FindByUsername(username);\n        \n        if (user != null)\n        {\n            if (string.IsNullOrWhiteSpace(user.Password) && string.IsNullOrWhiteSpace(password))\n            {\n                return true;\n            }\n            \n            return user.Password.Equals(password);\n        }\n        \n        return false;\n    }\n\n    /// <summary>\n    /// Finds the user by subject identifier.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <returns></returns>\n    public TestUser FindBySubjectId(string subjectId)\n    {\n        return _users.FirstOrDefault(x => x.SubjectId == subjectId);\n    }\n\n    /// <summary>\n    /// Finds the user by username.\n    /// </summary>\n    /// <param name=\"username\">The username.</param>\n    /// <returns></returns>\n    public TestUser FindByUsername(string username)\n    {\n        return _users.FirstOrDefault(x => x.Username.Equals(username, StringComparison.OrdinalIgnoreCase));\n    }\n\n    /// <summary>\n    /// Finds the user by external provider.\n    /// </summary>\n    /// <param name=\"provider\">The provider.</param>\n    /// <param name=\"userId\">The user identifier.</param>\n    /// <returns></returns>\n    public TestUser FindByExternalProvider(string provider, string userId)\n    {\n        return _users.FirstOrDefault(x =>\n            x.ProviderName == provider &&\n            x.ProviderSubjectId == userId);\n    }\n\n    /// <summary>\n    /// Automatically provisions a user.\n    /// </summary>\n    /// <param name=\"provider\">The provider.</param>\n    /// <param name=\"userId\">The user identifier.</param>\n    /// <param name=\"claims\">The claims.</param>\n    /// <returns></returns>\n    public TestUser AutoProvisionUser(string provider, string userId, List<Claim> claims)\n    {\n        // create a list of claims that we want to transfer into our store\n        var filtered = new List<Claim>();\n\n        foreach (var claim in claims)\n        {\n            // if the external system sends a display name - translate that to the standard OIDC name claim\n            if (claim.Type == ClaimTypes.Name)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, claim.Value));\n            }\n            // if the JWT handler has an outbound mapping to an OIDC claim use that\n            else if (JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.ContainsKey(claim.Type))\n            {\n                filtered.Add(new Claim(JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap[claim.Type], claim.Value));\n            }\n            // copy the claim as-is\n            else\n            {\n                filtered.Add(claim);\n            }\n        }\n\n        // if no display name was provided, try to construct by first and/or last name\n        if (!filtered.Any(x => x.Type == JwtClaimTypes.Name))\n        {\n            var first = filtered.FirstOrDefault(x => x.Type == JwtClaimTypes.GivenName)?.Value;\n            var last = filtered.FirstOrDefault(x => x.Type == JwtClaimTypes.FamilyName)?.Value;\n            if (first != null && last != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, first + \" \" + last));\n            }\n            else if (first != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, first));\n            }\n            else if (last != null)\n            {\n                filtered.Add(new Claim(JwtClaimTypes.Name, last));\n            }\n        }\n\n        // create a new unique subject id\n        var sub = CryptoRandom.CreateUniqueId(format: CryptoRandom.OutputFormat.Hex);\n\n        // check if a display name is available, otherwise fallback to subject id\n        var name = filtered.FirstOrDefault(c => c.Type == JwtClaimTypes.Name)?.Value ?? sub;\n\n        // create new user\n        var user = new TestUser\n        {\n            SubjectId = sub,\n            Username = name,\n            ProviderName = provider,\n            ProviderSubjectId = userId,\n            Claims = filtered\n        };\n\n        // add user to in-memory store\n        _users.Add(user);\n\n        return user;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Contexts/ClientConfigurationValidationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Context for client configuration validation.\n/// </summary>\npublic class ClientConfigurationValidationContext\n{\n    /// <summary>\n    /// Gets or sets the client.\n    /// </summary>\n    /// <value>\n    /// The client.\n    /// </value>\n    public Client Client { get; }\n\n    /// <summary>\n    /// Returns true if client configuration is valid.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is valid; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsValid { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets the error message.\n    /// </summary>\n    /// <value>\n    /// The error message.\n    /// </value>\n    public string ErrorMessage { get; set; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ClientConfigurationValidationContext\"/> class.\n    /// </summary>\n    /// <param name=\"client\">The client.</param>\n    public ClientConfigurationValidationContext(Client client)\n    {\n        Client = client;\n    }\n\n    /// <summary>\n    /// Sets a validation error.\n    /// </summary>\n    /// <param name=\"message\">The message.</param>\n    public void SetError(string message)\n    {\n        IsValid = false;\n        ErrorMessage = message;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Contexts/CustomAuthorizeRequestValidationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Context for custom authorize request validation.\n/// </summary>\npublic class CustomAuthorizeRequestValidationContext\n{\n    /// <summary>\n    /// The result of custom validation. \n    /// </summary>\n    public AuthorizeRequestValidationResult Result { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Contexts/CustomTokenRequestValidationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Context class for custom token request validation\n/// </summary>\npublic class CustomTokenRequestValidationContext\n{\n    /// <summary>\n    /// Gets or sets the result.\n    /// </summary>\n    /// <value>\n    /// The result.\n    /// </value>\n    public TokenRequestValidationResult Result { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Contexts/ExtensionGrantValidationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Class describing the extension grant validation context\n/// </summary>\npublic class ExtensionGrantValidationContext\n{\n    /// <summary>\n    /// Gets or sets the request.\n    /// </summary>\n    /// <value>\n    /// The request.\n    /// </value>\n    public ValidatedTokenRequest Request { get; set; }\n\n    /// <summary>\n    /// Gets or sets the result.\n    /// </summary>\n    /// <value>\n    /// The result.\n    /// </value>\n    public GrantValidationResult Result { get; set; } = new GrantValidationResult(TokenRequestErrors.InvalidGrant);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Contexts/ResourceOwnerPasswordValidationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Class describing the resource owner password validation context\n/// </summary>\npublic class ResourceOwnerPasswordValidationContext\n{\n    /// <summary>\n    /// Gets or sets the name of the user.\n    /// </summary>\n    /// <value>\n    /// The name of the user.\n    /// </value>\n    public string UserName { get; set; }\n\n    /// <summary>\n    /// Gets or sets the password.\n    /// </summary>\n    /// <value>\n    /// The password.\n    /// </value>\n    public string Password { get; set; }\n\n    /// <summary>\n    /// Gets or sets the request.\n    /// </summary>\n    /// <value>\n    /// The request.\n    /// </value>\n    public ValidatedTokenRequest Request { get; set; }\n\n    /// <summary>\n    /// Gets or sets the result.\n    /// </summary>\n    /// <value>\n    /// The result.\n    /// </value>\n    public GrantValidationResult Result { get; set; } = new GrantValidationResult(TokenRequestErrors.InvalidGrant);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Contexts/ResourceValidationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Class describing the resource validation context\n/// </summary>\npublic class ResourceValidationContext\n{\n    /// <summary>\n    /// Gets or sets the result.\n    /// </summary>\n    /// <value>\n    /// The result.\n    /// </value>\n    public GrantValidationResult Result { get; set; } = new GrantValidationResult(TokenRequestErrors.InvalidGrant);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/ApiSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates API secrets using the registered secret validators and parsers\n/// </summary>\npublic class ApiSecretValidator : IApiSecretValidator\n{\n    private readonly ILogger _logger;\n    private readonly IResourceStore _resources;\n    private readonly IEventService _events;\n    private readonly ISecretsListParser _parser;\n    private readonly ISecretsListValidator _validator;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiSecretValidator\"/> class.\n    /// </summary>\n    /// <param name=\"resources\">The resources.</param>\n    /// <param name=\"parsers\">The parsers.</param>\n    /// <param name=\"validator\">The validator.</param>\n    /// <param name=\"events\">The events.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public ApiSecretValidator(IResourceStore resources, ISecretsListParser parsers, ISecretsListValidator validator, IEventService events, ILogger<ApiSecretValidator> logger)\n    {\n        _resources = resources;\n        _parser = parsers;\n        _validator = validator;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the secret on the current request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public async Task<ApiSecretValidationResult> ValidateAsync(HttpContext context)\n    {\n        _logger.LogTrace(\"Start API validation\");\n\n        var fail = new ApiSecretValidationResult\n        {\n            IsError = true\n        };\n\n        var parsedSecret = await _parser.ParseAsync(context);\n        if (parsedSecret == null)\n        {\n            await RaiseFailureEventAsync(\"unknown\", \"No API id or secret found\");\n\n            _logger.LogError(\"No API secret found\");\n            return fail;\n        }\n\n        // load API resource\n        var apis = await _resources.FindApiResourcesByNameAsync(new[] { parsedSecret.Id });\n        if (apis == null || !apis.Any())\n        {\n            await RaiseFailureEventAsync(parsedSecret.Id, \"Unknown API resource\");\n\n            _logger.LogError(\"No API resource with that name found. aborting\");\n            return fail;\n        }\n\n        if (apis.Count() > 1)\n        {\n            await RaiseFailureEventAsync(parsedSecret.Id, \"Invalid API resource\");\n\n            _logger.LogError(\"More than one API resource with that name found. aborting\");\n            return fail;\n        }\n\n        var api = apis.Single();\n\n        if (api.Enabled == false)\n        {\n            await RaiseFailureEventAsync(parsedSecret.Id, \"API resource not enabled\");\n\n            _logger.LogError(\"API resource not enabled. aborting.\");\n            return fail;\n        }\n\n        var result = await _validator.ValidateAsync(api.ApiSecrets, parsedSecret);\n        if (result.Success)\n        {\n            _logger.LogDebug(\"API resource validation success\");\n\n            var success = new ApiSecretValidationResult\n            {\n                IsError = false,\n                Resource = api\n            };\n\n            await RaiseSuccessEventAsync(api.Name, parsedSecret.Type);\n            return success;\n        }\n\n        await RaiseFailureEventAsync(api.Name, \"Invalid API secret\");\n        _logger.LogError(\"API validation failed.\");\n\n        return fail;\n    }\n\n    private Task RaiseSuccessEventAsync(string clientId, string authMethod)\n    {\n        return _events.RaiseAsync(new ApiAuthenticationSuccessEvent(clientId, authMethod));\n    }\n\n    private Task RaiseFailureEventAsync(string clientId, string message)\n    {\n        return _events.RaiseAsync(new ApiAuthenticationFailureEvent(clientId, message));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/AuthorizeRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\ninternal class AuthorizeRequestValidator : IAuthorizeRequestValidator\n{\n    private readonly IdentityServerOptions _options;\n    private readonly IClientStore _clients;\n    private readonly ICustomAuthorizeRequestValidator _customValidator;\n    private readonly IRedirectUriValidator _uriValidator;\n    private readonly IResourceValidator _resourceValidator;\n    private readonly IUserSession _userSession;\n    private readonly JwtRequestValidator _jwtRequestValidator;\n    private readonly IJwtRequestUriHttpClient _jwtRequestUriHttpClient;\n    private readonly ILogger _logger;\n\n    private readonly ResponseTypeEqualityComparer\n        _responseTypeEqualityComparer = new ResponseTypeEqualityComparer();\n\n    public AuthorizeRequestValidator(\n        IdentityServerOptions options,\n        IClientStore clients,\n        ICustomAuthorizeRequestValidator customValidator,\n        IRedirectUriValidator uriValidator,\n        IResourceValidator resourceValidator,\n        IUserSession userSession,\n        JwtRequestValidator jwtRequestValidator,\n        IJwtRequestUriHttpClient jwtRequestUriHttpClient,\n        ILogger<AuthorizeRequestValidator> logger)\n    {\n        _options = options;\n        _clients = clients;\n        _customValidator = customValidator;\n        _uriValidator = uriValidator;\n        _resourceValidator = resourceValidator;\n        _jwtRequestValidator = jwtRequestValidator;\n        _userSession = userSession;\n        _jwtRequestUriHttpClient = jwtRequestUriHttpClient;\n        _logger = logger;\n    }\n\n    public async Task<AuthorizeRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject = null)\n    {\n        _logger.LogDebug(\"Start authorize request protocol validation\");\n\n        var request = new ValidatedAuthorizeRequest\n        {\n            Options = _options,\n            Subject = subject ?? Principal.Anonymous,\n            Raw = parameters ?? throw new ArgumentNullException(nameof(parameters))\n        };\n        \n        // load client_id\n        // client_id must always be present on the request\n        var loadClientResult = await LoadClientAsync(request);\n        if (loadClientResult.IsError)\n        {\n            return loadClientResult;\n        }\n\n        // load request object\n        var roLoadResult = await LoadRequestObjectAsync(request);\n        if (roLoadResult.IsError)\n        {\n            return roLoadResult;\n        }\n\n        // validate request object\n        var roValidationResult = await ValidateRequestObjectAsync(request);\n        if (roValidationResult.IsError)\n        {\n            return roValidationResult;\n        }\n\n        // validate client_id and redirect_uri\n        var clientResult = await ValidateClientAsync(request);\n        if (clientResult.IsError)\n        {\n            return clientResult;\n        }\n\n        // state, response_type, response_mode\n        var mandatoryResult = ValidateCoreParameters(request);\n        if (mandatoryResult.IsError)\n        {\n            return mandatoryResult;\n        }\n\n        // scope, scope restrictions and plausability\n        var scopeResult = await ValidateScopeAsync(request);\n        if (scopeResult.IsError)\n        {\n            return scopeResult;\n        }\n\n        // nonce, prompt, acr_values, login_hint etc.\n        var optionalResult = await ValidateOptionalParametersAsync(request);\n        if (optionalResult.IsError)\n        {\n            return optionalResult;\n        }\n\n        // custom validator\n        _logger.LogDebug(\"Calling into custom validator: {type}\", _customValidator.GetType().FullName);\n        var context = new CustomAuthorizeRequestValidationContext\n        {\n            Result = new AuthorizeRequestValidationResult(request)\n        };\n        await _customValidator.ValidateAsync(context);\n\n        var customResult = context.Result;\n        if (customResult.IsError)\n        {\n            LogError(\"Error in custom validation\", customResult.Error, request);\n            return Invalid(request, customResult.Error, customResult.ErrorDescription);\n        }\n\n        _logger.LogTrace(\"Authorize request protocol validation successful\");\n\n        return Valid(request);\n    }\n\n    private async Task<AuthorizeRequestValidationResult> LoadRequestObjectAsync(ValidatedAuthorizeRequest request)\n    {\n        var jwtRequest = request.Raw.Get(OidcConstants.AuthorizeRequest.Request);\n        var jwtRequestUri = request.Raw.Get(OidcConstants.AuthorizeRequest.RequestUri);\n\n        if (jwtRequest.IsPresent() && jwtRequestUri.IsPresent())\n        {\n            LogError(\"Both request and request_uri are present\", request);\n            return Invalid(request, description: \"Only one request parameter is allowed\");\n        }\n\n        if (_options.Endpoints.EnableJwtRequestUri)\n        {\n            if (jwtRequestUri.IsPresent())\n            {\n                // 512 is from the spec\n                if (jwtRequestUri.Length > 512)\n                {\n                    LogError(\"request_uri is too long\", request);\n                    return Invalid(request, error: OidcConstants.AuthorizeErrors.InvalidRequestUri, description: \"request_uri is too long\");\n                }\n\n                var jwt = await _jwtRequestUriHttpClient.GetJwtAsync(jwtRequestUri, request.Client);\n                if (jwt.IsMissing())\n                {\n                    LogError(\"no value returned from request_uri\", request);\n                    return Invalid(request, error: OidcConstants.AuthorizeErrors.InvalidRequestUri, description: \"no value returned from request_uri\");\n                }\n\n                jwtRequest = jwt;\n            }\n        }\n        else if (jwtRequestUri.IsPresent())\n        {\n            LogError(\"request_uri present but config prohibits\", request);\n            return Invalid(request, error: OidcConstants.AuthorizeErrors.RequestUriNotSupported);\n        }\n\n        // check length restrictions\n        if (jwtRequest.IsPresent())\n        {\n            if (jwtRequest.Length >= _options.InputLengthRestrictions.Jwt)\n            {\n                LogError(\"request value is too long\", request);\n                return Invalid(request, error: OidcConstants.AuthorizeErrors.InvalidRequestObject, description: \"Invalid request value\");\n            }\n        }\n\n        request.RequestObject = jwtRequest;\n        return Valid(request);\n    }\n\n    private async Task<AuthorizeRequestValidationResult> LoadClientAsync(ValidatedAuthorizeRequest request)\n    {\n        //////////////////////////////////////////////////////////\n        // client_id must be present\n        /////////////////////////////////////////////////////////\n        var clientId = request.Raw.Get(OidcConstants.AuthorizeRequest.ClientId);\n\n        if (clientId.IsMissingOrTooLong(_options.InputLengthRestrictions.ClientId))\n        {\n            LogError(\"client_id is missing or too long\", request);\n            return Invalid(request, description: \"Invalid client_id\");\n        }\n\n        request.ClientId = clientId;\n\n        //////////////////////////////////////////////////////////\n        // check for valid client\n        //////////////////////////////////////////////////////////\n        var client = await _clients.FindEnabledClientByIdAsync(request.ClientId);\n        if (client == null)\n        {\n            LogError(\"Unknown client or not enabled\", request.ClientId, request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, \"Unknown client or client not enabled\");\n        }\n\n        request.SetClient(client);\n\n        return Valid(request);\n    }\n\n    private async Task<AuthorizeRequestValidationResult> ValidateRequestObjectAsync(ValidatedAuthorizeRequest request)\n    {\n        //////////////////////////////////////////////////////////\n        // validate request object\n        /////////////////////////////////////////////////////////\n        if (request.RequestObject.IsPresent())\n        {\n            // validate the request JWT for this client\n            var jwtRequestValidationResult = await _jwtRequestValidator.ValidateAsync(request.Client, request.RequestObject);\n            if (jwtRequestValidationResult.IsError)\n            {\n                LogError(\"request JWT validation failure\", request);\n                return Invalid(request, error: OidcConstants.AuthorizeErrors.InvalidRequestObject, description: \"Invalid JWT request\");\n            }\n\n            // validate response_type match\n            var responseType = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseType);\n            if (responseType != null)\n            {\n                if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ResponseType, out var payloadResponseType))\n                {\n                    if (payloadResponseType != responseType)\n                    {\n                        LogError(\"response_type in JWT payload does not match response_type in request\", request);\n                        return Invalid(request, description: \"Invalid JWT request\");\n                    }\n                }\n            }\n\n            // validate client_id mismatch\n            if (jwtRequestValidationResult.Payload.TryGetValue(OidcConstants.AuthorizeRequest.ClientId, out var payloadClientId))\n            {\n                if (!string.Equals(request.Client.ClientId, payloadClientId, StringComparison.Ordinal))\n                {\n                    LogError(\"client_id in JWT payload does not match client_id in request\", request);\n                    return Invalid(request, description: \"Invalid JWT request\");\n                }\n            }\n            else\n            {\n                LogError(\"client_id is missing in JWT payload\", request);\n                return Invalid(request, error: OidcConstants.AuthorizeErrors.InvalidRequestObject, description: \"Invalid JWT request\");\n            }\n\n            var ignoreKeys = new[]\n            {\n                JwtClaimTypes.Issuer,\n                JwtClaimTypes.Audience\n            };\n\n            // merge jwt payload values into original request parameters\n            foreach (var key in jwtRequestValidationResult.Payload.Keys)\n            {\n                if (ignoreKeys.Contains(key)) continue;\n                \n                var value = jwtRequestValidationResult.Payload[key];\n                \n                var qsValue = request.Raw.Get(key);\n                if (qsValue != null)\n                {\n                    if (!string.Equals(value, qsValue, StringComparison.Ordinal))\n                    {\n                        LogError(\"parameter mismatch between request object and query string parameter.\", request);\n                        return Invalid(request, description: \"Parameter mismatch in JWT request\");\n                    }\n                }\n\n                request.Raw.Set(key, value);\n            }\n\n            request.RequestObjectValues = jwtRequestValidationResult.Payload;\n        }\n\n        return Valid(request);\n    }\n\n    private async Task<AuthorizeRequestValidationResult> ValidateClientAsync(ValidatedAuthorizeRequest request)\n    {\n        //////////////////////////////////////////////////////////\n        // check request object requirement\n        //////////////////////////////////////////////////////////\n        if (request.Client.RequireRequestObject)\n        {\n            if (!request.RequestObjectValues.Any())\n            {\n                return Invalid(request, description: \"Client must use request object, but no request or request_uri parameter present\");\n            }\n        }\n\n        //////////////////////////////////////////////////////////\n        // redirect_uri must be present, and a valid uri\n        //////////////////////////////////////////////////////////\n        var redirectUri = request.Raw.Get(OidcConstants.AuthorizeRequest.RedirectUri);\n\n        if (redirectUri.IsMissingOrTooLong(_options.InputLengthRestrictions.RedirectUri))\n        {\n            LogError(\"redirect_uri is missing or too long\", request);\n            return Invalid(request, description: \"Invalid redirect_uri\");\n        }\n\n        if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out _))\n        {\n            LogError(\"malformed redirect_uri\", redirectUri, request);\n            return Invalid(request, description: \"Invalid redirect_uri\");\n        }\n\n        //////////////////////////////////////////////////////////\n        // check if client protocol type is oidc\n        //////////////////////////////////////////////////////////\n        if (request.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect)\n        {\n            LogError(\"Invalid protocol type for OIDC authorize endpoint\", request.Client.ProtocolType, request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, description: \"Invalid protocol\");\n        }\n\n        //////////////////////////////////////////////////////////\n        // check if redirect_uri is valid\n        //////////////////////////////////////////////////////////\n        if (await _uriValidator.IsRedirectUriValidAsync(redirectUri, request.Client) == false)\n        {\n            LogError(\"Invalid redirect_uri\", redirectUri, request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.InvalidRequest, \"Invalid redirect_uri\");\n        }\n\n        request.RedirectUri = redirectUri;\n\n        return Valid(request);\n    }\n\n    private AuthorizeRequestValidationResult ValidateCoreParameters(ValidatedAuthorizeRequest request)\n    {\n        //////////////////////////////////////////////////////////\n        // check state\n        //////////////////////////////////////////////////////////\n        var state = request.Raw.Get(OidcConstants.AuthorizeRequest.State);\n        if (state.IsPresent())\n        {\n            request.State = state;\n        }\n\n        //////////////////////////////////////////////////////////\n        // response_type must be present and supported\n        //////////////////////////////////////////////////////////\n        var responseType = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseType);\n        if (responseType.IsMissing())\n        {\n            LogError(\"Missing response_type\", request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, \"Missing response_type\");\n        }\n\n        // The responseType may come in in an unconventional order.\n        // Use an IEqualityComparer that doesn't care about the order of multiple values.\n        // Per https://tools.ietf.org/html/rfc6749#section-3.1.1 -\n        // 'Extension response types MAY contain a space-delimited (%x20) list of\n        // values, where the order of values does not matter (e.g., response\n        // type \"a b\" is the same as \"b a\").'\n        // http://openid.net/specs/oauth-v2-multiple-response-types-1_0-03.html#terminology -\n        // 'If a response type contains one of more space characters (%20), it is compared\n        // as a space-delimited list of values in which the order of values does not matter.'\n        if (!Constants.SupportedResponseTypes.Contains(responseType, _responseTypeEqualityComparer))\n        {\n            LogError(\"Response type not supported\", responseType, request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, \"Response type not supported\");\n        }\n\n        // Even though the responseType may have come in in an unconventional order,\n        // we still need the request's ResponseType property to be set to the\n        // conventional, supported response type.\n        request.ResponseType = Constants.SupportedResponseTypes.First(\n            supportedResponseType => _responseTypeEqualityComparer.Equals(supportedResponseType, responseType));\n\n        //////////////////////////////////////////////////////////\n        // match response_type to grant type\n        //////////////////////////////////////////////////////////\n        request.GrantType = Constants.ResponseTypeToGrantTypeMapping[request.ResponseType];\n\n        // set default response mode for flow; this is needed for any client error processing below\n        request.ResponseMode = Constants.AllowedResponseModesForGrantType[request.GrantType].First();\n\n        //////////////////////////////////////////////////////////\n        // check if flow is allowed at authorize endpoint\n        //////////////////////////////////////////////////////////\n        if (!Constants.AllowedGrantTypesForAuthorizeEndpoint.Contains(request.GrantType))\n        {\n            LogError(\"Invalid grant type\", request.GrantType, request);\n            return Invalid(request, description: \"Invalid response_type\");\n        }\n\n        //////////////////////////////////////////////////////////\n        // check if PKCE is required and validate parameters\n        //////////////////////////////////////////////////////////\n        if (request.GrantType == GrantType.AuthorizationCode || request.GrantType == GrantType.Hybrid)\n        {\n            _logger.LogDebug(\"Checking for PKCE parameters\");\n\n            /////////////////////////////////////////////////////////////////////////////\n            // validate code_challenge and code_challenge_method\n            /////////////////////////////////////////////////////////////////////////////\n            var proofKeyResult = ValidatePkceParameters(request);\n\n            if (proofKeyResult.IsError)\n            {\n                return proofKeyResult;\n            }\n        }\n\n        //////////////////////////////////////////////////////////\n        // check response_mode parameter and set response_mode\n        //////////////////////////////////////////////////////////\n\n        // check if response_mode parameter is present and valid\n        var responseMode = request.Raw.Get(OidcConstants.AuthorizeRequest.ResponseMode);\n        if (responseMode.IsPresent())\n        {\n            if (Constants.SupportedResponseModes.Contains(responseMode))\n            {\n                if (Constants.AllowedResponseModesForGrantType[request.GrantType].Contains(responseMode))\n                {\n                    request.ResponseMode = responseMode;\n                }\n                else\n                {\n                    LogError(\"Invalid response_mode for response_type\", responseMode, request);\n                    return Invalid(request, OidcConstants.AuthorizeErrors.InvalidRequest, description: \"Invalid response_mode for response_type\");\n                }\n            }\n            else\n            {\n                LogError(\"Unsupported response_mode\", responseMode, request);\n                return Invalid(request, OidcConstants.AuthorizeErrors.UnsupportedResponseType, description: \"Invalid response_mode\");\n            }\n        }\n\n\n        //////////////////////////////////////////////////////////\n        // check if grant type is allowed for client\n        //////////////////////////////////////////////////////////\n        if (!request.Client.AllowedGrantTypes.Contains(request.GrantType))\n        {\n            LogError(\"Invalid grant type for client\", request.GrantType, request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, \"Invalid grant type for client\");\n        }\n\n        //////////////////////////////////////////////////////////\n        // check if response type contains an access token,\n        // and if client is allowed to request access token via browser\n        //////////////////////////////////////////////////////////\n        var responseTypes = responseType.FromSpaceSeparatedString();\n        if (responseTypes.Contains(OidcConstants.ResponseTypes.Token))\n        {\n            if (!request.Client.AllowAccessTokensViaBrowser)\n            {\n                LogError(\"Client requested access token - but client is not configured to receive access tokens via browser\", request);\n                return Invalid(request, description: \"Client not configured to receive access tokens via browser\");\n            }\n        }\n\n        return Valid(request);\n    }\n\n    private AuthorizeRequestValidationResult ValidatePkceParameters(ValidatedAuthorizeRequest request)\n    {\n        var fail = Invalid(request);\n\n        var codeChallenge = request.Raw.Get(OidcConstants.AuthorizeRequest.CodeChallenge);\n        if (codeChallenge.IsMissing())\n        {\n            if (request.Client.RequirePkce)\n            {\n                LogError(\"code_challenge is missing\", request);\n                fail.ErrorDescription = \"code challenge required\";\n            }\n            else\n            {\n                _logger.LogDebug(\"No PKCE used.\");\n                return Valid(request);\n            }\n\n            return fail;\n        }\n\n        if (codeChallenge.Length < _options.InputLengthRestrictions.CodeChallengeMinLength ||\n            codeChallenge.Length > _options.InputLengthRestrictions.CodeChallengeMaxLength)\n        {\n            LogError(\"code_challenge is either too short or too long\", request);\n            fail.ErrorDescription = \"Invalid code_challenge\";\n            return fail;\n        }\n\n        request.CodeChallenge = codeChallenge;\n\n        var codeChallengeMethod = request.Raw.Get(OidcConstants.AuthorizeRequest.CodeChallengeMethod);\n        if (codeChallengeMethod.IsMissing())\n        {\n            _logger.LogDebug(\"Missing code_challenge_method, defaulting to plain\");\n            codeChallengeMethod = OidcConstants.CodeChallengeMethods.Plain;\n        }\n\n        if (!Constants.SupportedCodeChallengeMethods.Contains(codeChallengeMethod))\n        {\n            LogError(\"Unsupported code_challenge_method\", codeChallengeMethod, request);\n            fail.ErrorDescription = \"Transform algorithm not supported\";\n            return fail;\n        }\n\n        // check if plain method is allowed\n        if (codeChallengeMethod == OidcConstants.CodeChallengeMethods.Plain)\n        {\n            if (!request.Client.AllowPlainTextPkce)\n            {\n                LogError(\"code_challenge_method of plain is not allowed\", request);\n                fail.ErrorDescription = \"Transform algorithm not supported\";\n                return fail;\n            }\n        }\n\n        request.CodeChallengeMethod = codeChallengeMethod;\n\n        return Valid(request);\n    }\n\n    private async Task<AuthorizeRequestValidationResult> ValidateScopeAsync(ValidatedAuthorizeRequest request)\n    {\n        //////////////////////////////////////////////////////////\n        // scope must be present\n        //////////////////////////////////////////////////////////\n        var scope = request.Raw.Get(OidcConstants.AuthorizeRequest.Scope);\n        if (scope.IsMissing())\n        {\n            LogError(\"scope is missing\", request);\n            return Invalid(request, description: \"Invalid scope\");\n        }\n\n        if (scope.Length > _options.InputLengthRestrictions.Scope)\n        {\n            LogError(\"scopes too long.\", request);\n            return Invalid(request, description: \"Invalid scope\");\n        }\n\n        request.RequestedScopes = scope.FromSpaceSeparatedString().Distinct().ToList();\n\n        if (request.RequestedScopes.Contains(IdentityServerConstants.StandardScopes.OpenId))\n        {\n            request.IsOpenIdRequest = true;\n        }\n\n        //////////////////////////////////////////////////////////\n        // check scope vs response_type plausability\n        //////////////////////////////////////////////////////////\n        var requirement = Constants.ResponseTypeToScopeRequirement[request.ResponseType];\n        if (requirement == Constants.ScopeRequirement.Identity ||\n            requirement == Constants.ScopeRequirement.IdentityOnly)\n        {\n            if (request.IsOpenIdRequest == false)\n            {\n                LogError(\"response_type requires the openid scope\", request);\n                return Invalid(request, description: \"Missing openid scope\");\n            }\n        }\n\n        //////////////////////////////////////////////////////////\n        // check if scopes are valid/supported and check for resource scopes\n        //////////////////////////////////////////////////////////\n        var validatedResources = await _resourceValidator.ValidateRequestedResourcesAsync(new ResourceValidationRequest\n        {\n            Client = request.Client,\n            Scopes = request.RequestedScopes\n        });\n\n        if (!validatedResources.Succeeded)\n        {\n            return Invalid(request, OidcConstants.AuthorizeErrors.InvalidScope, \"Invalid scope\");\n        }\n\n        if (validatedResources.Resources.IdentityResources.Any() && !request.IsOpenIdRequest)\n        {\n            LogError(\"Identity related scope requests, but no openid scope\", request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.InvalidScope, \"Identity scopes requested, but openid scope is missing\");\n        }\n\n        if (validatedResources.Resources.ApiScopes.Any())\n        {\n            request.IsApiResourceRequest = true;\n        }\n\n        //////////////////////////////////////////////////////////\n        // check id vs resource scopes and response types plausability\n        //////////////////////////////////////////////////////////\n        var responseTypeValidationCheck = true;\n        switch (requirement)\n        {\n            case Constants.ScopeRequirement.Identity:\n                if (!validatedResources.Resources.IdentityResources.Any())\n                {\n                    _logger.LogError(\"Requests for id_token response type must include identity scopes\");\n                    responseTypeValidationCheck = false;\n                }\n                break;\n            case Constants.ScopeRequirement.IdentityOnly:\n                if (!validatedResources.Resources.IdentityResources.Any() || validatedResources.Resources.ApiScopes.Any())\n                {\n                    _logger.LogError(\"Requests for id_token response type only must not include resource scopes\");\n                    responseTypeValidationCheck = false;\n                }\n                break;\n            case Constants.ScopeRequirement.ResourceOnly:\n                if (validatedResources.Resources.IdentityResources.Any() || !validatedResources.Resources.ApiScopes.Any())\n                {\n                    _logger.LogError(\"Requests for token response type only must include resource scopes, but no identity scopes.\");\n                    responseTypeValidationCheck = false;\n                }\n                break;\n        }\n\n        if (!responseTypeValidationCheck)\n        {\n            return Invalid(request, OidcConstants.AuthorizeErrors.InvalidScope, \"Invalid scope for response type\");\n        }\n\n        request.ValidatedResources = validatedResources;\n\n        return Valid(request);\n    }\n\n    private async Task<AuthorizeRequestValidationResult> ValidateOptionalParametersAsync(ValidatedAuthorizeRequest request)\n    {\n        //////////////////////////////////////////////////////////\n        // check nonce\n        //////////////////////////////////////////////////////////\n        var nonce = request.Raw.Get(OidcConstants.AuthorizeRequest.Nonce);\n        if (nonce.IsPresent())\n        {\n            if (nonce.Length > _options.InputLengthRestrictions.Nonce)\n            {\n                LogError(\"Nonce too long\", request);\n                return Invalid(request, description: \"Invalid nonce\");\n            }\n\n            request.Nonce = nonce;\n        }\n        else\n        {\n            if (request.GrantType == GrantType.Implicit ||\n                request.GrantType == GrantType.Hybrid)\n            {\n                // only openid requests require nonce\n                if (request.IsOpenIdRequest)\n                {\n                    LogError(\"Nonce required for implicit and hybrid flow with openid scope\", request);\n                    return Invalid(request, description: \"Invalid nonce\");\n                }\n            }\n        }\n\n\n        //////////////////////////////////////////////////////////\n        // check prompt\n        //////////////////////////////////////////////////////////\n        var prompt = request.Raw.Get(OidcConstants.AuthorizeRequest.Prompt);\n        if (prompt.IsPresent())\n        {\n            var prompts = prompt.Split(' ', StringSplitOptions.RemoveEmptyEntries);\n            if (prompts.All(p => Constants.SupportedPromptModes.Contains(p)))\n            {\n                if (prompts.Contains(OidcConstants.PromptModes.None) && prompts.Length > 1)\n                {\n                    LogError(\"prompt contains 'none' and other values. 'none' should be used by itself.\", request);\n                    return Invalid(request, description: \"Invalid prompt\");\n                }\n\n                request.PromptModes = prompts;\n            }\n            else\n            {\n                _logger.LogDebug(\"Unsupported prompt mode - ignored: \" + prompt);\n            }\n        }\n\n        //////////////////////////////////////////////////////////\n        // check ui locales\n        //////////////////////////////////////////////////////////\n        var uilocales = request.Raw.Get(OidcConstants.AuthorizeRequest.UiLocales);\n        if (uilocales.IsPresent())\n        {\n            if (uilocales.Length > _options.InputLengthRestrictions.UiLocale)\n            {\n                LogError(\"UI locale too long\", request);\n                return Invalid(request, description: \"Invalid ui_locales\");\n            }\n\n            request.UiLocales = uilocales;\n        }\n\n        //////////////////////////////////////////////////////////\n        // check display\n        //////////////////////////////////////////////////////////\n        var display = request.Raw.Get(OidcConstants.AuthorizeRequest.Display);\n        if (display.IsPresent())\n        {\n            if (Constants.SupportedDisplayModes.Contains(display))\n            {\n                request.DisplayMode = display;\n            }\n\n            _logger.LogDebug(\"Unsupported display mode - ignored: \" + display);\n        }\n\n        //////////////////////////////////////////////////////////\n        // check max_age\n        //////////////////////////////////////////////////////////\n        var maxAge = request.Raw.Get(OidcConstants.AuthorizeRequest.MaxAge);\n        if (maxAge.IsPresent())\n        {\n            if (int.TryParse(maxAge, out var seconds))\n            {\n                if (seconds >= 0)\n                {\n                    request.MaxAge = seconds;\n                }\n                else\n                {\n                    LogError(\"Invalid max_age.\", request);\n                    return Invalid(request, description: \"Invalid max_age\");\n                }\n            }\n            else\n            {\n                LogError(\"Invalid max_age.\", request);\n                return Invalid(request, description: \"Invalid max_age\");\n            }\n        }\n\n        //////////////////////////////////////////////////////////\n        // check login_hint\n        //////////////////////////////////////////////////////////\n        var loginHint = request.Raw.Get(OidcConstants.AuthorizeRequest.LoginHint);\n        if (loginHint.IsPresent())\n        {\n            if (loginHint.Length > _options.InputLengthRestrictions.LoginHint)\n            {\n                LogError(\"Login hint too long\", request);\n                return Invalid(request, description: \"Invalid login_hint\");\n            }\n\n            request.LoginHint = loginHint;\n        }\n\n        //////////////////////////////////////////////////////////\n        // check acr_values\n        //////////////////////////////////////////////////////////\n        var acrValues = request.Raw.Get(OidcConstants.AuthorizeRequest.AcrValues);\n        if (acrValues.IsPresent())\n        {\n            if (acrValues.Length > _options.InputLengthRestrictions.AcrValues)\n            {\n                LogError(\"Acr values too long\", request);\n                return Invalid(request, description: \"Invalid acr_values\");\n            }\n\n            request.AuthenticationContextReferenceClasses = acrValues.FromSpaceSeparatedString().Distinct().ToList();\n        }\n\n        //////////////////////////////////////////////////////////\n        // check custom acr_values: idp\n        //////////////////////////////////////////////////////////\n        var idp = request.GetIdP();\n        if (idp.IsPresent())\n        {\n            // if idp is present but client does not allow it, strip it from the request message\n            if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any())\n            {\n                if (!request.Client.IdentityProviderRestrictions.Contains(idp))\n                {\n                    _logger.LogWarning(\"idp requested ({idp}) is not in client restriction list.\", idp);\n                    request.RemoveIdP();\n                }\n            }\n        }\n\n        //////////////////////////////////////////////////////////\n        // check session cookie\n        //////////////////////////////////////////////////////////\n        if (_options.Endpoints.EnableCheckSessionEndpoint)\n        {\n            if (request.Subject.IsAuthenticated())\n            {\n                var sessionId = await _userSession.GetSessionIdAsync();\n                if (sessionId.IsPresent())\n                {\n                    request.SessionId = sessionId;\n                }\n                else\n                {\n                    LogError(\"Check session endpoint enabled, but SessionId is missing\", request);\n                }\n            }\n            else\n            {\n                request.SessionId = \"\"; // empty string for anonymous users\n            }\n        }\n\n        return Valid(request);\n    }\n\n    private AuthorizeRequestValidationResult Invalid(ValidatedAuthorizeRequest request, string error = OidcConstants.AuthorizeErrors.InvalidRequest, string description = null)\n    {\n        return new AuthorizeRequestValidationResult(request, error, description);\n    }\n\n    private AuthorizeRequestValidationResult Valid(ValidatedAuthorizeRequest request)\n    {\n        return new AuthorizeRequestValidationResult(request);\n    }\n\n    private void LogError(string message, ValidatedAuthorizeRequest request)\n    {\n        var requestDetails = new AuthorizeRequestValidationLog(request, _options.Logging.AuthorizeRequestSensitiveValuesFilter);\n        _logger.LogError(message + \"\\n{@requestDetails}\", requestDetails);\n    }\n\n    private void LogError(string message, string detail, ValidatedAuthorizeRequest request)\n    {\n        var requestDetails = new AuthorizeRequestValidationLog(request, _options.Logging.AuthorizeRequestSensitiveValuesFilter);\n        _logger.LogError(message + \": {detail}\\n{@requestDetails}\", detail, requestDetails);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/BasicAuthenticationSecretParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Parses a Basic Authentication header\n/// </summary>\npublic class BasicAuthenticationSecretParser : ISecretParser\n{\n    private readonly ILogger _logger;\n    private readonly IdentityServerOptions _options;\n\n    /// <summary>\n    /// Creates the parser with a reference to identity server options\n    /// </summary>\n    /// <param name=\"options\">IdentityServer options</param>\n    /// <param name=\"logger\">The logger</param>\n    public BasicAuthenticationSecretParser(IdentityServerOptions options, ILogger<BasicAuthenticationSecretParser> logger)\n    {\n        _options = options;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Returns the authentication method name that this parser implements\n    /// </summary>\n    /// <value>\n    /// The authentication method.\n    /// </value>\n    public string AuthenticationMethod => OidcConstants.EndpointAuthenticationMethods.BasicAuthentication;\n\n    /// <summary>\n    /// Tries to find a secret that can be used for authentication\n    /// </summary>\n    /// <returns>\n    /// A parsed secret\n    /// </returns>\n    public Task<ParsedSecret> ParseAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start parsing Basic Authentication secret\");\n\n        var notfound = Task.FromResult<ParsedSecret>(null);\n        var authorizationHeader = context.Request.Headers[\"Authorization\"].FirstOrDefault();\n\n        if (authorizationHeader.IsMissing())\n        {\n            return notfound;\n        }\n\n        if (!authorizationHeader.StartsWith(\"Basic \", StringComparison.OrdinalIgnoreCase))\n        {\n            return notfound;\n        }\n\n        var parameter = authorizationHeader.Substring(\"Basic \".Length);\n\n        string pair;\n        try\n        {\n            pair = Encoding.UTF8.GetString(\n                Convert.FromBase64String(parameter));\n        }\n        catch (FormatException)\n        {\n            _logger.LogWarning(\"Malformed Basic Authentication credential.\");\n            return notfound;\n        }\n        catch (ArgumentException)\n        {\n            _logger.LogWarning(\"Malformed Basic Authentication credential.\");\n            return notfound;\n        }\n\n        var ix = pair.IndexOf(':');\n        if (ix == -1)\n        {\n            _logger.LogWarning(\"Malformed Basic Authentication credential.\");\n            return notfound;\n        }\n\n        var clientId = pair.Substring(0, ix);\n        var secret = pair.Substring(ix + 1);\n\n        if (clientId.IsPresent())\n        {\n            if (clientId.Length > _options.InputLengthRestrictions.ClientId)\n            {\n                _logger.LogError(\"Client ID exceeds maximum length.\");\n                return notfound;\n            }\n\n            if (secret.IsPresent())\n            {\n                if (secret.Length > _options.InputLengthRestrictions.ClientSecret)\n                {\n                    _logger.LogError(\"Client secret exceeds maximum length.\");\n                    return notfound;\n                }\n\n                var parsedSecret = new ParsedSecret\n                {\n                    Id = Decode(clientId),\n                    Credential = Decode(secret),\n                    Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n                };\n\n                return Task.FromResult(parsedSecret);\n            }\n            else\n            {\n                // client secret is optional\n                _logger.LogDebug(\"client id without secret found\");\n\n                var parsedSecret = new ParsedSecret\n                {\n                    Id = Decode(clientId),\n                    Type = IdentityServerConstants.ParsedSecretTypes.NoSecret\n                };\n\n                return Task.FromResult(parsedSecret);\n            }\n        }\n\n        _logger.LogDebug(\"No Basic Authentication secret found\");\n        return notfound;\n    }\n\n    // RFC6749 says individual values must be application/x-www-form-urlencoded\n    // 2.3.1\n    private string Decode(string value)\n    {\n        if (value.IsMissing()) return string.Empty;\n\n        return Uri.UnescapeDataString(value.Replace(\"+\", \"%20\"));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/BearerTokenUsageValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates a request that uses a bearer token for authentication\n/// </summary>\ninternal class BearerTokenUsageValidator\n{\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"BearerTokenUsageValidator\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public BearerTokenUsageValidator(ILogger<BearerTokenUsageValidator> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public async Task<BearerTokenUsageValidationResult> ValidateAsync(HttpContext context)\n    {\n        var result = ValidateAuthorizationHeader(context);\n        if (result.TokenFound)\n        {\n            _logger.LogDebug(\"Bearer token found in header\");\n            return result;\n        }\n\n        if (context.Request.HasApplicationFormContentType())\n        {\n            result = await ValidatePostBodyAsync(context);\n            if (result.TokenFound)\n            {\n                _logger.LogDebug(\"Bearer token found in body\");\n                return result;\n            }\n        }\n\n        _logger.LogDebug(\"Bearer token not found\");\n        return new BearerTokenUsageValidationResult();\n    }\n\n    /// <summary>\n    /// Validates the authorization header.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public BearerTokenUsageValidationResult ValidateAuthorizationHeader(HttpContext context)\n    {\n        var authorizationHeader = context.Request.Headers[\"Authorization\"].FirstOrDefault();\n        if (authorizationHeader.IsPresent())\n        {\n            var header = authorizationHeader.Trim();\n            if (header.StartsWith(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer))\n            {\n                var value = header.Substring(OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer.Length).Trim();\n                if (value.IsPresent())\n                {\n                    return new BearerTokenUsageValidationResult\n                    {\n                        TokenFound = true,\n                        Token = value,\n                        UsageType = BearerTokenUsageType.AuthorizationHeader\n                    };\n                }\n            }\n            else\n            {\n                _logger.LogTrace(\"Unexpected header format: {header}\", Ioc.Sanitizer.Log.Sanitize(header));\n            }\n        }\n\n        return new BearerTokenUsageValidationResult();\n    }\n\n    /// <summary>\n    /// Validates the post body.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public async Task<BearerTokenUsageValidationResult> ValidatePostBodyAsync(HttpContext context)\n    {\n        var token = (await context.Request.ReadFormAsync())[\"access_token\"].FirstOrDefault();\n        if (token.IsPresent())\n        {\n            return new BearerTokenUsageValidationResult\n            {\n                TokenFound = true,\n                Token = token,\n                UsageType = BearerTokenUsageType.PostBody\n            };\n        }\n\n        return new BearerTokenUsageValidationResult();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/ClientSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates a client secret using the registered secret validators and parsers\n/// </summary>\npublic class ClientSecretValidator : IClientSecretValidator\n{\n    private readonly ILogger _logger;\n    private readonly IClientStore _clients;\n    private readonly IEventService _events;\n    private readonly ISecretsListValidator _validator;\n    private readonly ISecretsListParser _parser;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ClientSecretValidator\"/> class.\n    /// </summary>\n    /// <param name=\"clients\">The clients.</param>\n    /// <param name=\"parser\">The parser.</param>\n    /// <param name=\"validator\">The validator.</param>\n    /// <param name=\"events\">The events.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public ClientSecretValidator(IClientStore clients, ISecretsListParser parser, ISecretsListValidator validator, IEventService events, ILogger<ClientSecretValidator> logger)\n    {\n        _clients = clients;\n        _parser = parser;\n        _validator = validator;\n        _events = events;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the current request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public async Task<ClientSecretValidationResult> ValidateAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start client validation\");\n\n        var fail = new ClientSecretValidationResult\n        {\n            IsError = true\n        };\n\n        var parsedSecret = await _parser.ParseAsync(context);\n        if (parsedSecret == null)\n        {\n            await RaiseFailureEventAsync(\"unknown\", \"No client id found\");\n\n            _logger.LogError(\"No client identifier found\");\n            return fail;\n        }\n\n        // load client\n        var client = await _clients.FindEnabledClientByIdAsync(parsedSecret.Id);\n        if (client == null)\n        {\n            await RaiseFailureEventAsync(parsedSecret.Id, \"Unknown client\");\n\n            _logger.LogError(\"No client with id '{clientId}' found. aborting\", Ioc.Sanitizer.Log.Sanitize(parsedSecret.Id));\n            return fail;\n        }\n\n        SecretValidationResult secretValidationResult = null;\n        if (!client.RequireClientSecret || client.IsImplicitOnly())\n        {\n            _logger.LogDebug(\"Public Client - skipping secret validation success\");\n        }\n        else\n        {\n            secretValidationResult = await _validator.ValidateAsync(client.ClientSecrets, parsedSecret);\n            if (secretValidationResult.Success == false)\n            {\n                await RaiseFailureEventAsync(client.ClientId, \"Invalid client secret\");\n                _logger.LogError(\"Client secret validation failed for client: {clientId}.\", client.ClientId);\n\n                return fail;\n            }\n        }\n\n        _logger.LogDebug(\"Client validation success\");\n\n        var success = new ClientSecretValidationResult\n        {\n            IsError = false,\n            Client = client,\n            Secret = parsedSecret,\n            Confirmation = secretValidationResult?.Confirmation\n        };\n\n        await RaiseSuccessEventAsync(client.ClientId, parsedSecret.Type);\n        return success;\n    }\n\n    private Task RaiseSuccessEventAsync(string clientId, string authMethod)\n    {\n        return _events.RaiseAsync(new ClientAuthenticationSuccessEvent(clientId, authMethod));\n    }\n\n    private Task RaiseFailureEventAsync(string clientId, string message)\n    {\n        return _events.RaiseAsync(new ClientAuthenticationFailureEvent(clientId, message));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DefaultClientConfigurationValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default client configuration validator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.IClientConfigurationValidator\" />\npublic class DefaultClientConfigurationValidator : IClientConfigurationValidator\n{\n    private readonly IdentityServerOptions _options;\n\n    /// <summary>\n    /// Constructor for DefaultClientConfigurationValidator\n    /// </summary>\n    public DefaultClientConfigurationValidator(IdentityServerOptions options)\n    {\n        _options = options;\n    }\n\n    /// <summary>\n    /// Determines whether the configuration of a client is valid.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public async Task ValidateAsync(ClientConfigurationValidationContext context)\n    {\n        if (context.Client.ProtocolType == IdentityServerConstants.ProtocolTypes.OpenIdConnect)\n        {\n            await ValidateGrantTypesAsync(context);\n            if (context.IsValid == false) return;\n\n            await ValidateLifetimesAsync(context);\n            if (context.IsValid == false) return;\n\n            await ValidateRedirectUriAsync(context);\n            if (context.IsValid == false) return;\n\n            await ValidateAllowedCorsOriginsAsync(context);\n            if (context.IsValid == false) return;\n\n            await ValidateUriSchemesAsync(context);\n            if (context.IsValid == false) return;\n\n            await ValidateSecretsAsync(context);\n            if (context.IsValid == false) return;\n\n            await ValidatePropertiesAsync(context);\n            if (context.IsValid == false) return;\n        }\n    }\n\n    /// <summary>\n    /// Validates grant type related configuration settings.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    protected virtual Task ValidateGrantTypesAsync(ClientConfigurationValidationContext context)\n    {\n        if (context.Client.AllowedGrantTypes?.Any() != true)\n        {\n            context.SetError(\"no allowed grant type specified\");\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Validates lifetime related configuration settings.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    protected virtual Task ValidateLifetimesAsync(ClientConfigurationValidationContext context)\n    {\n        if (context.Client.AccessTokenLifetime <= 0)\n        {\n            context.SetError(\"access token lifetime is 0 or negative\");\n            return Task.CompletedTask;\n        }\n\n        if (context.Client.IdentityTokenLifetime <= 0)\n        {\n            context.SetError(\"identity token lifetime is 0 or negative\");\n            return Task.CompletedTask;\n        }\n\n        if (context.Client.AllowedGrantTypes?.Contains(GrantType.DeviceFlow) == true\n            && context.Client.DeviceCodeLifetime <= 0)\n        {\n            context.SetError(\"device code lifetime is 0 or negative\");\n        }\n\n        // 0 means unlimited lifetime\n        if (context.Client.AbsoluteRefreshTokenLifetime < 0)\n        {\n            context.SetError(\"absolute refresh token lifetime is negative\");\n            return Task.CompletedTask;\n        }\n\n        // 0 might mean that sliding is disabled\n        if (context.Client.SlidingRefreshTokenLifetime < 0)\n        {\n            context.SetError(\"sliding refresh token lifetime is negative\");\n            return Task.CompletedTask;\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Validates redirect URI related configuration.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    protected virtual Task ValidateRedirectUriAsync(ClientConfigurationValidationContext context)\n    {\n        if (context.Client.AllowedGrantTypes?.Any() == true)\n        {\n            if (context.Client.AllowedGrantTypes.Contains(GrantType.AuthorizationCode) ||\n                context.Client.AllowedGrantTypes.Contains(GrantType.Hybrid) ||\n                context.Client.AllowedGrantTypes.Contains(GrantType.Implicit))\n            {\n                if (context.Client.RedirectUris?.Any() == false)\n                {\n                    context.SetError(\"No redirect URI configured.\");\n                }\n            }\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Validates allowed CORS origins for valid format.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    protected virtual Task ValidateAllowedCorsOriginsAsync(ClientConfigurationValidationContext context)\n    {\n        if (context.Client.AllowedCorsOrigins?.Any() == true)\n        {\n            foreach (var origin in context.Client.AllowedCorsOrigins)\n            {\n                var fail = true;\n\n                if (!string.IsNullOrWhiteSpace(origin) && Uri.TryCreate(origin, UriKind.Absolute, out var uri))\n                {\n                    if (uri.AbsolutePath == \"/\" && !origin.EndsWith(\"/\"))\n                    {\n                        fail = false;\n                    }\n                }\n\n                if (fail)\n                {\n                    if (!string.IsNullOrWhiteSpace(origin))\n                    {\n                        context.SetError($\"AllowedCorsOrigins contains invalid origin: {origin}\");\n                    }\n                    else\n                    {\n                        context.SetError($\"AllowedCorsOrigins contains invalid origin. There is an empty value.\");\n                    }\n                    return Task.CompletedTask;\n                }\n            }\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Validates that URI schemes is not in the list of invalid URI scheme prefixes, as controlled by the ValidationOptions.\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <returns></returns>\n    protected virtual Task ValidateUriSchemesAsync(ClientConfigurationValidationContext context)\n    {\n        if (context.Client.RedirectUris?.Any() == true)\n        {\n            foreach (var uri in context.Client.RedirectUris)\n            {\n                if (_options.Validation.InvalidRedirectUriPrefixes\n                        .Any(scheme => uri?.StartsWith(scheme, StringComparison.OrdinalIgnoreCase) == true))\n                {\n                    context.SetError($\"RedirectUri '{uri}' uses invalid scheme. If this scheme should be allowed, then configure it via ValidationOptions.\");\n                }\n            }\n        }\n\n        if (context.Client.PostLogoutRedirectUris?.Any() == true)\n        {\n            foreach (var uri in context.Client.PostLogoutRedirectUris)\n            {\n                if (_options.Validation.InvalidRedirectUriPrefixes\n                        .Any(scheme => uri?.StartsWith(scheme, StringComparison.OrdinalIgnoreCase) == true))\n                {\n                    context.SetError($\"PostLogoutRedirectUri '{uri}' uses invalid scheme. If this scheme should be allowed, then configure it via ValidationOptions.\");\n                }\n            }\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Validates secret related configuration.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    protected virtual Task ValidateSecretsAsync(ClientConfigurationValidationContext context)\n    {\n        if (context.Client.AllowedGrantTypes?.Any() == true)\n        {\n            foreach (var grantType in context.Client.AllowedGrantTypes)\n            {\n                if (!string.Equals(grantType, GrantType.Implicit))\n                {\n                    if (context.Client.RequireClientSecret && context.Client.ClientSecrets.Count == 0)\n                    {\n                        context.SetError($\"Client secret is required for {grantType}, but no client secret is configured.\");\n                        return Task.CompletedTask;\n                    }\n                }\n            }\n        }\n\n        return Task.CompletedTask;\n    }\n\n    /// <summary>\n    /// Validates properties related configuration settings.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    protected virtual Task ValidatePropertiesAsync(ClientConfigurationValidationContext context)\n    {\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DefaultCustomAuthorizeRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default custom request validator\n/// </summary>\ninternal class DefaultCustomAuthorizeRequestValidator : ICustomAuthorizeRequestValidator\n{\n    /// <summary>\n    /// Custom validation logic for the authorize request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)\n    {\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DefaultCustomTokenRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default custom request validator\n/// </summary>\ninternal class DefaultCustomTokenRequestValidator : ICustomTokenRequestValidator\n{\n    /// <summary>\n    /// Custom validation logic for a token request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns>\n    /// The validation result\n    /// </returns>\n    public Task ValidateAsync(CustomTokenRequestValidationContext context)\n    {\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DefaultCustomTokenValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default custom token validator\n/// </summary>\npublic class DefaultCustomTokenValidator : ICustomTokenValidator\n{\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    /// The user service\n    /// </summary>\n    protected readonly IProfileService Profile;\n\n    /// <summary>\n    /// The client store\n    /// </summary>\n    protected readonly IClientStore Clients;\n\n    /// <summary>\n    /// Custom validation logic for access tokens.\n    /// </summary>\n    /// <param name=\"result\">The validation result so far.</param>\n    /// <returns>\n    /// The validation result\n    /// </returns>\n    public virtual Task<TokenValidationResult> ValidateAccessTokenAsync(TokenValidationResult result)\n    {\n        return Task.FromResult(result);\n    }\n\n    /// <summary>\n    /// Custom validation logic for identity tokens.\n    /// </summary>\n    /// <param name=\"result\">The validation result so far.</param>\n    /// <returns>\n    /// The validation result\n    /// </returns>\n    public virtual Task<TokenValidationResult> ValidateIdentityTokenAsync(TokenValidationResult result)\n    {\n        return Task.FromResult(result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DefaultResourceValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default implementation of IResourceValidator.\n/// </summary>\npublic class DefaultResourceValidator : IResourceValidator\n{\n    private readonly ILogger _logger;\n    private readonly IScopeParser _scopeParser;\n    private readonly IResourceStore _store;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DefaultResourceValidator\"/> class.\n    /// </summary>\n    /// <param name=\"store\">The store.</param>\n    /// <param name=\"scopeParser\"></param>\n    /// <param name=\"logger\">The logger.</param>\n    public DefaultResourceValidator(IResourceStore store, IScopeParser scopeParser, ILogger<DefaultResourceValidator> logger)\n    {\n        _logger = logger;\n        _scopeParser = scopeParser;\n        _store = store;\n    }\n\n    /// <inheritdoc/>\n    public virtual async Task<ResourceValidationResult> ValidateRequestedResourcesAsync(ResourceValidationRequest request)\n    {\n        if (request == null) throw new ArgumentNullException(nameof(request));\n\n        var parsedScopesResult = _scopeParser.ParseScopeValues(request.Scopes);\n\n        var result = new ResourceValidationResult();\n        \n        if (!parsedScopesResult.Succeeded)\n        {\n            foreach (var invalidScope in parsedScopesResult.Errors)\n            {\n                _logger.LogError(\"Invalid parsed scope {scope}, message: {error}\", Ioc.Sanitizer.Log.Sanitize(invalidScope.RawValue), Ioc.Sanitizer.Log.Sanitize(invalidScope.Error));\n                result.InvalidScopes.Add(invalidScope.RawValue);\n            }\n\n            return result;\n        }\n\n        var scopeNames = parsedScopesResult.ParsedScopes.Select(x => x.ParsedName).Distinct().ToArray();\n        var resourcesFromStore = await _store.FindEnabledResourcesByScopeAsync(scopeNames);\n\n        foreach (var scope in parsedScopesResult.ParsedScopes)\n        {\n            await ValidateScopeAsync(request.Client, resourcesFromStore, scope, result);\n        }\n\n        if (result.InvalidScopes.Count > 0)\n        {\n            result.Resources.IdentityResources.Clear();\n            result.Resources.ApiResources.Clear();\n            result.Resources.ApiScopes.Clear();\n            result.ParsedScopes.Clear();\n        }\n\n        return result;\n    }\n\n    /// <summary>\n    /// Validates that the requested scopes is contained in the store, and the client is allowed to request it.\n    /// </summary>\n    /// <param name=\"client\"></param>\n    /// <param name=\"resourcesFromStore\"></param>\n    /// <param name=\"requestedScope\"></param>\n    /// <param name=\"result\"></param>\n    /// <returns></returns>\n    protected virtual async Task ValidateScopeAsync(\n        Client client, \n        Resources resourcesFromStore, \n        ParsedScopeValue requestedScope, \n        ResourceValidationResult result)\n    {\n        if (requestedScope.ParsedName == IdentityServerConstants.StandardScopes.OfflineAccess)\n        {\n            if (await IsClientAllowedOfflineAccessAsync(client))\n            {\n                result.Resources.OfflineAccess = true;\n                result.ParsedScopes.Add(new ParsedScopeValue(IdentityServerConstants.StandardScopes.OfflineAccess));\n            }\n            else\n            {\n                result.InvalidScopes.Add(IdentityServerConstants.StandardScopes.OfflineAccess);\n            }\n        }\n        else\n        {\n            var identity = resourcesFromStore.FindIdentityResourcesByScope(requestedScope.ParsedName);\n            if (identity != null)\n            {\n                if (await IsClientAllowedIdentityResourceAsync(client, identity))\n                {\n                    result.ParsedScopes.Add(requestedScope);\n                    result.Resources.IdentityResources.Add(identity);\n                }\n                else\n                {\n                    result.InvalidScopes.Add(requestedScope.RawValue);\n                }\n            }\n            else\n            {\n                var apiScope = resourcesFromStore.FindApiScope(requestedScope.ParsedName);\n                if (apiScope != null)\n                {\n                    if (await IsClientAllowedApiScopeAsync(client, apiScope))\n                    {\n                        result.ParsedScopes.Add(requestedScope);\n                        result.Resources.ApiScopes.Add(apiScope);\n\n                        var apis = resourcesFromStore.FindApiResourcesByScope(apiScope.Name);\n                        foreach (var api in apis)\n                        {\n                            result.Resources.ApiResources.Add(api);\n                        }\n                    }\n                    else\n                    {\n                        result.InvalidScopes.Add(requestedScope.RawValue);\n                    }\n                }\n                else\n                {\n                    _logger.LogError(\"Scope {scope} not found in store.\", requestedScope.ParsedName);\n                    result.InvalidScopes.Add(requestedScope.RawValue);\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    /// Determines if client is allowed access to the identity scope.\n    /// </summary>\n    /// <param name=\"client\"></param>\n    /// <param name=\"identity\"></param>\n    /// <returns></returns>\n    protected virtual Task<bool> IsClientAllowedIdentityResourceAsync(Client client, IdentityResource identity)\n    {\n        var allowed = client.AllowedScopes.Contains(identity.Name);\n        if (!allowed)\n        {\n            _logger.LogError(\"Client {client} is not allowed access to scope {scope}.\", client.ClientId, identity.Name);\n        }\n        return Task.FromResult(allowed);\n    }\n\n    /// <summary>\n    /// Determines if client is allowed access to the API scope.\n    /// </summary>\n    /// <param name=\"client\"></param>\n    /// <param name=\"apiScope\"></param>\n    /// <returns></returns>\n    protected virtual Task<bool> IsClientAllowedApiScopeAsync(Client client, ApiScope apiScope)\n    {\n        var allowed = client.AllowedScopes.Contains(apiScope.Name);\n        if (!allowed)\n        {\n            _logger.LogError(\"Client {client} is not allowed access to scope {scope}.\", client.ClientId, apiScope.Name);\n        }\n        return Task.FromResult(allowed);\n    }\n\n    /// <summary>\n    /// Validates if the client is allowed offline_access.\n    /// </summary>\n    /// <param name=\"client\"></param>\n    /// <returns></returns>\n    protected virtual Task<bool> IsClientAllowedOfflineAccessAsync(Client client)\n    {\n        var allowed = client.AllowOfflineAccess;\n        if (!allowed)\n        {\n            _logger.LogError(\"Client {client} is not allowed access to scope offline_access (via AllowOfflineAccess setting).\", client.ClientId);\n        }\n        return Task.FromResult(allowed);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DefaultScopeParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default implementation of IScopeParser.\n/// </summary>\npublic class DefaultScopeParser : IScopeParser\n{\n    private readonly ILogger<DefaultScopeParser> _logger;\n\n    /// <summary>\n    /// Ctor.\n    /// </summary>\n    /// <param name=\"logger\"></param>\n    public DefaultScopeParser(ILogger<DefaultScopeParser> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <inheritdoc/>\n    public ParsedScopesResult ParseScopeValues(IEnumerable<string> scopeValues)\n    {\n        if (scopeValues == null) throw new ArgumentNullException(nameof(scopeValues));\n\n        var result = new ParsedScopesResult();\n\n        foreach (var scopeValue in scopeValues)\n        {\n            var ctx = new ParseScopeContext(scopeValue);\n            ParseScopeValue(ctx);\n            \n            if (ctx.Succeeded)\n            {\n                var parsedScope = ctx.ParsedName != null ?\n                    new ParsedScopeValue(ctx.RawValue, ctx.ParsedName, ctx.ParsedParameter) :\n                    new ParsedScopeValue(ctx.RawValue);\n\n                result.ParsedScopes.Add(parsedScope);\n            }\n            else if (!ctx.Ignore)\n            {\n                result.Errors.Add(new ParsedScopeValidationError(scopeValue, ctx.Error));\n            }\n            else\n            {\n                _logger.LogDebug(\"Scope parsing ignoring scope {scope}\", Ioc.Sanitizer.Log.Sanitize(scopeValue));\n            }\n        }\n\n        return result;\n    }\n\n    /// <summary>\n    /// Parses a scope value.\n    /// </summary>\n    /// <param name=\"scopeContext\"></param>\n    /// <returns></returns>\n    public virtual void ParseScopeValue(ParseScopeContext scopeContext)\n    {\n        // nop leaves the raw scope value as a success result.\n    }\n\n    /// <summary>\n    /// Models the context for parsing a scope.\n    /// </summary>\n    public class ParseScopeContext\n    {\n        /// <summary>\n        /// The original (raw) value of the scope.\n        /// </summary>\n        public string RawValue { get; }\n\n        /// <summary>\n        /// The parsed name of the scope. \n        /// </summary>\n        public string ParsedName { get; private set; }\n\n        /// <summary>\n        /// The parsed parameter value of the scope. \n        /// </summary>\n        public string ParsedParameter { get; private set; }\n\n        /// <summary>\n        /// The error encountered parsing the scope.\n        /// </summary>\n        public string Error { get; private set; }\n        \n        /// <summary>\n        /// Indicates if the scope should be excluded from the parsed results.\n        /// </summary>\n        public bool Ignore { get; private set; }\n\n        /// <summary>\n        /// Indicates if parsing the scope was successful.\n        /// </summary>\n        public bool Succeeded => !Ignore && Error == null;\n\n\n        /// <summary>\n        /// Ctor. Indicates success, but the scope should not be included in result.\n        /// </summary>\n        internal ParseScopeContext(string rawScopeValue)\n        {\n            RawValue = rawScopeValue;\n        }\n\n        /// <summary>\n        /// Sets the parsed name and parsed parameter value for the scope.\n        /// </summary>\n        /// <param name=\"parsedName\"></param>\n        /// <param name=\"parsedParameter\"></param>\n        public void SetParsedValues(string parsedName, string parsedParameter)\n        {\n            if (String.IsNullOrWhiteSpace(parsedName))\n            {\n                throw new ArgumentNullException(nameof(parsedName));\n            }\n            if (String.IsNullOrWhiteSpace(parsedParameter))\n            {\n                throw new ArgumentNullException(nameof(parsedParameter));\n            }\n\n            ParsedName = parsedName;\n            ParsedParameter = parsedParameter;\n            Error = null;\n            Ignore = false;\n        }\n\n        /// <summary>\n        /// Set the error encountered parsing the scope.\n        /// </summary>\n        /// <param name=\"error\"></param>\n        public void SetError(string error)\n        {\n            ParsedName = null;\n            ParsedParameter = null;\n            Error = error;\n            Ignore = false;\n        }\n\n        /// <summary>\n        /// Sets that the scope is to be ignore/excluded from the parsed results.\n        /// </summary>\n        public void SetIgnore()\n        {\n            ParsedName = null;\n            ParsedParameter = null;\n            Error = null;\n            Ignore = true;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DeviceAuthorizationRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\ninternal class DeviceAuthorizationRequestValidator : IDeviceAuthorizationRequestValidator\n{\n    private readonly IdentityServerOptions _options;\n    private readonly IResourceValidator _resourceValidator;\n    private readonly ILogger<DeviceAuthorizationRequestValidator> _logger;\n    \n    public DeviceAuthorizationRequestValidator(\n        IdentityServerOptions options,\n        IResourceValidator resourceValidator,\n        ILogger<DeviceAuthorizationRequestValidator> logger)\n    {\n        _options = options;\n        _resourceValidator = resourceValidator;\n        _logger = logger;\n    }\n\n    public async Task<DeviceAuthorizationRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult)\n    {\n        _logger.LogDebug(\"Start device authorization request validation\");\n\n        var request = new ValidatedDeviceAuthorizationRequest\n        {\n            Raw = parameters ?? throw new ArgumentNullException(nameof(parameters)),\n            Options = _options\n        };\n\n        var clientResult = ValidateClient(request, clientValidationResult);\n        if (clientResult.IsError)\n        {\n            return clientResult;\n        }\n\n        var scopeResult = await ValidateScopeAsync(request);\n        if (scopeResult.IsError)\n        {\n            return scopeResult;\n        }\n\n        _logger.LogDebug(\"{clientId} device authorization request validation success\", request.Client.ClientId);\n        return Valid(request);\n    }\n\n    private DeviceAuthorizationRequestValidationResult Valid(ValidatedDeviceAuthorizationRequest request)\n    {\n        return new DeviceAuthorizationRequestValidationResult(request);\n    }\n\n    private DeviceAuthorizationRequestValidationResult Invalid(ValidatedDeviceAuthorizationRequest request, string error = OidcConstants.AuthorizeErrors.InvalidRequest, string description = null)\n    {\n        return new DeviceAuthorizationRequestValidationResult(request, error, description);\n    }\n\n    private void LogError(string message, ValidatedDeviceAuthorizationRequest request)\n    {\n        var requestDetails = new DeviceAuthorizationRequestValidationLog(request);\n        _logger.LogError(message + \"\\n{requestDetails}\", requestDetails);\n    }\n\n    private void LogError(string message, string detail, ValidatedDeviceAuthorizationRequest request)\n    {\n        var requestDetails = new DeviceAuthorizationRequestValidationLog(request);\n        _logger.LogError(message + \": {detail}\\n{requestDetails}\", detail, requestDetails);\n    }\n\n    private DeviceAuthorizationRequestValidationResult ValidateClient(ValidatedDeviceAuthorizationRequest request, ClientSecretValidationResult clientValidationResult)\n    {\n        //////////////////////////////////////////////////////////\n        // set client & secret\n        //////////////////////////////////////////////////////////\n        if (clientValidationResult == null) throw new ArgumentNullException(nameof(clientValidationResult));\n        request.SetClient(clientValidationResult.Client, clientValidationResult.Secret);\n\n        //////////////////////////////////////////////////////////\n        // check if client protocol type is oidc\n        //////////////////////////////////////////////////////////\n        if (request.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect)\n        {\n            LogError(\"Invalid protocol type for OIDC authorize endpoint\", request.Client.ProtocolType, request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, \"Invalid protocol\");\n        }\n\n        //////////////////////////////////////////////////////////\n        // check if client allows device flow\n        //////////////////////////////////////////////////////////\n        if (!request.Client.AllowedGrantTypes.Contains(GrantType.DeviceFlow))\n        {\n            LogError(\"Client not configured for device flow\", GrantType.DeviceFlow, request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        }\n\n        return Valid(request);\n    }\n\n    private async Task<DeviceAuthorizationRequestValidationResult> ValidateScopeAsync(ValidatedDeviceAuthorizationRequest request)\n    {\n        //////////////////////////////////////////////////////////\n        // scope must be present\n        //////////////////////////////////////////////////////////\n        var scope = request.Raw.Get(OidcConstants.AuthorizeRequest.Scope);\n        if (scope.IsMissing())\n        {\n            _logger.LogTrace(\"Client provided no scopes - checking allowed scopes list\");\n\n            if (!request.Client.AllowedScopes.EnumerableIsNullOrEmpty())\n            {\n                var clientAllowedScopes = new List<string>(request.Client.AllowedScopes);\n                if (request.Client.AllowOfflineAccess)\n                {\n                    clientAllowedScopes.Add(IdentityServerConstants.StandardScopes.OfflineAccess);\n                }\n                scope = clientAllowedScopes.ToSpaceSeparatedString();\n                _logger.LogTrace(\"Defaulting to: {scopes}\", scope);\n            }\n            else\n            {\n                LogError(\"No allowed scopes configured for client\", request);\n                return Invalid(request, OidcConstants.AuthorizeErrors.InvalidScope);\n            }\n        }\n\n        if (scope.Length > _options.InputLengthRestrictions.Scope)\n        {\n            LogError(\"scopes too long.\", request);\n            return Invalid(request, description: \"Invalid scope\");\n        }\n\n        request.RequestedScopes = scope.FromSpaceSeparatedString().Distinct().ToList();\n\n        if (request.RequestedScopes.Contains(IdentityServerConstants.StandardScopes.OpenId))\n        {\n            request.IsOpenIdRequest = true;\n        }\n\n        //////////////////////////////////////////////////////////\n        // check if scopes are valid/supported\n        //////////////////////////////////////////////////////////\n        var validatedResources = await _resourceValidator.ValidateRequestedResourcesAsync(new ResourceValidationRequest{\n            Client = request.Client, \n            Scopes = request.RequestedScopes\n        });\n\n        if (!validatedResources.Succeeded)\n        {\n            if (validatedResources.InvalidScopes.Count > 0)\n            {\n                return Invalid(request, OidcConstants.AuthorizeErrors.InvalidScope);\n            }\n            \n            return Invalid(request, OidcConstants.AuthorizeErrors.UnauthorizedClient, \"Invalid scope\");\n        }\n\n        if (validatedResources.Resources.IdentityResources.Any() && !request.IsOpenIdRequest)\n        {\n            LogError(\"Identity related scope requests, but no openid scope\", request);\n            return Invalid(request, OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n\n        request.ValidatedResources = validatedResources;\n        \n        return Valid(request);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/DeviceCodeValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates an incoming token request using the device flow\n/// </summary>\ninternal class DeviceCodeValidator : IDeviceCodeValidator\n{\n    private readonly IDeviceFlowCodeService _devices;\n    private readonly IProfileService _profile;\n    private readonly IDeviceFlowThrottlingService _throttlingService;\n    private readonly ISystemClock _systemClock;\n    private readonly ILogger<DeviceCodeValidator> _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceCodeValidator\"/> class.\n    /// </summary>\n    /// <param name=\"devices\">The devices.</param>\n    /// <param name=\"profile\">The profile.</param>\n    /// <param name=\"throttlingService\">The throttling service.</param>\n    /// <param name=\"systemClock\">The system clock.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public DeviceCodeValidator(\n        IDeviceFlowCodeService devices,\n        IProfileService profile,\n        IDeviceFlowThrottlingService throttlingService,\n        ISystemClock systemClock,\n        ILogger<DeviceCodeValidator> logger)\n    {\n        _devices = devices;\n        _profile = profile;\n        _throttlingService = throttlingService;\n        _systemClock = systemClock;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the device code.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public async Task ValidateAsync(DeviceCodeValidationContext context)\n    {\n        var deviceCode = await _devices.FindByDeviceCodeAsync(context.DeviceCode);\n\n        if (deviceCode == null)\n        {\n            _logger.LogError(\"Invalid device code\");\n            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);\n            return;\n        }\n        \n        // validate client binding\n        if (deviceCode.ClientId != context.Request.Client.ClientId)\n        {\n            _logger.LogError(\"Client {0} is trying to use a device code from client {1}\", context.Request.Client.ClientId, deviceCode.ClientId);\n            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);\n            return;\n        }\n\n        if (await _throttlingService.ShouldSlowDown(context.DeviceCode, deviceCode))\n        {\n            _logger.LogError(\"Client {0} is polling too fast\", deviceCode.ClientId);\n            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.SlowDown);\n            return;\n        }\n\n        // validate lifetime\n        if (deviceCode.CreationTime.AddSeconds(deviceCode.Lifetime) < _systemClock.UtcNow)\n        {\n            _logger.LogError(\"Expired device code\");\n            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.ExpiredToken);\n            return;\n        }\n\n        // denied\n        if (deviceCode.IsAuthorized\n            && (deviceCode.AuthorizedScopes == null || deviceCode.AuthorizedScopes.Any() == false))\n        {\n            _logger.LogError(\"No scopes authorized for device authorization. Access denied\");\n            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AccessDenied);\n            return;\n        }\n\n        // make sure code is authorized\n        if (!deviceCode.IsAuthorized || deviceCode.Subject == null)\n        {\n            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.AuthorizationPending);\n            return;\n        }\n\n        // make sure user is enabled\n        var isActiveCtx = new IsActiveContext(deviceCode.Subject, context.Request.Client, IdentityServerConstants.ProfileIsActiveCallers.DeviceCodeValidation);\n        await _profile.IsActiveAsync(isActiveCtx);\n\n        if (isActiveCtx.IsActive == false)\n        {\n            _logger.LogError(\"User has been disabled: {subjectId}\", deviceCode.Subject.GetSubjectId());\n            context.Result = new TokenRequestValidationResult(context.Request, OidcConstants.TokenErrors.InvalidGrant);\n            return;\n        }\n\n        context.Request.DeviceCode = deviceCode;\n        context.Request.SessionId = deviceCode.SessionId;\n\n        context.Result = new TokenRequestValidationResult(context.Request);\n        await _devices.RemoveByDeviceCodeAsync(context.DeviceCode);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/EndSessionRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates requests to the end session endpoint.\n/// </summary>\npublic class EndSessionRequestValidator : IEndSessionRequestValidator\n{\n    /// <summary>\n    /// The logger.\n    /// </summary>\n    protected readonly ILogger Logger;\n\n    /// <summary>\n    ///  The IdentityServer options.\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// The token validator.\n    /// </summary>\n    protected readonly ITokenValidator TokenValidator;\n\n    /// <summary>\n    /// The URI validator.\n    /// </summary>\n    protected readonly IRedirectUriValidator UriValidator;\n\n    /// <summary>\n    /// The user session service.\n    /// </summary>\n    protected readonly IUserSession UserSession;\n\n    /// <summary>\n    /// The logout notification service.\n    /// </summary>\n    public ILogoutNotificationService LogoutNotificationService { get; }\n\n    /// <summary>\n    /// The end session message store.\n    /// </summary>\n    protected readonly IMessageStore<LogoutNotificationContext> EndSessionMessageStore;\n\n    /// <summary>\n    /// The HTTP context accessor.\n    /// </summary>\n    protected readonly IHttpContextAccessor Context;\n\n    /// <summary>\n    /// Creates a new instance of the EndSessionRequestValidator.\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <param name=\"options\"></param>\n    /// <param name=\"tokenValidator\"></param>\n    /// <param name=\"uriValidator\"></param>\n    /// <param name=\"userSession\"></param>\n    /// <param name=\"logoutNotificationService\"></param>\n    /// <param name=\"endSessionMessageStore\"></param>\n    /// <param name=\"logger\"></param>\n    public EndSessionRequestValidator(\n        IHttpContextAccessor context,\n        IdentityServerOptions options,\n        ITokenValidator tokenValidator,\n        IRedirectUriValidator uriValidator,\n        IUserSession userSession,\n        ILogoutNotificationService logoutNotificationService,\n        IMessageStore<LogoutNotificationContext> endSessionMessageStore,\n        ILogger<EndSessionRequestValidator> logger)\n    {\n        Context = context;\n        Options = options;\n        TokenValidator = tokenValidator;\n        UriValidator = uriValidator;\n        UserSession = userSession;\n        LogoutNotificationService = logoutNotificationService;\n        EndSessionMessageStore = endSessionMessageStore;\n        Logger = logger;\n    }\n\n    /// <inheritdoc />\n    public async Task<EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)\n    {\n        Logger.LogDebug(\"Start end session request validation\");\n\n        var isAuthenticated = subject.IsAuthenticated();\n\n        if (!isAuthenticated && Options.Authentication.RequireAuthenticatedUserForSignOutMessage)\n        {\n            return Invalid(\"User is anonymous. Ignoring end session parameters\");\n        }\n\n        var validatedRequest = new ValidatedEndSessionRequest\n        {\n            Raw = parameters\n        };\n\n        var idTokenHint = parameters.Get(OidcConstants.EndSessionRequest.IdTokenHint);\n        if (idTokenHint.IsPresent())\n        {\n            // validate id_token - no need to validate token life time\n            var tokenValidationResult = await TokenValidator.ValidateIdentityTokenAsync(idTokenHint, null, false);\n            if (tokenValidationResult.IsError)\n            {\n                return Invalid(\"Error validating id token hint\", validatedRequest);\n            }\n\n            validatedRequest.Client = tokenValidationResult.Client;\n\n            // validate sub claim against currently logged on user\n            var subClaim = tokenValidationResult.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject);\n            if (subClaim != null && isAuthenticated)\n            {\n                if (subject.GetSubjectId() != subClaim.Value)\n                {\n                    return Invalid(\"Current user does not match identity token\", validatedRequest);\n                }\n\n                validatedRequest.Subject = subject;\n                validatedRequest.SessionId = await UserSession.GetSessionIdAsync();\n                validatedRequest.ClientIds = await UserSession.GetClientListAsync();\n            }\n\n            var redirectUri = parameters.Get(OidcConstants.EndSessionRequest.PostLogoutRedirectUri);\n            if (redirectUri.IsPresent())\n            {\n                if (await UriValidator.IsPostLogoutRedirectUriValidAsync(redirectUri, validatedRequest.Client))\n                {\n                    validatedRequest.PostLogOutUri = redirectUri;\n                }\n                else\n                {\n                    Logger.LogWarning(\"Invalid PostLogoutRedirectUri: {postLogoutRedirectUri}\", redirectUri);\n                }\n            }\n\n            if (validatedRequest.PostLogOutUri != null)\n            {\n                var state = parameters.Get(OidcConstants.EndSessionRequest.State);\n                if (state.IsPresent())\n                {\n                    validatedRequest.State = state;\n                }\n            }\n        }\n        else\n        {\n            // no id_token to authenticate the client, but we do have a user and a user session\n            validatedRequest.Subject = subject;\n            validatedRequest.SessionId = await UserSession.GetSessionIdAsync();\n            validatedRequest.ClientIds = await UserSession.GetClientListAsync();\n        }\n\n        LogSuccess(validatedRequest);\n\n        return new EndSessionValidationResult\n        {\n            ValidatedRequest = validatedRequest,\n            IsError = false\n        };\n    }\n\n    /// <summary>\n    /// Creates a result that indicates an error.\n    /// </summary>\n    /// <param name=\"message\"></param>\n    /// <param name=\"request\"></param>\n    /// <returns></returns>\n    protected virtual EndSessionValidationResult Invalid(string message, ValidatedEndSessionRequest request = null)\n    {\n        message = \"End session request validation failure: \" + message;\n        if (request != null)\n        {\n            var log = new EndSessionRequestValidationLog(request);\n            Logger.LogInformation(message + Environment.NewLine + \"{@details}\", log);\n        }\n        else\n        {\n            Logger.LogInformation(message);\n        }\n\n        return new EndSessionValidationResult\n        {\n            IsError = true,\n            Error = \"Invalid request\",\n            ErrorDescription = message\n        };\n    }\n\n    /// <summary>\n    /// Logs a success result.\n    /// </summary>\n    /// <param name=\"request\"></param>\n    protected virtual void LogSuccess(ValidatedEndSessionRequest request)\n    {\n        var log = new EndSessionRequestValidationLog(request);\n        Logger.LogInformation(\"End session request validation success\" + Environment.NewLine + \"{@details}\", log);\n    }\n\n    /// <inheritdoc />\n    public async Task<EndSessionCallbackValidationResult> ValidateCallbackAsync(NameValueCollection parameters)\n    {\n        var result = new EndSessionCallbackValidationResult\n        {\n            IsError = true\n        };\n\n        var endSessionId = parameters[Constants.UIConstants.DefaultRoutePathParams.EndSessionCallback];\n        var endSessionMessage = await EndSessionMessageStore.ReadAsync(endSessionId);\n        if (endSessionMessage?.Data?.ClientIds?.Any() == true)\n        {\n            result.IsError = false;\n            result.FrontChannelLogoutUrls = await LogoutNotificationService.GetFrontChannelLogoutNotificationsUrlsAsync(endSessionMessage.Data);\n        }\n        else\n        {\n            result.Error = \"Failed to read end session callback message\";\n        }\n\n        return result;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/ExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates an extension grant request using the registered validators\n/// </summary>\npublic class ExtensionGrantValidator\n{\n    private readonly ILogger _logger;\n    private readonly IEnumerable<IExtensionGrantValidator> _validators;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ExtensionGrantValidator\"/> class.\n    /// </summary>\n    /// <param name=\"validators\">The validators.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public ExtensionGrantValidator(IEnumerable<IExtensionGrantValidator> validators, ILogger<ExtensionGrantValidator> logger)\n    {\n        if (validators == null)\n        {\n            _validators = Enumerable.Empty<IExtensionGrantValidator>();\n        }\n        else\n        {\n            _validators = validators;\n        }\n\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Gets the available grant types.\n    /// </summary>\n    /// <returns></returns>\n    public IEnumerable<string> GetAvailableGrantTypes()\n    {\n        return _validators.Select(v => v.GrantType);\n    }\n\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <returns></returns>\n    public async Task<GrantValidationResult> ValidateAsync(ValidatedTokenRequest request)\n    {\n        var validator = _validators.FirstOrDefault(v => v.GrantType.Equals(request.GrantType, StringComparison.Ordinal));\n\n        if (validator == null)\n        {\n            _logger.LogError(\"No validator found for grant type\");\n            return new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);\n        }\n\n        try\n        {\n            _logger.LogTrace(\"Calling into custom grant validator: {type}\", validator.GetType().FullName);\n\n            var context = new ExtensionGrantValidationContext\n            {\n                Request = request\n            };\n        \n            await validator.ValidateAsync(context);\n            return context.Result;\n        }\n        catch (Exception e)\n        {\n            _logger.LogError(1, e, \"Grant validation error: {message}\", e.Message);\n            return new GrantValidationResult(TokenRequestErrors.InvalidGrant);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/HashedSharedSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Secret = IdentityServer8.Models.Secret;\n\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates a shared secret stored in SHA256 or SHA512\n/// </summary>\npublic class HashedSharedSecretValidator : ISecretValidator\n{\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"HashedSharedSecretValidator\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public HashedSharedSecretValidator(ILogger<HashedSharedSecretValidator> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates a secret\n    /// </summary>\n    /// <param name=\"secrets\">The stored secrets.</param>\n    /// <param name=\"parsedSecret\">The received secret.</param>\n    /// <returns>\n    /// A validation result\n    /// </returns>\n    /// <exception cref=\"System.ArgumentNullException\">Id or cedential</exception>\n    public Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret)\n    {\n        var fail = Task.FromResult(new SecretValidationResult { Success = false });\n        var success = Task.FromResult(new SecretValidationResult { Success = true });\n\n        if (parsedSecret.Type != IdentityServerConstants.ParsedSecretTypes.SharedSecret)\n        {\n            _logger.LogDebug(\"Hashed shared secret validator cannot process {type}\", parsedSecret.Type ?? \"null\");\n            return fail;\n        }\n\n        var sharedSecrets = secrets.Where(s => s.Type == IdentityServerConstants.SecretTypes.SharedSecret);\n        if (!sharedSecrets.Any())\n        {\n            _logger.LogDebug(\"No shared secret configured for client.\");\n            return fail;\n        }\n\n        var sharedSecret = parsedSecret.Credential as string;\n\n        if (parsedSecret.Id.IsMissing() || sharedSecret.IsMissing())\n        {\n            throw new ArgumentException(\"Id or Credential is missing.\");\n        }\n\n        var secretSha256 = sharedSecret.Sha256();\n        var secretSha512 = sharedSecret.Sha512();\n\n        foreach (var secret in sharedSecrets)\n        {\n            var secretDescription = string.IsNullOrEmpty(secret.Description) ? \"no description\" : secret.Description;\n\n            bool isValid = false;\n            byte[] secretBytes;\n\n            try\n            {\n                secretBytes = Convert.FromBase64String(secret.Value);\n            }\n            catch (FormatException)\n            {\n                _logger.LogInformation(\"Secret: {description} uses invalid hashing algorithm.\", secretDescription);\n                return fail;\n            }\n            catch (ArgumentNullException)\n            {\n                _logger.LogInformation(\"Secret: {description} is null.\", secretDescription);\n                return fail;\n            }\n\n            if (secretBytes.Length == 32)\n            {\n                isValid = TimeConstantComparer.IsEqual(secret.Value, secretSha256);\n            }\n            else if (secretBytes.Length == 64)\n            {\n                isValid = TimeConstantComparer.IsEqual(secret.Value, secretSha512);\n            }\n            else\n            {\n                _logger.LogInformation(\"Secret: {description} uses invalid hashing algorithm.\", secretDescription);\n                return fail;\n            }\n\n            if (isValid)\n            {\n                return success;\n            }\n        }\n\n        _logger.LogDebug(\"No matching hashed secret found.\");\n        return fail;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/IntrospectionRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// The introspection request validator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.IIntrospectionRequestValidator\" />\ninternal class IntrospectionRequestValidator : IIntrospectionRequestValidator\n{\n    private readonly ILogger _logger;\n    private readonly ITokenValidator _tokenValidator;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IntrospectionRequestValidator\"/> class.\n    /// </summary>\n    /// <param name=\"tokenValidator\">The token validator.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public IntrospectionRequestValidator(ITokenValidator tokenValidator, ILogger<IntrospectionRequestValidator> logger)\n    {\n        _tokenValidator = tokenValidator;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"api\">The API.</param>\n    /// <returns></returns>\n    public async Task<IntrospectionRequestValidationResult> ValidateAsync(NameValueCollection parameters, ApiResource api)\n    {\n        _logger.LogDebug(\"Introspection request validation started.\");\n\n        // retrieve required token\n        var token = parameters.Get(\"token\");\n        if (token == null)\n        {\n            _logger.LogError(\"Token is missing\");\n\n            return new IntrospectionRequestValidationResult\n            {\n                IsError = true,\n                Api = api,\n                Error = \"missing_token\",\n                Parameters = parameters\n            };\n        }\n\n        // validate token\n        var tokenValidationResult = await _tokenValidator.ValidateAccessTokenAsync(token);\n\n        // invalid or unknown token\n        if (tokenValidationResult.IsError)\n        {\n            _logger.LogDebug(\"Token is invalid.\");\n\n            return new IntrospectionRequestValidationResult\n            {\n                IsActive = false,\n                IsError = false,\n                Token = token,\n                Api = api,\n                Parameters = parameters\n            };\n        }\n\n        _logger.LogDebug(\"Introspection request validation successful.\");\n\n        // valid token\n        return new IntrospectionRequestValidationResult\n        {\n            IsActive = true,\n            IsError = false,\n            Token = token,\n            Claims = tokenValidationResult.Claims,\n            Api = api,\n            Parameters = parameters\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/JwtBearerClientAssertionSecretParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Parses a POST body for a JWT bearer client assertion\n/// </summary>\npublic class JwtBearerClientAssertionSecretParser : ISecretParser\n{\n    private readonly IdentityServerOptions _options;\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"JwtBearerClientAssertionSecretParser\"/> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public JwtBearerClientAssertionSecretParser(IdentityServerOptions options, ILogger<JwtBearerClientAssertionSecretParser> logger)\n    {\n        _options = options;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Returns the authentication method name that this parser implements\n    /// </summary>\n    /// <value>\n    /// The authentication method.\n    /// </value>\n    public string AuthenticationMethod => OidcConstants.EndpointAuthenticationMethods.PrivateKeyJwt;\n\n    /// <summary>\n    /// Tries to find a JWT client assertion token in the request body that can be used for authentication\n    /// Used for \"private_key_jwt\" client authentication method as defined in http://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication\n    /// </summary>\n    /// <param name=\"context\">The HTTP context</param>\n    /// <returns>\n    /// A parsed secret\n    /// </returns>\n    public async Task<ParsedSecret> ParseAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start parsing for JWT client assertion in post body\");\n\n        if (!context.Request.HasApplicationFormContentType())\n        {\n            _logger.LogDebug(\"Content type is not a form\");\n            return null;\n        }\n\n        var body = await context.Request.ReadFormAsync();\n\n        if (body != null)\n        {\n            var clientAssertionType = body[OidcConstants.TokenRequest.ClientAssertionType].FirstOrDefault();\n            var clientAssertion = body[OidcConstants.TokenRequest.ClientAssertion].FirstOrDefault();\n\n            if (clientAssertion.IsPresent()\n                && clientAssertionType == OidcConstants.ClientAssertionTypes.JwtBearer)\n            {\n                if (clientAssertion.Length > _options.InputLengthRestrictions.Jwt)\n                {\n                    _logger.LogError(\"Client assertion token exceeds maximum length.\");\n                    return null;\n                }\n\n                var clientId = GetClientIdFromToken(clientAssertion);\n                if (!clientId.IsPresent())\n                {\n                    return null;\n                }\n\n                if (clientId.Length > _options.InputLengthRestrictions.ClientId)\n                {\n                    _logger.LogError(\"Client ID exceeds maximum length.\");\n                    return null;\n                }\n\n                var parsedSecret = new ParsedSecret\n                {\n                    Id = clientId,\n                    Credential = clientAssertion,\n                    Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n                };\n\n                return parsedSecret;\n            }\n        }\n\n        _logger.LogDebug(\"No JWT client assertion found in post body\");\n        return null;\n    }\n\n    private string GetClientIdFromToken(string token)\n    {\n        try\n        {\n            var jwt = new JwtSecurityToken(token);\n            return jwt.Subject;\n        }\n        catch (Exception e)\n        {\n            _logger.LogWarning(\"Could not parse client assertion: {e}\", e);\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/JwtRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates JWT authorization request objects\n/// </summary>\npublic class JwtRequestValidator\n{\n    private readonly string _audienceUri;\n    private readonly IHttpContextAccessor _httpContextAccessor;\n    \n    /// <summary>\n    /// JWT handler\n    /// </summary>\n    protected JwtSecurityTokenHandler Handler = new JwtSecurityTokenHandler\n    {\n        MapInboundClaims = false\n    };\n\n    /// <summary>\n    /// The audience URI to use\n    /// </summary>\n    protected string AudienceUri\n    {\n        get\n        {\n            if (_audienceUri.IsPresent())\n            {\n                return _audienceUri;\n            }\n\n            return _httpContextAccessor.HttpContext.GetIdentityServerIssuerUri();\n        }\n    }\n\n    /// <summary>\n    /// The logger\n    /// </summary>\n    protected readonly ILogger Logger;\n    \n    /// <summary>\n    /// The optione\n    /// </summary>\n    protected readonly IdentityServerOptions Options;\n\n    /// <summary>\n    /// Instantiates an instance of private_key_jwt secret validator\n    /// </summary>\n    public JwtRequestValidator(IHttpContextAccessor contextAccessor, IdentityServerOptions options, ILogger<JwtRequestValidator> logger)\n    {\n        _httpContextAccessor = contextAccessor;\n        \n        Options = options;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Instantiates an instance of private_key_jwt secret validator (used for testing)\n    /// </summary>\n    internal JwtRequestValidator(string audience, ILogger<JwtRequestValidator> logger)\n    {\n        _audienceUri = audience;\n        Logger = logger;\n    }\n\n    /// <summary>\n    /// Validates a JWT request object\n    /// </summary>\n    /// <param name=\"client\">The client</param>\n    /// <param name=\"jwtTokenString\">The JWT</param>\n    /// <returns></returns>\n    public virtual async Task<JwtRequestValidationResult> ValidateAsync(Client client, string jwtTokenString)\n    {\n        if (client == null) throw new ArgumentNullException(nameof(client));\n        if (String.IsNullOrWhiteSpace(jwtTokenString)) throw new ArgumentNullException(nameof(jwtTokenString));\n\n        var fail = new JwtRequestValidationResult { IsError = true };\n\n        List<SecurityKey> trustedKeys;\n        try\n        {\n            trustedKeys = await GetKeysAsync(client);\n        }\n        catch (Exception e)\n        {\n            Logger.LogError(e, \"Could not parse client secrets\");\n            return fail;\n        }\n\n        if (!trustedKeys.Any())\n        {\n            Logger.LogError(\"There are no keys available to validate JWT.\");\n            return fail;\n        }\n\n        JwtSecurityToken jwtSecurityToken;\n        try\n        {\n            jwtSecurityToken = await ValidateJwtAsync(jwtTokenString, trustedKeys, client);\n        }\n        catch (Exception e)\n        {\n            Logger.LogError(e, \"JWT token validation error\");\n            return fail;\n        }\n\n        if (jwtSecurityToken.Payload.ContainsKey(OidcConstants.AuthorizeRequest.Request) ||\n            jwtSecurityToken.Payload.ContainsKey(OidcConstants.AuthorizeRequest.RequestUri))\n        {\n            Logger.LogError(\"JWT payload must not contain request or request_uri\");\n            return fail;\n        }\n\n        var payload = await ProcessPayloadAsync(jwtSecurityToken);\n\n        var result = new JwtRequestValidationResult\n        {\n            IsError = false,\n            Payload = payload\n        };\n\n        Logger.LogDebug(\"JWT request object validation success.\");\n        return result;\n    }\n\n    /// <summary>\n    /// Retrieves keys for a given client\n    /// </summary>\n    /// <param name=\"client\">The client</param>\n    /// <returns></returns>\n    protected virtual Task<List<SecurityKey>> GetKeysAsync(Client client)\n    {\n        return client.ClientSecrets.GetKeysAsync();\n    }\n\n    /// <summary>\n    /// Validates the JWT token\n    /// </summary>\n    /// <param name=\"jwtTokenString\">JWT as a string</param>\n    /// <param name=\"keys\">The keys</param>\n    /// <param name=\"client\">The client</param>\n    /// <returns></returns>\n    protected virtual Task<JwtSecurityToken> ValidateJwtAsync(string jwtTokenString, IEnumerable<SecurityKey> keys, Client client)\n    {\n        var tokenValidationParameters = new TokenValidationParameters\n        {\n            IssuerSigningKeys = keys,\n            ValidateIssuerSigningKey = true,\n\n            ValidIssuer = client.ClientId,\n            ValidateIssuer = true,\n\n            ValidAudience = AudienceUri,\n            ValidateAudience = true,\n\n            RequireSignedTokens = true,\n            RequireExpirationTime = true\n        };\n\n        if (Options.StrictJarValidation)\n        {\n            tokenValidationParameters.ValidTypes = new[] { JwtClaimTypes.JwtTypes.AuthorizationRequest };\n        }\n\n        Handler.ValidateToken(jwtTokenString, tokenValidationParameters, out var token);\n        \n        return Task.FromResult((JwtSecurityToken)token);\n    }\n\n    /// <summary>\n    /// Processes the JWT contents\n    /// </summary>\n    /// <param name=\"token\">The JWT token</param>\n    /// <returns></returns>\n    protected virtual Task<Dictionary<string, string>> ProcessPayloadAsync(JwtSecurityToken token)\n    {\n        // filter JWT validation values\n        var payload = new Dictionary<string, string>();\n        foreach (var key in token.Payload.Keys)\n        {\n            if (!Constants.Filters.JwtRequestClaimTypesFilter.Contains(key))\n            {\n                var value = token.Payload[key];\n\n                switch (value)\n                {\n                    case string s:\n                        payload.Add(key, s);\n                        break;\n                    case JObject jobj:\n                        payload.Add(key, jobj.ToString(Formatting.None));\n                        break;\n                    case JArray jarr:\n                        payload.Add(key, jarr.ToString(Formatting.None));\n                        break;\n                }\n            }\n        }\n\n        return Task.FromResult(payload);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/MutualTlsSecretParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Parses secret according to MTLS spec\n/// </summary>\npublic class MutualTlsSecretParser : ISecretParser\n{\n    private readonly IdentityServerOptions _options;\n    private readonly ILogger<MutualTlsSecretParser> _logger;\n\n    /// <summary>\n    /// ctor\n    /// </summary>\n    /// <param name=\"options\"></param>\n    /// <param name=\"logger\"></param>\n    public MutualTlsSecretParser(IdentityServerOptions options, ILogger<MutualTlsSecretParser> logger)\n    {\n        _options = options;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Name of authentication method (blank to suppress in discovery since we do special handling)\n    /// </summary>\n    public string AuthenticationMethod => String.Empty;\n\n    /// <summary>\n    /// Parses the HTTP context\n    /// </summary>\n    /// <param name=\"context\"></param>\n    /// <returns></returns>\n    public async Task<ParsedSecret> ParseAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start parsing for client id in post body\");\n\n        if (!context.Request.HasApplicationFormContentType())\n        {\n            _logger.LogDebug(\"Content type is not a form\");\n            return null;\n        }\n\n        var body = await context.Request.ReadFormAsync();\n\n        if (body != null)\n        {\n            var id = body[\"client_id\"].FirstOrDefault();\n\n            // client id must be present\n            if (!String.IsNullOrWhiteSpace(id))\n            {\n                if (id.Length > _options.InputLengthRestrictions.ClientId)\n                {\n                    _logger.LogError(\"Client ID exceeds maximum length.\");\n                    return null;\n                }\n                \n                var clientCertificate = await context.Connection.GetClientCertificateAsync();\n                \n                if (clientCertificate is null)\n                {\n                    _logger.LogDebug(\"Client certificate not present\");\n                    return null;\n                }\n                \n                return new ParsedSecret\n                {\n                    Id = id,\n                    Credential = clientCertificate,\n                    Type = IdentityServerConstants.ParsedSecretTypes.X509Certificate\n                };\n            }\n        }\n\n        _logger.LogDebug(\"No post body found\");\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/NopClientConfigurationValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// No-op client configuration validator (for backwards-compatibility).\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.IClientConfigurationValidator\" />\npublic class NopClientConfigurationValidator : IClientConfigurationValidator\n{\n    /// <summary>\n    /// Determines whether the configuration of a client is valid.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public Task ValidateAsync(ClientConfigurationValidationContext context)\n    {\n        context.IsValid = true;\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/NotSupportedResouceOwnerCredentialValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default resource owner password validator (no implementation == not supported)\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.IResourceOwnerPasswordValidator\" />\npublic class NotSupportedResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator\n{\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"NotSupportedResourceOwnerPasswordValidator\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public NotSupportedResourceOwnerPasswordValidator(ILogger<NotSupportedResourceOwnerPasswordValidator> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the resource owner password credential\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)\n    {\n        context.Result = new GrantValidationResult(TokenRequestErrors.UnsupportedGrantType);\n\n        _logger.LogInformation(\"Resource owner password credential type not supported. Configure an IResourceOwnerPasswordValidator.\");\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/PlainTextSharedSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates a secret stored in plain text\n/// </summary>\npublic class PlainTextSharedSecretValidator : ISecretValidator\n{\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"PlainTextSharedSecretValidator\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public PlainTextSharedSecretValidator(ILogger<PlainTextSharedSecretValidator> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates a secret\n    /// </summary>\n    /// <param name=\"secrets\">The stored secrets.</param>\n    /// <param name=\"parsedSecret\">The received secret.</param>\n    /// <returns>\n    /// A validation result\n    /// </returns>\n    /// <exception cref=\"System.ArgumentException\">id or credential is missing.</exception>\n    public Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret)\n    {\n        var fail = Task.FromResult(new SecretValidationResult { Success = false });\n        var success = Task.FromResult(new SecretValidationResult { Success = true });\n\n        if (parsedSecret.Type != IdentityServerConstants.ParsedSecretTypes.SharedSecret)\n        {\n            _logger.LogError(\"Parsed secret should not be of type: {type}\", parsedSecret.Type ?? \"null\");\n            return fail;\n        }\n\n        var sharedSecrets = secrets.Where(s => s.Type == IdentityServerConstants.SecretTypes.SharedSecret);\n        if (!sharedSecrets.Any())\n        {\n            _logger.LogDebug(\"No shared secret configured for client.\");\n            return fail;\n        }\n\n        var sharedSecret = parsedSecret.Credential as string;\n\n        if (parsedSecret.Id.IsMissing() || sharedSecret.IsMissing())\n        {\n            throw new ArgumentException(\"Id or Credential is missing.\");\n        }\n\n        foreach (var secret in sharedSecrets)\n        {\n            // use time constant string comparison\n            var isValid = TimeConstantComparer.IsEqual(sharedSecret, secret.Value);\n\n            if (isValid)\n            {\n                return success;\n            }\n        }\n\n        _logger.LogDebug(\"No matching plain text secret found.\");\n        return fail;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/PostBodySecretParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Parses a POST body for secrets\n/// </summary>\npublic class PostBodySecretParser : ISecretParser\n{\n    private readonly ILogger _logger;\n    private readonly IdentityServerOptions _options;\n\n    /// <summary>\n    /// Creates the parser with options\n    /// </summary>\n    /// <param name=\"options\">IdentityServer options</param>\n    /// <param name=\"logger\">Logger</param>\n    public PostBodySecretParser(IdentityServerOptions options, ILogger<PostBodySecretParser> logger)\n    {\n        _logger = logger;\n        _options = options;\n    }\n\n    /// <summary>\n    /// Returns the authentication method name that this parser implements\n    /// </summary>\n    /// <value>\n    /// The authentication method.\n    /// </value>\n    public string AuthenticationMethod => OidcConstants.EndpointAuthenticationMethods.PostBody;\n\n    /// <summary>\n    /// Tries to find a secret on the context that can be used for authentication\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns>\n    /// A parsed secret\n    /// </returns>\n    public async Task<ParsedSecret> ParseAsync(HttpContext context)\n    {\n        _logger.LogDebug(\"Start parsing for secret in post body\");\n\n        if (!context.Request.HasApplicationFormContentType())\n        {\n            _logger.LogDebug(\"Content type is not a form\");\n            return null;\n        }\n\n        var body = await context.Request.ReadFormAsync();\n\n        if (body != null)\n        {\n            var id = body[\"client_id\"].FirstOrDefault();\n            var secret = body[\"client_secret\"].FirstOrDefault();\n\n            // client id must be present\n            if (id.IsPresent())\n            {\n                if (id.Length > _options.InputLengthRestrictions.ClientId)\n                {\n                    _logger.LogError(\"Client ID exceeds maximum length.\");\n                    return null;\n                }\n\n                if (secret.IsPresent())\n                {\n                    if (secret.Length > _options.InputLengthRestrictions.ClientSecret)\n                    {\n                        _logger.LogError(\"Client secret exceeds maximum length.\");\n                        return null;\n                    }\n\n                    return new ParsedSecret\n                    {\n                        Id = id,\n                        Credential = secret,\n                        Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n                    };\n                }\n                else\n                {\n                    // client secret is optional\n                    _logger.LogDebug(\"client id without secret found\");\n\n                    return new ParsedSecret\n                    {\n                        Id = id,\n                        Type = IdentityServerConstants.ParsedSecretTypes.NoSecret\n                    };\n                }\n            }\n        }\n\n        _logger.LogDebug(\"No secret in post body found\");\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/PrivateKeyJwtSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates a secret based on RS256 signed JWT token\n/// </summary>\npublic class PrivateKeyJwtSecretValidator : ISecretValidator\n{\n    private readonly IHttpContextAccessor _contextAccessor;\n    private readonly IReplayCache _replayCache;\n    private readonly ILogger _logger;\n\n    private const string Purpose = nameof(PrivateKeyJwtSecretValidator);\n    \n    /// <summary>\n    /// Instantiates an instance of private_key_jwt secret validator\n    /// </summary>\n    public PrivateKeyJwtSecretValidator(IHttpContextAccessor contextAccessor, IReplayCache replayCache, ILogger<PrivateKeyJwtSecretValidator> logger)\n    {\n        _contextAccessor = contextAccessor;\n        _replayCache = replayCache;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates a secret\n    /// </summary>\n    /// <param name=\"secrets\">The stored secrets.</param>\n    /// <param name=\"parsedSecret\">The received secret.</param>\n    /// <returns>\n    /// A validation result\n    /// </returns>\n    /// <exception cref=\"System.ArgumentException\">ParsedSecret.Credential is not a JWT token</exception>\n    public async Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret)\n    {\n        var fail = new SecretValidationResult { Success = false };\n        var success = new SecretValidationResult { Success = true };\n\n        if (parsedSecret.Type != IdentityServerConstants.ParsedSecretTypes.JwtBearer)\n        {\n            return fail;\n        }\n\n        if (!(parsedSecret.Credential is string jwtTokenString))\n        {\n            _logger.LogError(\"ParsedSecret.Credential is not a string.\");\n            return fail;\n        }\n\n        List<SecurityKey> trustedKeys;\n        try\n        {\n            trustedKeys = await secrets.GetKeysAsync();\n        }\n        catch (Exception e)\n        {\n            _logger.LogError(e, \"Could not parse secrets\");\n            return fail;\n        }\n\n        if (!trustedKeys.Any())\n        {\n            _logger.LogError(\"There are no keys available to validate client assertion.\");\n            return fail;\n        }\n\n        var validAudiences = new[]\n        {\n            // issuer URI (tbd)\n            //_contextAccessor.HttpContext.GetIdentityServerIssuerUri(),\n            \n            // token endpoint URL\n            string.Concat(_contextAccessor.HttpContext.GetIdentityServerIssuerUri().EnsureTrailingSlash(),\n                Constants.ProtocolRoutePaths.Token)\n        };\n        \n        var tokenValidationParameters = new TokenValidationParameters\n        {\n            IssuerSigningKeys = trustedKeys,\n            ValidateIssuerSigningKey = true,\n\n            ValidIssuer = parsedSecret.Id,\n            ValidateIssuer = true,\n\n            ValidAudiences = validAudiences,\n            ValidateAudience = true,\n\n            RequireSignedTokens = true,\n            RequireExpirationTime = true,\n            \n            ClockSkew = TimeSpan.FromMinutes(5)\n        };\n        try\n        {\n            var handler = new JwtSecurityTokenHandler();\n            handler.ValidateToken(jwtTokenString, tokenValidationParameters, out var token);\n\n            var jwtToken = (JwtSecurityToken)token;\n            if (jwtToken.Subject != jwtToken.Issuer)\n            {\n                _logger.LogError(\"Both 'sub' and 'iss' in the client assertion token must have a value of client_id.\");\n                return fail;\n            }\n            \n            var exp = jwtToken.Payload.Exp;\n            if (!exp.HasValue)\n            {\n                _logger.LogError(\"exp is missing.\");\n                return fail;\n            }\n            \n            var jti = jwtToken.Payload.Jti;\n            if (jti.IsMissing())\n            {\n                _logger.LogError(\"jti is missing.\");\n                return fail;\n            }\n\n            if (await _replayCache.ExistsAsync(Purpose, jti))\n            {\n                _logger.LogError(\"jti is found in replay cache. Possible replay attack.\");\n                return fail;\n            }\n            else\n            {\n                await _replayCache.AddAsync(Purpose, jti, DateTimeOffset.FromUnixTimeSeconds(exp.Value).AddMinutes(5));\n            }\n\n            return success;\n        }\n        catch (Exception e)\n        {\n            _logger.LogError(e, \"JWT token validation error\");\n            return fail;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/ResponseTypeEqualityComparer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Compares resource_type strings, where the order of space-delimited values is insignificant.\n/// </summary>\n/// <remarks>\n/// <para>\n/// This is to handle the fact that the order of multi-valued response_type lists is\n/// insignificant, per the <see href=\"https://tools.ietf.org/html/rfc6749#section-3.1.1\">OAuth2 spec</see>\n/// and the \n/// (<see href=\"http://openid.net/specs/oauth-v2-multiple-response-types-1_0-03.html#terminology\">OAuth \n/// 2.0 Multiple Response Type Encoding Practices draft </see>).\n/// </para>\n/// </remarks>\npublic class ResponseTypeEqualityComparer : IEqualityComparer<string>\n{\n    /// <summary>\n    /// Determines whether the specified values are equal.\n    /// </summary>\n    /// <param name=\"x\">The first string to compare.</param>\n    /// <param name=\"y\">The second string to compare.</param>\n    /// <returns>true if the specified values are equal; otherwise, false.</returns>\n    public bool Equals(string x, string y)\n    {\n        if (x == y) return true;\n\n        if (x == null || y == null) return false;\n\n        if (x.Length != y.Length) return false;\n\n        var xValues = x.Split(' ');\n        var yValues = y.Split(' ');\n\n        if (xValues.Length != yValues.Length)\n        {\n            return false;\n        }\n\n        Array.Sort(xValues);\n        Array.Sort(yValues);\n\n        for (var i = 0; i < xValues.Length; i++)\n        {\n            if (xValues[i] != yValues[i])\n            {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /// <summary>\n    /// Returns a hash code for the value.\n    /// </summary>\n    /// <param name=\"value\">The value for which a hash code is to be returned.</param>\n    /// <returns>A hash code for the value, suitable for use in hashing algorithms and data structures like a hash table.</returns>\n    public int GetHashCode(string value)\n    {\n        if (value == null) return 0;\n\n        var values = value.Split(' ');\n        if (values.Length == 1)\n        {\n            // Only one value, so just spit out the hash code of the whole string\n            return value.GetHashCode();\n        }\n\n        Array.Sort(values);\n\n        // Using Skeet's answer here: http://stackoverflow.com/a/7244729/208990\n        // Licensed under Creative Commons CC-BY-SA from SO: https://stackoverflow.com/legal/terms-of-service#licensing\n        // Creative Commons CC-BY-SA https://creativecommons.org/licenses/by-sa/4.0/\n        var hash = 17;\n        foreach (var element in values)\n        {\n            // changed to use StringComparer.Ordinal, rather than StringComparer.InvariantCulture\n            hash = hash * 31 + StringComparer.Ordinal.GetHashCode(element);\n        }\n        return hash;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/SecretParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Uses the registered secret parsers to parse a secret on the current request\n/// </summary>\npublic class SecretParser : ISecretsListParser\n{\n    private readonly ILogger _logger;\n    private readonly IEnumerable<ISecretParser> _parsers;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"SecretParser\"/> class.\n    /// </summary>\n    /// <param name=\"parsers\">The parsers.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public SecretParser(IEnumerable<ISecretParser> parsers, ILogger<ISecretsListParser> logger)\n    {\n        _parsers = parsers;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Checks the context to find a secret.\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns></returns>\n    public async Task<ParsedSecret> ParseAsync(HttpContext context)\n    {\n        // see if a registered parser finds a secret on the request\n        ParsedSecret bestSecret = null;\n        foreach (var parser in _parsers)\n        {\n            var parsedSecret = await parser.ParseAsync(context);\n            if (parsedSecret != null)\n            {\n                _logger.LogDebug(\"Parser found secret: {type}\", parser.GetType().Name);\n\n                bestSecret = parsedSecret;\n\n                if (parsedSecret.Type != IdentityServerConstants.ParsedSecretTypes.NoSecret)\n                {\n                    break;\n                }\n            }\n        }\n\n        if (bestSecret != null)\n        {\n            _logger.LogDebug(\"Secret id found: {id}\", Ioc.Sanitizer.Log.Sanitize(bestSecret.Id));\n            return bestSecret;\n        }\n\n        _logger.LogDebug(\"Parser found no secret\");\n        return null;\n    }\n\n    /// <summary>\n    /// Gets all available authentication methods.\n    /// </summary>\n    /// <returns></returns>\n    public IEnumerable<string> GetAvailableAuthenticationMethods()\n    {\n        return _parsers.Select(p => p.AuthenticationMethod).Where(p => !String.IsNullOrWhiteSpace(p));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/SecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates secrets using the registered validators\n/// </summary>\npublic class SecretValidator : ISecretsListValidator\n{\n    private readonly ILogger _logger;\n    private readonly IEnumerable<ISecretValidator> _validators;\n    private readonly ISystemClock _clock;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"SecretValidator\"/> class.\n    /// </summary>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"validators\">The validators.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public SecretValidator(ISystemClock clock, IEnumerable<ISecretValidator> validators, ILogger<ISecretsListValidator> logger)\n    {\n        _clock = clock;\n        _validators = validators;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the secret.\n    /// </summary>\n    /// <param name=\"parsedSecret\">The parsed secret.</param>\n    /// <param name=\"secrets\">The secrets.</param>\n    /// <returns></returns>\n    public async Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret)\n    {\n        var secretsArray = secrets as Secret[] ?? secrets.ToArray();\n\n        var expiredSecrets = secretsArray.Where(s => s.Expiration.HasExpired(_clock.UtcNow.UtcDateTime)).ToList();\n        if (expiredSecrets.Any())\n        {\n            expiredSecrets.ForEach(\n                ex => _logger.LogInformation(\"Secret [{description}] is expired\", ex.Description ?? \"no description\"));\n        }\n\n        var currentSecrets = secretsArray.Where(s => !s.Expiration.HasExpired(_clock.UtcNow.UtcDateTime)).ToArray();\n\n        // see if a registered validator can validate the secret\n        foreach (var validator in _validators)\n        {\n            var secretValidationResult = await validator.ValidateAsync(currentSecrets, parsedSecret);\n\n            if (secretValidationResult.Success)\n            {\n                _logger.LogDebug(\"Secret validator success: {0}\", validator.GetType().Name);\n                return secretValidationResult;\n            }\n        }\n\n        _logger.LogDebug(\"Secret validators could not validate secret\");\n        return new SecretValidationResult { Success = false };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/StrictRedirectUriValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default implementation of redirect URI validator. Validates the URIs against\n/// the client's configured URIs.\n/// </summary>\npublic class StrictRedirectUriValidator : IRedirectUriValidator\n{\n    /// <summary>\n    /// Checks if a given URI string is in a collection of strings (using ordinal ignore case comparison)\n    /// </summary>\n    /// <param name=\"uris\">The uris.</param>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <returns></returns>\n    protected bool StringCollectionContainsString(IEnumerable<string> uris, string requestedUri)\n    {\n        if (uris.EnumerableIsNullOrEmpty()) return false;\n\n        return uris.Contains(requestedUri, StringComparer.OrdinalIgnoreCase);\n    }\n\n    /// <summary>\n    /// Determines whether a redirect URI is valid for a client.\n    /// </summary>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    ///   <c>true</c> is the URI is valid; <c>false</c> otherwise.\n    /// </returns>\n    public virtual Task<bool> IsRedirectUriValidAsync(string requestedUri, Client client)\n    {\n        return Task.FromResult(StringCollectionContainsString(client.RedirectUris, requestedUri));\n    }\n\n    /// <summary>\n    /// Determines whether a post logout URI is valid for a client.\n    /// </summary>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    ///   <c>true</c> is the URI is valid; <c>false</c> otherwise.\n    /// </returns>\n    public virtual Task<bool> IsPostLogoutRedirectUriValidAsync(string requestedUri, Client client)\n    {\n        return Task.FromResult(StringCollectionContainsString(client.PostLogoutRedirectUris, requestedUri));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/StrictRedirectUriValidatorAppAuth.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Implementation of strict redirect URI validator that allows a random port if 127.0.0.1 is used.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.StrictRedirectUriValidator\" />\npublic class StrictRedirectUriValidatorAppAuth : StrictRedirectUriValidator\n{\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"StrictRedirectUriValidatorAppAuth\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public StrictRedirectUriValidatorAppAuth(ILogger<StrictRedirectUriValidatorAppAuth> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Determines whether a redirect URI is valid for a client.\n    /// </summary>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    /// <c>true</c> is the URI is valid; <c>false</c> otherwise.\n    /// </returns>\n    public override async Task<bool> IsRedirectUriValidAsync(string requestedUri, Client client)\n    {\n        var isAllowed = await base.IsRedirectUriValidAsync(requestedUri, client);\n        if (isAllowed) return isAllowed;\n\n        // since this is appauth specific, we can require pkce\n        if (client.RequirePkce && client.RedirectUris.Contains(\"http://127.0.0.1\")) return IsLoopback(requestedUri);\n\n        return false;\n    }\n\n    /// <summary>\n    /// Determines whether a post logout URI is valid for a client.\n    /// </summary>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns>\n    /// <c>true</c> is the URI is valid; <c>false</c> otherwise.\n    /// </returns>\n    public override async Task<bool> IsPostLogoutRedirectUriValidAsync(string requestedUri, Client client)\n    {\n        var isAllowed = await base.IsPostLogoutRedirectUriValidAsync(requestedUri, client);\n        if (isAllowed) return isAllowed;\n\n        // since this is appauth specific, we can require pkce\n        if (client.RequirePkce && client.RedirectUris.Contains(\"http://127.0.0.1\")) return IsLoopback(requestedUri);\n\n        return false;\n    }\n\n    /// <summary>\n    /// Check if <paramref name=\"requestedUri\"/> is of the form http://127.0.0.1:port/path.\n    /// </summary>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <returns>\n    /// <c>true</c> if <paramref name=\"requestedUri\"/> is a valid Loopback URI; <c>false</c> otherwise.\n    /// </returns>\n    internal bool IsLoopback(string requestedUri)\n    {\n        _logger.LogDebug(\"Checking for 127.0.0.1 redirect URI\");\n\n        // Validate that the requestedUri is not null or empty.\n        if (string.IsNullOrEmpty(requestedUri))\n        {\n            _logger.LogDebug(\"'requestedUri' is null or empty\");\n            return false;\n        }\n\n        var parts = requestedUri.Split(':');\n\n        if (parts.Length != 3)\n        {\n            _logger.LogDebug(\"invalid format - http://127.0.0.1:port is required.\");\n            return false;\n        }\n\n        if (!string.Equals(parts[0], \"http\", StringComparison.Ordinal) ||\n            !string.Equals(parts[1], \"//127.0.0.1\", StringComparison.Ordinal))\n        {\n            _logger.LogDebug(\"invalid format - http://127.0.0.1:port is required.\");\n            return false;\n        }\n\n        string portAsString;\n        int indexOfPathSeparator = parts[2].IndexOfAny(new[] { '/', '?', '#' });\n        if (indexOfPathSeparator > 0)\n        {\n            portAsString = parts[2].Substring(0, indexOfPathSeparator);\n        }\n        else\n        {\n            portAsString = parts[2];\n        }\n\n        // Valid port range is 0 through 65535.\n        if (int.TryParse(portAsString, out var port))\n        {\n            if (port >= 0 && port < 65536)\n            {\n                return true;\n            }\n        }\n\n        _logger.LogDebug(\"invalid port\");\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/TokenRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\ninternal class TokenRequestValidator : ITokenRequestValidator\n{\n    private readonly IdentityServerOptions _options;\n    private readonly IAuthorizationCodeStore _authorizationCodeStore;\n    private readonly ExtensionGrantValidator _extensionGrantValidator;\n    private readonly ICustomTokenRequestValidator _customRequestValidator;\n    private readonly IResourceValidator _resourceValidator;\n    private readonly IResourceStore _resourceStore;\n    private readonly ITokenValidator _tokenValidator;\n    private readonly IRefreshTokenService _refreshTokenService;\n    private readonly IEventService _events;\n    private readonly IResourceOwnerPasswordValidator _resourceOwnerValidator;\n    private readonly IProfileService _profile;\n    private readonly IDeviceCodeValidator _deviceCodeValidator;\n    private readonly ISystemClock _clock;\n    private readonly ILogger _logger;\n\n    private ValidatedTokenRequest _validatedRequest;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRequestValidator\" /> class.\n    /// </summary>\n    /// <param name=\"options\">The options.</param>\n    /// <param name=\"authorizationCodeStore\">The authorization code store.</param>\n    /// <param name=\"resourceOwnerValidator\">The resource owner validator.</param>\n    /// <param name=\"profile\">The profile.</param>\n    /// <param name=\"deviceCodeValidator\">The device code validator.</param>\n    /// <param name=\"extensionGrantValidator\">The extension grant validator.</param>\n    /// <param name=\"customRequestValidator\">The custom request validator.</param>\n    /// <param name=\"resourceValidator\">The resource validator.</param>\n    /// <param name=\"resourceStore\">The resource store.</param>\n    /// <param name=\"tokenValidator\">The token validator.</param>\n    /// <param name=\"refreshTokenService\"></param>\n    /// <param name=\"events\">The events.</param>\n    /// <param name=\"clock\">The clock.</param>\n    /// <param name=\"logger\">The logger.</param>\n    public TokenRequestValidator(IdentityServerOptions options, \n        IAuthorizationCodeStore authorizationCodeStore, \n        IResourceOwnerPasswordValidator resourceOwnerValidator, \n        IProfileService profile, \n        IDeviceCodeValidator deviceCodeValidator, \n        ExtensionGrantValidator extensionGrantValidator, \n        ICustomTokenRequestValidator customRequestValidator,\n        IResourceValidator resourceValidator,\n        IResourceStore resourceStore,\n        ITokenValidator tokenValidator, \n        IRefreshTokenService refreshTokenService,\n        IEventService events, \n        ISystemClock clock, \n        ILogger<TokenRequestValidator> logger)\n    {\n        _logger = logger;\n        _options = options;\n        _clock = clock;\n        _authorizationCodeStore = authorizationCodeStore;\n        _resourceOwnerValidator = resourceOwnerValidator;\n        _profile = profile;\n        _deviceCodeValidator = deviceCodeValidator;\n        _extensionGrantValidator = extensionGrantValidator;\n        _customRequestValidator = customRequestValidator;\n        _resourceValidator = resourceValidator;\n        _resourceStore = resourceStore;\n        _tokenValidator = tokenValidator;\n        _refreshTokenService = refreshTokenService;\n        _events = events;\n    }\n\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"clientValidationResult\">The client validation result.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">\n    /// parameters\n    /// or\n    /// client\n    /// </exception>\n    public async Task<TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult)\n    {\n        _logger.LogDebug(\"Start token request validation\");\n\n        _validatedRequest = new ValidatedTokenRequest\n        {\n            Raw = parameters ?? throw new ArgumentNullException(nameof(parameters)),\n            Options = _options\n        };\n\n        if (clientValidationResult == null) throw new ArgumentNullException(nameof(clientValidationResult));\n\n        _validatedRequest.SetClient(clientValidationResult.Client, clientValidationResult.Secret, clientValidationResult.Confirmation);\n\n        /////////////////////////////////////////////\n        // check client protocol type\n        /////////////////////////////////////////////\n        if (_validatedRequest.Client.ProtocolType != IdentityServerConstants.ProtocolTypes.OpenIdConnect)\n        {\n            LogError(\"Invalid protocol type for client\",\n                new\n                {\n                    clientId = _validatedRequest.Client.ClientId,\n                    expectedProtocolType = IdentityServerConstants.ProtocolTypes.OpenIdConnect,\n                    actualProtocolType = _validatedRequest.Client.ProtocolType\n                });\n\n            return Invalid(OidcConstants.TokenErrors.InvalidClient);\n        }\n\n        /////////////////////////////////////////////\n        // check grant type\n        /////////////////////////////////////////////\n        var grantType = parameters.Get(OidcConstants.TokenRequest.GrantType);\n        if (grantType.IsMissing())\n        {\n            LogError(\"Grant type is missing\");\n            return Invalid(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n\n        if (grantType.Length > _options.InputLengthRestrictions.GrantType)\n        {\n            LogError(\"Grant type is too long\");\n            return Invalid(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n\n        _validatedRequest.GrantType = grantType;\n\n        switch (grantType)\n        {\n            case OidcConstants.GrantTypes.AuthorizationCode:\n                return await RunValidationAsync(ValidateAuthorizationCodeRequestAsync, parameters);\n            case OidcConstants.GrantTypes.ClientCredentials:\n                return await RunValidationAsync(ValidateClientCredentialsRequestAsync, parameters);\n            case OidcConstants.GrantTypes.Password:\n                return await RunValidationAsync(ValidateResourceOwnerCredentialRequestAsync, parameters);\n            case OidcConstants.GrantTypes.RefreshToken:\n                return await RunValidationAsync(ValidateRefreshTokenRequestAsync, parameters);\n            case OidcConstants.GrantTypes.DeviceCode:\n                return await RunValidationAsync(ValidateDeviceCodeRequestAsync, parameters);\n            default:\n                return await RunValidationAsync(ValidateExtensionGrantRequestAsync, parameters);\n        }\n    }\n\n    private async Task<TokenRequestValidationResult> RunValidationAsync(Func<NameValueCollection, Task<TokenRequestValidationResult>> validationFunc, NameValueCollection parameters)\n    {\n        // run standard validation\n        var result = await validationFunc(parameters);\n        if (result.IsError)\n        {\n            return result;\n        }\n\n        // run custom validation\n        _logger.LogTrace(\"Calling into custom request validator: {type}\", _customRequestValidator.GetType().FullName);\n\n        var customValidationContext = new CustomTokenRequestValidationContext { Result = result };\n        await _customRequestValidator.ValidateAsync(customValidationContext);\n\n        if (customValidationContext.Result.IsError)\n        {\n            if (customValidationContext.Result.Error.IsPresent())\n            {\n                LogError(\"Custom token request validator\", new { error = customValidationContext.Result.Error });\n            }\n            else\n            {\n                LogError(\"Custom token request validator error\");\n            }\n\n            return customValidationContext.Result;\n        }\n\n        LogSuccess();\n        return customValidationContext.Result;\n    }\n\n    private async Task<TokenRequestValidationResult> ValidateAuthorizationCodeRequestAsync(NameValueCollection parameters)\n    {\n        _logger.LogDebug(\"Start validation of authorization code token request\");\n\n        /////////////////////////////////////////////\n        // check if client is authorized for grant type\n        /////////////////////////////////////////////\n        if (!_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.AuthorizationCode) &&\n            !_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.Hybrid))\n        {\n            LogError(\"Client not authorized for code flow\");\n            return Invalid(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        /////////////////////////////////////////////\n        // validate authorization code\n        /////////////////////////////////////////////\n        var code = parameters.Get(OidcConstants.TokenRequest.Code);\n        if (code.IsMissing())\n        {\n            LogError(\"Authorization code is missing\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        if (code.Length > _options.InputLengthRestrictions.AuthorizationCode)\n        {\n            LogError(\"Authorization code is too long\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        _validatedRequest.AuthorizationCodeHandle = code;\n\n        var authZcode = await _authorizationCodeStore.GetAuthorizationCodeAsync(code);\n        if (authZcode == null)\n        {\n            LogError(\"Invalid authorization code\", new { code });\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n        \n        /////////////////////////////////////////////\n        // validate client binding\n        /////////////////////////////////////////////\n        if (authZcode.ClientId != _validatedRequest.Client.ClientId)\n        {\n            LogError(\"Client is trying to use a code from a different client\", new { clientId = _validatedRequest.Client.ClientId, codeClient = authZcode.ClientId });\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        // remove code from store\n        // todo: set to consumed in the future?\n        await _authorizationCodeStore.RemoveAuthorizationCodeAsync(code);\n\n        if (authZcode.CreationTime.HasExceeded(authZcode.Lifetime, _clock.UtcNow.UtcDateTime))\n        {\n            LogError(\"Authorization code expired\", new { code });\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        /////////////////////////////////////////////\n        // populate session id\n        /////////////////////////////////////////////\n        if (authZcode.SessionId.IsPresent())\n        {\n            _validatedRequest.SessionId = authZcode.SessionId;\n        }\n\n        /////////////////////////////////////////////\n        // validate code expiration\n        /////////////////////////////////////////////\n        if (authZcode.CreationTime.HasExceeded(_validatedRequest.Client.AuthorizationCodeLifetime, _clock.UtcNow.UtcDateTime))\n        {\n            LogError(\"Authorization code is expired\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        _validatedRequest.AuthorizationCode = authZcode;\n        _validatedRequest.Subject = authZcode.Subject;\n\n        /////////////////////////////////////////////\n        // validate redirect_uri\n        /////////////////////////////////////////////\n        var redirectUri = parameters.Get(OidcConstants.TokenRequest.RedirectUri);\n        if (redirectUri.IsMissing())\n        {\n            LogError(\"Redirect URI is missing\");\n            return Invalid(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        if (redirectUri.Equals(_validatedRequest.AuthorizationCode.RedirectUri, StringComparison.Ordinal) == false)\n        {\n            LogError(\"Invalid redirect_uri\", new { redirectUri, expectedRedirectUri = _validatedRequest.AuthorizationCode.RedirectUri });\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        /////////////////////////////////////////////\n        // validate scopes are present\n        /////////////////////////////////////////////\n        if (_validatedRequest.AuthorizationCode.RequestedScopes == null ||\n            !_validatedRequest.AuthorizationCode.RequestedScopes.Any())\n        {\n            LogError(\"Authorization code has no associated scopes\");\n            return Invalid(OidcConstants.TokenErrors.InvalidRequest);\n        }\n\n        /////////////////////////////////////////////\n        // validate PKCE parameters\n        /////////////////////////////////////////////\n        var codeVerifier = parameters.Get(OidcConstants.TokenRequest.CodeVerifier);\n        if (_validatedRequest.Client.RequirePkce || _validatedRequest.AuthorizationCode.CodeChallenge.IsPresent())\n        {\n            _logger.LogDebug(\"Client required a proof key for code exchange. Starting PKCE validation\");\n\n            var proofKeyResult = ValidateAuthorizationCodeWithProofKeyParameters(codeVerifier, _validatedRequest.AuthorizationCode);\n            if (proofKeyResult.IsError)\n            {\n                return proofKeyResult;\n            }\n\n            _validatedRequest.CodeVerifier = codeVerifier;\n        }\n        else\n        {\n            if (codeVerifier.IsPresent())\n            {\n                LogError(\"Unexpected code_verifier: {codeVerifier}. This happens when the client is trying to use PKCE, but it is not enabled. Set RequirePkce to true.\", codeVerifier);\n                return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n            }\n        }\n\n        /////////////////////////////////////////////\n        // make sure user is enabled\n        /////////////////////////////////////////////\n        var isActiveCtx = new IsActiveContext(_validatedRequest.AuthorizationCode.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.AuthorizationCodeValidation);\n        await _profile.IsActiveAsync(isActiveCtx);\n\n        if (isActiveCtx.IsActive == false)\n        {\n            LogError(\"User has been disabled\", new { subjectId = _validatedRequest.AuthorizationCode.Subject.GetSubjectId() });\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        _logger.LogDebug(\"Validation of authorization code token request success\");\n\n        return Valid();\n    }\n\n    private async Task<TokenRequestValidationResult> ValidateClientCredentialsRequestAsync(NameValueCollection parameters)\n    {\n        _logger.LogDebug(\"Start client credentials token request validation\");\n\n        /////////////////////////////////////////////\n        // check if client is authorized for grant type\n        /////////////////////////////////////////////\n        if (!_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.ClientCredentials))\n        {\n            LogError(\"Client not authorized for client credentials flow, check the AllowedGrantTypes setting\", new { clientId = _validatedRequest.Client.ClientId });\n            return Invalid(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        /////////////////////////////////////////////\n        // check if client is allowed to request scopes\n        /////////////////////////////////////////////\n        if (!await ValidateRequestedScopesAsync(parameters, ignoreImplicitIdentityScopes: true, ignoreImplicitOfflineAccess: true))\n        {\n            return Invalid(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        if (_validatedRequest.ValidatedResources.Resources.IdentityResources.Any())\n        {\n            LogError(\"Client cannot request OpenID scopes in client credentials flow\", new { clientId = _validatedRequest.Client.ClientId });\n            return Invalid(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        if (_validatedRequest.ValidatedResources.Resources.OfflineAccess)\n        {\n            LogError(\"Client cannot request a refresh token in client credentials flow\", new { clientId = _validatedRequest.Client.ClientId });\n            return Invalid(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        _logger.LogDebug(\"{clientId} credentials token request validation success\", _validatedRequest.Client.ClientId);\n        return Valid();\n    }\n\n    private async Task<TokenRequestValidationResult> ValidateResourceOwnerCredentialRequestAsync(NameValueCollection parameters)\n    {\n        _logger.LogDebug(\"Start resource owner password token request validation\");\n\n        /////////////////////////////////////////////\n        // check if client is authorized for grant type\n        /////////////////////////////////////////////\n        if (!_validatedRequest.Client.AllowedGrantTypes.Contains(GrantType.ResourceOwnerPassword))\n        {\n            LogError(\"Client not authorized for resource owner flow, check the AllowedGrantTypes setting\", new { client_id = _validatedRequest.Client.ClientId });\n            return Invalid(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        /////////////////////////////////////////////\n        // check if client is allowed to request scopes\n        /////////////////////////////////////////////\n        if (!(await ValidateRequestedScopesAsync(parameters)))\n        {\n            return Invalid(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        /////////////////////////////////////////////\n        // check resource owner credentials\n        /////////////////////////////////////////////\n        var userName = parameters.Get(OidcConstants.TokenRequest.UserName);\n        var password = parameters.Get(OidcConstants.TokenRequest.Password);\n\n        if (userName.IsMissing())\n        {\n            LogError(\"Username is missing\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        if (password.IsMissing())\n        {\n            password = \"\";\n        }\n\n        if (userName.Length > _options.InputLengthRestrictions.UserName ||\n            password.Length > _options.InputLengthRestrictions.Password)\n        {\n            LogError(\"Username or password too long\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        _validatedRequest.UserName = userName;\n\n\n        /////////////////////////////////////////////\n        // authenticate user\n        /////////////////////////////////////////////\n        var resourceOwnerContext = new ResourceOwnerPasswordValidationContext\n        {\n            UserName = userName,\n            Password = password,\n            Request = _validatedRequest\n        };\n        await _resourceOwnerValidator.ValidateAsync(resourceOwnerContext);\n\n        if (resourceOwnerContext.Result.IsError)\n        {\n            // protect against bad validator implementations\n            resourceOwnerContext.Result.Error ??= OidcConstants.TokenErrors.InvalidGrant;\n\n            if (resourceOwnerContext.Result.Error == OidcConstants.TokenErrors.UnsupportedGrantType)\n            {\n                LogError(\"Resource owner password credential grant type not supported\");\n                await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, \"password grant type not supported\", resourceOwnerContext.Request.Client.ClientId);\n\n                return Invalid(OidcConstants.TokenErrors.UnsupportedGrantType, customResponse: resourceOwnerContext.Result.CustomResponse);\n            }\n\n            var errorDescription = \"invalid_username_or_password\";\n\n            if (resourceOwnerContext.Result.ErrorDescription.IsPresent())\n            {\n                errorDescription = resourceOwnerContext.Result.ErrorDescription;\n            }\n\n            LogInformation(\"User authentication failed: \", errorDescription ?? resourceOwnerContext.Result.Error);\n            await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, errorDescription, resourceOwnerContext.Request.Client.ClientId);\n\n            return Invalid(resourceOwnerContext.Result.Error, errorDescription, resourceOwnerContext.Result.CustomResponse);\n        }\n\n        if (resourceOwnerContext.Result.Subject == null)\n        {\n            var error = \"User authentication failed: no principal returned\";\n            LogError(error);\n            await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, error, resourceOwnerContext.Request.Client.ClientId);\n\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        /////////////////////////////////////////////\n        // make sure user is enabled\n        /////////////////////////////////////////////\n        var isActiveCtx = new IsActiveContext(resourceOwnerContext.Result.Subject, _validatedRequest.Client, IdentityServerConstants.ProfileIsActiveCallers.ResourceOwnerValidation);\n        await _profile.IsActiveAsync(isActiveCtx);\n\n        if (isActiveCtx.IsActive == false)\n        {\n            LogError(\"User has been disabled\", new { subjectId = resourceOwnerContext.Result.Subject.GetSubjectId() });\n            await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, \"user is inactive\", resourceOwnerContext.Request.Client.ClientId);\n\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        _validatedRequest.UserName = userName;\n        _validatedRequest.Subject = resourceOwnerContext.Result.Subject;\n\n        await RaiseSuccessfulResourceOwnerAuthenticationEventAsync(userName, resourceOwnerContext.Result.Subject.GetSubjectId(), resourceOwnerContext.Request.Client.ClientId);\n        _logger.LogDebug(\"Resource owner password token request validation success.\");\n        return Valid(resourceOwnerContext.Result.CustomResponse);\n    }\n\n    private async Task<TokenRequestValidationResult> ValidateRefreshTokenRequestAsync(NameValueCollection parameters)\n    {\n        _logger.LogDebug(\"Start validation of refresh token request\");\n\n        var refreshTokenHandle = parameters.Get(OidcConstants.TokenRequest.RefreshToken);\n        if (refreshTokenHandle.IsMissing())\n        {\n            LogError(\"Refresh token is missing\");\n            return Invalid(OidcConstants.TokenErrors.InvalidRequest);\n        }\n\n        if (refreshTokenHandle.Length > _options.InputLengthRestrictions.RefreshToken)\n        {\n            LogError(\"Refresh token too long\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        var result = await _refreshTokenService.ValidateRefreshTokenAsync(refreshTokenHandle, _validatedRequest.Client);\n\n        if (result.IsError)\n        {\n            LogWarning(\"Refresh token validation failed. aborting\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        _validatedRequest.RefreshToken = result.RefreshToken;\n        _validatedRequest.RefreshTokenHandle = refreshTokenHandle;\n        _validatedRequest.Subject = result.RefreshToken.Subject;\n\n        _logger.LogDebug(\"Validation of refresh token request success\");\n        // todo: more logging - similar to TokenValidator before\n        \n        return Valid();\n    }\n\n    private async Task<TokenRequestValidationResult> ValidateDeviceCodeRequestAsync(NameValueCollection parameters)\n    {\n        _logger.LogDebug(\"Start validation of device code request\");\n\n        /////////////////////////////////////////////\n        // check if client is authorized for grant type\n        /////////////////////////////////////////////\n        if (!_validatedRequest.Client.AllowedGrantTypes.ToList().Contains(GrantType.DeviceFlow))\n        {\n            LogError(\"Client not authorized for device flow\");\n            return Invalid(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        /////////////////////////////////////////////\n        // validate device code parameter\n        /////////////////////////////////////////////\n        var deviceCode = parameters.Get(OidcConstants.TokenRequest.DeviceCode);\n        if (deviceCode.IsMissing())\n        {\n            LogError(\"Device code is missing\");\n            return Invalid(OidcConstants.TokenErrors.InvalidRequest);\n        }\n\n        if (deviceCode.Length > _options.InputLengthRestrictions.DeviceCode)\n        {\n            LogError(\"Device code too long\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        /////////////////////////////////////////////\n        // validate device code\n        /////////////////////////////////////////////\n        var deviceCodeContext = new DeviceCodeValidationContext { DeviceCode = deviceCode, Request = _validatedRequest };\n        await _deviceCodeValidator.ValidateAsync(deviceCodeContext);\n\n        if (deviceCodeContext.Result.IsError) return deviceCodeContext.Result;\n\n        _logger.LogDebug(\"Validation of authorization code token request success\");\n\n        return Valid();\n    }\n\n    private async Task<TokenRequestValidationResult> ValidateExtensionGrantRequestAsync(NameValueCollection parameters)\n    {\n        _logger.LogDebug(\"Start validation of custom grant token request\");\n\n        /////////////////////////////////////////////\n        // check if client is allowed to use grant type\n        /////////////////////////////////////////////\n        if (!_validatedRequest.Client.AllowedGrantTypes.Contains(_validatedRequest.GrantType))\n        {\n            LogError(\"Client does not have the custom grant type in the allowed list, therefore requested grant is not allowed\", new { clientId = _validatedRequest.Client.ClientId });\n            return Invalid(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n\n        /////////////////////////////////////////////\n        // check if a validator is registered for the grant type\n        /////////////////////////////////////////////\n        if (!_extensionGrantValidator.GetAvailableGrantTypes().Contains(_validatedRequest.GrantType, StringComparer.Ordinal))\n        {\n            LogError(\"No validator is registered for the grant type\", new { grantType = _validatedRequest.GrantType });\n            return Invalid(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n\n        /////////////////////////////////////////////\n        // check if client is allowed to request scopes\n        /////////////////////////////////////////////\n        if (!await ValidateRequestedScopesAsync(parameters))\n        {\n            return Invalid(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        /////////////////////////////////////////////\n        // validate custom grant type\n        /////////////////////////////////////////////\n        var result = await _extensionGrantValidator.ValidateAsync(_validatedRequest);\n\n        if (result == null)\n        {\n            LogError(\"Invalid extension grant\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        if (result.IsError)\n        {\n            if (result.Error.IsPresent())\n            {\n                LogError(\"Invalid extension grant\", new { error = result.Error });\n                return Invalid(result.Error, result.ErrorDescription, result.CustomResponse);\n            }\n            else\n            {\n                LogError(\"Invalid extension grant\");\n                return Invalid(OidcConstants.TokenErrors.InvalidGrant, customResponse: result.CustomResponse);\n            }\n        }\n\n        if (result.Subject != null)\n        {\n            /////////////////////////////////////////////\n            // make sure user is enabled\n            /////////////////////////////////////////////\n            var isActiveCtx = new IsActiveContext(\n                result.Subject,\n                _validatedRequest.Client,\n                IdentityServerConstants.ProfileIsActiveCallers.ExtensionGrantValidation);\n\n            await _profile.IsActiveAsync(isActiveCtx);\n\n            if (isActiveCtx.IsActive == false)\n            {\n                // todo: raise event?\n\n                LogError(\"User has been disabled\", new { subjectId = result.Subject.GetSubjectId() });\n                return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n            }\n\n            _validatedRequest.Subject = result.Subject;\n        }\n\n        _logger.LogDebug(\"Validation of extension grant token request success\");\n        return Valid(result.CustomResponse);\n    }\n\n    // todo: do we want to rework the semantics of these ignore params?\n    // also seems like other workflows other than CC clients can omit scopes?\n    private async Task<bool> ValidateRequestedScopesAsync(NameValueCollection parameters, bool ignoreImplicitIdentityScopes = false, bool ignoreImplicitOfflineAccess = false)\n    {\n        var scopes = parameters.Get(OidcConstants.TokenRequest.Scope);\n        if (scopes.IsMissing())\n        {\n            _logger.LogTrace(\"Client provided no scopes - checking allowed scopes list\");\n\n            if (!_validatedRequest.Client.AllowedScopes.EnumerableIsNullOrEmpty())\n            {\n                // this finds all the scopes the client is allowed to access\n                var clientAllowedScopes = new List<string>();\n                if (!ignoreImplicitIdentityScopes)\n                {\n                    var resources = await _resourceStore.FindResourcesByScopeAsync(_validatedRequest.Client.AllowedScopes);\n                    clientAllowedScopes.AddRange(resources.ToScopeNames().Where(x => _validatedRequest.Client.AllowedScopes.Contains(x)));\n                }\n                else\n                {\n                    var apiScopes = await _resourceStore.FindApiScopesByNameAsync(_validatedRequest.Client.AllowedScopes);\n                    clientAllowedScopes.AddRange(apiScopes.Select(x => x.Name));\n                }\n\n                if (!ignoreImplicitOfflineAccess)\n                {\n                    if (_validatedRequest.Client.AllowOfflineAccess)\n                    {\n                        clientAllowedScopes.Add(IdentityServerConstants.StandardScopes.OfflineAccess);\n                    }\n                }\n\n                scopes = clientAllowedScopes.Distinct().ToSpaceSeparatedString();\n                _logger.LogTrace(\"Defaulting to: {scopes}\", scopes);\n            }\n            else\n            {\n                LogError(\"No allowed scopes configured for client\", new { clientId = _validatedRequest.Client.ClientId });\n                return false;\n            }\n        }\n\n        if (scopes.Length > _options.InputLengthRestrictions.Scope)\n        {\n            LogError(\"Scope parameter exceeds max allowed length\");\n            return false;\n        }\n\n        var requestedScopes = scopes.ParseScopesString();\n\n        if (requestedScopes == null)\n        {\n            LogError(\"No scopes found in request\");\n            return false;\n        }\n\n        var resourceValidationResult = await _resourceValidator.ValidateRequestedResourcesAsync(new ResourceValidationRequest { \n            Client = _validatedRequest.Client,\n            Scopes = requestedScopes\n        });\n\n        if (!resourceValidationResult.Succeeded)\n        {\n            if (resourceValidationResult.InvalidScopes.Any())\n            {\n                LogError(\"Invalid scopes requested\");\n            }\n            else\n            {\n                LogError(\"Invalid scopes for client requested\");\n            }\n\n            return false;\n        }\n\n        _validatedRequest.RequestedScopes = requestedScopes;\n        _validatedRequest.ValidatedResources = resourceValidationResult;\n        \n        return true;\n    }\n\n    private TokenRequestValidationResult ValidateAuthorizationCodeWithProofKeyParameters(string codeVerifier, AuthorizationCode authZcode)\n    {\n        if (authZcode.CodeChallenge.IsMissing() || authZcode.CodeChallengeMethod.IsMissing())\n        {\n            LogError(\"Client is missing code challenge or code challenge method\", new { clientId = _validatedRequest.Client.ClientId });\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        if (codeVerifier.IsMissing())\n        {\n            LogError(\"Missing code_verifier\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        if (codeVerifier.Length < _options.InputLengthRestrictions.CodeVerifierMinLength ||\n            codeVerifier.Length > _options.InputLengthRestrictions.CodeVerifierMaxLength)\n        {\n            LogError(\"code_verifier is too short or too long\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        if (Constants.SupportedCodeChallengeMethods.Contains(authZcode.CodeChallengeMethod) == false)\n        {\n            LogError(\"Unsupported code challenge method\", new { codeChallengeMethod = authZcode.CodeChallengeMethod });\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        if (ValidateCodeVerifierAgainstCodeChallenge(codeVerifier, authZcode.CodeChallenge, authZcode.CodeChallengeMethod) == false)\n        {\n            LogError(\"Transformed code verifier does not match code challenge\");\n            return Invalid(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        return Valid();\n    }\n\n    private bool ValidateCodeVerifierAgainstCodeChallenge(string codeVerifier, string codeChallenge, string codeChallengeMethod)\n    {\n        if (codeChallengeMethod == OidcConstants.CodeChallengeMethods.Plain)\n        {\n            return TimeConstantComparer.IsEqual(codeVerifier.Sha256(), codeChallenge);\n        }\n\n        var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier);\n        var hashedBytes = codeVerifierBytes.Sha256();\n        var transformedCodeVerifier = Base64Url.Encode(hashedBytes);\n\n        return TimeConstantComparer.IsEqual(transformedCodeVerifier.Sha256(), codeChallenge);\n    }\n\n    private TokenRequestValidationResult Valid(Dictionary<string, object> customResponse = null)\n    {\n        return new TokenRequestValidationResult(_validatedRequest, customResponse);\n    }\n\n    private TokenRequestValidationResult Invalid(string error, string errorDescription = null, Dictionary<string, object> customResponse = null)\n    {\n        return new TokenRequestValidationResult(_validatedRequest, error, errorDescription, customResponse);\n    }\n\n    private void LogError(string message = null, object values = null)\n    {\n        LogWithRequestDetails(LogLevel.Error, message, values);\n    }\n\n    private void LogWarning(string message = null, object values = null)\n    {\n        LogWithRequestDetails(LogLevel.Warning, message, values);\n    }\n\n    private void LogInformation(string message = null, object values = null)\n    {\n        LogWithRequestDetails(LogLevel.Information, message, values);\n    }\n\n    private void LogWithRequestDetails(LogLevel logLevel, string message = null, object values = null)\n    {\n        var details = new TokenRequestValidationLog(_validatedRequest, _options.Logging.TokenRequestSensitiveValuesFilter);\n\n        if (message.IsPresent())\n        {\n            try\n            {\n                if (values == null)\n                {\n                    _logger.Log(logLevel, message + \", {@details}\", details);\n                }\n                else\n                {\n                    _logger.Log(logLevel, message + \"{@values}, details: {@details}\", values, details);\n                }\n\n            }\n            catch (Exception ex)\n            {\n                _logger.LogError(\"Error logging {exception}, request details: {@details}\", ex.Message, details);\n            }\n        }\n        else\n        {\n            _logger.Log(logLevel, \"{@details}\", details);\n        }\n    }\n\n    private void LogSuccess()\n    {\n        LogWithRequestDetails(LogLevel.Information, \"Token request validation success\");\n    }\n\n    private Task RaiseSuccessfulResourceOwnerAuthenticationEventAsync(string userName, string subjectId, string clientId)\n    {\n        return _events.RaiseAsync(new UserLoginSuccessEvent(userName, subjectId, null, interactive: false, clientId));\n    }\n\n    private Task RaiseFailedResourceOwnerAuthenticationEventAsync(string userName, string error, string clientId)\n    {\n        return _events.RaiseAsync(new UserLoginFailureEvent(userName, error, interactive: false, clientId: clientId));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/TokenRevocationRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// The token revocation request validator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.ITokenRevocationRequestValidator\" />\ninternal class TokenRevocationRequestValidator : ITokenRevocationRequestValidator\n{\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRevocationRequestValidator\"/> class.\n    /// </summary>\n    /// <param name=\"logger\">The logger.</param>\n    public TokenRevocationRequestValidator(ILogger<TokenRevocationRequestValidator> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.ArgumentNullException\">\n    /// parameters\n    /// or\n    /// client\n    /// </exception>\n    public Task<TokenRevocationRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, Client client)\n    {\n        _logger.LogTrace(\"ValidateRequestAsync called\");\n\n        if (parameters == null)\n        {\n            _logger.LogError(\"no parameters passed\");\n            throw new ArgumentNullException(nameof(parameters));\n        }\n\n        if (client == null)\n        {\n            _logger.LogError(\"no client passed\");\n            throw new ArgumentNullException(nameof(client));\n        }\n\n        ////////////////////////////\n        // make sure token is present\n        ///////////////////////////\n        var token = parameters.Get(\"token\");\n        if (token.IsMissing())\n        {\n            _logger.LogError(\"No token found in request\");\n            return Task.FromResult(new TokenRevocationRequestValidationResult\n            {\n                IsError = true,\n                Error = OidcConstants.TokenErrors.InvalidRequest\n            });\n        }\n\n        var result = new TokenRevocationRequestValidationResult\n        {\n            IsError = false,\n            Token = token,\n            Client = client\n        };\n\n        ////////////////////////////\n        // check token type hint\n        ///////////////////////////\n        var hint = parameters.Get(\"token_type_hint\");\n        if (hint.IsPresent())\n        {\n            if (Constants.SupportedTokenTypeHints.Contains(hint))\n            {\n                _logger.LogDebug(\"Token type hint found in request: {tokenTypeHint}\", hint);\n                result.TokenTypeHint = hint;\n            }\n            else\n            {\n                _logger.LogError(\"Invalid token type hint: {tokenTypeHint}\", hint);\n                result.IsError = true;\n                result.Error = Constants.RevocationErrors.UnsupportedTokenType;\n            }\n        }\n\n        _logger.LogDebug(\"ValidateRequestAsync result: {validateRequestResult}\", result);\n\n        return Task.FromResult(result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/TokenValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer8.Validation;\n\ninternal class TokenValidator : ITokenValidator\n{\n    private readonly ILogger _logger;\n    private readonly IdentityServerOptions _options;\n    private readonly IHttpContextAccessor _context;\n    private readonly IReferenceTokenStore _referenceTokenStore;\n    private readonly ICustomTokenValidator _customValidator;\n    private readonly IClientStore _clients;\n    private readonly IProfileService _profile;\n    private readonly IKeyMaterialService _keys;\n    private readonly ISystemClock _clock;\n    private readonly TokenValidationLog _log;\n\n    public TokenValidator(\n        IdentityServerOptions options,\n        IHttpContextAccessor context,\n        IClientStore clients,\n        IProfileService profile,\n        IReferenceTokenStore referenceTokenStore,\n        IRefreshTokenStore refreshTokenStore,\n        ICustomTokenValidator customValidator,\n        IKeyMaterialService keys,\n        ISystemClock clock,\n        ILogger<TokenValidator> logger)\n    {\n        _options = options;\n        _context = context;\n        _clients = clients;\n        _profile = profile;\n        _referenceTokenStore = referenceTokenStore;\n        _customValidator = customValidator;\n        _keys = keys;\n        _clock = clock;\n        _logger = logger;\n\n        _log = new TokenValidationLog();\n    }\n\n    public async Task<TokenValidationResult> ValidateIdentityTokenAsync(string token, string clientId = null, bool validateLifetime = true)\n    {\n        _logger.LogDebug(\"Start identity token validation\");\n\n        if (token.Length > _options.InputLengthRestrictions.Jwt)\n        {\n            _logger.LogError(\"JWT too long\");\n            return Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        if (clientId.IsMissing())\n        {\n            clientId = GetClientIdFromJwt(token);\n\n            if (clientId.IsMissing())\n            {\n                _logger.LogError(\"No clientId supplied, can't find id in identity token.\");\n                return Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken);\n            }\n        }\n\n        _log.ClientId = clientId;\n        _log.ValidateLifetime = validateLifetime;\n\n        var client = await _clients.FindEnabledClientByIdAsync(clientId);\n        if (client == null)\n        {\n            _logger.LogError(\"Unknown or disabled client: {clientId}.\", clientId);\n            return Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        _log.ClientName = client.ClientName;\n        _logger.LogDebug(\"Client found: {clientId} / {clientName}\", client.ClientId, client.ClientName);\n\n        var keys = await _keys.GetValidationKeysAsync();\n        var result = await ValidateJwtAsync(token, keys, audience: clientId, validateLifetime: validateLifetime);\n\n        result.Client = client;\n\n        if (result.IsError)\n        {\n            LogError(\"Error validating JWT\");\n            return result;\n        }\n\n        _logger.LogDebug(\"Calling into custom token validator: {type}\", _customValidator.GetType().FullName);\n        var customResult = await _customValidator.ValidateIdentityTokenAsync(result);\n\n        if (customResult.IsError)\n        {\n            LogError(\"Custom validator failed: \" + (customResult.Error ?? \"unknown\"));\n            return customResult;\n        }\n\n        _log.Claims = customResult.Claims.ToClaimsDictionary();\n\n        LogSuccess();\n        return customResult;\n    }\n\n    public async Task<TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null)\n    {\n        _logger.LogTrace(\"Start access token validation\");\n\n        _log.ExpectedScope = expectedScope;\n        _log.ValidateLifetime = true;\n\n        TokenValidationResult result;\n\n        if (token.Contains(\".\"))\n        {\n            if (token.Length > _options.InputLengthRestrictions.Jwt)\n            {\n                _logger.LogError(\"JWT too long\");\n\n                return new TokenValidationResult\n                {\n                    IsError = true,\n                    Error = OidcConstants.ProtectedResourceErrors.InvalidToken,\n                    ErrorDescription = \"Token too long\"\n                };\n            }\n\n            _log.AccessTokenType = AccessTokenType.Jwt.ToString();\n            result = await ValidateJwtAsync(\n                token,\n                await _keys.GetValidationKeysAsync());\n        }\n        else\n        {\n            if (token.Length > _options.InputLengthRestrictions.TokenHandle)\n            {\n                _logger.LogError(\"token handle too long\");\n\n                return new TokenValidationResult\n                {\n                    IsError = true,\n                    Error = OidcConstants.ProtectedResourceErrors.InvalidToken,\n                    ErrorDescription = \"Token too long\"\n                };\n            }\n\n            _log.AccessTokenType = AccessTokenType.Reference.ToString();\n            result = await ValidateReferenceAccessTokenAsync(token);\n        }\n\n        _log.Claims = result.Claims.ToClaimsDictionary();\n\n        if (result.IsError)\n        {\n            return result;\n        }\n\n        // make sure client is still active (if client_id claim is present)\n        var clientClaim = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.ClientId);\n        if (clientClaim != null)\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(clientClaim.Value);\n            if (client == null)\n            {\n                _logger.LogError(\"Client deleted or disabled: {clientId}\", clientClaim.Value);\n\n                result.IsError = true;\n                result.Error = OidcConstants.ProtectedResourceErrors.InvalidToken;\n                result.Claims = null;\n\n                return result;\n            }\n        }\n\n        // make sure user is still active (if sub claim is present)\n        var subClaim = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Subject);\n        if (subClaim != null)\n        {\n            var principal = Principal.Create(\"tokenvalidator\", result.Claims.ToArray());\n\n            if (result.ReferenceTokenId.IsPresent())\n            {\n                principal.Identities.First().AddClaim(new Claim(JwtClaimTypes.ReferenceTokenId, result.ReferenceTokenId));\n            }\n\n            var isActiveCtx = new IsActiveContext(principal, result.Client, IdentityServerConstants.ProfileIsActiveCallers.AccessTokenValidation);\n            await _profile.IsActiveAsync(isActiveCtx);\n\n            if (isActiveCtx.IsActive == false)\n            {\n                _logger.LogError(\"User marked as not active: {subject}\", subClaim.Value);\n\n                result.IsError = true;\n                result.Error = OidcConstants.ProtectedResourceErrors.InvalidToken;\n                result.Claims = null;\n\n                return result;\n            }\n        }\n\n        // check expected scope(s)\n        if (expectedScope.IsPresent())\n        {\n            var scope = result.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.Scope && c.Value == expectedScope);\n            if (scope == null)\n            {\n                LogError($\"Checking for expected scope {expectedScope} failed\");\n                return Invalid(OidcConstants.ProtectedResourceErrors.InsufficientScope);\n            }\n        }\n\n        _logger.LogDebug(\"Calling into custom token validator: {type}\", _customValidator.GetType().FullName);\n        var customResult = await _customValidator.ValidateAccessTokenAsync(result);\n\n        if (customResult.IsError)\n        {\n            LogError(\"Custom validator failed: \" + (customResult.Error ?? \"unknown\"));\n            return customResult;\n        }\n\n        // add claims again after custom validation\n        _log.Claims = customResult.Claims.ToClaimsDictionary();\n\n        LogSuccess();\n        return customResult;\n    }\n\n    private async Task<TokenValidationResult> ValidateJwtAsync(string jwt, IEnumerable<SecurityKeyInfo> validationKeys, bool validateLifetime = true, string audience = null)\n    {\n        var handler = new JwtSecurityTokenHandler();\n        handler.InboundClaimTypeMap.Clear();\n\n        var parameters = new TokenValidationParameters\n        {\n            ValidIssuer = _context.HttpContext.GetIdentityServerIssuerUri(),\n            IssuerSigningKeys = validationKeys.Select(k => k.Key),\n            ValidateLifetime = validateLifetime\n        };\n\n        if (audience.IsPresent())\n        {\n            parameters.ValidAudience = audience;\n        }\n        else\n        {\n            parameters.ValidateAudience = false;\n        }\n\n        try\n        {\n            var id = handler.ValidateToken(jwt, parameters, out var securityToken);\n            var jwtSecurityToken = securityToken as JwtSecurityToken;\n\n            // if no audience is specified, we make at least sure that it is an access token\n            if (audience.IsMissing())\n            {\n                if (_options.AccessTokenJwtType.IsPresent())\n                {\n                    var type = jwtSecurityToken.Header.Typ;\n                    if (!string.Equals(type, _options.AccessTokenJwtType))\n                    {\n                        return new TokenValidationResult\n                        {\n                            IsError = true,\n                            Error = \"invalid JWT token type\"\n                        };\n                    }\n\n                }\n            }\n            \n            // if access token contains an ID, log it\n            var jwtId = id.FindFirst(JwtClaimTypes.JwtId);\n            if (jwtId != null)\n            {\n                _log.JwtId = jwtId.Value;\n            }\n\n            // load the client that belongs to the client_id claim\n            Client client = null;\n            var clientId = id.FindFirst(JwtClaimTypes.ClientId);\n            if (clientId != null)\n            {\n                client = await _clients.FindEnabledClientByIdAsync(clientId.Value);\n                if (client == null)\n                {\n                    throw new InvalidOperationException(\"Client does not exist anymore.\");\n                }\n            }\n\n            var claims = id.Claims.ToList();\n            \n            // check the scope format (array vs space delimited string)\n            var scopes = claims.Where(c => c.Type == JwtClaimTypes.Scope).ToArray();\n            if (scopes.Any())\n            {\n                foreach (var scope in scopes)\n                {\n                    if (scope.Value.Contains(\" \"))\n                    {\n                        claims.Remove(scope);\n                        \n                        var values = scope.Value.Split(' ', StringSplitOptions.RemoveEmptyEntries);\n                        foreach (var value in values)\n                        {\n                            claims.Add(new Claim(JwtClaimTypes.Scope, value));\n                        }\n                    }\n                }\n            }\n\n            return new TokenValidationResult\n            {\n                IsError = false,\n\n                Claims = claims,\n                Client = client,\n                Jwt = jwt\n            };\n        }\n        catch (SecurityTokenExpiredException expiredException)\n        {\n            _logger.LogInformation(expiredException, \"JWT token validation error: {exception}\", expiredException.Message);\n            return Invalid(OidcConstants.ProtectedResourceErrors.ExpiredToken);\n        }\n        catch (Exception ex)\n        {\n            _logger.LogError(ex, \"JWT token validation error: {exception}\", ex.Message);\n            return Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n    }\n\n    private async Task<TokenValidationResult> ValidateReferenceAccessTokenAsync(string tokenHandle)\n    {\n        _log.TokenHandle = tokenHandle;\n        var token = await _referenceTokenStore.GetReferenceTokenAsync(tokenHandle);\n\n        if (token == null)\n        {\n            LogError(\"Invalid reference token.\");\n            return Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        if (token.CreationTime.HasExceeded(token.Lifetime, _clock.UtcNow.UtcDateTime))\n        {\n            LogError(\"Token expired.\");\n\n            await _referenceTokenStore.RemoveReferenceTokenAsync(tokenHandle);\n            return Invalid(OidcConstants.ProtectedResourceErrors.ExpiredToken);\n        }\n\n        // load the client that is defined in the token\n        Client client = null;\n        if (token.ClientId != null)\n        {\n            client = await _clients.FindEnabledClientByIdAsync(token.ClientId);\n        }\n\n        if (client == null)\n        {\n            LogError($\"Client deleted or disabled: {token.ClientId}\");\n            return Invalid(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        return new TokenValidationResult\n        {\n            IsError = false,\n\n            Client = client,\n            Claims = ReferenceTokenToClaims(token),\n            ReferenceToken = token,\n            ReferenceTokenId = tokenHandle\n        };\n    }\n\n    private IEnumerable<Claim> ReferenceTokenToClaims(Token token)\n    {\n        var claims = new List<Claim>\n        {\n            new Claim(JwtClaimTypes.Issuer, token.Issuer),\n            new Claim(JwtClaimTypes.NotBefore, new DateTimeOffset(token.CreationTime).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64),\n            new Claim(JwtClaimTypes.Expiration, new DateTimeOffset(token.CreationTime).AddSeconds(token.Lifetime).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)\n        };\n\n        foreach (var aud in token.Audiences)\n        {\n            claims.Add(new Claim(JwtClaimTypes.Audience, aud));\n        }\n\n        claims.AddRange(token.Claims);\n        return claims;\n    }\n\n    private string GetClientIdFromJwt(string token)\n    {\n        try\n        {\n            var jwt = new JwtSecurityToken(token);\n            var clientId = jwt.Audiences.FirstOrDefault();\n\n            return clientId;\n        }\n        catch (Exception ex)\n        {\n            _logger.LogError(ex, \"Malformed JWT token: {exception}\", ex.Message);\n            return null;\n        }\n    }\n\n    private TokenValidationResult Invalid(string error)\n    {\n        return new TokenValidationResult\n        {\n            IsError = true,\n            Error = error\n        };\n    }\n\n    private void LogError(string message)\n    {\n        _logger.LogError(message + \"\\n{@logMessage}\", _log);\n    }\n\n    private void LogSuccess()\n    {\n        _logger.LogDebug(\"Token validation success\\n{@logMessage}\", _log);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/UserInfoRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Default userinfo request validator\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.IUserInfoRequestValidator\" />\ninternal class UserInfoRequestValidator : IUserInfoRequestValidator\n{\n    private readonly ITokenValidator _tokenValidator;\n    private readonly IProfileService _profile;\n    private readonly ILogger _logger;\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"UserInfoRequestValidator\" /> class.\n    /// </summary>\n    /// <param name=\"tokenValidator\">The token validator.</param>\n    /// <param name=\"profile\">The profile service</param>\n    /// <param name=\"logger\">The logger.</param>\n    public UserInfoRequestValidator(\n        ITokenValidator tokenValidator, \n        IProfileService profile,\n        ILogger<UserInfoRequestValidator> logger)\n    {\n        _tokenValidator = tokenValidator;\n        _profile = profile;\n        _logger = logger;\n    }\n\n    /// <summary>\n    /// Validates a userinfo request.\n    /// </summary>\n    /// <param name=\"accessToken\">The access token.</param>\n    /// <returns></returns>\n    /// <exception cref=\"System.NotImplementedException\"></exception>\n    public async Task<UserInfoRequestValidationResult> ValidateRequestAsync(string accessToken)\n    {\n        // the access token needs to be valid and have at least the openid scope\n        var tokenResult = await _tokenValidator.ValidateAccessTokenAsync(\n            accessToken,\n            IdentityServerConstants.StandardScopes.OpenId);\n\n        if (tokenResult.IsError)\n        {\n            return new UserInfoRequestValidationResult\n            {\n                IsError = true,\n                Error = tokenResult.Error\n            };\n        }\n\n        // the token must have a one sub claim\n        var subClaim = tokenResult.Claims.SingleOrDefault(c => c.Type == JwtClaimTypes.Subject);\n        if (subClaim == null)\n        {\n            _logger.LogError(\"Token contains no sub claim\");\n\n            return new UserInfoRequestValidationResult\n            {\n                IsError = true,\n                Error = OidcConstants.ProtectedResourceErrors.InvalidToken\n            };\n        }\n\n        // create subject from incoming access token\n        var claims = tokenResult.Claims.Where(x => !Constants.Filters.ProtocolClaimsFilter.Contains(x.Type));\n        var subject = Principal.Create(\"UserInfo\", claims.ToArray());\n\n        // make sure user is still active\n        var isActiveContext = new IsActiveContext(subject, tokenResult.Client, IdentityServerConstants.ProfileIsActiveCallers.UserInfoRequestValidation);\n        await _profile.IsActiveAsync(isActiveContext);\n\n        if (isActiveContext.IsActive == false)\n        {\n            _logger.LogError(\"User is not active: {sub}\", subject.GetSubjectId());\n\n            return new UserInfoRequestValidationResult\n            {\n                IsError = true,\n                Error = OidcConstants.ProtectedResourceErrors.InvalidToken\n            };\n        }\n\n        return new UserInfoRequestValidationResult\n        {\n            IsError = false,\n            TokenValidationResult = tokenResult,\n            Subject = subject\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/X509NameSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validator for an X.509 certificate based client secret using the common name\n/// </summary>\npublic class X509NameSecretValidator : ISecretValidator\n{\n    private readonly ILogger<X509NameSecretValidator> _logger;\n\n    /// <summary>\n    /// ctor\n    /// </summary>\n    /// <param name=\"logger\"></param>\n    public X509NameSecretValidator(ILogger<X509NameSecretValidator> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <inheritdoc/>\n    public Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret)\n    {\n        var fail = Task.FromResult(new SecretValidationResult { Success = false });\n\n        if (parsedSecret.Type != ParsedSecretTypes.X509Certificate)\n        {\n            _logger.LogDebug(\"X509 name secret validator cannot process {type}\", parsedSecret.Type ?? \"null\");\n            return fail;\n        }\n\n        if (!(parsedSecret.Credential is X509Certificate2 cert))\n        {\n            throw new InvalidOperationException(\"Credential is not a x509 certificate.\");\n        }\n\n        var name = cert.Subject;\n        if (name == null)\n        {\n            _logger.LogWarning(\"No subject/name found in X509 certificate.\");\n            return fail;\n        }\n\n        var nameSecrets = secrets.Where(s => s.Type == SecretTypes.X509CertificateName);\n        if (!nameSecrets.Any())\n        {\n            _logger.LogDebug(\"No x509 name secrets configured for client.\");\n            return fail;\n        }\n\n        foreach (var nameSecret in nameSecrets)\n        {\n            if (name.Equals(nameSecret.Value, StringComparison.Ordinal))\n            {\n                var result = new SecretValidationResult\n                {\n                    Success = true,\n                    Confirmation = cert.CreateThumbprintCnf()\n                };\n\n                return Task.FromResult(result);\n            }\n        }\n\n        _logger.LogDebug(\"No matching x509 name secret found.\");\n        return fail;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Default/X509ThumbprintSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validator for an X.509 certificate based client secret using the thumbprint\n/// </summary>\npublic class X509ThumbprintSecretValidator : ISecretValidator\n{\n    private readonly ILogger<X509ThumbprintSecretValidator> _logger;\n\n    /// <summary>\n    /// ctor\n    /// </summary>\n    /// <param name=\"logger\"></param>\n    public X509ThumbprintSecretValidator(ILogger<X509ThumbprintSecretValidator> logger)\n    {\n        _logger = logger;\n    }\n\n    /// <inheritdoc/>\n    public Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret)\n    {\n        var fail = Task.FromResult(new SecretValidationResult { Success = false });\n\n        if (parsedSecret.Type != ParsedSecretTypes.X509Certificate)\n        {\n            _logger.LogDebug(\"X509 thumbprint secret validator cannot process {type}\", parsedSecret.Type ?? \"null\");\n            return fail;\n        }\n\n        if (!(parsedSecret.Credential is X509Certificate2 cert))\n        {\n            throw new InvalidOperationException(\"Credential is not a x509 certificate.\");\n        }\n\n        var thumbprint = cert.Thumbprint;\n        if (thumbprint == null)\n        {\n            _logger.LogWarning(\"No thumbprint found in X509 certificate.\");\n            return fail;\n        }\n\n        var thumbprintSecrets = secrets.Where(s => s.Type == SecretTypes.X509CertificateThumbprint);\n        if (!thumbprintSecrets.Any())\n        {\n            _logger.LogDebug(\"No thumbprint secrets configured for client.\");\n            return fail;\n        }\n\n        foreach (var thumbprintSecret in thumbprintSecrets)\n        {\n            if (thumbprint.Equals(thumbprintSecret.Value, StringComparison.OrdinalIgnoreCase))\n            {\n                var result = new SecretValidationResult\n                {\n                    Success = true,\n                    Confirmation = cert.CreateThumbprintCnf()\n                };\n\n                return Task.FromResult(result);\n            }\n        }\n\n        _logger.LogDebug(\"No matching x509 thumbprint secret found.\");\n        return fail;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IApiSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validator for handling API client authentication.\n/// </summary>\npublic interface IApiSecretValidator\n{\n    /// <summary>\n    /// Tries to authenticate an API client based on the incoming request\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    Task<ApiSecretValidationResult> ValidateAsync(HttpContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IAuthorizeRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n///  Authorize endpoint request validator.\n/// </summary>\npublic interface IAuthorizeRequestValidator\n{\n    /// <summary>\n    ///  Validates authorize request parameters.\n    /// </summary>\n    /// <param name=\"parameters\"></param>\n    /// <param name=\"subject\"></param>\n    /// <returns></returns>\n    Task<AuthorizeRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject = null);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IClientConfigurationValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validator for handling client authentication\n/// </summary>\npublic interface IClientConfigurationValidator\n{\n    /// <summary>\n    /// Determines whether the configuration of a client is valid.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    Task ValidateAsync(ClientConfigurationValidationContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IClientSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validator for handling client authentication\n/// </summary>\npublic interface IClientSecretValidator\n{\n    /// <summary>\n    /// Tries to authenticate a client based on the incoming request\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    Task<ClientSecretValidationResult> ValidateAsync(HttpContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ICustomAuthorizeRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Allows inserting custom validation logic into authorize and token requests\n/// </summary>\npublic interface ICustomAuthorizeRequestValidator\n{\n    /// <summary>\n    /// Custom validation logic for the authorize request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    Task ValidateAsync(CustomAuthorizeRequestValidationContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ICustomTokenRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Allows inserting custom validation logic into token requests\n/// </summary>\npublic interface ICustomTokenRequestValidator\n{\n    /// <summary>\n    /// Custom validation logic for a token request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns>\n    /// The validation result\n    /// </returns>\n    Task ValidateAsync(CustomTokenRequestValidationContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ICustomTokenValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Allows inserting custom token validation logic\n/// </summary>\npublic interface ICustomTokenValidator\n{\n    /// <summary>\n    /// Custom validation logic for access tokens.\n    /// </summary>\n    /// <param name=\"result\">The validation result so far.</param>\n    /// <returns>The validation result</returns>\n    Task<TokenValidationResult> ValidateAccessTokenAsync(TokenValidationResult result);\n\n    /// <summary>\n    /// Custom validation logic for identity tokens.\n    /// </summary>\n    /// <param name=\"result\">The validation result so far.</param>\n    /// <returns>The validation result</returns>\n    Task<TokenValidationResult> ValidateIdentityTokenAsync(TokenValidationResult result);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IDeviceAuthorizationRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n///  Device authorization endpoint request validator.\n/// </summary>\npublic interface IDeviceAuthorizationRequestValidator\n{\n    /// <summary>\n    ///  Validates authorize request parameters.\n    /// </summary>\n    /// <param name=\"parameters\"></param>\n    /// <param name=\"clientValidationResult\"></param>\n    /// <returns></returns>\n    Task<DeviceAuthorizationRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IDeviceCodeValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// The device code validator\n/// </summary>\npublic interface IDeviceCodeValidator\n{\n    /// <summary>\n    /// Validates the device code.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns></returns>\n    Task ValidateAsync(DeviceCodeValidationContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IEndSessionRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n///  Validates end session requests.\n/// </summary>\npublic interface IEndSessionRequestValidator\n{\n    /// <summary>\n    /// Validates end session endpoint requests.\n    /// </summary>\n    /// <param name=\"parameters\"></param>\n    /// <param name=\"subject\"></param>\n    /// <returns></returns>\n    Task<EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject);\n\n    /// <summary>\n    ///  Validates requests from logout page iframe to trigger single signout.\n    /// </summary>\n    /// <param name=\"parameters\"></param>\n    /// <returns></returns>\n    Task<EndSessionCallbackValidationResult> ValidateCallbackAsync(NameValueCollection parameters);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Handles validation of token requests using custom grant types\n/// </summary>\npublic interface IExtensionGrantValidator\n{\n    /// <summary>\n    /// Validates the custom grant request.\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    /// <returns>\n    /// A principal\n    /// </returns>\n    Task ValidateAsync(ExtensionGrantValidationContext context);\n\n    /// <summary>\n    /// Returns the grant type this validator can deal with\n    /// </summary>\n    /// <value>\n    /// The type of the grant.\n    /// </value>\n    string GrantType { get; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IIntrospectionRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Interface for the introspection request validator\n/// </summary>\npublic interface IIntrospectionRequestValidator\n{\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"api\">The API.</param>\n    /// <returns></returns>\n    Task<IntrospectionRequestValidationResult> ValidateAsync(NameValueCollection parameters, ApiResource api);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IRedirectUriValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models the logic when validating redirect and post logout redirect URIs.\n/// </summary>\npublic interface IRedirectUriValidator\n{\n    /// <summary>\n    /// Determines whether a redirect URI is valid for a client.\n    /// </summary>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns><c>true</c> is the URI is valid; <c>false</c> otherwise.</returns>\n    Task<bool> IsRedirectUriValidAsync(string requestedUri, Client client);\n    \n    /// <summary>\n    /// Determines whether a post logout URI is valid for a client.\n    /// </summary>\n    /// <param name=\"requestedUri\">The requested URI.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns><c>true</c> is the URI is valid; <c>false</c> otherwise.</returns>\n    Task<bool> IsPostLogoutRedirectUriValidAsync(string requestedUri, Client client);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IResourceOwnerPasswordValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Handles validation of resource owner password credentials\n/// </summary>\npublic interface IResourceOwnerPasswordValidator\n{\n    /// <summary>\n    /// Validates the resource owner password credential\n    /// </summary>\n    /// <param name=\"context\">The context.</param>\n    Task ValidateAsync(ResourceOwnerPasswordValidationContext context);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IResourceValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validates requested resources (scopes and resource indicators)\n/// </summary>\npublic interface IResourceValidator\n{\n    // todo: should this be used anywhere we re-create tokens? do we need to re-run scope validation?\n\n    /// <summary>\n    /// Validates the requested resources for the client.\n    /// </summary>\n    Task<ResourceValidationResult> ValidateRequestedResourcesAsync(ResourceValidationRequest request);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IScopeParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Allows parsing raw scopes values into structured scope values.\n/// </summary>\npublic interface IScopeParser\n{\n    // todo: test return no error, and no parsed scopes. how do callers behave?\n    /// <summary>\n    /// Parses the requested scopes.\n    /// </summary>\n    ParsedScopesResult ParseScopeValues(IEnumerable<string> scopeValues);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ISecretParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// A service for parsing secrets found on the request\n/// </summary>\npublic interface ISecretParser\n{\n    /// <summary>\n    /// Tries to find a secret on the context that can be used for authentication\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns>\n    /// A parsed secret\n    /// </returns>\n    Task<ParsedSecret> ParseAsync(HttpContext context);\n\n    /// <summary>\n    /// Returns the authentication method name that this parser implements\n    /// </summary>\n    /// <value>\n    /// The authentication method.\n    /// </value>\n    string AuthenticationMethod { get; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ISecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Service for validating a received secret against a stored secret\n/// </summary>\npublic interface ISecretValidator\n{\n    /// <summary>\n    /// Validates a secret\n    /// </summary>\n    /// <param name=\"secrets\">The stored secrets.</param>\n    /// <param name=\"parsedSecret\">The received secret.</param>\n    /// <returns>A validation result</returns>\n    Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ISecretsListParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Parser for finding the best secret in an Enumerable List\n/// </summary>\npublic interface ISecretsListParser\n{\n    /// <summary>\n    /// Tries to find the best secret on the context that can be used for authentication\n    /// </summary>\n    /// <param name=\"context\">The HTTP context.</param>\n    /// <returns>\n    /// A parsed secret\n    /// </returns>\n    Task<ParsedSecret> ParseAsync(HttpContext context);\n\n    /// <summary>\n    /// Gets all available authentication methods.\n    /// </summary>\n    /// <returns></returns>\n    IEnumerable<string> GetAvailableAuthenticationMethods();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ISecretsListValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validator for an Enumerable List of Secrets\n/// </summary>\npublic interface ISecretsListValidator\n{\n    /// <summary>\n    /// Validates a list of secrets\n    /// </summary>\n    /// <param name=\"secrets\">The stored secrets.</param>\n    /// <param name=\"parsedSecret\">The received secret.</param>\n    /// <returns>A validation result</returns>\n    Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ITokenRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Interface for the token request validator\n/// </summary>\npublic interface ITokenRequestValidator\n{\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"clientValidationResult\">The client validation result.</param>\n    /// <returns></returns>\n    Task<TokenRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, ClientSecretValidationResult clientValidationResult);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ITokenRevocationRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Interface for the token revocation request validator\n/// </summary>\npublic interface ITokenRevocationRequestValidator\n{\n    /// <summary>\n    /// Validates the request.\n    /// </summary>\n    /// <param name=\"parameters\">The parameters.</param>\n    /// <param name=\"client\">The client.</param>\n    /// <returns></returns>\n    Task<TokenRevocationRequestValidationResult> ValidateRequestAsync(NameValueCollection parameters, Client client);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/ITokenValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Interface for the token validator\n/// </summary>\npublic interface ITokenValidator\n{\n    /// <summary>\n    /// Validates an access token.\n    /// </summary>\n    /// <param name=\"token\">The access token.</param>\n    /// <param name=\"expectedScope\">The expected scope.</param>\n    /// <returns></returns>\n    Task<TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null);\n    \n    /// <summary>\n    /// Validates an identity token.\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <param name=\"validateLifetime\">if set to <c>true</c> the lifetime gets validated. Otherwise not.</param>\n    /// <returns></returns>\n    Task<TokenValidationResult> ValidateIdentityTokenAsync(string token, string clientId = null, bool validateLifetime = true);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/IUserInfoRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validator for userinfo requests\n/// </summary>\npublic interface IUserInfoRequestValidator\n{\n    /// <summary>\n    /// Validates a userinfo request.\n    /// </summary>\n    /// <param name=\"accessToken\">The access token.</param>\n    /// <returns></returns>\n    Task<UserInfoRequestValidationResult> ValidateRequestAsync(string accessToken);\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/AuthorizeRequestValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for authorize requests\n/// </summary>\npublic class AuthorizeRequestValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"AuthorizeRequestValidationResult\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    public AuthorizeRequestValidationResult(ValidatedAuthorizeRequest request)\n    {\n        ValidatedRequest = request;\n        IsError = false;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"AuthorizeRequestValidationResult\" /> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"error\">The error.</param>\n    /// <param name=\"errorDescription\">The error description.</param>\n    public AuthorizeRequestValidationResult(ValidatedAuthorizeRequest request, string error, string errorDescription = null)\n    {\n        ValidatedRequest = request;\n        IsError = true;\n        Error = error;\n        ErrorDescription = errorDescription;\n    }\n\n    /// <summary>\n    /// Gets or sets the validated request.\n    /// </summary>\n    /// <value>\n    /// The validated request.\n    /// </value>\n    public ValidatedAuthorizeRequest ValidatedRequest { get; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/BearerTokenUsageType.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Validation;\n\npublic enum BearerTokenUsageType\n{\n    AuthorizationHeader = 0,\n    PostBody = 1,\n    QueryString = 2\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/BearerTokenUsageValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models usage of a bearer token\n/// </summary>\npublic class BearerTokenUsageValidationResult\n{\n    /// <summary>\n    /// Gets or sets a value indicating whether the token was found.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if the token was found; otherwise, <c>false</c>.\n    /// </value>\n    public bool TokenFound { get; set; }\n\n    /// <summary>\n    /// Gets or sets the token.\n    /// </summary>\n    /// <value>\n    /// The token.\n    /// </value>\n    public string Token { get; set; }\n\n    /// <summary>\n    /// Gets or sets the usage type.\n    /// </summary>\n    /// <value>\n    /// The type of the usage.\n    /// </value>\n    public BearerTokenUsageType UsageType { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ClientSecretValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for client validation\n/// </summary>\npublic class ClientSecretValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the client.\n    /// </summary>\n    /// <value>\n    /// The client.\n    /// </value>\n    public Client Client { get; set; }\n\n    /// <summary>\n    /// Gets or sets the secret used to authenticate the client.\n    /// </summary>\n    /// <value>\n    /// The secret.\n    /// </value>\n    public ParsedSecret Secret { get; set; }\n\n    /// <summary>\n    /// Gets or sets the value of the confirmation method (will become the cnf claim). Must be a JSON object.\n    /// </summary>\n    /// <value>\n    /// The confirmation.\n    /// </value>\n    public string Confirmation { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/DeviceAuthorizationRequestValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for device authorization requests\n/// </summary>\npublic class DeviceAuthorizationRequestValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceAuthorizationRequestValidationResult\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    public DeviceAuthorizationRequestValidationResult(ValidatedDeviceAuthorizationRequest request)\n    {\n        IsError = false;\n\n        ValidatedRequest = request;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"DeviceAuthorizationRequestValidationResult\"/> class.\n    /// </summary>\n    /// <param name=\"request\">The request.</param>\n    /// <param name=\"error\">The error.</param>\n    /// <param name=\"errorDescription\">The error description.</param>\n    public DeviceAuthorizationRequestValidationResult(ValidatedDeviceAuthorizationRequest request, string error, string errorDescription = null)\n    {\n        IsError = true;\n\n        Error = error;\n        ErrorDescription = errorDescription;\n        ValidatedRequest = request;\n    }\n\n    /// <summary>\n    /// Gets the validated request.\n    /// </summary>\n    /// <value>\n    /// The validated request.\n    /// </value>\n    public ValidatedDeviceAuthorizationRequest ValidatedRequest { get; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/DeviceCodeValidationContext.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for device code validation request.\n/// </summary>\npublic class DeviceCodeValidationContext\n{\n    /// <summary>\n    /// Gets or sets the device code.\n    /// </summary>\n    /// <value>\n    /// The device code.\n    /// </value>\n    public string DeviceCode { get; set; }\n\n    /// <summary>\n    /// Gets or sets the request.\n    /// </summary>\n    /// <value>\n    /// The request.\n    /// </value>\n    public ValidatedTokenRequest Request { get; set; }\n\n    /// <summary>\n    /// Gets or sets the result.\n    /// </summary>\n    /// <value>\n    /// The result.\n    /// </value>\n    public TokenRequestValidationResult Result { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/EndSessionCallbackValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for end session callback requests.\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.ValidationResult\" />\npublic class EndSessionCallbackValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets the client front-channel logout urls.\n    /// </summary>\n    public IEnumerable<string> FrontChannelLogoutUrls { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/EndSessionValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for end session requests\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.ValidationResult\" />\npublic class EndSessionValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the validated request.\n    /// </summary>\n    /// <value>\n    /// The validated request.\n    /// </value>\n    public ValidatedEndSessionRequest ValidatedRequest { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/GrantValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models the result of custom grant validation.\n/// </summary>\npublic class GrantValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the principal which represents the result of the validation.\n    /// </summary>\n    /// <value>\n    /// The principal.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n\n    /// <summary>\n    /// Custom fields for the token response\n    /// </summary>\n    public Dictionary<string, object> CustomResponse { get; set; } = new Dictionary<string, object>();\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"GrantValidationResult\"/> class with no subject.\n    /// Warning: the resulting access token will only contain the client identity.\n    /// </summary>\n    public GrantValidationResult(Dictionary<string, object> customResponse = null)\n    {\n        IsError = false;\n        CustomResponse = customResponse;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"GrantValidationResult\"/> class with a given principal.\n    /// Warning: the principal needs to include the required claims - it is recommended to use the other constructor that does validation.\n    /// </summary>\n    public GrantValidationResult(ClaimsPrincipal principal, Dictionary<string, object> customResponse = null)\n    {\n        IsError = false;\n\n        if (principal.Identities.Count() != 1) throw new InvalidOperationException(\"only a single identity supported\");\n        if (principal.FindFirst(JwtClaimTypes.Subject) == null) throw new InvalidOperationException(\"sub claim is missing\");\n        if (principal.FindFirst(JwtClaimTypes.IdentityProvider) == null) throw new InvalidOperationException(\"idp claim is missing\");\n        if (principal.FindFirst(JwtClaimTypes.AuthenticationMethod) == null) throw new InvalidOperationException(\"amr claim is missing\");\n        if (principal.FindFirst(JwtClaimTypes.AuthenticationTime) == null) throw new InvalidOperationException(\"auth_time claim is missing\");\n\n        Subject = principal;\n        CustomResponse = customResponse;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"GrantValidationResult\"/> class with an error and description.\n    /// </summary>\n    /// <param name=\"error\">The error.</param>\n    /// <param name=\"errorDescription\">The error description.</param>\n    /// <param name=\"customResponse\">Custom response elements</param>\n    public GrantValidationResult(TokenRequestErrors error, string errorDescription = null, Dictionary<string, object> customResponse = null)\n    {\n        Error = ConvertTokenErrorEnumToString(error);\n        ErrorDescription = errorDescription;\n        CustomResponse = customResponse;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"GrantValidationResult\" /> class.\n    /// </summary>\n    /// <param name=\"subject\">The subject claim used to uniquely identifier the user.</param>\n    /// <param name=\"authenticationMethod\">The authentication method which describes the custom grant type.</param>\n    /// <param name=\"claims\">Additional claims that will be maintained in the principal. \n    /// If you want these claims to appear in token, you need to add them explicitly in your custom implementation of <see cref=\"Services.IProfileService\"/> service.</param>\n    /// <param name=\"identityProvider\">The identity provider.</param>\n    /// <param name=\"customResponse\">The custom response.</param>\n    public GrantValidationResult(\n        string subject,\n        string authenticationMethod,\n        IEnumerable<Claim> claims = null,\n        string identityProvider = IdentityServerConstants.LocalIdentityProvider,\n        Dictionary<string, object> customResponse = null)\n        : this(subject, authenticationMethod, DateTime.UtcNow, claims, identityProvider, customResponse)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"GrantValidationResult\" /> class.\n    /// </summary>\n    /// <param name=\"subject\">The subject claim used to uniquely identifier the user.</param>\n    /// <param name=\"authenticationMethod\">The authentication method which describes the custom grant type.</param>\n    /// <param name=\"authTime\">The UTC date/time of authentication.</param>\n    /// <param name=\"claims\">Additional claims that will be maintained in the principal.\n    /// If you want these claims to appear in token, you need to add them explicitly in your custom implementation of <see cref=\"Services.IProfileService\"/> service.</param>\n    /// <param name=\"identityProvider\">The identity provider.</param>\n    /// <param name=\"customResponse\">The custom response.</param>\n    public GrantValidationResult(\n        string subject,\n        string authenticationMethod,\n        DateTime authTime,\n        IEnumerable<Claim> claims = null,\n        string identityProvider = IdentityServerConstants.LocalIdentityProvider,\n        Dictionary<string, object> customResponse = null)\n    {\n        IsError = false;\n\n        var resultClaims = new List<Claim>\n        {\n            new Claim(JwtClaimTypes.Subject, subject),\n            new Claim(JwtClaimTypes.AuthenticationMethod, authenticationMethod),\n            new Claim(JwtClaimTypes.IdentityProvider, identityProvider),\n            new Claim(JwtClaimTypes.AuthenticationTime, new DateTimeOffset(authTime).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)\n        };\n\n        if (!claims.EnumerableIsNullOrEmpty())\n        {\n            resultClaims.AddRange(claims);\n        }\n\n        var id = new ClaimsIdentity(authenticationMethod);\n        id.AddClaims(resultClaims.Distinct(new ClaimComparer()));\n\n        Subject = new ClaimsPrincipal(id);\n        CustomResponse = customResponse;\n    }\n\n    private string ConvertTokenErrorEnumToString(TokenRequestErrors error)\n    {\n        return error switch\n        {\n            TokenRequestErrors.InvalidClient => OidcConstants.TokenErrors.InvalidClient,\n            TokenRequestErrors.InvalidGrant => OidcConstants.TokenErrors.InvalidGrant,\n            TokenRequestErrors.InvalidRequest => OidcConstants.TokenErrors.InvalidRequest,\n            TokenRequestErrors.InvalidScope => OidcConstants.TokenErrors.InvalidScope,\n            TokenRequestErrors.UnauthorizedClient => OidcConstants.TokenErrors.UnauthorizedClient,\n            TokenRequestErrors.UnsupportedGrantType => OidcConstants.TokenErrors.UnsupportedGrantType,\n            TokenRequestErrors.InvalidTarget => OidcConstants.TokenErrors.InvalidTarget,\n            _ => throw new InvalidOperationException(\"invalid token error\")\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/IntrospectionRequestValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for introspection request\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Validation.ValidationResult\" />\npublic class IntrospectionRequestValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the request parameters.\n    /// </summary>\n    /// <value>\n    /// The parameters.\n    /// </value>\n    public NameValueCollection Parameters { get; set; }\n\n    /// <summary>\n    /// Gets or sets the API.\n    /// </summary>\n    /// <value>\n    /// The API.\n    /// </value>\n    public ApiResource Api { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the token is active.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if the token is active; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsActive { get; set; }\n\n    /// <summary>\n    /// Gets or sets the claims.\n    /// </summary>\n    /// <value>\n    /// The claims.\n    /// </value>\n    public IEnumerable<Claim> Claims { get; set; }\n\n    /// <summary>\n    /// Gets or sets the token.\n    /// </summary>\n    /// <value>\n    /// The token.\n    /// </value>\n    public string Token { get; set; }\n}\n\n/// <summary>\n/// Failure reasons for introspection request\n/// </summary>\npublic enum IntrospectionRequestValidationFailureReason\n{\n    /// <summary>\n    /// none\n    /// </summary>\n    None,\n\n    /// <summary>\n    /// missing token\n    /// </summary>\n    MissingToken,\n\n    /// <summary>\n    /// invalid token\n    /// </summary>\n    InvalidToken,\n\n    /// <summary>\n    /// invalid scope\n    /// </summary>\n    InvalidScope\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/JwtRequestValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models the result of JWT request validation.\n/// </summary>\npublic class JwtRequestValidationResult : ValidationResult\n{\n    /// <summary>\n    /// The key/value pairs from the JWT payload of a successfuly validated request.\n    /// </summary>\n    public Dictionary<string, string> Payload { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ParsedScopeValidationError.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models an error parsing a scope.\n/// </summary>\npublic class ParsedScopeValidationError\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    /// <param name=\"rawValue\"></param>\n    /// <param name=\"error\"></param>\n    public ParsedScopeValidationError(string rawValue, string error)\n    {\n        if (String.IsNullOrWhiteSpace(rawValue))\n        {\n            throw new ArgumentNullException(nameof(rawValue));\n        }\n\n        if (String.IsNullOrWhiteSpace(error))\n        {\n            throw new ArgumentNullException(nameof(error));\n        }\n\n        RawValue = rawValue;\n        Error = error;\n    }\n\n    /// <summary>\n    /// The original (raw) value of the scope.\n    /// </summary>\n    public string RawValue { get; set; }\n\n    /// <summary>\n    /// Error message describing why the raw scope failed to be parsed.\n    /// </summary>\n    public string Error { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ParsedScopeValue.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models a parsed scope value.\n/// </summary>\npublic class ParsedScopeValue\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    /// <param name=\"rawValue\"></param>\n    public ParsedScopeValue(string rawValue)\n        : this(rawValue, rawValue, null)\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    /// <param name=\"rawValue\"></param>\n    /// <param name=\"parsedName\"></param>\n    /// <param name=\"parsedParameter\"></param>\n    public ParsedScopeValue(string rawValue, string parsedName, string parsedParameter)\n    {\n        if (String.IsNullOrWhiteSpace(rawValue))\n        {\n            throw new ArgumentNullException(nameof(rawValue));\n        }\n\n        if (String.IsNullOrWhiteSpace(parsedName))\n        {\n            throw new ArgumentNullException(nameof(parsedName));\n        }\n\n        RawValue = rawValue;\n        ParsedName = parsedName;\n        ParsedParameter = parsedParameter;\n    }\n\n    /// <summary>\n    /// The original (raw) value of the scope.\n    /// </summary>\n    public string RawValue { get; set; }\n\n    /// <summary>\n    /// The parsed name of the scope. If the scope has no structure, the parsed name will be the same as the raw value.\n    /// </summary>\n    public string ParsedName { get; set; }\n\n    // future: maybe this should be something w/ more structure? dictionary?\n    /// <summary>\n    /// The parameter value of the parsed scope. If the scope has no structure, then the value will be null.\n    /// </summary>\n    public string ParsedParameter { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ParsedScopesResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Represents the result of scope parsing.\n/// </summary>\npublic class ParsedScopesResult\n{\n    /// <summary>\n    /// The valid parsed scopes.\n    /// </summary>\n    public ICollection<ParsedScopeValue> ParsedScopes { get; set; } = new HashSet<ParsedScopeValue>();\n\n    /// <summary>\n    /// The errors encountered while parsing.\n    /// </summary>\n    public ICollection<ParsedScopeValidationError> Errors { get; set; } = new HashSet<ParsedScopeValidationError>();\n\n    /// <summary>\n    /// Indicates if the result of parsing the scopes was successful.\n    /// </summary>\n    public bool Succeeded => Errors == null || !Errors.Any();\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ResourceValidationRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models the request to validate scopes and resource indicators for a client.\n/// </summary>\npublic class ResourceValidationRequest\n{\n    /// <summary>\n    /// The client.\n    /// </summary>\n    public Client Client { get; set; }\n\n    /// <summary>\n    /// The requested scope values.\n    /// </summary>\n    public IEnumerable<string> Scopes { get; set; }\n\n    // /// <summary>\n    // /// The requested resource indicators.\n    // /// </summary>\n    //  todo: add back when we support resource indicators\n    // public IEnumerable<string> ResourceIndicators { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ResourceValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Result of validation of requested scopes and resource indicators.\n/// </summary>\npublic class ResourceValidationResult\n{\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    public ResourceValidationResult()\n    {\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    /// <param name=\"resources\"></param>\n    public ResourceValidationResult(Resources resources)\n    {\n        Resources = resources;\n        ParsedScopes = resources.ToScopeNames().Select(x => new ParsedScopeValue(x)).ToList();\n    }\n\n    /// <summary>\n    /// Ctor\n    /// </summary>\n    /// <param name=\"resources\"></param>\n    /// <param name=\"parsedScopeValues\"></param>\n    public ResourceValidationResult(Resources resources, IEnumerable<ParsedScopeValue> parsedScopeValues)\n    {\n        Resources = resources;\n        ParsedScopes = parsedScopeValues.ToList();\n    }\n\n    /// <summary>\n    /// Indicates if the result was successful.\n    /// </summary>\n    public bool Succeeded => ParsedScopes.Any() && !InvalidScopes.Any();\n\n    /// <summary>\n    /// The resources of the result.\n    /// </summary>\n    public Resources Resources { get; set; } = new Resources();\n\n    /// <summary>\n    /// The parsed scopes represented by the result.\n    /// </summary>\n    public ICollection<ParsedScopeValue> ParsedScopes { get; set; } = new HashSet<ParsedScopeValue>();\n\n    /// <summary>\n    /// The original (raw) scope values represented by the validated result.\n    /// </summary>\n    public IEnumerable<string> RawScopeValues => ParsedScopes.Select(x => x.RawValue);\n\n    /// <summary>\n    /// The requested scopes that are invalid.\n    /// </summary>\n    public ICollection<string> InvalidScopes { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Returns new result filted by the scope values.\n    /// </summary>\n    /// <param name=\"scopeValues\"></param>\n    /// <returns></returns>\n    public ResourceValidationResult Filter(IEnumerable<string> scopeValues)\n    {\n        scopeValues ??= Enumerable.Empty<string>();\n\n        var offline = scopeValues.Contains(IdentityServerConstants.StandardScopes.OfflineAccess);\n\n        var parsedScopesToKeep = ParsedScopes.Where(x => scopeValues.Contains(x.RawValue)).ToArray();\n        var parsedScopeNamesToKeep = parsedScopesToKeep.Select(x => x.ParsedName).ToArray();\n\n        var identityToKeep = Resources.IdentityResources.Where(x => parsedScopeNamesToKeep.Contains(x.Name));\n        var apiScopesToKeep = Resources.ApiScopes.Where(x => parsedScopeNamesToKeep.Contains(x.Name));\n\n        var apiScopesNamesToKeep = apiScopesToKeep.Select(x => x.Name).ToArray();\n        var apiResourcesToKeep = Resources.ApiResources.Where(x => x.Scopes.Any(y => apiScopesNamesToKeep.Contains(y)));\n\n        var resources = new Resources(identityToKeep, apiResourcesToKeep, apiScopesToKeep)\n        {\n            OfflineAccess = offline\n        };\n        \n        return new ResourceValidationResult()\n        {\n            Resources = resources,\n            ParsedScopes = parsedScopesToKeep\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ScopeSecretValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for API validation\n/// </summary>\npublic class ApiSecretValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the resource.\n    /// </summary>\n    /// <value>\n    /// The resource.\n    /// </value>\n    public ApiResource Resource { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/SecretValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for secrets\n/// </summary>\npublic class SecretValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets a value indicating whether the secret validation was successful.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if success; otherwise, <c>false</c>.\n    /// </value>\n    public bool Success { get; set; }\n\n    /// <summary>\n    /// Gets or sets the value of the confirmation method (will become the cnf claim). Must be a JSON object.\n    /// </summary>\n    /// <value>\n    /// The confirmation.\n    /// </value>\n    public string Confirmation { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/TokenRequestValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for token requests\n/// </summary>\npublic class TokenRequestValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRequestValidationResult\"/> class.\n    /// </summary>\n    /// <param name=\"validatedRequest\">The validated request.</param>\n    /// <param name=\"customResponse\">The custom response.</param>\n    public TokenRequestValidationResult(ValidatedTokenRequest validatedRequest, Dictionary<string, object> customResponse = null)\n    {\n        IsError = false;\n\n        ValidatedRequest = validatedRequest;\n        CustomResponse = customResponse;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"TokenRequestValidationResult\"/> class.\n    /// </summary>\n    /// <param name=\"validatedRequest\">The validated request.</param>\n    /// <param name=\"error\">The error.</param>\n    /// <param name=\"errorDescription\">The error description.</param>\n    /// <param name=\"customResponse\">The custom response.</param>\n    public TokenRequestValidationResult(ValidatedTokenRequest validatedRequest, string error, string errorDescription = null, Dictionary<string, object> customResponse = null)\n    {\n        IsError = true;\n\n        Error = error;\n        ErrorDescription = errorDescription;\n        ValidatedRequest = validatedRequest;\n        CustomResponse = customResponse;\n    }\n\n    /// <summary>\n    /// Gets the validated request.\n    /// </summary>\n    /// <value>\n    /// The validated request.\n    /// </value>\n    public ValidatedTokenRequest ValidatedRequest { get; }\n\n    /// <summary>\n    /// Gets or sets the custom response.\n    /// </summary>\n    /// <value>\n    /// The custom response.\n    /// </value>\n    public Dictionary<string, object> CustomResponse { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/TokenRevocationRequestValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models the validation result of access tokens and id tokens.\n/// </summary>\npublic class TokenRevocationRequestValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the token type hint.\n    /// </summary>\n    /// <value>\n    /// The token type hint.\n    /// </value>\n    public string TokenTypeHint { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the token.\n    /// </summary>\n    /// <value>\n    /// The token.\n    /// </value>\n    public string Token { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client.\n    /// </summary>\n    /// <value>\n    /// The client.\n    /// </value>\n    public Client Client { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/TokenValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models the validation result of access tokens and id tokens.\n/// </summary>\npublic class TokenValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the claims.\n    /// </summary>\n    /// <value>\n    /// The claims.\n    /// </value>\n    public IEnumerable<Claim> Claims { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the JWT.\n    /// </summary>\n    /// <value>\n    /// The JWT.\n    /// </value>\n    public string Jwt { get; set; }\n\n    /// <summary>\n    /// Gets or sets the reference token (in case of access token validation).\n    /// </summary>\n    /// <value>\n    /// The reference token.\n    /// </value>\n    public Token ReferenceToken { get; set; }\n\n    /// <summary>\n    /// Gets or sets the reference token identifier (in case of access token validation).\n    /// </summary>\n    /// <value>\n    /// The reference token identifier.\n    /// </value>\n    public string ReferenceTokenId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the refresh token (in case of refresh token validation).\n    /// </summary>\n    /// <value>\n    /// The reference token identifier.\n    /// </value>\n    public RefreshToken RefreshToken { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client.\n    /// </summary>\n    /// <value>\n    /// The client.\n    /// </value>\n    public Client Client { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/UserInfoRequestValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Validation result for userinfo requests\n/// </summary>\npublic class UserInfoRequestValidationResult : ValidationResult\n{\n    /// <summary>\n    /// Gets or sets the token validation result.\n    /// </summary>\n    /// <value>\n    /// The token validation result.\n    /// </value>\n    public TokenValidationResult TokenValidationResult { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ValidatedAuthorizeRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models a validated request to the authorize endpoint.\n/// </summary>\npublic class ValidatedAuthorizeRequest : ValidatedRequest\n{\n    /// <summary>\n    /// Gets or sets the type of the response.\n    /// </summary>\n    /// <value>\n    /// The type of the response.\n    /// </value>\n    public string ResponseType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the response mode.\n    /// </summary>\n    /// <value>\n    /// The response mode.\n    /// </value>\n    public string ResponseMode { get; set; }\n\n    /// <summary>\n    /// Gets or sets the grant type.\n    /// </summary>\n    /// <value>\n    /// The grant type.\n    /// </value>\n    public string GrantType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the redirect URI.\n    /// </summary>\n    /// <value>\n    /// The redirect URI.\n    /// </value>\n    public string RedirectUri { get; set; }\n\n    /// <summary>\n    /// Gets or sets the requested scopes.\n    /// </summary>\n    /// <value>\n    /// The requested scopes.\n    /// </value>\n    // todo: consider replacing with extension method to access Raw collection; would neeed to be done wholesale for all props.\n    public List<string> RequestedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether consent was shown.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if consent was shown; otherwise, <c>false</c>.\n    /// </value>\n    public bool WasConsentShown { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Gets or sets the state.\n    /// </summary>\n    /// <value>\n    /// The state.\n    /// </value>\n    public string State { get; set; }\n\n    /// <summary>\n    /// Gets or sets the UI locales.\n    /// </summary>\n    /// <value>\n    /// The UI locales.\n    /// </value>\n    public string UiLocales { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the request was an OpenID Connect request.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the request was an OpenID Connect request; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsOpenIdRequest { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether this instance is API resource request.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if this instance is API resource request; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsApiResourceRequest { get; set; }\n\n    /// <summary>\n    /// Gets or sets the nonce.\n    /// </summary>\n    /// <value>\n    /// The nonce.\n    /// </value>\n    public string Nonce { get; set; }\n\n    /// <summary>\n    /// Gets or sets the authentication context reference classes.\n    /// </summary>\n    /// <value>\n    /// The authentication context reference classes.\n    /// </value>\n    public List<string> AuthenticationContextReferenceClasses { get; set; }\n\n    /// <summary>\n    /// Gets or sets the display mode.\n    /// </summary>\n    /// <value>\n    /// The display mode.\n    /// </value>\n    public string DisplayMode { get; set; }\n\n    /// <summary>\n    /// Gets or sets the collection of prompt modes.\n    /// </summary>\n    /// <value>\n    /// The collection of prompt modes.\n    /// </value>\n    public IEnumerable<string> PromptModes { get; set; } = Enumerable.Empty<string>();\n\n    /// <summary>\n    /// Gets or sets the maximum age.\n    /// </summary>\n    /// <value>\n    /// The maximum age.\n    /// </value>\n    public int? MaxAge { get; set; }\n\n    /// <summary>\n    /// Gets or sets the login hint.\n    /// </summary>\n    /// <value>\n    /// The login hint.\n    /// </value>\n    public string LoginHint { get; set; }\n\n    /// <summary>\n    /// Gets or sets the code challenge\n    /// </summary>\n    /// <value>\n    /// The code challenge\n    /// </value>\n    public string CodeChallenge { get; set; }\n\n    /// <summary>\n    /// Gets or sets the code challenge method\n    /// </summary>\n    /// <value>\n    /// The code challenge method\n    /// </value>\n    public string CodeChallengeMethod { get; set; }\n\n    /// <summary>\n    /// Gets or sets the validated contents of the request object (if present)\n    /// </summary>\n    /// <value>\n    /// The request object values\n    /// </value>\n    public Dictionary<string, string> RequestObjectValues { get; set; } = new Dictionary<string, string>();\n\n    /// <summary>\n    /// Gets or sets the request object (either passed by value or retrieved by reference)\n    /// </summary>\n    /// <value>\n    /// The request object\n    /// </value>\n    public string RequestObject { get; set; }\n    \n    /// <summary>\n    /// Gets a value indicating whether an access token was requested.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if an access token was requested; otherwise, <c>false</c>.\n    /// </value>\n    public bool AccessTokenRequested => ResponseType == OidcConstants.ResponseTypes.IdTokenToken ||\n                                        ResponseType == OidcConstants.ResponseTypes.Code ||\n                                        ResponseType == OidcConstants.ResponseTypes.CodeIdToken ||\n                                        ResponseType == OidcConstants.ResponseTypes.CodeToken ||\n                                        ResponseType == OidcConstants.ResponseTypes.CodeIdTokenToken;\n\n\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ValidatedAuthorizeRequest\"/> class.\n    /// </summary>\n    public ValidatedAuthorizeRequest()\n    {\n        RequestedScopes = new List<string>();\n        AuthenticationContextReferenceClasses = new List<string>();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ValidatedDeviceAuthorizationRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models a validated request to the device authorization endpoint.\n/// </summary>\npublic class ValidatedDeviceAuthorizationRequest : ValidatedRequest\n{\n    /// <summary>\n    /// Gets or sets the requested scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public IEnumerable<string> RequestedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether this instance is open identifier request.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is open identifier request; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsOpenIdRequest { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ValidatedEndSessionRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Represents a validated end session (logout) request\n/// </summary>\npublic class ValidatedEndSessionRequest : ValidatedRequest\n{\n    /// <summary>\n    /// Gets a value indicating whether this instance is authenticated.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if this instance is authenticated; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsAuthenticated => Client != null;\n\n    /// <summary>\n    /// Gets or sets the post-logout URI.\n    /// </summary>\n    /// <value>\n    /// The post-logout URI.\n    /// </value>\n    public string PostLogOutUri { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the state.\n    /// </summary>\n    /// <value>\n    /// The state.\n    /// </value>\n    public string State { get; set; }\n\n    /// <summary>\n    ///  Ids of clients known to have an authentication session for user at end session time\n    /// </summary>\n    public IEnumerable<string> ClientIds { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ValidatedRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Base class for a validate authorize or token request\n/// </summary>\npublic class ValidatedRequest\n{\n    /// <summary>\n    /// Gets or sets the raw request data\n    /// </summary>\n    /// <value>\n    /// The raw.\n    /// </value>\n    public NameValueCollection Raw { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client.\n    /// </summary>\n    /// <value>\n    /// The client.\n    /// </value>\n    public Client Client { get; set; }\n\n    /// <summary>\n    /// Gets or sets the secret used to authenticate the client.\n    /// </summary>\n    /// <value>\n    /// The parsed secret.\n    /// </value>\n    public ParsedSecret Secret { get; set; }\n\n    /// <summary>\n    /// Gets or sets the effective access token lifetime for the current request.\n    /// This value is initally read from the client configuration but can be modified in the request pipeline\n    /// </summary>\n    public int AccessTokenLifetime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client claims for the current request.\n    /// This value is initally read from the client configuration but can be modified in the request pipeline\n    /// </summary>\n    public ICollection<Claim> ClientClaims { get; set; } = new HashSet<Claim>(new ClaimComparer());\n\n    /// <summary>\n    /// Gets or sets the effective access token type for the current request.\n    /// This value is initally read from the client configuration but can be modified in the request pipeline\n    /// </summary>\n    public AccessTokenType AccessTokenType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n\n    /// <summary>\n    /// Gets or sets the session identifier.\n    /// </summary>\n    /// <value>\n    /// The session identifier.\n    /// </value>\n    public string SessionId { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the identity server options.\n    /// </summary>\n    /// <value>\n    /// The options.\n    /// </value>\n    public IdentityServerOptions Options { get; set; }\n\n    /// <summary>\n    /// Gets or sets the validated resources for the request.\n    /// </summary>\n    /// <value>\n    /// The validated resources.\n    /// </value>\n    public ResourceValidationResult ValidatedResources { get; set; } = new ResourceValidationResult();\n\n    /// <summary>\n    /// Gets or sets the value of the confirmation method (will become the cnf claim). Must be a JSON object.\n    /// </summary>\n    /// <value>\n    /// The confirmation.\n    /// </value>\n    public string Confirmation { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client ID that should be used for the current request (this is useful for token exchange scenarios)\n    /// </summary>\n    /// <value>\n    /// The client ID\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Sets the client and the appropriate request specific settings.\n    /// </summary>\n    /// <param name=\"client\">The client.</param>\n    /// <param name=\"secret\">The client secret (optional).</param>\n    /// <param name=\"confirmation\">The confirmation.</param>\n    /// <exception cref=\"ArgumentNullException\">client</exception>\n    public void SetClient(Client client, ParsedSecret secret = null, string confirmation = \"\")\n    {\n        Client = client ?? throw new ArgumentNullException(nameof(client));\n        Secret = secret;\n        Confirmation = confirmation;\n        ClientId = client.ClientId;\n\n        AccessTokenLifetime = client.AccessTokenLifetime;\n        AccessTokenType = client.AccessTokenType;\n        ClientClaims = client.Claims.Select(c => new Claim(c.Type, c.Value, c.ValueType)).ToList();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ValidatedTokenRequest.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Models a validated request to the token endpoint.\n/// </summary>\npublic class ValidatedTokenRequest : ValidatedRequest\n{\n    /// <summary>\n    /// Gets or sets the type of the grant.\n    /// </summary>\n    /// <value>\n    /// The type of the grant.\n    /// </value>\n    public string GrantType { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public IEnumerable<string> RequestedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the username used in the request.\n    /// </summary>\n    /// <value>\n    /// The name of the user.\n    /// </value>\n    public string UserName { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the refresh token.\n    /// </summary>\n    /// <value>\n    /// The refresh token.\n    /// </value>\n    public RefreshToken RefreshToken { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the refresh token handle.\n    /// </summary>\n    /// <value>\n    /// The refresh token handle.\n    /// </value>\n    public string RefreshTokenHandle { get; set; }\n\n    /// <summary>\n    /// Gets or sets the authorization code.\n    /// </summary>\n    /// <value>\n    /// The authorization code.\n    /// </value>\n    public AuthorizationCode AuthorizationCode { get; set; }\n\n    /// <summary>\n    /// Gets or sets the authorization code handle.\n    /// </summary>\n    /// <value>\n    /// The authorization code handle.\n    /// </value>\n    public string AuthorizationCodeHandle { get; set; }\n\n    /// <summary>\n    /// Gets or sets the code verifier.\n    /// </summary>\n    /// <value>\n    /// The code verifier.\n    /// </value>\n    public string CodeVerifier { get; set; }\n\n    /// <summary>\n    /// Gets or sets the device code.\n    /// </summary>\n    /// <value>\n    /// The device code.\n    /// </value>\n    public DeviceCode DeviceCode { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/src/Validation/Models/ValidationResult.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Validation;\n\n/// <summary>\n/// Minimal validation result class (base-class for more complext validation results)\n/// </summary>\npublic class ValidationResult\n{\n    /// <summary>\n    /// Gets or sets a value indicating whether the validation was successful.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if the validation is failed; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsError { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets the error.\n    /// </summary>\n    /// <value>\n    /// The error.\n    /// </value>\n    public string Error { get; set; }\n\n    /// <summary>\n    /// Gets or sets the error description.\n    /// </summary>\n    /// <value>\n    /// The error description.\n    /// </value>\n    public string ErrorDescription { get; set; }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/ClientAssertionClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing IdentityServer.IntegrationTests.Common;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Microsoft.IdentityModel.Tokens;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Text.Json;\nusing Xunit;\n\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class ClientAssertionClient\n{\n    private const string TokenEndpoint = \"https://idsvr8/connect/token\";\n    private const string ClientId = \"certificate_base64_valid\";\n\n    private readonly HttpClient _client;\n\n    public ClientAssertionClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Valid_client_with_manual_payload_should_succeed()\n    {\n        var token = CreateToken(ClientId);\n        var requestBody = new FormUrlEncodedContent(new Dictionary<string, string>\n            {\n                { \"client_id\", ClientId },\n                { \"client_assertion_type\", \"urn:ietf:params:oauth:client-assertion-type:jwt-bearer\" },\n                { \"client_assertion\", token },\n                { \"grant_type\", \"client_credentials\" },\n                { \"scope\", \"api1\" }\n            });\n\n        var response = await GetToken(requestBody);\n\n        AssertValidToken(response);\n    }\n\n    [Fact]\n    public async Task Valid_client_should_succeed()\n    {\n        var token = CreateToken(ClientId);\n\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientCredentialStyle = ClientCredentialStyle.PostBody,\n            GrantType = \"client_credentials\",\n            ClientId = ClientId,\n            ClientAssertion =\n            {\n                Type = OidcConstants.ClientAssertionTypes.JwtBearer,\n                Value = token\n            },\n\n            Scope = \"api1\"\n        });\n\n        AssertValidToken(response);\n    }\n\n    [Fact]\n    public async Task Valid_client_with_implicit_clientId_should_succeed()\n    {\n        var token = CreateToken(ClientId);\n\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientCredentialStyle = ClientCredentialStyle.PostBody,\n            GrantType = \"client_credentials\",\n            ClientAssertion =\n            {\n                Type = OidcConstants.ClientAssertionTypes.JwtBearer,\n                Value = token\n            },\n\n            Scope = \"api1\"\n        });\n\n        AssertValidToken(response);\n    }\n\n    [Fact]\n    public async Task Valid_client_with_token_replay_should_fail()\n    {\n        var token = CreateToken(ClientId);\n\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientCredentialStyle = ClientCredentialStyle.PostBody,\n            GrantType = \"client_credentials\",\n            ClientId = ClientId,\n            ClientAssertion =\n            {\n                Type = OidcConstants.ClientAssertionTypes.JwtBearer,\n                Value = token\n            },\n\n            Scope = \"api1\"\n        });\n\n        AssertValidToken(response);\n\n        // replay\n        response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientCredentialStyle = ClientCredentialStyle.PostBody,\n            GrantType = \"client_credentials\",\n            ClientId = ClientId,\n            ClientAssertion =\n            {\n                Type = OidcConstants.ClientAssertionTypes.JwtBearer,\n                Value = token\n            },\n\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().BeTrue();\n        response.Error.Should().Be(\"invalid_client\");\n    }\n\n    [Fact]\n    public async Task Client_with_invalid_secret_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"client_credentials\",\n            ClientCredentialStyle = ClientCredentialStyle.PostBody,\n            ClientId = ClientId,\n\n            ClientAssertion =\n            {\n                Type = OidcConstants.ClientAssertionTypes.JwtBearer,\n                Value = \"invalid\"\n            },\n\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.Error.Should().Be(OidcConstants.TokenErrors.InvalidClient);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n    }\n\n    [Fact]\n    public async Task Invalid_client_should_fail()\n    {\n        const string clientId = \"certificate_base64_invalid\";\n        var token = CreateToken(clientId);\n\n        var tokenRequest = new ClientCredentialsTokenRequest();\n        tokenRequest.Address = TokenEndpoint;\n        tokenRequest.ClientId = clientId;\n        tokenRequest.GrantType = \"client_credentials\";\n        tokenRequest.ClientAssertion.Type = OidcConstants.ClientAssertionTypes.JwtBearer;\n        tokenRequest.ClientAssertion.Value = token;\n        tokenRequest.Scope = \"api1\";\n        tokenRequest.ClientCredentialStyle = ClientCredentialStyle.PostBody;\n        var response = await _client.RequestTokenAsync(tokenRequest);\n\n\n        response.IsError.Should().Be(true);\n        response.Error.Should().Be(OidcConstants.TokenErrors.InvalidClient);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n    }\n\n    private async Task<TokenResponse> GetToken(FormUrlEncodedContent body)\n    {\n        var response = await _client.PostAsync(TokenEndpoint, body);\n        return await ProtocolResponse.FromHttpResponseAsync<TokenResponse>(response);\n    }\n\n    private void AssertValidToken(TokenResponse response)\n    {\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(8);\n\n        payload.Keys.Should().Contain(\"iss\");\n        payload.Keys.Should().Contain(\"client_id\");\n\n        payload[\"iss\"].ValueKind.Should().Be(JsonValueKind.String);\n        payload[\"client_id\"].ValueKind.Should().Be(JsonValueKind.String);\n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(ClientId);\n\n\n\n        payload[\"scope\"].ValueKind.Should().Be(JsonValueKind.Array);\n\n\n        var scopes = payload[\"scope\"].EnumerateArray();\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        payload[\"aud\"].ToString().Should().Be(\"api\");\n    }\n\n    private Dictionary<string, JsonElement> GetPayload(TokenResponse response)\n    {\n        var token = response.AccessToken.Split('.').Skip(1).Take(1).First();\n        var dictionary = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(\n            Encoding.UTF8.GetString(Base64Url.Decode(token)));\n\n        return dictionary;\n    }\n\n    private string CreateToken(string clientId, DateTime? nowOverride = null)\n    {\n        var certificate = TestCert.Load();\n        var now = nowOverride ?? DateTime.UtcNow;\n\n        var token = new JwtSecurityToken(\n                clientId,\n                TokenEndpoint,\n                new List<Claim>()\n                {\n                    new Claim(\"jti\", Guid.NewGuid().ToString()),\n                    new Claim(JwtClaimTypes.Subject, clientId),\n                    new Claim(JwtClaimTypes.IssuedAt, new DateTimeOffset(now).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)\n                },\n                now,\n                now.AddMinutes(1),\n                new SigningCredentials(\n                    new X509SecurityKey(certificate),\n                    SecurityAlgorithms.RsaSha256\n                )\n            );\n\n        var tokenHandler = new JwtSecurityTokenHandler();\n        return tokenHandler.WriteToken(token);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/ClientCredentialsAndResourceOwnerClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class ClientCredentialsandResourceOwnerClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n\n    private readonly HttpClient _client;\n\n    public ClientCredentialsandResourceOwnerClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Resource_scope_should_be_requestable_via_client_credentials()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.and.ro\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(false);\n    }\n\n    [Fact]\n    public async Task Openid_scope_should_not_be_requestable_via_client_credentials()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.and.ro\",\n            ClientSecret = \"secret\",\n            Scope = \"openid api1\"\n        });\n\n        response.IsError.Should().Be(true);\n    }\n\n    [Fact]\n    public async Task Openid_scope_should_be_requestable_via_password()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.and.ro\",\n            ClientSecret = \"secret\",\n            Scope = \"openid\",\n\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().Be(false);\n    }\n\n    [Fact]\n    public async Task Openid_and_resource_scope_should_be_requestable_via_password()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.and.ro\",\n            ClientSecret = \"secret\",\n            Scope = \"openid api1\",\n\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().Be(false);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/ClientCredentialsClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing System.Net;\nusing System.Text;\nusing System.Text.Json;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class ClientCredentialsClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n\n    private readonly HttpClient _client;\n\n    public ClientCredentialsClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Invalid_endpoint_should_return_404()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint + \"invalid\",\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Http);\n        response.Error.Should().Be(\"Not Found\");\n        response.HttpStatusCode.Should().Be(HttpStatusCode.NotFound);\n    }\n\n    [Fact]\n    public async Task Valid_request_single_audience_should_return_expected_payload()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(8);\n\n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(\"client\");\n\n        payload[\"aud\"].ToString().Should().Be(\"api\");\n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n        \n        payload[\"aud\"].ToString().Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"].EnumerateArray().Select(x => x.GetString());\n        scopes.First().ToString().Should().Be(\"api1\");\n    }\n\n    [Fact]\n    public async Task Valid_request_multiple_audiences_should_return_expected_payload()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1 other_api\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(8);\n\n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(\"client\");\n\n     \n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n\n        var audiences = payload[\"aud\"].EnumerateArray().Select(x => x.GetString());\n        audiences.Count().Should().Be(2);\n        audiences.Should().Contain(\"api\");\n        audiences.Should().Contain(\"other_api\");\n\n        var scopes = payload[\"scope\"].EnumerateArray().Select(x => x.ToString());\n        scopes.First().ToString().Should().Be(\"api1\");\n    }\n\n    [Fact]\n    public async Task Valid_request_with_confirmation_should_return_expected_payload()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.cnf\",\n            ClientSecret = \"foo\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(9);\n\n\n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(\"client.cnf\");\n\n        payload[\"aud\"].ToString().Should().Be(\"api\");\n\n\n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n\n\n\n        var scopes = payload[\"scope\"].EnumerateArray().Select(x => x.GetString());\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        payload[\"cnf\"].ValueKind.Should().Be(JsonValueKind.Array);\n        var cnfArray = payload[\"cnf\"].EnumerateArray().ToList();\n        cnfArray.Count.Should().Be(1);\n        var elArray= cnfArray.First().EnumerateArray().ToList();\n        elArray.Count.Should().Be(1);\n        elArray.First().GetString().Should().Be(\"foo\");\n\n    }\n\n    [Fact]\n    public async Task Requesting_multiple_scopes_should_return_expected_payload()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1 api2\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(8);\n\n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(\"client\");\n\n        payload[\"aud\"].ToString().Should().Be(\"api\");\n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n        \n\n\n        var scopes = payload[\"scope\"].EnumerateArray().Select(x => x.GetString());\n        scopes.Count().Should().Be(2);\n        scopes.First().ToString().Should().Be(\"api1\");\n        scopes.Skip(1).First().ToString().Should().Be(\"api2\");\n    }\n\n    [Fact]\n    public async Task Request_with_no_explicit_scopes_should_return_expected_payload()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(8);\n\n\n\n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(\"client\");\n\n\n\n        var scopes = payload[\"scope\"].EnumerateArray().Select(x => x.GetString());\n\n\n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n\n        var audiences = payload[\"aud\"].EnumerateArray().Select(x=> x.GetString());\n        audiences.Count().Should().Be(2);\n        audiences.Should().Contain(\"api\");\n        audiences.Should().Contain(\"other_api\");\n\n\n        scopes.Count().Should().Be(3);\n        scopes.Should().Contain(\"api1\");\n        scopes.Should().Contain(\"api2\");\n        scopes.Should().Contain(\"other_api\");\n    }\n\n    [Fact]\n    public async Task Client_without_default_scopes_skipping_scope_parameter_should_return_error()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.no_default_scopes\",\n            ClientSecret = \"secret\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ExpiresIn.Should().Be(0);\n        response.TokenType.Should().BeNull();\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n        response.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n    }\n\n    [Fact]\n    public async Task Request_posting_client_secret_in_body_should_succeed()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\",\n\n            ClientCredentialStyle = ClientCredentialStyle.PostBody\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n\n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(\"client\");\n\n        payload[\"aud\"].ToString().Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"].EnumerateArray();\n        scopes.First().ToString().Should().Be(\"api1\");\n    }\n\n\n    [Fact]\n    public async Task Request_For_client_with_no_secret_and_basic_authentication_should_succeed()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.no_secret\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n        \n        payload[\"iss\"].ToString().Should().Be(\"https://idsvr8\");\n        payload[\"client_id\"].ToString().Should().Be(\"client.no_secret\");\n\n        var scopes = payload[\"scope\"].EnumerateArray();\n        scopes.First().ToString().Should().Be(\"api1\");\n    }\n\n    [Fact]\n    public async Task Request_with_invalid_client_secret_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"invalid\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.Error.Should().Be(\"invalid_client\");\n    }\n\n    [Fact]\n    public async Task Unknown_client_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"invalid\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_client\");\n    }\n\n    [Fact]\n    public async Task Implicit_client_should_not_use_client_credential_grant()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"implicit\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"unauthorized_client\");\n    }\n\n    [Fact]\n    public async Task Implicit_and_client_creds_client_should_not_use_client_credential_grant_without_secret()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"implicit_and_client_creds\",\n            ClientSecret = \"invalid\",\n            Scope = \"api1\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_client\");\n    }\n\n\n    [Fact]\n    public async Task Requesting_unknown_scope_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"unknown\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_scope\");\n    }\n\n    [Fact]\n    public async Task Client_explicitly_requesting_identity_scope_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client.identityscopes\",\n            ClientSecret = \"secret\",\n            Scope = \"openid api1\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_scope\");\n    }\n\n    [Fact]\n    public async Task Client_explicitly_requesting_offline_access_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1 offline_access\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_scope\");\n    }\n\n    [Fact]\n    public async Task Requesting_unauthorized_scope_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api3\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_scope\");\n    }\n\n    [Fact]\n    public async Task Requesting_authorized_and_unauthorized_scopes_should_fail()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1 api3\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_scope\");\n    }\n\n    private Dictionary<string, JsonElement> GetPayload(TokenResponse response)\n    {\n        var token = response.AccessToken.Split('.').Skip(1).Take(1).First();\n        var dictionary = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(\n            Encoding.UTF8.GetString(Base64Url.Decode(token)));\n\n        return dictionary;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/CustomTokenRequestValidatorClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing IdentityServer8.Extensions;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing System.Text.Json;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class CustomTokenRequestValidatorClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n\n    private readonly HttpClient _client;\n\n    public CustomTokenRequestValidatorClient()\n    {\n        var val = new TestCustomTokenRequestValidator();\n        Startup.CustomTokenRequestValidator = val;\n\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Client_credentials_request_should_contain_custom_response()\n    {\n        var response = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n\n            ClientId = \"client\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n        ValidateCustomFields(response);\n    }\n\n    [Fact]\n    public async Task Resource_owner_credentials_request_should_contain_custom_response()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\",\n\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        ValidateCustomFields(response);\n    }\n\n    [Fact]\n    public async Task Refreshing_a_token_should_contain_custom_response()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n            Scope = \"api1 offline_access\",\n\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = response.RefreshToken\n        });\n\n        ValidateCustomFields(response);\n    }\n\n    [Fact]\n    public async Task Extension_grant_request_should_contain_custom_response()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n                { \"custom_credential\", \"custom credential\"}\n            }\n        });\n\n        ValidateCustomFields(response);\n    }\n\n     private Dictionary<string, JsonElement> GetFields(JsonElement json)\n    {\n        return json.ToObject<Dictionary<string, JsonElement>>();\n    }\n    private void ValidateCustomFields(TokenResponse response)\n    {\n        var fields = GetFields(response.Json);\n        fields[\"custom\"].ToString().Should().Be(\"custom\");\n\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/CustomTokenResponseClients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing IdentityServer8.Extensions;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing System.Text;\nusing System.Text.Json;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class CustomTokenResponseClients\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n\n    private readonly HttpClient _client;\n\n    public CustomTokenResponseClients()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<StartupWithCustomTokenResponses>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Resource_owner_success_should_return_custom_response()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            UserName = \"bob\",\n            Password = \"bob\",\n            Scope = \"api1\"\n        });\n\n        // raw fields\n        var fields = GetFields(response);\n        fields[\"string_value\"].GetString().Should().Be(\"some_string\");\n        fields[\"int_value\"].GetInt64().Should().Be(42);\n\n        JsonElement temp;\n        fields.TryGetValue(\"identity_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"refresh_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"error\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"error_description\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"token_type\", out temp).Should().BeTrue();\n        fields.TryGetValue(\"expires_in\", out temp).Should().BeTrue();\n\n        var responseObject = fields[\"dto\"];\n        responseObject.Should().NotBeNull();\n\n        var responseDto = GetDto(responseObject);\n        var dto = CustomResponseDto.Create;\n\n        responseDto.string_value.Should().Be(dto.string_value);\n        responseDto.int_value.Should().Be(dto.int_value);\n        responseDto.nested.string_value.Should().Be(dto.nested.string_value);\n        responseDto.nested.int_value.Should().Be(dto.nested.int_value);\n\n\n        // token client response\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n\n        // token content\n        var payload = GetPayload(response);\n        payload.Count().Should().Be(12);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"roclient\");\n        payload.Should().Contain(\"sub\", \"bob\");\n        payload.Should().Contain(\"idp\", \"local\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"password\");\n    }\n\n    [Fact]\n    public async Task Resource_owner_failure_should_return_custom_error_response()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            UserName = \"bob\",\n            Password = \"invalid\",\n            Scope = \"api1\"\n        });\n\n        // raw fields\n        var fields = GetFields(response);\n        fields[\"string_value\"].ToString().Should().Be(\"some_string\");\n        fields[\"int_value\"].GetInt64().Should().Be(42);\n\n        JsonElement temp;\n        fields.TryGetValue(\"identity_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"refresh_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"error\", out temp).Should().BeTrue();\n        fields.TryGetValue(\"error_description\", out temp).Should().BeTrue();\n        fields.TryGetValue(\"token_type\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"expires_in\", out temp).Should().BeFalse();\n\n        var responseObject = fields[\"dto\"];\n        responseObject.Should().NotBeNull();\n\n        var responseDto = GetDto(responseObject);\n        var dto = CustomResponseDto.Create;\n\n        responseDto.string_value.Should().Be(dto.string_value);\n        responseDto.int_value.Should().Be(dto.int_value);\n        responseDto.nested.string_value.Should().Be(dto.nested.string_value);\n        responseDto.nested.int_value.Should().Be(dto.nested.int_value);\n\n\n        // token client response\n        response.IsError.Should().Be(true);\n        response.Error.Should().Be(\"invalid_grant\");\n        response.ErrorDescription.Should().Be(\"invalid_credential\");\n        response.ExpiresIn.Should().Be(0);\n        response.TokenType.Should().BeNull();\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n    }\n\n    [Fact]\n    public async Task Extension_grant_success_should_return_custom_response()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n                { \"outcome\", \"succeed\"}\n            }\n        });\n\n\n        // raw fields\n        var fields = GetFields(response);\n        fields[\"string_value\"].ToString().Should().Be(\"some_string\");\n        fields[\"int_value\"].GetInt64().Should().Be(42);\n\n        JsonElement temp;\n        fields.TryGetValue(\"identity_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"refresh_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"error\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"error_description\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"token_type\", out temp).Should().BeTrue();\n        fields.TryGetValue(\"expires_in\", out temp).Should().BeTrue();\n\n        var responseObject = fields[\"dto\"];\n        responseObject.Should().NotBeNull();\n\n        var responseDto = GetDto(responseObject);\n        var dto = CustomResponseDto.Create;\n\n        responseDto.string_value.Should().Be(dto.string_value);\n        responseDto.int_value.Should().Be(dto.int_value);\n        responseDto.nested.string_value.Should().Be(dto.nested.string_value);\n        responseDto.nested.int_value.Should().Be(dto.nested.int_value);\n\n\n        // token client response\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n\n        // token content\n        var payload = GetPayload(response);\n        payload.Count().Should().Be(12);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.custom\");\n        payload.Should().Contain(\"sub\", \"bob\");\n        payload.Should().Contain(\"idp\", \"local\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"custom\");\n\n    }\n\n    [Fact]\n    public async Task Extension_grant_failure_should_return_custom_error_response()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n                { \"outcome\", \"fail\"}\n            }\n        });\n\n        var s = response.Json.ToString();\n        var fd = GetFieldsD(response);\n        // raw fields\n        var fields = GetFields(response);\n        fields[\"string_value\"].ToString().Should().Be(\"some_string\");\n        fields[\"int_value\"].GetInt64().Should().Be(42);\n\n        JsonElement temp;\n        fields.TryGetValue(\"identity_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"refresh_token\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"error\", out temp).Should().BeTrue();\n        fields.TryGetValue(\"error_description\", out temp).Should().BeTrue();\n        fields.TryGetValue(\"token_type\", out temp).Should().BeFalse();\n        fields.TryGetValue(\"expires_in\", out temp).Should().BeFalse();\n\n        var responseObject = fields[\"dto\"];\n        responseObject.Should().NotBeNull();\n\n        var responseDto = GetDto(responseObject);\n        var dto = CustomResponseDto.Create;\n\n        responseDto.string_value.Should().Be(dto.string_value);\n        responseDto.int_value.Should().Be(dto.int_value);\n        responseDto.nested.string_value.Should().Be(dto.nested.string_value);\n        responseDto.nested.int_value.Should().Be(dto.nested.int_value);\n\n\n        // token client response\n        response.IsError.Should().Be(true);\n        response.Error.Should().Be(\"invalid_grant\");\n        response.ErrorDescription.Should().Be(\"invalid_credential\");\n        response.ExpiresIn.Should().Be(0);\n        response.TokenType.Should().BeNull();\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n    }\n\n    private CustomResponseDto GetDto(JsonElement responseObject)\n    {\n        return responseObject.ToObject<CustomResponseDto>();\n    }\n\n    private Dictionary<string, object> GetFieldsD(TokenResponse response)\n    {\n        return response.Json.ToObject<Dictionary<string, object>>();\n    }\n\n\n    private Dictionary<string, JsonElement> GetFields(TokenResponse response)\n    {\n        return GetFields(response.Json);\n    }\n\n    private Dictionary<string, JsonElement> GetFields(JsonElement json)\n    {\n        return json.ToObject<Dictionary<string, JsonElement>>();\n    }\n\n    private Dictionary<string, object> GetPayload(TokenResponse response)\n    {\n        var token = response.AccessToken.Split('.').Skip(1).Take(1).First();\n        var dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(\n            Encoding.UTF8.GetString(Base64Url.Decode(token)));\n\n        return dictionary;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/DiscoveryClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class DiscoveryClientTests\n{\n    private const string DiscoveryEndpoint = \"https://server/.well-known/openid-configuration\";\n\n    private readonly HttpClient _client;\n\n    public DiscoveryClientTests()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Discovery_document_should_have_expected_values()\n    {\n        var doc = await _client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest\n        {\n            Address = DiscoveryEndpoint,\n            Policy =\n            {\n                ValidateIssuerName = false\n            }\n        });\n\n        // endpoints\n        doc.TokenEndpoint.Should().Be(\"https://server/connect/token\");\n        doc.AuthorizeEndpoint.Should().Be(\"https://server/connect/authorize\");\n        doc.IntrospectionEndpoint.Should().Be(\"https://server/connect/introspect\");\n        doc.EndSessionEndpoint.Should().Be(\"https://server/connect/endsession\");\n\n        // jwk\n        doc.KeySet.Keys.Count.Should().Be(1);\n        doc.KeySet.Keys.First().E.Should().NotBeNull();\n        doc.KeySet.Keys.First().N.Should().NotBeNull();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/ExtensionGrantClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Net;\nusing System.Text;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class ExtensionGrantClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n\n    private readonly HttpClient _client;\n\n    public ExtensionGrantClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Valid_client_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"custom_credential\", \"custom credential\"},\n                { \"scope\", \"api1\" }\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        var unixNow = DateTimeOffset.UtcNow.ToUnixTimeSeconds();\n        var exp = Int64.Parse(payload[\"exp\"].ToString());\n        exp.Should().BeLessThan(unixNow + 3605);\n        exp.Should().BeGreaterThan(unixNow + 3595);\n\n        payload.Count().Should().Be(12);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.custom\");\n        payload.Should().Contain(\"sub\", \"818727\");\n        payload.Should().Contain(\"idp\", \"local\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"custom\");\n    }\n\n    [Fact]\n    public async Task Valid_client_with_extra_claim_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"custom_credential\", \"custom credential\"},\n                { \"extra_claim\", \"extra_value\" },\n                { \"scope\", \"api1\" }\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        var unixNow = DateTimeOffset.UtcNow.ToUnixTimeSeconds();\n        var exp = Int64.Parse(payload[\"exp\"].ToString());\n        exp.Should().BeLessThan(unixNow + 3605);\n        exp.Should().BeGreaterThan(unixNow + 3595);\n\n        payload.Count().Should().Be(13);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.custom\");\n        payload.Should().Contain(\"sub\", \"818727\");\n        payload.Should().Contain(\"idp\", \"local\");\n        payload.Should().Contain(\"extra_claim\", \"extra_value\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"custom\");\n    }\n\n    [Fact]\n    public async Task Valid_client_with_refreshed_extra_claim_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"custom_credential\", \"custom credential\"},\n                { \"extra_claim\", \"extra_value\" },\n                { \"scope\", \"api1 offline_access\" }\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var refreshResponse = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            \n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = response.RefreshToken\n        });\n\n        refreshResponse.IsError.Should().BeFalse();\n        refreshResponse.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        refreshResponse.ExpiresIn.Should().Be(3600);\n        refreshResponse.TokenType.Should().Be(\"Bearer\");\n        refreshResponse.IdentityToken.Should().BeNull();\n        refreshResponse.RefreshToken.Should().NotBeNull();\n\n        var payload = GetPayload(refreshResponse);\n\n        var unixNow = DateTimeOffset.UtcNow.ToUnixTimeSeconds();\n        var exp = Int64.Parse(payload[\"exp\"].ToString());\n        exp.Should().BeLessThan(unixNow + 3605);\n        exp.Should().BeGreaterThan(unixNow + 3595);\n\n        payload.Count().Should().Be(13);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.custom\");\n        payload.Should().Contain(\"sub\", \"818727\");\n        payload.Should().Contain(\"idp\", \"local\");\n        payload.Should().Contain(\"extra_claim\", \"extra_value\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"custom\");\n    }\n\n    [Fact]\n    public async Task Valid_client_no_subject_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom.nosubject\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"custom_credential\", \"custom credential\"},\n                { \"scope\", \"api1\" }\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(8);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.custom\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n    }\n\n    [Fact]\n    public async Task Valid_client_with_default_scopes_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"custom_credential\", \"custom credential\"}\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(12);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.custom\");\n        payload.Should().Contain(\"sub\", \"818727\");\n        payload.Should().Contain(\"idp\", \"local\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"custom\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.Count().Should().Be(3);\n        scopes.First().ToString().Should().Be(\"api1\");\n        scopes.Skip(1).First().ToString().Should().Be(\"api2\");\n        scopes.Skip(2).First().ToString().Should().Be(\"offline_access\");\n    }\n\n    [Fact]\n    public async Task Valid_client_missing_grant_specific_data_should_fail()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" }\n            }\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        response.ErrorDescription.Should().Be(\"invalid_custom_credential\");\n    }\n\n    [Fact]\n    public async Task Valid_client_using_unsupported_grant_type_should_fail()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"invalid\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"custom_credential\", \"custom credential\"},\n                { \"scope\", \"api1\" }\n            }\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"unsupported_grant_type\");\n    }\n\n    [Fact]\n    public async Task Valid_client_using_unauthorized_grant_type_should_fail()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"custom2\",\n\n            ClientId = \"client.custom\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"custom_credential\", \"custom credential\"},\n                { \"scope\", \"api1\" }\n            }\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"unsupported_grant_type\");\n    }\n\n    [Fact(Skip = \"needs improvement\")]\n    public async Task Dynamic_lifetime_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"dynamic\",\n\n            ClientId = \"client.dynamic\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n\n                { \"lifetime\", \"5000\"},\n                { \"sub\",  \"818727\"}\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(5000);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        var unixNow = DateTimeOffset.UtcNow.ToUnixTimeSeconds();\n        var exp = Int64.Parse(payload[\"exp\"].ToString());\n        exp.Should().BeLessThan(unixNow + 5005);\n        exp.Should().BeGreaterThan(unixNow + 4995);\n\n        payload.Count().Should().Be(10);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.dynamic\");\n        payload.Should().Contain(\"sub\", \"818727\");\n        payload.Should().Contain(\"idp\", \"local\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"delegation\");\n    }\n\n    [Fact]\n    public async Task Dynamic_token_type_jwt_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"dynamic\",\n\n            ClientId = \"client.dynamic\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n\n                { \"type\", \"jwt\"},\n                { \"sub\",  \"818727\"}\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        response.AccessToken.Should().Contain(\".\");\n    }\n\n    [Fact]\n    public async Task Impersonate_client_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"dynamic\",\n\n            ClientId = \"client.dynamic\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n\n                { \"type\", \"jwt\"},\n                { \"impersonated_client\", \"impersonated_client_id\"},\n                { \"sub\",  \"818727\"}\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        response.AccessToken.Should().Contain(\".\");\n\n        var jwt = new JwtSecurityToken(response.AccessToken);\n        jwt.Payload[\"client_id\"].Should().Be(\"impersonated_client_id\");\n    }\n\n    [Fact]\n    public async Task Dynamic_token_type_reference_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"dynamic\",\n\n            ClientId = \"client.dynamic\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n\n                { \"type\", \"reference\"},\n                { \"sub\",  \"818727\"}\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        response.AccessToken.Should().NotContain(\".\");\n    }\n\n    [Fact]\n    public async Task Dynamic_client_claims_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"dynamic\",\n\n            ClientId = \"client.dynamic\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n\n                { \"claim\", \"extra_claim\"},\n                { \"sub\",  \"818727\"}\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(13);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.dynamic\");\n        payload.Should().Contain(\"sub\", \"818727\");\n        payload.Should().Contain(\"idp\", \"local\");\n\n        payload.Should().Contain(\"client_extra\", \"extra_claim\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"delegation\");\n    }\n\n    [Fact]\n    public async Task Dynamic_client_claims_no_sub_should_succeed()\n    {\n        var response = await _client.RequestTokenAsync(new TokenRequest\n        {\n            Address = TokenEndpoint,\n            GrantType = \"dynamic\",\n\n            ClientId = \"client.dynamic\",\n            ClientSecret = \"secret\",\n\n            Parameters =\n            {\n                { \"scope\", \"api1\" },\n\n                { \"claim\", \"extra_claim\"},\n            }\n        });\n\n        response.IsError.Should().BeFalse();\n        response.HttpStatusCode.Should().Be(HttpStatusCode.OK);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(9);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"client.dynamic\");\n        payload.Should().Contain(\"client_extra\", \"extra_claim\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = payload[\"scope\"] as JArray;\n        scopes.First().ToString().Should().Be(\"api1\");\n    }\n\n    private Dictionary<string, object> GetPayload(TokenResponse response)\n    {\n        var token = response.AccessToken.Split('.').Skip(1).Take(1).First();\n        var dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(\n            Encoding.UTF8.GetString(Base64Url.Decode(token)));\n\n        return dictionary;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/RefreshTokenClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class RefreshTokenClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n    private const string RevocationEndpoint = \"https://server/connect/revocation\";\n\n    private readonly HttpClient _client;\n\n    public RefreshTokenClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Requesting_a_refresh_token_without_identity_scopes_should_return_expected_results()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = response.RefreshToken\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n    }\n\n    [Fact]\n    public async Task Requesting_a_refresh_token_with_identity_scopes_should_return_expected_results()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = response.RefreshToken\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().NotBeNull();\n        response.RefreshToken.Should().NotBeNull();\n    }\n\n    [Fact]\n    public async Task Refreshing_a_refresh_token_with_reuse_should_return_same_refresh_token()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient.reuse\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var rt1 = response.RefreshToken;\n\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient.reuse\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = response.RefreshToken\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().NotBeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var rt2 = response.RefreshToken;\n\n        rt1.Should().BeEquivalentTo(rt2);\n    }\n    \n    [Fact]\n    public async Task Refreshing_a_refresh_token_with_one_time_only_should_return_different_refresh_token()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var rt1 = response.RefreshToken;\n\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = response.RefreshToken\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().NotBeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var rt2 = response.RefreshToken;\n\n        rt1.Should().NotBeEquivalentTo(rt2);\n    }\n    \n    [Fact]\n    public async Task Replaying_a_rotated_token_should_fail()\n    {\n        // request initial token\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var rt1 = response.RefreshToken;\n\n        // refresh token\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = response.RefreshToken\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().NotBeNull();\n        response.RefreshToken.Should().NotBeNull();\n        \n        // refresh token (again)\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = rt1\n        });\n\n        response.IsError.Should().BeTrue();\n        response.Error.Should().Be(\"invalid_grant\");\n    }\n    \n    [Fact]\n    public async Task Using_a_valid_refresh_token_should_succeed()\n    {\n        // request initial token\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var rt1 = response.RefreshToken;\n\n        // refresh token\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = rt1\n        });\n\n        response.IsError.Should().BeFalse();\n    }\n    \n    [Fact]\n    public async Task Using_a_revoked_refresh_token_should_fail()\n    {\n        // request initial token\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var rt1 = response.RefreshToken;\n\n        // revoke refresh token\n        var revocationResponse = await _client.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = RevocationEndpoint,\n\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Token = rt1,\n            TokenTypeHint = \"refresh_token\"\n        });\n\n        revocationResponse.IsError.Should().Be(false);\n        \n        // refresh token\n        response = await _client.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            RefreshToken = rt1\n        });\n\n        response.IsError.Should().BeTrue();\n        response.Error.Should().Be(\"invalid_grant\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/ResourceOwnerClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing System.Net;\nusing System.Text;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class ResourceOwnerClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n\n    private readonly HttpClient _client;\n\n    public ResourceOwnerClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Valid_user_should_succeed_with_expected_response_payload()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(12);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"roclient\");\n        payload.Should().Contain(\"sub\", \"88421113\");\n        payload.Should().Contain(\"idp\", \"local\");\n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n        \n        payload[\"aud\"].Should().Be(\"api\");\n\n        var scopes = ((JArray)payload[\"scope\"]).Select(x => x.ToString());\n        scopes.Count().Should().Be(1);\n        scopes.Should().Contain(\"api1\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"pwd\");\n    }\n\n    [Fact]\n    public async Task Request_with_no_explicit_scopes_should_return_allowed_scopes()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNull();\n\n        var payload = GetPayload(response);\n        \n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"roclient\");\n        payload.Should().Contain(\"sub\", \"88421113\");\n        payload.Should().Contain(\"idp\", \"local\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"pwd\");\n\n        var scopes = ((JArray)payload[\"scope\"]).Select(x => x.ToString());\n        scopes.Count().Should().Be(8);\n\n        // {[  \"address\",  \"api1\",  \"api2\", \"api4.with.roles\", \"email\",  \"offline_access\",  \"openid\", \"role\"]}\n\n        scopes.Should().Contain(\"address\");\n        scopes.Should().Contain(\"api1\");\n        scopes.Should().Contain(\"api2\");\n        scopes.Should().Contain(\"api4.with.roles\");\n        scopes.Should().Contain(\"email\");\n        scopes.Should().Contain(\"offline_access\");\n        scopes.Should().Contain(\"openid\");\n        scopes.Should().Contain(\"roles\");\n    }\n\n    [Fact]\n    public async Task Request_containing_identity_scopes_should_return_expected_payload()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid email api1\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().BeNull();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(12);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"roclient\");\n        payload.Should().Contain(\"sub\", \"88421113\");\n        payload.Should().Contain(\"idp\", \"local\");\n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"pwd\");\n\n        var scopes = ((JArray)payload[\"scope\"]).Select(x=>x.ToString());\n        scopes.Count().Should().Be(3);\n        scopes.Should().Contain(\"api1\");\n        scopes.Should().Contain(\"email\");\n        scopes.Should().Contain(\"openid\");\n    }\n\n    [Fact]\n    public async Task Request_for_refresh_token_should_return_expected_payload()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid email api1 offline_access\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().Be(false);\n        response.ExpiresIn.Should().Be(3600);\n        response.TokenType.Should().Be(\"Bearer\");\n        response.IdentityToken.Should().BeNull();\n        response.RefreshToken.Should().NotBeNullOrWhiteSpace();\n\n        var payload = GetPayload(response);\n\n        payload.Count().Should().Be(12);\n        payload.Should().Contain(\"iss\", \"https://idsvr8\");\n        payload.Should().Contain(\"client_id\", \"roclient\");\n        payload.Should().Contain(\"sub\", \"88421113\");\n        payload.Should().Contain(\"idp\", \"local\");\n        payload.Keys.Should().Contain(\"jti\");\n        payload.Keys.Should().Contain(\"iat\");\n\n        payload[\"aud\"].Should().Be(\"api\");\n\n        var amr = payload[\"amr\"] as JArray;\n        amr.Count().Should().Be(1);\n        amr.First().ToString().Should().Be(\"pwd\");\n\n        var scopes = ((JArray)payload[\"scope\"]).Select(x => x.ToString());\n        scopes.Count().Should().Be(4);\n        scopes.Should().Contain(\"api1\");\n        scopes.Should().Contain(\"email\");\n        scopes.Should().Contain(\"offline_access\");\n        scopes.Should().Contain(\"openid\");\n    }\n\n    [Fact]\n    public async Task Unknown_user_should_fail()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1\",\n            UserName = \"unknown\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_grant\");\n    }\n    \n    [Fact]\n    public async Task User_with_empty_password_should_succeed()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1\",\n            UserName = \"bob_no_password\"\n        });\n\n        response.IsError.Should().Be(false);\n    }\n\n    [Theory]\n    [InlineData(\"invalid\")]\n    [InlineData(\"\")]\n    public async Task User_with_invalid_password_should_fail(string password)\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1\",\n            UserName = \"bob\",\n            Password = password\n        });\n\n        response.IsError.Should().Be(true);\n        response.ErrorType.Should().Be(ResponseErrorType.Protocol);\n        response.HttpStatusCode.Should().Be(HttpStatusCode.BadRequest);\n        response.Error.Should().Be(\"invalid_grant\");\n    }\n\n\n    private static Dictionary<string, object> GetPayload(IdentityModel.Client.TokenResponse response)\n    {\n        var token = response.AccessToken.Split('.').Skip(1).Take(1).First();\n        var dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(\n            Encoding.UTF8.GetString(Base64Url.Decode(token)));\n\n        return dictionary;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/RevocationClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class RevocationClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n    private const string RevocationEndpoint = \"https://server/connect/revocation\";\n    private const string IntrospectionEndpoint = \"https://server/connect/introspect\";\n\n    private readonly HttpClient _client;\n\n    public RevocationClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Revoking_reference_token_should_invalidate_token()\n    {\n        // request acccess token\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient.reference\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n\n        // introspect - should be active\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api\",\n            ClientSecret = \"secret\",\n\n            Token = response.AccessToken\n        });\n\n        introspectionResponse.IsActive.Should().Be(true);\n\n        // revoke access token\n        var revocationResponse = await _client.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = RevocationEndpoint,\n            ClientId = \"roclient.reference\",\n            ClientSecret = \"secret\",\n\n            Token = response.AccessToken\n        });\n\n        // introspect - should be inactive\n        introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api\",\n            ClientSecret = \"secret\",\n\n            Token = response.AccessToken\n        });\n\n        introspectionResponse.IsActive.Should().Be(false);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/Clients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Security.Cryptography.X509Certificates;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\ninternal class Clients\n{\n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            ///////////////////////////////////////////\n            // Console Client Credentials Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowOfflineAccess = true,\n\n                AllowedScopes =\n                {\n                    \"api1\", \"api2\", \"other_api\"\n                }\n            },\n            new Client\n            {\n                ClientId = \"client.cnf\",\n                ClientSecrets =\n                {\n                    new Secret\n                    {\n                        Type = \"confirmation.test\",\n                        Description = \"Test for cnf claim\",\n                        Value = \"foo\"\n                    }\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowOfflineAccess = true,\n\n                AllowedScopes =\n                {\n                    \"api1\", \"api2\"\n                }\n            },\n            new Client\n            {\n                ClientId = \"client.and.ro\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,\n\n                AllowedScopes =\n                {\n                    \"openid\",\n                    \"api1\", \"api2\"\n                }\n            },\n            new Client\n            {\n                ClientId = \"client.identityscopes\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n\n                AllowedScopes =\n                {\n                    \"openid\", \"profile\",\n                    \"api1\", \"api2\"\n                }\n            },\n            new Client\n            {\n                ClientId = \"client.no_default_scopes\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials\n            },\n            new Client\n            {\n                ClientId = \"client.no_secret\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                RequireClientSecret = false,\n                AllowedScopes = { \"api1\" }\n            },\n\n            ///////////////////////////////////////////\n            // Console Resource Owner Flow Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                RefreshTokenUsage = TokenUsage.OneTimeOnly,\n\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Email,\n                    IdentityServerConstants.StandardScopes.Address,\n                    \"roles\",\n                    \"api1\", \"api2\", \"api4.with.roles\"\n                }\n            },\n            new Client\n            {\n                ClientId = \"roclient.reuse\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    IdentityServerConstants.StandardScopes.OpenId,\n                    IdentityServerConstants.StandardScopes.Email,\n                    IdentityServerConstants.StandardScopes.Address,\n                    \"roles\",\n                    \"api1\", \"api2\", \"api4.with.roles\"\n                },\n\n                RefreshTokenUsage = TokenUsage.ReUse\n            },\n\n            /////////////////////////////////////////\n            // Console Custom Grant Flow Sample\n            ////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"client.custom\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = { \"custom\", \"custom.nosubject\" },\n\n                AllowedScopes =\n                {\n                    \"api1\", \"api2\"\n                },\n\n                AllowOfflineAccess = true\n            },\n            new Client\n            {\n                ClientId = \"client.dynamic\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = { \"dynamic\" },\n\n                AllowedScopes =\n                {\n                    \"api1\", \"api2\"\n                },\n\n                AlwaysSendClientClaims = true\n            },\n\n            ///////////////////////////////////////////\n            // Introspection Client Sample\n            //////////////////////////////////////////\n            new Client\n            {\n                ClientId = \"roclient.reference\",\n                ClientSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n\n                AllowOfflineAccess = true,\n                AllowedScopes =\n                {\n                    \"api1\", \"api2\"\n                },\n\n                AccessTokenType = AccessTokenType.Reference\n            },\n\n            new Client\n            {\n                ClientName = \"Client with Base64 encoded X509 Certificate\",\n                ClientId = \"certificate_base64_valid\",\n                Enabled = true,\n\n                ClientSecrets =\n                {\n                    new Secret\n                    {\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                        Value = Convert.ToBase64String(TestCert.Load().Export(X509ContentType.Cert))\n                    }\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n\n                AllowedScopes = new List<string>\n                {\n                    \"api1\", \"api2\"\n                }\n            },\n\n            new Client\n            {\n                ClientId = \"implicit\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                AllowedScopes = {\"api1\"},\n                RedirectUris = { \"http://implicit\" }\n            },\n            new Client\n            {\n                ClientId = \"implicit_and_client_creds\",\n                AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,\n                AllowedScopes = {\"api1\"},\n                RedirectUris = { \"http://implicit_and_client_creds\" }\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/ConfirmationSecretValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Newtonsoft.Json;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class ConfirmationSecretValidator : ISecretValidator\n{\n    public Task<SecretValidationResult> ValidateAsync(IEnumerable<Secret> secrets, ParsedSecret parsedSecret)\n    {\n        if (secrets.Any())\n        {\n            if (secrets.First().Type == \"confirmation.test\")\n            {\n                var cnf = new Dictionary<string, string>\n                {\n                    { \"x5t#S256\", \"foo\" }\n                };\n\n                var result = new SecretValidationResult\n                {\n                    Success = true,\n                    Confirmation = JsonConvert.SerializeObject(cnf)\n                };\n\n                return Task.FromResult(result);\n            }\n        }\n\n        return Task.FromResult(new SecretValidationResult { Success = false });\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/CustomProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\nclass CustomProfileService : TestUserProfileService\n{\n    public CustomProfileService(TestUserStore users, ILogger<TestUserProfileService> logger) : base(users, logger)\n    { }\n\n    public override async Task GetProfileDataAsync(ProfileDataRequestContext context)\n    {\n        await base.GetProfileDataAsync(context);\n\n        if (context.Subject.Identity.AuthenticationType == \"custom\")\n        {\n            var extraClaim = context.Subject.FindFirst(\"extra_claim\");\n            if (extraClaim != null)\n            {\n                context.IssuedClaims.Add(extraClaim);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/CustomResponseDto.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class CustomResponseDto\n{\n    public string string_value { get; set; }\n    public int int_value { get; set; }\n\n    public CustomResponseDto nested { get; set; }\n\n    public static CustomResponseDto Create\n    {\n        get\n        {\n            return new CustomResponseDto\n            {\n                string_value = \"dto_string\",\n                int_value = 43,\n                nested = new CustomResponseDto\n                {\n                    string_value = \"dto_nested_string\",\n                    int_value = 44\n                }\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/CustomResponseExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class CustomResponseExtensionGrantValidator : IExtensionGrantValidator\n{\n    public Task ValidateAsync(ExtensionGrantValidationContext context)\n    {\n        var response = new Dictionary<string, object>\n        {\n            { \"string_value\", \"some_string\" },\n            { \"int_value\", 42 },\n            { \"dto\",  CustomResponseDto.Create }\n        };\n\n        var credential = context.Request.Raw.Get(\"outcome\");\n\n        if (credential == \"succeed\")\n        {\n            context.Result = new GrantValidationResult(\"bob\", \"custom\", customResponse: response);\n        }\n        else\n        {\n            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, \"invalid_credential\", response);\n        }\n\n        return Task.CompletedTask;\n    }\n\n    public string GrantType\n    {\n        get { return \"custom\"; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/CustomResponseResourceOwnerValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class CustomResponseResourceOwnerValidator : IResourceOwnerPasswordValidator\n{\n    public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)\n    {\n        var response = new Dictionary<string, object>\n        {\n            { \"string_value\", \"some_string\" },\n            { \"int_value\", 42 },\n            { \"dto\",  CustomResponseDto.Create }\n        };\n\n        if (context.UserName == context.Password)\n        {\n            context.Result = new GrantValidationResult(context.UserName, \"password\", customResponse: response);\n        }\n        else\n        {\n            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, \"invalid_credential\", response);\n        }\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/DynamicParameterExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class DynamicParameterExtensionGrantValidator : IExtensionGrantValidator\n{\n    public Task ValidateAsync(ExtensionGrantValidationContext context)\n    {\n        var impersonatedClient = context.Request.Raw.Get(\"impersonated_client\");\n        var lifetime = context.Request.Raw.Get(\"lifetime\");\n        var extraClaim = context.Request.Raw.Get(\"claim\");\n        var tokenType = context.Request.Raw.Get(\"type\");\n        var sub = context.Request.Raw.Get(\"sub\");\n\n        if (!string.IsNullOrEmpty(impersonatedClient))\n        {\n            context.Request.ClientId = impersonatedClient;\n        }\n\n        if (!string.IsNullOrEmpty(lifetime))\n        {\n            context.Request.AccessTokenLifetime = int.Parse(lifetime);\n        }\n\n        if (!string.IsNullOrEmpty(tokenType))\n        {\n            if (tokenType == \"jwt\")\n            {\n                context.Request.AccessTokenType = AccessTokenType.Jwt;\n            }\n            else if (tokenType == \"reference\")\n            {\n                context.Request.AccessTokenType = AccessTokenType.Reference;\n            }\n        }\n\n        if (!string.IsNullOrEmpty(extraClaim))\n        {\n            context.Request.ClientClaims.Add(new Claim(\"extra\", extraClaim));\n        }\n\n        if (!string.IsNullOrEmpty(sub))\n        {\n            context.Result = new GrantValidationResult(sub, \"delegation\");\n        }\n        else\n        {\n            context.Result = new GrantValidationResult();\n        }\n\n        return Task.CompletedTask;\n    }\n\n    public string GrantType => \"dynamic\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/ExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class ExtensionGrantValidator : IExtensionGrantValidator\n{\n    public Task ValidateAsync(ExtensionGrantValidationContext context)\n    {\n        var credential = context.Request.Raw.Get(\"custom_credential\");\n        var extraClaim = context.Request.Raw.Get(\"extra_claim\");\n\n        if (credential != null)\n        {\n            if (extraClaim != null)\n            {\n                context.Result = new GrantValidationResult(\n                    subject: \"818727\",\n                    claims: new[] { new Claim(\"extra_claim\", extraClaim) },\n                    authenticationMethod: GrantType);\n            }\n            else\n            {\n                context.Result = new GrantValidationResult(subject: \"818727\", authenticationMethod: GrantType);\n            }\n        }\n        else\n        {\n            // custom error message\n            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, \"invalid_custom_credential\");\n        }\n\n        return Task.CompletedTask;\n    }\n\n    public string GrantType =>  \"custom\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/ExtensionGrantValidator2.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class ExtensionGrantValidator2 : IExtensionGrantValidator\n{\n    public Task ValidateAsync(ExtensionGrantValidationContext context)\n    {\n        var credential = context.Request.Raw.Get(\"custom_credential\");\n\n        if (credential != null)\n        {\n            // valid credential\n            context.Result = new GrantValidationResult(\"818727\", \"custom\");\n        }\n        else\n        {\n            // custom error message\n            context.Result = new GrantValidationResult(IdentityServer8.Models.TokenRequestErrors.InvalidGrant, \"invalid custom credential\");\n        }\n\n        return Task.CompletedTask;\n    }\n\n    public string GrantType => \"custom2\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/NoSubjectExtensionGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class NoSubjectExtensionGrantValidator : IExtensionGrantValidator\n{\n    public Task ValidateAsync(ExtensionGrantValidationContext context)\n    {\n        var credential = context.Request.Raw.Get(\"custom_credential\");\n\n        if (credential != null)\n        {\n            context.Result = new GrantValidationResult();\n        }\n        else\n        {\n            // custom error message\n            context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, \"invalid custom credential\");\n        }\n\n        return Task.CompletedTask;\n    }\n\n    public string GrantType => \"custom.nosubject\";\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/Scopes.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\ninternal class Scopes\n{\n    public static IEnumerable<IdentityResource> GetIdentityScopes()\n    {\n        return new IdentityResource[]\n        {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Email(),\n            new IdentityResources.Address(),\n            new IdentityResource(\"roles\", new[] { \"role\" })\n        };\n    }\n\n    public static IEnumerable<ApiResource> GetApiResources()\n    {\n        return new List<ApiResource>\n        {\n            new ApiResource\n            {\n                Name = \"api\",\n                ApiSecrets =\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n                Scopes = { \"api1\", \"api2\", \"api3\", \"api4.with.roles\" }\n            },\n            new ApiResource(\"other_api\")\n            {\n                Scopes = { \"other_api\" }\n            }\n        };\n    }\n\n    public static IEnumerable<ApiScope> GetApiScopes()\n    {\n        return new ApiScope[]\n        {\n            new ApiScope\n            {\n                Name = \"api1\"\n            },\n            new ApiScope\n            {\n                Name = \"api2\"\n            },\n            new ApiScope\n            {\n                Name = \"api3\"\n            },\n            new ApiScope\n            {\n                Name = \"api4.with.roles\",\n                UserClaims = { \"role\" }\n            },\n            new ApiScope\n            {\n                Name = \"other_api\",\n            },\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class Startup\n{\n    static public ICustomTokenRequestValidator CustomTokenRequestValidator { get; set; } \n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddAuthentication();\n\n        var builder = services.AddIdentityServer(options =>\n        {\n            options.IssuerUri = \"https://idsvr8\";\n\n            options.Events = new EventsOptions\n            {\n                RaiseErrorEvents = true,\n                RaiseFailureEvents = true,\n                RaiseInformationEvents = true,\n                RaiseSuccessEvents = true\n            };\n        });\n\n        builder.AddInMemoryClients(Clients.Get());\n        builder.AddInMemoryIdentityResources(Scopes.GetIdentityScopes());\n        builder.AddInMemoryApiResources(Scopes.GetApiResources());\n        builder.AddInMemoryApiScopes(Scopes.GetApiScopes());\n        builder.AddTestUsers(Users.Get());\n\n        builder.AddDeveloperSigningCredential(persistKey: false);\n\n        builder.AddExtensionGrantValidator<ExtensionGrantValidator>();\n        builder.AddExtensionGrantValidator<ExtensionGrantValidator2>();\n        builder.AddExtensionGrantValidator<NoSubjectExtensionGrantValidator>();\n        builder.AddExtensionGrantValidator<DynamicParameterExtensionGrantValidator>();\n\n        builder.AddProfileService<CustomProfileService>();\n\n        builder.AddJwtBearerClientAuthentication();\n        builder.AddSecretValidator<ConfirmationSecretValidator>();\n\n        // add a custom token request validator if set\n        if (CustomTokenRequestValidator != null)\n        {\n            builder.Services.AddTransient(r => CustomTokenRequestValidator);\n        }\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseIdentityServer();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/StartupWithCustomTokenResponses.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class StartupWithCustomTokenResponses\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddAuthentication();\n\n        var builder = services.AddIdentityServer(options =>\n        {\n            options.IssuerUri = \"https://idsvr8\";\n\n            options.Events = new EventsOptions\n            {\n                RaiseErrorEvents = true,\n                RaiseFailureEvents = true,\n                RaiseInformationEvents = true,\n                RaiseSuccessEvents = true\n            };\n        });\n\n        builder.AddInMemoryClients(Clients.Get());\n        builder.AddInMemoryIdentityResources(Scopes.GetIdentityScopes());\n        builder.AddInMemoryApiResources(Scopes.GetApiResources());\n        builder.AddInMemoryApiScopes(Scopes.GetApiScopes());\n\n        builder.AddDeveloperSigningCredential(persistKey: false);\n\n        services.AddTransient<IResourceOwnerPasswordValidator, CustomResponseResourceOwnerValidator>();\n        builder.AddExtensionGrantValidator<CustomResponseExtensionGrantValidator>();\n    }\n\n    public void Configure(IApplicationBuilder app)\n    {\n        app.UseIdentityServer();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/TestCustomTokenRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\npublic class TestCustomTokenRequestValidator : ICustomTokenRequestValidator\n{\n    public Task ValidateAsync(CustomTokenRequestValidationContext context)\n    {\n        context.Result.CustomResponse = new Dictionary<string, object>\n        {\n            {\"custom\", \"custom\" }\n        };\n\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/Setup/Users.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing IdentityModel;\nusing IdentityServer8;\nusing IdentityServer8.Test;\n\nnamespace IdentityServer.IntegrationTests.Clients.Setup;\n\ninternal static class Users\n{\n    public static List<TestUser> Get()\n    {\n        var users = new List<TestUser>\n        {\n            new TestUser{SubjectId = \"818727\", Username = \"alice\", Password = \"alice\", \n                Claims = new Claim[]\n                {\n                    new Claim(JwtClaimTypes.Name, \"Alice Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Alice\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"AliceSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.Role, \"Admin\"),\n                    new Claim(JwtClaimTypes.Role, \"Geek\"),\n                    new Claim(JwtClaimTypes.WebSite, \"http://alice.com\"),\n                    new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServerConstants.ClaimValueTypes.Json)\n                }\n            },\n            new TestUser{SubjectId = \"88421113\", Username = \"bob\", Password = \"bob\", \n                Claims = new Claim[]\n                {\n                    new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"BobSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.Role, \"Developer\"),\n                    new Claim(JwtClaimTypes.Role, \"Geek\"),\n                    new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                    new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServerConstants.ClaimValueTypes.Json)\n                }\n            },\n            new TestUser{SubjectId = \"88421113\", Username = \"bob_no_password\", \n                Claims = new Claim[]\n                {\n                    new Claim(JwtClaimTypes.Name, \"Bob Smith\"),\n                    new Claim(JwtClaimTypes.GivenName, \"Bob\"),\n                    new Claim(JwtClaimTypes.FamilyName, \"Smith\"),\n                    new Claim(JwtClaimTypes.Email, \"BobSmith@email.com\"),\n                    new Claim(JwtClaimTypes.EmailVerified, \"true\", ClaimValueTypes.Boolean),\n                    new Claim(JwtClaimTypes.Role, \"Developer\"),\n                    new Claim(JwtClaimTypes.Role, \"Geek\"),\n                    new Claim(JwtClaimTypes.WebSite, \"http://bob.com\"),\n                    new Claim(JwtClaimTypes.Address, @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServerConstants.ClaimValueTypes.Json)\n                }\n            }\n        };\n\n        return users;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Clients/UserInfoClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Http;\nusing System.Text;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Clients.Setup;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Clients;\n\npublic class UserInfoEndpointClient\n{\n    private const string TokenEndpoint = \"https://server/connect/token\";\n    private const string UserInfoEndpoint = \"https://server/connect/userinfo\";\n\n    private readonly HttpClient _client;\n\n    public UserInfoEndpointClient()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    public async Task Valid_client_with_GET_should_succeed()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid email api1\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n\n        var userInfo = await _client.GetUserInfoAsync(new UserInfoRequest\n        {\n            Address = UserInfoEndpoint,\n            Token = response.AccessToken\n        });\n\n        userInfo.IsError.Should().BeFalse();\n        userInfo.Claims.Count().Should().Be(3);\n\n        userInfo.Claims.Should().Contain(c => c.Type == \"sub\" && c.Value == \"88421113\");\n        userInfo.Claims.Should().Contain(c => c.Type == \"email\" && c.Value == \"BobSmith@email.com\");\n        userInfo.Claims.Should().Contain(c => c.Type == \"email_verified\" && c.Value == \"true\");\n    }\n\n    [Fact]\n    public async Task Request_address_scope_should_return_expected_response()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid address\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n\n        var userInfo = await _client.GetUserInfoAsync(new UserInfoRequest\n        {\n            Address = UserInfoEndpoint,\n            Token = response.AccessToken\n        });\n\n        userInfo.IsError.Should().BeFalse();\n        userInfo.Claims.First().Value.Should().Be(\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\");\n    }\n\n    [Fact]\n    public async Task Using_a_token_with_no_identity_scope_should_fail()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n\n        var userInfo = await _client.GetUserInfoAsync(new UserInfoRequest\n        {\n            Address = UserInfoEndpoint,\n            Token = response.AccessToken\n        });\n\n        userInfo.IsError.Should().BeTrue();\n        userInfo.HttpStatusCode.Should().Be(HttpStatusCode.Forbidden);\n    }\n\n    [Fact]\n    public async Task Using_a_token_with_an_identity_scope_but_no_openid_should_fail()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"email api1\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n\n        var userInfo = await _client.GetUserInfoAsync(new UserInfoRequest\n        {\n            Address = UserInfoEndpoint,\n            Token = response.AccessToken\n        });\n\n        userInfo.IsError.Should().BeTrue();\n        userInfo.HttpStatusCode.Should().Be(HttpStatusCode.Forbidden);\n    }\n\n    [Fact]\n    public async Task Invalid_token_should_fail()\n    {\n        var userInfo = await _client.GetUserInfoAsync(new UserInfoRequest\n        {\n            Address = UserInfoEndpoint,\n            Token = \"invalid\"\n        });\n\n        userInfo.IsError.Should().BeTrue();\n        userInfo.HttpStatusCode.Should().Be(HttpStatusCode.Unauthorized);\n    }\n\n    [Fact]\n    public async Task Complex_json_should_be_correct()\n    {\n        var response = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"roclient\",\n            ClientSecret = \"secret\",\n\n            Scope = \"openid email api1 api4.with.roles roles\",\n            UserName = \"bob\",\n            Password = \"bob\"\n        });\n\n        response.IsError.Should().BeFalse();\n\n        var payload = GetPayload(response);\n\n        var scopes = ((JArray) payload[\"scope\"]).Select(x => x.ToString()).ToArray();\n        scopes.Length.Should().Be(5);\n        scopes.Should().Contain(\"openid\");\n        scopes.Should().Contain(\"email\");\n        scopes.Should().Contain(\"api1\");\n        scopes.Should().Contain(\"api4.with.roles\");\n        scopes.Should().Contain(\"roles\");\n\n        var roles = ((JArray) payload[\"role\"]).Select(x => x.ToString()).ToArray();\n        roles.Length.Should().Be(2);\n        roles.Should().Contain(\"Geek\");\n        roles.Should().Contain(\"Developer\");\n\n        var userInfo = await _client.GetUserInfoAsync(new UserInfoRequest\n        {\n            Address = UserInfoEndpoint,\n            Token = response.AccessToken\n        });\n\n        //roles = ((JArray)userInfo.Json[\"role\"]).Select(x => x.ToString()).ToArray();\n        roles = userInfo.Json.TryGetStringArray(\"role\").ToArray();\n        roles.Length.Should().Be(2);\n        roles.Should().Contain(\"Geek\");\n        roles.Should().Contain(\"Developer\");\n    }\n\n    private Dictionary<string, object> GetPayload(TokenResponse response)\n    {\n        var token = response.AccessToken.Split('.').Skip(1).Take(1).First();\n        var dictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(\n            Encoding.UTF8.GetString(Base64Url.Decode(token)));\n\n        return dictionary;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Common/BrowserClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Net.Http;\n\nnamespace IdentityServer.IntegrationTests.Common;\n\npublic class BrowserClient : HttpClient\n{\n    public BrowserClient(BrowserHandler browserHandler)\n        : base(browserHandler)\n    {\n        BrowserHandler = browserHandler;\n    }\n\n    public BrowserHandler BrowserHandler { get; private set; }\n\n    public bool AllowCookies\n    {\n        get { return BrowserHandler.AllowCookies; }\n        set { BrowserHandler.AllowCookies = value; }\n    }\n    public bool AllowAutoRedirect\n    {\n        get { return BrowserHandler.AllowAutoRedirect; }\n        set { BrowserHandler.AllowAutoRedirect = value; }\n    }\n    public int ErrorRedirectLimit\n    {\n        get { return BrowserHandler.ErrorRedirectLimit; }\n        set { BrowserHandler.ErrorRedirectLimit = value; }\n    }\n    public int StopRedirectingAfter\n    {\n        get { return BrowserHandler.StopRedirectingAfter; }\n        set { BrowserHandler.StopRedirectingAfter = value; }\n    }\n\n    internal void RemoveCookie(string uri, string name)\n    {\n        BrowserHandler.RemoveCookie(uri, name);\n    }\n\n    internal System.Net.Cookie GetCookie(string uri, string name)\n    {\n        return BrowserHandler.GetCookie(uri, name);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Common/BrowserHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.IntegrationTests.Common;\n\n// thanks to Damian Hickey for this awesome sample\n// https://github.com/damianh/OwinHttpMessageHandler/blob/master/src/OwinHttpMessageHandler/OwinHttpMessageHandler.cs\npublic class BrowserHandler : DelegatingHandler\n{\n    private CookieContainer _cookieContainer = new CookieContainer();\n\n    public bool AllowCookies { get; set; } = true;\n    public bool AllowAutoRedirect { get; set; } = true;\n    public int ErrorRedirectLimit { get; set; } = 20;\n    public int StopRedirectingAfter { get; set; } = Int32.MaxValue;\n\n    public BrowserHandler(HttpMessageHandler next)\n        : base(next)\n    {\n    }\n\n    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n    {\n        var response = await SendCookiesAsync(request, cancellationToken);\n\n        int redirectCount = 0;\n\n        while (AllowAutoRedirect && \n            (300 <= (int)response.StatusCode && (int)response.StatusCode < 400) &&\n            redirectCount < StopRedirectingAfter)\n        {\n            if (redirectCount >= ErrorRedirectLimit)\n            {\n                throw new InvalidOperationException(string.Format(\"Too many redirects. Error limit = {0}\", redirectCount));\n            }\n\n            var location = response.Headers.Location;\n            if (!location.IsAbsoluteUri)\n            {\n                location = new Uri(response.RequestMessage.RequestUri, location);\n            }\n\n            request = new HttpRequestMessage(HttpMethod.Get, location);\n\n            response = await SendCookiesAsync(request, cancellationToken).ConfigureAwait(false);\n\n            redirectCount++;\n        }\n\n        return response;\n    }\n\n    internal Cookie GetCookie(string uri, string name)\n    {\n        return _cookieContainer.GetCookies(new Uri(uri)).Cast<Cookie>().Where(x => x.Name == name).FirstOrDefault();\n    }\n\n    internal void RemoveCookie(string uri, string name)\n    {\n        var cookie = _cookieContainer.GetCookies(new Uri(uri)).Cast<Cookie>().Where(x=>x.Name == name).FirstOrDefault();\n        if (cookie != null)\n        {\n            cookie.Expired = true;\n        }\n    }\n\n    protected async Task<HttpResponseMessage> SendCookiesAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n    {\n        if (AllowCookies)\n        {\n            string cookieHeader = _cookieContainer.GetCookieHeader(request.RequestUri);\n            if (!string.IsNullOrEmpty(cookieHeader))\n            {\n                request.Headers.Add(\"Cookie\", cookieHeader);\n            }\n        }\n\n        var response = await base.SendAsync(request, cancellationToken);\n\n        if (AllowCookies && response.Headers.Contains(\"Set-Cookie\"))\n        {\n            var responseCookieHeader = string.Join(\",\", response.Headers.GetValues(\"Set-Cookie\"));\n            _cookieContainer.SetCookies(request.RequestUri, responseCookieHeader);\n        }\n\n        return response;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Common/IdentityServerPipeline.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Test;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.TestHost;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer.IntegrationTests.Common;\n\npublic class IdentityServerPipeline\n{\n    public const string BaseUrl = \"https://server\";\n    public const string LoginPage = BaseUrl + \"/account/login\";\n    public const string ConsentPage = BaseUrl + \"/account/consent\";\n    public const string ErrorPage = BaseUrl + \"/home/error\";\n\n    public const string DeviceAuthorization = BaseUrl + \"/connect/deviceauthorization\";\n    public const string DiscoveryEndpoint = BaseUrl + \"/.well-known/openid-configuration\";\n    public const string DiscoveryKeysEndpoint = BaseUrl + \"/.well-known/openid-configuration/jwks\";\n    public const string AuthorizeEndpoint = BaseUrl + \"/connect/authorize\";\n    public const string TokenEndpoint = BaseUrl + \"/connect/token\";\n    public const string RevocationEndpoint = BaseUrl + \"/connect/revocation\";\n    public const string UserInfoEndpoint = BaseUrl + \"/connect/userinfo\";\n    public const string IntrospectionEndpoint = BaseUrl + \"/connect/introspect\";\n    public const string IdentityTokenValidationEndpoint = BaseUrl + \"/connect/identityTokenValidation\";\n    public const string EndSessionEndpoint = BaseUrl + \"/connect/endsession\";\n    public const string EndSessionCallbackEndpoint = BaseUrl + \"/connect/endsession/callback\";\n    public const string CheckSessionEndpoint = BaseUrl + \"/connect/checksession\";\n\n    public const string FederatedSignOutPath = \"/signout-oidc\";\n    public const string FederatedSignOutUrl = BaseUrl + FederatedSignOutPath;\n\n    public IdentityServerOptions Options { get; set; }\n    public List<Client> Clients { get; set; } = new List<Client>();\n    public List<IdentityResource> IdentityScopes { get; set; } = new List<IdentityResource>();\n    public List<ApiResource> ApiResources { get; set; } = new List<ApiResource>();\n    public List<ApiScope> ApiScopes { get; set; } = new List<ApiScope>();\n    public List<TestUser> Users { get; set; } = new List<TestUser>();\n\n    public TestServer Server { get; set; }\n    public HttpMessageHandler Handler { get; set; }\n\n    public BrowserClient BrowserClient { get; set; }\n    public HttpClient BackChannelClient { get; set; }\n\n    public MockMessageHandler BackChannelMessageHandler { get; set; } = new MockMessageHandler();\n    public MockMessageHandler JwtRequestMessageHandler { get; set; } = new MockMessageHandler();\n\n    public event Action<IServiceCollection> OnPreConfigureServices = services => { };\n    public event Action<IServiceCollection> OnPostConfigureServices = services => { };\n    public event Action<IApplicationBuilder> OnPreConfigure = app => { };\n    public event Action<IApplicationBuilder> OnPostConfigure = app => { };\n\n    public Func<HttpContext, Task<bool>> OnFederatedSignout;\n\n    public void Initialize(string basePath = null, bool enableLogging = false)\n    {\n        var builder = new WebHostBuilder();\n        builder.ConfigureServices(ConfigureServices);\n        builder.Configure(app =>\n        {\n            if (basePath != null)\n            {\n                app.Map(basePath, map =>\n                {\n                    ConfigureApp(map);\n                });\n            }\n            else\n            {\n                ConfigureApp(app);\n            }\n        });\n\n        if (enableLogging)\n        {\n            builder.ConfigureLogging((ctx, b) => b.AddConsole());\n        }\n\n        Server = new TestServer(builder);\n        Handler = Server.CreateHandler();\n\n        BrowserClient = new BrowserClient(new BrowserHandler(Handler));\n        BackChannelClient = new HttpClient(Handler);\n    }\n\n    public void ConfigureServices(IServiceCollection services)\n    {\n        OnPreConfigureServices(services);\n\n        services.AddAuthentication(opts =>\n        {\n            opts.AddScheme(\"external\", scheme =>\n            {\n                scheme.DisplayName = \"External\";\n                scheme.HandlerType = typeof(MockExternalAuthenticationHandler);\n            });\n        });\n        services.AddTransient<MockExternalAuthenticationHandler>(svcs =>\n        {\n            var handler = new MockExternalAuthenticationHandler(svcs.GetRequiredService<IHttpContextAccessor>());\n            if (OnFederatedSignout != null) handler.OnFederatedSignout = OnFederatedSignout;\n            return handler;\n        });\n\n        services.AddIdentityServer(options =>\n        {\n            Options = options;\n\n            options.Events = new EventsOptions\n            {\n                RaiseErrorEvents = true,\n                RaiseFailureEvents = true,\n                RaiseInformationEvents = true,\n                RaiseSuccessEvents = true\n            };\n        })\n        .AddInMemoryClients(Clients)\n        .AddInMemoryIdentityResources(IdentityScopes)\n        .AddInMemoryApiResources(ApiResources)\n        .AddInMemoryApiScopes(ApiScopes)\n        .AddTestUsers(Users)\n        .AddDeveloperSigningCredential(persistKey: false);\n\n        services.AddHttpClient(IdentityServerConstants.HttpClients.BackChannelLogoutHttpClient)\n            .AddHttpMessageHandler(() => BackChannelMessageHandler);\n\n        services.AddHttpClient(IdentityServerConstants.HttpClients.JwtRequestUriHttpClient)\n            .AddHttpMessageHandler(() => JwtRequestMessageHandler);\n\n        OnPostConfigureServices(services);\n    }\n\n    public void ConfigureApp(IApplicationBuilder app)\n    {\n        OnPreConfigure(app);\n\n        app.UseIdentityServer();\n\n        // UI endpoints\n        app.Map(Constants.UIConstants.DefaultRoutePaths.Login.EnsureLeadingSlash(), path =>\n        {\n            path.Run(ctx => OnLogin(ctx));\n        });\n        app.Map(Constants.UIConstants.DefaultRoutePaths.Logout.EnsureLeadingSlash(), path =>\n        {\n            path.Run(ctx => OnLogout(ctx));\n        });\n        app.Map(Constants.UIConstants.DefaultRoutePaths.Consent.EnsureLeadingSlash(), path =>\n        {\n            path.Run(ctx => OnConsent(ctx));\n        });\n        app.Map(Constants.UIConstants.DefaultRoutePaths.Error.EnsureLeadingSlash(), path =>\n        {\n            path.Run(ctx => OnError(ctx));\n        });\n\n        OnPostConfigure(app);\n    }\n\n    public bool LoginWasCalled { get; set; }\n    public AuthorizationRequest LoginRequest { get; set; }\n    public ClaimsPrincipal Subject { get; set; }\n    public bool FollowLoginReturnUrl { get; set; }\n\n    private async Task OnLogin(HttpContext ctx)\n    {\n        LoginWasCalled = true;\n        await ReadLoginRequest(ctx);\n        await IssueLoginCookie(ctx);\n    }\n\n    private async Task ReadLoginRequest(HttpContext ctx)\n    {\n        var interaction = ctx.RequestServices.GetRequiredService<IIdentityServerInteractionService>();\n        LoginRequest = await interaction.GetAuthorizationContextAsync(ctx.Request.Query[\"returnUrl\"].FirstOrDefault());\n    }\n\n    private async Task IssueLoginCookie(HttpContext ctx)\n    {\n        if (Subject != null)\n        {\n            var props = new AuthenticationProperties();\n            await ctx.SignInAsync(Subject, props);\n            Subject = null;\n            var url = ctx.Request.Query[Options.UserInteraction.LoginReturnUrlParameter].FirstOrDefault();\n            if (url != null)\n            {\n                ctx.Response.RedirectIfAllowed(url);\n            }\n        }\n    }\n\n    public bool LogoutWasCalled { get; set; }\n    public LogoutRequest LogoutRequest { get; set; }\n\n    private async Task OnLogout(HttpContext ctx)\n    {\n        LogoutWasCalled = true;\n        await ReadLogoutRequest(ctx);\n        await ctx.SignOutAsync();\n    }\n\n    private async Task ReadLogoutRequest(HttpContext ctx)\n    {\n        var interaction = ctx.RequestServices.GetRequiredService<IIdentityServerInteractionService>();\n        LogoutRequest = await interaction.GetLogoutContextAsync(ctx.Request.Query[\"logoutId\"].FirstOrDefault());\n    }\n\n    public bool ConsentWasCalled { get; set; }\n    public AuthorizationRequest ConsentRequest { get; set; }\n    public ConsentResponse ConsentResponse { get; set; }\n\n    private async Task OnConsent(HttpContext ctx)\n    {\n        ConsentWasCalled = true;\n        await ReadConsentMessage(ctx);\n        await CreateConsentResponse(ctx);\n    }\n\n    private async Task ReadConsentMessage(HttpContext ctx)\n    {\n        var interaction = ctx.RequestServices.GetRequiredService<IIdentityServerInteractionService>();\n        ConsentRequest = await interaction.GetAuthorizationContextAsync(ctx.Request.Query[\"returnUrl\"].FirstOrDefault());\n    }\n\n    private async Task CreateConsentResponse(HttpContext ctx)\n    {\n        if (ConsentRequest != null && ConsentResponse != null)\n        {\n            var interaction = ctx.RequestServices.GetRequiredService<IIdentityServerInteractionService>();\n            await interaction.GrantConsentAsync(ConsentRequest, ConsentResponse);\n            ConsentResponse = null;\n\n            var url = ctx.Request.Query[Options.UserInteraction.ConsentReturnUrlParameter].FirstOrDefault();\n            if (url != null)\n            {\n                ctx.Response.RedirectIfAllowed(url);\n            }\n        }\n    }\n\n    public bool ErrorWasCalled { get; set; }\n    public ErrorMessage ErrorMessage { get; set; }\n\n    private async Task OnError(HttpContext ctx)\n    {\n        ErrorWasCalled = true;\n        await ReadErrorMessage(ctx);\n    }\n\n    private async Task ReadErrorMessage(HttpContext ctx)\n    {\n        var interaction = ctx.RequestServices.GetRequiredService<IIdentityServerInteractionService>();\n        ErrorMessage = await interaction.GetErrorContextAsync(ctx.Request.Query[\"errorId\"].FirstOrDefault());\n    }\n\n    /* helpers */\n    public async Task LoginAsync(ClaimsPrincipal subject)\n    {\n        var old = BrowserClient.AllowAutoRedirect;\n        BrowserClient.AllowAutoRedirect = false;\n\n        Subject = subject;\n        await BrowserClient.GetAsync(LoginPage);\n\n        BrowserClient.AllowAutoRedirect = old;\n    }\n\n    public async Task LoginAsync(string subject)\n    {\n        await LoginAsync(new IdentityServerUser(subject).CreatePrincipal());\n    }\n\n    public void RemoveLoginCookie()\n    {\n        BrowserClient.RemoveCookie(BaseUrl, IdentityServerConstants.DefaultCookieAuthenticationScheme);\n    }\n    public void RemoveSessionCookie()\n    {\n        BrowserClient.RemoveCookie(BaseUrl, IdentityServerConstants.DefaultCheckSessionCookieName);\n    }\n    public Cookie GetSessionCookie()\n    {\n        return BrowserClient.GetCookie(BaseUrl, IdentityServerConstants.DefaultCheckSessionCookieName);\n    }\n\n    public string CreateAuthorizeUrl(\n        string clientId = null,\n        string responseType = null,\n        string scope = null,\n        string redirectUri = null,\n        string state = null,\n        string nonce = null,\n        string loginHint = null,\n        string acrValues = null,\n        string responseMode = null,\n        string codeChallenge = null,\n        string codeChallengeMethod = null,\n        object extra = null)\n    {\n        Parameters prms = extra is null ? null : Parameters.FromObject(extra);\n        var url = new RequestUrl(AuthorizeEndpoint).CreateAuthorizeUrl(\n            clientId: clientId,\n            responseType: responseType,\n            scope: scope,\n            redirectUri: redirectUri,\n            state: state,\n            nonce: nonce,\n            loginHint: loginHint,\n            acrValues: acrValues,\n            responseMode: responseMode,\n            codeChallenge: codeChallenge,\n            codeChallengeMethod: codeChallengeMethod,\n            extra: prms);\n        return url;\n    }\n\n    public AuthorizeResponse ParseAuthorizationResponseUrl(string url)\n    {\n        return new AuthorizeResponse(url);\n    }\n\n    public async Task<AuthorizeResponse> RequestAuthorizationEndpointAsync(\n        string clientId,\n        string responseType,\n        string scope = null,\n        string redirectUri = null,\n        string state = null,\n        string nonce = null,\n        string loginHint = null,\n        string acrValues = null,\n        string responseMode = null,\n        string codeChallenge = null,\n        string codeChallengeMethod = null,\n        object extra = null)\n    {\n        var old = BrowserClient.AllowAutoRedirect;\n        BrowserClient.AllowAutoRedirect = false;\n\n        var url = CreateAuthorizeUrl(clientId, responseType, scope, redirectUri, state, nonce, loginHint, acrValues, responseMode, codeChallenge, codeChallengeMethod, extra);\n        var result = await BrowserClient.GetAsync(url);\n        result.StatusCode.Should().Be(HttpStatusCode.Found);\n\n        BrowserClient.AllowAutoRedirect = old;\n\n        var redirect = result.Headers.Location.ToString();\n        if (redirect.StartsWith(IdentityServerPipeline.ErrorPage))\n        {\n            // request error page in pipeline so we can get error info\n            await BrowserClient.GetAsync(redirect);\n\n            // no redirect to client\n            return null;\n        }\n\n        return new AuthorizeResponse(redirect);\n    }\n}\n\npublic class MockMessageHandler : DelegatingHandler\n{\n    public bool InvokeWasCalled { get; set; }\n    public Func<HttpRequestMessage, Task> OnInvoke { get; set; }\n    public HttpResponseMessage Response { get; set; } = new HttpResponseMessage(HttpStatusCode.OK);\n\n    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n    {\n        InvokeWasCalled = true;\n\n        if (OnInvoke != null)\n        {\n            await OnInvoke.Invoke(request);\n        }\n        return Response;\n    }\n}\n\npublic class MockExternalAuthenticationHandler :\n    IAuthenticationHandler,\n    IAuthenticationSignInHandler,\n    IAuthenticationRequestHandler\n{\n    private readonly IHttpContextAccessor _httpContextAccessor;\n    private HttpContext HttpContext => _httpContextAccessor.HttpContext;\n\n    public Func<HttpContext, Task<bool>> OnFederatedSignout =\n        async context =>\n        {\n            await context.SignOutAsync();\n            return true;\n        };\n\n    public MockExternalAuthenticationHandler(IHttpContextAccessor httpContextAccessor)\n    {\n        _httpContextAccessor = httpContextAccessor;\n    }\n\n    public async Task<bool> HandleRequestAsync()\n    {\n        if (HttpContext.Request.Path == IdentityServerPipeline.FederatedSignOutPath)\n        {\n            return await OnFederatedSignout(HttpContext);\n        }\n\n        return false;\n    }\n\n    public Task<AuthenticateResult> AuthenticateAsync()\n    {\n        return Task.FromResult(AuthenticateResult.NoResult());\n    }\n\n    public Task ChallengeAsync(AuthenticationProperties properties)\n    {\n        return Task.CompletedTask;\n    }\n\n    public Task ForbidAsync(AuthenticationProperties properties)\n    {\n        return Task.CompletedTask;\n    }\n\n    public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)\n    {\n        return Task.CompletedTask;\n    }\n\n    public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)\n    {\n        return Task.CompletedTask;\n    }\n\n    public Task SignOutAsync(AuthenticationProperties properties)\n    {\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Common/MessageHandlerWrapper.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.IntegrationTests.Common;\n\npublic class MessageHandlerWrapper : DelegatingHandler\n{\n    public HttpResponseMessage Response { get; set; }\n\n    public MessageHandlerWrapper(HttpMessageHandler handler)\n        : base(handler)\n    {\n    }\n\n    protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n    {\n        Response = await base.SendAsync(request, cancellationToken);\n        return Response;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Common/NetworkHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.IntegrationTests.Common;\n\npublic class NetworkHandler : HttpMessageHandler\n{\n    enum Behavior\n    {\n        Throw,\n        ReturnError,\n        ReturnDocument\n    }\n\n    private readonly Exception _exception;\n    private readonly Behavior _behavior;\n    private readonly HttpStatusCode _statusCode;\n    private readonly string _reason;\n    private readonly string _document;\n    private readonly Func<HttpRequestMessage, string> _selector;\n    private readonly Func<HttpRequestMessage, HttpResponseMessage> _action;\n\n    public HttpRequestMessage Request { get; set; }\n    public string Body { get; set; }\n\n    public NetworkHandler(Exception exception)\n    {\n        _exception = exception;\n        _behavior = Behavior.Throw;\n    }\n\n    public NetworkHandler(HttpStatusCode statusCode, string reason)\n    {\n        _statusCode = statusCode;\n        _reason = reason;\n\n        _behavior = Behavior.ReturnError;\n    }\n\n    public NetworkHandler(string document, HttpStatusCode statusCode)\n    {\n        _statusCode = statusCode;\n        _document = document;\n        _behavior = Behavior.ReturnDocument;\n    }\n\n    public NetworkHandler(Func<HttpRequestMessage, string> documentSelector, HttpStatusCode statusCode)\n    {\n        _statusCode = statusCode;\n        _selector = documentSelector;\n        _behavior = Behavior.ReturnDocument;\n    }\n\n    public NetworkHandler(Func<HttpRequestMessage, HttpResponseMessage> action)\n    {\n        _action = action;\n    }\n\n    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n    {\n        Request = request;\n        Body = await SafeReadContentFrom(request);\n\n        if (_action != null)\n        {\n            return _action(request);\n        }\n\n        if (_behavior == Behavior.Throw) throw _exception;\n\n        var response = new HttpResponseMessage(_statusCode);\n\n        if (_behavior == Behavior.ReturnError)\n        {\n            response.ReasonPhrase = _reason;\n        }\n\n        if (_behavior == Behavior.ReturnDocument)\n        {\n            if (_selector != null)\n            {\n                response.Content = new StringContent(_selector(request));\n            }\n            else\n            {\n                response.Content = new StringContent(_document);\n            }\n        }\n\n        return response;\n    }\n\n    private async Task<string> SafeReadContentFrom(HttpRequestMessage request)\n    {\n        if (request.Content == null) return null;\n\n        return await request.Content.ReadAsStringAsync();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Common/TestCert.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO;\nusing System.Security.Cryptography.X509Certificates;\n\nnamespace IdentityServer.IntegrationTests.Common;\n\ninternal static class TestCert\n{\n    public static X509Certificate2 Load()\n    {\n        var cert = Path.Combine(System.AppContext.BaseDirectory, \"identityserver_testing.pfx\");\n        return new X509Certificate2(cert, \"password\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Conformance/Basic/ClientAuthenticationTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Conformance.Basic;\n\npublic class ClientAuthenticationTests \n{\n    private const string Category = \"Conformance.Basic.ClientAuthenticationTests\";\n\n    private IdentityServerPipeline _pipeline = new IdentityServerPipeline();\n\n    public ClientAuthenticationTests()\n    {\n        _pipeline.IdentityScopes.Add(new IdentityResources.OpenId());\n        _pipeline.Clients.Add(new Client\n        {\n            Enabled = true,\n            ClientId = \"code_pipeline.Client\",\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(\"secret\".Sha512())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RequirePkce = false,\n            RedirectUris = new List<string>\n            {\n                \"https://code_pipeline.Client/callback\",\n                \"https://code_pipeline.Client/callback?foo=bar&baz=quux\"\n            }\n        });\n\n        _pipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n               {\n                    new Claim(\"name\", \"Bob Loblaw\"),\n                    new Claim(\"email\", \"bob@loblaw.com\"),\n                    new Claim(\"role\", \"Attorney\")\n               }\n        });\n\n        _pipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Token_endpoint_supports_client_authentication_with_basic_authentication_with_POST()\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n\n        _pipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _pipeline.CreateAuthorizeUrl(\n                       clientId: \"code_pipeline.Client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://code_pipeline.Client/callback?foo=bar&baz=quux\",\n                       nonce: nonce);\n        var response = await _pipeline.BrowserClient.GetAsync(url);\n\n        var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());\n        authorization.Code.Should().NotBeNull();\n\n        var code = authorization.Code;\n\n        // backchannel client\n        var wrapper = new MessageHandlerWrapper(_pipeline.Handler);\n        var tokenClient = new HttpClient(wrapper);\n        var tokenResult = await tokenClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = \"code_pipeline.Client\",\n            ClientSecret = \"secret\",\n\n            Code = code,\n            RedirectUri = \"https://code_pipeline.Client/callback?foo=bar&baz=quux\"\n        });\n\n        tokenResult.IsError.Should().BeFalse();\n        tokenResult.HttpErrorReason.Should().Be(\"OK\");\n        tokenResult.TokenType.Should().Be(\"Bearer\");\n        tokenResult.AccessToken.Should().NotBeNull();\n        tokenResult.ExpiresIn.Should().BeGreaterThan(0);\n        tokenResult.IdentityToken.Should().NotBeNull();\n\n        wrapper.Response.Headers.CacheControl.NoCache.Should().BeTrue();\n        wrapper.Response.Headers.CacheControl.NoStore.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Token_endpoint_supports_client_authentication_with_form_encoded_authentication_in_POST_body()\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n\n        _pipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _pipeline.CreateAuthorizeUrl(\n                       clientId: \"code_pipeline.Client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://code_pipeline.Client/callback?foo=bar&baz=quux\",\n                       nonce: nonce);\n        var response = await _pipeline.BrowserClient.GetAsync(url);\n\n        var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());\n        authorization.Code.Should().NotBeNull();\n\n        var code = authorization.Code;\n\n        // backchannel client\n        var wrapper = new MessageHandlerWrapper(_pipeline.Handler);\n        var tokenClient = new HttpClient(wrapper);\n        var tokenResult = await tokenClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = \"code_pipeline.Client\",\n            ClientSecret = \"secret\",\n            ClientCredentialStyle = ClientCredentialStyle.PostBody,\n\n            Code = code,\n            RedirectUri = \"https://code_pipeline.Client/callback?foo=bar&baz=quux\"\n        });\n\n        tokenResult.IsError.Should().BeFalse();\n        tokenResult.HttpErrorReason.Should().Be(\"OK\");\n        tokenResult.TokenType.Should().Be(\"Bearer\");\n        tokenResult.AccessToken.Should().NotBeNull();\n        tokenResult.ExpiresIn.Should().BeGreaterThan(0);\n        tokenResult.IdentityToken.Should().NotBeNull();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Conformance/Basic/CodeFlowTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Linq;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Conformance.Basic;\n\npublic class CodeFlowTests \n{\n    private const string Category = \"Conformance.Basic.CodeFlowTests\";\n\n    private IdentityServerPipeline _pipeline = new IdentityServerPipeline();\n\n    public CodeFlowTests()\n    {\n        _pipeline.IdentityScopes.Add(new IdentityResources.OpenId());\n        _pipeline.Clients.Add(new Client\n        {\n            Enabled = true,\n            ClientId = \"code_pipeline.Client\",\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(\"secret\".Sha512())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RequirePkce = false,\n            RedirectUris = new List<string>\n            {\n                \"https://code_pipeline.Client/callback\",\n                \"https://code_pipeline.Client/callback?foo=bar&baz=quux\"\n            }\n        });\n\n        _pipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n               {\n                    new Claim(\"name\", \"Bob Loblaw\"),\n                    new Claim(\"email\", \"bob@loblaw.com\"),\n                    new Claim(\"role\", \"Attorney\")\n               }\n        });\n\n        _pipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task No_state_should_not_result_in_shash()\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n\n        _pipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _pipeline.CreateAuthorizeUrl(\n                       clientId: \"code_pipeline.Client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://code_pipeline.Client/callback?foo=bar&baz=quux\",\n                       nonce: nonce);\n        var response = await _pipeline.BrowserClient.GetAsync(url);\n\n        var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());\n        authorization.Code.Should().NotBeNull();\n\n        var code = authorization.Code;\n\n        // backchannel client\n        var wrapper = new MessageHandlerWrapper(_pipeline.Handler);\n        var tokenClient = new HttpClient(wrapper);\n        var tokenResult = await tokenClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = \"code_pipeline.Client\",\n            ClientSecret = \"secret\",\n\n            Code = code,\n            RedirectUri = \"https://code_pipeline.Client/callback?foo=bar&baz=quux\"\n        });\n\n        tokenResult.IsError.Should().BeFalse();\n        tokenResult.HttpErrorReason.Should().Be(\"OK\");\n        tokenResult.TokenType.Should().Be(\"Bearer\");\n        tokenResult.AccessToken.Should().NotBeNull();\n        tokenResult.ExpiresIn.Should().BeGreaterThan(0);\n        tokenResult.IdentityToken.Should().NotBeNull();\n\n        var token = new JwtSecurityToken(tokenResult.IdentityToken);\n        \n        var s_hash = token.Claims.FirstOrDefault(c => c.Type == \"s_hash\");\n        s_hash.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task State_should_result_in_shash()\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n\n        _pipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _pipeline.CreateAuthorizeUrl(\n                       clientId: \"code_pipeline.Client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://code_pipeline.Client/callback?foo=bar&baz=quux\",\n                       state: \"state\",\n                       nonce: nonce);\n        var response = await _pipeline.BrowserClient.GetAsync(url);\n\n        var authorization = _pipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());\n        authorization.Code.Should().NotBeNull();\n\n        var code = authorization.Code;\n\n        // backchannel client\n        var wrapper = new MessageHandlerWrapper(_pipeline.Handler);\n        var tokenClient = new HttpClient(wrapper);\n        var tokenResult = await tokenClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = \"code_pipeline.Client\",\n            ClientSecret = \"secret\",\n\n            Code = code,\n            RedirectUri = \"https://code_pipeline.Client/callback?foo=bar&baz=quux\"\n        });\n\n        tokenResult.IsError.Should().BeFalse();\n        tokenResult.HttpErrorReason.Should().Be(\"OK\");\n        tokenResult.TokenType.Should().Be(\"Bearer\");\n        tokenResult.AccessToken.Should().NotBeNull();\n        tokenResult.ExpiresIn.Should().BeGreaterThan(0);\n        tokenResult.IdentityToken.Should().NotBeNull();\n\n        var token = new JwtSecurityToken(tokenResult.IdentityToken);\n        \n        var s_hash = token.Claims.FirstOrDefault(c => c.Type == \"s_hash\");\n        s_hash.Should().NotBeNull();\n        s_hash.Value.Should().Be(CryptoHelper.CreateHashClaimValue(\"state\", \"RS256\"));\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Conformance/Basic/RedirectUriTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Conformance.Basic;\n\npublic class RedirectUriTests\n{\n    private const string Category = \"Conformance.Basic.RedirectUriTests\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public RedirectUriTests()\n    {\n        _mockPipeline.Initialize();\n\n        _mockPipeline.Clients.Add(new Client\n        {\n            Enabled = true,\n            ClientId = \"code_client\",\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(\"secret\".Sha512())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RequirePkce = false,\n            RedirectUris = new List<string>\n            {\n                \"https://code_client/callback\",\n                \"https://code_client/callback?foo=bar&baz=quux\"\n            }\n        });\n\n        _mockPipeline.IdentityScopes.Add(new IdentityResources.OpenId());\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n                {\n                    new Claim(\"name\", \"Bob Loblaw\"),\n                    new Claim(\"email\", \"bob@loblaw.com\"),\n                    new Claim(\"role\", \"Attorney\")\n                }\n        });\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Reject_redirect_uri_not_matching_registered_redirect_uri()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var state = Guid.NewGuid().ToString();\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n                       clientId: \"code_client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://bad\",\n                       state: state,\n                       nonce: nonce);\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Reject_request_without_redirect_uri_when_multiple_registered()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var state = Guid.NewGuid().ToString();\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n                      clientId: \"code_client\",\n                      responseType: \"code\",\n                      scope: \"openid\",\n                      // redirectUri deliberately absent \n                      redirectUri: null,\n                      state: state,\n                      nonce: nonce);\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Preserves_query_parameters_in_redirect_uri()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var state = Guid.NewGuid().ToString();\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _mockPipeline.CreateAuthorizeUrl(\n                       clientId: \"code_client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://code_client/callback?foo=bar&baz=quux\",\n                       state: state,\n                       nonce: nonce);\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://code_client/callback?\");\n        var authorization = _mockPipeline.ParseAuthorizationResponseUrl(response.Headers.Location.ToString());\n        authorization.Code.Should().NotBeNull();\n        authorization.State.Should().Be(state);\n        var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(response.Headers.Location.Query);\n        query[\"foo\"].ToString().Should().Be(\"bar\");\n        query[\"baz\"].ToString().Should().Be(\"quux\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Rejects_redirect_uri_when_query_parameter_does_not_match()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var state = Guid.NewGuid().ToString();\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n                       clientId: \"code_client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://code_client/callback?baz=quux&foo=bar\",\n                       state: state,\n                       nonce: nonce);\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Conformance/Basic/ResponseTypeResponseModeTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Conformance.Basic;\n\npublic class ResponseTypeResponseModeTests\n{\n    private const string Category = \"Conformance.Basic.ResponseTypeResponseModeTests\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public ResponseTypeResponseModeTests()\n    {\n        _mockPipeline.Initialize();\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        _mockPipeline.Clients.Add(new Client\n        {\n            Enabled = true,\n            ClientId = \"code_client\",\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(\"secret\".Sha512())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RequirePkce = false,\n            RedirectUris = new List<string>\n            {\n                \"https://code_client/callback\"\n            }\n        });\n\n        _mockPipeline.IdentityScopes.Add(new IdentityResources.OpenId());\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n                {\n                    new Claim(\"name\", \"Bob Loblaw\"),\n                    new Claim(\"email\", \"bob@loblaw.com\"),\n                    new Claim(\"role\", \"Attorney\")\n                }\n        });\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Request_with_response_type_code_supported()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var metadata = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.DiscoveryEndpoint);\n        metadata.StatusCode.Should().Be(HttpStatusCode.OK);\n\n        var state = Guid.NewGuid().ToString();\n        var nonce = Guid.NewGuid().ToString();\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n                       clientId: \"code_client\",\n                       responseType: \"code\",\n                       scope: \"openid\",\n                       redirectUri: \"https://code_client/callback\",\n                       state: state,\n                       nonce: nonce);\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        response.StatusCode.Should().Be(HttpStatusCode.Found);\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IsError.Should().BeFalse();\n        authorization.Code.Should().NotBeNull();\n        authorization.State.Should().Be(state);\n    }\n\n    // this might not be in sync with the actual conformance tests\n    // since we dead-end on the error page due to changes \n    // to follow the RFC to address open redirect in original OAuth RFC\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Request_missing_response_type_rejected()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var state = Guid.NewGuid().ToString();\n        var nonce = Guid.NewGuid().ToString();\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"code_client\",\n            responseType: null, // missing\n            scope: \"openid\",\n            redirectUri: \"https://code_client/callback\",\n            state: state,\n            nonce: nonce);\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"unsupported_response_type\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Conformance/Pkce/PkceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Conformance.Pkce;\n\npublic class PkceTests\n{\n    private const string Category = \"PKCE\";\n\n    private IdentityServerPipeline _pipeline = new IdentityServerPipeline();\n\n    private Client client;\n\n    private const string client_id = \"code_client\";\n    private const string client_id_optional = \"code_client_optional\";\n    private const string client_id_plain = \"code_plain_client\";\n    private const string client_id_pkce = \"codewithproofkey_client\";\n    private const string client_id_pkce_plain = \"codewithproofkey_plain_client\";\n\n\n    private string redirect_uri = \"https://code_client/callback\";\n    private string code_verifier = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\";\n    private string client_secret = \"secret\";\n    private string response_type = \"code\";\n\n    public PkceTests()\n    {\n        _pipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                    new Claim(\"name\", \"Bob Loblaw\"),\n                    new Claim(\"email\", \"bob@loblaw.com\"),\n                    new Claim(\"role\", \"Attorney\")\n            }\n        });\n        _pipeline.IdentityScopes.Add(new IdentityResources.OpenId());\n\n        _pipeline.Clients.Add(client = new Client\n        {\n            Enabled = true,\n            ClientId = client_id,\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(client_secret.Sha256())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            RequirePkce = true,\n\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RedirectUris = new List<string>\n            {\n                redirect_uri\n            }\n        });\n        _pipeline.Clients.Add(client = new Client\n        {\n            Enabled = true,\n            ClientId = client_id_optional,\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(client_secret.Sha256())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            RequirePkce = false,\n\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RedirectUris = new List<string>\n            {\n                redirect_uri\n            }\n        });\n        _pipeline.Clients.Add(client = new Client\n        {\n            Enabled = true,\n            ClientId = client_id_pkce,\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(client_secret.Sha256())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            RequirePkce = true,\n\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RedirectUris = new List<string>\n            {\n                redirect_uri\n            }\n        });\n\n        // allow plain text PKCE\n        _pipeline.Clients.Add(client = new Client\n        {\n            Enabled = true,\n            ClientId = client_id_plain,\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(client_secret.Sha256())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            RequirePkce = true,\n            AllowPlainTextPkce = true,\n\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RedirectUris = new List<string>\n            {\n                redirect_uri\n            }\n        });\n        _pipeline.Clients.Add(client = new Client\n        {\n            Enabled = true,\n            ClientId = client_id_pkce_plain,\n            ClientSecrets = new List<Secret>\n            {\n                new Secret(client_secret.Sha256())\n            },\n\n            AllowedGrantTypes = GrantTypes.Code,\n            RequirePkce = true,\n            AllowPlainTextPkce = true,\n\n            AllowedScopes = { \"openid\" },\n\n            RequireConsent = false,\n            RedirectUris = new List<string>\n            {\n                redirect_uri\n            }\n        });\n\n        _pipeline.Initialize();\n    }\n\n    [Theory]\n    [InlineData(client_id)]\n    [InlineData(client_id_pkce)]\n    [Trait(\"Category\", Category)]\n    public async Task Client_cannot_use_plain_code_challenge_method(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: OidcConstants.CodeChallengeMethods.Plain);\n\n        _pipeline.ErrorWasCalled.Should().BeTrue();\n        _pipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n    }\n\n    [Theory]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Client_can_use_plain_code_challenge_method(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: OidcConstants.CodeChallengeMethods.Plain);\n\n        authorizeResponse.IsError.Should().BeFalse();\n\n        var code = authorizeResponse.Code;\n\n        var tokenResponse = await _pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = clientId,\n            ClientSecret = client_secret,\n\n            Code = code,\n            RedirectUri = redirect_uri,\n            CodeVerifier = code_verifier\n        });\n\n        tokenResponse.IsError.Should().BeFalse();\n        tokenResponse.TokenType.Should().Be(\"Bearer\");\n        tokenResponse.AccessToken.Should().NotBeNull();\n        tokenResponse.IdentityToken.Should().NotBeNull();\n        tokenResponse.ExpiresIn.Should().BeGreaterThan(0);\n    }\n\n    [Theory]\n    [InlineData(client_id)]\n    [InlineData(client_id_pkce)]\n    [Trait(\"Category\", Category)]\n    public async Task Client_can_use_sha256_code_challenge_method(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = Sha256OfCodeVerifier(code_verifier);\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: OidcConstants.CodeChallengeMethods.Sha256);\n\n        authorizeResponse.IsError.Should().BeFalse();\n\n        var code = authorizeResponse.Code;\n\n        var tokenResponse = await _pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = clientId,\n            ClientSecret = client_secret,\n\n            Code = code,\n            RedirectUri = redirect_uri,\n            CodeVerifier = code_verifier\n        });\n\n        tokenResponse.IsError.Should().BeFalse();\n        tokenResponse.TokenType.Should().Be(\"Bearer\");\n        tokenResponse.AccessToken.Should().NotBeNull();\n        tokenResponse.IdentityToken.Should().NotBeNull();\n        tokenResponse.ExpiresIn.Should().BeGreaterThan(0);\n    }\n\n    [Theory]\n    [InlineData(client_id_pkce)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Authorize_request_needs_code_challenge(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce);\n\n        authorizeResponse.Should().BeNull();\n    }\n    \n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Code_verifier_should_not_be_accepted_if_no_code_challenge_was_used()\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(client_id_optional,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce);\n\n        authorizeResponse.IsError.Should().BeFalse();\n\n        var code = authorizeResponse.Code;\n\n        var tokenResponse = await _pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = client_id_optional,\n            ClientSecret = client_secret,\n\n            Code = code,\n            RedirectUri = redirect_uri,\n            CodeVerifier = code_verifier\n        });\n\n        tokenResponse.IsError.Should().BeTrue();\n    }\n\n    [Theory]\n    [InlineData(client_id)]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Authorize_request_code_challenge_cannot_be_too_short(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge:\"a\");\n\n        _pipeline.ErrorWasCalled.Should().BeTrue();\n        _pipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n    }\n\n    [Theory]\n    [InlineData(client_id)]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Authorize_request_code_challenge_cannot_be_too_long(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: new string('a', _pipeline.Options.InputLengthRestrictions.CodeChallengeMaxLength + 1)\n        );\n\n        _pipeline.ErrorWasCalled.Should().BeTrue();\n        _pipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n    }\n\n    [Theory]\n    [InlineData(client_id)]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Authorize_request_needs_supported_code_challenge_method(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: \"unknown_code_challenge_method\"\n        );\n\n        authorizeResponse.Should().BeNull();\n    }\n\n    [Theory]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Token_request_needs_code_verifier(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: OidcConstants.CodeChallengeMethods.Plain);\n\n        authorizeResponse.IsError.Should().BeFalse();\n\n        var code = authorizeResponse.Code;\n\n        var tokenResponse = await _pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = clientId,\n            ClientSecret = client_secret,\n\n            Code = code,\n            RedirectUri = redirect_uri,\n        });\n\n        tokenResponse.IsError.Should().BeTrue();\n        tokenResponse.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n    }\n\n    [Theory]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Token_request_code_verifier_cannot_be_too_short(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: OidcConstants.CodeChallengeMethods.Plain);\n\n        authorizeResponse.IsError.Should().BeFalse();\n\n        var code = authorizeResponse.Code;\n\n        var tokenResponse = await _pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = clientId,\n            ClientSecret = client_secret,\n\n            Code = code,\n            RedirectUri = redirect_uri,\n            CodeVerifier = \"a\"\n        });\n\n        tokenResponse.IsError.Should().BeTrue();\n        tokenResponse.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n    }\n\n    [Theory]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Token_request_code_verifier_cannot_be_too_long(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: OidcConstants.CodeChallengeMethods.Plain);\n\n        authorizeResponse.IsError.Should().BeFalse();\n\n        var code = authorizeResponse.Code;\n\n        var tokenResponse = await _pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = clientId,\n            ClientSecret = client_secret,\n\n            Code = code,\n            RedirectUri = redirect_uri,\n            CodeVerifier = new string('a', _pipeline.Options.InputLengthRestrictions.CodeVerifierMaxLength + 1)\n        });\n\n        tokenResponse.IsError.Should().BeTrue();\n        tokenResponse.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n    }\n\n    [Theory]\n    [InlineData(client_id_plain)]\n    [InlineData(client_id_pkce_plain)]\n    [Trait(\"Category\", Category)]\n    public async Task Token_request_code_verifier_must_match_with_code_chalenge(string clientId)\n    {\n        await _pipeline.LoginAsync(\"bob\");\n\n        var nonce = Guid.NewGuid().ToString();\n        var code_challenge = code_verifier;\n        var authorizeResponse = await _pipeline.RequestAuthorizationEndpointAsync(clientId,\n            response_type,\n            IdentityServerConstants.StandardScopes.OpenId,\n            redirect_uri,\n            nonce: nonce,\n            codeChallenge: code_challenge,\n            codeChallengeMethod: OidcConstants.CodeChallengeMethods.Plain);\n\n        authorizeResponse.IsError.Should().BeFalse();\n\n        var code = authorizeResponse.Code;\n\n        var tokenResponse = await _pipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = clientId,\n            ClientSecret = client_secret,\n\n            Code = code,\n            RedirectUri = redirect_uri,\n            CodeVerifier = \"mismatched_code_verifier\"\n        });\n\n        tokenResponse.IsError.Should().BeTrue();\n        tokenResponse.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n    }\n\n    private static string Sha256OfCodeVerifier(string codeVerifier)\n    {\n        var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier);\n        var hashedBytes = codeVerifierBytes.Sha256();\n        var transformedCodeVerifier = Base64Url.Encode(hashedBytes);\n\n        return transformedCodeVerifier;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Authorize/AuthorizeTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Stores.Default;\nusing IdentityServer8.Test;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Authorize;\n\npublic class AuthorizeTests\n{\n    private const string Category = \"Authorize endpoint\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    private Client _client1;\n\n    public AuthorizeTests()\n    {\n        _mockPipeline.Clients.AddRange(new Client[] {\n            _client1 = new Client\n            {\n                ClientId = \"client1\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n\n                AllowedScopes = new List<string> { \"openid\", \"profile\" },\n                RedirectUris = new List<string> { \"https://client1/callback\" },\n                AllowAccessTokensViaBrowser = true\n            },\n            new Client\n            {\n                ClientId = \"client2\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = true,\n\n                AllowedScopes = new List<string> { \"openid\", \"profile\", \"api1\", \"api2\" },\n                RedirectUris = new List<string> { \"https://client2/callback\" },\n                AllowAccessTokensViaBrowser = true\n            },\n            new Client\n            {\n                ClientId = \"client3\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n\n                AllowedScopes = new List<string> { \"openid\", \"profile\", \"api1\", \"api2\" },\n                RedirectUris = new List<string> { \"https://client3/callback\" },\n                AllowAccessTokensViaBrowser = true,\n                EnableLocalLogin = false,\n                IdentityProviderRestrictions = new List<string> { \"google\" }\n            },\n            new Client\n            {\n                ClientId = \"client4\",\n                AllowedGrantTypes = GrantTypes.Code,\n                RequireClientSecret = false,\n                RequireConsent = false,\n                RequirePkce = false,\n                AllowedScopes = new List<string> { \"openid\", \"profile\", \"api1\", \"api2\" },\n                RedirectUris = new List<string> { \"https://client4/callback\" },\n            },\n\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email()\n        });\n        _mockPipeline.ApiResources.AddRange(new ApiResource[] {\n            new ApiResource\n            {\n                Name = \"api\",\n                Scopes = { \"api1\", \"api2\" }\n            }\n        });\n        _mockPipeline.ApiScopes.AddRange(new ApiScope[] {\n            new ApiScope\n            {\n                Name = \"api1\"\n            },\n            new ApiScope\n            {\n                Name = \"api2\"\n            }\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task get_request_should_not_return_404()\n    {\n        var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.AuthorizeEndpoint);\n\n        response.StatusCode.Should().NotBe(HttpStatusCode.NotFound);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task post_request_without_form_should_return_415()\n    {\n        var response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.AuthorizeEndpoint, new StringContent(\"foo\"));\n\n        response.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task post_request_should_return_200()\n    {\n        var response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.AuthorizeEndpoint,\n            new FormUrlEncodedContent(\n                new Dictionary<string, string> { }));\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task get_request_should_not_return_500()\n    {\n        var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.AuthorizeEndpoint);\n\n        ((int) response.StatusCode).Should().BeLessThan(500);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task anonymous_user_should_be_redirected_to_login_page()\n    {\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginWasCalled.Should().BeTrue();\n    }\n\n    [Theory]\n    [InlineData((Type) null)]\n    [InlineData(typeof(QueryStringAuthorizationParametersMessageStore))]\n    [InlineData(typeof(DistributedCacheAuthorizationParametersMessageStore))]\n    [Trait(\"Category\", Category)]\n    public async Task signin_request_should_have_authorization_params(Type storeType)\n    {\n        if (storeType != null)\n        {\n            _mockPipeline.OnPostConfigureServices += services =>\n            {\n                services.AddTransient(typeof(IAuthorizationParametersMessageStore), storeType);\n            };\n            _mockPipeline.Initialize();\n        }\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            loginHint: \"login_hint_value\",\n            acrValues: \"acr_1 acr_2 tenant:tenant_value idp:idp_value\",\n            extra: new\n            {\n                display = \"popup\", // must use a valid value from the spec for display\n                ui_locales = \"ui_locale_value\",\n                custom_foo = \"foo_value\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url + \"&foo=bar\");\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n        _mockPipeline.LoginRequest.Client.ClientId.Should().Be(\"client1\");\n        _mockPipeline.LoginRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.LoginRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"idp_value\");\n        _mockPipeline.LoginRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.LoginRequest.LoginHint.Should().Be(\"login_hint_value\");\n        _mockPipeline.LoginRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n        _mockPipeline.LoginRequest.Parameters.AllKeys.Should().Contain(\"foo\");\n        _mockPipeline.LoginRequest.Parameters[\"foo\"].Should().Be(\"bar\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task signin_response_should_allow_successful_authorization_response()\n    {\n        _mockPipeline.Subject = new IdentityServerUser(\"bob\").CreatePrincipal();\n        _mockPipeline.BrowserClient.StopRedirectingAfter = 2;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://client1/callback\");\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IsError.Should().BeFalse();\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.State.Should().Be(\"123_state\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authenticated_user_with_valid_request_should_receive_authorization_response()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://client1/callback\");\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IsError.Should().BeFalse();\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.State.Should().Be(\"123_state\");\n    }\n\n    [Theory]\n    [InlineData((Type) null)]\n    [InlineData(typeof(QueryStringAuthorizationParametersMessageStore))]\n    [InlineData(typeof(DistributedCacheAuthorizationParametersMessageStore))]\n    [Trait(\"Category\", Category)]\n    public async Task login_response_and_consent_response_should_receive_authorization_response(Type storeType)\n    {\n        if (storeType != null)\n        {\n            _mockPipeline.OnPostConfigureServices += services =>\n            {\n                services.AddTransient(typeof(IAuthorizationParametersMessageStore), storeType);\n            };\n            _mockPipeline.Initialize();\n        }\n\n        _mockPipeline.Subject = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n        _mockPipeline.ConsentResponse = new ConsentResponse()\n        {\n            ScopesValuesConsented = new string[] { \"openid\", \"api1\", \"profile\" }\n        };\n\n        _mockPipeline.BrowserClient.StopRedirectingAfter = 4;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token token\",\n            scope: \"openid profile api1 api2\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://client2/callback\");\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IsError.Should().BeFalse();\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.State.Should().Be(\"123_state\");\n        var scopes = authorization.Scope.Split(' ');\n        scopes.Should().BeEquivalentTo(new string[] { \"profile\", \"api1\", \"openid\" });\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task idp_should_be_passed_to_login_page()\n    {\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client3\",\n            responseType: \"id_token\",\n            scope: \"openid profile\",\n            redirectUri: \"https://client3/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            acrValues: \"idp:google\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginWasCalled.Should().BeTrue();\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"google\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task idp_not_allowed_by_client_should_not_be_passed_to_login_page()\n    {\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client3\",\n            responseType: \"id_token\",\n            scope: \"openid profile\",\n            redirectUri: \"https://client3/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            acrValues: \"idp:facebook\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginWasCalled.Should().BeTrue();\n        _mockPipeline.LoginRequest.IdP.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task user_idp_not_allowed_by_client_should_cause_login_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client3\",\n            responseType: \"id_token\",\n            scope: \"openid profile\",\n            redirectUri: \"https://client3/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginWasCalled.Should().BeTrue();\n        _mockPipeline.LoginRequest.IdP.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task for_invalid_client_error_page_should_not_receive_client_id()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: null,\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://invalid\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.ClientId.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task error_page_should_receive_client_id()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://invalid\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.ClientId.Should().Be(\"client1\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_redirect_uri_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://invalid\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"redirect_uri\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_redirect_uri_should_not_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://invalid\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().BeNull();\n        _mockPipeline.ErrorMessage.ResponseMode.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_client_id_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1_invalid\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_client_id_should_not_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1_invalid\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().BeNull();\n        _mockPipeline.ErrorMessage.ResponseMode.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_redirect_uri_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1_invalid\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            //redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"client\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_redirect_uri_should_not_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1_invalid\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            //redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().BeNull();\n        _mockPipeline.ErrorMessage.ResponseMode.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task malformed_redirect_uri_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1_invalid\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"invalid-uri\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"client\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task disabled_client_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _client1.Enabled = false;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task disabled_client_should_not_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _client1.Enabled = false;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().BeNull();\n        _mockPipeline.ErrorMessage.ResponseMode.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_protocol_for_client_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _client1.ProtocolType = \"invalid\";\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"protocol\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_protocol_for_client_should_not_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _client1.ProtocolType = \"invalid\";\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().BeNull();\n        _mockPipeline.ErrorMessage.ResponseMode.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_response_type_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"invalid\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.UnsupportedResponseType);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_response_type_should_not_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"invalid\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().BeNull();\n        _mockPipeline.ErrorMessage.ResponseMode.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_response_mode_for_flow_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            responseMode: \"query\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"response_mode\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_response_mode_for_flow_should_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            responseMode: \"query\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_response_mode_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            responseMode: \"invalid\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.UnsupportedResponseType);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"response_mode\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_response_mode_should_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            responseMode: \"invalid\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_scope_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            //scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"scope\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_scope_should_pass_return_url_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            //scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task explicit_response_mode_should_be_passed_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            responseMode: \"form_post\",\n            //scope: \"openid\", // this will cause the error\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"form_post\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task scope_too_long_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: new string('x', 500),\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"scope\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_openid_scope_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"profile\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"scope\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"openid\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task client_not_allowed_access_to_scope_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid email\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"scope\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_nonce_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\"\n        //nonce: \"123_nonce\"\n        );\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"nonce\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task nonce_too_long_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: new string('x', 500));\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"nonce\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task locale_too_long_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            extra: new { ui_locales = new string('x', 500) });\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"ui_locales\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task invalid_max_age_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            extra: new { max_age = \"invalid\" });\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"max_age\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task negative_max_age_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            extra: new { max_age = \"-10\" });\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"max_age\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task login_hint_too_long_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            loginHint: new string('x', 500));\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"login_hint\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task acr_values_too_long_should_show_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            acrValues: new string('x', 500));\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Contain(\"acr_values\");\n        _mockPipeline.ErrorMessage.RedirectUri.Should().StartWith(\"https://client1/callback\");\n        _mockPipeline.ErrorMessage.ResponseMode.Should().Be(\"fragment\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task overlapping_identity_scopes_and_api_scopes_should_show_error_page()\n    {\n        _mockPipeline.IdentityScopes.Add(new IdentityResource(\"foo\", \"Foo\", new string[] { \"name\" }));\n        _mockPipeline.IdentityScopes.Add(new IdentityResource(\"bar\", \"Bar\", new string[] { \"name\" }));\n        _mockPipeline.ApiScopes.Add(new ApiScope(\"foo\", \"Foo\"));\n        _mockPipeline.ApiScopes.Add(new ApiScope(\"bar\", \"Bar\"));\n\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid foo bar\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n\n        Func<Task> a = async () => await _mockPipeline.BrowserClient.GetAsync(url);\n        await a.Should().ThrowAsync<Exception>();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task ui_locales_should_be_passed_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            acrValues: new string('x', 500),\n            extra: new { ui_locales = \"fr-FR\" });\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.UiLocales.Should().Be(\"fr-FR\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task display_mode_should_be_passed_to_error_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            acrValues: new string('x', 500),\n            extra: new { display = \"popup\" });\n        await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.ErrorMessage.DisplayMode.Should().Be(\"popup\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task unicode_values_in_url_should_be_processed_correctly()\n    {\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        url = url.Replace(IdentityServerPipeline.BaseUrl, \"https://грант.рф\");\n\n        var result = await _mockPipeline.BackChannelClient.GetAsync(url);\n        result.Headers.Location.Authority.Should().Be(\"xn--80af5akm.xn--p1ai\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task code_flow_with_fragment_response_type_should_be_allowed()\n    {\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client4\",\n            responseType: \"code\",\n            responseMode: \"fragment\",\n            scope: \"openid\",\n            redirectUri: \"https://client4/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        _mockPipeline.LoginWasCalled.Should().BeTrue();\n    }\n\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task prompt_login_should_show_login_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client3\",\n            responseType: \"id_token\",\n            scope: \"openid profile\",\n            redirectUri: \"https://client3/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            extra: new { prompt = \"login\" }\n        );\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginWasCalled.Should().BeTrue();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Authorize/ConsentTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Stores.Default;\nusing IdentityServer8.Test;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Authorize;\n\npublic class ConsentTests\n{\n    private const string Category = \"Authorize and consent tests\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public ConsentTests()\n    {\n        _mockPipeline.Clients.AddRange(new Client[] {\n            new Client\n            {\n                ClientId = \"client1\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n                AllowedScopes = new List<string> { \"openid\", \"profile\" },\n                RedirectUris = new List<string> { \"https://client1/callback\" },\n                AllowAccessTokensViaBrowser = true\n            },\n            new Client\n            {\n                ClientId = \"client2\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = true,\n                AllowedScopes = new List<string> { \"openid\", \"profile\", \"api1\", \"api2\" },\n                RedirectUris = new List<string> { \"https://client2/callback\" },\n                AllowAccessTokensViaBrowser = true\n            },\n            new Client\n            {\n                ClientId = \"client3\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n                AllowedScopes = new List<string> { \"openid\", \"profile\", \"api1\", \"api2\" },\n                RedirectUris = new List<string> { \"https://client3/callback\" },\n                AllowAccessTokensViaBrowser = true,\n                IdentityProviderRestrictions = new List<string> { \"google\" }\n            }\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email()\n        });\n        _mockPipeline.ApiResources.AddRange(new ApiResource[] {\n            new ApiResource\n            {\n                Name = \"api\",\n                Scopes = { \"api1\", \"api2\" }\n            }\n        });\n\n        _mockPipeline.ApiScopes.AddRange(new ApiScope[]\n        {\n            new ApiScope\n            {\n                Name = \"api1\"\n            },\n            new ApiScope\n            {\n                Name = \"api2\"\n            }\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task client_requires_consent_should_show_consent_page()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\"\n        );\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ConsentWasCalled.Should().BeTrue();\n    }\n\n    [Theory]\n    [InlineData((Type)null)]\n    [InlineData(typeof(QueryStringAuthorizationParametersMessageStore))]\n    [InlineData(typeof(DistributedCacheAuthorizationParametersMessageStore))]\n    [Trait(\"Category\", Category)]\n    public async Task consent_page_should_have_authorization_params(Type storeType)\n    {\n        if (storeType != null)\n        {\n            _mockPipeline.OnPostConfigureServices += services =>\n            {\n                services.AddTransient(typeof(IAuthorizationParametersMessageStore), storeType);\n            };\n            _mockPipeline.Initialize();\n        }\n\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token token\",\n            scope: \"openid api1 api2\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\",\n            acrValues: \"acr_1 acr_2 tenant:tenant_value\",\n            extra: new\n            {\n                display = \"popup\", // must use a valid value form the spec for display\n                ui_locales = \"ui_locale_value\",\n                custom_foo = \"foo_value\"\n            }\n        );\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ConsentRequest.Should().NotBeNull();\n        _mockPipeline.ConsentRequest.Client.ClientId.Should().Be(\"client2\");\n        _mockPipeline.ConsentRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.ConsentRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.ConsentRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.ConsentRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n        _mockPipeline.ConsentRequest.Parameters.AllKeys.Should().Contain(\"custom_foo\");\n        _mockPipeline.ConsentRequest.Parameters[\"custom_foo\"].Should().Be(\"foo_value\");\n        _mockPipeline.ConsentRequest.ValidatedResources.RawScopeValues.Should().BeEquivalentTo(new string[] { \"api2\", \"openid\", \"api1\" });\n    }\n\n    [Theory]\n    [InlineData((Type)null)]\n    [InlineData(typeof(QueryStringAuthorizationParametersMessageStore))]\n    [InlineData(typeof(DistributedCacheAuthorizationParametersMessageStore))]\n    [Trait(\"Category\", Category)]\n    public async Task consent_response_should_allow_successful_authorization_response(Type storeType)\n    {\n        if (storeType != null)\n        {\n            _mockPipeline.OnPostConfigureServices += services =>\n            {\n                services.AddTransient(typeof(IAuthorizationParametersMessageStore), storeType);\n            };\n            _mockPipeline.Initialize();\n        }\n\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _mockPipeline.ConsentResponse = new ConsentResponse()\n        {\n            ScopesValuesConsented = new string[] { \"openid\", \"api2\" }\n        };\n        _mockPipeline.BrowserClient.StopRedirectingAfter = 2;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token token\",\n            scope: \"openid profile api1 api2\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://client2/callback\");\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IsError.Should().BeFalse();\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.State.Should().Be(\"123_state\");\n        var scopes = authorization.Scope.Split(' ');\n        scopes.Should().BeEquivalentTo(new string[] { \"api2\", \"openid\" });\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task consent_response_should_reject_modified_request_params()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _mockPipeline.ConsentResponse = new ConsentResponse()\n        {\n            ScopesValuesConsented = new string[] { \"openid\", \"api2\" }\n        };\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token token\",\n            scope: \"openid profile api2\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://server/consent\");\n\n        response = await _mockPipeline.BrowserClient.GetAsync(response.Headers.Location.ToString());\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"/connect/authorize/callback\");\n\n        var modifiedAuthorizeCallback = \"https://server\" + response.Headers.Location.ToString();\n        modifiedAuthorizeCallback = modifiedAuthorizeCallback.Replace(\"api2\", \"api1%20api2\");\n\n        response = await _mockPipeline.BrowserClient.GetAsync(modifiedAuthorizeCallback);\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://server/consent\");\n    }\n\n    [Fact()]\n    [Trait(\"Category\", Category)]\n    public async Task consent_response_missing_required_scopes_should_error()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _mockPipeline.ConsentResponse = new ConsentResponse()\n        {\n            ScopesValuesConsented = new string[] { \"api2\" }\n        };\n        _mockPipeline.BrowserClient.StopRedirectingAfter = 2;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token token\",\n            scope: \"openid profile api1 api2\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://client2/callback\");\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IsError.Should().BeTrue();\n        authorization.Error.Should().Be(\"access_denied\");\n        authorization.State.Should().Be(\"123_state\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Authorize/JwtRequestAuthorizeTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Security.Claims;\nusing System.Security.Cryptography.X509Certificates;\nusing System.Text.Json;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Microsoft.IdentityModel.Logging;\nusing Microsoft.IdentityModel.Tokens;\nusing Xunit;\nusing JsonWebKey = Microsoft.IdentityModel.Tokens.JsonWebKey;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Authorize;\n\npublic class JwtRequestAuthorizeTests\n{\n    private const string Category = \"Authorize endpoint with JWT requests\";\n\n    private readonly IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n    private readonly Client _client;\n\n    private readonly string _symmetricJwk = @\"{ \"\"kty\"\": \"\"oct\"\", \"\"use\"\": \"\"sig\"\", \"\"kid\"\": \"\"1\"\", \"\"k\"\": \"\"nYA-IFt8xTsdBHe9hunvizcp3Dt7f6qGqudq18kZHNtvqEGjJ9Ud-9x3kbQ-LYfLHS3xM2MpFQFg1JzT_0U_F8DI40oby4TvBDGszP664UgA8_5GjB7Flnrlsap1NlitvNpgQX3lpyTvC2zVuQ-UVsXbBDAaSBUSlnw7SE4LM8Ye2WYZrdCCXL8yAX9vIR7vf77yvNTEcBCI6y4JlvZaqMB4YKVSfygs8XqGGCHjLpE5bvI-A4ESbAUX26cVFvCeDg9pR6HK7BmwPMlO96krgtKZcXEJtUELYPys6-rbwAIdmxJxKxpgRpt0FRv_9fm6YPwG7QivYBX-vRwaodL1TA\"\", \"\"alg\"\": \"\"HS256\"\"}\";\n    private readonly RsaSecurityKey _rsaKey;\n\n    public JwtRequestAuthorizeTests()\n    {\n        IdentityModelEventSource.ShowPII = true;\n\n        _rsaKey = CryptoHelper.CreateRsaSecurityKey();\n\n        _mockPipeline.Clients.AddRange(new Client[]\n        {\n            _client = new Client\n            {\n                ClientName = \"Client with keys\",\n                ClientId = \"client\",\n                Enabled = true,\n                RequireRequestObject = true,\n\n                RedirectUris = { \"https://client/callback\" },\n\n                ClientSecrets =\n                {\n                    new Secret\n                    {\n                        // x509 cert as base64 string\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                        Value = Convert.ToBase64String(TestCert.Load().Export(X509ContentType.Cert))\n                    },\n                    new Secret\n                    {\n                        // symmetric key as JWK\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value = _symmetricJwk\n                    },\n                    new Secret\n                    {\n                        // RSA key as JWK\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value = JsonSerializer.Serialize(JsonWebKeyConverter.ConvertFromRSASecurityKey(_rsaKey))\n                    },\n                    new Secret\n                    {\n                        // x509 cert as JWK\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value = JsonSerializer.Serialize(JsonWebKeyConverter.ConvertFromX509SecurityKey(new X509SecurityKey(TestCert.Load())))\n                    }\n                },\n\n                AllowedGrantTypes = GrantTypes.Implicit,\n\n                AllowedScopes = new List<string>\n                {\n                    \"openid\", \"profile\", \"api1\", \"api2\"\n                }\n            },\n            _client = new Client\n            {\n                ClientName = \"Client with keys\",\n                ClientId = \"client2\",\n                Enabled = true,\n                RequireRequestObject = true,\n\n                RedirectUris = { \"https://client/callback\" },\n\n                ClientSecrets =\n                {\n                    new Secret\n                    {\n                        // x509 cert as base64 string\n                        Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                        Value = Convert.ToBase64String(TestCert.Load().Export(X509ContentType.Cert))\n                    },\n                    new Secret\n                    {\n                        // symmetric key as JWK\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value = _symmetricJwk\n                    },\n                    new Secret\n                    {\n                        // RSA key as JWK\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value = JsonSerializer.Serialize(JsonWebKeyConverter.ConvertFromRSASecurityKey(_rsaKey))\n                    },\n                    new Secret\n                    {\n                        // x509 cert as JWK\n                        Type = IdentityServerConstants.SecretTypes.JsonWebKey,\n                        Value = JsonSerializer.Serialize(JsonWebKeyConverter.ConvertFromX509SecurityKey(new X509SecurityKey(TestCert.Load())))\n                    }\n                },\n\n                AllowedGrantTypes = GrantTypes.Implicit,\n\n                AllowedScopes = new List<string>\n                {\n                    \"openid\", \"profile\", \"api1\", \"api2\"\n                }\n            },\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email()\n        });\n        _mockPipeline.ApiResources.AddRange(new ApiResource[] {\n            new ApiResource\n            {\n                Name = \"api\",\n                Scopes = { \"api1\", \"api2\" }\n            }\n        });\n        _mockPipeline.ApiScopes.AddRange(new ApiScope[] {\n            new ApiScope\n            {\n                Name = \"api1\"\n            },\n            new ApiScope\n            {\n                Name = \"api2\"\n            }\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    string CreateRequestJwt(string issuer, string audience, SigningCredentials credential, Claim[] claims, bool setJwtTyp = false)\n    {\n        var handler = new JwtSecurityTokenHandler();\n        handler.OutboundClaimTypeMap.Clear();\n\n        var token = handler.CreateJwtSecurityToken(\n            issuer: issuer,\n            audience: audience,\n            signingCredentials: credential,\n            subject: Identity.Create(\"pwd\", claims));\n\n        if (setJwtTyp)\n        {\n            token.Header[\"typ\"] = JwtClaimTypes.JwtTypes.AuthorizationRequest;\n        }\n\n        return handler.WriteToken(token);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_request_object_should_fail()\n    {\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            scope: \"openid profile\",\n            state: \"123state\",\n            nonce: \"123nonce\",\n            redirectUri: \"https://client/callback\");\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Client must use request object, but no request or request_uri parameter present\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_accept_valid_JWT_request_object_parameters_using_X509_certificate()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n        _mockPipeline.LoginRequest.Client.ClientId.Should().Be(_client.ClientId);\n        _mockPipeline.LoginRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.LoginRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"idp_value\");\n        _mockPipeline.LoginRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.LoginRequest.LoginHint.Should().Be(\"login_hint_value\");\n        _mockPipeline.LoginRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n\n        _mockPipeline.LoginRequest.Parameters.AllKeys.Should().Contain(\"foo\");\n        _mockPipeline.LoginRequest.Parameters[\"foo\"].Should().Be(\"123foo\");\n\n        _mockPipeline.LoginRequest.RequestObjectValues.Count.Should().Be(11);\n        _mockPipeline.LoginRequest.RequestObjectValues.Should().ContainKey(\"foo\");\n        _mockPipeline.LoginRequest.RequestObjectValues[\"foo\"].Should().Be(\"123foo\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_accept_valid_JWT_request_object_parameters_using_symmetric_jwk()\n    {\n        var jwk = new Microsoft.IdentityModel.Tokens.JsonWebKey(_symmetricJwk);\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new SigningCredentials(jwk, \"HS256\"),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n        _mockPipeline.LoginRequest.Client.ClientId.Should().Be(_client.ClientId);\n        _mockPipeline.LoginRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.LoginRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"idp_value\");\n        _mockPipeline.LoginRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.LoginRequest.LoginHint.Should().Be(\"login_hint_value\");\n        _mockPipeline.LoginRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n\n        _mockPipeline.LoginRequest.Parameters.AllKeys.Should().Contain(\"foo\");\n        _mockPipeline.LoginRequest.Parameters[\"foo\"].Should().Be(\"123foo\");\n\n        _mockPipeline.LoginRequest.RequestObjectValues.Count.Should().Be(11);\n        _mockPipeline.LoginRequest.RequestObjectValues.Should().ContainKey(\"foo\");\n        _mockPipeline.LoginRequest.RequestObjectValues[\"foo\"].Should().Be(\"123foo\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_accept_valid_JWT_request_object_parameters_using_rsa_jwk()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new SigningCredentials(_rsaKey, \"RS256\"),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n        _mockPipeline.LoginRequest.Client.ClientId.Should().Be(_client.ClientId);\n        _mockPipeline.LoginRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.LoginRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"idp_value\");\n        _mockPipeline.LoginRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.LoginRequest.LoginHint.Should().Be(\"login_hint_value\");\n        _mockPipeline.LoginRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n\n        _mockPipeline.LoginRequest.Parameters.AllKeys.Should().Contain(\"foo\");\n        _mockPipeline.LoginRequest.Parameters[\"foo\"].Should().Be(\"123foo\");\n\n        _mockPipeline.LoginRequest.RequestObjectValues.Count.Should().Be(11);\n        _mockPipeline.LoginRequest.RequestObjectValues.Should().ContainKey(\"foo\");\n        _mockPipeline.LoginRequest.RequestObjectValues[\"foo\"].Should().Be(\"123foo\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task correct_jwt_typ_should_pass_strict_validation()\n    {\n        _mockPipeline.Options.StrictJarValidation = true;\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new SigningCredentials(_rsaKey, \"RS256\"),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        }, setJwtTyp: true);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n        _mockPipeline.LoginRequest.Client.ClientId.Should().Be(_client.ClientId);\n        _mockPipeline.LoginRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.LoginRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"idp_value\");\n        _mockPipeline.LoginRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.LoginRequest.LoginHint.Should().Be(\"login_hint_value\");\n        _mockPipeline.LoginRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n\n        _mockPipeline.LoginRequest.Parameters.AllKeys.Should().Contain(\"foo\");\n        _mockPipeline.LoginRequest.Parameters[\"foo\"].Should().Be(\"123foo\");\n\n        _mockPipeline.LoginRequest.RequestObjectValues.Count.Should().Be(11);\n        _mockPipeline.LoginRequest.RequestObjectValues.Should().ContainKey(\"foo\");\n        _mockPipeline.LoginRequest.RequestObjectValues[\"foo\"].Should().Be(\"123foo\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task missing_jwt_typ_should_error()\n    {\n        _mockPipeline.Options.StrictJarValidation = true;\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new SigningCredentials(_rsaKey, \"RS256\"),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request_object\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task mismatch_in_jwt_values_should_error()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new SigningCredentials(_rsaKey, \"RS256\"),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            scope: \"bad\",\n            state: \"bad\",\n            nonce: \"bad\",\n            redirectUri: \"bad\",\n            acrValues: \"bad\",\n            loginHint: \"bad\",\n            extra: new\n            {\n                display = \"bad\",\n                ui_locales = \"bad\",\n                foo = \"bad\",\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Parameter mismatch in JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_accept_complex_objects_in_request_object()\n    {\n        var someObj = new { foo = new { bar = \"bar\" }, baz = \"baz\" };\n        var someObjJson = JsonSerializer.Serialize(someObj);\n        var someArr = new[] { \"a\", \"b\", \"c\" };\n        var someArrJson = JsonSerializer.Serialize(someArr);\n\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n                new Claim(\"someObj\", someObjJson),\n                new Claim(\"someArr\", someArrJson),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n\n        _mockPipeline.LoginRequest.Parameters[\"someObj\"].Should().NotBeNull();\n        var someObj2 = JsonSerializer.Deserialize(_mockPipeline.LoginRequest.Parameters[\"someObj\"], someObj.GetType());\n        someObj.Should().BeEquivalentTo(someObj2);\n        _mockPipeline.LoginRequest.Parameters[\"someArr\"].Should().NotBeNull();\n        var someArr2 =JsonSerializer.Deserialize<string[]>(_mockPipeline.LoginRequest.Parameters[\"someArr\"]);\n        someArr2.Should().Contain(new[] { \"a\", \"c\", \"b\" });\n        someArr2.Length.Should().Be(3);\n\n        _mockPipeline.LoginRequest.RequestObjectValues.Count.Should().Be(13);\n        _mockPipeline.LoginRequest.RequestObjectValues[\"someObj\"].Should().NotBeNull();\n        someObj2 =JsonSerializer.Deserialize(_mockPipeline.LoginRequest.RequestObjectValues[\"someObj\"], someObj.GetType());\n        someObj.Should().BeEquivalentTo(someObj2);\n        _mockPipeline.LoginRequest.RequestObjectValues[\"someArr\"].Should().NotBeNull();\n        someArr2 =JsonSerializer.Deserialize<string[]>(_mockPipeline.LoginRequest.Parameters[\"someArr\"]);\n        someArr2.Should().Contain(new[] { \"a\", \"c\", \"b\" });\n        someArr2.Length.Should().Be(3);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_without_client_id()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid client_id\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_without_client_id_in_jwt()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n            });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request_object\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_if_audience_is_incorrect()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: \"invalid\",\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request_object\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_if_issuer_does_not_match_client_id()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: \"invalid\",\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request_object\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_that_includes_request_param()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n                new Claim(\"request\", \"request\")\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request_object\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_that_includes_request_uri_param()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n                new Claim(\"request_uri\", \"request_uri\")\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request_object\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_if_response_type_does_not_match()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"response_type\", \"id_token token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\")\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_jwt_request_if_client_id_does_not_match()\n    {\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"client_id\", \"client\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\")\n        });\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt\n            });\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request\");\n        _mockPipeline.ErrorMessage.ErrorDescription.Should().Be(\"Invalid JWT request\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_ignore_request_uri_when_feature_is_disabled()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = false;\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n        _mockPipeline.JwtRequestMessageHandler.OnInvoke = req =>\n        {\n            req.RequestUri.Should().Be(new Uri(\"http://client_jwt\"));\n            return Task.CompletedTask;\n        };\n        _mockPipeline.JwtRequestMessageHandler.Response.Content = new StringContent(requestJwt);\n\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request_uri = \"http://client_jwt\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_accept_request_uri_with_valid_jwt()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = true;\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n        _mockPipeline.JwtRequestMessageHandler.OnInvoke = req =>\n        {\n            req.RequestUri.Should().Be(new Uri(\"http://client_jwt\"));\n            return Task.CompletedTask;\n        };\n        _mockPipeline.JwtRequestMessageHandler.Response.Content = new StringContent(requestJwt);\n\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request_uri = \"http://client_jwt\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n        _mockPipeline.LoginRequest.Client.ClientId.Should().Be(_client.ClientId);\n        _mockPipeline.LoginRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.LoginRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"idp_value\");\n        _mockPipeline.LoginRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.LoginRequest.LoginHint.Should().Be(\"login_hint_value\");\n        _mockPipeline.LoginRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n        _mockPipeline.LoginRequest.Parameters.AllKeys.Should().Contain(\"foo\");\n        _mockPipeline.LoginRequest.Parameters[\"foo\"].Should().Be(\"123foo\");\n\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_accept_request_uri_with_valid_jwt_and_strict_validation()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = true;\n        _mockPipeline.Options.StrictJarValidation = true;\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        }, setJwtTyp: true);\n        _mockPipeline.JwtRequestMessageHandler.OnInvoke = req =>\n        {\n            req.RequestUri.Should().Be(new Uri(\"http://client_jwt\"));\n            return Task.CompletedTask;\n        };\n        _mockPipeline.JwtRequestMessageHandler.Response.Content = new StringContent(requestJwt);\n        _mockPipeline.JwtRequestMessageHandler.Response.Content.Headers.ContentType = new MediaTypeHeaderValue($\"application/{JwtClaimTypes.JwtTypes.AuthorizationRequest}\");\n\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request_uri = \"http://client_jwt\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginRequest.Should().NotBeNull();\n        _mockPipeline.LoginRequest.Client.ClientId.Should().Be(_client.ClientId);\n        _mockPipeline.LoginRequest.DisplayMode.Should().Be(\"popup\");\n        _mockPipeline.LoginRequest.UiLocales.Should().Be(\"ui_locale_value\");\n        _mockPipeline.LoginRequest.IdP.Should().Be(\"idp_value\");\n        _mockPipeline.LoginRequest.Tenant.Should().Be(\"tenant_value\");\n        _mockPipeline.LoginRequest.LoginHint.Should().Be(\"login_hint_value\");\n        _mockPipeline.LoginRequest.AcrValues.Should().BeEquivalentTo(new string[] { \"acr_2\", \"acr_1\" });\n        _mockPipeline.LoginRequest.Parameters.AllKeys.Should().Contain(\"foo\");\n        _mockPipeline.LoginRequest.Parameters[\"foo\"].Should().Be(\"123foo\");\n\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task authorize_should_reject_request_uri_with_valid_jwt_and_strict_validation_but_invalid_content_type()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = true;\n        _mockPipeline.Options.StrictJarValidation = true;\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        }, setJwtTyp: true);\n        _mockPipeline.JwtRequestMessageHandler.OnInvoke = req =>\n        {\n            req.RequestUri.Should().Be(new Uri(\"http://client_jwt\"));\n            return Task.CompletedTask;\n        };\n        _mockPipeline.JwtRequestMessageHandler.Response.Content = new StringContent(requestJwt);\n\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request_uri = \"http://client_jwt\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorMessage.Error.Should().Be(\"invalid_request_uri\");\n        _mockPipeline.LoginRequest.Should().BeNull();\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task request_uri_response_returns_500_should_fail()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = true;\n\n        _mockPipeline.JwtRequestMessageHandler.Response = new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request_uri = \"http://client_jwt\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.LoginRequest.Should().BeNull();\n\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task request_uri_response_returns_404_should_fail()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = true;\n\n        _mockPipeline.JwtRequestMessageHandler.Response = new HttpResponseMessage(System.Net.HttpStatusCode.NotFound);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request_uri = \"http://client_jwt\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.LoginRequest.Should().BeNull();\n\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task request_uri_length_too_long_should_fail()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = true;\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request_uri = \"http://\" + new string('x', 512)\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.LoginRequest.Should().BeNull();\n\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task both_request_and_request_uri_params_should_fail()\n    {\n        _mockPipeline.Options.Endpoints.EnableJwtRequestUri = true;\n\n        var requestJwt = CreateRequestJwt(\n            issuer: _client.ClientId,\n            audience: IdentityServerPipeline.BaseUrl,\n            credential: new X509SigningCredentials(TestCert.Load()),\n            claims: new[] {\n                new Claim(\"client_id\", _client.ClientId),\n                new Claim(\"response_type\", \"id_token\"),\n                new Claim(\"scope\", \"openid profile\"),\n                new Claim(\"state\", \"123state\"),\n                new Claim(\"nonce\", \"123nonce\"),\n                new Claim(\"redirect_uri\", \"https://client/callback\"),\n                new Claim(\"acr_values\", \"acr_1 acr_2 tenant:tenant_value idp:idp_value\"),\n                new Claim(\"login_hint\", \"login_hint_value\"),\n                new Claim(\"display\", \"popup\"),\n                new Claim(\"ui_locales\", \"ui_locale_value\"),\n                new Claim(\"foo\", \"123foo\"),\n        });\n        _mockPipeline.JwtRequestMessageHandler.Response.Content = new StringContent(requestJwt);\n\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: _client.ClientId,\n            responseType: \"id_token\",\n            extra: new\n            {\n                request = requestJwt,\n                request_uri = \"http://client_jwt\"\n            });\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n        _mockPipeline.LoginRequest.Should().BeNull();\n\n        _mockPipeline.JwtRequestMessageHandler.InvokeWasCalled.Should().BeFalse();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Authorize/RestrictAccessTokenViaBrowserTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Authorize;\n\npublic class RestrictAccessTokenViaBrowserTests\n{\n    private const string Category = \"RestrictAccessTokenViaBrowserTests\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    private ClaimsPrincipal _user = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n    public RestrictAccessTokenViaBrowserTests()\n    {\n        _mockPipeline.Clients.AddRange(new Client[] {\n            new Client\n            {\n                ClientId = \"client1\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n                AllowedScopes = new List<string> { \"openid\" },\n                RedirectUris = new List<string> { \"https://client1/callback\" },\n                AllowAccessTokensViaBrowser = true\n            },\n            new Client\n            {\n                ClientId = \"client2\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n                AllowedScopes = new List<string> { \"openid\" },\n                RedirectUris = new List<string> { \"https://client2/callback\" },\n                AllowAccessTokensViaBrowser = false\n            },\n            new Client\n            {\n                ClientId = \"client3\",\n                AllowedGrantTypes = GrantTypes.Hybrid,\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n                RequireConsent = false,\n                RequirePkce = false,\n                AllowedScopes = new List<string> { \"openid\" },\n                RedirectUris = new List<string> { \"https://client3/callback\" },\n                AllowAccessTokensViaBrowser = true\n            },\n            new Client\n            {\n                ClientId = \"client4\",\n                AllowedGrantTypes = GrantTypes.Hybrid,\n                ClientSecrets = { new Secret(\"secret\".Sha256()) },\n                RequireConsent = false,\n                RequirePkce = false,\n                AllowedScopes = new List<string> { \"openid\" },\n                RedirectUris = new List<string> { \"https://client4/callback\" },\n                AllowAccessTokensViaBrowser = false\n            }\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId()\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Unrestricted_implicit_client_can_request_IdToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client1\",\n            \"id_token\", \"openid\", \"https://client1/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Found);\n        response.Headers.Location.AbsoluteUri.Should().StartWith(\"https://client1/callback\");\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.AccessToken.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Unrestricted_implicit_client_can_request_IdTokenToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client1\",\n            \"id_token token\", \"openid\", \"https://client1/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Found);\n        response.Headers.Location.AbsoluteUri.Should().StartWith(\"https://client1/callback\");\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.AccessToken.Should().NotBeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Restricted_implicit_client_can_request_IdToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client2\",\n            \"id_token\", \"openid\", \"https://client2/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Found);\n        response.Headers.Location.AbsoluteUri.Should().StartWith(\"https://client2/callback\");\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.AccessToken.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Restricted_implicit_client_cannot_request_IdTokenToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client2\",\n            \"id_token token\", \"openid\", \"https://client2/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Unrestricted_hybrid_client_can_request_CodeIdToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client3\",\n            \"code id_token\", \"openid\", \"https://client3/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Found);\n        response.Headers.Location.AbsoluteUri.Should().StartWith(\"https://client3/callback\");\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.AccessToken.Should().BeNull();\n        authorization.Code.Should().NotBeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Unrestricted_hybrid_client_can_request_CodeIdTokenToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client3\",\n            \"code id_token token\", \"openid\", \"https://client3/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Found);\n        response.Headers.Location.AbsoluteUri.Should().StartWith(\"https://client3/callback\");\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.AccessToken.Should().NotBeNull();\n        authorization.Code.Should().NotBeNull();\n    }\n\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Restricted_hybrid_client_can_request_CodeIdToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client4\",\n            \"code id_token\", \"openid\", \"https://client4/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Found);\n        response.Headers.Location.AbsoluteUri.Should().StartWith(\"https://client4/callback\");\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IdentityToken.Should().NotBeNull();\n        authorization.AccessToken.Should().BeNull();\n        authorization.Code.Should().NotBeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Restricted_hybrid_client_cannot_request_CodeIdTokenToken()\n    {\n        await _mockPipeline.LoginAsync(_user);\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\"client4\",\n            \"code id_token token\", \"openid\", \"https://client4/callback\", \"state\", \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        _mockPipeline.ErrorWasCalled.Should().BeTrue();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Authorize/SessionIdTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Authorize;\n\npublic class SessionIdTests\n{\n    private const string Category = \"SessionIdTests\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public SessionIdTests()\n    {\n        _mockPipeline.Clients.AddRange(new Client[] {\n            new Client\n            {\n                ClientId = \"client1\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n                AllowedScopes = new List<string> { \"openid\", \"profile\" },\n                RedirectUris = new List<string> { \"https://client1/callback\" },\n                AllowAccessTokensViaBrowser = true\n            },\n            new Client\n            {\n                ClientId = \"client2\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = true,\n                AllowedScopes = new List<string> { \"openid\", \"profile\", \"api1\", \"api2\" },\n                RedirectUris = new List<string> { \"https://client2/callback\" },\n                AllowAccessTokensViaBrowser = true\n            }\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email()\n        });\n        _mockPipeline.ApiResources.AddRange(new ApiResource[] {\n            new ApiResource\n            {\n                Name = \"api\",\n            }\n        });\n        _mockPipeline.ApiScopes.AddRange(new ApiScope[] {\n            new ApiScope\n            {\n                Name = \"api1\"\n            },\n            new ApiScope\n            {\n                Name = \"api2\"\n            }\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    public async Task session_id_should_be_reissued_if_session_cookie_absent()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n        var sid1 = _mockPipeline.GetSessionCookie().Value;\n        sid1.Should().NotBeNull();\n\n        _mockPipeline.RemoveSessionCookie();\n\n        await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.DiscoveryEndpoint);\n\n        var sid2 = _mockPipeline.GetSessionCookie().Value;\n        sid2.Should().Be(sid1);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/CheckSession/CheckSessionTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Net;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.IntegrationTests.Common;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.CheckSession;\n\npublic class CheckSessionTests\n{\n    private const string Category = \"Check session endpoint\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public CheckSessionTests()\n    {\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task get_request_should_not_return_404()\n    {\n        var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.CheckSessionEndpoint);\n\n        response.StatusCode.Should().NotBe(HttpStatusCode.NotFound);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/DeviceAuthorization/DeviceAuthorizationTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Net;\nusing System.Net.Http;\nusing System.Text;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing Newtonsoft.Json;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.DeviceAuthorization;\n\npublic class DeviceAuthorizationTests\n{\n    private const string Category = \"Device authorization endpoint\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public DeviceAuthorizationTests()\n    {\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = \"client1\",\n            ClientSecrets = {new Secret(\"secret\".Sha256())},\n            AllowedGrantTypes = GrantTypes.DeviceFlow,\n            AllowedScopes = {\"openid\"}\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId()\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task get_should_return_InvalidRequest()\n    {\n        var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.DeviceAuthorization);\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n\n        var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());\n\n        resultDto.Should().NotBeNull();\n        resultDto.error.Should().Be(OidcConstants.TokenErrors.InvalidRequest);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task wrong_content_type_return_InvalidRequest()\n    {\n        var form = new Dictionary<string, string>\n        {\n            {\"client_id\", Guid.NewGuid().ToString()}\n        };\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization,\n            new StringContent(@\"{\"\"client_id\"\": \"\"client1\"\"}\", Encoding.UTF8, \"application/json\"));\n\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n\n        var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());\n\n        resultDto.Should().NotBeNull();\n        resultDto.error.Should().Be(OidcConstants.TokenErrors.InvalidRequest);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task empty_request_should_return_InvalidClient()\n    {\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization,\n            new FormUrlEncodedContent(new Dictionary<string, string>()));\n\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n\n        var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());\n\n        resultDto.Should().NotBeNull();\n        resultDto.error.Should().Be(OidcConstants.TokenErrors.InvalidClient);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task unknown_client_should_return_InvalidClient()\n    {\n        var form = new Dictionary<string, string>\n        {\n            {\"client_id\", \"client1\"}\n        };\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization, new FormUrlEncodedContent(form));\n\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n\n        var resultDto = ParseJsonBody<ErrorResultDto>(await response.Content.ReadAsStreamAsync());\n\n        resultDto.Should().NotBeNull();\n        resultDto.error.Should().Be(OidcConstants.TokenErrors.InvalidClient);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task valid_should_return_json()\n    {\n        var form = new Dictionary<string, string>\n        {\n            {\"client_id\", \"client1\"},\n            {\"client_secret\", \"secret\" }\n        };\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.DeviceAuthorization, new FormUrlEncodedContent(form));\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        response.Content.Headers.ContentType.MediaType.Should().Be(\"application/json\");\n        \n        var resultDto = ParseJsonBody<ResultDto>(await response.Content.ReadAsStreamAsync());\n\n        resultDto.Should().NotBeNull();\n\n        resultDto.Should().NotBeNull();\n        resultDto.device_code.Should().NotBeNull();\n        resultDto.user_code.Should().NotBeNull();\n        resultDto.verification_uri.Should().NotBeNull();\n        resultDto.verification_uri_complete.Should().NotBeNull();\n        resultDto.expires_in.Should().BeGreaterThan(0);\n        resultDto.interval.Should().BeGreaterThan(0);\n    }\n\n    private T ParseJsonBody<T>(Stream streamBody)\n    {\n        streamBody.Position = 0;\n        using (var reader = new StreamReader(streamBody))\n        {\n            var jsonString = reader.ReadToEnd();\n            return JsonConvert.DeserializeObject<T>(jsonString);\n        }\n    }\n\n    internal class ResultDto\n    {\n        public string device_code { get; set; }\n        public string user_code { get; set; }\n        public string verification_uri { get; set; }\n        public string verification_uri_complete { get; set; }\n        public int expires_in { get; set; }\n        public int interval { get; set; }\n    }\n\n    internal class ErrorResultDto\n    {\n        public string error { get; set; }\n        public string error_description { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Discovery/DiscoveryEndpointTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.IdentityModel.Tokens;\nusing Newtonsoft.Json.Linq;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Xunit;\nusing JsonWebKey = Microsoft.IdentityModel.Tokens.JsonWebKey;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Discovery;\n\npublic class DiscoveryEndpointTests\n{\n    private const string Category = \"Discovery endpoint\";\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Issuer_uri_should_be_lowercase()\n    {\n        IdentityServerPipeline pipeline = new IdentityServerPipeline();\n        pipeline.Initialize(\"/ROOT\");\n\n        var result = await pipeline.BackChannelClient.GetAsync(\"HTTPS://SERVER/ROOT/.WELL-KNOWN/OPENID-CONFIGURATION\");\n\n        var json = await result.Content.ReadAsStringAsync();\n        var data = JObject.Parse(json);\n        var issuer = data[\"issuer\"].ToString();\n\n        issuer.Should().Be(\"https://server/root\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task when_lower_case_issuer_option_disabled_issuer_uri_should_be_preserved()\n    {\n        IdentityServerPipeline pipeline = new IdentityServerPipeline();\n        pipeline.Initialize(\"/ROOT\");\n\n        pipeline.Options.LowerCaseIssuerUri = false;\n\n        var result = await pipeline.BackChannelClient.GetAsync(\"HTTPS://SERVER/ROOT/.WELL-KNOWN/OPENID-CONFIGURATION\");\n\n        var json = await result.Content.ReadAsStringAsync();\n        var data = JObject.Parse(json);\n        var issuer = data[\"issuer\"].ToString();\n\n        issuer.Should().Be(\"https://server/ROOT\");\n    }\n\n    private void Pipeline_OnPostConfigureServices(IServiceCollection obj)\n    {\n        throw new System.NotImplementedException();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Algorithms_supported_should_match_signing_key()\n    {\n        var key = CryptoHelper.CreateECDsaSecurityKey(JsonWebKeyECTypes.P256);\n        var expectedAlgorithm = SecurityAlgorithms.EcdsaSha256;\n\n        IdentityServerPipeline pipeline = new IdentityServerPipeline();\n        pipeline.OnPostConfigureServices += services =>\n        {\n            // add key to standard RSA key\n            services.AddIdentityServerBuilder()\n                .AddSigningCredential(key, expectedAlgorithm);\n        };\n        pipeline.Initialize(\"/ROOT\");\n\n        var result = await pipeline.BackChannelClient.GetAsync(\"https://server/root/.well-known/openid-configuration\");\n\n        var json = await result.Content.ReadAsStringAsync();\n        var data = JObject.Parse(json);\n        var algorithmsSupported = data[\"id_token_signing_alg_values_supported\"];\n\n        algorithmsSupported.Count().Should().Be(2);\n\n        algorithmsSupported.Values().Should().Contain(SecurityAlgorithms.RsaSha256);\n        algorithmsSupported.Values().Should().Contain(SecurityAlgorithms.EcdsaSha256);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Jwks_entries_should_countain_crv()\n    {\n        var ecdsaKey = CryptoHelper.CreateECDsaSecurityKey(JsonWebKeyECTypes.P256);\n        var parameters = ecdsaKey.ECDsa.ExportParameters(true);\n\n        IdentityServerPipeline pipeline = new IdentityServerPipeline();\n\n        var jsonWebKeyFromECDsa = new JsonWebKey()\n        {\n            Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,\n            Use = \"sig\",\n            Kid = ecdsaKey.KeyId,\n            KeyId = ecdsaKey.KeyId,\n            X = Base64UrlEncoder.Encode(parameters.Q.X),\n            Y = Base64UrlEncoder.Encode(parameters.Q.Y),\n            D = Base64UrlEncoder.Encode(parameters.D),\n            Crv = JsonWebKeyECTypes.P256,\n            Alg = SecurityAlgorithms.EcdsaSha256\n        };\n        pipeline.OnPostConfigureServices += services =>\n        {\n            // add ECDsa as JsonWebKey\n            services.AddIdentityServerBuilder()\n                .AddSigningCredential(jsonWebKeyFromECDsa, SecurityAlgorithms.EcdsaSha256);\n        };\n\n        pipeline.Initialize(\"/ROOT\");\n\n        var result = await pipeline.BackChannelClient.GetAsync(\"https://server/root/.well-known/openid-configuration/jwks\");\n\n        var json = await result.Content.ReadAsStringAsync();\n        var data = JObject.Parse(json);\n\n        var keys = data[\"keys\"];\n        keys.Should().NotBeNull();\n\n        var key = keys[1];\n        key.Should().NotBeNull();\n\n        var crv = key[\"crv\"];\n        crv.Should().NotBeNull();\n\n        crv.Value<string>().Should().Be(JsonWebKeyECTypes.P256);\n\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Jwks_entries_should_contain_alg()\n    {\n        IdentityServerPipeline pipeline = new IdentityServerPipeline();\n        pipeline.Initialize(\"/ROOT\");\n\n        var result = await pipeline.BackChannelClient.GetAsync(\"https://server/root/.well-known/openid-configuration/jwks\");\n\n        var json = await result.Content.ReadAsStringAsync();\n        var data = JObject.Parse(json);\n\n        var keys = data[\"keys\"];\n        keys.Should().NotBeNull();\n\n        var key = keys[0];\n        key.Should().NotBeNull();\n\n        var alg = key[\"alg\"];\n        alg.Should().NotBeNull();\n\n        alg.Value<string>().Should().Be(Constants.SigningAlgorithms.RSA_SHA_256);\n    }\n\n    [Theory]\n    [InlineData(JsonWebKeyECTypes.P256, SecurityAlgorithms.EcdsaSha256)]\n    [InlineData(JsonWebKeyECTypes.P384, SecurityAlgorithms.EcdsaSha384)]\n    [InlineData(JsonWebKeyECTypes.P521, SecurityAlgorithms.EcdsaSha512)]\n    [Trait(\"Category\", Category)]\n    public async Task Jwks_with_ecdsa_should_have_parsable_key(string crv, string alg)\n    {\n        var key = CryptoHelper.CreateECDsaSecurityKey(crv);\n\n        IdentityServerPipeline pipeline = new IdentityServerPipeline();\n        pipeline.OnPostConfigureServices += services =>\n        {\n            services.AddIdentityServerBuilder()\n                .AddSigningCredential(key, alg);\n        };\n        pipeline.Initialize(\"/ROOT\");\n\n        var result = await pipeline.BackChannelClient.GetAsync(\"https://server/root/.well-known/openid-configuration/jwks\");\n\n        var json = await result.Content.ReadAsStringAsync();\n        var jwks = new JsonWebKeySet(json);\n        var parsedKeys = jwks.GetSigningKeys();\n\n        var matchingKey = parsedKeys.FirstOrDefault(x => x.KeyId == key.KeyId);\n        matchingKey.Should().NotBeNull();\n        matchingKey.Should().BeOfType<ECDsaSecurityKey>();\n    }\n\n    [Fact]\n    public async Task Jwks_with_two_key_using_different_algs_expect_different_alg_values()\n    {\n        var ecdsaKey = CryptoHelper.CreateECDsaSecurityKey();\n        var rsaKey = CryptoHelper.CreateRsaSecurityKey();\n\n        IdentityServerPipeline pipeline = new IdentityServerPipeline();\n        pipeline.OnPostConfigureServices += services =>\n        {\n            services.AddIdentityServerBuilder()\n                .AddSigningCredential(ecdsaKey, \"ES256\")\n                .AddValidationKey(new SecurityKeyInfo { Key = rsaKey, SigningAlgorithm = \"RS256\" });\n        };\n        pipeline.Initialize(\"/ROOT\");\n\n        var result = await pipeline.BackChannelClient.GetAsync(\"https://server/root/.well-known/openid-configuration/jwks\");\n\n        var json = await result.Content.ReadAsStringAsync();\n        var jwks = new JsonWebKeySet(json);\n\n        jwks.Keys.Should().Contain(x => x.KeyId == ecdsaKey.KeyId && x.Alg == \"ES256\");\n        jwks.Keys.Should().Contain(x => x.KeyId == rsaKey.KeyId && x.Alg == \"RS256\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Unicode_values_in_url_should_be_processed_correctly()\n    {\n        var pipeline = new IdentityServerPipeline();\n        pipeline.Initialize();\n\n        var result = await pipeline.BackChannelClient.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest\n        {\n            Address = \"https://грант.рф\",\n            Policy =\n            {\n                ValidateIssuerName = false,\n                ValidateEndpoints = false,\n                RequireHttps = false,\n                RequireKeySet = false\n            }\n        });\n\n        result.Issuer.Should().Be(\"https://грант.рф\");\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/EndSession/EndSessionTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Text.Encodings.Web;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Microsoft.AspNetCore.WebUtilities;\nusing Newtonsoft.Json.Linq;\nusing Xunit;\nusing static IdentityServer8.IdentityServerConstants;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.EndSession;\n\npublic class EndSessionTests\n{\n    private const string Category = \"End session endpoint\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n    private Client _wsfedClient;\n\n    public EndSessionTests()\n    {\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = \"client1\",\n            AllowedGrantTypes = GrantTypes.Implicit,\n            RequireConsent = false,\n            AllowedScopes = new List<string> { \"openid\" },\n            RedirectUris = new List<string> { \"https://client1/callback\" },\n            FrontChannelLogoutUri = \"https://client1/signout\",\n            PostLogoutRedirectUris = new List<string> { \"https://client1/signout-callback\" },\n            AllowAccessTokensViaBrowser = true\n        });\n\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = \"client2\",\n            AllowedGrantTypes = GrantTypes.Implicit,\n            RequireConsent = false,\n            AllowedScopes = new List<string> { \"openid\" },\n            RedirectUris = new List<string> { \"https://client2/callback\" },\n            FrontChannelLogoutUri = \"https://client2/signout\",\n            PostLogoutRedirectUris = new List<string> {\n                \"https://client2/signout-callback\",\n                \"https://client2/signout-callback2\"\n            },\n            AllowAccessTokensViaBrowser = true\n        });\n\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = \"client3\",\n            AllowedGrantTypes = GrantTypes.Implicit,\n            RequireConsent = false,\n            AllowedScopes = new List<string> { \"openid\" },\n            RedirectUris = new List<string> { \"https://client3/callback\" },\n            BackChannelLogoutUri = \"https://client3/signout\",\n            AllowAccessTokensViaBrowser = true\n        });\n\n        _mockPipeline.Clients.Add(_wsfedClient = new Client\n        {\n            ClientId = \"client4\",\n            AllowedGrantTypes = GrantTypes.Implicit,\n            RequireConsent = false,\n            AllowedScopes = new List<string> { \"openid\" },\n            RedirectUris = new List<string> { \"https://client4/callback\" },\n            FrontChannelLogoutUri = \"https://client4/signout\",\n            AllowAccessTokensViaBrowser = true\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId()\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task get_request_should_not_return_404()\n    {\n        var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        response.StatusCode.Should().NotBe(HttpStatusCode.NotFound);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task signout_request_should_redirect_to_logout_page()\n    {\n        var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        _mockPipeline.LogoutWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task get_request_should_redirect_to_configured_logout_path()\n    {\n        _mockPipeline.Options.UserInteraction.LogoutUrl = \"/logout\";\n        _mockPipeline.Options.UserInteraction.LogoutIdParameter = \"id\";\n\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        var id_token = authorization.IdentityToken;\n\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +\n            \"?id_token_hint=\" + id_token +\n            \"&post_logout_redirect_uri=https://client1/signout-callback\");\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://server/logout?id=\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task logout_request_with_params_should_pass_values_in_logout_context()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var authorization = await _mockPipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client2\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        var id_token = authorization.IdentityToken;\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +\n            \"?id_token_hint=\" + id_token +\n            \"&post_logout_redirect_uri=https://client2/signout-callback2\");\n\n        _mockPipeline.LogoutWasCalled.Should().BeTrue();\n        _mockPipeline.LogoutRequest.Should().NotBeNull();\n        _mockPipeline.LogoutRequest.ClientId.Should().Be(\"client2\");\n        _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().Be(\"https://client2/signout-callback2\");\n\n        var parts = _mockPipeline.LogoutRequest.SignOutIFrameUrl.Split('?');\n        parts[0].Should().Be(IdentityServerPipeline.EndSessionCallbackEndpoint);\n        var iframeUrl = QueryHelpers.ParseNullableQuery(parts[1]);\n        iframeUrl[\"endSessionId\"].FirstOrDefault().Should().NotBeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task logout_request_with_params_but_user_no_longer_authenticated_should_pass_redirect_info_to_logout()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var authorization = await _mockPipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client2\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        var id_token = authorization.IdentityToken;\n\n        _mockPipeline.RemoveLoginCookie();\n\n        var response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +\n            \"?id_token_hint=\" + id_token +\n            \"&post_logout_redirect_uri=https://client2/signout-callback2\");\n\n        _mockPipeline.LogoutWasCalled.Should().BeTrue();\n        _mockPipeline.LogoutRequest.Should().NotBeNull();\n        _mockPipeline.LogoutRequest.ClientId.Should().Be(\"client2\");\n        _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().Be(\"https://client2/signout-callback2\");\n        _mockPipeline.LogoutRequest.SignOutIFrameUrl.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task signout_should_support_POST()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        var id_token = authorization.IdentityToken;\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n\n        var values = new List<KeyValuePair<string, string>>();\n        values.Add(new KeyValuePair<string, string>(\"id_token_hint\", id_token));\n        values.Add(new KeyValuePair<string, string>(\"post_logout_redirect_uri\", \"https://client1/signout-callback\"));\n        var content = new FormUrlEncodedContent(values);\n        response = await _mockPipeline.BrowserClient.PostAsync(IdentityServerPipeline.EndSessionEndpoint, content);\n\n        _mockPipeline.LogoutWasCalled.Should().BeTrue();\n        _mockPipeline.LogoutRequest.Should().NotBeNull();\n        _mockPipeline.LogoutRequest.ClientId.Should().Be(\"client1\");\n        _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().Be(\"https://client1/signout-callback\");\n\n        var parts = _mockPipeline.LogoutRequest.SignOutIFrameUrl.Split('?');\n        parts[0].Should().Be(IdentityServerPipeline.EndSessionCallbackEndpoint);\n        var iframeUrl = QueryHelpers.ParseNullableQuery(parts[1]);\n        iframeUrl[\"endSessionId\"].FirstOrDefault().Should().NotBeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task signout_callback_without_params_should_return_400()\n    {\n        var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.EndSessionCallbackEndpoint);\n\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task signout_callback_with_mismatched_post_logout_redirect_uri_should_not_pass_along_logout_uri()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        var id_token = authorization.IdentityToken;\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +\n            \"?id_token_hint=\" + id_token +\n            \"&post_logout_redirect_uri=https://client1/signout-callback-not-valid\");\n\n        var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;\n\n        response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);\n\n        _mockPipeline.LogoutRequest.ClientId.Should().NotBeNull();\n        _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task signout_callback_with_mismatched_id_token_hint_should_not_pass_along_logout_message()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        var id_token = authorization.IdentityToken;\n\n        await _mockPipeline.LoginAsync(\"alice\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +\n            \"?id_token_hint=\" + id_token +\n            \"&post_logout_redirect_uri=https://client1/signout-callback\");\n\n        _mockPipeline.LogoutRequest.ClientId.Should().BeNull();\n        _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task valid_signout_callback_should_return_200_html()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;\n\n        response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        response.Content.Headers.ContentType.MediaType.Should().Be(\"text/html\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task valid_signout_callback_should_render_iframes_for_all_clients()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n        var sid = _mockPipeline.GetSessionCookie().Value;\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        var url2 = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response2 = await _mockPipeline.BrowserClient.GetAsync(url2);\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;\n\n        response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Contain(HtmlEncoder.Default.Encode(\"https://client1/signout?sid=\" + sid + \"&iss=\" + UrlEncoder.Default.Encode(\"https://server\")));\n        html.Should().Contain(HtmlEncoder.Default.Encode(\"https://client2/signout?sid=\" + sid + \"&iss=\" + UrlEncoder.Default.Encode(\"https://server\")));\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task signout_callback_should_use_signoutcleanup_for_wsfed_client()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n        var sid = _mockPipeline.GetSessionCookie().Value;\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client4\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client4/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        var signoutFrameUrl = _mockPipeline.LogoutRequest.SignOutIFrameUrl;\n\n        // since we don't have real ws-fed, we used OIDC to signin, but fooling this\n        // at signout to use ws-fed so we can test the iframe params\n        _wsfedClient.ProtocolType = ProtocolTypes.WsFederation;\n\n        response = await _mockPipeline.BrowserClient.GetAsync(signoutFrameUrl);\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Contain(\"https://client4/signout?wa=wsignoutcleanup1.0\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task valid_id_token_hint_but_no_post_logout_redirect_uri_should_not_use_single_registered_post_logout_redirect_uri()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        var id_token = authorization.IdentityToken;\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint + \n            \"?id_token_hint=\" + id_token);\n\n        _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task valid_id_token_hint_but_no_post_logout_redirect_uri_should_not_use_any_of_multiple_registered_post_logout_redirect_uri()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"client2\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        var id_token = authorization.IdentityToken;\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = true;\n        response = await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint +\n            \"?id_token_hint=\" + id_token);\n\n        _mockPipeline.LogoutRequest.PostLogoutRedirectUri.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task logout_with_clients_should_render_signout_callback_iframe()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var response = await _mockPipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client2\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client2/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        response.Should().NotBeNull();\n\n        await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        _mockPipeline.LogoutWasCalled.Should().BeTrue();\n        _mockPipeline.LogoutRequest.SignOutIFrameUrl.Should().NotBeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task logout_without_clients_should_not_render_signout_callback_iframe()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        _mockPipeline.LogoutWasCalled.Should().BeTrue();\n        _mockPipeline.LogoutRequest.SignOutIFrameUrl.Should().BeNull();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task logout_should_invoke_back_channel_logout()\n    {\n        _mockPipeline.BackChannelMessageHandler.OnInvoke = async req =>\n        {\n            req.RequestUri.ToString().Should().StartWith(\"https://client3/signout\");\n\n            var form = await req.Content.ReadAsStringAsync();\n            form.Should().Contain(OidcConstants.BackChannelLogoutRequest.LogoutToken);\n\n            var token = form.Split('=')[1];\n            var parts = token.Split('.');\n            parts.Length.Should().Be(3);\n\n            var bytes = Base64Url.Decode(parts[1]);\n            var json = Encoding.UTF8.GetString(bytes);\n            var payload = JObject.Parse(json);\n            payload[\"iss\"].ToString().Should().Be(\"https://server\");\n            payload[\"sub\"].ToString().Should().Be(\"bob\");\n            payload[\"aud\"].ToString().Should().Be(\"client3\");\n            payload[\"iat\"].Should().NotBeNull();\n            payload[\"jti\"].Should().NotBeNull();\n            payload[\"sid\"].Should().NotBeNull();\n            payload[\"events\"].Type.Should().Be(JTokenType.Object);\n\n            var events = (JObject)payload[\"events\"];\n            events.Count.Should().Be(1);\n            events[\"http://schemas.openid.net/event/backchannel-logout\"].Should().NotBeNull();\n            events[\"http://schemas.openid.net/event/backchannel-logout\"].Type.Should().Be(JTokenType.Object);\n\n            var evt = (JObject)events[\"http://schemas.openid.net/event/backchannel-logout\"];\n            evt.Count.Should().Be(0);\n        };\n\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var response = await _mockPipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client3\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client3/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        response.Should().NotBeNull();\n\n        await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        _mockPipeline.BackChannelMessageHandler.InvokeWasCalled.Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task back_channel_logout_should_not_affect_end_session_callback()\n    {\n        _mockPipeline.BackChannelMessageHandler.OnInvoke = req => throw new Exception(\"boom!\");\n\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var response = await _mockPipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client3\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client3/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        response.Should().NotBeNull();\n\n        await _mockPipeline.BrowserClient.GetAsync(IdentityServerPipeline.EndSessionEndpoint);\n\n        _mockPipeline.BackChannelMessageHandler.InvokeWasCalled.Should().BeTrue();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Introspection/IntrospectionTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net;\nusing System.Net.Http;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Endpoints.Introspection.Setup;\nusing IdentityServer8.Extensions;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Introspection;\n\npublic class IntrospectionTests\n{\n    private const string Category = \"Introspection endpoint\";\n    private const string IntrospectionEndpoint = \"https://server/connect/introspect\";\n    private const string TokenEndpoint = \"https://server/connect/token\";\n\n    private readonly HttpClient _client;\n    private readonly HttpMessageHandler _handler;\n\n    public IntrospectionTests()\n    {\n        var builder = new WebHostBuilder()\n            .UseStartup<Startup>();\n        var server = new TestServer(builder);\n\n        _handler = server.CreateHandler();\n        _client = server.CreateClient();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Empty_request_should_fail()\n    {\n        var form = new Dictionary<string, string>();\n\n        var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));\n\n        response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Unknown_scope_should_fail()\n    {\n        var form = new Dictionary<string, string>();\n\n        _client.SetBasicAuthentication(\"unknown\", \"invalid\");\n        var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));\n\n        response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Invalid_scope_secret_should_fail()\n    {\n        var form = new Dictionary<string, string>();\n\n        _client.SetBasicAuthentication(\"api1\", \"invalid\");\n        var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));\n\n        response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Missing_token_should_fail()\n    {\n        var form = new Dictionary<string, string>();\n\n        _client.SetBasicAuthentication(\"api1\", \"secret\");\n        var response = await _client.PostAsync(IntrospectionEndpoint, new FormUrlEncodedContent(form));\n\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Invalid_token_should_fail()\n    {\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api1\",\n            ClientSecret = \"secret\",\n\n            Token = \"invalid\"\n        });\n\n        introspectionResponse.IsActive.Should().Be(false);\n        introspectionResponse.IsError.Should().Be(false);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Invalid_Content_type_should_fail()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client1\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        var data = new\n        {\n            client_id = \"api1\",\n            client_secret = \"secret\",\n            token = tokenResponse.AccessToken\n        };\n        var json = JsonSerializer.Serialize(data);\n\n        var client = new HttpClient(_handler);\n        var response = await client.PostAsync(IntrospectionEndpoint, new StringContent(json, Encoding.UTF8, \"application/json\"));\n        response.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Valid_token_and_valid_scope_should_succeed()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client1\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api1\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        introspectionResponse.IsActive.Should().Be(true);\n        introspectionResponse.IsError.Should().Be(false);\n\n        var scopes = from c in introspectionResponse.Claims\n                     where c.Type == \"scope\"\n                     select c;\n\n        scopes.Count().Should().Be(1);\n        scopes.First().Value.Should().Be(\"api1\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Response_data_should_be_valid_using_single_scope()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client1\",\n            ClientSecret = \"secret\",\n            Scope = \"api1\"\n        });\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api1\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        var values = introspectionResponse.Json.ToObject<Dictionary<string, JsonElement>>();\n\n        values[\"aud\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"iss\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"nbf\"].ValueKind.Should().Be(JsonValueKind.Number); \n        values[\"exp\"].ValueKind.Should().Be(JsonValueKind.Number); \n        values[\"client_id\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"active\"].ValueKind.Should().Be(JsonValueKind.True); \n        values[\"scope\"].ValueKind.Should().Be(JsonValueKind.String);\n\n        values[\"scope\"].ToString().Should().Be(\"api1\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Response_data_with_user_authentication_should_be_valid_using_single_scope()\n    {\n        var tokenResponse = await _client.RequestPasswordTokenAsync(new PasswordTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"ro.client\",\n            ClientSecret = \"secret\",\n            UserName = \"bob\",\n            Password = \"bob\",\n\n            Scope = \"api1\",\n        });\n\n        tokenResponse.IsError.Should().BeFalse();\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api1\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        var values = introspectionResponse.Json.ToObject<Dictionary<string, JsonElement>>();\n\n        values[\"aud\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"iss\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"nbf\"].ValueKind.Should().Be(JsonValueKind.Number); \n        values[\"exp\"].ValueKind.Should().Be(JsonValueKind.Number); \n        values[\"auth_time\"].ValueKind.Should().Be(JsonValueKind.Number); \n        values[\"client_id\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"sub\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"active\"].ValueKind.Should().Be(JsonValueKind.True); \n        values[\"scope\"].ValueKind.Should().Be(JsonValueKind.String);\n\n        values[\"scope\"].ToString().Should().Be(\"api1\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Response_data_should_be_valid_using_multiple_scopes_multiple_audiences()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client1\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api2 api3-a api3-b\",\n        });\n\n        tokenResponse.IsError.Should().BeFalse();\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api3\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        var values = introspectionResponse.Json.ToObject<Dictionary<string, JsonElement>>();\n\n\n        values[\"aud\"].GetType().Name.Should().Be(\"JsonElement\");\n        values[\"aud\"].ValueKind.Should().Be(JsonValueKind.Array);\n\n        // Access the 'aud' array\n        var audiences = values[\"aud\"].EnumerateArray();\n        foreach (var aud in audiences)\n        {\n            // Check each audience value to ensure it's a string\n            aud.ValueKind.Should().Be(JsonValueKind.String);\n        }\n\n        values[\"iss\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"iss\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"nbf\"].ValueKind.Should().Be(JsonValueKind.Number);\n        values[\"exp\"].ValueKind.Should().Be(JsonValueKind.Number);\n        values[\"client_id\"].ValueKind.Should().Be(JsonValueKind.String);\n        var activeKind= values[\"active\"].ValueKind;\n        values[\"active\"].ValueKind.Should().Be(JsonValueKind.True);\n        values[\"scope\"].ValueKind.Should().Be(JsonValueKind.String);\n\n        var scopes = values[\"scope\"].ToString();\n        scopes.Should().Be(\"api3-a api3-b\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Response_data_should_be_valid_using_multiple_scopes_single_audience()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client1\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api3-a api3-b\",\n        });\n\n        tokenResponse.IsError.Should().BeFalse();\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api3\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        var values = introspectionResponse.Json.ToObject<Dictionary<string, JsonElement>>();\n        values[\"aud\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"aud\"].ValueKind.Should().Be(JsonValueKind.String);\n        values[\"iss\"].ValueKind.Should().Be(JsonValueKind.String); \n        values[\"nbf\"].ValueKind.Should().Be(JsonValueKind.Number);  \n        values[\"exp\"].ValueKind.Should().Be(JsonValueKind.Number);  \n        values[\"client_id\"].ValueKind.Should().Be(JsonValueKind.String); \n        values[\"active\"].ValueKind.Should().Be(JsonValueKind.True); \n        values[\"scope\"].ValueKind.Should().Be(JsonValueKind.String);\n\n        var scopes = values[\"scope\"].ToString();\n        scopes.Should().Be(\"api3-a api3-b\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Token_with_many_scopes_but_api_should_only_see_its_own_scopes()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client3\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1 api2 api3-a\",\n        });\n\n        tokenResponse.IsError.Should().BeFalse();\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api3\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        introspectionResponse.IsActive.Should().BeTrue();\n        introspectionResponse.IsError.Should().BeFalse();\n\n        var scopes = from c in introspectionResponse.Claims\n                     where c.Type == \"scope\"\n                     select c.Value;\n\n        scopes.Count().Should().Be(1);\n        scopes.First().Should().Be(\"api3-a\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Valid_token_with_valid_multiple_scopes()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client1\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1 api2\",\n        });\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api1\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        introspectionResponse.IsActive.Should().Be(true);\n        introspectionResponse.IsError.Should().Be(false);\n\n        var scopes = from c in introspectionResponse.Claims\n                     where c.Type == \"scope\"\n                     select c;\n\n        scopes.Count().Should().Be(1);\n        scopes.First().Value.Should().Be(\"api1\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Valid_token_with_invalid_scopes_should_fail()\n    {\n        var tokenResponse = await _client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest\n        {\n            Address = TokenEndpoint,\n            ClientId = \"client1\",\n            ClientSecret = \"secret\",\n\n            Scope = \"api1\",\n        });\n\n        var introspectionResponse = await _client.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IntrospectionEndpoint,\n            ClientId = \"api2\",\n            ClientSecret = \"secret\",\n\n            Token = tokenResponse.AccessToken\n        });\n\n        introspectionResponse.IsActive.Should().Be(false);\n        introspectionResponse.IsError.Should().Be(false);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Introspection/Setup/Clients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Introspection.Setup;\n\ninternal class Clients\n{\n    public static IEnumerable<Client> Get()\n    {\n        return new List<Client>\n        {\n            new Client\n            {\n                ClientId = \"client1\",\n                ClientSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"api1\", \"api2\", \"api3-a\", \"api3-b\" },\n                AccessTokenType = AccessTokenType.Reference\n            },\n            new Client\n            {\n                ClientId = \"client2\",\n                ClientSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"api1\", \"api2\", \"api3-a\", \"api3-b\" },\n                AccessTokenType = AccessTokenType.Reference\n            },\n            new Client\n            {\n                ClientId = \"client3\",\n                ClientSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"api1\", \"api2\", \"api3-a\", \"api3-b\" },\n                AccessTokenType = AccessTokenType.Reference\n            },\n            new Client\n            {\n                ClientId = \"ro.client\",\n                ClientSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                AllowedScopes = { \"api1\", \"api2\", \"api3-a\", \"api3-b\" },\n                AccessTokenType = AccessTokenType.Reference\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Introspection/Setup/Scopes.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Introspection.Setup;\n\ninternal class Scopes\n{\n    public static IEnumerable<ApiResource> GetApis()\n    {\n        return new ApiResource[]\n        {\n            new ApiResource\n            {\n                Name = \"api1\",\n                ApiSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n                Scopes = { \"api1\" }\n            },\n            new ApiResource\n            {\n                Name = \"api2\",\n                ApiSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n                Scopes = { \"api2\" }\n            },\n             new ApiResource\n            {\n                Name = \"api3\",\n                ApiSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n                Scopes = { \"api3-a\", \"api3-b\" }\n            }\n        };\n    }\n    public static IEnumerable<ApiScope> GetScopes()\n    {\n        return new ApiScope[]\n        {\n            new ApiScope\n            {\n                Name = \"api1\"\n            },\n            new ApiScope\n            {\n                Name = \"api2\"\n            },\n            new ApiScope\n            {\n                Name = \"api3-a\"\n            },\n            new ApiScope\n            {\n                Name = \"api3-b\"\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Introspection/Setup/Startup.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Introspection.Setup;\n\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        var builder = services.AddIdentityServer(options =>\n        {\n            options.IssuerUri = \"https://idsvr8\";\n            options.Endpoints.EnableAuthorizeEndpoint = false;\n        });\n\n        builder.AddInMemoryClients(Clients.Get());\n        builder.AddInMemoryApiResources(Scopes.GetApis());\n        builder.AddInMemoryApiScopes(Scopes.GetScopes());\n        builder.AddTestUsers(Users.Get());\n        builder.AddDeveloperSigningCredential(persistKey: false);\n    }\n\n    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)\n    {\n        app.UseIdentityServer();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Introspection/Setup/Users.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8.Test;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Introspection.Setup;\n\npublic static class Users\n{\n    public static List<TestUser> Get()\n    {\n        return new List<TestUser>\n        {\n            new TestUser\n            {\n                SubjectId = \"1\",\n                Username = \"bob\",\n                Password = \"bob\"\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Revocation/RevocationTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Revocation;\n\npublic class RevocationTests\n{\n    private const string Category = \"RevocationTests endpoint\";\n\n    private string client_id = \"client\";\n    private string client_secret = \"secret\";\n    private string redirect_uri = \"https://client/callback\";\n\n    private string scope_name = \"api\";\n    private string scope_secret = \"api_secret\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public RevocationTests()\n    {\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = client_id,\n            ClientSecrets = new List<Secret> { new Secret(client_secret.Sha256()) },\n            AllowedGrantTypes = GrantTypes.Code,\n            RequireConsent = false,\n            RequirePkce = false,\n            AllowOfflineAccess = true,\n            AllowedScopes = new List<string> { \"api\" },\n            RedirectUris = new List<string> { redirect_uri },\n            AllowAccessTokensViaBrowser = true,\n            AccessTokenType = AccessTokenType.Reference,\n            RefreshTokenUsage = TokenUsage.ReUse\n        });\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = \"implicit\",\n            AllowedGrantTypes = GrantTypes.Implicit,\n            RequireConsent = false,\n            AllowedScopes = new List<string> { \"api\" },\n            RedirectUris = new List<string> { redirect_uri },\n            AllowAccessTokensViaBrowser = true,\n            AccessTokenType = AccessTokenType.Reference\n        });\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = \"implicit_and_client_creds\",\n            AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,\n            ClientSecrets = { new Secret(\"secret\".Sha256()) },\n            RequireConsent = false,\n            AllowedScopes = new List<string> { \"api\" },\n            RedirectUris = new List<string> { redirect_uri },\n            AllowAccessTokensViaBrowser = true,\n            AccessTokenType = AccessTokenType.Reference\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId()\n        });\n\n        _mockPipeline.ApiResources.AddRange(new ApiResource[] {\n            new ApiResource\n            {\n                Name = \"api\",\n                ApiSecrets = new List<Secret> { new Secret(scope_secret.Sha256()) },\n                Scopes = { scope_name }\n            }\n        });\n\n        _mockPipeline.ApiScopes.AddRange(new ApiScope[]\n        {\n            new ApiScope\n            {\n                Name = scope_name\n            }\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    private class Tokens\n    {\n        public Tokens(TokenResponse response)\n        {\n            AccessToken = response.AccessToken;\n            RefreshToken = response.RefreshToken;\n        }\n\n        public string AccessToken { get; set; }\n        public string RefreshToken { get; set; }\n    }\n\n    private async Task<Tokens> GetTokensAsync()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var authorizationResponse = await _mockPipeline.RequestAuthorizationEndpointAsync(\n            client_id,\n            \"code\",\n            \"api offline_access\",\n            \"https://client/callback\");\n\n        authorizationResponse.IsError.Should().BeFalse();\n        authorizationResponse.Code.Should().NotBeNull();\n\n        var tokenResponse = await _mockPipeline.BackChannelClient.RequestAuthorizationCodeTokenAsync(new AuthorizationCodeTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            Code = authorizationResponse.Code,\n            RedirectUri = redirect_uri\n        });\n\n        tokenResponse.IsError.Should().BeFalse();\n        tokenResponse.AccessToken.Should().NotBeNull();\n        tokenResponse.RefreshToken.Should().NotBeNull();\n\n        return new Tokens(tokenResponse);\n    }\n\n    private async Task<string> GetAccessTokenForImplicitClientAsync(string clientId)\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var authorizationResponse = await _mockPipeline.RequestAuthorizationEndpointAsync(\n            clientId,\n            \"token\",\n            \"api\",\n            \"https://client/callback\");\n\n        authorizationResponse.IsError.Should().BeFalse();\n        authorizationResponse.AccessToken.Should().NotBeNull();\n\n        return authorizationResponse.AccessToken;\n    }\n\n    private Task<bool> IsAccessTokenValidAsync(Tokens tokens)\n    {\n        return IsAccessTokenValidAsync(tokens.AccessToken);\n    }\n\n    private async Task<bool> IsAccessTokenValidAsync(string token)\n    {\n        var response = await _mockPipeline.BackChannelClient.IntrospectTokenAsync(new TokenIntrospectionRequest\n        {\n            Address = IdentityServerPipeline.IntrospectionEndpoint,\n            ClientId = scope_name,\n            ClientSecret = scope_secret,\n\n            Token = token,\n            TokenTypeHint = IdentityModel.OidcConstants.TokenTypes.AccessToken\n        });\n\n        return response.IsError == false && response.IsActive;\n    }\n\n    private async Task<bool> UseRefreshTokenAsync(Tokens tokens)\n    {\n        var response = await _mockPipeline.BackChannelClient.RequestRefreshTokenAsync(new RefreshTokenRequest\n        {\n            Address = IdentityServerPipeline.TokenEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            RefreshToken = tokens.RefreshToken\n        });\n\n        if (response.IsError)\n        {\n            return false;\n        }\n\n        tokens.AccessToken = response.AccessToken;\n        return true;\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Get_request_should_return_405()\n    {\n        var response = await _mockPipeline.BackChannelClient.GetAsync(IdentityServerPipeline.RevocationEndpoint);\n\n        response.StatusCode.Should().Be(HttpStatusCode.MethodNotAllowed);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Post_without_form_urlencoded_should_return_415()\n    {\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, null);\n\n        response.StatusCode.Should().Be(HttpStatusCode.UnsupportedMediaType);\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Revoke_valid_access_token_should_return_success()\n    {\n        var tokens = await GetTokensAsync();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            Token = tokens.AccessToken\n        });\n\n        result.IsError.Should().BeFalse();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Revoke_valid_access_token_belonging_to_another_client_should_return_success_but_not_revoke_token()\n    {\n        var tokens = await GetTokensAsync();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = \"implicit\",\n            ClientSecret = client_secret,\n\n            Token = tokens.AccessToken\n        });\n\n        result.IsError.Should().BeFalse();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Revoke_valid_refresh_token_should_return_success()\n    {\n        var tokens = await GetTokensAsync();\n        (await UseRefreshTokenAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            Token = tokens.RefreshToken\n        });\n\n        result.IsError.Should().BeFalse();\n\n        (await UseRefreshTokenAsync(tokens)).Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Revoke_valid_refresh_token_belonging_to_another_client_should_return_success_but_not_revoke_token()\n    {\n        var tokens = await GetTokensAsync();\n        (await UseRefreshTokenAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = \"implicit\",\n            ClientSecret = client_secret,\n\n            Token = tokens.RefreshToken\n        });\n\n        result.IsError.Should().BeFalse();\n\n        (await UseRefreshTokenAsync(tokens)).Should().BeTrue();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Revoke_invalid_access_token_should_return_success()\n    {\n        var tokens = await GetTokensAsync();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            Token = tokens.AccessToken\n        });\n\n        result.IsError.Should().BeFalse();\n\n        (await IsAccessTokenValidAsync(tokens)).Should().BeFalse();\n\n        result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            Token = tokens.AccessToken\n        });\n\n        result.IsError.Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Revoke_invalid_refresh_token_should_return_success()\n    {\n        var tokens = await GetTokensAsync();\n        (await UseRefreshTokenAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            Token = tokens.RefreshToken\n        });\n\n        result.IsError.Should().BeFalse();\n\n        (await UseRefreshTokenAsync(tokens)).Should().BeFalse();\n\n        result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = client_id,\n            ClientSecret = client_secret,\n\n            Token = tokens.RefreshToken\n        });\n\n        result.IsError.Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Invalid_client_id_should_return_error()\n    {\n        var tokens = await GetTokensAsync();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = \"not_valid\",\n            ClientSecret = client_secret,\n\n            Token = tokens.AccessToken\n        });\n\n        result.IsError.Should().BeTrue();\n        result.Error.Should().Be(\"invalid_client\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Invalid_credentials_should_return_error()\n    {\n        var tokens = await GetTokensAsync();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n\n        var result = await _mockPipeline.BackChannelClient.RevokeTokenAsync(new TokenRevocationRequest\n        {\n            Address = IdentityServerPipeline.RevocationEndpoint,\n            ClientId = client_id,\n            ClientSecret = \"not_valid\",\n\n            Token = tokens.AccessToken\n        });\n\n        result.IsError.Should().BeTrue();\n        result.Error.Should().Be(\"invalid_client\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Missing_token_should_return_error()\n    {\n        var data = new Dictionary<string, string>\n        {\n            { \"client_id\", client_id },\n            { \"client_secret\", client_secret }\n        };\n\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n\n        var result = await ProtocolResponse.FromHttpResponseAsync<TokenRevocationResponse>(response);\n        result.IsError.Should().BeTrue();\n        result.Error.Should().Be(\"invalid_request\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Invalid_token_type_hint_should_return_error()\n    {\n        var tokens = await GetTokensAsync();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n\n        var data = new Dictionary<string, string>\n        {\n            { \"client_id\", client_id },\n            { \"client_secret\", client_secret },\n            { \"token\", tokens.AccessToken },\n            { \"token_type_hint\", \"not_valid\" }\n        };\n\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n\n        var result = await ProtocolResponse.FromHttpResponseAsync<TokenRevocationResponse>(response);\n        result.IsError.Should().BeTrue();\n        result.Error.Should().Be(\"unsupported_token_type\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Valid_access_token_but_missing_token_type_hint_should_succeed()\n    {\n        var tokens = await GetTokensAsync();\n        (await IsAccessTokenValidAsync(tokens)).Should().BeTrue();\n\n        var data = new Dictionary<string, string>\n        {\n            { \"client_id\", client_id },\n            { \"client_secret\", client_secret },\n            { \"token\", tokens.AccessToken }\n        };\n\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n\n        (await IsAccessTokenValidAsync(tokens)).Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Valid_refresh_token_but_missing_token_type_hint_should_succeed()\n    {\n        var tokens = await GetTokensAsync();\n        (await UseRefreshTokenAsync(tokens)).Should().BeTrue();\n\n        var data = new Dictionary<string, string>\n        {\n            { \"client_id\", client_id },\n            { \"client_secret\", client_secret },\n            { \"token\", tokens.RefreshToken }\n        };\n\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n\n        (await UseRefreshTokenAsync(tokens)).Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Implicit_client_without_secret_revoking_token_should_succeed()\n    {\n        var token = await GetAccessTokenForImplicitClientAsync(\"implicit\");\n\n        var data = new Dictionary<string, string>\n        {\n            { \"client_id\", \"implicit\" },\n            { \"token\", token }\n        };\n\n        (await IsAccessTokenValidAsync(token)).Should().BeTrue();\n\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        (await IsAccessTokenValidAsync(token)).Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task Implicit_and_client_creds_client_without_secret_revoking_token_should_fail()\n    {\n        var token = await GetAccessTokenForImplicitClientAsync(\"implicit_and_client_creds\");\n\n        var data = new Dictionary<string, string>\n        {\n            { \"client_id\", \"implicit_and_client_creds\" },\n            { \"token\", token }\n        };\n\n        (await IsAccessTokenValidAsync(token)).Should().BeTrue();\n\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.RevocationEndpoint, new FormUrlEncodedContent(data));\n        response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n        (await IsAccessTokenValidAsync(token)).Should().BeTrue();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Endpoints/Token/TokenEndpointTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Newtonsoft.Json.Linq;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer.IntegrationTests.Common;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Endpoints.Token;\n\npublic class TokenEndpointTests\n{\n    private const string Category = \"Token endpoint\";\n\n    private string client_id = \"client\";\n    private string client_secret = \"secret\";\n\n    private string scope_name = \"api\";\n    private string scope_secret = \"api_secret\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public TokenEndpointTests()\n    {\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = client_id,\n            ClientSecrets = new List<Secret> { new Secret(client_secret.Sha256()) },\n            AllowedGrantTypes = { GrantType.ClientCredentials, GrantType.ResourceOwnerPassword },\n            AllowedScopes = new List<string> { \"api\" },\n        });\n\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Password = \"password\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId()\n        });\n\n        _mockPipeline.ApiResources.AddRange(new ApiResource[] {\n            new ApiResource\n            {\n                Name = \"api\",\n                ApiSecrets = new List<Secret> { new Secret(scope_secret.Sha256()) },\n                Scopes = {scope_name}\n            }\n        });\n\n        _mockPipeline.ApiScopes.AddRange(new[] {\n            new ApiScope\n            {\n                Name = scope_name\n            }\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task client_credentials_request_with_funny_headers_should_not_hang()\n    {\n        var data = new Dictionary<string, string>\n        {\n            { \"grant_type\", \"client_credentials\" },\n            { \"client_id\", client_id },\n            { \"client_secret\", client_secret },\n            { \"scope\", scope_name },\n        };\n        var form = new FormUrlEncodedContent(data);\n        _mockPipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Referer\", \"http://127.0.0.1:33086/appservice/appservice?t=1564165664142?load\");\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form);\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        var json = await response.Content.ReadAsStringAsync();\n        var result = JObject.Parse(json);\n        result.ContainsKey(\"error\").Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task resource_owner_request_with_funny_headers_should_not_hang()\n    {\n        var data = new Dictionary<string, string>\n        {\n            { \"grant_type\", \"password\" },\n            { \"username\", \"bob\" },\n            { \"password\", \"password\" },\n            { \"client_id\", client_id },\n            { \"client_secret\", client_secret },\n            { \"scope\", scope_name },\n        };\n        var form = new FormUrlEncodedContent(data);\n        _mockPipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Referer\", \"http://127.0.0.1:33086/appservice/appservice?t=1564165664142?load\");\n        var response = await _mockPipeline.BackChannelClient.PostAsync(IdentityServerPipeline.TokenEndpoint, form);\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        var json = await response.Content.ReadAsStringAsync();\n        var result = JObject.Parse(json);\n        result.ContainsKey(\"error\").Should().BeFalse();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Extensibility/CustomProfileServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Net;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing Microsoft.Extensions.DependencyInjection;\nusing Newtonsoft.Json.Linq;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Extensibility;\n\npublic class CustomProfileServiceTests\n{\n    private const string Category = \"Authorize endpoint\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    public CustomProfileServiceTests()\n    {\n        _mockPipeline.OnPostConfigureServices += svcs =>\n        {\n            svcs.AddTransient<IProfileService, CustomProfileService>();\n        };\n\n        _mockPipeline.Clients.Add(new Client\n        {\n            ClientId = \"implicit\",\n            AllowedGrantTypes = GrantTypes.Implicit,\n            RedirectUris = { \"https://client/callback\" },\n            RequireConsent = false,\n            AllowedScopes = { \"openid\", \"custom_identity\" }\n        });\n\n        _mockPipeline.IdentityScopes.Add(new IdentityResources.OpenId());\n        _mockPipeline.IdentityScopes.Add(new IdentityResource(\"custom_identity\", new string[] { \"foo\" }));\n\n        _mockPipeline.Users.Add(new IdentityServer8.Test.TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Password = \"password\",\n        });\n\n        _mockPipeline.Initialize();\n    }\n\n    [Fact]\n    public async Task custom_profile_should_return_claims_for_implicit_client()\n    {\n        await _mockPipeline.LoginAsync(\"bob\");\n\n        var url = _mockPipeline.CreateAuthorizeUrl(\n            clientId: \"implicit\",\n            responseType: \"id_token\",\n            scope: \"openid custom_identity\",\n            redirectUri: \"https://client/callback\",\n            state: \"state\",\n            nonce: \"nonce\");\n\n        _mockPipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Headers.Location.ToString().Should().StartWith(\"https://client/callback\");\n\n        var authorization = new IdentityModel.Client.AuthorizeResponse(response.Headers.Location.ToString());\n        authorization.IsError.Should().BeFalse();\n        authorization.IdentityToken.Should().NotBeNull();\n\n        var payload = authorization.IdentityToken.Split('.')[1];\n        var json = Encoding.UTF8.GetString(Base64Url.Decode(payload));\n        var obj = JObject.Parse(json);\n\n        obj.GetValue(\"foo\").Should().NotBeNull();\n        obj[\"foo\"].ToString().Should().Be(\"bar\");\n    }\n}\n\npublic class CustomProfileService : IProfileService\n{\n    public Task GetProfileDataAsync(ProfileDataRequestContext context)\n    {\n        var claims = new Claim[]\n        {\n            new Claim(\"foo\", \"bar\")\n        };\n        context.AddRequestedClaims(claims);\n        return Task.CompletedTask;\n    }\n\n    public Task IsActiveAsync(IsActiveContext context)\n    {\n        context.IsActive = true;\n        return Task.CompletedTask;\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/IdentityServer.IntegrationTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <AssemblyOriginatorKeyFile>../../../../key.snk</AssemblyOriginatorKeyFile>\n    <SignAssembly>true</SignAssembly>\n    <PublicSign Condition=\"'$(OS)' != 'Windows_NT'\">true</PublicSign>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.TestHost\" />\n    <PackageReference Include=\"System.IdentityModel.Tokens.Jwt\" />\n    \n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"FluentAssertions\" />\n    <PackageReference Include=\"coverlet.collector\" GeneratePathProperty=\"true\">\n        <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n        <PrivateAssets>all</PrivateAssets>\n    </PackageReference>     \n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"identityserver_testing.cer\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Update=\"identityserver_testing.pfx\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Update=\"xunit.runner.json\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.csproj\" />\n  </ItemGroup>\n\n</Project>"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Pipeline/CorsTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Test;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Pipeline;\n\npublic class CorsTests\n{\n    private const string Category = \"CORS Integration\";\n\n    private IdentityServerPipeline _pipeline = new IdentityServerPipeline();\n\n    public CorsTests()\n    {\n        _pipeline.Clients.AddRange(new Client[] {\n            new Client\n            {\n                ClientId = \"client\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = true,\n                AllowedScopes = new List<string> { \"openid\", \"profile\", \"api1\", \"api2\" },\n                RedirectUris = new List<string> { \"https://client/callback\" },\n                AllowedCorsOrigins = new List<string> { \"https://client\" }\n            }\n        });\n\n        _pipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _pipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email()\n        });\n        _pipeline.ApiResources.AddRange(new ApiResource[] {\n            new ApiResource\n            {\n                Name = \"api\",\n                Scopes = { \"api1\", \"api2\" }\n            }\n        });\n        _pipeline.ApiScopes.AddRange(new[] {\n            new ApiScope\n            {\n                Name = \"api1\"\n            },\n            new ApiScope\n            {\n                Name = \"api2\"\n            }\n        });\n\n        _pipeline.Initialize();\n    }\n\n    [Theory]\n    [InlineData(IdentityServerPipeline.DiscoveryEndpoint)]\n    [InlineData(IdentityServerPipeline.DiscoveryKeysEndpoint)]\n    [InlineData(IdentityServerPipeline.TokenEndpoint)]\n    [InlineData(IdentityServerPipeline.UserInfoEndpoint)]\n    [InlineData(IdentityServerPipeline.RevocationEndpoint)]\n    [Trait(\"Category\", Category)]\n    public async Task cors_request_to_allowed_endpoints_should_succeed(string url)\n    {\n        _pipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Origin\", \"https://client\");\n        _pipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Access-Control-Request-Method\", \"GET\");\n        \n        var message = new HttpRequestMessage(HttpMethod.Options, url);\n        var response = await _pipeline.BackChannelClient.SendAsync(message);\n\n        response.StatusCode.Should().Be(HttpStatusCode.NoContent);\n        response.Headers.Contains(\"Access-Control-Allow-Origin\").Should().BeTrue();\n    }\n\n    [Theory]\n    [InlineData(IdentityServerPipeline.AuthorizeEndpoint)]\n    [InlineData(IdentityServerPipeline.EndSessionEndpoint)]\n    [InlineData(IdentityServerPipeline.CheckSessionEndpoint)]\n    [InlineData(IdentityServerPipeline.LoginPage)]\n    [InlineData(IdentityServerPipeline.ConsentPage)]\n    [InlineData(IdentityServerPipeline.ErrorPage)]\n    [Trait(\"Category\", Category)]\n    public async Task cors_request_to_restricted_endpoints_should_not_succeed(string url)\n    {\n        _pipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Origin\", \"https://client\");\n        _pipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Access-Control-Request-Method\", \"GET\");\n\n        var message = new HttpRequestMessage(HttpMethod.Options, url);\n        var response = await _pipeline.BackChannelClient.SendAsync(message);\n\n        response.Headers.Contains(\"Access-Control-Allow-Origin\").Should().BeFalse();\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task custom_cors_policy_provider_should_be_used()\n    {\n        var policy = new StubCorePolicyProvider();\n        _pipeline.OnPreConfigureServices += services =>\n        {\n            services.AddSingleton<ICorsPolicyService>(policy);\n        };\n        _pipeline.Initialize();\n\n        _pipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Origin\", \"https://client\");\n        _pipeline.BackChannelClient.DefaultRequestHeaders.Add(\"Access-Control-Request-Method\", \"GET\");\n\n        var message = new HttpRequestMessage(HttpMethod.Options, IdentityServerPipeline.DiscoveryEndpoint);\n        var response = await _pipeline.BackChannelClient.SendAsync(message);\n\n        policy.WasCalled.Should().BeTrue();\n    }\n}\n\npublic class StubCorePolicyProvider : ICorsPolicyService\n{\n    public bool Result;\n    public bool WasCalled;\n\n    public Task<bool> IsOriginAllowedAsync(string origin)\n    {\n        WasCalled = true;\n        return Task.FromResult(Result);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Pipeline/FederatedSignoutTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Microsoft.AspNetCore.Authentication;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Pipeline;\n\npublic class FederatedSignoutTests\n{\n    private const string Category = \"Federated Signout\";\n\n    private IdentityServerPipeline _pipeline = new IdentityServerPipeline();\n    private ClaimsPrincipal _user;\n\n    public FederatedSignoutTests()\n    {\n        _user = new IdentityServerUser(\"bob\")\n        {\n            AdditionalClaims = { new Claim(JwtClaimTypes.SessionId, \"123\") }\n        }.CreatePrincipal();\n\n        _pipeline = new IdentityServerPipeline();\n\n        _pipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId()\n        });\n\n        _pipeline.Clients.Add(new Client\n        {\n            ClientId = \"client1\",\n            AllowedGrantTypes = GrantTypes.Implicit,\n            RequireConsent = false,\n            AllowedScopes = new List<string> { \"openid\" },\n            RedirectUris = new List<string> { \"https://client1/callback\" },\n            FrontChannelLogoutUri = \"https://client1/signout\",\n            PostLogoutRedirectUris = new List<string> { \"https://client1/signout-callback\" },\n            AllowAccessTokensViaBrowser = true\n        });\n\n        _pipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n           {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n           }\n        });\n\n        _pipeline.Initialize();\n    }\n\n    [Fact]\n    public async Task valid_request_to_federated_signout_endpoint_should_render_page_with_iframe()\n    {\n        await _pipeline.LoginAsync(_user);\n\n        await _pipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        var response = await _pipeline.BrowserClient.GetAsync(IdentityServerPipeline.FederatedSignOutUrl + \"?sid=123\");\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        response.Content.Headers.ContentType.MediaType.Should().Be(\"text/html\");\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Contain(\"https://server/connect/endsession/callback?endSessionId=\");\n    }\n\n    [Fact]\n    public async Task valid_POST_request_to_federated_signout_endpoint_should_render_page_with_iframe()\n    {\n        await _pipeline.LoginAsync(_user);\n\n        await _pipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        var response = await _pipeline.BrowserClient.PostAsync(IdentityServerPipeline.FederatedSignOutUrl, new FormUrlEncodedContent(new Dictionary<string, string> { { \"sid\", \"123\" } }));\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        response.Content.Headers.ContentType.MediaType.Should().Be(\"text/html\");\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Contain(\"https://server/connect/endsession/callback?endSessionId=\");\n    }\n\n    [Fact]\n    public async Task no_clients_signed_into_should_not_render_page_with_iframe()\n    {\n        await _pipeline.LoginAsync(_user);\n\n        var response = await _pipeline.BrowserClient.GetAsync(IdentityServerPipeline.FederatedSignOutUrl + \"?sid=123\");\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        response.Content.Headers.ContentType.Should().BeNull();\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Be(String.Empty);\n    }\n\n    [Fact]\n    public async Task no_authenticated_user_should_not_render_page_with_iframe()\n    {\n        var response = await _pipeline.BrowserClient.GetAsync(IdentityServerPipeline.FederatedSignOutUrl + \"?sid=123\");\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        response.Content.Headers.ContentType.Should().BeNull();\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Be(String.Empty);\n    }\n\n    [Fact]\n    public async Task user_not_signed_out_should_not_render_page_with_iframe()\n    {\n        _pipeline.OnFederatedSignout = ctx =>\n        {\n            return Task.FromResult(true);\n        };\n\n        await _pipeline.LoginAsync(_user);\n\n        await _pipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        var response = await _pipeline.BrowserClient.GetAsync(IdentityServerPipeline.FederatedSignOutUrl + \"?sid=123\");\n\n        response.StatusCode.Should().Be(HttpStatusCode.OK);\n        response.Content.Headers.ContentType.Should().BeNull();\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Be(String.Empty);\n    }\n\n    [Fact]\n    public async Task non_200_should_not_render_page_with_iframe()\n    {\n        _pipeline.OnFederatedSignout = async ctx =>\n        {\n            await ctx.SignOutAsync(); // even if we signout, we should not see iframes\n            ctx.Response.Redirect(\"http://foo\");\n            return true;\n        };\n\n        await _pipeline.LoginAsync(_user);\n\n        await _pipeline.RequestAuthorizationEndpointAsync(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n\n        _pipeline.BrowserClient.AllowAutoRedirect = false;\n        var response = await _pipeline.BrowserClient.GetAsync(IdentityServerPipeline.FederatedSignOutUrl + \"?sid=123\");\n\n        response.StatusCode.Should().Be(HttpStatusCode.Redirect);\n        response.Content.Headers.ContentType.Should().BeNull();\n        var html = await response.Content.ReadAsStringAsync();\n        html.Should().Be(String.Empty);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/Pipeline/SubpathHosting.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel.Client;\nusing IdentityServer.IntegrationTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Test;\nusing Xunit;\n\nnamespace IdentityServer.IntegrationTests.Pipeline;\n\npublic class SubpathHosting\n{\n    private const string Category = \"Subpath endpoint\";\n\n    private IdentityServerPipeline _mockPipeline = new IdentityServerPipeline();\n\n    private Client _client1;\n\n    public SubpathHosting()\n    {\n        _mockPipeline.Clients.AddRange(new Client[] {\n            _client1 = new Client\n            {\n                ClientId = \"client1\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RequireConsent = false,\n                AllowedScopes = new List<string> { \"openid\", \"profile\" },\n                RedirectUris = new List<string> { \"https://client1/callback\" },\n                AllowAccessTokensViaBrowser = true\n            }\n        });\n\n        _mockPipeline.Users.Add(new TestUser\n        {\n            SubjectId = \"bob\",\n            Username = \"bob\",\n            Claims = new Claim[]\n            {\n                new Claim(\"name\", \"Bob Loblaw\"),\n                new Claim(\"email\", \"bob@loblaw.com\"),\n                new Claim(\"role\", \"Attorney\")\n            }\n        });\n\n        _mockPipeline.IdentityScopes.AddRange(new IdentityResource[] {\n            new IdentityResources.OpenId(),\n            new IdentityResources.Profile(),\n            new IdentityResources.Email()\n        });\n        \n        _mockPipeline.Initialize(\"/subpath\");\n    }\n\n    [Fact]\n    [Trait(\"Category\", Category)]\n    public async Task anonymous_user_should_be_redirected_to_login_page()\n    {\n        var url = new RequestUrl(\"https://server/subpath/connect/authorize\").CreateAuthorizeUrl(\n            clientId: \"client1\",\n            responseType: \"id_token\",\n            scope: \"openid\",\n            redirectUri: \"https://client1/callback\",\n            state: \"123_state\",\n            nonce: \"123_nonce\");\n        var response = await _mockPipeline.BrowserClient.GetAsync(url);\n\n        _mockPipeline.LoginWasCalled.Should().BeTrue();\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/identityserver_testing.cer",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDQTCCAimgAwIBAgIQO+9qzaJY9I5Ewq81kNEKWTANBgkqhkiG9w0BAQsFADAh\nMR8wHQYDVQQDDBZpZGVudGl0eXNlcnZlcl90ZXN0aW5nMCAXDTIwMDEyMjIzMTYz\nOFoYDzIxMDMwNTIyMjMyNjM5WjAhMR8wHQYDVQQDDBZpZGVudGl0eXNlcnZlcl90\nZXN0aW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuyZQvE+6gEoB\na+LV3dxjk/Xj4DRJ/tefQKR2AZoYAAfKN4ditFmEfRC1A6rckBpMVihTeb1kwwQT\n7H4HTS6O/ERHVjOdghoOjEsVakWhAkvh8gphC4IU0upXlYqMh2WzgXEXwYRFB9Tk\n7zoHb1/zjEEAhCf2Xbi6YslBoU71bFWyAaeOTl859wV6WaiBIK5L8nJUaIaq4zmC\nk8caPZq5E867mZiMdL4TcW9/YoAAO96Wa/W9o6OiuZrP414TlEjVuccpLXvjk0hB\nU5OZD2bTvD3MQZu1n1QMLwXfaOBrcv1/RqYJkK7vpP6Pp1YYlo7b2PBDVAIrRSVT\nlaViBP0owQIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB\nBQUHAwIGCCsGAQUFBwMBMCEGA1UdEQQaMBiCFmlkZW50aXR5c2VydmVyX3Rlc3Rp\nbmcwHQYDVR0OBBYEFCVXNpKp8QlHywXEBFfpXxWcOMcsMA0GCSqGSIb3DQEBCwUA\nA4IBAQBsEAzwyN6V6N5ggN9G1O0ZpviSjixGkWtySNCBjbGXAhOvfW4M3ysNkDwZ\nltk/Q17ihZzw135MrDCmnr5pRiN4CbEGbe1qsb+Z0uCCn8/WcIVYYooW66H/Jez+\ndg5RxUukA67ZDnjzRskIer7L2t1C4pDqpvPVcneUxkiYDSgcKpTuCVjkPNQKQTIw\nSm98NkQG8G8V8+ENIU837ytkiC5nqQa4zDRHexzWrYhiuayWWxJKcNRVF9YaE8ts\nvp5N1ewmWbSgF8caJuKraVOISj9R4iqf0XuhfSpW/7eIWYmXfqy/UloeqlALfP5C\n2d2FdDSfsQ4Jgc3ebrECAQaCC3Gq\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.IntegrationTests/xunit.runner.json",
    "content": "﻿{\n  \"methodDisplay\":\"classAndMethod\"\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/IAuthenticationSchemeHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal interface IAuthenticationSchemeHandler\n    {\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockAuthenticationHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Http;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class MockAuthenticationHandler : IAuthenticationHandler\n    {\n        public AuthenticateResult Result { get; set; } = AuthenticateResult.NoResult();\n\n        public Task<AuthenticateResult> AuthenticateAsync()\n        {\n            return Task.FromResult(Result);\n        }\n\n        public Task ChallengeAsync(AuthenticationProperties properties)\n        {\n            return Task.CompletedTask;\n        }\n\n        public Task ForbidAsync(AuthenticationProperties properties)\n        {\n            return Task.CompletedTask;\n        }\n\n        public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)\n        {\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockAuthenticationHandlerProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Http;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class MockAuthenticationHandlerProvider : IAuthenticationHandlerProvider\n    {\n        public IAuthenticationHandler Handler { get; set; }\n\n        public Task<IAuthenticationHandler> GetHandlerAsync(HttpContext context, string authenticationScheme)\n        {\n            return Task.FromResult(Handler);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockAuthenticationSchemeProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class MockAuthenticationSchemeProvider : IAuthenticationSchemeProvider\n    {\n        public string Default { get; set; } = \"scheme\";\n        public List<AuthenticationScheme> Schemes { get; set; } = new List<AuthenticationScheme>()\n        {\n            new AuthenticationScheme(\"scheme\", null, typeof(MockAuthenticationHandler))\n        };\n\n        public void AddScheme(AuthenticationScheme scheme)\n        {\n            Schemes.Add(scheme);\n        }\n\n        public Task<IEnumerable<AuthenticationScheme>> GetAllSchemesAsync()\n        {\n            return Task.FromResult(Schemes.AsEnumerable());\n        }\n\n        public Task<AuthenticationScheme> GetDefaultAuthenticateSchemeAsync()\n        {\n            var scheme = Schemes.Where(x => x.Name == Default).FirstOrDefault();\n            return Task.FromResult(scheme);\n        }\n\n        public Task<AuthenticationScheme> GetDefaultChallengeSchemeAsync()\n        {\n            return GetDefaultAuthenticateSchemeAsync();\n        }\n\n        public Task<AuthenticationScheme> GetDefaultForbidSchemeAsync()\n        {\n            return GetDefaultAuthenticateSchemeAsync();\n        }\n\n        public Task<AuthenticationScheme> GetDefaultSignInSchemeAsync()\n        {\n            return GetDefaultAuthenticateSchemeAsync();\n        }\n\n        public Task<AuthenticationScheme> GetDefaultSignOutSchemeAsync()\n        {\n            return GetDefaultAuthenticateSchemeAsync();\n        }\n\n        public Task<IEnumerable<AuthenticationScheme>> GetRequestHandlerSchemesAsync()\n        {\n            return Task.FromResult(Schemes.AsEnumerable());\n        }\n\n        public Task<AuthenticationScheme> GetSchemeAsync(string name)\n        {\n            return Task.FromResult(Schemes.Where(x => x.Name == name).FirstOrDefault());\n        }\n\n        public void RemoveScheme(string name)\n        {\n            var scheme = Schemes.Where(x => x.Name == name).FirstOrDefault();\n            if (scheme != null)\n            {\n                Schemes.Remove(scheme);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockAuthenticationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Http;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class MockAuthenticationService : IAuthenticationService\n    {\n        public AuthenticateResult Result { get; set; }\n\n        public Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme)\n        {\n            return Task.FromResult(Result);\n        }\n\n        public Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)\n        {\n            return Task.CompletedTask;\n        }\n\n        public Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties)\n        {\n            return Task.CompletedTask;\n        }\n\n        public Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)\n        {\n            return Task.CompletedTask;\n        }\n\n        public Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties)\n        {\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockClaimsService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    class MockClaimsService : IClaimsService\n    {\n        public List<Claim> IdentityTokenClaims { get; set; } = new List<Claim>();\n        public List<Claim> AccessTokenClaims { get; set; } = new List<Claim>();\n\n        public Task<IEnumerable<Claim>> GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, ResourceValidationResult resources, bool includeAllIdentityClaims, ValidatedRequest request)\n        {\n            return Task.FromResult(IdentityTokenClaims.AsEnumerable());\n        }\n\n        public Task<IEnumerable<Claim>> GetAccessTokenClaimsAsync(ClaimsPrincipal subject, ResourceValidationResult resources, ValidatedRequest request)\n        {\n            return Task.FromResult(AccessTokenClaims.AsEnumerable());\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockClientSessionService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer.UnitTests.Common\n{\n    //class MockClientSessionService : IClientSessionService\n    //{\n    //    public List<string> Clients = new List<string>();\n\n    //    public bool RemoveCookieWasCalled { get; private set; }\n\n    //    public Task AddClientIdAsync(string clientId)\n    //    {\n    //        Clients.Add(clientId);\n    //        return Task.CompletedTask;\n    //    }\n\n    //    public Task EnsureClientListCookieAsync(string sid)\n    //    {\n    //        return Task.CompletedTask;\n    //    }\n\n    //    public Task<IEnumerable<string>> GetClientListAsync()\n    //    {\n    //        return Task.FromResult<IEnumerable<string>>(Clients);\n    //    }\n\n    //    public IEnumerable<string> GetClientListFromCookie(string sid)\n    //    {\n    //        return Clients;\n    //    }\n\n    //    public void RemoveCookie(string sid)\n    //    {\n    //        RemoveCookieWasCalled = true;\n    //        Clients.Clear();\n    //    }\n    //}\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockConsentMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockConsentMessageStore : IConsentMessageStore\n    {\n        public Dictionary<string, Message<ConsentResponse>> Messages { get; set; } = new Dictionary<string, Message<ConsentResponse>>();\n\n        public Task DeleteAsync(string id)\n        {\n            if (id != null && Messages.ContainsKey(id))\n            {\n                Messages.Remove(id);\n            }\n            return Task.CompletedTask;\n        }\n\n        public Task<Message<ConsentResponse>> ReadAsync(string id)\n        {\n            Message<ConsentResponse> val = null;\n            if (id != null)\n            {\n                Messages.TryGetValue(id, out val);\n            }\n            return Task.FromResult(val);\n        }\n\n        public Task WriteAsync(string id, Message<ConsentResponse> message)\n        {\n            Messages[id] = message;\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockConsentService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockConsentService : IConsentService\n    {\n        public bool RequiresConsentResult { get; set; }\n\n        public Task<bool> RequiresConsentAsync(ClaimsPrincipal subject, Client client, IEnumerable<ParsedScopeValue> parsedScopes)\n        {\n            return Task.FromResult(RequiresConsentResult);\n        }\n\n        public ClaimsPrincipal ConsentSubject { get; set; }\n        public Client ConsentClient { get; set; }\n        public IEnumerable<string> ConsentScopes { get; set; }\n\n        public Task UpdateConsentAsync(ClaimsPrincipal subject, Client client, IEnumerable<ParsedScopeValue> parsedScopes)\n        {\n            ConsentSubject = subject;\n            ConsentClient = client;\n            ConsentScopes = parsedScopes?.Select(x => x.RawValue);\n\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockHttpContextAccessor.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Stores;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class MockHttpContextAccessor : IHttpContextAccessor\n    {\n        private HttpContext _context = new DefaultHttpContext();\n        public MockAuthenticationService AuthenticationService { get; set; } = new MockAuthenticationService();\n\n        public MockAuthenticationSchemeProvider Schemes { get; set; } = new MockAuthenticationSchemeProvider();\n\n        public MockHttpContextAccessor(\n            IdentityServerOptions options = null,\n            IUserSession userSession = null,\n            IMessageStore<LogoutNotificationContext> endSessionStore = null)\n        {\n            options = options ?? TestIdentityServerOptions.Create();\n\n            var services = new ServiceCollection();\n            services.AddSingleton(options);\n\n            services.AddSingleton<IAuthenticationSchemeProvider>(Schemes);\n            services.AddSingleton<IAuthenticationService>(AuthenticationService);\n\n            services.AddAuthentication(auth =>\n            {\n                auth.DefaultAuthenticateScheme = Schemes.Default;\n            });\n\n            if (userSession == null)\n            {\n                services.AddScoped<IUserSession, DefaultUserSession>();\n            }\n            else\n            {\n                services.AddSingleton(userSession);\n            }\n\n            if (endSessionStore == null)\n            {\n                services.AddTransient<IMessageStore<LogoutNotificationContext>, ProtectedDataMessageStore<LogoutNotificationContext>>();\n            }\n            else\n            {\n                services.AddSingleton(endSessionStore);\n            }\n\n            _context.RequestServices = services.BuildServiceProvider();\n        }\n\n        public HttpContext HttpContext\n        {\n            get\n            {\n                return _context;\n            }\n\n            set\n            {\n                _context = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockKeyMaterialService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing Microsoft.IdentityModel.Tokens;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    class MockKeyMaterialService : IKeyMaterialService\n    {\n        public List<SigningCredentials> SigningCredentials = new List<SigningCredentials>();\n        public List<SecurityKeyInfo> ValidationKeys = new List<SecurityKeyInfo>();\n\n        public Task<IEnumerable<SigningCredentials>> GetAllSigningCredentialsAsync()\n        {\n            return Task.FromResult(SigningCredentials.AsEnumerable());\n        }\n\n        public Task<SigningCredentials> GetSigningCredentialsAsync(IEnumerable<string> allowedAlgorithms = null)\n        {\n            return Task.FromResult(SigningCredentials.FirstOrDefault());\n        }\n\n        public Task<IEnumerable<SecurityKeyInfo>> GetValidationKeysAsync()\n        {\n            return Task.FromResult(ValidationKeys.AsEnumerable());\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockLogoutNotificationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockLogoutNotificationService : ILogoutNotificationService\n    {\n        public bool GetFrontChannelLogoutNotificationsUrlsCalled { get; set; }\n        public List<string> FrontChannelLogoutNotificationsUrls { get; set; } = new List<string>();\n\n        public bool SendBackChannelLogoutNotificationsCalled { get; set; }\n        public List<BackChannelLogoutRequest> BackChannelLogoutRequests { get; set; } = new List<BackChannelLogoutRequest>();\n\n        public Task<IEnumerable<string>> GetFrontChannelLogoutNotificationsUrlsAsync(LogoutNotificationContext context)\n        {\n            GetFrontChannelLogoutNotificationsUrlsCalled = true;\n            return Task.FromResult(FrontChannelLogoutNotificationsUrls.AsEnumerable());\n        }\n\n        public Task<IEnumerable<BackChannelLogoutRequest>> GetBackChannelLogoutNotificationsAsync(LogoutNotificationContext context)\n        {\n            SendBackChannelLogoutNotificationsCalled = true;\n            return Task.FromResult(BackChannelLogoutRequests.AsEnumerable());\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockMessageStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockMessageStore<TModel> : IMessageStore<TModel>\n    {\n        public Dictionary<string, Message<TModel>> Messages { get; set; } = new Dictionary<string, Message<TModel>>();\n\n        public Task<Message<TModel>> ReadAsync(string id)\n        {\n            Message<TModel> val = null;\n            if (id != null)\n            {\n                Messages.TryGetValue(id, out val);\n            }\n            return Task.FromResult(val);\n        }\n\n        public Task<string> WriteAsync(Message<TModel> message)\n        {\n            var id = Guid.NewGuid().ToString();\n            Messages[id] = message;\n            return Task.FromResult(id);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockPersistedGrantService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockPersistedGrantService : IPersistedGrantService\n    {\n        public IEnumerable<Grant> GetAllGrantsResult { get; set; }\n        public bool RemoveAllGrantsWasCalled { get; set; }\n\n        public Task<IEnumerable<Grant>> GetAllGrantsAsync(string subjectId)\n        {\n            return Task.FromResult(GetAllGrantsResult ?? Enumerable.Empty<Grant>());\n        }\n\n        public Task RemoveAllGrantsAsync(string subjectId, string clientId, string sessionId = null)\n        {\n            RemoveAllGrantsWasCalled = true;\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockProfileService : IProfileService\n    {\n        public ICollection<Claim> ProfileClaims { get; set; } = new HashSet<Claim>();\n        public bool IsActive { get; set; } = true;\n\n        public bool GetProfileWasCalled => ProfileContext != null;\n        public ProfileDataRequestContext ProfileContext { get; set; }\n\n        public bool IsActiveWasCalled => ActiveContext != null;\n        public IsActiveContext ActiveContext { get; set; }\n\n        public Task GetProfileDataAsync(ProfileDataRequestContext context)\n        {\n            ProfileContext = context;\n            context.IssuedClaims = ProfileClaims.ToList();\n            return Task.CompletedTask;\n        }\n\n        public Task IsActiveAsync(IsActiveContext context)\n        {\n            ActiveContext = context;\n            context.IsActive = IsActive;\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockReferenceTokenStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing System;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    class MockReferenceTokenStore : IReferenceTokenStore\n    {\n        public Task<Token> GetReferenceTokenAsync(string handle)\n        {\n            throw new NotImplementedException();\n        }\n\n        public Task RemoveReferenceTokenAsync(string handle)\n        {\n            throw new NotImplementedException();\n        }\n\n        public Task RemoveReferenceTokensAsync(string subjectId, string clientId)\n        {\n            throw new NotImplementedException();\n        }\n\n        public Task<string> StoreReferenceTokenAsync(Token token)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockResourceValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Validation;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    class MockResourceValidator : IResourceValidator\n    {\n        public ResourceValidationResult Result { get; set; } = new ResourceValidationResult();\n\n        public Task<IEnumerable<ParsedScopeValue>> ParseRequestedScopesAsync(IEnumerable<string> scopeValues)\n        {\n            return Task.FromResult(scopeValues.Select(x => new ParsedScopeValue(x)));\n        }\n\n        public Task<ResourceValidationResult> ValidateRequestedResourcesAsync(ResourceValidationRequest request)\n        {\n            return Task.FromResult(Result);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockReturnUrlParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Linq;\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockReturnUrlParser : ReturnUrlParser\n    {\n        public AuthorizationRequest AuthorizationRequestResult { get; set; }\n        public bool IsValidReturnUrlResult { get; set; }\n\n        public MockReturnUrlParser() : base(Enumerable.Empty<IReturnUrlParser>())\n        {\n        }\n\n        public override Task<AuthorizationRequest> ParseAsync(string returnUrl)\n        {\n            return Task.FromResult(AuthorizationRequestResult);\n        }\n\n        public override bool IsValidReturnUrl(string returnUrl)\n        {\n            return IsValidReturnUrlResult;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockSessionIdService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer.UnitTests.Common\n{\n    //public class MockSessionIdService : ISessionIdService\n    //{\n    //    public bool RemoveCookieWasCalled { get; private set; }\n    //    public string SessionId { get; set; } = \"session_id\";\n\n    //    public void CreateSessionId(SignInContext context)\n    //    {\n    //    }\n\n    //    public Task EnsureSessionCookieAsync()\n    //    {\n    //        return Task.CompletedTask;\n    //    }\n\n    //    public string GetCookieName()\n    //    {\n    //        return \"sessionid\";\n    //    }\n\n    //    public string GetCookieValue()\n    //    {\n    //        return SessionId;\n    //    }\n\n    //    public Task<string> GetCurrentSessionIdAsync()\n    //    {\n    //        return Task.FromResult(SessionId);\n    //    }\n\n    //    public void RemoveCookie()\n    //    {\n    //        RemoveCookieWasCalled = true;\n    //        SessionId = null;\n    //    }\n    //}\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockSystemClock.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.AspNetCore.Authentication;\nusing System;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    class MockSystemClock : ISystemClock\n    {\n        public DateTimeOffset Now { get; set; }\n\n        public DateTimeOffset UtcNow\n        {\n            get\n            {\n                return Now;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockTokenCreationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    class MockTokenCreationService : ITokenCreationService\n    {\n        public string Token { get; set; }\n\n        public Task<string> CreateTokenAsync(Token token)\n        {\n            return Task.FromResult(Token);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/MockUserSession.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer8.Services;\nusing Microsoft.AspNetCore.Authentication;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class MockUserSession : IUserSession\n    {\n        public List<string> Clients = new List<string>();\n\n        public bool EnsureSessionIdCookieWasCalled { get; set; }\n        public bool RemoveSessionIdCookieWasCalled { get; set; }\n        public bool CreateSessionIdWasCalled { get; set; }\n\n        public ClaimsPrincipal User { get; set; }\n        public string SessionId { get; set; }\n        public AuthenticationProperties Properties { get; set; }\n\n\n        public Task<string> CreateSessionIdAsync(ClaimsPrincipal principal, AuthenticationProperties properties)\n        {\n            CreateSessionIdWasCalled = true;\n            User = principal;\n            SessionId = Guid.NewGuid().ToString();\n            return Task.FromResult(SessionId);\n        }\n\n        public Task<ClaimsPrincipal> GetUserAsync()\n        {\n            return Task.FromResult(User);\n        }\n\n        Task<string> IUserSession.GetSessionIdAsync()\n        {\n            return Task.FromResult(SessionId);\n        }\n\n        public Task EnsureSessionIdCookieAsync()\n        {\n            EnsureSessionIdCookieWasCalled = true;\n            return Task.CompletedTask;\n        }\n\n        public Task RemoveSessionIdCookieAsync()\n        {\n            RemoveSessionIdCookieWasCalled = true;\n            return Task.CompletedTask;\n        }\n\n        public Task<IEnumerable<string>> GetClientListAsync()\n        {\n            return Task.FromResult<IEnumerable<string>>(Clients);\n        }\n\n        public Task AddClientIdAsync(string clientId)\n        {\n            Clients.Add(clientId);\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/NetworkHandler.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class NetworkHandler : HttpMessageHandler\n    {\n        enum Behavior\n        {\n            Throw,\n            ReturnError,\n            ReturnDocument\n        }\n\n        private readonly Exception _exception;\n        private readonly Behavior _behavior;\n        private readonly HttpStatusCode _statusCode;\n        private readonly string _reason;\n        private readonly string _document;\n        private readonly Func<HttpRequestMessage, string> _selector;\n        private readonly Func<HttpRequestMessage, HttpResponseMessage> _action;\n\n        public HttpRequestMessage Request { get; set; }\n        public string Body { get; set; }\n\n        public NetworkHandler(Exception exception)\n        {\n            _exception = exception;\n            _behavior = Behavior.Throw;\n        }\n\n        public NetworkHandler(HttpStatusCode statusCode, string reason)\n        {\n            _statusCode = statusCode;\n            _reason = reason;\n\n            _behavior = Behavior.ReturnError;\n        }\n\n        public NetworkHandler(string document, HttpStatusCode statusCode)\n        {\n            _statusCode = statusCode;\n            _document = document;\n            _behavior = Behavior.ReturnDocument;\n        }\n\n        public NetworkHandler(Func<HttpRequestMessage, string> documentSelector, HttpStatusCode statusCode)\n        {\n            _statusCode = statusCode;\n            _selector = documentSelector;\n            _behavior = Behavior.ReturnDocument;\n        }\n\n        public NetworkHandler(Func<HttpRequestMessage, HttpResponseMessage> action)\n        {\n            _action = action;\n        }\n\n        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\n        {\n            Request = request;\n            Body = await SafeReadContentFrom(request);\n\n            if (_action != null)\n            {\n                return _action(request);\n            }\n\n            if (_behavior == Behavior.Throw) throw _exception;\n\n            var response = new HttpResponseMessage(_statusCode);\n\n            if (_behavior == Behavior.ReturnError)\n            {\n                response.ReasonPhrase = _reason;\n            }\n\n            if (_behavior == Behavior.ReturnDocument)\n            {\n                if (_selector != null)\n                {\n                    response.Content = new StringContent(_selector(request));\n                }\n                else\n                {\n                    response.Content = new StringContent(_document);\n                }\n            }\n\n            return response;\n        }\n\n        private async Task<string> SafeReadContentFrom(HttpRequestMessage request)\n        {\n            if (request.Content == null) return null;\n\n            return await request.Content.ReadAsStringAsync();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/StubAuthorizeResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.ResponseHandling;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class StubAuthorizeResponseGenerator : IAuthorizeResponseGenerator\n    {\n        public AuthorizeResponse Response { get; set; } = new AuthorizeResponse();\n\n        public Task<AuthorizeResponse> CreateResponseAsync(ValidatedAuthorizeRequest request)\n        {\n            return Task.FromResult(Response);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/StubClock.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing Microsoft.AspNetCore.Authentication;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class StubClock : ISystemClock\n    {\n        public Func<DateTime> UtcNowFunc = () => DateTime.UtcNow;\n        public DateTimeOffset UtcNow => new DateTimeOffset(UtcNowFunc());\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/StubHandleGenerationService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class StubHandleGenerationService : DefaultHandleGenerationService, IHandleGenerationService\n    {\n        public string Handle { get; set; }\n\n        public new Task<string> GenerateAsync(int length)\n        {\n            if (Handle != null) return Task.FromResult(Handle);\n            return base.GenerateAsync(length);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/TestCert.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO;\nusing System.Security.Cryptography.X509Certificates;\nusing Microsoft.IdentityModel.Tokens;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal static class TestCert\n    {\n        public static X509Certificate2 Load()\n        {\n            var cert = Path.Combine(System.AppContext.BaseDirectory, \"identityserver_testing.pfx\");\n            return new X509Certificate2(cert, \"password\");\n        }\n\n        public static SigningCredentials LoadSigningCredentials()\n        {\n            var cert = Load();\n            return new SigningCredentials(new X509SecurityKey(cert), \"RS256\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/TestEventService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer8.Events;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class TestEventService : IEventService\n    {\n        private Dictionary<Type, object> _events = new Dictionary<Type, object>();\n\n        public Task RaiseAsync(Event evt)\n        {\n            _events.Add(evt.GetType(), evt);\n            return Task.CompletedTask;\n        }\n\n        public T AssertEventWasRaised<T>()\n            where T : class\n        {\n            _events.ContainsKey(typeof(T)).Should().BeTrue();\n            return (T)_events.Where(x => x.Key == typeof(T)).Select(x=>x.Value).First();\n        }\n\n        public bool CanRaiseEventType(EventTypes evtType)\n        {\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/TestExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Linq;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal static class TestExtensions\n    {\n        public static string Repeat(this string value, int count)\n        {\n            var parts = new string[count];\n            return parts.Aggregate((x, y) => (x ?? value) + value);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/TestIdentityServerOptions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Configuration;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    internal class TestIdentityServerOptions\n    {\n        public static IdentityServerOptions Create()\n        {\n            var options = new IdentityServerOptions\n            {\n                IssuerUri = \"https://idsvr.com\"\n            };\n\n            return options;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/TestLogger.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public static class TestLogger\n    {\n        public static ILogger<T> Create<T>()\n        {\n            return new LoggerFactory().CreateLogger<T>();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Common/TestUserConsentStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Stores.Serialization;\n\nnamespace IdentityServer.UnitTests.Common\n{\n    public class TestUserConsentStore : IUserConsentStore\n    {\n        private DefaultUserConsentStore _userConsentStore;\n        private InMemoryPersistedGrantStore _grantStore = new InMemoryPersistedGrantStore();\n\n        public TestUserConsentStore()\n        {\n            _userConsentStore = new DefaultUserConsentStore(\n               _grantStore,\n               new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n               TestLogger.Create<DefaultUserConsentStore>());\n        }\n\n        public Task StoreUserConsentAsync(Consent consent)\n        {\n            return _userConsentStore.StoreUserConsentAsync(consent);\n        }\n\n        public Task<Consent> GetUserConsentAsync(string subjectId, string clientId)\n        {\n            return _userConsentStore.GetUserConsentAsync(subjectId, clientId);\n        }\n\n        public Task RemoveUserConsentAsync(string subjectId, string clientId)\n        {\n            return _userConsentStore.RemoveUserConsentAsync(subjectId, clientId);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Cors/MockCorsPolicyProvider.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Cors.Infrastructure;\nusing Microsoft.AspNetCore.Http;\n\nnamespace IdentityServer.UnitTests.Cors\n{\n    public class MockCorsPolicyProvider : ICorsPolicyProvider\n    {\n        public bool WasCalled { get; set; }\n        public CorsPolicy Response { get; set; }\n\n        public Task<CorsPolicy> GetPolicyAsync(HttpContext context, string policyName)\n        {\n            WasCalled = true;\n            return Task.FromResult(Response);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Cors/MockCorsPolicyService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Cors\n{\n    public class MockCorsPolicyService : ICorsPolicyService\n    {\n        public bool WasCalled { get; set; }\n        public bool Response { get; set; }\n\n        public Task<bool> IsOriginAllowedAsync(string origin)\n        {\n            WasCalled = true;\n            return Task.FromResult(Response);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Cors/PolicyProviderTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Configuration.DependencyInjection;\nusing IdentityServer8.Hosting;\nusing IdentityServer8.Services;\nusing Microsoft.AspNetCore.Cors.Infrastructure;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Cors\n{\n    public class PolicyProviderTests\n    {\n        private const string Category = \"PolicyProvider\";\n\n        private CorsPolicyProvider _subject;\n        private List<string> _allowedPaths = new List<string>();\n\n        private MockCorsPolicyProvider _mockInner = new MockCorsPolicyProvider();\n        private MockCorsPolicyService _mockPolicy = new MockCorsPolicyService();\n        private IdentityServerOptions _options;\n\n        public PolicyProviderTests()\n        {\n            Init();\n        }\n\n        internal void Init()\n        {\n            _options = new IdentityServerOptions();\n            _options.Cors.CorsPaths.Clear();\n            foreach(var path in _allowedPaths)\n            {\n                _options.Cors.CorsPaths.Add(new PathString(path));\n            }\n\n            var ctx = new DefaultHttpContext();\n            var svcs = new ServiceCollection();\n            svcs.AddSingleton<ICorsPolicyService>(_mockPolicy);\n            ctx.RequestServices = svcs.BuildServiceProvider();\n            var ctxAccessor = new HttpContextAccessor();\n            ctxAccessor.HttpContext = ctx;\n\n            _subject = new CorsPolicyProvider(\n                TestLogger.Create<CorsPolicyProvider>(),\n                new Decorator<ICorsPolicyProvider>(_mockInner),\n                _options,\n                ctxAccessor);\n        }\n\n        [Theory]\n        [InlineData(\"/foo\")]\n        [InlineData(\"/bar/\")]\n        [InlineData(\"/baz/quux\")]\n        [InlineData(\"/baz/quux/\")]\n        [Trait(\"Category\", Category)]\n        public async Task valid_paths_should_call_policy_service(string path)\n        {\n            _allowedPaths.AddRange(new string[] {\n                \"/foo\",\n                \"/bar/\",\n                \"/baz/quux\",\n                \"/baz/quux/\"\n            });\n            Init();\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"https\";\n            ctx.Request.Host = new HostString(\"server\");\n            ctx.Request.Path = new PathString(path);\n            ctx.Request.Headers.Append(\"Origin\", \"http://notserver\");\n\n            var response = await _subject.GetPolicyAsync(ctx, _options.Cors.CorsPolicyName);\n\n            _mockPolicy.WasCalled.Should().BeTrue();\n            _mockInner.WasCalled.Should().BeFalse();\n        }\n\n        [Theory]\n        [InlineData(\"/foo/\")]\n        [InlineData(\"/xoxo\")]\n        [InlineData(\"/xoxo/\")]\n        [InlineData(\"/foo/xoxo\")]\n        [InlineData(\"/baz/quux/xoxo\")]\n        [Trait(\"Category\", Category)]\n        public async Task invalid_paths_should_not_call_policy_service(string path)\n        {\n            _allowedPaths.AddRange(new string[] {\n                \"/foo\",\n                \"/bar\",\n                \"/baz/quux\"\n            });\n            Init();\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"https\";\n            ctx.Request.Host = new HostString(\"server\");\n            ctx.Request.Path = new PathString(path);\n            ctx.Request.Headers.Append(\"Origin\", \"http://notserver\");\n\n            var response = await _subject.GetPolicyAsync(ctx, _options.Cors.CorsPolicyName);\n\n            _mockPolicy.WasCalled.Should().BeFalse();\n            _mockInner.WasCalled.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task different_policy_name_should_call_inner_policy_service()\n        {\n            _allowedPaths.AddRange(new string[] {\n                \"/foo\",\n                \"/bar\",\n                \"/baz/quux\"\n            });\n            Init();\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"https\";\n            ctx.Request.Host = new HostString(\"server\");\n            ctx.Request.Path = new PathString(\"/foo\");\n            ctx.Request.Headers.Append(\"Origin\", \"http://notserver\");\n\n            var response = await _subject.GetPolicyAsync(ctx, \"wrong_name\");\n\n            _mockPolicy.WasCalled.Should().BeFalse();\n            _mockInner.WasCalled.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task origin_same_as_server_should_not_call_policy()\n        {\n            _allowedPaths.AddRange(new string[] {\n                \"/foo\"\n            });\n            Init();\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"https\";\n            ctx.Request.Host = new HostString(\"server\");\n            ctx.Request.Path = new PathString(\"/foo\");\n            ctx.Request.Headers.Append(\"Origin\", \"https://server\");\n\n            var response = await _subject.GetPolicyAsync(ctx, _options.Cors.CorsPolicyName);\n\n            _mockPolicy.WasCalled.Should().BeFalse();\n            _mockInner.WasCalled.Should().BeFalse();\n        }\n\n        [Theory]\n        [InlineData(\"https://notserver\")]\n        [InlineData(\"http://server\")]\n        [Trait(\"Category\", Category)]\n        public async Task origin_not_same_as_server_should_call_policy(string origin)\n        {\n            _allowedPaths.AddRange(new string[] {\n                \"/foo\"\n            });\n            Init();\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"https\";\n            ctx.Request.Host = new HostString(\"server\");\n            ctx.Request.Path = new PathString(\"/foo\");\n            ctx.Request.Headers.Append(\"Origin\", origin);\n\n            var response = await _subject.GetPolicyAsync(ctx, _options.Cors.CorsPolicyName);\n\n            _mockPolicy.WasCalled.Should().BeTrue();\n            _mockInner.WasCalled.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Authorize/AuthorizeCallbackEndpointTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.Authorize\n{\n    public class AuthorizeCallbackEndpointTests\n    {\n        private const string Category = \"Authorize Endpoint\";\n\n        private HttpContext _context;\n\n        private TestEventService _fakeEventService = new TestEventService();\n\n        private ILogger<AuthorizeCallbackEndpoint> _fakeLogger = TestLogger.Create<AuthorizeCallbackEndpoint>();\n\n        private IdentityServerOptions _options = new IdentityServerOptions();\n\n        private MockConsentMessageStore _mockUserConsentResponseMessageStore = new MockConsentMessageStore();\n\n        private MockUserSession _mockUserSession = new MockUserSession();\n\n        private NameValueCollection _params = new NameValueCollection();\n\n        private StubAuthorizeRequestValidator _stubAuthorizeRequestValidator = new StubAuthorizeRequestValidator();\n\n        private StubAuthorizeResponseGenerator _stubAuthorizeResponseGenerator = new StubAuthorizeResponseGenerator();\n\n        private StubAuthorizeInteractionResponseGenerator _stubInteractionGenerator = new StubAuthorizeInteractionResponseGenerator();\n\n        private AuthorizeCallbackEndpoint _subject;\n\n        private ClaimsPrincipal _user = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n        private ValidatedAuthorizeRequest _validatedAuthorizeRequest;\n\n        public AuthorizeCallbackEndpointTests()\n        {\n            Init();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_authorize_after_consent_path_should_return_authorization_result()\n        {\n            var parameters = new NameValueCollection()\n            {\n                { \"client_id\", \"client\" },\n                { \"nonce\", \"some_nonce\" },\n                { \"scope\", \"api1 api2\" }\n            };\n            var request = new ConsentRequest(parameters, _user.GetSubjectId());\n            _mockUserConsentResponseMessageStore.Messages.Add(request.Id, new Message<ConsentResponse>(new ConsentResponse()));\n\n            _mockUserSession.User = _user;\n\n            _context.Request.Method = \"GET\";\n            _context.Request.Path = new PathString(\"/connect/authorize/callback\");\n            _context.Request.QueryString = new QueryString(\"?\" + parameters.ToQueryString());\n\n            var result = await _subject.ProcessAsync(_context);\n\n            result.Should().BeOfType<AuthorizeResult>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_authorize_after_login_path_should_return_authorization_result()\n        {\n            _context.Request.Method = \"GET\";\n            _context.Request.Path = new PathString(\"/connect/authorize/callback\");\n            _mockUserSession.User = _user;\n\n            var result = await _subject.ProcessAsync(_context);\n\n            result.Should().BeOfType<AuthorizeResult>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_consent_missing_consent_data_should_return_error_page()\n        {\n            var parameters = new NameValueCollection()\n            {\n                { \"client_id\", \"client\" },\n                { \"nonce\", \"some_nonce\" },\n                { \"scope\", \"api1 api2\" }\n            };\n            var request = new ConsentRequest(parameters, _user.GetSubjectId());\n            _mockUserConsentResponseMessageStore.Messages.Add(request.Id, new Message<ConsentResponse>(null));\n\n            _mockUserSession.User = _user;\n\n            _context.Request.Method = \"GET\";\n            _context.Request.Path = new PathString(\"/connect/authorize/callback\");\n            _context.Request.QueryString = new QueryString(\"?\" + parameters.ToQueryString());\n\n            var result = await _subject.ProcessAsync(_context);\n\n            result.Should().BeOfType<AuthorizeResult>();\n            ((AuthorizeResult)result).Response.IsError.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_no_consent_message_should_return_redirect_for_consent()\n        {\n            _stubInteractionGenerator.Response.IsConsent = true;\n\n            var parameters = new NameValueCollection()\n            {\n                { \"client_id\", \"client\" },\n                { \"nonce\", \"some_nonce\" },\n                { \"scope\", \"api1 api2\" }\n            };\n            var request = new ConsentRequest(parameters, _user.GetSubjectId());\n            _mockUserConsentResponseMessageStore.Messages.Add(request.Id, null);\n\n            _mockUserSession.User = _user;\n\n            _context.Request.Method = \"GET\";\n            _context.Request.Path = new PathString(\"/connect/authorize/callback\");\n            _context.Request.QueryString = new QueryString(\"?\" + parameters.ToQueryString());\n\n            var result = await _subject.ProcessAsync(_context);\n\n            result.Should().BeOfType<ConsentPageResult>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_post_to_entry_point_should_return_405()\n        {\n            _context.Request.Method = \"POST\";\n\n            var result = await _subject.ProcessAsync(_context);\n\n            var statusCode = result as StatusCodeResult;\n            statusCode.Should().NotBeNull();\n            statusCode.StatusCode.Should().Be(405);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_valid_consent_message_should_cleanup_consent_cookie()\n        {\n            var parameters = new NameValueCollection()\n            {\n                { \"client_id\", \"client\" },\n                { \"nonce\", \"some_nonce\" },\n                { \"scope\", \"api1 api2\" }\n            };\n            var request = new ConsentRequest(parameters, _user.GetSubjectId());\n            _mockUserConsentResponseMessageStore.Messages.Add(request.Id, new Message<ConsentResponse>(new ConsentResponse() { ScopesValuesConsented = new string[] { \"api1\", \"api2\" } }));\n\n            _mockUserSession.User = _user;\n\n            _context.Request.Method = \"GET\";\n            _context.Request.Path = new PathString(\"/connect/authorize/callback\");\n            _context.Request.QueryString = new QueryString(\"?\" + parameters.ToQueryString());\n\n            var result = await _subject.ProcessAsync(_context);\n\n            _mockUserConsentResponseMessageStore.Messages.Count.Should().Be(0);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_valid_consent_message_should_return_authorize_result()\n        {\n            var parameters = new NameValueCollection()\n            {\n                { \"client_id\", \"client\" },\n                { \"nonce\", \"some_nonce\" },\n                { \"scope\", \"api1 api2\" }\n            };\n            var request = new ConsentRequest(parameters, _user.GetSubjectId());\n            _mockUserConsentResponseMessageStore.Messages.Add(request.Id, new Message<ConsentResponse>(new ConsentResponse() { ScopesValuesConsented = new string[] { \"api1\", \"api2\" } }));\n\n            _mockUserSession.User = _user;\n\n            _context.Request.Method = \"GET\";\n            _context.Request.Path = new PathString(\"/connect/authorize/callback\");\n            _context.Request.QueryString = new QueryString(\"?\" + parameters.ToQueryString());\n\n            var result = await _subject.ProcessAsync(_context);\n\n            result.Should().BeOfType<AuthorizeResult>();\n        }\n\n        internal void Init()\n        {\n            _context = new MockHttpContextAccessor().HttpContext;\n\n            _validatedAuthorizeRequest = new ValidatedAuthorizeRequest()\n            {\n                RedirectUri = \"http://client/callback\",\n                State = \"123\",\n                ResponseMode = \"fragment\",\n                ClientId = \"client\",\n                Client = new Client\n                {\n                    ClientId = \"client\",\n                    ClientName = \"Test Client\"\n                },\n                Raw = _params,\n                Subject = _user\n            };\n            _stubAuthorizeResponseGenerator.Response.Request = _validatedAuthorizeRequest;\n\n            _stubAuthorizeRequestValidator.Result = new AuthorizeRequestValidationResult(_validatedAuthorizeRequest);\n\n            _subject = new AuthorizeCallbackEndpoint(\n                _fakeEventService,\n                _fakeLogger,\n                _options,\n                _stubAuthorizeRequestValidator,\n                _stubInteractionGenerator,\n                _stubAuthorizeResponseGenerator,\n                _mockUserSession,\n                _mockUserConsentResponseMessageStore);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Authorize/AuthorizeEndpointBaseTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Hosting;\nusing IdentityServer8.Models;\nusing IdentityServer8.ResponseHandling;\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.Authorize\n{\n    public class AuthorizeEndpointBaseTests\n    {\n        private const string Category = \"Authorize Endpoint\";\n\n        private HttpContext _context;\n\n        private TestEventService _fakeEventService = new TestEventService();\n\n        private ILogger<TestAuthorizeEndpoint> _fakeLogger = TestLogger.Create<TestAuthorizeEndpoint>();\n\n        private IdentityServerOptions _options = new IdentityServerOptions();\n\n        private MockUserSession _mockUserSession = new MockUserSession();\n\n        private NameValueCollection _params = new NameValueCollection();\n\n        private StubAuthorizeRequestValidator _stubAuthorizeRequestValidator = new StubAuthorizeRequestValidator();\n\n        private StubAuthorizeResponseGenerator _stubAuthorizeResponseGenerator = new StubAuthorizeResponseGenerator();\n\n        private StubAuthorizeInteractionResponseGenerator _stubInteractionGenerator = new StubAuthorizeInteractionResponseGenerator();\n\n        private TestAuthorizeEndpoint _subject;\n\n        private ClaimsPrincipal _user = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n        private ValidatedAuthorizeRequest _validatedAuthorizeRequest;\n\n        public AuthorizeEndpointBaseTests()\n        {\n            Init();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task error_resurect_with_prompt_none_should_include_session_state_in_response()\n        {\n            _params.Add(\"prompt\", \"none\");\n            _stubAuthorizeRequestValidator.Result.ValidatedRequest.IsOpenIdRequest = true;\n            _stubAuthorizeRequestValidator.Result.ValidatedRequest.ClientId = \"client\";\n            _stubAuthorizeRequestValidator.Result.ValidatedRequest.SessionId = \"some_session\";\n            _stubAuthorizeRequestValidator.Result.ValidatedRequest.RedirectUri = \"http://redirect\";\n            _stubAuthorizeRequestValidator.Result.IsError = true;\n            _stubAuthorizeRequestValidator.Result.Error = \"login_required\";\n\n            var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n            result.Should().BeOfType<AuthorizeResult>();\n            ((AuthorizeResult)result).Response.IsError.Should().BeTrue();\n            ((AuthorizeResult)result).Response.SessionState.Should().NotBeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task authorize_request_validation_produces_error_should_display_error_page()\n        {\n            _stubAuthorizeRequestValidator.Result.IsError = true;\n            _stubAuthorizeRequestValidator.Result.Error = \"some_error\";\n\n            var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n            result.Should().BeOfType<AuthorizeResult>();\n            ((AuthorizeResult)result).Response.IsError.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task interaction_generator_consent_produces_consent_should_show_consent_page()\n        {\n            _stubInteractionGenerator.Response.IsConsent = true;\n\n            var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n            result.Should().BeOfType<ConsentPageResult>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task interaction_produces_error_should_show_error_page()\n        {\n            _stubInteractionGenerator.Response.Error = \"error\";\n\n            var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n            result.Should().BeOfType<AuthorizeResult>();\n            ((AuthorizeResult)result).Response.IsError.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task interaction_produces_error_should_show_error_page_with_error_description_if_present()\n        {\n            var errorDescription = \"some error description\";\n\n             _stubInteractionGenerator.Response.Error = \"error\";\n            _stubInteractionGenerator.Response.ErrorDescription = errorDescription;\n\n             var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n             result.Should().BeOfType<AuthorizeResult>();\n            var authorizeResult = ((AuthorizeResult)result);\n            authorizeResult.Response.IsError.Should().BeTrue();\n            authorizeResult.Response.ErrorDescription.Should().Be(errorDescription);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task interaction_produces_login_result_should_trigger_login()\n        {\n            _stubInteractionGenerator.Response.IsLogin = true;\n\n            var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n            result.Should().BeOfType<LoginPageResult>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAuthorizeRequestAsync_custom_interaction_redirect_result_should_issue_redirect()\n        {\n            _mockUserSession.User = _user;\n            _stubInteractionGenerator.Response.RedirectUrl = \"http://foo.com\";\n\n            var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n            result.Should().BeOfType<CustomRedirectResult>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task successful_authorization_request_should_generate_authorize_result()\n        {\n            var result = await _subject.ProcessAuthorizeRequestAsync(_params, _user, null);\n\n            result.Should().BeOfType<AuthorizeResult>();\n        }\n\n        internal void Init()\n        {\n            _context = new MockHttpContextAccessor().HttpContext;\n\n            _validatedAuthorizeRequest = new ValidatedAuthorizeRequest()\n            {\n                RedirectUri = \"http://client/callback\",\n                State = \"123\",\n                ResponseMode = \"fragment\",\n                ClientId = \"client\",\n                Client = new Client\n                {\n                    ClientId = \"client\",\n                    ClientName = \"Test Client\"\n                },\n                Raw = _params,\n                Subject = _user\n            };\n            _stubAuthorizeResponseGenerator.Response.Request = _validatedAuthorizeRequest;\n\n            _stubAuthorizeRequestValidator.Result = new AuthorizeRequestValidationResult(_validatedAuthorizeRequest);\n\n            _subject = new TestAuthorizeEndpoint(\n                _fakeEventService,\n                _fakeLogger,\n                _options,\n                _stubAuthorizeRequestValidator,\n                _stubInteractionGenerator,\n                _stubAuthorizeResponseGenerator,\n                _mockUserSession);\n        }\n\n        internal class TestAuthorizeEndpoint : AuthorizeEndpointBase\n        {\n            public TestAuthorizeEndpoint(\n              IEventService events,\n              ILogger<TestAuthorizeEndpoint> logger,\n              IdentityServerOptions options,\n              IAuthorizeRequestValidator validator,\n              IAuthorizeInteractionResponseGenerator interactionGenerator,\n              IAuthorizeResponseGenerator authorizeResponseGenerator,\n              IUserSession userSession)\n            : base(events, logger, options, validator, interactionGenerator, authorizeResponseGenerator, userSession)\n            {\n            }\n\n            public override Task<IEndpointResult> ProcessAsync(HttpContext context)\n            {\n                throw new System.NotImplementedException();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Authorize/AuthorizeEndpointTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.Authorize\n{\n    public class AuthorizeEndpointTests\n    {\n        private const string Category = \"Authorize Endpoint\";\n\n        private HttpContext _context;\n\n        private TestEventService _fakeEventService = new TestEventService();\n\n        private ILogger<AuthorizeEndpoint> _fakeLogger = TestLogger.Create<AuthorizeEndpoint>();\n\n        private IdentityServerOptions _options = new IdentityServerOptions();\n\n        private MockUserSession _mockUserSession = new MockUserSession();\n\n        private NameValueCollection _params = new NameValueCollection();\n\n        private StubAuthorizeRequestValidator _stubAuthorizeRequestValidator = new StubAuthorizeRequestValidator();\n\n        private StubAuthorizeResponseGenerator _stubAuthorizeResponseGenerator = new StubAuthorizeResponseGenerator();\n\n        private StubAuthorizeInteractionResponseGenerator _stubInteractionGenerator = new StubAuthorizeInteractionResponseGenerator();\n\n        private AuthorizeEndpoint _subject;\n\n        private ClaimsPrincipal _user = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n        private ValidatedAuthorizeRequest _validatedAuthorizeRequest;\n\n        public AuthorizeEndpointTests()\n        {\n            Init();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_authorize_path_should_return_authorization_result()\n        {\n            _context.Request.Method = \"GET\";\n            _context.Request.Path = new PathString(\"/connect/authorize\");\n            _mockUserSession.User = _user;\n\n            var result = await _subject.ProcessAsync(_context);\n\n            result.Should().BeOfType<AuthorizeResult>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ProcessAsync_post_without_form_content_type_should_return_415()\n        {\n            _context.Request.Method = \"POST\";\n\n            var result = await _subject.ProcessAsync(_context);\n\n            var statusCode = result as StatusCodeResult;\n            statusCode.Should().NotBeNull();\n            statusCode.StatusCode.Should().Be(415);\n        }\n\n        internal void Init()\n        {\n            _context = new MockHttpContextAccessor().HttpContext;\n\n            _validatedAuthorizeRequest = new ValidatedAuthorizeRequest()\n            {\n                RedirectUri = \"http://client/callback\",\n                State = \"123\",\n                ResponseMode = \"fragment\",\n                ClientId = \"client\",\n                Client = new Client\n                {\n                    ClientId = \"client\",\n                    ClientName = \"Test Client\"\n                },\n                Raw = _params,\n                Subject = _user\n            };\n            _stubAuthorizeResponseGenerator.Response.Request = _validatedAuthorizeRequest;\n\n            _stubAuthorizeRequestValidator.Result = new AuthorizeRequestValidationResult(_validatedAuthorizeRequest);\n\n            _subject = new AuthorizeEndpoint(\n                _fakeEventService,\n                _fakeLogger,\n                _options,\n                _stubAuthorizeRequestValidator,\n                _stubInteractionGenerator,\n                _stubAuthorizeResponseGenerator,\n                _mockUserSession);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Authorize/StubAuthorizeInteractionResponseGenerator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.ResponseHandling;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Endpoints.Authorize\n{\n    internal class StubAuthorizeInteractionResponseGenerator : IAuthorizeInteractionResponseGenerator\n    {\n        internal InteractionResponse Response { get; set; } = new InteractionResponse();\n\n        public Task<InteractionResponse> ProcessInteractionAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)\n        {\n            return Task.FromResult(Response);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Authorize/StubAuthorizeRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Endpoints.Authorize\n{\n    public class StubAuthorizeRequestValidator : IAuthorizeRequestValidator\n    {\n        public AuthorizeRequestValidationResult Result { get; set; }\n\n        public Task<AuthorizeRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject = null)\n        {\n            return Task.FromResult(Result);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/EndSession/EndSessionCallbackEndpointTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Endpoints;\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer.UnitTests.Endpoints.EndSession\n{\n    public class EndSessionCallbackEndpointTests\n    {\n        private const string Category = \"End Session Callback Endpoint\";\n\n        StubEndSessionRequestValidator _stubEndSessionRequestValidator = new StubEndSessionRequestValidator();\n        EndSessionCallbackEndpoint _subject;\n\n        public EndSessionCallbackEndpointTests()\n        {\n            _subject = new EndSessionCallbackEndpoint(\n                _stubEndSessionRequestValidator,\n                new LoggerFactory().CreateLogger<EndSessionCallbackEndpoint>());\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/EndSession/EndSessionCallbackResultTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.EndSession\n{\n    public class EndSessionCallbackResultTests\n    {\n        private const string Category = \"End Session Callback Result\";\n\n        private readonly EndSessionCallbackValidationResult _validationResult;\n        private readonly IdentityServerOptions _options;\n        private readonly EndSessionCallbackResult _subject;\n\n        public EndSessionCallbackResultTests()\n        {\n            _validationResult = new EndSessionCallbackValidationResult()\n            {\n                IsError = false,\n            };\n            _options = new IdentityServerOptions();\n            _subject = new EndSessionCallbackResult(_validationResult, _options);\n        }\n\n        [Fact]\n        public async Task default_options_should_emit_frame_src_csp_headers()\n        {\n            _validationResult.FrontChannelLogoutUrls = new[] { \"http://foo\" };\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"GET\";\n\n            await _subject.ExecuteAsync(ctx);\n\n            ctx.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"frame-src http://foo\");\n        }\n\n        [Fact]\n        public async Task relax_csp_options_should_prevent_frame_src_csp_headers()\n        {\n            _options.Authentication.RequireCspFrameSrcForSignout = false;\n            _validationResult.FrontChannelLogoutUrls = new[] { \"http://foo\" };\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"GET\";\n\n            await _subject.ExecuteAsync(ctx);\n\n            ctx.Response.Headers[\"Content-Security-Policy\"].FirstOrDefault().Should().BeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/EndSession/StubBackChannelLogoutClient.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Endpoints.EndSession\n{\n    internal class StubBackChannelLogoutClient : IBackChannelLogoutService\n    {\n        public bool SendLogoutsWasCalled { get; set; }\n\n        public Task SendLogoutNotificationsAsync(LogoutNotificationContext context)\n        {\n            SendLogoutsWasCalled = true;\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/EndSession/StubEndSessionRequestValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Endpoints.EndSession\n{\n    class StubEndSessionRequestValidator : IEndSessionRequestValidator\n    {\n        public EndSessionValidationResult EndSessionValidationResult { get; set; } = new EndSessionValidationResult();\n        public EndSessionCallbackValidationResult EndSessionCallbackValidationResult { get; set; } = new EndSessionCallbackValidationResult();\n\n        public Task<EndSessionValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject)\n        {\n            return Task.FromResult(EndSessionValidationResult);\n        }\n\n        public Task<EndSessionCallbackValidationResult> ValidateCallbackAsync(NameValueCollection parameters)\n        {\n            return Task.FromResult(EndSessionCallbackValidationResult);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Results/AuthorizeResultTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.ResponseHandling;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.WebUtilities;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.Results\n{\n    public class AuthorizeResultTests\n    {\n        private AuthorizeResult _subject;\n\n        private AuthorizeResponse _response = new AuthorizeResponse();\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private MockUserSession _mockUserSession = new MockUserSession();\n        private MockMessageStore<IdentityServer8.Models.ErrorMessage> _mockErrorMessageStore = new MockMessageStore<IdentityServer8.Models.ErrorMessage>();\n\n        private DefaultHttpContext _context = new DefaultHttpContext();\n\n        public AuthorizeResultTests()\n        {\n            _context.SetIdentityServerOrigin(\"https://server\");\n            _context.SetIdentityServerBasePath(\"/\");\n            _context.Response.Body = new MemoryStream();\n\n            _options.UserInteraction.ErrorUrl = \"~/error\";\n            _options.UserInteraction.ErrorIdParameter = \"errorId\";\n\n            _subject = new AuthorizeResult(_response, _options, _mockUserSession, _mockErrorMessageStore, new StubClock());\n        }\n\n        [Fact]\n        public async Task error_should_redirect_to_error_page_and_passs_info()\n        {\n            _response.Error = \"some_error\";\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockErrorMessageStore.Messages.Count.Should().Be(1);\n            _context.Response.StatusCode.Should().Be(302);\n            var location = _context.Response.Headers[\"Location\"].First();\n            location.Should().StartWith(\"https://server/error\");\n            var query = QueryHelpers.ParseQuery(new Uri(location).Query);\n            query[\"errorId\"].First().Should().Be(_mockErrorMessageStore.Messages.First().Key);\n        }\n\n        [Theory]\n        [InlineData(OidcConstants.AuthorizeErrors.AccountSelectionRequired)]\n        [InlineData(OidcConstants.AuthorizeErrors.LoginRequired)]\n        [InlineData(OidcConstants.AuthorizeErrors.ConsentRequired)]\n        [InlineData(OidcConstants.AuthorizeErrors.InteractionRequired)]\n        public async Task prompt_none_errors_should_return_to_client(string error)\n        {\n            _response.Error = error;\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ResponseMode = OidcConstants.ResponseModes.Query,\n                RedirectUri = \"http://client/callback\",\n                PromptModes = new[] { \"none\" }\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockUserSession.Clients.Count.Should().Be(0);\n            _context.Response.StatusCode.Should().Be(302);\n            var location = _context.Response.Headers[\"Location\"].First();\n            location.Should().StartWith(\"http://client/callback\");\n        }\n\n        [Theory]\n        [InlineData(OidcConstants.AuthorizeErrors.AccountSelectionRequired)]\n        [InlineData(OidcConstants.AuthorizeErrors.LoginRequired)]\n        [InlineData(OidcConstants.AuthorizeErrors.ConsentRequired)]\n        [InlineData(OidcConstants.AuthorizeErrors.InteractionRequired)]\n        public async Task prompt_none_errors_for_anonymous_users_should_include_session_state(string error)\n        {\n            _response.Error = error;\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ResponseMode = OidcConstants.ResponseModes.Query,\n                RedirectUri = \"http://client/callback\",\n                PromptModes = new[] { \"none\" },\n            };\n            _response.SessionState = \"some_session_state\";\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockUserSession.Clients.Count.Should().Be(0);\n            _context.Response.StatusCode.Should().Be(302);\n            var location = _context.Response.Headers[\"Location\"].First();\n            location.Should().Contain(\"session_state=some_session_state\");\n        }\n\n        [Fact]\n        public async Task access_denied_should_return_to_client()\n        {\n            const string errorDescription = \"some error description\";\n\n            _response.Error = OidcConstants.AuthorizeErrors.AccessDenied;\n            _response.ErrorDescription = errorDescription;\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ResponseMode = OidcConstants.ResponseModes.Query,\n                RedirectUri = \"http://client/callback\"\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockUserSession.Clients.Count.Should().Be(0);\n            _context.Response.StatusCode.Should().Be(302);\n            var location = _context.Response.Headers[\"Location\"].First();\n            location.Should().StartWith(\"http://client/callback\");\n\n            var queryString = new Uri(location).Query;\n            var queryParams = QueryHelpers.ParseQuery(queryString);\n\n            queryParams[\"error\"].Should().Equal(OidcConstants.AuthorizeErrors.AccessDenied);\n            queryParams[\"error_description\"].Should().Equal(errorDescription);\n        }\n\n        [Fact]\n        public async Task success_should_add_client_to_client_list()\n        {\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"client\",\n                ResponseMode = OidcConstants.ResponseModes.Query,\n                RedirectUri = \"http://client/callback\"\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockUserSession.Clients.Should().Contain(\"client\");\n        }\n\n        [Fact]\n        public async Task query_mode_should_pass_results_in_query()\n        {\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"client\",\n                ResponseMode = OidcConstants.ResponseModes.Query,\n                RedirectUri = \"http://client/callback\",\n                State = \"state\"\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.StatusCode.Should().Be(302);\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-store\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-cache\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"max-age=0\");\n            var location = _context.Response.Headers[\"Location\"].First();\n            location.Should().StartWith(\"http://client/callback\");\n            location.Should().Contain(\"?state=state\");\n        }\n\n        [Fact]\n        public async Task fragment_mode_should_pass_results_in_fragment()\n        {\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"client\",\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                RedirectUri = \"http://client/callback\",\n                State = \"state\"\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.StatusCode.Should().Be(302);\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-store\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-cache\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"max-age=0\");\n            var location = _context.Response.Headers[\"Location\"].First();\n            location.Should().StartWith(\"http://client/callback\");\n            location.Should().Contain(\"#state=state\");\n        }\n\n        [Fact]\n        public async Task form_post_mode_should_pass_results_in_body()\n        {\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"client\",\n                ResponseMode = OidcConstants.ResponseModes.FormPost,\n                RedirectUri = \"http://client/callback\",\n                State = \"state\"\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.StatusCode.Should().Be(200);\n            _context.Response.ContentType.Should().StartWith(\"text/html\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-store\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-cache\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"max-age=0\");\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"default-src 'none';\");\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"script-src 'sha256-orD0/VhH8hLqrLxKHD/HUEMdwqX6/0ve7c5hspX5VJ8='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"default-src 'none';\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"script-src 'sha256-orD0/VhH8hLqrLxKHD/HUEMdwqX6/0ve7c5hspX5VJ8='\");\n            _context.Response.Body.Seek(0, SeekOrigin.Begin);\n            using (var rdr = new StreamReader(_context.Response.Body))\n            {\n                var html = rdr.ReadToEnd();\n                html.Should().Contain(\"<base target='_self'/>\");\n                html.Should().Contain(\"<form method='post' action='http://client/callback'>\");\n                html.Should().Contain(\"<input type='hidden' name='state' value='state' />\");\n            }\n        }\n\n        [Fact]\n        public async Task form_post_mode_should_add_unsafe_inline_for_csp_level_1()\n        {\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"client\",\n                ResponseMode = OidcConstants.ResponseModes.FormPost,\n                RedirectUri = \"http://client/callback\",\n                State = \"state\"\n            };\n\n            _options.Csp.Level = CspLevel.One;\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"script-src 'unsafe-inline' 'sha256-orD0/VhH8hLqrLxKHD/HUEMdwqX6/0ve7c5hspX5VJ8='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"script-src 'unsafe-inline' 'sha256-orD0/VhH8hLqrLxKHD/HUEMdwqX6/0ve7c5hspX5VJ8='\");\n        }\n\n        [Fact]\n        public async Task form_post_mode_should_not_add_deprecated_header_when_it_is_disabled()\n        {\n            _response.Request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"client\",\n                ResponseMode = OidcConstants.ResponseModes.FormPost,\n                RedirectUri = \"http://client/callback\",\n                State = \"state\"\n            };\n\n            _options.Csp.AddDeprecatedHeader = false;\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"script-src 'sha256-orD0/VhH8hLqrLxKHD/HUEMdwqX6/0ve7c5hspX5VJ8='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].Should().BeEmpty();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Results/CheckSessionResultTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.Results\n{\n    public class CheckSessionResultTests\n    {\n        private CheckSessionResult _subject;\n\n        private IdentityServerOptions _options = new IdentityServerOptions();\n\n        private DefaultHttpContext _context = new DefaultHttpContext();\n\n        public CheckSessionResultTests()\n        {\n            _context.SetIdentityServerOrigin(\"https://server\");\n            _context.SetIdentityServerBasePath(\"/\");\n            _context.Response.Body = new MemoryStream();\n\n            _options.Authentication.CheckSessionCookieName = \"foobar\";\n\n            _subject = new CheckSessionResult(_options);\n        }\n\n        [Fact]\n        public async Task should_pass_results_in_body()\n        {\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.StatusCode.Should().Be(200);\n            _context.Response.ContentType.Should().StartWith(\"text/html\");\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"default-src 'none';\");\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"script-src 'sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"default-src 'none';\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"script-src 'sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI='\");\n            _context.Response.Body.Seek(0, SeekOrigin.Begin);\n            using (var rdr = new StreamReader(_context.Response.Body))\n            {\n                var html = rdr.ReadToEnd();\n                html.Should().Contain(\"<script id='cookie-name' type='application/json'>foobar</script>\");\n            }\n        }\n\n        [Fact]\n        public async Task form_post_mode_should_add_unsafe_inline_for_csp_level_1()\n        {\n            _options.Csp.Level = CspLevel.One;\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"script-src 'unsafe-inline' 'sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"script-src 'unsafe-inline' 'sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI='\");\n        }\n\n        [Fact]\n        public async Task form_post_mode_should_not_add_deprecated_header_when_it_is_disabled()\n        {\n            _options.Csp.AddDeprecatedHeader = false;\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"script-src 'sha256-fa5rxHhZ799izGRP38+h4ud5QXNT0SFaFlh4eqDumBI='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].Should().BeEmpty();\n        }\n\n        [Theory]\n        [InlineData(\"foobar\")]\n        [InlineData(\"morefoobar\")]\n\n        public async Task can_change_cached_cookiename(string cookieName)\n        {\n            _options.Authentication.CheckSessionCookieName = cookieName;\n            await _subject.ExecuteAsync(_context);\n            _context.Response.Body.Seek(0, SeekOrigin.Begin);\n            using (var rdr = new StreamReader(_context.Response.Body))\n            {\n                var html = rdr.ReadToEnd();\n                html.Should().Contain($\"<script id='cookie-name' type='application/json'>{cookieName}</script>\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Results/EndSessionCallbackResultTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.Results\n{\n    public class EndSessionCallbackResultTests\n    {\n        private EndSessionCallbackResult _subject;\n\n        private EndSessionCallbackValidationResult _result = new EndSessionCallbackValidationResult();\n        private IdentityServerOptions _options = TestIdentityServerOptions.Create();\n\n        private DefaultHttpContext _context = new DefaultHttpContext();\n\n        public EndSessionCallbackResultTests()\n        {\n            _context.SetIdentityServerOrigin(\"https://server\");\n            _context.SetIdentityServerBasePath(\"/\");\n            _context.Response.Body = new MemoryStream();\n\n            _subject = new EndSessionCallbackResult(_result, _options);\n        }\n\n        [Fact]\n        public async Task error_should_return_400()\n        {\n            _result.IsError = true;\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.StatusCode.Should().Be(400);\n        }\n\n        [Fact]\n        public async Task success_should_render_html_and_iframes()\n        {\n            _result.IsError = false;\n            _result.FrontChannelLogoutUrls = new string[] { \"http://foo.com\", \"http://bar.com\" };\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.ContentType.Should().StartWith(\"text/html\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-store\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"no-cache\");\n            _context.Response.Headers[\"Cache-Control\"].First().Should().Contain(\"max-age=0\");\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"default-src 'none';\");\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"style-src 'sha256-u+OupXgfekP+x/f6rMdoEAspPCYUtca912isERnoEjY=';\");\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"frame-src http://foo.com http://bar.com\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"default-src 'none';\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"style-src 'sha256-u+OupXgfekP+x/f6rMdoEAspPCYUtca912isERnoEjY=';\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"frame-src http://foo.com http://bar.com\");\n            _context.Response.Body.Seek(0, SeekOrigin.Begin);\n            using (var rdr = new StreamReader(_context.Response.Body))\n            {\n                var html = rdr.ReadToEnd();\n                html.Should().Contain(\"<iframe src='http://foo.com'></iframe>\");\n                html.Should().Contain(\"<iframe src='http://bar.com'></iframe>\");\n            }\n        }\n\n        [Fact]\n        public async Task fsuccess_should_add_unsafe_inline_for_csp_level_1()\n        {\n            _result.IsError = false;\n\n            _options.Csp.Level = CspLevel.One;\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"style-src 'unsafe-inline' 'sha256-u+OupXgfekP+x/f6rMdoEAspPCYUtca912isERnoEjY='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].First().Should().Contain(\"style-src 'unsafe-inline' 'sha256-u+OupXgfekP+x/f6rMdoEAspPCYUtca912isERnoEjY='\");\n        }\n\n        [Fact]\n        public async Task form_post_mode_should_not_add_deprecated_header_when_it_is_disabled()\n        {\n            _result.IsError = false;\n\n            _options.Csp.AddDeprecatedHeader = false;\n\n            await _subject.ExecuteAsync(_context);\n\n            _context.Response.Headers[\"Content-Security-Policy\"].First().Should().Contain(\"style-src 'sha256-u+OupXgfekP+x/f6rMdoEAspPCYUtca912isERnoEjY='\");\n            _context.Response.Headers[\"X-Content-Security-Policy\"].Should().BeEmpty();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Endpoints/Results/EndSessionResultTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Endpoints.Results;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.WebUtilities;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Endpoints.Results\n{\n    public class EndSessionResultTests\n    {\n        private EndSessionResult _subject;\n\n        private EndSessionValidationResult _result = new EndSessionValidationResult();\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private MockMessageStore<LogoutMessage> _mockLogoutMessageStore = new MockMessageStore<LogoutMessage>();\n\n        private DefaultHttpContext _context = new DefaultHttpContext();\n\n        public EndSessionResultTests()\n        {\n            _context.SetIdentityServerOrigin(\"https://server\");\n            _context.SetIdentityServerBasePath(\"/\");\n\n            _options.UserInteraction.LogoutUrl = \"~/logout\";\n            _options.UserInteraction.LogoutIdParameter = \"logoutId\";\n\n            _subject = new EndSessionResult(_result, _options, new StubClock(), _mockLogoutMessageStore);\n        }\n\n        [Fact]\n        public async Task validated_signout_should_pass_logout_message()\n        {\n            _result.IsError = false;\n            _result.ValidatedRequest = new ValidatedEndSessionRequest\n            {\n                Client = new Client\n                {\n                    ClientId = \"client\"\n                },\n                PostLogOutUri = \"http://client/post-logout-callback\"\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockLogoutMessageStore.Messages.Count.Should().Be(1);\n            var location = _context.Response.Headers[\"Location\"].Single();\n            var query = QueryHelpers.ParseQuery(new Uri(location).Query);\n\n            location.Should().StartWith(\"https://server/logout\");\n            query[\"logoutId\"].First().Should().Be(_mockLogoutMessageStore.Messages.First().Key);\n        }\n\n        [Fact]\n        public async Task unvalidated_signout_should_not_pass_logout_message()\n        {\n            _result.IsError = false;\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockLogoutMessageStore.Messages.Count.Should().Be(0);\n            var location = _context.Response.Headers[\"Location\"].Single();\n            var query = QueryHelpers.ParseQuery(new Uri(location).Query);\n\n            location.Should().StartWith(\"https://server/logout\");\n            query.Count.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task error_result_should_not_pass_logout_message()\n        {\n            _result.IsError = true;\n            _result.ValidatedRequest = new ValidatedEndSessionRequest\n            {\n                Client = new Client\n                {\n                    ClientId = \"client\"\n                },\n                PostLogOutUri = \"http://client/post-logout-callback\"\n            };\n\n            await _subject.ExecuteAsync(_context);\n\n            _mockLogoutMessageStore.Messages.Count.Should().Be(0);\n            var location = _context.Response.Headers[\"Location\"].Single();\n            var query = QueryHelpers.ParseQuery(new Uri(location).Query);\n\n            location.Should().StartWith(\"https://server/logout\");\n            query.Count.Should().Be(0);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/ApiResourceSigningAlgorithmSelectionTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing FluentAssertions;\nusing IdentityServer8.Models;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class ApiResourceSigningAlgorithmSelectionTests\n    {\n        [Fact]\n        public void Single_resource_no_allowed_algorithms_set_should_return_empty_list()\n        {\n            var resource = new ApiResource();\n\n            var allowedAlgorithms = new List<ApiResource> { resource }.FindMatchingSigningAlgorithms();\n\n            allowedAlgorithms.Count().Should().Be(0);\n        }\n        \n        [Fact]\n        public void Two_resources_no_allowed_algorithms_set_should_return_empty_list()\n        {\n            var resource1 = new ApiResource();\n            var resource2 = new ApiResource();\n\n            var allowedAlgorithms = new List<ApiResource> { resource1, resource2 }.FindMatchingSigningAlgorithms();\n\n            allowedAlgorithms.Count().Should().Be(0);\n        }\n        \n        [Theory]\n        [InlineData(new [] { \"A\" }, new [] { \"A\" }, \n                    new [] { \"A\" })]\n        [InlineData(new [] { \"A\", \"B\" }, new [] { \"A\", \"B\" }, \n                    new [] { \"A\", \"B\" })]\n        [InlineData(new [] { \"A\", \"B\", \"C\" }, new [] { \"A\", \"B\", \"C\" }, \n                    new [] { \"A\", \"B\", \"C\" })]\n\n        [InlineData(new [] { \"A\", \"B\" }, new [] { \"A\", \"D\" }, \n                    new [] { \"A\" })]\n        [InlineData(new [] { \"A\", \"B\", \"C\" }, new [] { \"A\", \"B\", \"Z\" }, \n                    new [] { \"A\", \"B\" })]\n\n        [InlineData(new string[] { }, new [] { \"B\" },\n                    new string[] { \"B\" })]\n        [InlineData(new string[] { }, new [] { \"C\", \"D\" },\n                    new string[] { \"C\", \"D\" })]\n\n        [InlineData(new [] { \"A\" }, new [] { \"B\" }, \n                    new string[] { })]\n        [InlineData(new [] { \"A\", \"B\" }, new [] { \"C\", \"D\" }, \n                    new string[] { })]\n        public void Two_resources_with_allowed_algorithms_set_should_return_right_values(\n            string[] resource1Algorithms, string[] resource2Algorithms, \n            string[] expectedAlgorithms)\n        {\n            var resource1 = new ApiResource()\n            {\n                AllowedAccessTokenSigningAlgorithms = resource1Algorithms\n            };\n            \n            var resource2 = new ApiResource\n            {\n                AllowedAccessTokenSigningAlgorithms = resource2Algorithms\n            };\n\n            if (expectedAlgorithms.Any())\n            {\n                var allowedAlgorithms = new List<ApiResource> { resource1, resource2 }.FindMatchingSigningAlgorithms();\n                allowedAlgorithms.Should().BeEquivalentTo(expectedAlgorithms);\n            }\n            else\n            {\n                Action act = () => new List<ApiResource> { resource1, resource2 }.FindMatchingSigningAlgorithms();\n                act.Should().Throw<InvalidOperationException>();\n            }\n        }\n        \n        [Theory]\n        [InlineData(new [] { \"A\" }, new [] { \"A\" }, new [] { \"A\" }, \n            new [] { \"A\" })]\n        [InlineData(new [] { \"A\", \"B\" }, new [] { \"A\", \"B\" }, new [] { \"A\", \"B\" }, \n            new [] { \"A\", \"B\" })]\n        [InlineData(new [] { \"A\", \"B\", \"C\" }, new [] { \"A\", \"B\", \"C\" }, new [] { \"A\", \"B\", \"C\" }, \n            new [] { \"A\", \"B\", \"C\" })]\n        \n        [InlineData(new [] { \"A\", \"B\" }, new [] { \"A\", \"D\" }, new [] { \"A\", \"E\" } ,\n                    new [] { \"A\" })]\n        [InlineData(new [] { \"A\", \"B\", \"X\" }, new [] { \"A\", \"B\", \"Y\" }, new [] { \"A\", \"B\", \"Z\" },\n                    new [] { \"A\", \"B\" })]\n        [InlineData(new [] { \"A\", \"B\", \"X\" }, new [] { \"C\", \"D\", \"X\" }, new [] { \"E\", \"F\", \"X\" },\n                    new [] { \"X\" })]\n\n        [InlineData(new[] { \"A\", \"B\" }, new[] { \"A\", \"D\" }, new string[] { },\n                    new[] { \"A\" })]\n        [InlineData(new[] { \"A\", \"B\" }, new[] { \"A\", \"C\", \"B\" }, new string[] { },\n                    new[] { \"A\", \"B\" })]\n        [InlineData(new[] { \"A\", \"B\" }, new string[] { }, new string[] { },\n                    new[] { \"A\", \"B\" })]\n\n        [InlineData(new [] { \"A\" }, new [] { \"B\" }, new [] { \"C\" }, \n            new string[] { })]\n        [InlineData(new [] { \"A\", \"B\" }, new [] { \"C\", \"D\" }, new [] { \"X\", \"Y\" }, \n            new string[] { })]\n        [InlineData(new [] { \"A\", \"B\", \"C\" }, new [] { \"C\", \"D\", \"E\" }, new [] { \"E\", \"F\", \"G\" },\n                    new string[] { })]\n        public void Three_resources_with_allowed_algorithms_set_should_return_right_values(\n            string[] resource1Algorithms, string[] resource2Algorithms, string[] resource3Algorithms, \n            string[] expectedAlgorithms)\n        {\n            var resource1 = new ApiResource()\n            {\n                AllowedAccessTokenSigningAlgorithms = resource1Algorithms\n            };\n            \n            var resource2 = new ApiResource\n            {\n                AllowedAccessTokenSigningAlgorithms = resource2Algorithms\n            };\n            \n            var resource3 = new ApiResource\n            {\n                AllowedAccessTokenSigningAlgorithms = resource3Algorithms\n            };\n\n            if (expectedAlgorithms.Any())\n            {\n                var allowedAlgorithms = new List<ApiResource> {resource1, resource2, resource3}.FindMatchingSigningAlgorithms();\n                allowedAlgorithms.Should().BeEquivalentTo(expectedAlgorithms);\n            }\n            else\n            {\n                Action act = () => new List<ApiResource> {resource1, resource2, resource3}.FindMatchingSigningAlgorithms();\n                act.Should().Throw<InvalidOperationException>();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/EndpointOptionsExtensionsTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Hosting;\nusing Xunit;\nusing static IdentityServer8.Constants;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class EndpointOptionsExtensionsTests\n    {\n        private readonly EndpointsOptions _options = new EndpointsOptions();\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForAuthorizeEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableAuthorizeEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.Authorize)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForCheckSessionEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableCheckSessionEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.CheckSession)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForDeviceAuthorizationEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableDeviceAuthorizationEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.DeviceAuthorization)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForDiscoveryEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableDiscoveryEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.Discovery)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForEndSessionEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableEndSessionEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.EndSession)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForIntrospectionEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableIntrospectionEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.Introspection)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForTokenEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableTokenEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.Token)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForRevocationEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableTokenRevocationEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.Revocation)));\n        }\n\n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        public void IsEndpointEnabledShouldReturnExpectedForUserInfoEndpoint(bool expectedIsEndpointEnabled)\n        {\n            _options.EnableUserInfoEndpoint = expectedIsEndpointEnabled;\n\n            Assert.Equal(\n                expectedIsEndpointEnabled,\n                _options.IsEndpointEnabled(\n                    CreateTestEndpoint(EndpointNames.UserInfo)));\n        }\n\n        private Endpoint CreateTestEndpoint(string name)\n        {\n            return new Endpoint(name, \"\", null);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/HttpRequestExtensionsTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.Extensions;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class HttpRequestExtensionsTests\n    {\n        [Fact]\n        public void GetCorsOrigin_valid_cors_request_should_return_cors_origin()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"http\";\n            ctx.Request.Host = new HostString(\"foo\");\n            ctx.Request.Headers.Append(\"Origin\", \"http://bar\");\n\n            ctx.Request.GetCorsOrigin().Should().Be(\"http://bar\");\n        }\n\n        [Fact]\n        public void GetCorsOrigin_origin_from_same_host_should_not_return_cors_origin()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"http\";\n            ctx.Request.Host = new HostString(\"foo\");\n            ctx.Request.Headers.Append(\"Origin\", \"http://foo\");\n\n            ctx.Request.GetCorsOrigin().Should().BeNull();\n        }\n\n        [Fact]\n        public void GetCorsOrigin_no_origin_should_not_return_cors_origin()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Scheme = \"http\";\n            ctx.Request.Host = new HostString(\"foo\");\n\n            ctx.Request.GetCorsOrigin().Should().BeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/IResourceStoreExtensionsTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class IResourceStoreExtensionsTests\n    {\n        [Fact]\n        public async Task GetAllEnabledResourcesAsync_on_duplicate_identity_scopes_should_fail()\n        {\n            var store = new MockResourceStore()\n            {\n                IdentityResources = {\n                    new IdentityResource { Name = \"A\" },\n                    new IdentityResource { Name = \"A\" } }\n            };\n\n            Func<Task> a = async () => await store.GetAllEnabledResourcesAsync();\n            (await a.Should().ThrowAsync<Exception>()).And.Message.ToLowerInvariant().Should().Contain(\"duplicate\").And.Contain(\"identity scopes\");\n        }\n\n        [Fact]\n        public async Task GetAllEnabledResourcesAsync_without_duplicate_identity_scopes_should_succeed()\n        {\n            var store = new MockResourceStore()\n            {\n                IdentityResources = {\n                    new IdentityResource { Name = \"A\" },\n                    new IdentityResource { Name = \"B\" } }\n            };\n\n            await store.GetAllEnabledResourcesAsync();\n        }\n\n        [Fact]\n        public async Task GetAllEnabledResourcesAsync_on_duplicate_api_resources_should_fail()\n        {\n            var store = new MockResourceStore()\n            {\n                ApiResources = { new ApiResource { Name = \"a\" }, new ApiResource { Name = \"a\" } }\n            };\n\n            Func<Task> a = async () => await store.GetAllEnabledResourcesAsync();\n            (await a.Should().ThrowAsync<Exception>())\n                .And.Message.ToLowerInvariant().Should().Contain(\"duplicate\").And.Contain(\"api resources\");\n        }\n\n        [Fact]\n        public async Task GetAllEnabledResourcesAsync_without_duplicate_api_scopes_should_succeed()\n        {\n            var store = new MockResourceStore()\n            {\n                ApiResources = { new ApiResource(\"A\"), new ApiResource(\"B\") }\n            };\n\n            await store.GetAllEnabledResourcesAsync();\n        }\n\n        [Fact]\n        public async Task FindResourcesByScopeAsync_on_duplicate_identity_scopes_should_fail()\n        {\n            var store = new MockResourceStore()\n            {\n                IdentityResources = {\n                    new IdentityResource { Name = \"A\" },\n                    new IdentityResource { Name = \"A\" } }\n            };\n\n            Func<Task> a = async () => await store.FindResourcesByScopeAsync(new string[] { \"A\" });\n            (await a.Should().ThrowAsync<Exception>()).And.Message.ToLowerInvariant().Should().Contain(\"duplicate\").And.Contain(\"identity scopes\");\n        }\n\n        [Fact]\n        public async Task FindResourcesByScopeAsync_without_duplicate_identity_scopes_should_succeed()\n        {\n            var store = new MockResourceStore()\n            {\n                IdentityResources = {\n                    new IdentityResource { Name = \"A\" },\n                    new IdentityResource { Name = \"B\" } }\n            };\n\n            await store.FindResourcesByScopeAsync(new string[] { \"A\" });\n        }\n\n        [Fact]\n        public async Task FindResourcesByScopeAsync_on_duplicate_api_scopes_should_succeed()\n        {\n            var store = new MockResourceStore()\n            {\n                ApiResources = { \n                    new ApiResource { Name = \"api1\", Scopes = { \"a\" } },\n                    new ApiResource() { Name = \"api2\", Scopes = { \"a\" } },\n                },\n                ApiScopes = { \n                    new ApiScope(\"a\") \n                } \n            };\n\n            var result = await store.FindResourcesByScopeAsync(new string[] { \"a\" });\n            result.ApiResources.Count.Should().Be(2);\n            result.ApiScopes.Count.Should().Be(1);\n            result.ApiResources.Select(x => x.Name).Should().BeEquivalentTo(new[] { \"api1\", \"api2\" });\n            result.ApiScopes.Select(x => x.Name).Should().BeEquivalentTo(new[] { \"a\" });\n        }\n\n        [Fact]\n        public async Task FindResourcesByScopeAsync_without_duplicate_api_scopes_should_succeed()\n        {\n            var store = new MockResourceStore()\n            {\n                ApiResources = { new ApiResource(\"A\"), new ApiResource(\"B\") }\n            };\n\n            await store.FindResourcesByScopeAsync(new string[] { \"A\" });\n        }\n\n        [Fact]\n        public async Task FindResourcesByScopeAsync_with_duplicate_api_scopes_on_single_api_resource_should_succeed_and_only_reuturn_one_resource()\n        {\n            var store = new MockResourceStore()\n            {\n                ApiResources = { \n                    new ApiResource { \n                        Name = \"api1\", Scopes = { \"a\", \"a\" }\n                    }\n                },\n                ApiScopes = {\n                    new ApiScope(\"a\"),\n                }\n            };\n\n            var result = await store.FindResourcesByScopeAsync(new string[] { \"a\" });\n            result.ApiResources.Count.Should().Be(1);\n        }\n\n        public class MockResourceStore : IResourceStore\n        {\n            public List<IdentityResource> IdentityResources { get; set; } = new List<IdentityResource>();\n            public List<ApiResource> ApiResources { get; set; } = new List<ApiResource>();\n            public List<ApiScope> ApiScopes { get; set; } = new List<ApiScope>();\n\n            public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> names)\n            {\n                var apis = from a in ApiResources\n                          where names.Contains(a.Name)\n                          select a;\n                return Task.FromResult(apis);\n            }\n\n            public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> names)\n            {\n                if (names == null) throw new ArgumentNullException(nameof(names));\n\n                var api = from a in ApiResources\n                          where a.Scopes.Any(x => names.Contains(x))\n                          select a;\n\n                return Task.FromResult(api);\n            }\n\n            public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> names)\n            {\n                if (names == null) throw new ArgumentNullException(nameof(names));\n\n                var identity = from i in IdentityResources\n                               where names.Contains(i.Name)\n                               select i;\n\n                return Task.FromResult(identity);\n            }\n\n            public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)\n            {\n                var q = from x in ApiScopes\n                        where scopeNames.Contains(x.Name)\n                        select x;\n                return Task.FromResult(q);\n            }\n\n            public Task<Resources> GetAllResourcesAsync()\n            {\n                var result = new Resources(IdentityResources, ApiResources, ApiScopes);\n                return Task.FromResult(result);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/IdentityServerBuilderExtensionsCacheStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class IdentityServerBuilderExtensionsCacheStoreTests\n    {\n        private class CustomClientStore: IClientStore\n        {\n            public Task<Client> FindClientByIdAsync(string clientId)\n            {\n                throw new System.NotImplementedException();\n            }\n        }\n\n        private class CustomResourceStore : IResourceStore\n        {\n            public Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames)\n            {\n                throw new System.NotImplementedException();\n            }\n\n            public Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames)\n            {\n                throw new System.NotImplementedException();\n            }\n\n            public Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> names)\n            {\n                throw new System.NotImplementedException();\n            }\n\n            public Task<Resources> GetAllResourcesAsync()\n            {\n                throw new System.NotImplementedException();\n            }\n\n            public Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames)\n            {\n                throw new System.NotImplementedException();\n            }\n        }\n\n        [Fact]\n        public void AddClientStoreCache_should_add_concrete_iclientstore_implementation()\n        {\n            var services = new ServiceCollection();\n            var identityServerBuilder = new IdentityServerBuilder(services);\n\n            identityServerBuilder.AddClientStoreCache<CustomClientStore>();\n\n            services.Any(x => x.ImplementationType == typeof(CustomClientStore)).Should().BeTrue();\n        }\n\n        [Fact]\n        public void AddResourceStoreCache_should_attempt_to_register_iresourcestore_implementation()\n        {\n            var services = new ServiceCollection();\n            var identityServerBuilder = new IdentityServerBuilder(services);\n\n            identityServerBuilder.AddResourceStoreCache<CustomResourceStore>();\n\n            services.Any(x => x.ImplementationType == typeof(CustomResourceStore)).Should().BeTrue();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/IdentityServerBuilderExtensionsCryptoTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.IdentityModel.Tokens;\nusing System;\nusing System.IO;\nusing System.Security.Cryptography;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class IdentityServerBuilderExtensionsCryptoTests\n    {\n        [Fact]\n        public void AddSigningCredential_with_json_web_key_containing_asymmetric_key_should_succeed()\n        {\n            IServiceCollection services = new ServiceCollection();\n            IIdentityServerBuilder identityServerBuilder = new IdentityServerBuilder(services);\n\n            String json =\n            @\"{\n                \"\"alg\"\" : \"\"RS256\"\",\n                \"\"kty\"\" : \"\"RSA\"\",\n                \"\"use\"\" : \"\"sig\"\",\n                \"\"d\"\" : \"\"KGGNkbbgm2hNMqW6fP1fmcWwEBy77WOJIPAXnDJ0KxNTtqDF8K5ULj7EElHO1A8ZnNl1Ey/x//G9lJCOQUU9wmj010dOSsW0NBbR5NtRtLLuVbkVdyft53PGeTQs+1S3c51fz9jojtNqmlfXSANPFOH6QhxmzpTx3KLsf/TpCzblkSrEGOOqCCvVdl7ybTcB230jNhh3JoL7po1rvxKtoOM4a/Bs0NtKj7e+VaHcf0GLnBPJYetsHu43ZfNejJeDoouaXZzeVEklY3B0pe10OTCIOu0JUKGZxNekklRIo1WSEYdL+CJfrSKWIv8bLj6xSr5zrASvWODyH443LN6ZvQ==\"\",\n                \"\"e\"\" : \"\"AQAB\"\",\n                \"\"n\"\" : \"\"q7mZfquRq8tzg/5slbNdQmrosNN/mFXS25dbSPm11qEDCgZa452KkO8+hvMtqa92QaqdlmalSF8+FRDOz3grDR5NtmnXZxuKnp+raKfzpC6hCvh2JSIe/J9enmsMM4YeI4d1FOSDwhJlZIYMdMnqG/VJtO1LSHjOaF3XN31ANKF0nPAsmr2/WysiQlxnxxiikLEnsFuNdS615ODDXFGTQ1E+zc4zVur4/Ox0cllPwHPA4PqoIgdPJPL+xM9IOIXuAGtsp4CYoxT6VWaRrALIZXXDY806WGTuctq4KKot6FGL9HQte2hRLl4E/r8SzIK86U3wRwrBe7saK+XUXoP0gQ=\"\",\n\t\t        \"\"p\"\" :\t\"\"25dkucyCSqxRcJpRrhl7PXqw7wqBZeLQgYlZLpK493PdM8pFfq+/LK1hFtxIjdFKqXS/TOikB4YCBMEH0Im3HZ8Lo0dub3SWNhdegJyRjMbcoO+A9YSODEj7DFaNpZtdmtDi1n6etJm66ctPSR20NNpzoYZuaJ92fVQiKiOh6Qs=\"\",\n                \"\"q\"\" : \"\"yDKBrS8l1DOx4dwP9hdwhqZJ3XahidiIZSL7m46I/6+cjaki/1mtNiA60MOgqTKegP7Fo7jAYvliqQwnvVGmQvLv19cfKywlIuKN9DdkLHnKh75hfo7aakEbO7GJ5zVgsNnKOdf8wvpclfvIuRDEVva4cksPzsJy6K7C8ENCSCM=\"\",\n                \"\"dp\"\" :  \"\"GlYJ6o6wgawxCEQ5z5uWwETau5CS/Fk7kI2ceI14SZVHzlJQC2WglAcnQcqhmQCk57Xsy5iLM6vKyi8sdMJPh+nvR2HlyNA+w7YBy4L7odqn01VmLgv7zVVjZpNq4ZXEoDC1Q+xjtF1LoYaUt7wsRLp+a7znuPyHBXj1sAAeBwk=\"\",\n                \"\"dq\"\" :  \"\"W8OK3S83T8VCTBzq1Ap6cb3XLcQq11yBaJpYaj0zXr/IKsbUW+dnFeBAFWEWS3gAX3Bod1tAFB3rs0D3FjhO1XE1ruHUT520iAEAwGiDaj+JLh994NzqELo3GW2PoIM/BtFNeKYgHd9UgQsgPnQJCzOb6Aev/z3yHeW9RRQPVbE=\"\",\n                \"\"qi\"\" :  \"\"w4KdmiDN1GtK71JxaasqmEKPNfV3v2KZDXKnfyhUsdx/idKbdTVjvMOkxFPJ4FqV4yIVn06f3QHTm4NEG18Diqxsrzd6kXQIHOa858tLsCcmt9FoGfrgCFgVceh3K/Zah/r8rl9Y61u0Z1kZumwMvFpFE+mVU01t9HgTEAVkHTc=\"\"\n            }\";\n\n            JsonWebKey jsonWebKey = new JsonWebKey(json);\n            SigningCredentials credentials = new SigningCredentials(jsonWebKey, jsonWebKey.Alg);\n            identityServerBuilder.AddSigningCredential(credentials);\n        }\n\n        [Fact]\n        public void AddSigningCredential_with_json_web_key_containing_symmetric_key_should_throw_exception()\n        {\n            IServiceCollection services = new ServiceCollection();\n            IIdentityServerBuilder identityServerBuilder = new IdentityServerBuilder(services);\n\n            String json =\n            @\"{\n                \"\"alg\"\" : \"\"HS256\"\",\n                \"\"kty\"\" : \"\"oct\"\",\n                \"\"use\"\" : \"\"sig\"\",\n                \"\"k\"\" : \"\"y5FHaQFtC294HLAtPXAcMkxZ5gHzCq24223vSYQUrDuu-3CUw7UzPru-AX30ubeB2IM_gUsNQ80bX22wwSk_3LC6XxYxqeGJZSeoQqHG0VNbaWCVkqeuB_HOiL1-ksPfGT-o8_A_Uv-6zi2NaEOYpnIyff5LpdW__LhiE-bhIenaw7GhoXSAfsGEZfNZpUUOU35NAiN2dv0T5vptb87wkL1I2zLhV0pdLvWsDWgQPINEa8bbCA_mseBYpB1eioZvt0TZbp6CL9tiEoiikYV_F3IutrJ2SOWYtDNFeQ3sbyYP7zTzh9a2eyaM8ca5_q3qosI92AbZ7WpEFLa9cZ_O7g\"\"\n            }\";\n\n            JsonWebKey jsonWebKey = new JsonWebKey(json);\n            SigningCredentials credentials = new SigningCredentials(jsonWebKey, jsonWebKey.Alg);\n            Assert.Throws<InvalidOperationException>(() => identityServerBuilder.AddSigningCredential(credentials));\n        }\n\n        [Fact]\n        public void AddDeveloperSigningCredential_should_succeed()\n        {\n            IServiceCollection services = new ServiceCollection();\n            IIdentityServerBuilder identityServerBuilder = new IdentityServerBuilder(services);\n\n            identityServerBuilder.AddDeveloperSigningCredential();\n\n            //clean up... delete stored rsa key\n            var filename = Path.Combine(Directory.GetCurrentDirectory(), \"tempkey.rsa\");\n\n            if (File.Exists(filename))\n                File.Delete(filename);\n        }\n\n        [Fact]\n        public void AddDeveloperSigningCredential_should_succeed_when_called_multiple_times()\n        {\n            IServiceCollection services = new ServiceCollection();\n            IIdentityServerBuilder identityServerBuilder = new IdentityServerBuilder(services);\n\n            try\n            {\n                identityServerBuilder.AddDeveloperSigningCredential();\n\n                //calling a second time will try to load the saved rsa key from disk. An exception will be throw if the private key is not serialized properly.\n                identityServerBuilder.AddDeveloperSigningCredential();\n            }\n            finally\n            {\n                //clean up... delete stored rsa key\n                var filename = Path.Combine(Directory.GetCurrentDirectory(), \"tempkey.rsa\");\n\n                if (File.Exists(filename))\n                    File.Delete(filename);\n            }\n        }\n\n        [Theory]\n        [InlineData(Constants.CurveOids.P256, SecurityAlgorithms.EcdsaSha256)]\n        [InlineData(Constants.CurveOids.P384, SecurityAlgorithms.EcdsaSha384)]\n        [InlineData(Constants.CurveOids.P521, SecurityAlgorithms.EcdsaSha512)]\n        public void AddSigningCredential_with_valid_curve_should_succeed(string curveOid, string alg)\n        {\n            IServiceCollection services = new ServiceCollection();\n            IIdentityServerBuilder identityServerBuilder = new IdentityServerBuilder(services);\n\n            var key = new ECDsaSecurityKey(ECDsa.Create(\n                ECCurve.CreateFromOid(Oid.FromOidValue(curveOid, OidGroup.All))));\n\n            identityServerBuilder.AddSigningCredential(key, alg);\n        }\n\n        [Theory]\n        [InlineData(Constants.CurveOids.P256, SecurityAlgorithms.EcdsaSha512)]\n        [InlineData(Constants.CurveOids.P384, SecurityAlgorithms.EcdsaSha512)]\n        [InlineData(Constants.CurveOids.P521, SecurityAlgorithms.EcdsaSha256)]\n        public void AddSigningCredential_with_invalid_curve_should_throw_exception(string curveOid, string alg)\n        {\n            IServiceCollection services = new ServiceCollection();\n            IIdentityServerBuilder identityServerBuilder = new IdentityServerBuilder(services);\n\n            var key = new ECDsaSecurityKey(ECDsa.Create(\n                ECCurve.CreateFromOid(Oid.FromOidValue(curveOid, OidGroup.All))));\n\n            Assert.Throws<InvalidOperationException>(() => identityServerBuilder.AddSigningCredential(key, alg));\n        }\n\n\n\n        [Theory]\n        [InlineData(Constants.CurveOids.P256, SecurityAlgorithms.EcdsaSha256, JsonWebKeyECTypes.P256)]\n        [InlineData(Constants.CurveOids.P384, SecurityAlgorithms.EcdsaSha384, JsonWebKeyECTypes.P384)]\n        [InlineData(Constants.CurveOids.P521, SecurityAlgorithms.EcdsaSha512, JsonWebKeyECTypes.P521)]\n        public void AddSigningCredential_with_invalid_crv_value_should_throw_exception(string curveOid, string alg, string crv)\n        {\n            IServiceCollection services = new ServiceCollection();\n            IIdentityServerBuilder identityServerBuilder = new IdentityServerBuilder(services);\n\n            var key = new ECDsaSecurityKey(ECDsa.Create(\n                ECCurve.CreateFromOid(Oid.FromOidValue(curveOid, OidGroup.All))));\n            var parameters = key.ECDsa.ExportParameters(true);\n\n            var jsonWebKeyFromECDsa = new JsonWebKey()\n            {\n                Kty = JsonWebAlgorithmsKeyTypes.EllipticCurve,\n                Use = \"sig\",\n                Kid = key.KeyId,\n                KeyId = key.KeyId,\n                X = Base64UrlEncoder.Encode(parameters.Q.X),\n                Y = Base64UrlEncoder.Encode(parameters.Q.Y),\n                D = Base64UrlEncoder.Encode(parameters.D),\n                Crv = crv.Replace(\"-\", string.Empty),\n                Alg = SecurityAlgorithms.EcdsaSha256\n            };\n            Assert.Throws<InvalidOperationException>(() => identityServerBuilder.AddSigningCredential(jsonWebKeyFromECDsa, alg));\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/JwtPayloadCreationTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing Microsoft.AspNetCore.Authentication;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class JwtPayloadCreationTests\n    {\n        private Token _token;\n        \n        public JwtPayloadCreationTests()\n        {\n            var claims = new List<Claim>\n            {\n                new Claim(JwtClaimTypes.Scope, \"scope1\"),\n                new Claim(JwtClaimTypes.Scope, \"scope2\"),\n                new Claim(JwtClaimTypes.Scope, \"scope3\"),\n            };\n            \n            _token = new Token(OidcConstants.TokenTypes.AccessToken)\n            {\n                CreationTime = DateTime.UtcNow,\n                Issuer = \"issuer\",\n                Lifetime = 60,\n                Claims = claims.Distinct(new ClaimComparer()).ToList(),\n                ClientId = \"client\"\n            };\n        }\n        \n        [Fact]\n        public void Should_create_scopes_as_array_by_default()\n        {\n            var options = new IdentityServerOptions();\n            var payload = _token.CreateJwtPayload(new SystemClock(), options, TestLogger.Create<JwtPayloadCreationTests>());\n\n            payload.Should().NotBeNull();\n            var scopes = payload.Claims.Where(c => c.Type == JwtClaimTypes.Scope).ToArray();\n            scopes.Count().Should().Be(3);\n            scopes[0].Value.Should().Be(\"scope1\");\n            scopes[1].Value.Should().Be(\"scope2\");\n            scopes[2].Value.Should().Be(\"scope3\");\n        }\n        \n        [Fact]\n        public void Should_create_scopes_as_string()\n        {\n            var options = new IdentityServerOptions\n            {\n                EmitScopesAsSpaceDelimitedStringInJwt = true\n            };\n            \n            var payload = _token.CreateJwtPayload(new SystemClock(), options, TestLogger.Create<JwtPayloadCreationTests>());\n\n            payload.Should().NotBeNull();\n            var scopes = payload.Claims.Where(c => c.Type == JwtClaimTypes.Scope).ToList();\n            scopes.Count().Should().Be(1);\n            scopes.First().Value.Should().Be(\"scope1 scope2 scope3\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/StringExtensionsTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Extensions;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class StringExtensionsTests\n    {\n        private void CheckOrigin(string inputUrl, string expectedOrigin)\n        {\n            var actualOrigin = inputUrl.GetOrigin();\n            Assert.Equal(expectedOrigin, actualOrigin);\n        }\n\n        [Fact]\n        public void TestGetOrigin()\n        {\n            CheckOrigin(\"http://idsvr.com\", \"http://idsvr.com\");\n            CheckOrigin(\"http://idsvr.com/\", \"http://idsvr.com\");\n            CheckOrigin(\"http://idsvr.com/test\", \"http://idsvr.com\");\n            CheckOrigin(\"http://idsvr.com/test/resource\", \"http://idsvr.com\");\n            CheckOrigin(\"http://idsvr.com:8080\", \"http://idsvr.com:8080\");\n            CheckOrigin(\"http://idsvr.com:8080/\", \"http://idsvr.com:8080\");\n            CheckOrigin(\"http://idsvr.com:8080/test\", \"http://idsvr.com:8080\");\n            CheckOrigin(\"http://idsvr.com:8080/test/resource\", \"http://idsvr.com:8080\");\n            CheckOrigin(\"http://127.0.0.1\", \"http://127.0.0.1\");\n            CheckOrigin(\"http://127.0.0.1/\", \"http://127.0.0.1\");\n            CheckOrigin(\"http://127.0.0.1/test\", \"http://127.0.0.1\");\n            CheckOrigin(\"http://127.0.0.1/test/resource\", \"http://127.0.0.1\");\n            CheckOrigin(\"http://127.0.0.1:8080\", \"http://127.0.0.1:8080\");\n            CheckOrigin(\"http://127.0.0.1:8080/\", \"http://127.0.0.1:8080\");\n            CheckOrigin(\"http://127.0.0.1:8080/test\", \"http://127.0.0.1:8080\");\n            CheckOrigin(\"http://127.0.0.1:8080/test/resource\", \"http://127.0.0.1:8080\");\n            CheckOrigin(\"http://localhost\", \"http://localhost\");\n            CheckOrigin(\"http://localhost/\", \"http://localhost\");\n            CheckOrigin(\"http://localhost/test\", \"http://localhost\");\n            CheckOrigin(\"http://localhost/test/resource\", \"http://localhost\");\n            CheckOrigin(\"http://localhost:8080\", \"http://localhost:8080\");\n            CheckOrigin(\"http://localhost:8080/\", \"http://localhost:8080\");\n            CheckOrigin(\"http://localhost:8080/test\", \"http://localhost:8080\");\n            CheckOrigin(\"http://localhost:8080/test/resource\", \"http://localhost:8080\");\n            CheckOrigin(\"https://idsvr.com\", \"https://idsvr.com\");\n            CheckOrigin(\"https://idsvr.com/\", \"https://idsvr.com\");\n            CheckOrigin(\"https://idsvr.com/test\", \"https://idsvr.com\");\n            CheckOrigin(\"https://idsvr.com/test/resource\", \"https://idsvr.com\");\n            CheckOrigin(\"https://idsvr.com:8080\", \"https://idsvr.com:8080\");\n            CheckOrigin(\"https://idsvr.com:8080/\", \"https://idsvr.com:8080\");\n            CheckOrigin(\"https://idsvr.com:8080/test\", \"https://idsvr.com:8080\");\n            CheckOrigin(\"https://idsvr.com:8080/test/resource\", \"https://idsvr.com:8080\");\n            CheckOrigin(\"https://127.0.0.1\", \"https://127.0.0.1\");\n            CheckOrigin(\"https://127.0.0.1/\", \"https://127.0.0.1\");\n            CheckOrigin(\"https://127.0.0.1/test\", \"https://127.0.0.1\");\n            CheckOrigin(\"https://127.0.0.1/test/resource\", \"https://127.0.0.1\");\n            CheckOrigin(\"https://127.0.0.1:8080\", \"https://127.0.0.1:8080\");\n            CheckOrigin(\"https://127.0.0.1:8080/\", \"https://127.0.0.1:8080\");\n            CheckOrigin(\"https://127.0.0.1:8080/test\", \"https://127.0.0.1:8080\");\n            CheckOrigin(\"https://127.0.0.1:8080/test/resource\", \"https://127.0.0.1:8080\");\n            CheckOrigin(\"https://localhost\", \"https://localhost\");\n            CheckOrigin(\"https://localhost/\", \"https://localhost\");\n            CheckOrigin(\"https://localhost/test\", \"https://localhost\");\n            CheckOrigin(\"https://localhost/test/resource\", \"https://localhost\");\n            CheckOrigin(\"https://localhost:8080\", \"https://localhost:8080\");\n            CheckOrigin(\"https://localhost:8080/\", \"https://localhost:8080\");\n            CheckOrigin(\"https://localhost:8080/test\", \"https://localhost:8080\");\n            CheckOrigin(\"https://localhost:8080/test/resource\", \"https://localhost:8080\");\n            CheckOrigin(\"test://idsvr.com\", null);\n            CheckOrigin(\"test://idsvr.com/\", null);\n            CheckOrigin(\"test://idsvr.com/test\", null);\n            CheckOrigin(\"test://idsvr.com/test/resource\", null);\n            CheckOrigin(\"test://idsvr.com:8080\", null);\n            CheckOrigin(\"test://idsvr.com:8080/\", null);\n            CheckOrigin(\"test://idsvr.com:8080/test\", null);\n            CheckOrigin(\"test://idsvr.com:8080/test/resource\", null);\n            CheckOrigin(\"test://127.0.0.1\", null);\n            CheckOrigin(\"test://127.0.0.1/\", null);\n            CheckOrigin(\"test://127.0.0.1/test\", null);\n            CheckOrigin(\"test://127.0.0.1/test/resource\", null);\n            CheckOrigin(\"test://127.0.0.1:8080\", null);\n            CheckOrigin(\"test://127.0.0.1:8080/\", null);\n            CheckOrigin(\"test://127.0.0.1:8080/test\", null);\n            CheckOrigin(\"test://127.0.0.1:8080/test/resource\", null);\n            CheckOrigin(\"test://localhost\", null);\n            CheckOrigin(\"test://localhost/\", null);\n            CheckOrigin(\"test://localhost/test\", null);\n            CheckOrigin(\"test://localhost/test/resource\", null);\n            CheckOrigin(\"test://localhost:8080\", null);\n            CheckOrigin(\"test://localhost:8080/\", null);\n            CheckOrigin(\"test://localhost:8080/test\", null);\n            CheckOrigin(\"test://localhost:8080/test/resource\", null);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Extensions/ValidatedAuthorizeRequestExtensionsTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Extensions\n{\n    public class ValidatedAuthorizeRequestExtensionsTests\n    {\n        [Fact]\n        public void GetAcrValues_should_return_snapshot_of_values()\n        {\n            var request = new ValidatedAuthorizeRequest()\n            {\n                Raw = new System.Collections.Specialized.NameValueCollection()\n            };\n            request.AuthenticationContextReferenceClasses.Add(\"a\");\n            request.AuthenticationContextReferenceClasses.Add(\"b\");\n            request.AuthenticationContextReferenceClasses.Add(\"c\");\n\n            var acrs = request.GetAcrValues();\n            foreach(var acr in acrs)\n            {\n                request.RemoveAcrValue(acr);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Hosting/EndpointRouterTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Hosting;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\nusing static IdentityServer8.Constants;\n\nnamespace IdentityServer.UnitTests.Hosting\n{\n    public class EndpointRouterTests\n    {\n        private Dictionary<string, IdentityServer8.Hosting.Endpoint> _pathMap;\n        private List<IdentityServer8.Hosting.Endpoint> _endpoints;\n        private IdentityServerOptions _options;\n        private EndpointRouter _subject;\n\n        public EndpointRouterTests()\n        {\n            _pathMap = new Dictionary<string, IdentityServer8.Hosting.Endpoint>();\n            _endpoints = new List<IdentityServer8.Hosting.Endpoint>();\n            _options = new IdentityServerOptions();\n            _subject = new EndpointRouter(_endpoints, _options, TestLogger.Create<EndpointRouter>());\n        }\n\n        [Fact]\n        public void Endpoint_ctor_requires_path_to_start_with_slash()\n        {\n            Action a = () => new IdentityServer8.Hosting.Endpoint(\"ep1\", \"ep1\", typeof(MyEndpointHandler));\n            a.Should().Throw<ArgumentException>();\n        }\n\n        [Fact]\n        public void Find_should_return_null_for_incorrect_path()\n        {\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep1\", \"/ep1\", typeof(MyEndpointHandler)));\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep2\", \"/ep2\", typeof(MyOtherEndpointHandler)));\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Path = new PathString(\"/wrong\");\n            ctx.RequestServices = new StubServiceProvider();\n\n            var result = _subject.Find(ctx);\n            result.Should().BeNull();\n        }\n\n        [Fact]\n        public void Find_should_find_path()\n        {\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep1\", \"/ep1\", typeof(MyEndpointHandler)));\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep2\", \"/ep2\", typeof(MyOtherEndpointHandler)));\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Path = new PathString(\"/ep1\");\n            ctx.RequestServices = new StubServiceProvider();\n\n            var result = _subject.Find(ctx);\n            result.Should().BeOfType<MyEndpointHandler>();\n        }\n\n        [Fact]\n        public void Find_should_not_find_nested_paths()\n        {\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep1\", \"/ep1\", typeof(MyEndpointHandler)));\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep2\", \"/ep2\", typeof(MyOtherEndpointHandler)));\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Path = new PathString(\"/ep1/subpath\");\n            ctx.RequestServices = new StubServiceProvider();\n\n            var result = _subject.Find(ctx);\n            result.Should().BeNull();\n        }\n\n        [Fact]\n        public void Find_should_find_first_registered_mapping()\n        {\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep1\", \"/ep1\", typeof(MyEndpointHandler)));\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep1\", \"/ep1\", typeof(MyOtherEndpointHandler)));\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Path = new PathString(\"/ep1\");\n            ctx.RequestServices = new StubServiceProvider();\n\n            var result = _subject.Find(ctx);\n            result.Should().BeOfType<MyEndpointHandler>();\n        }\n\n        [Fact]\n        public void Find_should_return_null_for_disabled_endpoint()\n        {\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(EndpointNames.Authorize, \"/ep1\", typeof(MyEndpointHandler)));\n            _endpoints.Add(new IdentityServer8.Hosting.Endpoint(\"ep2\", \"/ep2\", typeof(MyOtherEndpointHandler)));\n\n            _options.Endpoints.EnableAuthorizeEndpoint = false;\n\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Path = new PathString(\"/ep1\");\n            ctx.RequestServices = new StubServiceProvider();\n\n            var result = _subject.Find(ctx);\n            result.Should().BeNull();\n        }\n\n        private class MyEndpointHandler : IEndpointHandler\n        {\n            public Task<IEndpointResult> ProcessAsync(HttpContext context)\n            {\n                throw new NotImplementedException();\n            }\n        }\n\n        private class MyOtherEndpointHandler : IEndpointHandler\n        {\n            public Task<IEndpointResult> ProcessAsync(HttpContext context)\n            {\n                throw new NotImplementedException();\n            }\n        }\n\n        private class StubServiceProvider : IServiceProvider\n        {\n            public object GetService(Type serviceType)\n            {\n                if (serviceType == typeof(MyEndpointHandler)) return new MyEndpointHandler();\n                if (serviceType == typeof(MyOtherEndpointHandler)) return new MyOtherEndpointHandler();\n\n                throw new InvalidOperationException();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/IdentityServer.UnitTests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n\n  <PropertyGroup>\n    <AssemblyOriginatorKeyFile>../../../../key.snk</AssemblyOriginatorKeyFile>\n    <SignAssembly>true</SignAssembly>\n    <PublicSign Condition=\"'$(OS)' != 'Windows_NT'\">true</PublicSign>\n  </PropertyGroup>\n\n \n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" PrivateAssets=\"All\" />\n    <PackageReference Include=\"FluentAssertions\" />\n    <PackageReference Include=\"coverlet.collector\" GeneratePathProperty=\"true\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageReference>\n  </ItemGroup>\n\n  <ItemGroup>\n    <None Update=\"identityserver_testing.cer\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n    <None Update=\"identityserver_testing.pfx\">\n      <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\IdentityServer8.csproj\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Infrastructure/ObjectSerializerTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing FluentAssertions;\nusing IdentityServer8.Models;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Infrastructure\n{\n    public class ObjectSerializerTests\n    {\n        public ObjectSerializerTests()\n        {\n        }\n\n        [Fact]\n        public void Can_be_deserialize_message()\n        {\n            Action a = () => IdentityServer8.ObjectSerializer.FromString<Message<ErrorMessage>>(\"{\\\"created\\\":0, \\\"data\\\": {\\\"error\\\": \\\"error\\\"}}\");\n            a.Should().NotThrow();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/ResponseHandling/AuthorizeInteractionResponseGenerator/AuthorizeInteractionResponseGeneratorTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Xunit;\nusing static IdentityModel.OidcConstants;\n\nnamespace IdentityServer.UnitTests.ResponseHandling.AuthorizeInteractionResponseGenerator\n{\n    public class AuthorizeInteractionResponseGeneratorTests\n    {\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator _subject;\n        private MockConsentService _mockConsentService = new MockConsentService();\n        private StubClock _clock = new StubClock();\n\n        public AuthorizeInteractionResponseGeneratorTests()\n        {\n            _subject = new IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator(\n                _clock,\n                TestLogger.Create<IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator>(),\n                _mockConsentService,\n                new MockProfileService());\n        }\n\n\n        [Fact]\n        public async Task Authenticated_User_with_restricted_current_Idp_with_prompt_none_must_error()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client\n                {\n                    EnableLocalLogin = false,\n                    IdentityProviderRestrictions = new List<string>\n                    {\n                        \"some_idp\"\n                    }\n                },\n                PromptModes = new[] { PromptModes.None },\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_with_maxage_with_prompt_none_must_error()\n        {\n            _clock.UtcNowFunc = () => new DateTime(2020, 02, 03, 9, 0, 0);\n\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    AuthenticationTime = new DateTime(2020, 02, 01, 9, 0, 0),\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client\n                {\n                    EnableLocalLogin = true,\n                },\n                PromptModes = new[] { PromptModes.None },\n                MaxAge = 3600\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_with_different_requested_Idp_with_prompt_none_must_error()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client(),\n                AuthenticationContextReferenceClasses = new List<string>{\n                    \"idp:some_idp\"\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                PromptModes = new[] { PromptModes.None }\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_beyond_client_user_sso_lifetime_with_prompt_none_should_error()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client()\n                {\n                    UserSsoLifetime = 3600 // 1h\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = \"local\",\n                    AuthenticationTime = _clock.UtcNow.UtcDateTime.Subtract(TimeSpan.FromSeconds(3700))\n                }.CreatePrincipal(),\n                PromptModes = new[] { PromptModes.None }\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task locally_authenticated_user_but_client_does_not_allow_local_with_prompt_none_should_error()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client()\n                {\n                    EnableLocalLogin = false\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                PromptModes = new[] { PromptModes.None }\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.IsLogin.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/ResponseHandling/AuthorizeInteractionResponseGenerator/AuthorizeInteractionResponseGeneratorTests_Consent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.ResponseHandling.AuthorizeInteractionResponseGenerator\n{\n    public class AuthorizeInteractionResponseGeneratorTests_Consent\n    {\n        private IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator _subject;\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private MockConsentService _mockConsent = new MockConsentService();\n        private MockProfileService _fakeUserService = new MockProfileService();\n\n        private void RequiresConsent(bool value)\n        {\n            _mockConsent.RequiresConsentResult = value;\n        }\n\n        private void AssertUpdateConsentNotCalled()\n        {\n            _mockConsent.ConsentClient.Should().BeNull();\n            _mockConsent.ConsentSubject.Should().BeNull();\n            _mockConsent.ConsentScopes.Should().BeNull();\n        }\n\n        private void AssertUpdateConsentCalled(Client client, ClaimsPrincipal user, params string[] scopes)\n        {\n            _mockConsent.ConsentClient.Should().BeSameAs(client);\n            _mockConsent.ConsentSubject.Should().BeSameAs(user);\n            _mockConsent.ConsentScopes.Should().BeEquivalentTo(scopes);\n        }\n\n        private static IEnumerable<IdentityResource> GetIdentityScopes()\n        {\n            return new IdentityResource[]\n            {\n                new IdentityResources.OpenId(),\n                new IdentityResources.Profile(),\n                new IdentityResources.Email()\n            };\n        }\n\n        private static IEnumerable<ApiResource> GetApiResources()\n        {\n            return new ApiResource[]\n            {\n                new ApiResource\n                {\n                    Name = \"api\",\n                    Scopes = { \"read\", \"write\", \"forbidden\" }\n                }\n             };\n        }\n\n        private static IEnumerable<ApiScope> GetScopes()\n        {\n            return new ApiScope[]\n            {\n                new ApiScope\n                {\n                    Name = \"read\",\n                    DisplayName = \"Read data\",\n                    Emphasize = false\n                },\n                new ApiScope\n                {\n                    Name = \"write\",\n                    DisplayName = \"Write data\",\n                    Emphasize = true\n                },\n                new ApiScope\n                {\n                    Name = \"forbidden\",\n                    DisplayName = \"Forbidden scope\",\n                    Emphasize = true\n                }\n             };\n        }\n\n        public AuthorizeInteractionResponseGeneratorTests_Consent()\n        {\n            _subject = new IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator(\n                new StubClock(),\n                TestLogger.Create<IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator>(),\n                _mockConsent,\n                _fakeUserService);\n        }\n\n        private static ResourceValidationResult GetValidatedResources(params string[] scopes)\n        {\n            var resources = new Resources(GetIdentityScopes(), GetApiResources(), GetScopes());\n            return new ResourceValidationResult(resources).Filter(scopes);\n        }\n\n\n        [Fact]\n        public async Task ProcessConsentAsync_NullRequest_Throws()\n        {\n            Func<Task> act = async () => await _subject.ProcessConsentAsync(null, new ConsentResponse());\n\n            (await act.Should().ThrowAsync<ArgumentNullException>())\n                .And.ParamName.Should().Be(\"request\");\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_AllowsNullConsent()\n        {\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                PromptModes = new[] { OidcConstants.PromptModes.Consent },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            await _subject.ProcessConsentAsync(request, null);\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_PromptModeIsLogin_Throws()\n        {\n            RequiresConsent(true);\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                PromptModes = new[] { OidcConstants.PromptModes.Login },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n\n            Func<Task> act = async () => await _subject.ProcessConsentAsync(request);\n\n            (await act.Should().ThrowAsync<ArgumentException>())\n                .And.Message.Should().Contain(\"PromptMode\");\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_PromptModeIsSelectAccount_Throws()\n        {\n            RequiresConsent(true);\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                PromptModes = new[] { OidcConstants.PromptModes.SelectAccount },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n\n            Func<Task> act = async () => await _subject.ProcessConsentAsync(request);\n\n            (await act.Should().ThrowAsync<ArgumentException>())\n                 .And.Message.Should().Contain(\"PromptMode\");\n        }\n\n\n        [Fact]\n        public async Task ProcessConsentAsync_RequiresConsentButPromptModeIsNone_ReturnsErrorResult()\n        {\n            RequiresConsent(true);\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                PromptModes = new[] { OidcConstants.PromptModes.None },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var result = await _subject.ProcessConsentAsync(request);\n\n            request.WasConsentShown.Should().BeFalse();\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.ConsentRequired);\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_PromptModeIsConsent_NoPriorConsent_ReturnsConsentResult()\n        {\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                PromptModes = new[] { OidcConstants.PromptModes.Consent },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var result = await _subject.ProcessConsentAsync(request);\n            request.WasConsentShown.Should().BeFalse();\n            result.IsConsent.Should().BeTrue();\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_NoPromptMode_ConsentServiceRequiresConsent_NoPriorConsent_ReturnsConsentResult()\n        {\n            RequiresConsent(true);\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                PromptModes = new[] { OidcConstants.PromptModes.Consent },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var result = await _subject.ProcessConsentAsync(request);\n            request.WasConsentShown.Should().BeFalse();\n            result.IsConsent.Should().BeTrue();\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_PromptModeIsConsent_ConsentNotGranted_ReturnsErrorResult()\n        {\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                PromptModes = new[] { OidcConstants.PromptModes.Consent },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n\n            var consent = new ConsentResponse\n            {\n                RememberConsent = false,\n                ScopesValuesConsented = new string[] { }\n            };\n            var result = await _subject.ProcessConsentAsync(request, consent);\n            request.WasConsentShown.Should().BeTrue();\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.AccessDenied);\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_NoPromptMode_ConsentServiceRequiresConsent_ConsentNotGranted_ReturnsErrorResult()\n        {\n            RequiresConsent(true);\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var consent = new ConsentResponse\n            {\n                RememberConsent = false,\n                ScopesValuesConsented = new string[] { }\n            };\n            var result = await _subject.ProcessConsentAsync(request, consent);\n            request.WasConsentShown.Should().BeTrue();\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.AccessDenied);\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_NoPromptMode_ConsentServiceRequiresConsent_ConsentGrantedButMissingRequiredScopes_ReturnsErrorResult()\n        {\n            RequiresConsent(true);\n            var client = new Client { };\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n                Client = client\n            };\n\n            var consent = new ConsentResponse\n            {\n                RememberConsent = false,\n                ScopesValuesConsented = new string[] { \"read\" }\n            };\n\n            var result = await _subject.ProcessConsentAsync(request, consent);\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.AccessDenied);\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_NoPromptMode_ConsentServiceRequiresConsent_ConsentGranted_ScopesSelected_ReturnsConsentResult()\n        {\n            RequiresConsent(true);\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                Client = new Client\n                {\n                    AllowRememberConsent = false\n                },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var consent = new ConsentResponse\n            {\n                RememberConsent = false,\n                ScopesValuesConsented = new string[] { \"openid\", \"read\" }\n            };\n            var result = await _subject.ProcessConsentAsync(request, consent);\n            request.ValidatedResources.Resources.IdentityResources.Count().Should().Be(1);\n            request.ValidatedResources.Resources.ApiScopes.Count().Should().Be(1);\n            \"openid\".Should().Be(request.ValidatedResources.Resources.IdentityResources.Select(x => x.Name).First());\n            \"read\".Should().Be(request.ValidatedResources.Resources.ApiScopes.First().Name);\n            request.WasConsentShown.Should().BeTrue();\n            result.IsConsent.Should().BeFalse();\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_PromptModeConsent_ConsentGranted_ScopesSelected_ReturnsConsentResult()\n        {\n            RequiresConsent(true);\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                Client = new Client\n                {\n                    AllowRememberConsent = false\n                },\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var consent = new ConsentResponse\n            {\n                RememberConsent = false,\n                ScopesValuesConsented = new string[] { \"openid\", \"read\" }\n            };\n            var result = await _subject.ProcessConsentAsync(request, consent);\n            request.ValidatedResources.Resources.IdentityResources.Count().Should().Be(1);\n            request.ValidatedResources.Resources.ApiScopes.Count().Should().Be(1);\n            \"read\".Should().Be(request.ValidatedResources.Resources.ApiScopes.First().Name);\n            request.WasConsentShown.Should().BeTrue();\n            result.IsConsent.Should().BeFalse();\n            AssertUpdateConsentNotCalled();\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_AllowConsentSelected_SavesConsent()\n        {\n            RequiresConsent(true);\n            var client = new Client { AllowRememberConsent = true };\n            var user = new ClaimsPrincipal();\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                Client = client,\n                Subject = user,\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var consent = new ConsentResponse\n            {\n                RememberConsent = true,\n                ScopesValuesConsented = new string[] { \"openid\", \"read\" }\n            };\n            var result = await _subject.ProcessConsentAsync(request, consent);\n            AssertUpdateConsentCalled(client, user, \"openid\", \"read\");\n        }\n\n        [Fact]\n        public async Task ProcessConsentAsync_NotRememberingConsent_DoesNotSaveConsent()\n        {\n            RequiresConsent(true);\n            var client = new Client { AllowRememberConsent = true };\n            var user = new ClaimsPrincipal();\n            var request = new ValidatedAuthorizeRequest()\n            {\n                ResponseMode = OidcConstants.ResponseModes.Fragment,\n                State = \"12345\",\n                RedirectUri = \"https://client.com/callback\",\n                Client = client,\n                Subject = user,\n                RequestedScopes = new List<string> { \"openid\", \"read\", \"write\" },\n                ValidatedResources = GetValidatedResources(\"openid\", \"read\", \"write\"),\n            };\n            var consent = new ConsentResponse\n            {\n                RememberConsent = false,\n                ScopesValuesConsented = new string[] { \"openid\", \"read\" }\n            };\n            var result = await _subject.ProcessConsentAsync(request, consent);\n            AssertUpdateConsentCalled(client, user);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/ResponseHandling/AuthorizeInteractionResponseGenerator/AuthorizeInteractionResponseGeneratorTests_Custom.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.ResponseHandling;\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\nusing static IdentityModel.OidcConstants;\n\nnamespace IdentityServer.UnitTests.ResponseHandling.AuthorizeInteractionResponseGenerator\n{\n    public class CustomAuthorizeInteractionResponseGenerator : IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator\n    {\n        public CustomAuthorizeInteractionResponseGenerator(ISystemClock clock, ILogger<IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator> logger, IConsentService consent, IProfileService profile) : base(clock, logger, consent, profile)\n        {\n        }\n\n        public InteractionResponse ProcessLoginResponse { get; set; }\n        protected internal override Task<InteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request)\n        {\n            if (ProcessLoginResponse != null)\n            {\n                return Task.FromResult(ProcessLoginResponse);\n            }\n\n            return base.ProcessLoginAsync(request);\n        }\n\n        public InteractionResponse ProcessConsentResponse { get; set; }\n        protected internal override Task<InteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, ConsentResponse consent = null)\n        {\n            if (ProcessConsentResponse != null)\n            {\n                return Task.FromResult(ProcessConsentResponse);\n            }\n            return base.ProcessConsentAsync(request, consent);\n        }\n    }\n\n    public class AuthorizeInteractionResponseGeneratorTests_Custom\n    {\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private CustomAuthorizeInteractionResponseGenerator _subject;\n        private MockConsentService _mockConsentService = new MockConsentService();\n        private StubClock _clock = new StubClock();\n\n        public AuthorizeInteractionResponseGeneratorTests_Custom()\n        {\n            _subject = new CustomAuthorizeInteractionResponseGenerator(\n                _clock,\n                TestLogger.Create<IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator>(),\n                _mockConsentService,\n                new MockProfileService());\n        }\n\n\n        [Fact]\n        public async Task ProcessInteractionAsync_with_overridden_login_returns_redirect_should_return_redirect()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client\n                {\n                },\n            };\n\n            _subject.ProcessLoginResponse = new InteractionResponse\n            {\n                RedirectUrl = \"/custom\"\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsRedirect.Should().BeTrue();\n            result.RedirectUrl.Should().Be(\"/custom\");\n        }\n\n        [Fact]\n        public async Task ProcessInteractionAsync_with_prompt_none_and_login_returns_login_should_return_error()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client\n                {\n                },\n                PromptModes = new[] { PromptModes.None },\n            };\n\n            _subject.ProcessLoginResponse = new InteractionResponse\n            {\n                IsLogin = true\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(\"login_required\");\n        }\n\n        [Fact]\n        public async Task ProcessInteractionAsync_with_prompt_none_and_login_returns_redirect_should_return_error()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client\n                {\n                },\n                PromptModes = new[] { PromptModes.None },\n            };\n\n            _subject.ProcessLoginResponse = new InteractionResponse\n            {\n                RedirectUrl = \"/custom\"\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(\"interaction_required\");\n            result.RedirectUrl.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task ProcessInteractionAsync_with_prompt_none_and_consent_returns_consent_should_return_error()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client\n                {\n                },\n                PromptModes = new[] { PromptModes.None },\n            };\n\n            _subject.ProcessConsentResponse = new InteractionResponse\n            {\n                IsConsent = true\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(\"consent_required\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/ResponseHandling/AuthorizeInteractionResponseGenerator/AuthorizeInteractionResponseGeneratorTests_Login.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.ResponseHandling.AuthorizeInteractionResponseGenerator\n{\n    public class AuthorizeInteractionResponseGeneratorTests_Login\n    {\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator _subject;\n        private MockConsentService _mockConsentService = new MockConsentService();\n        private StubClock _clock = new StubClock();\n\n        public AuthorizeInteractionResponseGeneratorTests_Login()\n        {\n            _subject = new IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator(\n                _clock,\n                TestLogger.Create<IdentityServer8.ResponseHandling.AuthorizeInteractionResponseGenerator>(),\n                _mockConsentService,\n                new MockProfileService());\n        }\n\n        [Fact]\n        public async Task Anonymous_User_must_SignIn()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = Principal.Anonymous\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_must_not_SignIn()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client(),\n                ValidatedResources = new ResourceValidationResult(),\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal()\n            };\n\n            var result = await _subject.ProcessInteractionAsync(request);\n\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_with_allowed_current_Idp_must_not_SignIn()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\") {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client \n                {\n                    IdentityProviderRestrictions = new List<string> \n                    {\n                        IdentityServerConstants.LocalIdentityProvider\n                    }\n                }\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_with_restricted_current_Idp_must_SignIn()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal(),\n                Client = new Client\n                {\n                    EnableLocalLogin = false,\n                    IdentityProviderRestrictions = new List<string> \n                    {\n                        \"some_idp\"\n                    }\n                }\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_with_allowed_requested_Idp_must_not_SignIn()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client(),\n                 AuthenticationContextReferenceClasses = new List<string>{\n                    \"idp:\" + IdentityServerConstants.LocalIdentityProvider\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal()\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_with_different_requested_Idp_must_SignIn()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client(),\n                AuthenticationContextReferenceClasses = new List<string>{\n                    \"idp:some_idp\"\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal()\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_within_client_user_sso_lifetime_should_not_signin()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client() {\n                    UserSsoLifetime = 3600 // 1h\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = \"local\",\n                    AuthenticationTime = _clock.UtcNow.UtcDateTime.Subtract(TimeSpan.FromSeconds(10))\n                }.CreatePrincipal()\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Authenticated_User_beyond_client_user_sso_lifetime_should_signin()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client()\n                {\n                    UserSsoLifetime = 3600 // 1h\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = \"local\",\n                    AuthenticationTime = _clock.UtcNow.UtcDateTime.Subtract(TimeSpan.FromSeconds(3700))\n                }.CreatePrincipal()\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task locally_authenticated_user_but_client_does_not_allow_local_should_sign_in()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Client = new Client()\n                {\n                    EnableLocalLogin = false\n                },\n                Subject = new IdentityServerUser(\"123\")\n                {\n                    IdentityProvider = IdentityServerConstants.LocalIdentityProvider\n                }.CreatePrincipal()\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task prompt_login_should_sign_in()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                PromptModes = new[] { OidcConstants.PromptModes.Login },\n                Raw = new NameValueCollection()\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task prompt_select_account_should_sign_in()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                PromptModes = new[] { OidcConstants.PromptModes.SelectAccount },\n                Raw = new NameValueCollection()\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            result.IsLogin.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task prompt_for_signin_should_remove_prompt_from_raw_url()\n        {\n            var request = new ValidatedAuthorizeRequest\n            {\n                ClientId = \"foo\",\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                PromptModes = new[] { OidcConstants.PromptModes.Login },\n                Raw = new NameValueCollection\n                {\n                    { OidcConstants.AuthorizeRequest.Prompt, OidcConstants.PromptModes.Login }\n                }\n            };\n\n            var result = await _subject.ProcessLoginAsync(request);\n\n            request.Raw.AllKeys.Should().NotContain(OidcConstants.AuthorizeRequest.Prompt);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/ResponseHandling/DeviceAuthorizationResponseGeneratorTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.ResponseHandling;\nusing IdentityServer8.Services;\nusing IdentityServer8.Services.Default;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Microsoft.Extensions.Logging.Abstractions;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.ResponseHandling\n{\n    public class DeviceAuthorizationResponseGeneratorTests\n    {\n        private readonly List<IdentityResource> identityResources = new List<IdentityResource> {new IdentityResources.OpenId(), new IdentityResources.Profile()};\n        private readonly List<ApiResource> apiResources = new List<ApiResource> { new ApiResource(\"resource\") { Scopes = {\"api1\" } } };\n        private readonly List<ApiScope> scopes = new List<ApiScope> { new ApiScope(\"api1\") };\n\n        private readonly FakeUserCodeGenerator fakeUserCodeGenerator = new FakeUserCodeGenerator();\n        private readonly IDeviceFlowCodeService deviceFlowCodeService = new DefaultDeviceFlowCodeService(new InMemoryDeviceFlowStore(), new StubHandleGenerationService());\n        private readonly IdentityServerOptions options = new IdentityServerOptions();\n        private readonly StubClock clock = new StubClock();\n        \n        private readonly DeviceAuthorizationResponseGenerator generator;\n        private readonly DeviceAuthorizationRequestValidationResult testResult;\n        private const string TestBaseUrl = \"http://localhost:5000/\";\n\n        public DeviceAuthorizationResponseGeneratorTests()\n        {\n            testResult = new DeviceAuthorizationRequestValidationResult(new ValidatedDeviceAuthorizationRequest\n            {\n                Client = new Client {ClientId = Guid.NewGuid().ToString()},\n                IsOpenIdRequest = true,\n                ValidatedResources = new ResourceValidationResult()\n            });\n\n            generator = new DeviceAuthorizationResponseGenerator(\n                options,\n                new DefaultUserCodeService(new IUserCodeGenerator[] {new NumericUserCodeGenerator(), fakeUserCodeGenerator }),\n                deviceFlowCodeService,\n                clock,\n                new NullLogger<DeviceAuthorizationResponseGenerator>());\n        }\n\n        [Fact]\n        public async Task ProcessAsync_when_valiationresult_null_exect_exception()\n        {\n            Func<Task> act = async () => await generator.ProcessAsync(null, TestBaseUrl);\n            await act.Should().ThrowAsync<ArgumentNullException>();\n        }\n\n        [Fact]\n        public void ProcessAsync_when_valiationresult_client_null_exect_exception()\n        {\n            var validationResult = new DeviceAuthorizationRequestValidationResult(new ValidatedDeviceAuthorizationRequest());\n            Func <Task> act = () => generator.ProcessAsync(validationResult, TestBaseUrl);\n            act.Should().ThrowAsync<ArgumentNullException>();\n        }\n\n        [Fact]\n        public void ProcessAsync_when_baseurl_null_exect_exception()\n        {\n            Func<Task> act = () => generator.ProcessAsync(testResult, null);\n            act.Should().ThrowAsync<ArgumentException>();\n        }\n\n        [Fact]\n        public async Task ProcessAsync_when_user_code_collision_expect_retry()\n        {\n            var creationTime = DateTime.UtcNow;\n            clock.UtcNowFunc = () => creationTime;\n\n            testResult.ValidatedRequest.Client.UserCodeType = FakeUserCodeGenerator.UserCodeTypeValue;\n            await deviceFlowCodeService.StoreDeviceAuthorizationAsync(FakeUserCodeGenerator.TestCollisionUserCode, new DeviceCode());\n\n            var response = await generator.ProcessAsync(testResult, TestBaseUrl);\n\n            response.UserCode.Should().Be(FakeUserCodeGenerator.TestUniqueUserCode);\n        }\n\n        [Fact]\n        public async Task ProcessAsync_when_user_code_collision_retry_limit_reached_expect_error()\n        {\n            var creationTime = DateTime.UtcNow;\n            clock.UtcNowFunc = () => creationTime;\n\n            fakeUserCodeGenerator.RetryLimit = 1;\n            testResult.ValidatedRequest.Client.UserCodeType = FakeUserCodeGenerator.UserCodeTypeValue;\n            await deviceFlowCodeService.StoreDeviceAuthorizationAsync(FakeUserCodeGenerator.TestCollisionUserCode, new DeviceCode());\n\n            await Assert.ThrowsAsync<InvalidOperationException>(() => generator.ProcessAsync(testResult, TestBaseUrl));\n        }\n\n        [Fact]\n        public async Task ProcessAsync_when_generated_expect_user_code_stored()\n        {\n            var creationTime = DateTime.UtcNow;\n            clock.UtcNowFunc = () => creationTime;\n\n            testResult.ValidatedRequest.RequestedScopes = new List<string> { \"openid\", \"api1\" };\n            testResult.ValidatedRequest.ValidatedResources = new ResourceValidationResult(new Resources(\n                identityResources.Where(x=>x.Name == \"openid\"), \n                apiResources.Where(x=>x.Name == \"resource\"), \n                scopes.Where(x=>x.Name == \"api1\")));\n\n            var response = await generator.ProcessAsync(testResult, TestBaseUrl);\n\n            response.UserCode.Should().NotBeNullOrWhiteSpace();\n\n            var userCode = await deviceFlowCodeService.FindByUserCodeAsync(response.UserCode);\n            userCode.Should().NotBeNull();\n            userCode.ClientId.Should().Be(testResult.ValidatedRequest.Client.ClientId);\n            userCode.Lifetime.Should().Be(testResult.ValidatedRequest.Client.DeviceCodeLifetime);\n            userCode.CreationTime.Should().Be(creationTime);\n            userCode.Subject.Should().BeNull();\n            userCode.AuthorizedScopes.Should().BeNull();\n\n            userCode.RequestedScopes.Should().Contain(testResult.ValidatedRequest.RequestedScopes);\n        }\n\n        [Fact]\n        public async Task ProcessAsync_when_generated_expect_device_code_stored()\n        {\n            var creationTime = DateTime.UtcNow;\n            clock.UtcNowFunc = () => creationTime;\n\n            var response = await generator.ProcessAsync(testResult, TestBaseUrl);\n\n            response.DeviceCode.Should().NotBeNullOrWhiteSpace();\n            response.Interval.Should().Be(options.DeviceFlow.Interval);\n            \n            var deviceCode = await deviceFlowCodeService.FindByDeviceCodeAsync(response.DeviceCode);\n            deviceCode.Should().NotBeNull();\n            deviceCode.ClientId.Should().Be(testResult.ValidatedRequest.Client.ClientId);\n            deviceCode.IsOpenId.Should().Be(testResult.ValidatedRequest.IsOpenIdRequest);\n            deviceCode.Lifetime.Should().Be(testResult.ValidatedRequest.Client.DeviceCodeLifetime);\n            deviceCode.CreationTime.Should().Be(creationTime);\n            deviceCode.Subject.Should().BeNull();\n            deviceCode.AuthorizedScopes.Should().BeNull();\n            \n            response.DeviceCodeLifetime.Should().Be(deviceCode.Lifetime);\n        }\n\n        [Fact]\n        public async Task ProcessAsync_when_DeviceVerificationUrl_is_relative_uri_expect_correct_VerificationUris()\n        {\n            const string baseUrl = \"http://localhost:5000/\";\n            options.UserInteraction.DeviceVerificationUrl = \"/device\";\n            options.UserInteraction.DeviceVerificationUserCodeParameter = \"userCode\";\n\n            var response = await generator.ProcessAsync(testResult, baseUrl);\n\n            response.VerificationUri.Should().Be(\"http://localhost:5000/device\");\n            response.VerificationUriComplete.Should().StartWith(\"http://localhost:5000/device?userCode=\");\n        }\n\n        [Fact]\n        public async Task ProcessAsync_when_DeviceVerificationUrl_is_absolute_uri_expect_correct_VerificationUris()\n        {\n            const string baseUrl = \"http://localhost:5000/\";\n            options.UserInteraction.DeviceVerificationUrl = \"http://short/device\";\n            options.UserInteraction.DeviceVerificationUserCodeParameter = \"userCode\";\n\n            var response = await generator.ProcessAsync(testResult, baseUrl);\n\n            response.VerificationUri.Should().Be(\"http://short/device\");\n            response.VerificationUriComplete.Should().StartWith(\"http://short/device?userCode=\");\n        }\n    }\n\n    internal class FakeUserCodeGenerator : IUserCodeGenerator\n    {\n        public const string UserCodeTypeValue = \"Collider\";\n        public const string TestUniqueUserCode = \"123\";\n        public const string TestCollisionUserCode = \"321\";\n        private int tryCount = 0;\n        private int retryLimit = 2;\n\n\n        public string UserCodeType => UserCodeTypeValue;\n\n        public int RetryLimit\n        {\n            get => retryLimit;\n            set => retryLimit = value;\n        }\n\n        public Task<string> GenerateAsync()\n        {\n            if (tryCount == 0)\n            {\n                tryCount++;\n                return Task.FromResult(TestCollisionUserCode);\n            }\n\n            tryCount++;\n            return Task.FromResult(TestUniqueUserCode);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/ResponseHandling/UserInfoResponseGeneratorTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Text.Json;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.ResponseHandling;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.ResponseHandling\n{\n    public class UserInfoResponseGeneratorTests\n    {\n        private UserInfoResponseGenerator _subject;\n        private MockProfileService _mockProfileService = new MockProfileService();\n        private ClaimsPrincipal _user;\n        private Client _client;\n\n        private InMemoryResourcesStore _resourceStore;\n        private List<IdentityResource> _identityResources = new List<IdentityResource>();\n        private List<ApiResource> _apiResources = new List<ApiResource>();\n        private List<ApiScope> _apiScopes = new List<ApiScope>();\n\n        public UserInfoResponseGeneratorTests()\n        {\n            _client = new Client\n            {\n                ClientId = \"client\"\n            };\n\n            _user = new IdentityServerUser(\"bob\")\n            {\n                AdditionalClaims =\n                {\n                    new Claim(\"foo\", \"foo1\"),\n                    new Claim(\"foo\", \"foo2\"),\n                    new Claim(\"bar\", \"bar1\"),\n                    new Claim(\"bar\", \"bar2\")\n                }\n            }.CreatePrincipal();\n\n            _resourceStore = new InMemoryResourcesStore(_identityResources, _apiResources, _apiScopes);\n            _subject = new UserInfoResponseGenerator(_mockProfileService, _resourceStore, TestLogger.Create<UserInfoResponseGenerator>());\n        }\n\n        [Fact]\n        public async Task GetRequestedClaimTypesAsync_when_no_scopes_requested_should_return_empty_claim_types()\n        {\n            var resources = await _subject.GetRequestedResourcesAsync(null);\n            var claims = await _subject.GetRequestedClaimTypesAsync(resources);\n            claims.Should().BeEquivalentTo(new string[] { });\n        }\n\n        [Fact]\n        public async Task GetRequestedClaimTypesAsync_should_return_correct_identity_claims()\n        {\n            _identityResources.Add(new IdentityResource(\"id1\", new[] { \"c1\", \"c2\" }));\n            _identityResources.Add(new IdentityResource(\"id2\", new[] { \"c2\", \"c3\" }));\n\n            var resources = await _subject.GetRequestedResourcesAsync(new[] { \"id1\", \"id2\", \"id3\" });\n            var claims = await _subject.GetRequestedClaimTypesAsync(resources);\n            claims.Should().BeEquivalentTo(new string[] { \"c1\", \"c2\", \"c3\" });\n        }\n\n        [Fact]\n        public async Task GetRequestedClaimTypesAsync_should_only_return_enabled_identity_claims()\n        {\n            _identityResources.Add(new IdentityResource(\"id1\", new[] { \"c1\", \"c2\" }) { Enabled = false });\n            _identityResources.Add(new IdentityResource(\"id2\", new[] { \"c2\", \"c3\" }));\n\n            var resources = await _subject.GetRequestedResourcesAsync(new[] { \"id1\", \"id2\", \"id3\" });\n            var claims = await _subject.GetRequestedClaimTypesAsync(resources);\n            claims.Should().BeEquivalentTo(new string[] { \"c2\", \"c3\" });\n        }\n\n        [Fact]\n        public async Task ProcessAsync_should_call_profile_service_with_requested_claim_types()\n        {\n            _identityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _identityResources.Add(new IdentityResource(\"id2\", new[] { \"bar\" }));\n\n            var result = new UserInfoRequestValidationResult\n            {\n                Subject = _user,\n                TokenValidationResult = new TokenValidationResult\n                {\n                    Claims = new List<Claim>\n                    {\n                        { new Claim(\"scope\", \"id1\") },\n                        { new Claim(\"scope\", \"id2\") },\n                        { new Claim(\"scope\", \"id3\") }\n                    },\n                    Client = _client\n                }\n            };\n\n            var claims = await _subject.ProcessAsync(result);\n\n            _mockProfileService.GetProfileWasCalled.Should().BeTrue();\n            _mockProfileService.ProfileContext.RequestedClaimTypes.Should().BeEquivalentTo(new[] { \"foo\", \"bar\" });\n        }\n\n        [Fact]\n        public async Task ProcessAsync_should_return_claims_issued_by_profile_service()\n        {\n            _identityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _identityResources.Add(new IdentityResource(\"id2\", new[] { \"bar\" }));\n            \n            var address = new\n            {\n                street_address = \"One Hacker Way\",\n                locality = \"Heidelberg\",\n                postal_code = 69118,\n                country = \"Germany\"\n            };\n            \n            _mockProfileService.ProfileClaims = new[]\n            {\n                new Claim(\"email\", \"fred@gmail.com\"),\n                new Claim(\"name\", \"fred jones\"),\n                new Claim(\"address\", @\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\", IdentityServerConstants.ClaimValueTypes.Json),\n                new Claim(\"address2\", JsonSerializer.Serialize(address), IdentityServerConstants.ClaimValueTypes.Json)\n            };\n\n            var result = new UserInfoRequestValidationResult\n            {\n                Subject = _user,\n                TokenValidationResult = new TokenValidationResult\n                {\n                    Claims = new List<Claim>\n                    {\n                        { new Claim(\"scope\", \"id1\") },\n                        { new Claim(\"scope\", \"id2\") },\n                        { new Claim(\"scope\", \"id3\") }\n                    },\n                    Client = _client\n                }\n            };\n\n            var claims = await _subject.ProcessAsync(result);\n\n            claims.Should().ContainKey(\"email\");\n            claims[\"email\"].Should().Be(\"fred@gmail.com\");\n            claims.Should().ContainKey(\"name\");\n            claims[\"name\"].Should().Be(\"fred jones\");\n            \n            // this will be treated as a string because this is not valid JSON from the System.Text library point of view\n            claims.Should().ContainKey(\"address\");\n            claims[\"address\"].Should().Be(\"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }\");\n            \n            // this is a JsonElement\n            claims.Should().ContainKey(\"address2\");\n            claims[\"address2\"].ToString().Should().Be(\"{\\\"street_address\\\":\\\"One Hacker Way\\\",\\\"locality\\\":\\\"Heidelberg\\\",\\\"postal_code\\\":69118,\\\"country\\\":\\\"Germany\\\"}\");\n        }\n\n        [Fact]\n        public async Task ProcessAsync_should_return_sub_from_user()\n        {\n            _identityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _identityResources.Add(new IdentityResource(\"id2\", new[] { \"bar\" }));\n\n            var result = new UserInfoRequestValidationResult\n            {\n                Subject = _user,\n                TokenValidationResult = new TokenValidationResult\n                {\n                    Claims = new List<Claim>\n                    {\n                        { new Claim(\"scope\", \"id1\") },\n                        { new Claim(\"scope\", \"id2\") },\n                        { new Claim(\"scope\", \"id3\") }\n                    },\n                    Client = _client\n                }\n            };\n\n            var claims = await _subject.ProcessAsync(result);\n\n            claims.Should().ContainKey(\"sub\");\n            claims[\"sub\"].Should().Be(\"bob\");\n        }\n\n        [Fact]\n        public async Task ProcessAsync_should_throw_if_incorrect_sub_issued_by_profile_service()\n        {\n            _identityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _identityResources.Add(new IdentityResource(\"id2\", new[] { \"bar\" }));\n            _mockProfileService.ProfileClaims = new[]\n            {\n                new Claim(\"sub\", \"fred\")\n            };\n\n            var result = new UserInfoRequestValidationResult\n            {\n                Subject = _user,\n                TokenValidationResult = new TokenValidationResult\n                {\n                    Claims = new List<Claim>\n                    {\n                        { new Claim(\"scope\", \"id1\") },\n                        { new Claim(\"scope\", \"id2\") },\n                        { new Claim(\"scope\", \"id3\") }\n                    },\n                    Client = _client\n                }\n            };\n\n            Func<Task> act = async () => await _subject.ProcessAsync(result);\n\n            (await act.Should().ThrowAsync<InvalidOperationException>())\n                .And.Message.Should().Contain(\"subject\");\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultClaimsServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultClaimsServiceTests\n    {\n        private DefaultClaimsService _subject;\n        private MockProfileService _mockMockProfileService = new MockProfileService();\n\n        private ClaimsPrincipal _user;\n        private Client _client;\n        private ValidatedRequest _validatedRequest;\n        private Resources _resources = new Resources();\n\n        public ResourceValidationResult ResourceValidationResult => new ResourceValidationResult(_resources);\n\n        public DefaultClaimsServiceTests()\n        {\n            _client = new Client\n            {\n                ClientId = \"client\",\n                Claims = { new ClientClaim(\"some_claim\", \"some_claim_value\") }\n            };\n\n            _user = new IdentityServerUser(\"bob\")\n            {\n                IdentityProvider = \"idp\",\n                AuthenticationMethods = { OidcConstants.AuthenticationMethods.Password },\n                AuthenticationTime = new System.DateTime(2000, 1, 1),\n                AdditionalClaims =\n                {\n                    new Claim(\"foo\", \"foo1\"),\n                    new Claim(\"foo\", \"foo2\"),\n                    new Claim(\"bar\", \"bar1\"),\n                    new Claim(\"bar\", \"bar2\"),\n                    new Claim(JwtClaimTypes.AuthenticationContextClassReference, \"acr1\")\n                }\n            }.CreatePrincipal();\n\n            _subject = new DefaultClaimsService(_mockMockProfileService, TestLogger.Create<DefaultClaimsService>());\n\n            _validatedRequest = new ValidatedRequest();\n            _validatedRequest.Options = new IdentityServerOptions();\n            _validatedRequest.SetClient(_client);\n        }\n\n        [Fact]\n        public async Task GetIdentityTokenClaimsAsync_should_return_standard_user_claims()\n        {\n            var claims = await _subject.GetIdentityTokenClaimsAsync(_user, ResourceValidationResult, false, _validatedRequest);\n\n            var types = claims.Select(x => x.Type);\n            types.Should().Contain(JwtClaimTypes.Subject);\n            types.Should().Contain(JwtClaimTypes.AuthenticationTime);\n            types.Should().Contain(JwtClaimTypes.IdentityProvider);\n            types.Should().Contain(JwtClaimTypes.AuthenticationMethod);\n            types.Should().Contain(JwtClaimTypes.AuthenticationContextClassReference);\n        }\n\n        [Fact]\n        public async Task GetIdentityTokenClaimsAsync_should_return_minimal_claims_when_includeAllIdentityClaims_is_false()\n        {\n            _resources.IdentityResources.Add(new IdentityResource(\"id_scope\", new[] { \"foo\" }));\n\n            var claims = await _subject.GetIdentityTokenClaimsAsync(_user, ResourceValidationResult, false, _validatedRequest);\n\n            _mockMockProfileService.GetProfileWasCalled.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task GetIdentityTokenClaimsAsync_should_return_all_claims_when_includeAllIdentityClaims_is_true()\n        {\n            _resources.IdentityResources.Add(new IdentityResource(\"id_scope\", new[] { \"foo\" }));\n            _mockMockProfileService.ProfileClaims.Add(new Claim(\"foo\", \"foo1\"));\n\n            var claims = await _subject.GetIdentityTokenClaimsAsync(_user, ResourceValidationResult, true, _validatedRequest);\n\n            _mockMockProfileService.GetProfileWasCalled.Should().BeTrue();\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().Contain(\"foo\");\n        }\n\n        [Fact]\n        public async Task GetIdentityTokenClaimsAsync_should_return_all_claims_when_client_configured_for_always_include_all_claims_in_id_token()\n        {\n            _client.AlwaysIncludeUserClaimsInIdToken = true;\n\n            _resources.IdentityResources.Add(new IdentityResource(\"id_scope\", new[] { \"foo\" }));\n            _mockMockProfileService.ProfileClaims.Add(new Claim(\"foo\", \"foo1\"));\n\n            var claims = await _subject.GetIdentityTokenClaimsAsync(_user, ResourceValidationResult, false, _validatedRequest);\n\n            _mockMockProfileService.GetProfileWasCalled.Should().BeTrue();\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().Contain(\"foo\");\n        }\n\n        [Fact]\n        public async Task GetIdentityTokenClaimsAsync_should_filter_protocol_claims_from_profile_service()\n        {\n            _resources.IdentityResources.Add(new IdentityResource(\"id_scope\", new[] { \"foo\" }));\n            _mockMockProfileService.ProfileClaims.Add(new Claim(\"aud\", \"bar\"));\n\n            var claims = await _subject.GetIdentityTokenClaimsAsync(_user, ResourceValidationResult, true, _validatedRequest);\n\n            claims.Count(x => x.Type == \"aud\" && x.Value == \"bar\").Should().Be(0);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_contain_client_id()\n        {\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            claims.Count(x => x.Type == JwtClaimTypes.ClientId && x.Value == _client.ClientId).Should().Be(1);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_client_claims_should_be_prefixed_with_default_value()\n        {\n            var claims = await _subject.GetAccessTokenClaimsAsync(null, ResourceValidationResult, _validatedRequest);\n\n            claims.Count(x => x.Type == \"client_some_claim\" && x.Value == \"some_claim_value\").Should().Be(1);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_client_claims_should_be_prefixed_with_custom_value()\n        {\n            _validatedRequest.Client.ClientClaimsPrefix = \"custom_prefix_\";\n            var claims = await _subject.GetAccessTokenClaimsAsync(null, ResourceValidationResult, _validatedRequest);\n\n            claims.Count(x => x.Type == \"custom_prefix_some_claim\" && x.Value == \"some_claim_value\").Should().Be(1);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_contain_client_claims_when_no_subject()\n        {\n            _validatedRequest.Client.ClientClaimsPrefix = null;\n            var claims = await _subject.GetAccessTokenClaimsAsync(null, ResourceValidationResult, _validatedRequest);\n\n            claims.Count(x => x.Type == \"some_claim\" && x.Value == \"some_claim_value\").Should().Be(1);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_contain_client_claims_when_configured_to_send_client_claims()\n        {\n            _validatedRequest.Client.ClientClaimsPrefix = null;\n            _validatedRequest.Client.AlwaysSendClientClaims = true;\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            claims.Count(x => x.Type == \"some_claim\" && x.Value == \"some_claim_value\").Should().Be(1);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_contain_scopes()\n        {\n            _resources.IdentityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _resources.IdentityResources.Add(new IdentityResource(\"id2\", new[] { \"bar\" }));\n            _resources.ApiScopes.Add(new ApiScope(\"api1\"));\n            _resources.ApiScopes.Add(new ApiScope(\"api2\"));\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            var scopes = claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n            scopes.Count().Should().Be(4);\n            scopes.ToArray().Should().BeEquivalentTo(new string[] { \"api1\", \"api2\", \"id1\", \"id2\" });\n        }\n        \n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_contain_parameterized_scope_values()\n        {\n            _resources.ApiScopes.Add(new ApiScope(\"api\"));\n            var resourceResult = new ResourceValidationResult()\n            {\n                Resources = _resources,\n                ParsedScopes = { new ParsedScopeValue(\"api:123\", \"api\", \"123\") }\n            };\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, resourceResult, _validatedRequest);\n\n            var scopes = claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n            scopes.Count().Should().Be(1);\n            scopes.ToArray().Should().BeEquivalentTo(new string[] { \"api:123\" });\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_when_no_ApiScopes_should_not_contain_scopes()\n        {\n            _resources.ApiResources.Add(new ApiResource(\"api1\"));\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            var scopes = claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n            scopes.Count().Should().Be(0);\n        }\n        \n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_only_consider_parsed_scope_values_and_not_ApiScope()\n        {\n            // arguably, if this situation arises, then the ResourceValidationResult was not populated properly\n            // with ParsedScopes matching ApiScopes\n            _resources.ApiScopes.Add(new ApiScope(\"api1\"));\n            var resourceResult = new ResourceValidationResult()\n            {\n                Resources = _resources,\n                ParsedScopes = { new ParsedScopeValue(\"api2\") }\n            };\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, resourceResult, _validatedRequest);\n\n            var scopes = claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n            scopes.Count().Should().Be(1);\n            scopes.ToArray().Should().BeEquivalentTo(new string[] { \"api2\" });\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_when_multiple_resources_with_same_scope_should_contain_scope_once()\n        {\n            _resources.OfflineAccess = false;\n            _resources.IdentityResources.Clear();\n            _resources.ApiResources.Clear();\n            _resources.ApiScopes.Clear();\n\n            _resources.ApiResources.Add(new ApiResource { Name = \"api1\", Scopes = { \"resource\" } });\n            _resources.ApiResources.Add(new ApiResource { Name = \"api2\", Scopes = { \"resource\" } });\n            _resources.ApiResources.Add(new ApiResource { Name = \"api3\", Scopes = { \"resource\" } });\n            _resources.ApiScopes.Add(new ApiScope(\"resource\"));\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            var scopes = claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n            scopes.Count().Should().Be(1);\n            scopes.ToArray().Should().BeEquivalentTo(new string[] { \"resource\" });\n        }\n        \n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_contain_offline_scope()\n        {\n            _resources.IdentityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _resources.IdentityResources.Add(new IdentityResource(\"id2\", new[] { \"bar\" }));\n            _resources.ApiResources.Add(new ApiResource(\"api1\"));\n            _resources.ApiResources.Add(new ApiResource(\"api2\"));\n            _resources.OfflineAccess = true;\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            var scopes = claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n            scopes.Should().Contain(IdentityServerConstants.StandardScopes.OfflineAccess);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_not_contain_offline_scope_if_no_user()\n        {\n            _resources.IdentityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _resources.IdentityResources.Add(new IdentityResource(\"id2\", new[] { \"bar\" }));\n            _resources.ApiResources.Add(new ApiResource(\"api1\"));\n            _resources.ApiResources.Add(new ApiResource(\"api2\"));\n            _resources.OfflineAccess = true;\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(null, ResourceValidationResult, _validatedRequest);\n\n            var scopes = claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n            scopes.Should().NotContain(IdentityServerConstants.StandardScopes.OfflineAccess);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_return_standard_user_claims()\n        {\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            var types = claims.Select(x => x.Type);\n            types.Should().Contain(JwtClaimTypes.Subject);\n            types.Should().Contain(JwtClaimTypes.AuthenticationTime);\n            types.Should().Contain(JwtClaimTypes.IdentityProvider);\n            types.Should().Contain(JwtClaimTypes.AuthenticationMethod);\n            types.Should().Contain(JwtClaimTypes.AuthenticationContextClassReference);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_only_contain_api_claims()\n        {\n            _resources.IdentityResources.Add(new IdentityResource(\"id1\", new[] { \"foo\" }));\n            _resources.ApiResources.Add(new ApiResource(\"api1\", new string[] { \"bar\" }));\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            _mockMockProfileService.GetProfileWasCalled.Should().BeTrue();\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().NotContain(\"foo\");\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().Contain(\"bar\");\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_filter_protocol_claims_from_profile_service()\n        {\n            _resources.ApiResources.Add(new ApiResource(\"api1\", new[] { \"foo\" }));\n            _mockMockProfileService.ProfileClaims.Add(new Claim(\"aud\", \"bar\"));\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            claims.Count(x => x.Type == \"aud\" && x.Value == \"bar\").Should().Be(0);\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_request_api_claims()\n        {\n            _resources.ApiResources.Add(new ApiResource(\"api1\", new[] { \"foo\" }));\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().Contain(\"foo\");\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_request_api_scope_claims()\n        {\n            _resources.ApiResources.Add(\n                new ApiResource(\"api\")\n                {\n                    Scopes = { \"api1\" }\n                }\n            );\n            _resources.ApiScopes.Add(\n                new ApiScope(\"api1\")\n                {\n                    UserClaims = { \"foo\" }\n                }\n            );\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().Contain(\"foo\");\n        }\n\n        [Fact]\n        public async Task GetAccessTokenClaimsAsync_should_request_both_api_and_api_scope_claims()\n        {\n            _resources.ApiResources.Add(\n                new ApiResource(\"api\")\n                {\n                    UserClaims = { \"foo\" },\n                    Scopes = { \"api1\" } \n                }\n            );\n            _resources.ApiScopes.Add(\n                new ApiScope(\"api1\")\n                {\n                    UserClaims = { \"bar\" }\n                }\n            );\n\n            var claims = await _subject.GetAccessTokenClaimsAsync(_user, ResourceValidationResult, _validatedRequest);\n\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().Contain(\"foo\");\n            _mockMockProfileService.ProfileContext.RequestedClaimTypes.Should().Contain(\"bar\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultConsentServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultConsentServiceTests\n    {\n        private DefaultConsentService _subject;\n        private MockProfileService _mockMockProfileService = new MockProfileService();\n\n        private ClaimsPrincipal _user;\n        private Client _client;\n        private TestUserConsentStore _userConsentStore = new TestUserConsentStore();\n        private StubClock _clock = new StubClock();\n\n        private DateTime now;\n\n        public DefaultConsentServiceTests()\n        {\n            _clock.UtcNowFunc = () => UtcNow;\n\n            _client = new Client\n            {\n                ClientId = \"client\",\n                RequireConsent = true,\n                RequirePkce = false\n            };\n\n            _user = new IdentityServerUser(\"bob\")\n            {\n                AdditionalClaims =\n                {\n                    new Claim(\"foo\", \"foo1\"),\n                    new Claim(\"foo\", \"foo2\"),\n                    new Claim(\"bar\", \"bar1\"),\n                    new Claim(\"bar\", \"bar2\"),\n                    new Claim(JwtClaimTypes.AuthenticationContextClassReference, \"acr1\")\n                }\n            }.CreatePrincipal();\n\n            _subject = new DefaultConsentService(_clock, _userConsentStore, TestLogger.Create<DefaultConsentService>());\n        }\n\n        public DateTime UtcNow\n        {\n            get\n            {\n                if (now > DateTime.MinValue) return now;\n                return DateTime.UtcNow;\n            }\n        }\n\n        [Fact]\n        public async Task UpdateConsentAsync_when_client_does_not_allow_remember_consent_should_not_update_store()\n        {\n            _client.AllowRememberConsent = false;\n\n            await _subject.UpdateConsentAsync(_user, _client, new [] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            var consent = await _userConsentStore.GetUserConsentAsync(_user.GetSubjectId(), _client.ClientId);\n            consent.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task UpdateConsentAsync_should_persist_consent()\n        {\n            await _subject.UpdateConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            var consent = await _userConsentStore.GetUserConsentAsync(_user.GetSubjectId(), _client.ClientId);\n            consent.Scopes.Count().Should().Be(2);\n            consent.Scopes.Should().Contain(\"scope1\");\n            consent.Scopes.Should().Contain(\"scope2\");\n        }\n\n        [Fact]\n        public async Task UpdateConsentAsync_empty_scopes_should_should_remove_consent()\n        {\n            await _subject.UpdateConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            await _subject.UpdateConsentAsync(_user, _client, new ParsedScopeValue[] { });\n\n            var consent = await _userConsentStore.GetUserConsentAsync(_user.GetSubjectId(), _client.ClientId);\n            consent.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_client_does_not_require_consent_should_not_require_consent()\n        {\n            _client.RequireConsent = false;\n\n            var result = await _subject.RequiresConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            result.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_client_does_not_allow_remember_consent_should_require_consent()\n        {\n            _client.AllowRememberConsent = false;\n\n            var result = await _subject.RequiresConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            result.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_no_scopes_should_not_require_consent()\n        {\n            var result = await _subject.RequiresConsentAsync(_user, _client, new ParsedScopeValue[] { });\n\n            result.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_offline_access_should_require_consent()\n        {\n            var result = await _subject.RequiresConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"offline_access\") });\n\n            result.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_no_prior_consent_should_require_consent()\n        {\n            var result = await _subject.RequiresConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            result.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_prior_consent_should_not_require_consent()\n        {\n            await _subject.UpdateConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            var result = await _subject.RequiresConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            result.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_prior_consent_with_more_scopes_should_not_require_consent()\n        {\n            await _subject.UpdateConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\"), new ParsedScopeValue(\"scope3\") });\n\n            var result = await _subject.RequiresConsentAsync(_user, _client, new [] { new ParsedScopeValue(\"scope2\") });\n\n            result.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_prior_consent_with_too_few_scopes_should_require_consent()\n        {\n            await _subject.UpdateConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope2\"), new ParsedScopeValue(\"scope3\") });\n\n            var result = await _subject.RequiresConsentAsync(_user, _client, new[] { new ParsedScopeValue(\"scope1\"), new ParsedScopeValue(\"scope2\") });\n\n            result.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_expired_consent_should_require_consent()\n        {\n            now = DateTime.UtcNow;\n\n            var scopes = new[] { new ParsedScopeValue(\"foo\"), new ParsedScopeValue(\"bar\") };\n            _client.ConsentLifetime = 2;\n\n            await _subject.UpdateConsentAsync(_user, _client, scopes);\n\n            now = now.AddSeconds(3);\n\n            var result = await _subject.RequiresConsentAsync(_user, _client, scopes);\n\n            result.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task RequiresConsentAsync_expired_consent_should_remove_consent()\n        {\n            now = DateTime.UtcNow;\n\n            var scopes = new[] { new ParsedScopeValue(\"foo\"), new ParsedScopeValue(\"bar\") };\n            _client.ConsentLifetime = 2;\n\n            await _subject.UpdateConsentAsync(_user, _client, scopes);\n\n            now = now.AddSeconds(3);\n\n            await _subject.RequiresConsentAsync(_user, _client, scopes);\n\n            var result = await _userConsentStore.GetUserConsentAsync(_user.GetSubjectId(), _client.ClientId);\n\n            result.Should().BeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultCorsPolicyServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Services;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultCorsPolicyServiceTests\n    {\n        private const string Category = \"DefaultCorsPolicyService\";\n\n        private DefaultCorsPolicyService subject;\n\n        public DefaultCorsPolicyServiceTests()\n        {\n            subject = new DefaultCorsPolicyService(TestLogger.Create<DefaultCorsPolicyService>());\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IsOriginAllowed_null_param_ReturnsFalse()\n        {\n            (await subject.IsOriginAllowedAsync(null)).Should().Be(false);\n            (await subject.IsOriginAllowedAsync(String.Empty)).Should().Be(false);\n            (await subject.IsOriginAllowedAsync(\"    \")).Should().Be(false);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IsOriginAllowed_OriginIsAllowed_ReturnsTrue()\n        {\n            subject.AllowedOrigins.Add(\"http://foo\");\n            (await subject.IsOriginAllowedAsync(\"http://foo\")).Should().Be(true);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IsOriginAllowed_OriginIsNotAllowed_ReturnsFalse()\n        {\n            subject.AllowedOrigins.Add(\"http://foo\");\n            (await subject.IsOriginAllowedAsync(\"http://bar\")).Should().Be(false);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IsOriginAllowed_OriginIsInAllowedList_ReturnsTrue()\n        {\n            subject.AllowedOrigins.Add(\"http://foo\");\n            subject.AllowedOrigins.Add(\"http://bar\");\n            subject.AllowedOrigins.Add(\"http://baz\");\n            (await subject.IsOriginAllowedAsync(\"http://bar\")).Should().Be(true);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IsOriginAllowed_OriginIsNotInAllowedList_ReturnsFalse()\n        {\n            subject.AllowedOrigins.Add(\"http://foo\");\n            subject.AllowedOrigins.Add(\"http://bar\");\n            subject.AllowedOrigins.Add(\"http://baz\");\n            (await subject.IsOriginAllowedAsync(\"http://quux\")).Should().Be(false);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task  IsOriginAllowed_AllowAllTrue_ReturnsTrue()\n        {\n            subject.AllowAll = true;\n            (await subject.IsOriginAllowedAsync(\"http://foo\")).Should().Be(true);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultIdentityServerInteractionServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultIdentityServerInteractionServiceTests\n    {\n        private DefaultIdentityServerInteractionService _subject;\n\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private MockHttpContextAccessor _mockMockHttpContextAccessor;\n        private MockMessageStore<LogoutNotificationContext> _mockEndSessionStore = new MockMessageStore<LogoutNotificationContext>();\n        private MockMessageStore<LogoutMessage> _mockLogoutMessageStore = new MockMessageStore<LogoutMessage>();\n        private MockMessageStore<ErrorMessage> _mockErrorMessageStore = new MockMessageStore<ErrorMessage>();\n        private MockConsentMessageStore _mockConsentStore = new MockConsentMessageStore();\n        private MockPersistedGrantService _mockPersistedGrantService = new MockPersistedGrantService();\n        private MockUserSession _mockUserSession = new MockUserSession();\n        private MockReturnUrlParser _mockReturnUrlParser = new MockReturnUrlParser();\n\n        private ResourceValidationResult _resourceValidationResult;\n\n        public DefaultIdentityServerInteractionServiceTests()\n        {\n            _mockMockHttpContextAccessor = new MockHttpContextAccessor(_options, _mockUserSession, _mockEndSessionStore);\n\n            _subject = new DefaultIdentityServerInteractionService(new StubClock(), \n                _mockMockHttpContextAccessor,\n                _mockLogoutMessageStore,\n                _mockErrorMessageStore,\n                _mockConsentStore,\n                _mockPersistedGrantService,\n                _mockUserSession,\n                _mockReturnUrlParser,\n                TestLogger.Create<DefaultIdentityServerInteractionService>()\n            );\n\n            _resourceValidationResult = new ResourceValidationResult();\n            _resourceValidationResult.Resources.IdentityResources.Add(new IdentityResources.OpenId());\n            _resourceValidationResult.ParsedScopes.Add(new ParsedScopeValue(\"openid\"));\n        }\n        \n        [Fact]\n        public async Task GetLogoutContextAsync_valid_session_and_logout_id_should_not_provide_signout_iframe()\n        {\n            // for this, we're just confirming that since the session has changed, there's not use in doing the iframe and thsu SLO\n            _mockUserSession.SessionId = null;\n            _mockLogoutMessageStore.Messages.Add(\"id\", new Message<LogoutMessage>(new LogoutMessage() { SessionId = \"session\" }));\n\n            var context = await _subject.GetLogoutContextAsync(\"id\");\n\n            context.SignOutIFrameUrl.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task GetLogoutContextAsync_valid_session_no_logout_id_should_provide_iframe()\n        {\n            _mockUserSession.Clients.Add(\"foo\");\n            _mockUserSession.SessionId = \"session\";\n            _mockUserSession.User = new IdentityServerUser(\"123\").CreatePrincipal();\n\n            var context = await _subject.GetLogoutContextAsync(null);\n\n            context.SignOutIFrameUrl.Should().NotBeNull();\n        }\n\n        [Fact]\n        public async Task GetLogoutContextAsync_without_session_should_not_provide_iframe()\n        {\n            _mockUserSession.SessionId = null;\n            _mockLogoutMessageStore.Messages.Add(\"id\", new Message<LogoutMessage>(new LogoutMessage()));\n\n            var context = await _subject.GetLogoutContextAsync(\"id\");\n\n            context.SignOutIFrameUrl.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task CreateLogoutContextAsync_without_session_should_not_create_session()\n        {\n            var context = await _subject.CreateLogoutContextAsync();\n\n            context.Should().BeNull();\n            _mockLogoutMessageStore.Messages.Should().BeEmpty();\n        }\n\n        [Fact]\n        public async Task CreateLogoutContextAsync_with_session_should_create_session()\n        {\n            _mockUserSession.Clients.Add(\"foo\");\n            _mockUserSession.User = new IdentityServerUser(\"123\").CreatePrincipal();\n            _mockUserSession.SessionId = \"session\";\n\n            var context = await _subject.CreateLogoutContextAsync();\n\n            context.Should().NotBeNull();\n            _mockLogoutMessageStore.Messages.Should().NotBeEmpty();\n        }\n\n        [Fact]\n        public async Task GrantConsentAsync_should_throw_if_granted_and_no_subject()\n        {\n            Func<Task> act = async () => await _subject.GrantConsentAsync(\n                new AuthorizationRequest(), \n                new ConsentResponse() { ScopesValuesConsented = new[] { \"openid\" } }, \n                null);\n\n            (await act.Should().ThrowAsync<ArgumentNullException>())\n                .And.Message.Should().Contain(\"subject\");\n        }\n\n        [Fact]\n        public async Task GrantConsentAsync_should_allow_deny_for_anonymous_users()\n        {\n            var req = new AuthorizationRequest()\n            {\n                Client = new Client { ClientId = \"client\" },\n                ValidatedResources = _resourceValidationResult\n            };\n            await _subject.GrantConsentAsync(req, new ConsentResponse { Error = AuthorizationError.AccessDenied }, null);\n        }\n\n        [Fact]\n        public async Task GrantConsentAsync_should_use_current_subject_and_create_message()\n        {\n            _mockUserSession.User = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n            var req = new AuthorizationRequest() { \n                Client = new Client { ClientId = \"client\" },\n                ValidatedResources = _resourceValidationResult\n            };\n            await _subject.GrantConsentAsync(req, new ConsentResponse(), null);\n\n            _mockConsentStore.Messages.Should().NotBeEmpty();\n            var consentRequest = new ConsentRequest(req, \"bob\");\n            _mockConsentStore.Messages.First().Key.Should().Be(consentRequest.Id);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultPersistedGrantServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Stores.Serialization;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultPersistedGrantServiceTests\n    {\n        private DefaultPersistedGrantService _subject;\n        private InMemoryPersistedGrantStore _store = new InMemoryPersistedGrantStore();\n        private IAuthorizationCodeStore _codes;\n        private IRefreshTokenStore _refreshTokens;\n        private IReferenceTokenStore _referenceTokens;\n        private IUserConsentStore _userConsent;\n\n        private ClaimsPrincipal _user = new IdentityServerUser(\"123\").CreatePrincipal();\n\n        public DefaultPersistedGrantServiceTests()\n        {\n            _subject = new DefaultPersistedGrantService(\n                _store, \n                new PersistentGrantSerializer(), \n                TestLogger.Create<DefaultPersistedGrantService>());\n            _codes = new DefaultAuthorizationCodeStore(_store,\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultAuthorizationCodeStore>());\n            _refreshTokens = new DefaultRefreshTokenStore(_store,\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultRefreshTokenStore>());\n            _referenceTokens = new DefaultReferenceTokenStore(_store,\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultReferenceTokenStore>());\n            _userConsent = new DefaultUserConsentStore(_store,\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultUserConsentStore>());\n        }\n\n        [Fact]\n        public async Task GetAllGrantsAsync_should_return_all_grants()\n        {\n            await _userConsent.StoreUserConsentAsync(new Consent()\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = \"client1\",\n                SubjectId = \"123\",\n                Scopes = new string[] { \"foo1\", \"foo2\" }\n            });\n            await _userConsent.StoreUserConsentAsync(new Consent()\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = \"client2\",\n                SubjectId = \"123\",\n                Scopes = new string[] { \"foo3\" }\n            });\n            await _userConsent.StoreUserConsentAsync(new Consent()\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = \"client1\",\n                SubjectId = \"456\",\n                Scopes = new string[] { \"foo3\" }\n            });\n\n            var handle1 = await _referenceTokens.StoreReferenceTokenAsync(new Token()\n            {\n                ClientId = \"client1\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"bar1\"),\n                    new Claim(\"scope\", \"bar2\")\n                }\n            });\n\n            var handle2 = await _referenceTokens.StoreReferenceTokenAsync(new Token()\n            {\n                ClientId = \"client2\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"bar3\")\n                }\n            });\n\n            var handle3 = await _referenceTokens.StoreReferenceTokenAsync(new Token()\n            {\n                ClientId = \"client1\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"456\"),\n                    new Claim(\"scope\", \"bar3\")\n                }\n            });\n\n            var handle4 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client1\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"baz1\"),\n                        new Claim(\"scope\", \"baz2\")\n                    }\n                },\n                Version = 1\n            });\n            var handle5 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client1\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"456\"),\n                        new Claim(\"scope\", \"baz3\")\n                    }\n                },\n                Version = 1\n            });\n            var handle6 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client2\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"baz3\")\n                    }\n                },\n                Version = 1\n            });\n\n            var handle7 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client1\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = _user,\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux1\", \"quux2\" }\n            });\n\n            var handle8 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client2\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = _user,\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux3\" }\n            });\n\n            var handle9 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client1\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = new IdentityServerUser(\"456\").CreatePrincipal(),\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux3\" }\n            });\n\n            var grants = await _subject.GetAllGrantsAsync(\"123\");\n\n            grants.Count().Should().Be(2);\n            var grant1 = grants.First(x => x.ClientId == \"client1\");\n            grant1.SubjectId.Should().Be(\"123\");\n            grant1.ClientId.Should().Be(\"client1\");\n            grant1.Scopes.Should().BeEquivalentTo(new string[] { \"foo1\", \"foo2\", \"bar1\", \"bar2\", \"baz1\", \"baz2\", \"quux1\", \"quux2\" });\n\n            var grant2 = grants.First(x => x.ClientId == \"client2\");\n            grant2.SubjectId.Should().Be(\"123\");\n            grant2.ClientId.Should().Be(\"client2\");\n            grant2.Scopes.Should().BeEquivalentTo(new string[] { \"foo3\", \"bar3\", \"baz3\", \"quux3\" });\n        }\n\n        [Fact]\n        public async Task RemoveAllGrantsAsync_should_remove_all_grants()\n        {\n            await _userConsent.StoreUserConsentAsync(new Consent()\n            {\n                ClientId = \"client1\",\n                SubjectId = \"123\",\n                Scopes = new string[] { \"foo1\", \"foo2\" }\n            });\n            await _userConsent.StoreUserConsentAsync(new Consent()\n            {\n                ClientId = \"client2\",\n                SubjectId = \"123\",\n                Scopes = new string[] { \"foo3\" }\n            });\n            await _userConsent.StoreUserConsentAsync(new Consent()\n            {\n                ClientId = \"client1\",\n                SubjectId = \"456\",\n                Scopes = new string[] { \"foo3\" }\n            });\n\n            var handle1 = await _referenceTokens.StoreReferenceTokenAsync(new Token()\n            {\n                ClientId = \"client1\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"bar1\"),\n                    new Claim(\"scope\", \"bar2\")\n                }\n            });\n\n            var handle2 = await _referenceTokens.StoreReferenceTokenAsync(new Token()\n            {\n                ClientId = \"client2\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"bar3\")\n                }\n            });\n\n            var handle3 = await _referenceTokens.StoreReferenceTokenAsync(new Token()\n            {\n                ClientId = \"client1\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"456\"),\n                    new Claim(\"scope\", \"bar3\")\n                }\n            });\n\n            var handle4 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client1\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"baz1\"),\n                        new Claim(\"scope\", \"baz2\")\n                    }\n                },\n                Version = 1\n            });\n            var handle5 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client1\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"456\"),\n                        new Claim(\"scope\", \"baz3\")\n                    }\n                },\n                Version = 1\n            });\n            var handle6 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client2\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"baz3\")\n                    }\n                },\n                Version = 1\n            });\n\n            var handle7 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client1\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = _user,\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux1\", \"quux2\" }\n            });\n\n            var handle8 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client2\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = _user,\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux3\" }\n            });\n\n            var handle9 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client1\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = new IdentityServerUser(\"456\").CreatePrincipal(),\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux3\" }\n            });\n\n            await _subject.RemoveAllGrantsAsync(\"123\", \"client1\");\n\n            (await _referenceTokens.GetReferenceTokenAsync(handle1)).Should().BeNull();\n            (await _referenceTokens.GetReferenceTokenAsync(handle2)).Should().NotBeNull();\n            (await _referenceTokens.GetReferenceTokenAsync(handle3)).Should().NotBeNull();\n            (await _refreshTokens.GetRefreshTokenAsync(handle4)).Should().BeNull();\n            (await _refreshTokens.GetRefreshTokenAsync(handle5)).Should().NotBeNull();\n            (await _refreshTokens.GetRefreshTokenAsync(handle6)).Should().NotBeNull();\n            (await _codes.GetAuthorizationCodeAsync(handle7)).Should().BeNull();\n            (await _codes.GetAuthorizationCodeAsync(handle8)).Should().NotBeNull();\n            (await _codes.GetAuthorizationCodeAsync(handle9)).Should().NotBeNull();\n        }\n        [Fact]\n        public async Task RemoveAllGrantsAsync_should_filter_on_session_id()\n        {\n            {\n                var handle1 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client1\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle2 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client2\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle3 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client3\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session3\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n\n                await _subject.RemoveAllGrantsAsync(\"123\");\n\n                (await _refreshTokens.GetRefreshTokenAsync(handle1)).Should().BeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle2)).Should().BeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle3)).Should().BeNull();\n                await _refreshTokens.RemoveRefreshTokenAsync(handle1);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle2);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle3);\n            }\n            {\n                var handle1 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client1\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle2 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client2\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle3 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client3\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session3\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n\n                await _subject.RemoveAllGrantsAsync(\"123\", \"client1\");\n\n                (await _refreshTokens.GetRefreshTokenAsync(handle1)).Should().BeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle2)).Should().NotBeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle3)).Should().NotBeNull();\n                await _refreshTokens.RemoveRefreshTokenAsync(handle1);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle2);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle3);\n            }\n            {\n                var handle1 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client1\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle2 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client2\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle3 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client3\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle4 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client1\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session2\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                await _subject.RemoveAllGrantsAsync(\"123\", \"client1\", \"session1\");\n\n                (await _refreshTokens.GetRefreshTokenAsync(handle1)).Should().BeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle2)).Should().NotBeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle3)).Should().NotBeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle4)).Should().NotBeNull();\n                await _refreshTokens.RemoveRefreshTokenAsync(handle1);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle2);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle3);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle4);\n            }\n            {\n                var handle1 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client1\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle2 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client2\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle3 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client3\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session1\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                var handle4 = await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n                {\n                    CreationTime = DateTime.UtcNow,\n                    Lifetime = 10,\n                    AccessToken = new Token\n                    {\n                        ClientId = \"client1\",\n                        Audiences = { \"aud\" },\n                        CreationTime = DateTime.UtcNow,\n                        Type = \"type\",\n                        Claims = new List<Claim>\n                        {\n                            new Claim(\"sub\", \"123\"),\n                            new Claim(\"sid\", \"session2\"),\n                            new Claim(\"scope\", \"baz\")\n                        }\n                    },\n                    Version = 1\n                });\n                await _subject.RemoveAllGrantsAsync(\"123\", sessionId:\"session1\");\n\n                (await _refreshTokens.GetRefreshTokenAsync(handle1)).Should().BeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle2)).Should().BeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle3)).Should().BeNull();\n                (await _refreshTokens.GetRefreshTokenAsync(handle4)).Should().NotBeNull();\n                await _refreshTokens.RemoveRefreshTokenAsync(handle1);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle2);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle3);\n                await _refreshTokens.RemoveRefreshTokenAsync(handle4);\n            }\n        }\n\n        [Fact]\n        public async Task GetAllGrantsAsync_should_aggregate_correctly()\n        {\n            await _userConsent.StoreUserConsentAsync(new Consent()\n            {\n                ClientId = \"client1\",\n                SubjectId = \"123\",\n                Scopes = new string[] { \"foo1\", \"foo2\" }\n            });\n\n            var grants = await _subject.GetAllGrantsAsync(\"123\");\n\n            grants.Count().Should().Be(1);\n            grants.First().Scopes.Should().Contain(new string[] { \"foo1\", \"foo2\" });\n\n            var handle9 = await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client1\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux3\" }\n            });\n\n            grants = await _subject.GetAllGrantsAsync(\"123\");\n\n            grants.Count().Should().Be(1);\n            grants.First().Scopes.Should().Contain(new string[] { \"foo1\", \"foo2\", \"quux3\" });\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultRefreshTokenServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Stores.Serialization;\nusing System;\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultRefreshTokenServiceTests\n    {\n        private DefaultRefreshTokenService _subject;\n        private DefaultRefreshTokenStore _store;\n\n        private ClaimsPrincipal _user = new IdentityServerUser(\"123\").CreatePrincipal();\n        private StubClock _clock = new StubClock();\n\n        public DefaultRefreshTokenServiceTests()\n        {\n            _store = new DefaultRefreshTokenStore(\n                new InMemoryPersistedGrantStore(),\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultRefreshTokenStore>());\n\n            _subject = new DefaultRefreshTokenService(\n                _store, \n                new TestProfileService(),\n                _clock, \n                TestLogger.Create<DefaultRefreshTokenService>());\n        }\n\n        [Fact]\n        public async Task CreateRefreshToken_token_exists_in_store()\n        {\n            var client = new Client();\n            var accessToken = new Token();\n\n            var handle = await _subject.CreateRefreshTokenAsync(_user, accessToken, client);\n\n            (await _store.GetRefreshTokenAsync(handle)).Should().NotBeNull();\n        }\n\n        [Fact]\n        public async Task CreateRefreshToken_should_match_absolute_lifetime()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.ReUse,\n                RefreshTokenExpiration = TokenExpiration.Absolute,\n                AbsoluteRefreshTokenLifetime = 10\n            };\n\n            var handle = await _subject.CreateRefreshTokenAsync(_user, new Token(), client);\n\n            var refreshToken = (await _store.GetRefreshTokenAsync(handle));\n\n            refreshToken.Should().NotBeNull();\n            refreshToken.Lifetime.Should().Be(client.AbsoluteRefreshTokenLifetime);\n        }\n\n        [Fact]\n        public async Task CreateRefreshToken_should_cap_sliding_lifetime_that_exceeds_absolute_lifetime()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.ReUse,\n                RefreshTokenExpiration = TokenExpiration.Sliding,\n                SlidingRefreshTokenLifetime  = 100,\n                AbsoluteRefreshTokenLifetime = 10\n            };\n\n            var handle = await _subject.CreateRefreshTokenAsync(_user, new Token(), client);\n\n            var refreshToken = (await _store.GetRefreshTokenAsync(handle));\n\n            refreshToken.Should().NotBeNull();\n            refreshToken.Lifetime.Should().Be(client.AbsoluteRefreshTokenLifetime);\n        }\n\n        [Fact]\n        public async Task CreateRefreshToken_should_match_sliding_lifetime()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.ReUse,\n                RefreshTokenExpiration = TokenExpiration.Sliding,\n                SlidingRefreshTokenLifetime = 10\n            };\n\n            var handle = await _subject.CreateRefreshTokenAsync(_user, new Token(), client);\n\n            var refreshToken = (await _store.GetRefreshTokenAsync(handle));\n\n            refreshToken.Should().NotBeNull();\n            refreshToken.Lifetime.Should().Be(client.SlidingRefreshTokenLifetime);\n        }\n\n        [Fact]\n        public async Task UpdateRefreshToken_one_time_use_should_create_new_token()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var refreshToken = new RefreshToken\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            };\n\n            var handle = await _store.StoreRefreshTokenAsync(refreshToken);\n\n            (await _subject.UpdateRefreshTokenAsync(handle, refreshToken, client))\n                .Should().NotBeNull()\n                .And\n                .NotBe(handle);\n        }\n\n        [Fact]\n        public async Task UpdateRefreshToken_sliding_with_non_zero_absolute_should_update_lifetime()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.ReUse,\n                RefreshTokenExpiration = TokenExpiration.Sliding,\n                SlidingRefreshTokenLifetime = 10,\n                AbsoluteRefreshTokenLifetime = 100\n            };\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var handle = await _store.StoreRefreshTokenAsync(new RefreshToken\n            {\n                CreationTime = now.AddSeconds(-10),\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            });\n\n            var refreshToken = await _store.GetRefreshTokenAsync(handle);\n            var newHandle = await _subject.UpdateRefreshTokenAsync(handle, refreshToken, client);\n\n            newHandle.Should().NotBeNull().And.Be(handle);\n\n            var newRefreshToken = await _store.GetRefreshTokenAsync(newHandle);\n\n            newRefreshToken.Should().NotBeNull();\n            newRefreshToken.Lifetime.Should().Be((int)(now - newRefreshToken.CreationTime).TotalSeconds + client.SlidingRefreshTokenLifetime);\n        }\n\n        [Fact]\n        public async Task UpdateRefreshToken_lifetime_exceeds_absolute_should_be_absolute_lifetime()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.ReUse,\n                RefreshTokenExpiration = TokenExpiration.Sliding,\n                SlidingRefreshTokenLifetime = 10,\n                AbsoluteRefreshTokenLifetime = 1000\n            };\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var handle = await _store.StoreRefreshTokenAsync(new RefreshToken\n            {\n                CreationTime = now.AddSeconds(-1000),\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            });\n\n            var refreshToken = await _store.GetRefreshTokenAsync(handle);\n            var newHandle = await _subject.UpdateRefreshTokenAsync(handle, refreshToken, client);\n\n            newHandle.Should().NotBeNull().And.Be(handle);\n\n            var newRefreshToken = await _store.GetRefreshTokenAsync(newHandle);\n\n            newRefreshToken.Should().NotBeNull();\n            newRefreshToken.Lifetime.Should().Be(client.AbsoluteRefreshTokenLifetime);\n        }\n\n        [Fact]\n        public async Task UpdateRefreshToken_sliding_with_zero_absolute_should_update_lifetime()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.ReUse,\n                RefreshTokenExpiration = TokenExpiration.Sliding,\n                SlidingRefreshTokenLifetime = 10,\n                AbsoluteRefreshTokenLifetime = 0\n            };\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var handle = await _store.StoreRefreshTokenAsync(new RefreshToken\n            {\n                CreationTime = now.AddSeconds(-1000),\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            });\n\n            var refreshToken = await _store.GetRefreshTokenAsync(handle);\n            var newHandle = await _subject.UpdateRefreshTokenAsync(handle, refreshToken, client);\n\n            newHandle.Should().NotBeNull().And.Be(handle);\n\n            var newRefreshToken = await _store.GetRefreshTokenAsync(newHandle);\n\n            newRefreshToken.Should().NotBeNull();\n            newRefreshToken.Lifetime.Should().Be((int)(now - newRefreshToken.CreationTime).TotalSeconds + client.SlidingRefreshTokenLifetime);\n        }\n\n        [Fact]\n        public async Task UpdateRefreshToken_for_onetime_and_sliding_with_zero_absolute_should_update_lifetime()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.OneTimeOnly,\n                RefreshTokenExpiration = TokenExpiration.Sliding,\n                SlidingRefreshTokenLifetime = 10,\n                AbsoluteRefreshTokenLifetime = 0\n            };\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var handle = await _store.StoreRefreshTokenAsync(new RefreshToken\n            {\n                CreationTime = now.AddSeconds(-1000),\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            });\n\n            var refreshToken = await _store.GetRefreshTokenAsync(handle);\n            var newHandle = await _subject.UpdateRefreshTokenAsync(handle, refreshToken, client);\n\n            newHandle.Should().NotBeNull().And.NotBe(handle);\n\n            var newRefreshToken = await _store.GetRefreshTokenAsync(newHandle);\n\n            newRefreshToken.Should().NotBeNull();\n            newRefreshToken.Lifetime.Should().Be((int)(now - newRefreshToken.CreationTime).TotalSeconds + client.SlidingRefreshTokenLifetime);\n        }\n\n        [Fact]\n        public async Task UpdateRefreshToken_one_time_use_should_consume_token_and_create_new_one_with_correct_dates()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var refreshToken = new RefreshToken\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            };\n\n            var handle = await _store.StoreRefreshTokenAsync(refreshToken);\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var newHandle = await _subject.UpdateRefreshTokenAsync(handle, refreshToken, client);\n\n            var oldToken = await _store.GetRefreshTokenAsync(handle);\n            var newToken = await _store.GetRefreshTokenAsync(newHandle);\n\n            oldToken.ConsumedTime.Should().Be(now);\n            newToken.ConsumedTime.Should().BeNull();\n        }\n        \n        [Fact]\n        public async Task ValidateRefreshToken_invalid_token_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var result = await _subject.ValidateRefreshTokenAsync(\"invalid\", client);\n\n            result.IsError.Should().BeTrue();\n        }\n        \n        [Fact]\n        public async Task ValidateRefreshToken_client_without_allow_offline_access_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var refreshToken = new RefreshToken\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            };\n\n            var handle = await _store.StoreRefreshTokenAsync(refreshToken);\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var result = await _subject.ValidateRefreshTokenAsync(handle, client);\n\n            result.IsError.Should().BeTrue();\n        }\n        \n        [Fact]\n        public async Task ValidateRefreshToken_invalid_client_binding_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                AllowOfflineAccess = true,\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var refreshToken = new RefreshToken\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client2\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            };\n\n            var handle = await _store.StoreRefreshTokenAsync(refreshToken);\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var result = await _subject.ValidateRefreshTokenAsync(handle, client);\n\n            result.IsError.Should().BeTrue();\n        }\n        \n        [Fact]\n        public async Task ValidateRefreshToken_expired_token_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                AllowOfflineAccess = true,\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var refreshToken = new RefreshToken\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            };\n\n            var handle = await _store.StoreRefreshTokenAsync(refreshToken);\n\n            var now = DateTime.UtcNow.AddSeconds(20);\n            _clock.UtcNowFunc = () => now;\n\n            var result = await _subject.ValidateRefreshTokenAsync(handle, client);\n\n            result.IsError.Should().BeTrue();\n        }\n        \n        [Fact]\n        public async Task ValidateRefreshToken_consumed_token_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                AllowOfflineAccess = true,\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var refreshToken = new RefreshToken\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                ConsumedTime = DateTime.UtcNow,\n                \n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            };\n\n            var handle = await _store.StoreRefreshTokenAsync(refreshToken);\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var result = await _subject.ValidateRefreshTokenAsync(handle, client);\n\n            result.IsError.Should().BeTrue();\n        }\n        \n        [Fact]\n        public async Task ValidateRefreshToken_valid_token_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"client1\",\n                AllowOfflineAccess = true,\n                RefreshTokenUsage = TokenUsage.OneTimeOnly\n            };\n\n            var refreshToken = new RefreshToken\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = client.ClientId,\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Claims = new List<Claim>()\n                    {\n                        new Claim(\"sub\", \"123\")\n                    }\n                }\n            };\n\n            var handle = await _store.StoreRefreshTokenAsync(refreshToken);\n\n            var now = DateTime.UtcNow;\n            _clock.UtcNowFunc = () => now;\n\n            var result = await _subject.ValidateRefreshTokenAsync(handle, client);\n\n            result.IsError.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultTokenServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultTokenServiceTests\n    {\n        private DefaultTokenService _subject;\n\n        MockClaimsService _mockClaimsService = new MockClaimsService();\n        MockReferenceTokenStore _mockReferenceTokenStore = new MockReferenceTokenStore();\n        MockTokenCreationService _mockTokenCreationService = new MockTokenCreationService();\n        DefaultHttpContext _httpContext = new DefaultHttpContext();\n        MockSystemClock _mockSystemClock = new MockSystemClock();\n        MockKeyMaterialService _mockKeyMaterialService = new MockKeyMaterialService();\n        IdentityServerOptions _options = new IdentityServerOptions();\n\n        public DefaultTokenServiceTests()\n        {\n            _options.IssuerUri = \"https://test.identityserver8.io\";\n\n            var svcs = new ServiceCollection();\n            svcs.AddSingleton(_options);\n            _httpContext.RequestServices = svcs.BuildServiceProvider();\n\n            _subject = new DefaultTokenService(\n                _mockClaimsService,\n                _mockReferenceTokenStore,\n                _mockTokenCreationService,\n                new HttpContextAccessor { HttpContext = _httpContext },\n                _mockSystemClock,\n                _mockKeyMaterialService,\n                _options,\n                TestLogger.Create<DefaultTokenService>());\n        }\n\n        [Fact]\n        public async Task CreateAccessTokenAsync_should_include_aud_for_each_ApiResource()\n        {\n            var request = new TokenCreationRequest { \n                ValidatedResources = new ResourceValidationResult()\n                {\n                    Resources = new Resources()\n                    {\n                        ApiResources = \n                        {\n                            new ApiResource(\"api1\"){ Scopes = { \"scope1\" } },\n                            new ApiResource(\"api2\"){ Scopes = { \"scope2\" } },\n                            new ApiResource(\"api3\"){ Scopes = { \"scope3\" } },\n                        },\n                    },\n                    ParsedScopes =\n                    {\n                        new ParsedScopeValue(\"scope1\"),\n                        new ParsedScopeValue(\"scope2\"),\n                        new ParsedScopeValue(\"scope3\"),\n                    }\n                },\n                ValidatedRequest = new ValidatedRequest()\n                {\n                    Client = new Client { }\n                }\n            };\n\n            var result = await _subject.CreateAccessTokenAsync(request);\n\n            result.Audiences.Count.Should().Be(3);\n            result.Audiences.Should().BeEquivalentTo(new[] { \"api1\", \"api2\", \"api3\" });\n        }\n\n        [Fact]\n        public async Task CreateAccessTokenAsync_when_no_apiresources_should_not_include_any_aud()\n        {\n            var request = new TokenCreationRequest\n            {\n                ValidatedResources = new ResourceValidationResult()\n                {\n                    Resources = new Resources()\n                    {\n                        ApiScopes =\n                        {\n                            new ApiScope(\"scope1\"),\n                            new ApiScope(\"scope2\"),\n                            new ApiScope(\"scope3\"),\n                        },\n                    },\n                    ParsedScopes =\n                    {\n                        new ParsedScopeValue(\"scope1\"),\n                        new ParsedScopeValue(\"scope2\"),\n                        new ParsedScopeValue(\"scope3\"),\n                    }\n                },\n                ValidatedRequest = new ValidatedRequest()\n                {\n                    Client = new Client { }\n                }\n            };\n\n            var result = await _subject.CreateAccessTokenAsync(request);\n\n            result.Audiences.Count.Should().Be(0);\n        }\n\n\n        [Fact]\n        public async Task CreateAccessTokenAsync_when_no_session_should_not_include_sid()\n        {\n            var request = new TokenCreationRequest\n            {\n                ValidatedResources = new ResourceValidationResult(),\n                ValidatedRequest = new ValidatedRequest()\n                {\n                    Client = new Client { },\n                    SessionId = null\n                }\n            };\n\n            var result = await _subject.CreateAccessTokenAsync(request);\n\n            result.Claims.SingleOrDefault(x => x.Type == JwtClaimTypes.SessionId).Should().BeNull();\n        }\n        [Fact]\n        public async Task CreateAccessTokenAsync_when_session_should_include_sid()\n        {\n            var request = new TokenCreationRequest\n            {\n                ValidatedResources = new ResourceValidationResult(),\n                ValidatedRequest = new ValidatedRequest()\n                {\n                    Client = new Client { },\n                    SessionId = \"123\"\n                }\n            };\n\n            var result = await _subject.CreateAccessTokenAsync(request);\n\n            result.Claims.SingleOrDefault(x => x.Type == JwtClaimTypes.SessionId).Value.Should().Be(\"123\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DefaultUserSessionTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Linq;\nusing System.Net;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Services;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DefaultUserSessionTests\n    {\n        private DefaultUserSession _subject;\n        private MockHttpContextAccessor _mockHttpContext = new MockHttpContextAccessor();\n        private MockAuthenticationHandlerProvider _mockAuthenticationHandlerProvider = new MockAuthenticationHandlerProvider();\n        private MockAuthenticationHandler _mockAuthenticationHandler = new MockAuthenticationHandler();\n\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private ClaimsPrincipal _user;\n        private AuthenticationProperties _props = new AuthenticationProperties();\n\n        public DefaultUserSessionTests()\n        {\n            _mockAuthenticationHandlerProvider.Handler = _mockAuthenticationHandler;\n\n            _user = new IdentityServerUser(\"123\").CreatePrincipal();\n            _subject = new DefaultUserSession(\n                _mockHttpContext, \n                _mockAuthenticationHandlerProvider,\n                _options,\n                new StubClock(), \n                TestLogger.Create<DefaultUserSession>());\n        }\n\n        [Fact]\n        public async Task CreateSessionId_when_user_is_anonymous_should_generate_new_sid()\n        {\n            await _subject.CreateSessionIdAsync(_user, _props);\n\n            _props.GetSessionId().Should().NotBeNull();\n        }\n\n        [Fact]\n        public async Task CreateSessionId_when_user_is_authenticated_should_not_generate_new_sid()\n        {\n            // this test is needed to allow same session id when cookie is slid\n            // IOW, if UI layer passes in same properties dictionary, then we assume it's the same user\n\n            _props.SetSessionId(\"999\");\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            await _subject.CreateSessionIdAsync(_user, _props);\n\n            _props.GetSessionId().Should().NotBeNull();\n            _props.GetSessionId().Should().Be(\"999\");\n        }\n\n        [Fact]\n        public async Task CreateSessionId_when_props_does_not_contain_key_should_generate_new_sid()\n        {\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            _props.GetSessionId().Should().BeNull();\n\n            await _subject.CreateSessionIdAsync(_user, _props);\n\n            _props.GetSessionId().Should().NotBeNull();\n        }\n\n        [Fact]\n        public async Task CreateSessionId_when_user_is_authenticated_but_different_sub_should_create_new_sid()\n        {\n            _props.SetSessionId(\"999\");\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            await _subject.CreateSessionIdAsync(new IdentityServerUser(\"alice\").CreatePrincipal(), _props);\n\n            _props.GetSessionId().Should().NotBeNull();\n            _props.GetSessionId().Should().NotBe(\"999\");\n        }\n\n        [Fact]\n        public async Task CreateSessionId_should_issue_session_id_cookie()\n        {\n            await _subject.CreateSessionIdAsync(_user, _props);\n\n            var cookieContainer = new CookieContainer();\n            var cookies = _mockHttpContext.HttpContext.Response.Headers.Where(x => x.Key.Equals(\"Set-Cookie\", StringComparison.OrdinalIgnoreCase)).Select(x => x.Value);\n            cookieContainer.SetCookies(new Uri(\"http://server\"), string.Join(\",\", cookies));\n            _mockHttpContext.HttpContext.Response.Headers.Clear();\n\n            var cookie = cookieContainer.GetCookies(new Uri(\"http://server\")).Cast<Cookie>().Where(x => x.Name == _options.Authentication.CheckSessionCookieName).FirstOrDefault();\n            cookie.Value.Should().Be(_props.GetSessionId());\n        }\n\n        [Fact]\n        public async Task EnsureSessionIdCookieAsync_should_add_cookie()\n        {\n            _props.SetSessionId(\"999\");\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            await _subject.EnsureSessionIdCookieAsync();\n\n            var cookieContainer = new CookieContainer();\n            var cookies = _mockHttpContext.HttpContext.Response.Headers.Where(x => x.Key.Equals(\"Set-Cookie\", StringComparison.OrdinalIgnoreCase)).Select(x => x.Value);\n            cookieContainer.SetCookies(new Uri(\"http://server\"), string.Join(\",\", cookies));\n            _mockHttpContext.HttpContext.Response.Headers.Clear();\n\n            var cookie = cookieContainer.GetCookies(new Uri(\"http://server\")).Cast<Cookie>().Where(x => x.Name == _options.Authentication.CheckSessionCookieName).FirstOrDefault();\n            cookie.Value.Should().Be(\"999\");\n        }\n\n        [Fact]\n        public async Task EnsureSessionIdCookieAsync_should_not_add_cookie_if_no_sid()\n        {\n            await _subject.EnsureSessionIdCookieAsync();\n\n            var cookieContainer = new CookieContainer();\n            var cookies = _mockHttpContext.HttpContext.Response.Headers.Where(x => x.Key.Equals(\"Set-Cookie\", StringComparison.OrdinalIgnoreCase)).Select(x => x.Value);\n            cookieContainer.SetCookies(new Uri(\"http://server\"), string.Join(\",\", cookies));\n            _mockHttpContext.HttpContext.Response.Headers.Clear();\n\n            var cookie = cookieContainer.GetCookies(new Uri(\"http://server\")).Cast<Cookie>().Where(x => x.Name == _options.Authentication.CheckSessionCookieName).FirstOrDefault();\n            cookie.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task RemoveSessionIdCookie_should_remove_cookie()\n        {\n            _props.SetSessionId(\"999\");\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            await _subject.EnsureSessionIdCookieAsync();\n\n            var cookieContainer = new CookieContainer();\n            var cookies = _mockHttpContext.HttpContext.Response.Headers.Where(x => x.Key.Equals(\"Set-Cookie\", StringComparison.OrdinalIgnoreCase)).Select(x => x.Value);\n            cookieContainer.SetCookies(new Uri(\"http://server\"), string.Join(\",\", cookies));\n            _mockHttpContext.HttpContext.Response.Headers.Clear();\n\n            string cookie = cookieContainer.GetCookieHeader(new Uri(\"http://server\"));\n            _mockHttpContext.HttpContext.Request.Headers.Append(\"Cookie\", cookie);\n\n            await _subject.RemoveSessionIdCookieAsync();\n\n            cookies = _mockHttpContext.HttpContext.Response.Headers.Where(x => x.Key.Equals(\"Set-Cookie\", StringComparison.OrdinalIgnoreCase)).Select(x => x.Value);\n            cookieContainer.SetCookies(new Uri(\"http://server\"), string.Join(\",\", cookies));\n\n            var query = cookieContainer.GetCookies(new Uri(\"http://server\")).Cast<Cookie>().Where(x => x.Name == _options.Authentication.CheckSessionCookieName);\n            query.Count().Should().Be(0);\n        }\n\n        [Fact]\n        public async Task GetCurrentSessionIdAsync_when_user_is_authenticated_should_return_sid()\n        {\n            _props.SetSessionId(\"999\");\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            var sid = await _subject.GetSessionIdAsync();\n            sid.Should().Be(\"999\");\n        }\n\n        [Fact]\n        public async Task GetCurrentSessionIdAsync_when_user_is_anonymous_should_return_null()\n        {\n            var sid = await _subject.GetSessionIdAsync();\n            sid.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task adding_client_should_set_item_in_cookie_properties()\n        {\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            _props.Items.Count.Should().Be(0);\n            await _subject.AddClientIdAsync(\"client\");\n            _props.Items.Count.Should().Be(1);\n        }\n\n        [Fact]\n        public async Task when_authenticated_GetIdentityServerUserAsync_should_should_return_authenticated_user()\n        {\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            var user = await _subject.GetUserAsync();\n            user.GetSubjectId().Should().Be(\"123\");\n        }\n\n        [Fact]\n        public async Task when_anonymous_GetIdentityServerUserAsync_should_should_return_null()\n        {\n            var user = await _subject.GetUserAsync();\n            user.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task corrupt_properties_entry_should_clear_entry()\n        {\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            await _subject.AddClientIdAsync(\"client\");\n            var item = _props.Items.First();\n            _props.Items[item.Key] = \"junk\";\n\n            var clients = await _subject.GetClientListAsync();\n            clients.Should().BeEmpty();\n            _props.Items.Count.Should().Be(0);\n        }\n\n        [Fact]\n        public async Task adding_client_should_be_able_to_read_client()\n        {\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            await _subject.AddClientIdAsync(\"client\");\n            var clients = await _subject.GetClientListAsync();\n            clients.Should().Contain(new string[] { \"client\" });\n        }\n\n        [Fact]\n        public async Task adding_clients_should_be_able_to_read_clients()\n        {\n            _mockAuthenticationHandler.Result = AuthenticateResult.Success(new AuthenticationTicket(_user, _props, \"scheme\"));\n\n            await _subject.AddClientIdAsync(\"client1\");\n            await _subject.AddClientIdAsync(\"client2\");\n            var clients = await _subject.GetClientListAsync();\n            clients.Should().Contain(new string[] { \"client2\", \"client1\" });\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/DistributedDeviceFlowThrottlingServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing Microsoft.Extensions.Caching.Distributed;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class DistributedDeviceFlowThrottlingServiceTests\n    {\n        private TestCache cache = new TestCache();\n\n        private readonly IdentityServerOptions options = new IdentityServerOptions {DeviceFlow = new DeviceFlowOptions {Interval = 5}};\n        private readonly DeviceCode deviceCode = new DeviceCode\n        {\n            Lifetime = 300,\n            CreationTime = DateTime.UtcNow\n        };\n\n        private const string CacheKey = \"devicecode_\";\n        private readonly DateTime testDate = new DateTime(2018, 06, 28, 13, 37, 42);\n\n        [Fact]\n        public async Task First_Poll()\n        {\n            var handle = Guid.NewGuid().ToString();\n            var service = new DistributedDeviceFlowThrottlingService(cache, new StubClock {UtcNowFunc = () => testDate}, options);\n\n            var result = await service.ShouldSlowDown(handle, deviceCode);\n\n            result.Should().BeFalse();\n\n            CheckCacheEntry(handle);\n        }\n\n        [Fact]\n        public async Task Second_Poll_Too_Fast()\n        {\n            var handle = Guid.NewGuid().ToString();\n            var service = new DistributedDeviceFlowThrottlingService(cache, new StubClock { UtcNowFunc = () => testDate }, options);\n\n            cache.Set(CacheKey + handle, Encoding.UTF8.GetBytes(testDate.AddSeconds(-1).ToString(\"O\")));\n\n            var result = await service.ShouldSlowDown(handle, deviceCode);\n\n            result.Should().BeTrue();\n            \n            CheckCacheEntry(handle);\n        }\n\n        [Fact]\n        public async Task Second_Poll_After_Interval()\n        {\n            var handle = Guid.NewGuid().ToString();\n            \n            var service = new DistributedDeviceFlowThrottlingService(cache, new StubClock { UtcNowFunc = () => testDate }, options);\n\n            cache.Set($\"devicecode_{handle}\", Encoding.UTF8.GetBytes(testDate.AddSeconds(-deviceCode.Lifetime - 1).ToString(\"O\")));\n\n            var result = await service.ShouldSlowDown(handle, deviceCode);\n\n            result.Should().BeFalse();\n\n            CheckCacheEntry(handle);\n        }\n\n        /// <summary>\n        /// Addresses race condition from #3860\n        /// </summary>\n        [Fact]\n        public async Task Expired_Device_Code_Should_Not_Have_Expiry_in_Past()\n        {\n            var handle = Guid.NewGuid().ToString();\n            deviceCode.CreationTime = testDate.AddSeconds(-deviceCode.Lifetime * 2);\n\n            var service = new DistributedDeviceFlowThrottlingService(cache, new StubClock { UtcNowFunc = () => testDate }, options);\n\n            var result = await service.ShouldSlowDown(handle, deviceCode);\n            \n            result.Should().BeFalse();\n\n            cache.Items.TryGetValue(CacheKey + handle, out var values).Should().BeTrue();\n            values?.Item2.AbsoluteExpiration.Should().BeOnOrAfter(testDate);\n        }\n\n        private void CheckCacheEntry(string handle)\n        {\n            cache.Items.TryGetValue(CacheKey + handle, out var values).Should().BeTrue();\n\n            var dateTimeAsString = Encoding.UTF8.GetString(values?.Item1);\n            var dateTime = DateTime.Parse(dateTimeAsString);\n            dateTime.Should().Be(testDate);\n\n            values?.Item2.AbsoluteExpiration.Should().BeCloseTo(testDate.AddSeconds(deviceCode.Lifetime), TimeSpan.FromMilliseconds(100));\n        }\n    }\n\n    internal class TestCache : IDistributedCache\n    {\n        public readonly Dictionary<string, Tuple<byte[], DistributedCacheEntryOptions>> Items =\n            new Dictionary<string, Tuple<byte[], DistributedCacheEntryOptions>>();\n\n        public byte[] Get(string key)\n        {\n            if (Items.TryGetValue(key, out var value)) return value.Item1;\n            return null;\n        }\n\n        public Task<byte[]> GetAsync(string key, CancellationToken token = new CancellationToken())\n        {\n            return Task.FromResult(Get(key));\n        }\n\n        public void Set(string key, byte[] value, DistributedCacheEntryOptions options)\n        {\n            Items.Remove(key);\n\n            Items.Add(key, new Tuple<byte[], DistributedCacheEntryOptions>(value, options));\n        }\n\n        public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = new CancellationToken())\n        {\n            Set(key, value, options);\n            return Task.CompletedTask;\n        }\n\n        public void Refresh(string key)\n        {\n            throw new NotImplementedException();\n        }\n\n        public Task RefreshAsync(string key, CancellationToken token = new CancellationToken())\n        {\n            throw new NotImplementedException();\n        }\n\n        public void Remove(string key)\n        {\n            throw new NotImplementedException();\n        }\n\n        public Task RemoveAsync(string key, CancellationToken token = new CancellationToken())\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/Default/NumericUserCodeServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer8.Services;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.Default\n{\n    public class NumericUserCodeGeneratorTests\n    {\n        [Fact]\n        public async Task GenerateAsync_should_return_expected_code()\n        {\n            var sut = new NumericUserCodeGenerator();\n\n            var userCode = await sut.GenerateAsync();\n            var userCodeInt = int.Parse(userCode);\n\n            userCodeInt.Should().BeGreaterOrEqualTo(100000000);\n            userCodeInt.Should().BeLessOrEqualTo(999999999);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Services/InMemory/InMemoryCorsPolicyService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Services.InMemory\n{\n    public class InMemoryCorsPolicyServiceTests\n    {\n        private const string Category = \"InMemoryCorsPolicyService\";\n\n        private InMemoryCorsPolicyService _subject;\n        private List<Client> _clients = new List<Client>();\n\n        public InMemoryCorsPolicyServiceTests()\n        {\n            _subject = new InMemoryCorsPolicyService(TestLogger.Create<InMemoryCorsPolicyService>(), _clients);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task client_has_origin_should_allow_origin()\n        {\n            _clients.Add(new Client\n            {\n                AllowedCorsOrigins = new List<string>\n                {\n                    \"http://foo\"\n                }\n            });\n\n            (await _subject.IsOriginAllowedAsync(\"http://foo\")).Should().BeTrue();\n        }\n\n        [Theory]\n        [InlineData(\"http://foo\")]\n        [InlineData(\"https://bar\")]\n        [InlineData(\"http://bar-baz\")]\n        [Trait(\"Category\", Category)]\n        public async Task client_does_not_has_origin_should_not_allow_origin(string clientOrigin)\n        {\n            _clients.Add(new Client\n            {\n                AllowedCorsOrigins = new List<string>\n                {\n                    clientOrigin\n                }\n            });\n            (await _subject.IsOriginAllowedAsync(\"http://bar\")).Should().Be(false);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task client_has_many_origins_and_origin_is_in_list_should_allow_origin()\n        {\n            _clients.Add(new Client\n            {\n                AllowedCorsOrigins = new List<string>\n                {\n                    \"http://foo\",\n                    \"http://bar\",\n                    \"http://baz\"\n                }\n            });\n            (await _subject.IsOriginAllowedAsync(\"http://bar\")).Should().Be(true);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task client_has_many_origins_and_origin_is_in_not_list_should_not_allow_origin()\n        {\n            _clients.Add(new Client\n            {\n                AllowedCorsOrigins = new List<string>\n                {\n                    \"http://foo\",\n                    \"http://bar\",\n                    \"http://baz\"\n                }\n            });\n            (await _subject.IsOriginAllowedAsync(\"http://quux\")).Should().Be(false);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task many_clients_have_same_origins_should_allow_origin()\n        {\n            _clients.AddRange(new Client[] {\n                new Client\n                {\n                    AllowedCorsOrigins = new List<string>\n                    {\n                        \"http://foo\"\n                    }\n                },\n                new Client\n                {\n                    AllowedCorsOrigins = new List<string>\n                    {\n                        \"http://foo\"\n                    }\n                }\n            });\n            (await _subject.IsOriginAllowedAsync(\"http://foo\")).Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task handle_invalid_cors_origin_format_exception()\n        {\n            _clients.AddRange(new Client[] {\n                new Client\n                {\n                    AllowedCorsOrigins = new List<string>\n                    {\n                        \"http://foo\",\n                        \"http://ba z\"\n                    }\n                },\n                new Client\n                {\n                    AllowedCorsOrigins = new List<string>\n                    {\n                        \"http://foo\",\n                        \"http://bar\"\n                    }\n                }\n            });\n            (await _subject.IsOriginAllowedAsync(\"http://bar\")).Should().BeTrue();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Stores/Default/DefaultPersistedGrantStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Stores.Serialization;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Stores.Default\n{\n    public class DefaultPersistedGrantStoreTests\n    {\n        private InMemoryPersistedGrantStore _store = new InMemoryPersistedGrantStore();\n        private IAuthorizationCodeStore _codes;\n        private IRefreshTokenStore _refreshTokens;\n        private IReferenceTokenStore _referenceTokens;\n        private IUserConsentStore _userConsent;\n        private StubHandleGenerationService _stubHandleGenerationService = new StubHandleGenerationService();\n\n        private ClaimsPrincipal _user = new IdentityServerUser(\"123\").CreatePrincipal();\n\n        public DefaultPersistedGrantStoreTests()\n        {\n            _codes = new DefaultAuthorizationCodeStore(_store,\n                new PersistentGrantSerializer(),\n                _stubHandleGenerationService,\n                TestLogger.Create<DefaultAuthorizationCodeStore>());\n            _refreshTokens = new DefaultRefreshTokenStore(_store,\n                new PersistentGrantSerializer(),\n                _stubHandleGenerationService,\n                TestLogger.Create<DefaultRefreshTokenStore>());\n            _referenceTokens = new DefaultReferenceTokenStore(_store,\n                new PersistentGrantSerializer(),\n                _stubHandleGenerationService,\n                TestLogger.Create<DefaultReferenceTokenStore>());\n            _userConsent = new DefaultUserConsentStore(_store,\n                new PersistentGrantSerializer(),\n                _stubHandleGenerationService,\n                TestLogger.Create<DefaultUserConsentStore>());\n        }\n        \n        [Fact]\n        public async Task StoreAuthorizationCodeAsync_should_persist_grant()\n        {\n            var code1 = new AuthorizationCode()\n            {\n                ClientId = \"test\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = _user,\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"scope1\", \"scope2\" }\n            };\n\n            var handle = await _codes.StoreAuthorizationCodeAsync(code1);\n            var code2 = await _codes.GetAuthorizationCodeAsync(handle);\n\n            code1.ClientId.Should().Be(code2.ClientId);\n            code1.CreationTime.Should().Be(code2.CreationTime);\n            code1.Lifetime.Should().Be(code2.Lifetime);\n            code1.Subject.GetSubjectId().Should().Be(code2.Subject.GetSubjectId());\n            code1.CodeChallenge.Should().Be(code2.CodeChallenge);\n            code1.RedirectUri.Should().Be(code2.RedirectUri);\n            code1.Nonce.Should().Be(code2.Nonce);\n            code1.RequestedScopes.Should().BeEquivalentTo(code2.RequestedScopes);\n        }\n\n        [Fact]\n        public async Task RemoveAuthorizationCodeAsync_should_remove_grant()\n        {\n            var code1 = new AuthorizationCode()\n            {\n                ClientId = \"test\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Subject = _user,\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"scope1\", \"scope2\" }\n            };\n\n            var handle = await _codes.StoreAuthorizationCodeAsync(code1);\n            await _codes.RemoveAuthorizationCodeAsync(handle);\n            var code2 = await _codes.GetAuthorizationCodeAsync(handle);\n            code2.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task StoreRefreshTokenAsync_should_persist_grant()\n        {\n            var token1 = new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"foo\")\n                    }\n                },\n                Version = 1\n            };\n\n            var handle = await _refreshTokens.StoreRefreshTokenAsync(token1);\n            var token2 = await _refreshTokens.GetRefreshTokenAsync(handle);\n\n            token1.ClientId.Should().Be(token2.ClientId);\n            token1.CreationTime.Should().Be(token2.CreationTime);\n            token1.Lifetime.Should().Be(token2.Lifetime);\n            token1.Subject.GetSubjectId().Should().Be(token2.Subject.GetSubjectId());\n            token1.Version.Should().Be(token2.Version);\n            token1.AccessToken.Audiences.Count.Should().Be(1);\n            token1.AccessToken.Audiences.First().Should().Be(\"aud\");\n            token1.AccessToken.ClientId.Should().Be(token2.AccessToken.ClientId);\n            token1.AccessToken.CreationTime.Should().Be(token2.AccessToken.CreationTime);\n            token1.AccessToken.Type.Should().Be(token2.AccessToken.Type);\n        }\n\n        [Fact]\n        public async Task RemoveRefreshTokenAsync_should_remove_grant()\n        {\n            var token1 = new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"foo\")\n                    }\n                },\n                Version = 1\n            };\n\n\n            var handle = await _refreshTokens.StoreRefreshTokenAsync(token1);\n            await _refreshTokens.RemoveRefreshTokenAsync(handle);\n            var token2 = await _refreshTokens.GetRefreshTokenAsync(handle);\n            token2.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task RemoveRefreshTokenAsync_by_sub_and_client_should_remove_grant()\n        {\n            var token1 = new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                AccessToken = new Token\n                {\n                    ClientId = \"client\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"foo\")\n                    }\n                },\n                Version = 1\n            };\n\n            var handle1 = await _refreshTokens.StoreRefreshTokenAsync(token1);\n            var handle2 = await _refreshTokens.StoreRefreshTokenAsync(token1);\n            await _refreshTokens.RemoveRefreshTokensAsync(\"123\", \"client\");\n\n            var token2 = await _refreshTokens.GetRefreshTokenAsync(handle1);\n            token2.Should().BeNull();\n            token2 = await _refreshTokens.GetRefreshTokenAsync(handle2);\n            token2.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task StoreReferenceTokenAsync_should_persist_grant()\n        {\n            var token1 = new Token()\n            {\n                ClientId = \"client\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"foo\")\n                },\n                Version = 1\n            };\n\n            var handle = await _referenceTokens.StoreReferenceTokenAsync(token1);\n            var token2 = await _referenceTokens.GetReferenceTokenAsync(handle);\n\n            token1.ClientId.Should().Be(token2.ClientId);\n            token1.Audiences.Count.Should().Be(1);\n            token1.Audiences.First().Should().Be(\"aud\");\n            token1.CreationTime.Should().Be(token2.CreationTime);\n            token1.Type.Should().Be(token2.Type);\n            token1.Lifetime.Should().Be(token2.Lifetime);\n            token1.Version.Should().Be(token2.Version);\n        }\n\n        [Fact]\n        public async Task RemoveReferenceTokenAsync_should_remove_grant()\n        {\n            var token1 = new Token()\n            {\n                ClientId = \"client\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"foo\")\n                },\n                Version = 1\n            };\n\n            var handle = await _referenceTokens.StoreReferenceTokenAsync(token1);\n            await _referenceTokens.RemoveReferenceTokenAsync(handle);\n            var token2 = await _referenceTokens.GetReferenceTokenAsync(handle);\n            token2.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task RemoveReferenceTokenAsync_by_sub_and_client_should_remove_grant()\n        {\n            var token1 = new Token()\n            {\n                ClientId = \"client\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"foo\")\n                },\n                Version = 1\n            };\n\n            var handle1 = await _referenceTokens.StoreReferenceTokenAsync(token1);\n            var handle2 = await _referenceTokens.StoreReferenceTokenAsync(token1);\n            await _referenceTokens.RemoveReferenceTokensAsync(\"123\", \"client\");\n\n            var token2 = await _referenceTokens.GetReferenceTokenAsync(handle1);\n            token2.Should().BeNull();\n            token2 = await _referenceTokens.GetReferenceTokenAsync(handle2);\n            token2.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task StoreUserConsentAsync_should_persist_grant()\n        {\n            var consent1 = new Consent()\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = \"client\",\n                SubjectId = \"123\",\n                Scopes = new string[] { \"foo\", \"bar\" }\n            };\n\n            await _userConsent.StoreUserConsentAsync(consent1);\n            var consent2 = await _userConsent.GetUserConsentAsync(\"123\", \"client\");\n\n            consent2.ClientId.Should().Be(consent1.ClientId);\n            consent2.SubjectId.Should().Be(consent1.SubjectId);\n            consent2.Scopes.Should().BeEquivalentTo(new string[] { \"bar\", \"foo\" });\n        }\n\n        [Fact]\n        public async Task RemoveUserConsentAsync_should_remove_grant()\n        {\n            var consent1 = new Consent()\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = \"client\",\n                SubjectId = \"123\",\n                Scopes = new string[] { \"foo\", \"bar\" }\n            };\n\n            await _userConsent.StoreUserConsentAsync(consent1);\n            await _userConsent.RemoveUserConsentAsync(\"123\", \"client\");\n            var consent2 = await _userConsent.GetUserConsentAsync(\"123\", \"client\");\n            consent2.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task same_key_for_different_grant_types_should_not_interfere_with_each_other()\n        {\n            _stubHandleGenerationService.Handle = \"key\";\n\n            await _referenceTokens.StoreReferenceTokenAsync(new Token()\n            {\n                ClientId = \"client1\",\n                Audiences = { \"aud\" },\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 10,\n                Type = \"type\",\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\"),\n                    new Claim(\"scope\", \"bar1\"),\n                    new Claim(\"scope\", \"bar2\")\n                }\n            });\n\n            await _refreshTokens.StoreRefreshTokenAsync(new RefreshToken()\n            {\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 20,\n                AccessToken = new Token\n                {\n                    ClientId = \"client1\",\n                    Audiences = { \"aud\" },\n                    CreationTime = DateTime.UtcNow,\n                    Type = \"type\",\n                    Claims = new List<Claim>\n                    {\n                        new Claim(\"sub\", \"123\"),\n                        new Claim(\"scope\", \"baz1\"),\n                        new Claim(\"scope\", \"baz2\")\n                    }\n                },\n                Version = 1\n            });\n\n            await _codes.StoreAuthorizationCodeAsync(new AuthorizationCode()\n            {\n                ClientId = \"client1\",\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 30,\n                Subject = _user,\n                CodeChallenge = \"challenge\",\n                RedirectUri = \"http://client/cb\",\n                Nonce = \"nonce\",\n                RequestedScopes = new string[] { \"quux1\", \"quux2\" }\n            });\n\n            (await _codes.GetAuthorizationCodeAsync(\"key\")).Lifetime.Should().Be(30);\n            (await _refreshTokens.GetRefreshTokenAsync(\"key\")).Lifetime.Should().Be(20);\n            (await _referenceTokens.GetReferenceTokenAsync(\"key\")).Lifetime.Should().Be(10);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Stores/InMemoryClientStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing System;\nusing System.Collections.Generic;\nusing Xunit;\nusing FluentAssertions;\n\nnamespace IdentityServer.UnitTests.Stores\n{\n    public class InMemoryClientStoreTests\n    {\n        [Fact]\n        public void InMemoryClient_should_throw_if_contain_duplicate_client_ids()\n        {\n            List<Client> clients = new List<Client>\n            {\n                new Client { ClientId = \"1\"},\n                new Client { ClientId = \"1\"},\n                new Client { ClientId = \"3\"}\n            };\n\n            Action act = () => new InMemoryClientStore(clients);\n            act.Should().Throw<ArgumentException>();\n        }\n\n        [Fact]\n        public void InMemoryClient_should_not_throw_if_does_not_contain_duplicate_client_ids()\n        {\n            List<Client> clients = new List<Client>\n            {\n                new Client { ClientId = \"1\"},\n                new Client { ClientId = \"2\"},\n                new Client { ClientId = \"3\"}\n            };\n\n            new InMemoryClientStore(clients);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Stores/InMemoryDeviceFlowStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Stores\n{\n    public class InMemoryDeviceFlowStoreTests\n    {\n        private InMemoryDeviceFlowStore _store = new InMemoryDeviceFlowStore();\n\n        [Fact]\n        public async Task StoreDeviceAuthorizationAsync_should_persist_data_by_user_code()\n        {\n            var deviceCode = Guid.NewGuid().ToString();\n            var userCode = Guid.NewGuid().ToString();\n            var data = new DeviceCode\n            {\n                ClientId = Guid.NewGuid().ToString(),\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 300,\n                IsAuthorized = false,\n                IsOpenId = true,\n                Subject = null,\n                RequestedScopes = new[] {\"scope1\", \"scope2\"}\n            };\n\n            await _store.StoreDeviceAuthorizationAsync(deviceCode, userCode, data);\n            var foundData = await _store.FindByUserCodeAsync(userCode);\n\n            foundData.ClientId.Should().Be(data.ClientId);\n            foundData.CreationTime.Should().Be(data.CreationTime);\n            foundData.Lifetime.Should().Be(data.Lifetime);\n            foundData.IsAuthorized.Should().Be(data.IsAuthorized);\n            foundData.IsOpenId.Should().Be(data.IsOpenId);\n            foundData.Subject.Should().Be(data.Subject);\n            foundData.RequestedScopes.Should().BeEquivalentTo(data.RequestedScopes);\n        }\n\n        [Fact]\n        public async Task StoreDeviceAuthorizationAsync_should_persist_data_by_device_code()\n        {\n            var deviceCode = Guid.NewGuid().ToString();\n            var userCode = Guid.NewGuid().ToString();\n            var data = new DeviceCode\n            {\n                ClientId = Guid.NewGuid().ToString(),\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 300,\n                IsAuthorized = false,\n                IsOpenId = true,\n                Subject = null,\n                RequestedScopes = new[] {\"scope1\", \"scope2\"}\n            };\n\n            await _store.StoreDeviceAuthorizationAsync(deviceCode, userCode, data);\n            var foundData = await _store.FindByDeviceCodeAsync(deviceCode);\n\n            foundData.ClientId.Should().Be(data.ClientId);\n            foundData.CreationTime.Should().Be(data.CreationTime);\n            foundData.Lifetime.Should().Be(data.Lifetime);\n            foundData.IsAuthorized.Should().Be(data.IsAuthorized);\n            foundData.IsOpenId.Should().Be(data.IsOpenId);\n            foundData.Subject.Should().Be(data.Subject);\n            foundData.RequestedScopes.Should().BeEquivalentTo(data.RequestedScopes);\n        }\n\n        [Fact]\n        public async Task UpdateByUserCodeAsync_should_update_data()\n        {\n            var deviceCode = Guid.NewGuid().ToString();\n            var userCode = Guid.NewGuid().ToString();\n            var initialData = new DeviceCode\n            {\n                ClientId = Guid.NewGuid().ToString(),\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 300,\n                IsAuthorized = false,\n                IsOpenId = true,\n                Subject = null,\n                RequestedScopes = new[] {\"scope1\", \"scope2\"}\n            };\n\n            await _store.StoreDeviceAuthorizationAsync(deviceCode, userCode, initialData);\n\n            var updatedData = new DeviceCode\n            {\n                ClientId = Guid.NewGuid().ToString(),\n                CreationTime = initialData.CreationTime.AddHours(2),\n                Lifetime = initialData.Lifetime + 600,\n                IsAuthorized = !initialData.IsAuthorized,\n                IsOpenId = !initialData.IsOpenId,\n                Subject = new ClaimsPrincipal(new ClaimsIdentity(new List<Claim> {new Claim(\"sub\", \"123\")})),\n                RequestedScopes = new[] {\"api1\", \"api2\"}\n            };\n\n            await _store.UpdateByUserCodeAsync(userCode, updatedData);\n\n            var foundData = await _store.FindByUserCodeAsync(userCode);\n\n            foundData.ClientId.Should().Be(updatedData.ClientId);\n            foundData.CreationTime.Should().Be(updatedData.CreationTime);\n            foundData.Lifetime.Should().Be(updatedData.Lifetime);\n            foundData.IsAuthorized.Should().Be(updatedData.IsAuthorized);\n            foundData.IsOpenId.Should().Be(updatedData.IsOpenId);\n            foundData.Subject.Should().BeEquivalentTo(updatedData.Subject);\n            foundData.RequestedScopes.Should().BeEquivalentTo(updatedData.RequestedScopes);\n        }\n\n        [Fact]\n        public async Task RemoveByDeviceCodeAsync_should_update_data()\n        {\n            var deviceCode = Guid.NewGuid().ToString();\n            var userCode = Guid.NewGuid().ToString();\n            var data = new DeviceCode\n            {\n                ClientId = Guid.NewGuid().ToString(),\n                CreationTime = DateTime.UtcNow,\n                Lifetime = 300,\n                IsAuthorized = false,\n                IsOpenId = true,\n                Subject = null,\n                RequestedScopes = new[] { \"scope1\", \"scope2\" }\n            };\n\n            await _store.StoreDeviceAuthorizationAsync(deviceCode, userCode, data);\n            await _store.RemoveByDeviceCodeAsync(deviceCode);\n            var foundData = await _store.FindByUserCodeAsync(userCode);\n\n            foundData.Should().BeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Stores/InMemoryPersistedGrantStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\nusing FluentAssertions;\nusing System.Threading.Tasks;\nusing System.Linq;\n\nnamespace IdentityServer.UnitTests.Stores\n{\n    public class InMemoryPersistedGrantStoreTests\n    {\n        InMemoryPersistedGrantStore _subject;\n\n        public InMemoryPersistedGrantStoreTests()\n        {\n            _subject = new InMemoryPersistedGrantStore();\n        }\n\n        [Fact]\n        public async Task Store_should_persist_value()\n        {\n            {\n                var item = await _subject.GetAsync(\"key1\");\n                item.Should().BeNull();\n            }\n\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key1\" });\n\n            {\n                var item = await _subject.GetAsync(\"key1\");\n                item.Should().NotBeNull();\n            }\n        }\n\n        [Fact]\n        public async Task GetAll_should_filter()\n        {\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key1\", SubjectId = \"sub1\", ClientId = \"client1\", SessionId = \"session1\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key2\", SubjectId = \"sub1\", ClientId = \"client2\", SessionId = \"session1\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key3\", SubjectId = \"sub1\", ClientId = \"client1\", SessionId = \"session2\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key4\", SubjectId = \"sub1\", ClientId = \"client3\", SessionId = \"session2\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key5\", SubjectId = \"sub1\", ClientId = \"client4\", SessionId = \"session3\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key6\", SubjectId = \"sub1\", ClientId = \"client4\", SessionId = \"session4\" });\n\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key7\", SubjectId = \"sub2\", ClientId = \"client4\", SessionId = \"session4\" });\n\n\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key1\", \"key2\", \"key3\", \"key4\", \"key5\", \"key6\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key7\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub3\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client1\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key1\", \"key3\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client2\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key2\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client3\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key4\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client4\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key5\", \"key6\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client5\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\",\n                ClientId = \"client1\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\",\n                ClientId = \"client4\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key7\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub3\",\n                ClientId = \"client1\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client1\",\n                SessionId = \"session1\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key1\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client1\",\n                SessionId = \"session2\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key3\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client1\",\n                SessionId = \"session3\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client2\",\n                SessionId = \"session1\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key2\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client2\",\n                SessionId = \"session2\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub1\",\n                ClientId = \"client4\",\n                SessionId = \"session4\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key6\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\",\n                ClientId = \"client4\",\n                SessionId = \"session4\"\n            }))\n            .Select(x => x.Key).Should().BeEquivalentTo(new[] { \"key7\" });\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\",\n                ClientId = \"client4\",\n                SessionId = \"session1\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n\n            (await _subject.GetAllAsync(new PersistedGrantFilter\n            {\n                SubjectId = \"sub2\",\n                ClientId = \"client4\",\n                SessionId = \"session5\"\n            }))\n            .Select(x => x.Key).Should().BeEmpty();\n        }\n\n        [Fact]\n        public async Task RemoveAll_should_filter()\n        {\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().BeNull();\n                (await _subject.GetAsync(\"key2\")).Should().BeNull();\n                (await _subject.GetAsync(\"key3\")).Should().BeNull();\n                (await _subject.GetAsync(\"key4\")).Should().BeNull();\n                (await _subject.GetAsync(\"key5\")).Should().BeNull();\n                (await _subject.GetAsync(\"key6\")).Should().BeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub2\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().BeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub3\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().BeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().BeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client2\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().BeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client3\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().BeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client4\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().BeNull();\n                (await _subject.GetAsync(\"key6\")).Should().BeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client5\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub2\",\n                    ClientId = \"client1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client4\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().BeNull();\n                (await _subject.GetAsync(\"key6\")).Should().BeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub3\",\n                    ClientId = \"client1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client1\",\n                    SessionId = \"session1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().BeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client1\",\n                    SessionId = \"session2\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().BeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client1\",\n                    SessionId = \"session3\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client2\",\n                    SessionId = \"session1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().BeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client2\",\n                    SessionId = \"session2\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub1\",\n                    ClientId = \"client4\",\n                    SessionId = \"session4\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().BeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub2\",\n                    ClientId = \"client4\",\n                    SessionId = \"session4\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().BeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub2\",\n                    ClientId = \"client4\",\n                    SessionId = \"session1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub2\",\n                    ClientId = \"client4\",\n                    SessionId = \"session5\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n            {\n                await Populate();\n                await _subject.RemoveAllAsync(new PersistedGrantFilter\n                {\n                    SubjectId = \"sub3\",\n                    ClientId = \"client1\",\n                    SessionId = \"session1\"\n                });\n                (await _subject.GetAsync(\"key1\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key2\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key3\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key4\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key5\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key6\")).Should().NotBeNull();\n                (await _subject.GetAsync(\"key7\")).Should().NotBeNull();\n            }\n        }\n\n        private async Task Populate()\n        {\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key1\", SubjectId = \"sub1\", ClientId = \"client1\", SessionId = \"session1\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key2\", SubjectId = \"sub1\", ClientId = \"client2\", SessionId = \"session1\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key3\", SubjectId = \"sub1\", ClientId = \"client1\", SessionId = \"session2\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key4\", SubjectId = \"sub1\", ClientId = \"client3\", SessionId = \"session2\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key5\", SubjectId = \"sub1\", ClientId = \"client4\", SessionId = \"session3\" });\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key6\", SubjectId = \"sub1\", ClientId = \"client4\", SessionId = \"session4\" });\n\n            await _subject.StoreAsync(new PersistedGrant() { Key = \"key7\", SubjectId = \"sub2\", ClientId = \"client4\", SessionId = \"session4\" });\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Stores/InMemoryResourcesStoreTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing System;\nusing System.Collections.Generic;\nusing Xunit;\nusing FluentAssertions;\n\nnamespace IdentityServer.UnitTests.Stores\n{\n    public class InMemoryResourcesStoreTests\n    {\n        [Fact]\n        public void InMemoryResourcesStore_should_throw_if_contains_duplicate_names()\n        {\n            List<IdentityResource> identityResources = new List<IdentityResource>\n            {\n                new IdentityResource { Name = \"A\" },\n                new IdentityResource { Name = \"A\" },\n                new IdentityResource { Name = \"C\" }\n            };\n\n            List<ApiResource> apiResources = new List<ApiResource>\n            {\n                new ApiResource { Name = \"B\" },\n                new ApiResource { Name = \"B\" },\n                new ApiResource { Name = \"C\" }\n            };\n\n            List<ApiScope> scopes = new List<ApiScope>\n            {\n                new ApiScope { Name = \"B\" },\n                new ApiScope { Name = \"C\" },\n                new ApiScope { Name = \"C\" },\n            };\n\n            Action act = () => new InMemoryResourcesStore(identityResources, null, null);\n            act.Should().Throw<ArgumentException>();\n\n            act = () => new InMemoryResourcesStore(null, apiResources, null);\n            act.Should().Throw<ArgumentException>();\n            \n            act = () => new InMemoryResourcesStore(null, null, scopes);\n            act.Should().Throw<ArgumentException>();\n        }\n\n        [Fact]\n        public void InMemoryResourcesStore_should_not_throw_if_does_not_contains_duplicate_names()\n        {\n            List<IdentityResource> identityResources = new List<IdentityResource>\n            {\n                new IdentityResource { Name = \"A\" },\n                new IdentityResource { Name = \"B\" },\n                new IdentityResource { Name = \"C\" }\n            };\n\n            List<ApiResource> apiResources = new List<ApiResource>\n            {\n                new ApiResource { Name = \"A\" },\n                new ApiResource { Name = \"B\" },\n                new ApiResource { Name = \"C\" }\n            };\n\n            List<ApiScope> apiScopes = new List<ApiScope>\n            {\n                new ApiScope { Name = \"A\" },\n                new ApiScope { Name = \"B\" },\n                new ApiScope { Name = \"C\" },\n            };\n            \n            new InMemoryResourcesStore(identityResources, null, null);\n            new InMemoryResourcesStore(null, apiResources, null);\n            new InMemoryResourcesStore(null, null, apiScopes);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AccessTokenValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class AccessTokenValidation\n    {\n        private const string Category = \"Access token validation\";\n\n        private IClientStore _clients = Factory.CreateClientStore();\n        private IdentityServerOptions _options = new IdentityServerOptions();\n        private StubClock _clock = new StubClock();\n\n        static AccessTokenValidation()\n        {\n            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n        }\n\n        private DateTime now;\n        public DateTime UtcNow\n        {\n            get\n            {\n                if (now > DateTime.MinValue) return now;\n                return DateTime.UtcNow;\n            }\n        }\n\n        public AccessTokenValidation()\n        {\n            _clock.UtcNowFunc = () => UtcNow;\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Reference_Token()\n        {\n            var store = Factory.CreateReferenceTokenStore();\n            var validator = Factory.CreateTokenValidator(store);\n\n            var token = TokenFactory.CreateAccessToken(new Client { ClientId = \"roclient\" }, \"valid\", 600, \"read\", \"write\");\n\n            var handle = await store.StoreReferenceTokenAsync(token);\n\n            var result = await validator.ValidateAccessTokenAsync(handle);\n\n            result.IsError.Should().BeFalse();\n            result.Claims.Count().Should().Be(8);\n            result.Claims.First(c => c.Type == JwtClaimTypes.ClientId).Value.Should().Be(\"roclient\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Reference_Token_with_required_Scope()\n        {\n            var store = Factory.CreateReferenceTokenStore();\n            var validator = Factory.CreateTokenValidator(store);\n\n            var token = TokenFactory.CreateAccessToken(new Client { ClientId = \"roclient\" }, \"valid\", 600, \"read\", \"write\");\n\n            var handle = await store.StoreReferenceTokenAsync(token);\n\n            var result = await validator.ValidateAccessTokenAsync(handle, \"read\");\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Reference_Token_with_missing_Scope()\n        {\n            var store = Factory.CreateReferenceTokenStore();\n            var validator = Factory.CreateTokenValidator(store);\n\n            var token = TokenFactory.CreateAccessToken(new Client { ClientId = \"roclient\" }, \"valid\", 600, \"read\", \"write\");\n\n            var handle = await store.StoreReferenceTokenAsync(token);\n\n            var result = await validator.ValidateAccessTokenAsync(handle, \"missing\");\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InsufficientScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_Reference_Token()\n        {\n            var validator = Factory.CreateTokenValidator();\n\n            var result = await validator.ValidateAccessTokenAsync(\"unknown\");\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Reference_Token_Too_Long()\n        {\n            var validator = Factory.CreateTokenValidator();\n            var options = new IdentityServerOptions();\n\n            var longToken = \"x\".Repeat(options.InputLengthRestrictions.TokenHandle + 1);\n            var result = await validator.ValidateAccessTokenAsync(longToken);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Expired_Reference_Token()\n        {\n            now = DateTime.UtcNow;\n\n            var store = Factory.CreateReferenceTokenStore();\n            var validator = Factory.CreateTokenValidator(store, clock:_clock);\n\n            var token = TokenFactory.CreateAccessToken(new Client { ClientId = \"roclient\" }, \"valid\", 2, \"read\", \"write\");\n            token.CreationTime = now;\n\n            var handle = await store.StoreReferenceTokenAsync(token);\n\n            now = now.AddSeconds(3);\n\n            var result = await validator.ValidateAccessTokenAsync(handle);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.ExpiredToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Malformed_JWT_Token()\n        {\n            var validator = Factory.CreateTokenValidator();\n\n            var result = await validator.ValidateAccessTokenAsync(\"unk.nown\");\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_JWT_Token()\n        {\n            var signer = Factory.CreateDefaultTokenCreator();\n            var jwt = await signer.CreateTokenAsync(TokenFactory.CreateAccessToken(new Client { ClientId = \"roclient\" }, \"valid\", 600, \"read\", \"write\"));\n\n            var validator = Factory.CreateTokenValidator(null);\n            var result = await validator.ValidateAccessTokenAsync(jwt);\n\n            result.IsError.Should().BeFalse();\n        }\n        \n        [Theory]\n        [InlineData(true)]\n        [InlineData(false)]\n        [Trait(\"Category\", Category)]\n        public async Task JWT_Token_with_scopes_have_expected_claims(bool flag)\n        {\n            var options = TestIdentityServerOptions.Create();\n            options.EmitScopesAsSpaceDelimitedStringInJwt = flag;\n            \n            var signer = Factory.CreateDefaultTokenCreator(options);\n            var jwt = await signer.CreateTokenAsync(TokenFactory.CreateAccessToken(new Client { ClientId = \"roclient\" }, \"valid\", 600, \"read\", \"write\"));\n\n            var validator = Factory.CreateTokenValidator(null);\n            var result = await validator.ValidateAccessTokenAsync(jwt);\n\n            result.IsError.Should().BeFalse();\n            result.Jwt.Should().NotBeNullOrEmpty();\n            result.Client.ClientId.Should().Be(\"roclient\");\n\n            result.Claims.Count().Should().Be(8);\n            var scopes = result.Claims.Where(c => c.Type == \"scope\").Select(c => c.Value).ToArray();\n            scopes.Count().Should().Be(2);\n            scopes[0].Should().Be(\"read\");\n            scopes[1].Should().Be(\"write\");\n        }\n        \n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task JWT_Token_invalid_Issuer()\n        {\n            var signer = Factory.CreateDefaultTokenCreator();\n            var token = TokenFactory.CreateAccessToken(new Client { ClientId = \"roclient\" }, \"valid\", 600, \"read\", \"write\");\n            token.Issuer = \"invalid\";\n            var jwt = await signer.CreateTokenAsync(token);\n\n            var validator = Factory.CreateTokenValidator(null);\n            var result = await validator.ValidateAccessTokenAsync(jwt);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task JWT_Token_Too_Long()\n        {\n            var signer = Factory.CreateDefaultTokenCreator();\n            var jwt = await signer.CreateTokenAsync(TokenFactory.CreateAccessTokenLong(new Client { ClientId = \"roclient\" }, \"valid\", 600, 1000, \"read\", \"write\"));\n            \n            var validator = Factory.CreateTokenValidator(null);\n            var result = await validator.ValidateAccessTokenAsync(jwt);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_AccessToken_but_Client_not_active()\n        {\n            var store = Factory.CreateReferenceTokenStore();\n            var validator = Factory.CreateTokenValidator(store);\n\n            var token = TokenFactory.CreateAccessToken(new Client { ClientId = \"unknown\" }, \"valid\", 600, \"read\", \"write\");\n\n            var handle = await store.StoreReferenceTokenAsync(token);\n\n            var result = await validator.ValidateAccessTokenAsync(handle);\n\n            result.IsError.Should().BeTrue();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ClientValidation_Code.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ClientValidation_Code\n    {\n        private IdentityServerOptions _options = TestIdentityServerOptions.Create();\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - Code\")]\n        public async Task Code_Request_Unknown_Scope()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"unknown\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - Code\")]\n        public async Task OpenId_Code_Request_Invalid_RedirectUri()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://invalid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - Code\")]\n        public async Task OpenId_Code_Request_Invalid_IdToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - Code\")]\n        public async Task OpenId_Code_Request_Invalid_IdTokenToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - Code\")]\n        public async Task OpenId_Code_Request_With_Unknown_Client()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"unknown\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - Code\")]\n        public async Task OpenId_Code_Request_With_Restricted_Scope()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient_restricted\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid profile\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ClientValidation_IdToken.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n\n    public class Authorize_ClientValidation_IdToken\n    {\n        private IdentityServerOptions _options = TestIdentityServerOptions.Create();\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - IdToken\")]\n        public async Task Mixed_IdToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ClientValidation_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ClientValidation_Invalid\n    {\n        private const string Category = \"AuthorizeRequest Client Validation - Invalid\";\n\n        private IdentityServerOptions _options = TestIdentityServerOptions.Create();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Protocol_Client()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"wsfed\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://wsfed/callback\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ClientValidation_Token.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ClientValidation_Token\n    {\n        private const string Category = \"AuthorizeRequest Client Validation - Token\";\n\n        private IdentityServerOptions _options = TestIdentityServerOptions.Create();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Mixed_Token_Request_Without_OpenId_Scope()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"resource profile\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Token);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IdTokenToken_Request_with_no_AAVB()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient_no_aavb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task CodeIdTokenToken_Request_with_no_AAVB()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient_no_aavb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"nonce\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdTokenToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ClientValidation_Valid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ClientValidation_Valid\n    {\n        private const string Category = \"AuthorizeRequest Client Validation - Valid\";\n\n        private IdentityServerOptions _options = TestIdentityServerOptions.Create();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_Code_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Resource_Code_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_Code_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_Code_Request_Multiple_Scopes()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid profile resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_CodeIdToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"nonce\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_CodeIdTokenToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"nonce\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdTokenToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_CodeIdToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"nonce\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_CodeIdTokenToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"nonce\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdTokenToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_IdTokenToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_IdTokenToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_IdTokenToken_Request_Multiple_Scopes()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid profile resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Resource_Token_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Token);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n            \n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", \"AuthorizeRequest Client Validation - Valid\")]\n        public async Task Valid_OpenId_TokenIdToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, \"token id_token\"); // Unconventional order\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ProtocolValidation_CustomValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ProtocolValidation_CustomValidator\n    {\n        private const string Category = \"AuthorizeRequest Protocol Validation\";\n\n        private StubAuthorizeRequestValidator _stubAuthorizeRequestValidator = new StubAuthorizeRequestValidator();\n        private AuthorizeRequestValidator _subject;\n\n        public Authorize_ProtocolValidation_CustomValidator()\n        {\n            _subject = Factory.CreateAuthorizeRequestValidator(customValidator: _stubAuthorizeRequestValidator);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task should_call_custom_validator()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var result = await _subject.ValidateAsync(parameters);\n\n            _stubAuthorizeRequestValidator.WasCalled.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task should_return_error_info_from_custom_validator()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            _stubAuthorizeRequestValidator.Callback = ctx =>\n            {\n                ctx.Result = new AuthorizeRequestValidationResult(ctx.Result.ValidatedRequest, \"foo\", \"bar\");\n            };\n            var result = await _subject.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(\"foo\");\n            result.ErrorDescription.Should().Be(\"bar\");\n        }\n    }\n\n    public class StubAuthorizeRequestValidator : ICustomAuthorizeRequestValidator\n    {\n        public Action<CustomAuthorizeRequestValidationContext> Callback;\n        public bool WasCalled { get; set; }\n\n        public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)\n        {\n            WasCalled = true;\n            Callback?.Invoke(context);\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ProtocolValidation_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ProtocolValidation_Invalid\n    {\n        private const string Category = \"AuthorizeRequest Protocol Validation\";\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Null_Parameter()\n        {\n            var validator = Factory.CreateAuthorizeRequestValidator();\n\n            Func<Task> act = () => validator.ValidateAsync(null);\n\n            act.Should().ThrowAsync<ArgumentNullException>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Empty_Parameters()\n        {\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(new NameValueCollection());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        // fails because openid scope is requested, but no response type that indicates an identity token\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task OpenId_Token_Only_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, IdentityServerConstants.StandardScopes.OpenId);\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Token);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Resource_Only_IdToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Mixed_Token_Only_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Token);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task OpenId_IdToken_Request_Nonce_Missing()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_ClientId()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/callback\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_Scope()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_RedirectUri()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"client\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Malformed_RedirectUri()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"client\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"malformed\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Malformed_RedirectUri_Triple_Slash()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"client\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https:///attacker.com\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnsupportedResponseType);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, \"unknown\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnsupportedResponseType);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResponseMode_For_IdToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Query);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResponseMode_For_IdTokenToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Query);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResponseMode_For_CodeToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Query);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResponseMode_For_CodeIdToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Query);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResponseMode_For_CodeIdTokenToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Query);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Malformed_MaxAge()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n            parameters.Add(OidcConstants.AuthorizeRequest.MaxAge, \"malformed\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Negative_MaxAge()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n            parameters.Add(OidcConstants.AuthorizeRequest.MaxAge, \"-1\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResponseMode_For_TokenIdToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, \"token id_token\"); // Unconventional order\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Query);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResponseMode_For_IdTokenCodeToken_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, \"id_token code token\"); // Unconventional ordering\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Query);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task prompt_none_and_other_values_should_fail()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Fragment);\n            parameters.Add(OidcConstants.AuthorizeRequest.Prompt, \"none login\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ProtocolValidation_PKCE.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ProtocolValidation_Valid_PKCE\n    {\n        private const string Category = \"AuthorizeRequest Protocol Validation - PKCE\";\n\n        private InputLengthRestrictions lengths = new InputLengthRestrictions();\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task valid_openid_code_request_with_challenge_and_plain_method_should_be_forbidden_if_plain_is_forbidden(string clientId)\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, clientId);\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, \"x\".Repeat(lengths.CodeChallengeMinLength));\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallengeMethod, OidcConstants.CodeChallengeMethods.Plain);\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(true);\n            result.ErrorDescription.Should().Be(\"Transform algorithm not supported\");\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task valid_openid_code_request_with_challenge_and_sh256_method_should_be_allowed(string clientId)\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, clientId);\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, \"x\".Repeat(lengths.CodeChallengeMinLength));\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallengeMethod, OidcConstants.CodeChallengeMethods.Sha256);\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(false);\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce.plain\")]\n        [InlineData(\"codeclient.plain\")]\n        [Trait(\"Category\", Category)]\n        public async Task valid_openid_code_request_with_challenge_and_missing_method_should_be_allowed_if_plain_is_allowed(string clientId)\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, clientId);\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, \"x\".Repeat(lengths.CodeChallengeMinLength));\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(false);\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task valid_openid_code_request_with_challenge_and_missing_method_should_be_forbidden_if_plain_is_forbidden(string clientId)\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, clientId);\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, \"x\".Repeat(lengths.CodeChallengeMinLength));\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(true);\n            result.ErrorDescription.Should().Be(\"Transform algorithm not supported\");\n        }\n\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task openid_code_request_missing_challenge_should_be_rejected()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient.pkce\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(true);\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n            result.ErrorDescription.Should().Be(\"code challenge required\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task openid_hybrid_request_missing_challenge_should_be_rejected()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"hybridclient.pkce\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.CodeIdToken);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(true);\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n            result.ErrorDescription.Should().Be(\"code challenge required\");\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient.pkce.plain\")]\n        [InlineData(\"codeclient\")]\n        [InlineData(\"codeclient.plain\")]\n        [Trait(\"Category\", Category)]\n        public async Task openid_code_request_with_challenge_and_invalid_method_should_be_rejected(string clientId)\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, clientId);\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, \"x\".Repeat(lengths.CodeChallengeMinLength));\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallengeMethod, \"invalid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(true);\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n            result.ErrorDescription.Should().Be(\"Transform algorithm not supported\");\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient.pkce.plain\")]\n        [InlineData(\"codeclient\")]\n        [InlineData(\"codeclient.plain\")]\n        [Trait(\"Category\", Category)]\n        public async Task openid_code_request_with_too_short_challenge_should_be_rejected(string clientId)\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, clientId);\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, \"x\".Repeat(lengths.CodeChallengeMinLength - 1));\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallengeMethod, OidcConstants.CodeChallengeMethods.Plain);\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(true);\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient.pkce.plain\")]\n        [InlineData(\"codeclient\")]\n        [InlineData(\"codeclient.plain\")]\n        [Trait(\"Category\", Category)]\n        public async Task openid_code_request_with_too_long_challenge_should_be_rejected(string clientId)\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, clientId);\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallenge, \"x\".Repeat(lengths.CodeChallengeMaxLength + 1));\n            parameters.Add(OidcConstants.AuthorizeRequest.CodeChallengeMethod, OidcConstants.CodeChallengeMethods.Plain);\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(true);\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidRequest);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/AuthorizeRequest Validation/Authorize_ProtocolValidation_Valid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.AuthorizeRequest_Validation\n{\n    public class Authorize_ProtocolValidation_Valid\n    {\n        private const string Category = \"AuthorizeRequest Protocol Validation - Valid\";\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_Code_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().Be(false);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Resource_Code_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_Code_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Resource_Token_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Token);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_IdToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_IdTokenToken_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_IdToken_With_FormPost_ResponseMode_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, IdentityServerConstants.StandardScopes.OpenId);\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.FormPost);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_IdToken_Token_With_FormPost_ResponseMode_Request()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"implicitclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid resource\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"oob://implicit/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.IdTokenToken);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.FormPost);\n            parameters.Add(OidcConstants.AuthorizeRequest.Nonce, \"abc\");\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_ResponseMode_For_Code_ResponseType()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Fragment);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task anonymous_user_should_produce_session_state_value()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Fragment);\n            parameters.Add(OidcConstants.AuthorizeRequest.Prompt, OidcConstants.PromptModes.None);\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.ValidatedRequest.SessionId.Should().NotBeNull();\n        }\n        \n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task multiple_prompt_values_should_be_accepted()\n        {\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.AuthorizeRequest.ClientId, \"codeclient\");\n            parameters.Add(OidcConstants.AuthorizeRequest.Scope, \"openid\");\n            parameters.Add(OidcConstants.AuthorizeRequest.RedirectUri, \"https://server/cb\");\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseType, OidcConstants.ResponseTypes.Code);\n            parameters.Add(OidcConstants.AuthorizeRequest.ResponseMode, OidcConstants.ResponseModes.Fragment);\n            parameters.Add(OidcConstants.AuthorizeRequest.Prompt, OidcConstants.PromptModes.Consent.ToString() + \" \" + OidcConstants.PromptModes.Login.ToString());\n\n            var validator = Factory.CreateAuthorizeRequestValidator();\n            var result = await validator.ValidateAsync(parameters);\n\n            result.ValidatedRequest.PromptModes.Count().Should().Be(2);\n            result.ValidatedRequest.PromptModes.Should().Contain(OidcConstants.PromptModes.Login);\n            result.ValidatedRequest.PromptModes.Should().Contain(OidcConstants.PromptModes.Consent);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/BearerTokenUsageValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO;\nusing System.Text;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class BearerTokenUsageValidation\n    {\n        private const string Category = \"BearerTokenUsageValidator Tests\";\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task No_Header_no_Body_Get()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"GET\";\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create< BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task No_Header_no_Body_Post()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"POST\";\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Non_Bearer_Scheme_Header()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"GET\";\n            ctx.Request.Headers.Append(\"Authorization\", new string[] { \"Foo Bar\" });\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Empty_Bearer_Scheme_Header()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"GET\";\n            ctx.Request.Headers.Append(\"Authorization\", new string[] { \"Bearer\" });\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Whitespaces_Bearer_Scheme_Header()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"GET\";\n            ctx.Request.Headers.Append(\"Authorization\", new string[] { \"Bearer           \" });\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Bearer_Scheme_Header()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"GET\";\n            ctx.Request.Headers.Append(\"Authorization\", new string[] { \"Bearer token\" });\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeTrue();\n            result.Token.Should().Be(\"token\");\n            result.UsageType.Should().Be(BearerTokenUsageType.AuthorizationHeader);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Body_Post()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"POST\";\n            ctx.Request.ContentType = \"application/x-www-form-urlencoded\";\n            var body = \"access_token=token\";\n            ctx.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeTrue();\n            result.Token.Should().Be(\"token\");\n            result.UsageType.Should().Be(BearerTokenUsageType.PostBody);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Body_Post_empty_Token()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"POST\";\n            ctx.Request.ContentType = \"application/x-www-form-urlencoded\";\n            var body = \"access_token=\";\n            ctx.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Body_Post_Whitespace_Token()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"POST\";\n            ctx.Request.ContentType = \"application/x-www-form-urlencoded\";\n            var body = \"access_token=                \";\n            ctx.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Body_Post_no_Token()\n        {\n            var ctx = new DefaultHttpContext();\n            ctx.Request.Method = \"POST\";\n            ctx.Request.ContentType = \"application/x-www-form-urlencoded\";\n            var body = \"foo=bar\";\n            ctx.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n\n            var validator = new BearerTokenUsageValidator(TestLogger.Create<BearerTokenUsageValidator>());\n            var result = await validator.ValidateAsync(ctx);\n\n            result.TokenFound.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/ClientConfigurationValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing System;\nusing System.Threading.Tasks;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class ClientConfigurationValidation\n    {\n        private const string Category = \"Client Configuration Validation Tests\";\n        private IClientConfigurationValidator _validator;\n        IdentityServerOptions _options;\n\n        public ClientConfigurationValidation()\n        {\n            _options = new IdentityServerOptions();\n            _validator = new DefaultClientConfigurationValidator(_options);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Standard_clients_should_succeed()\n        {\n            foreach (var client in TestClients.Get())\n            {\n                // deliberate invalid configuration\n                if (client.ClientId == \"implicit_and_client_creds\") continue;\n\n                var context = await ValidateAsync(client);\n\n                if (!context.IsValid)\n                {\n                    throw new System.Exception($\"client {client.ClientId} failed configuration validation: {context.ErrorMessage}\");\n                }\n\n            }\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_access_token_lifetime_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                RequireClientSecret = false,\n                AllowedScopes = { \"foo\" },\n\n                AccessTokenLifetime = 0\n            };\n\n            await ShouldFailAsync(client, \"access token lifetime is 0 or negative\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_identity_token_lifetime_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                RequireClientSecret = false,\n                AllowedScopes = { \"foo\" },\n\n                IdentityTokenLifetime = 0\n            };\n\n            await ShouldFailAsync(client, \"identity token lifetime is 0 or negative\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_absolute_refresh_token_lifetime_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                RequireClientSecret = false,\n                AllowedScopes = { \"foo\" },\n\n                AbsoluteRefreshTokenLifetime = -1\n            };\n\n            await ShouldFailAsync(client, \"absolute refresh token lifetime is negative\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_sliding_refresh_token_lifetime_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                RequireClientSecret = false,\n                AllowedScopes = { \"foo\" },\n\n                SlidingRefreshTokenLifetime = -1\n            };\n\n            await ShouldFailAsync(client, \"sliding refresh token lifetime is negative\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_allowed_grant_type_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                RequireClientSecret = false,\n                AllowedScopes = { \"foo\" },\n            };\n\n            await ShouldFailAsync(client, \"no allowed grant type specified\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_client_secret_for_client_credentials_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                AllowedScopes = { \"foo\" },\n            };\n\n            await ShouldFailAsync(client, \"Client secret is required for client_credentials, but no client secret is configured.\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_client_secret_for_implicit_and_client_credentials_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,\n                RedirectUris = { \"https://foo\" },\n                AllowedScopes = { \"foo\" },\n            };\n\n            await ShouldFailAsync(client, \"Client secret is required for client_credentials, but no client secret is configured.\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_client_secret_for_hybrid_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Hybrid,\n                RedirectUris = { \"https://foo\" },\n                AllowedScopes = { \"foo\" },\n            };\n\n            await ShouldFailAsync(client, \"Client secret is required for hybrid, but no client secret is configured.\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_client_secret_for_code_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Code,\n                RedirectUris = { \"https://foo\" },\n                AllowedScopes = { \"foo\" },\n            };\n\n            await ShouldFailAsync(client, \"Client secret is required for authorization_code, but no client secret is configured.\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Not_required_client_secret_for_hybrid_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Hybrid,\n                RequireClientSecret = false,\n                RedirectUris = { \"https://foo\" },\n                AllowedScopes = { \"foo\" },\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_client_secret_for_implicit_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { \"https://foo\" }\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task empty_grant_types_collection_should_fail()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = { },\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { \"https://foo\" }\n            };\n\n            var context = await ValidateAsync(client);\n            await ShouldFailAsync(client, \"no allowed grant type specified\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task null_redirect_uris_collection_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                ClientSecrets = { new Secret(\"hash\") },\n                AllowedScopes = { \"foo\" },\n                RedirectUris = null,\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task null_post_logout_redirect_uris_collection_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                ClientSecrets = { new Secret(\"hash\") },\n                AllowedScopes = { \"foo\" },\n                PostLogoutRedirectUris = null\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task null_redirect_uris_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                ClientSecrets = { new Secret(\"hash\") },\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { null }\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task null_post_logout_redirect_uris_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                ClientSecrets = { new Secret(\"hash\") },\n                AllowedScopes = { \"foo\" },\n                PostLogoutRedirectUris = { null }\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task empty_redirect_uris_collection_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                ClientSecrets = { new Secret(\"hash\") },\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { },\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task empty_post_logout_redirect_uris_collection_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.ClientCredentials,\n                ClientSecrets = { new Secret(\"hash\") },\n                AllowedScopes = { \"foo\" },\n                PostLogoutRedirectUris = { },\n            };\n\n            var context = await ValidateAsync(client);\n            context.IsValid.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ValidateUriSchemesAsync_for_invalid_redirecturi_scheme_should_fail()\n        {\n            _options.Validation.InvalidRedirectUriPrefixes.Add(\"custom\");\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { \"http://callback\", \"custom://callback\" }\n            };\n\n            var result = await ValidateAsync(client);\n            await ShouldFailAsync(client, \"RedirectUri 'custom://callback' uses invalid scheme. If this scheme should be allowed, then configure it via ValidationOptions.\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ValidateUriSchemesAsync_for_null_redirecturi_scheme_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                AllowedScopes = { \"foo\" },\n                RedirectUris = null\n            };\n\n            var result = await ValidateAsync(client);\n            result.IsValid.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ValidateUriSchemesAsync_for_valid_redirect_uri_scheme_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { \"http://callback\", \"custom://callback\" }\n            };\n\n            var result = await ValidateAsync(client);\n            result.IsValid.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ValidateUriSchemesAsync_for_invalid_post_logout_redirect_uri_scheme_should_fail()\n        {\n            _options.Validation.InvalidRedirectUriPrefixes.Add(\"custom\");\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { \"http://callback\" },\n                PostLogoutRedirectUris = { \"http://postcallback\", \"custom://postcallback\" }\n            };\n\n            var result = await ValidateAsync(client);\n            await ShouldFailAsync(client, \"PostLogoutRedirectUri 'custom://postcallback' uses invalid scheme. If this scheme should be allowed, then configure it via ValidationOptions.\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task ValidateUriSchemesAsync_for_valid_post_logout_redirect_uri_scheme_should_succeed()\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                AllowedScopes = { \"foo\" },\n                RedirectUris = { \"http://callback\" },\n                PostLogoutRedirectUris = { \"http://postcallback\", \"custom://postcallback\" }\n            };\n\n            var result = await ValidateAsync(client);\n            result.IsValid.Should().BeTrue();\n        }\n\n        [Theory]\n        [Trait(\"Category\", Category)]\n        [InlineData(\"bad\")]\n        [InlineData(\"urn:foo\")]\n        [InlineData(\"urn:foo:123\")]\n        [InlineData(\"http://foo/\")]\n        [InlineData(\"http://foo:80/path\")]\n        [InlineData(\"http://foo/path\")]\n        [InlineData(\"http://foo:123/path\")]\n        [InlineData(\"https://foo:443/path\")]\n        [InlineData(\"custom://foo/\")]\n        [InlineData(\"custom://foo/path\")]\n        [InlineData(\"custom://foo:443/\")]\n        [InlineData(\"custom://foo:443/path\")]\n        [InlineData(\"\")]\n        [InlineData(\"   \")]\n        [InlineData((string)null)]\n        public async Task ValidateAllowedCorsOriginsAsync_should_report_invalid_URL_format(string origin)\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RedirectUris = { \"http://client\" },\n                AllowedCorsOrigins = { origin }\n            };\n\n            var result = await ValidateAsync(client);\n            result.IsValid.Should().BeFalse();\n            result.ErrorMessage.Should().Contain(\"invalid origin\");\n            if (!String.IsNullOrWhiteSpace(origin))\n            {\n                result.ErrorMessage.Should().Contain(origin);\n            }\n            else\n            {\n                result.ErrorMessage.Should().Contain(\"empty value\");\n            }\n        }\n\n        [Theory]\n        [Trait(\"Category\", Category)]\n        [InlineData(\"http://foo\")]\n        [InlineData(\"http://foo:80\")]\n        [InlineData(\"https://foo\")]\n        [InlineData(\"http://foo:123\")]\n        [InlineData(\"https://foo:456\")]\n        [InlineData(\"https://foo:443\")]\n        [InlineData(\"custom://foo\")]\n        [InlineData(\"custom://foo:443\")]\n        public async Task ValidateAllowedCorsOriginsAsync_should_allow_valid_formats(string origin)\n        {\n            var client = new Client\n            {\n                ClientId = \"id\",\n                AllowedGrantTypes = GrantTypes.Implicit,\n                RedirectUris = { \"http://client\" },\n                AllowedCorsOrigins = { origin }\n            };\n\n            var result = await ValidateAsync(client);\n            result.IsValid.Should().BeTrue();\n        }\n\n\n        private async Task<ClientConfigurationValidationContext> ValidateAsync(Client client)\n        {\n            var context = new ClientConfigurationValidationContext(client);\n            await _validator.ValidateAsync(context);\n\n            return context;\n        }\n\n        private async Task ShouldFailAsync(Client client, string expectedError)\n        {\n            var context = await ValidateAsync(client);\n\n            context.IsValid.Should().BeFalse();\n            context.ErrorMessage.Should().Be(expectedError);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/DeviceAuthorizationRequestValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Specialized;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class DeviceAuthorizationRequestValidation\n    {\n        private const string Category = \"Device authorization request validation\";\n\n        private readonly NameValueCollection testParameters = new NameValueCollection { { \"scope\", \"resource\" } };\n        private readonly Client testClient = new Client\n        {\n            ClientId = \"device_flow\",\n            AllowedGrantTypes = GrantTypes.DeviceFlow,\n            AllowedScopes = {\"openid\", \"profile\", \"resource\"},\n            AllowOfflineAccess = true\n        };\n        \n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Null_Parameter()\n        {\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n\n            Func<Task> act = () => validator.ValidateAsync(null, null);\n\n            act.Should().ThrowAsync<ArgumentNullException>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Protocol_Client()\n        {\n            testClient.ProtocolType = IdentityServerConstants.ProtocolTypes.WsFederation;\n\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n            var result = await validator.ValidateAsync(testParameters, new ClientSecretValidationResult {Client = testClient});\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Grant_Type()\n        {\n            testClient.AllowedGrantTypes = GrantTypes.Implicit;\n\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n            var result = await validator.ValidateAsync(testParameters, new ClientSecretValidationResult {Client = testClient});\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unauthorized_Scope()\n        {\n            var parameters = new NameValueCollection {{\"scope\", \"resource2\"}};\n\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n            var result = await validator.ValidateAsync(parameters, new ClientSecretValidationResult {Client = testClient});\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_Scope()\n        {\n            var parameters = new NameValueCollection {{\"scope\", Guid.NewGuid().ToString()}};\n\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n            var result = await validator.ValidateAsync(parameters, new ClientSecretValidationResult {Client = testClient});\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_OpenId_Request()\n        {\n            var parameters = new NameValueCollection {{\"scope\", \"openid\"}};\n\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n            var result = await validator.ValidateAsync(parameters, new ClientSecretValidationResult {Client = testClient});\n\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.IsOpenIdRequest.Should().BeTrue();\n            result.ValidatedRequest.RequestedScopes.Should().Contain(\"openid\");\n\n            result.ValidatedRequest.ValidatedResources.Resources.IdentityResources.Should().Contain(x => x.Name == \"openid\");\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.Should().BeEmpty();\n            result.ValidatedRequest.ValidatedResources.Resources.OfflineAccess.Should().BeFalse();\n\n            result.ValidatedRequest.ValidatedResources.Resources.IdentityResources.Any().Should().BeTrue();\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.Any().Should().BeFalse();\n            result.ValidatedRequest.ValidatedResources.Resources.OfflineAccess.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Resource_Request()\n        {\n            var parameters = new NameValueCollection { { \"scope\", \"resource\" } };\n\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n            var result = await validator.ValidateAsync(parameters, new ClientSecretValidationResult { Client = testClient });\n\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.IsOpenIdRequest.Should().BeFalse();\n            result.ValidatedRequest.RequestedScopes.Should().Contain(\"resource\");\n\n            result.ValidatedRequest.ValidatedResources.Resources.IdentityResources.Should().BeEmpty();\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.Should().Contain(x => x.Name == \"api\");\n            result.ValidatedRequest.ValidatedResources.Resources.ApiScopes.Should().Contain(x => x.Name == \"resource\");\n            result.ValidatedRequest.ValidatedResources.Resources.OfflineAccess.Should().BeFalse();\n\n            result.ValidatedRequest.ValidatedResources.Resources.IdentityResources.Any().Should().BeFalse();\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.Any().Should().BeTrue();\n            result.ValidatedRequest.ValidatedResources.Resources.ApiScopes.Any().Should().BeTrue();\n            result.ValidatedRequest.ValidatedResources.Resources.OfflineAccess.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Mixed_Request()\n        {\n            var parameters = new NameValueCollection { { \"scope\", \"openid resource offline_access\" } };\n\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n            var result = await validator.ValidateAsync(parameters, new ClientSecretValidationResult { Client = testClient });\n\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.IsOpenIdRequest.Should().BeTrue();\n            result.ValidatedRequest.RequestedScopes.Should().Contain(\"openid\");\n            result.ValidatedRequest.RequestedScopes.Should().Contain(\"resource\");\n            result.ValidatedRequest.RequestedScopes.Should().Contain(\"offline_access\");\n\n            result.ValidatedRequest.ValidatedResources.Resources.IdentityResources.Should().Contain(x => x.Name == \"openid\");\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.Should().Contain(x => x.Name == \"api\");\n            result.ValidatedRequest.ValidatedResources.Resources.ApiScopes.Should().Contain(x => x.Name == \"resource\");\n            result.ValidatedRequest.ValidatedResources.Resources.OfflineAccess.Should().BeTrue();\n\n            result.ValidatedRequest.ValidatedResources.Resources.IdentityResources.Any().Should().BeTrue();\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.Any().Should().BeTrue();\n            result.ValidatedRequest.ValidatedResources.Resources.ApiScopes.Any().Should().BeTrue();\n            result.ValidatedRequest.ValidatedResources.Resources.OfflineAccess.Should().BeTrue();\n        }\n\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_Scopes_Expect_Client_Scopes()\n        {\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n\n            var result = await validator.ValidateAsync(\n                new NameValueCollection(),\n                new ClientSecretValidationResult { Client = testClient });\n\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.RequestedScopes.Should().Contain(testClient.AllowedScopes);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_Scopes_And_Client_Scopes_Empty()\n        {\n            testClient.AllowedScopes.Clear();\n            var validator = Factory.CreateDeviceAuthorizationRequestValidator();\n\n            var result = await validator.ValidateAsync(\n                new NameValueCollection(),\n                new ClientSecretValidationResult { Client = testClient });\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.AuthorizeErrors.InvalidScope);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/DeviceCodeValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class DeviceCodeValidation\n    {\n        private const string Category = \"Device code validation\";\n\n        private readonly IClientStore _clients = Factory.CreateClientStore();\n\n        private readonly DeviceCode deviceCode = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            IsAuthorized = true,\n            Subject = new IdentityServerUser(\"bob\").CreatePrincipal(),\n            IsOpenId = true,\n            Lifetime = 300,\n            CreationTime = DateTime.UtcNow,\n            AuthorizedScopes = new[] { \"openid\", \"profile\", \"resource\" }\n        };\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task DeviceCode_Missing()\n        {\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var validator = Factory.CreateDeviceCodeValidator(service);\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = null, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task DeviceCode_From_Different_Client()\n        {\n            var badActor = await _clients.FindClientByIdAsync(\"codeclient\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service);\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(badActor);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = handle, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Expired_DeviceCode()\n        {\n            deviceCode.CreationTime = DateTime.UtcNow.AddDays(-10);\n            deviceCode.Lifetime = 300;\n\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service);\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = handle, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.ExpiredToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Access_Denied()\n        {\n            deviceCode.AuthorizedScopes = new List<string>();\n\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service);\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = handle, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.AccessDenied);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task DeviceCode_Not_Yet_Authorized()\n        {\n            deviceCode.IsAuthorized = false;\n\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service);\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = handle, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.AuthorizationPending);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task DeviceCode_Missing_Subject()\n        {\n            deviceCode.Subject = null;\n\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service);\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = handle, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.AuthorizationPending);\n        }\n\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task User_Disabled()\n        {\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service, new TestProfileService(false));\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = handle, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task DeviceCode_Polling_Too_Fast()\n        {\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service, throttlingService: new TestDeviceFlowThrottlingService(true));\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext { DeviceCode = handle, Request = request };\n\n            await validator.ValidateAsync(context);\n\n            context.Result.IsError.Should().BeTrue();\n            context.Result.Error.Should().Be(OidcConstants.TokenErrors.SlowDown);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_DeviceCode()\n        {\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n            var service = Factory.CreateDeviceCodeService();\n\n            var handle = await service.StoreDeviceAuthorizationAsync(Guid.NewGuid().ToString(), deviceCode);\n\n            var validator = Factory.CreateDeviceCodeValidator(service);\n\n            var request = new ValidatedTokenRequest();\n            request.SetClient(client);\n\n            var context = new DeviceCodeValidationContext {DeviceCode = handle, Request = request};\n\n            await validator.ValidateAsync(context);\n            \n            context.Result.IsError.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/EndSessionRequestValidation/EndSessionRequestValidatorTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.EndSessionRequestValidation\n{\n    public class EndSessionRequestValidatorTests\n    {\n        private EndSessionRequestValidator _subject;\n        private IdentityServerOptions _options;\n        private StubTokenValidator _stubTokenValidator = new StubTokenValidator();\n        private StubRedirectUriValidator _stubRedirectUriValidator = new StubRedirectUriValidator();\n        private MockHttpContextAccessor _context = new MockHttpContextAccessor();\n        private MockUserSession _userSession = new MockUserSession();\n        private MockLogoutNotificationService _mockLogoutNotificationService = new MockLogoutNotificationService();\n        private MockMessageStore<LogoutNotificationContext> _mockEndSessionMessageStore = new MockMessageStore<LogoutNotificationContext>();\n\n        private ClaimsPrincipal _user;\n\n        public EndSessionRequestValidatorTests()\n        {\n            _user = new IdentityServerUser(\"alice\").CreatePrincipal();\n\n            _options = TestIdentityServerOptions.Create();\n            _subject = new EndSessionRequestValidator(\n                _context,\n                _options,\n                _stubTokenValidator,\n                _stubRedirectUriValidator,\n                _userSession,\n                _mockLogoutNotificationService,\n                _mockEndSessionMessageStore,\n                TestLogger.Create<EndSessionRequestValidator>());\n        }\n\n        [Fact]\n        public async Task anonymous_user_when_options_require_authenticated_user_should_return_error()\n        {\n            _options.Authentication.RequireAuthenticatedUserForSignOutMessage = true;\n\n            var parameters = new NameValueCollection();\n            var result = await _subject.ValidateAsync(parameters, null);\n            result.IsError.Should().BeTrue();\n\n            result = await _subject.ValidateAsync(parameters, new ClaimsPrincipal());\n            result.IsError.Should().BeTrue();\n\n            result = await _subject.ValidateAsync(parameters, new ClaimsPrincipal(new ClaimsIdentity()));\n            result.IsError.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task valid_params_should_return_success()\n        {\n            _stubTokenValidator.IdentityTokenValidationResult = new TokenValidationResult()\n            {\n                IsError = false,\n                Claims = new Claim[] { new Claim(\"sub\", _user.GetSubjectId()) },\n                Client = new Client() { ClientId = \"client\"}\n            };\n            _stubRedirectUriValidator.IsPostLogoutRedirectUriValid = true;\n\n            var parameters = new NameValueCollection();\n            parameters.Add(\"id_token_hint\", \"id_token\");\n            parameters.Add(\"post_logout_redirect_uri\", \"http://client/signout-cb\");\n            parameters.Add(\"client_id\", \"client1\");\n            parameters.Add(\"state\", \"foo\");\n\n            var result = await _subject.ValidateAsync(parameters, _user);\n            result.IsError.Should().BeFalse();\n\n            result.ValidatedRequest.Client.ClientId.Should().Be(\"client\");\n            result.ValidatedRequest.PostLogOutUri.Should().Be(\"http://client/signout-cb\");\n            result.ValidatedRequest.State.Should().Be(\"foo\");\n            result.ValidatedRequest.Subject.GetSubjectId().Should().Be(_user.GetSubjectId());\n        }\n\n        [Fact]\n        public async Task no_post_logout_redirect_uri_should_not_use_single_registered_uri()\n        {\n            _stubTokenValidator.IdentityTokenValidationResult = new TokenValidationResult()\n            {\n                IsError = false,\n                Claims = new Claim[] { new Claim(\"sub\", _user.GetSubjectId()) },\n                Client = new Client() { ClientId = \"client1\", PostLogoutRedirectUris = new List<string> { \"foo\" } }\n            };\n            _stubRedirectUriValidator.IsPostLogoutRedirectUriValid = true;\n\n            var parameters = new NameValueCollection();\n            parameters.Add(\"id_token_hint\", \"id_token\");\n\n            var result = await _subject.ValidateAsync(parameters, _user);\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.PostLogOutUri.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task no_post_logout_redirect_uri_should_not_use_multiple_registered_uri()\n        {\n            _stubTokenValidator.IdentityTokenValidationResult = new TokenValidationResult()\n            {\n                IsError = false,\n                Claims = new Claim[] { new Claim(\"sub\", _user.GetSubjectId()) },\n                Client = new Client() { ClientId = \"client1\", PostLogoutRedirectUris = new List<string> { \"foo\", \"bar\" } }\n            };\n            _stubRedirectUriValidator.IsPostLogoutRedirectUriValid = true;\n\n            var parameters = new NameValueCollection();\n            parameters.Add(\"id_token_hint\", \"id_token\");\n\n            var result = await _subject.ValidateAsync(parameters, _user);\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.PostLogOutUri.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task post_logout_uri_fails_validation_should_not_honor_logout_uri()\n        {\n            _stubTokenValidator.IdentityTokenValidationResult = new TokenValidationResult()\n            {\n                IsError = false,\n                Claims = new Claim[] { new Claim(\"sub\", _user.GetSubjectId()) },\n                Client = new Client() { ClientId = \"client\" }\n            };\n            _stubRedirectUriValidator.IsPostLogoutRedirectUriValid = false;\n\n            var parameters = new NameValueCollection();\n            parameters.Add(\"id_token_hint\", \"id_token\");\n            parameters.Add(\"post_logout_redirect_uri\", \"http://client/signout-cb\");\n            parameters.Add(\"client_id\", \"client1\");\n            parameters.Add(\"state\", \"foo\");\n\n            var result = await _subject.ValidateAsync(parameters, _user);\n            result.IsError.Should().BeFalse();\n\n            result.ValidatedRequest.Client.ClientId.Should().Be(\"client\");\n            result.ValidatedRequest.Subject.GetSubjectId().Should().Be(_user.GetSubjectId());\n            \n            result.ValidatedRequest.State.Should().BeNull();\n            result.ValidatedRequest.PostLogOutUri.Should().BeNull();\n        }\n\n        [Fact]\n        public async Task subject_mismatch_should_return_error()\n        {\n            _stubTokenValidator.IdentityTokenValidationResult = new TokenValidationResult()\n            {\n                IsError = false,\n                Claims = new Claim[] { new Claim(\"sub\", \"xoxo\") },\n                Client = new Client() { ClientId = \"client\" }\n            };\n            _stubRedirectUriValidator.IsPostLogoutRedirectUriValid = true;\n\n            var parameters = new NameValueCollection();\n            parameters.Add(\"id_token_hint\", \"id_token\");\n            parameters.Add(\"post_logout_redirect_uri\", \"http://client/signout-cb\");\n            parameters.Add(\"client_id\", \"client1\");\n            parameters.Add(\"state\", \"foo\");\n\n            var result = await _subject.ValidateAsync(parameters, _user);\n            result.IsError.Should().BeTrue();\n        }\n\n        [Fact]\n        public async Task successful_request_should_return_inputs()\n        {\n            var parameters = new NameValueCollection();\n\n            var result = await _subject.ValidateAsync(parameters, _user);\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.Raw.Should().BeSameAs(parameters);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/EndSessionRequestValidation/StubRedirectUriValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Validation.EndSessionRequestValidation\n{\n    public class StubRedirectUriValidator : IRedirectUriValidator\n    {\n        public bool IsRedirectUriValid { get; set; }\n        public bool IsPostLogoutRedirectUriValid { get; set; }\n\n        public Task<bool> IsPostLogoutRedirectUriValidAsync(string requestedUri, Client client)\n        {\n            return Task.FromResult(IsPostLogoutRedirectUriValid);\n        }\n\n        public Task<bool> IsRedirectUriValidAsync(string requestedUri, Client client)\n        {\n            return Task.FromResult(IsRedirectUriValid);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/EndSessionRequestValidation/StubTokenValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Validation.EndSessionRequestValidation\n{\n    public class StubTokenValidator : ITokenValidator\n    {\n        public TokenValidationResult AccessTokenValidationResult { get; set; } = new TokenValidationResult();\n        public TokenValidationResult IdentityTokenValidationResult { get; set; } = new TokenValidationResult();\n\n        public Task<TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null)\n        {\n            return Task.FromResult(AccessTokenValidationResult);\n        }\n\n        public Task<TokenValidationResult> ValidateIdentityTokenAsync(string token, string clientId = null, bool validateLifetime = true)\n        {\n            return Task.FromResult(IdentityTokenValidationResult);\n        }\n\n        public Task<TokenValidationResult> ValidateRefreshTokenAsync(string token, Client client)\n        {\n            throw new System.NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/GrantTypesValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing FluentAssertions;\nusing IdentityServer8.Models;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class GrantTypesValidation\n    {\n        private const string Category = \"Grant Types Validation\";\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void empty_should_be_allowed()\n        {\n            var client = new Client();\n            client.AllowedGrantTypes = new List<string>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void implicit_should_be_allowed()\n        {\n            var client = new Client();\n            client.AllowedGrantTypes = GrantTypes.Implicit;\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void custom_should_be_allowed()\n        {\n            var client = new Client();\n            client.AllowedGrantTypes = new[] { \"custom\" };\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void custom_should_be_allowed_raw()\n        {\n            var client = new Client();\n            client.AllowedGrantTypes = new[] { \"custom\" };\n        }\n        \n        [Theory]\n        [Trait(\"Category\", Category)]\n        [InlineData(GrantType.Implicit, GrantType.Hybrid)]\n        [InlineData(GrantType.Implicit, GrantType.AuthorizationCode)]\n        [InlineData(GrantType.AuthorizationCode, GrantType.Hybrid)]\n        public void forbidden_grant_type_combinations_should_throw(string type1, string type2)\n        {\n            var client = new Client();\n\n            Action act = () => client.AllowedGrantTypes = new[] { type1, type2 };\n\n            act.Should().Throw<InvalidOperationException>();            \n        }\n\n        [Theory]\n        [Trait(\"Category\", Category)]\n        [InlineData(GrantType.Implicit, GrantType.Hybrid)]\n        [InlineData(GrantType.Implicit, GrantType.AuthorizationCode)]\n        [InlineData(GrantType.AuthorizationCode, GrantType.Hybrid)]\n        public void custom_and_forbidden_grant_type_combinations_should_throw(string type1, string type2)\n        {\n            var client = new Client();\n\n            Action act = () => client.AllowedGrantTypes = new[] { \"custom1\", type2, \"custom2\", type1 };\n\n            act.Should().Throw<InvalidOperationException>();\n        }\n\n        [Fact]\n        public void duplicate_values_should_throw()\n        {\n            var client = new Client();\n\n            Action act = () => client.AllowedGrantTypes = new[] { \"custom1\", \"custom2\", \"custom1\" };\n\n            act.Should().Throw<InvalidOperationException>();\n        }\n\n        [Fact]\n        public void null_grant_type_list_should_throw_single()\n        {\n            var client = new Client();\n\n            Action act = () => client.AllowedGrantTypes = null;\n\n            act.Should().Throw<ArgumentNullException>();\n        }\n\n        [Fact]\n        public void grant_type_with_space_should_throw_single()\n        {\n            var client = new Client();\n\n            Action act = () => client.AllowedGrantTypes = new[] { \"custo m2\" };\n\n            act.Should().Throw<InvalidOperationException>();\n        }\n\n        [Fact]\n        public void grant_type_with_space_should_throw_multiple()\n        {\n            var client = new Client();\n\n            Action act = () => client.AllowedGrantTypes = new[] { \"custom1\", \"custo m2\", \"custom1\" };\n\n            act.Should().Throw<InvalidOperationException>();\n        }\n\n        [Fact]\n        public void adding_invalid_value_to_collection_should_throw()\n        {\n            var client = new Client()\n            {\n                AllowedGrantTypes = { \"implicit\" }\n            };\n\n            Action act = () => client.AllowedGrantTypes.Add(\"authorization_code\");\n\n            act.Should().Throw<InvalidOperationException>();\n        }\n\n        [Fact]\n        public void adding_valid_value_to_collection_should_succeed()\n        {\n            var client = new Client()\n            {\n                AllowedGrantTypes = { \"implicit\" }\n            };\n\n            client.AllowedGrantTypes.Add(\"custom\");\n\n            client.AllowedGrantTypes.Count.Should().Be(2);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/IdentityTokenValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class IdentityTokenValidation\n    {\n        private const string Category = \"Identity token validation\";\n\n        static IdentityTokenValidation()\n        {\n            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_IdentityToken_DefaultKeyType()\n        {\n            var creator = Factory.CreateDefaultTokenCreator();\n            var token = TokenFactory.CreateIdentityToken(\"roclient\", \"valid\");\n            var jwt = await creator.CreateTokenAsync(token);\n\n            var validator = Factory.CreateTokenValidator();\n            var result = await validator.ValidateIdentityTokenAsync(jwt, \"roclient\");\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_IdentityToken_DefaultKeyType_no_ClientId_supplied()\n        {\n            var creator = Factory.CreateDefaultTokenCreator();\n            var jwt = await creator.CreateTokenAsync(TokenFactory.CreateIdentityToken(\"roclient\", \"valid\"));\n            var validator = Factory.CreateTokenValidator();\n\n            var result = await validator.ValidateIdentityTokenAsync(jwt, \"roclient\");\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_IdentityToken_no_ClientId_supplied()\n        {\n            var creator = Factory.CreateDefaultTokenCreator();\n            var jwt = await creator.CreateTokenAsync(TokenFactory.CreateIdentityToken(\"roclient\", \"valid\"));\n            var validator = Factory.CreateTokenValidator();\n\n            var result = await validator.ValidateIdentityTokenAsync(jwt);\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IdentityToken_InvalidClientId()\n        {\n            var creator = Factory.CreateDefaultTokenCreator();\n            var jwt = await creator.CreateTokenAsync(TokenFactory.CreateIdentityToken(\"roclient\", \"valid\"));\n            var validator = Factory.CreateTokenValidator();\n\n            var result = await validator.ValidateIdentityTokenAsync(jwt, \"invalid\");\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task IdentityToken_Too_Long()\n        {\n            var creator = Factory.CreateDefaultTokenCreator();\n            var jwt = await creator.CreateTokenAsync(TokenFactory.CreateIdentityTokenLong(\"roclient\", \"valid\", 1000));\n            var validator = Factory.CreateTokenValidator();\n\n            var result = await validator.ValidateIdentityTokenAsync(jwt, \"roclient\");\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/IntrospectionRequestValidatorTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Specialized;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class IntrospectionRequestValidatorTests\n    {\n        private const string Category = \"Introspection request validation\";\n\n        private IntrospectionRequestValidator _subject;\n        private IReferenceTokenStore _referenceTokenStore;\n\n        public IntrospectionRequestValidatorTests()\n        {\n            _referenceTokenStore = Factory.CreateReferenceTokenStore();\n            var tokenValidator = Factory.CreateTokenValidator(_referenceTokenStore);\n\n            _subject = new IntrospectionRequestValidator(tokenValidator, TestLogger.Create<IntrospectionRequestValidator>());\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task valid_token_should_successfully_validate()\n        {\n            var token = new Token {\n                CreationTime = DateTime.UtcNow,\n                Issuer = \"http://op\",\n                ClientId = \"codeclient\",\n                Lifetime = 1000,\n                Claims =\n                {\n                    new System.Security.Claims.Claim(\"scope\", \"a\"),\n                    new System.Security.Claims.Claim(\"scope\", \"b\")\n                }\n            };\n            var handle = await _referenceTokenStore.StoreReferenceTokenAsync(token);\n            \n            var param = new NameValueCollection()\n            {\n                { \"token\", handle}\n            };\n\n            var result = await _subject.ValidateAsync(param, null);\n\n            result.IsError.Should().Be(false);\n            result.IsActive.Should().Be(true);\n            result.Claims.Count().Should().Be(5);\n            result.Token.Should().Be(handle);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task missing_token_should_error()\n        {\n            var param = new NameValueCollection();\n            \n            var result = await _subject.ValidateAsync(param, null);\n\n            result.IsError.Should().Be(true);\n            result.Error.Should().Be(\"missing_token\");\n            result.IsActive.Should().Be(false);\n            result.Claims.Should().BeNull();\n            result.Token.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task invalid_token_should_return_inactive()\n        {\n            var param = new NameValueCollection()\n            {\n                { \"token\", \"invalid\" }\n            };\n\n            var result = await _subject.ValidateAsync(param, null);\n\n            result.IsError.Should().Be(false);\n            result.IsActive.Should().Be(false);\n            result.Claims.Should().BeNull();\n            result.Token.Should().Be(\"invalid\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/ResourceValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Extensions;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class ResourceValidation\n    {\n        private const string Category = \"Resource Validation\";\n\n        private List<IdentityResource> _identityResources = new List<IdentityResource>\n        {\n            new IdentityResource\n            {\n                Name = \"openid\",\n                Required = true\n            },\n            new IdentityResource\n            {\n                Name = \"email\"\n            }\n        };\n\n        private List<ApiResource> _apiResources = new List<ApiResource>\n        {\n            new ApiResource\n            {\n                Name = \"api\",\n                Scopes = { \"resource1\", \"resource2\" }\n            },\n            new ApiResource\n            {\n                Name = \"disabled_api\",\n                Enabled = false,\n                Scopes = { \"disabled\" }\n            }\n        };\n\n        private List<ApiScope> _scopes = new List<ApiScope> {\n            new ApiScope\n            {\n                Name = \"resource1\",\n                Required = true\n            },\n            new ApiScope\n            {\n                Name = \"resource2\"\n            }\n        };\n\n        private Client _restrictedClient = new Client\n        {\n            ClientId = \"restricted\",\n\n            AllowedScopes = new List<string>\n                {\n                    \"openid\",\n                    \"resource1\",\n                    \"disabled\"\n                }\n        };\n\n        private IResourceStore _store;\n\n        public ResourceValidation()\n        {\n            _store = new InMemoryResourcesStore(_identityResources, _apiResources, _scopes);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Parse_Scopes_with_Empty_Scope_List()\n        {\n            var scopes = string.Empty.ParseScopesString();\n\n            scopes.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Parse_Scopes_with_Sorting()\n        {\n            var scopes = \"scope3 scope2 scope1\".ParseScopesString();\n\n            scopes.Count.Should().Be(3);\n\n            scopes[0].Should().Be(\"scope1\");\n            scopes[1].Should().Be(\"scope2\");\n            scopes[2].Should().Be(\"scope3\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Parse_Scopes_with_Extra_Spaces()\n        {\n            var scopes = \"   scope3     scope2     scope1   \".ParseScopesString();\n\n            scopes.Count.Should().Be(3);\n\n            scopes[0].Should().Be(\"scope1\");\n            scopes[1].Should().Be(\"scope2\");\n            scopes[2].Should().Be(\"scope3\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Parse_Scopes_with_Duplicate_Scope()\n        {\n            var scopes = \"scope2 scope1 scope2\".ParseScopesString();\n\n            scopes.Count.Should().Be(2);\n\n            scopes[0].Should().Be(\"scope1\");\n            scopes[1].Should().Be(\"scope2\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Only_Offline_Access_Requested()\n        {\n            var scopes = \"offline_access\".ParseScopesString();\n\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeFalse();\n            result.InvalidScopes.Should().Contain(\"offline_access\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task All_Scopes_Valid()\n        {\n            var scopes = \"openid resource1\".ParseScopesString();\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeTrue();\n            result.InvalidScopes.Should().BeEmpty();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Scope()\n        {\n            {\n                var scopes = \"openid email resource1 unknown\".ParseScopesString();\n\n                var validator = Factory.CreateResourceValidator(_store);\n                var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n                {\n                    Client = _restrictedClient,\n                    Scopes = scopes\n                });\n\n                result.Succeeded.Should().BeFalse();\n                result.InvalidScopes.Should().Contain(\"unknown\");\n                result.InvalidScopes.Should().Contain(\"email\");\n            }\n            {\n                var scopes = \"openid resource1 resource2\".ParseScopesString();\n\n                var validator = Factory.CreateResourceValidator(_store);\n                var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n                {\n                    Client = _restrictedClient,\n                    Scopes = scopes\n                });\n\n                result.Succeeded.Should().BeFalse();\n                result.InvalidScopes.Should().Contain(\"resource2\");\n            }\n            {\n                var scopes = \"openid email resource1\".ParseScopesString();\n\n                var validator = Factory.CreateResourceValidator(_store);\n                var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n                {\n                    Client = _restrictedClient,\n                    Scopes = scopes\n                });\n\n                result.Succeeded.Should().BeFalse();\n                result.InvalidScopes.Should().Contain(\"email\");\n            }\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Disabled_Scope()\n        {\n            var scopes = \"openid resource1 disabled\".ParseScopesString();\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeFalse();\n            result.InvalidScopes.Should().Contain(\"disabled\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task All_Scopes_Allowed_For_Restricted_Client()\n        {\n            var scopes = \"openid resource1\".ParseScopesString();\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeTrue();\n            result.InvalidScopes.Should().BeEmpty();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Restricted_Scopes()\n        {\n            var scopes = \"openid email resource1 resource2\".ParseScopesString();\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeFalse();\n            result.InvalidScopes.Should().Contain(\"email\");\n            result.InvalidScopes.Should().Contain(\"resource2\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Contains_Resource_and_Identity_Scopes()\n        {\n            var scopes = \"openid resource1\".ParseScopesString();\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeTrue();\n            result.Resources.IdentityResources.SelectMany(x => x.Name).Should().Contain(\"openid\");\n            result.Resources.ApiScopes.Select(x => x.Name).Should().Contain(\"resource1\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Contains_Resource_Scopes_Only()\n        {\n            var scopes = \"resource1\".ParseScopesString();\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeTrue();\n            result.Resources.IdentityResources.Should().BeEmpty();\n            result.Resources.ApiScopes.Select(x => x.Name).Should().Contain(\"resource1\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Contains_Identity_Scopes_Only()\n        {\n            var scopes = \"openid\".ParseScopesString();\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = _restrictedClient,\n                Scopes = scopes\n            });\n\n            result.Succeeded.Should().BeTrue();\n            result.Resources.IdentityResources.SelectMany(x => x.Name).Should().Contain(\"openid\");\n            result.Resources.ApiResources.Should().BeEmpty();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Scope_matches_multipls_apis_should_succeed()\n        {\n            _apiResources.Clear();\n            _apiResources.Add(new ApiResource { Name = \"api1\", Scopes = { \"resource\" } });\n            _apiResources.Add(new ApiResource { Name = \"api2\", Scopes = { \"resource\" } });\n            _scopes.Clear();\n            _scopes.Add(new ApiScope(\"resource\"));\n\n            var validator = Factory.CreateResourceValidator(_store);\n            var result = await validator.ValidateRequestedResourcesAsync(new IdentityServer8.Validation.ResourceValidationRequest\n            {\n                Client = new Client { AllowedScopes = { \"resource\" } },\n                Scopes = new[] { \"resource\" }\n            });\n\n            result.Succeeded.Should().BeTrue();\n            result.Resources.ApiResources.Count.Should().Be(2);\n            result.Resources.ApiResources.Select(x => x.Name).Should().BeEquivalentTo(new[] { \"api1\", \"api2\" });\n            result.RawScopeValues.Count().Should().Be(1);\n            result.RawScopeValues.Should().BeEquivalentTo(new[] { \"resource\" });\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/ResponseTypeEqualityComparison.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    /// <summary>\n    /// Tests for ResponseTypeEqualityComparer\n    /// </summary>\n    /// <remarks>\n    /// Some of these are pretty fundamental equality checks, but the purpose here is to ensure the\n    /// important property: that the order is insignificant when multiple values are\n    /// sent in a space-delimited string.  We want to ensure that property holds and at the same time\n    /// the basic equality function works as well.\n    /// </remarks>\n    public class ResponseTypeEqualityComparison\n    {\n        /// <summary>\n        /// These tests ensure that single-value strings compare with the\n        /// same behavior as default string comparisons.\n        /// </summary>\n        public class SingleValueStringComparisons\n        {\n            [Fact]\n            public void Both_null()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = null;\n                string y = null;\n                var result = comparer.Equals(x, y);\n                var expected = (x == y);\n                result.Should().Be(expected);\n            }\n\n            [Fact]\n            public void Left_null_other_not()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = null;\n                string y = string.Empty;\n                var result = comparer.Equals(x, y);\n                var expected = (x == y);\n                result.Should().Be(expected);\n            }\n\n            [Fact]\n            public void Right_null_other_not()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = string.Empty;\n                string y = null;\n                var result = comparer.Equals(x, y);\n                var expected = (x == y);\n                result.Should().Be(expected);\n            }\n\n            [Fact]\n            public void token_token()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"token\";\n                string y = \"token\";\n                var result = comparer.Equals(x, y);\n                var expected = (x == y);\n                result.Should().Be(expected);\n            }\n\n            [Fact]\n            public void id_token_id_token()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"id_token\";\n                string y = \"id_token\";\n                var result = comparer.Equals(x, y);\n                var expected = (x == y);\n                result.Should().Be(expected);\n            }\n\n            [Fact]\n            public void id_token_token()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"id_token\";\n                string y = \"token\";\n                var result = comparer.Equals(x, y);\n                var expected = (x == y);\n                result.Should().Be(expected);\n            }\n        }\n\n        /// <summary>\n        /// These tests ensure the property demanded by the \n        /// <see href=\"https://tools.ietf.org/html/rfc6749#section-3.1.1\">OAuth2 spec</see>\n        /// where, in a space-delimited list of values, the order is not important.\n        /// </summary>\n        public class MultipleValueStringComparisons\n        {\n            [Fact]\n            public void id_token_token_both_ways()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"id_token token\";\n                string y = \"token id_token\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeTrue();\n            }\n\n            [Fact]\n            public void code_id_token_both_ways()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"code id_token\";\n                string y = \"id_token code\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeTrue();\n            }\n\n            [Fact]\n            public void code_token_both_ways()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"code token\";\n                string y = \"token code\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeTrue();\n            }\n\n            [Fact]\n            public void code_id_token_token_combo1()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"code id_token token\";\n                string y = \"id_token code token\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeTrue();\n            }\n\n            [Fact]\n            public void code_id_token_token_combo2()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"code id_token token\";\n                string y = \"token id_token code\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeTrue();\n            }\n\n            [Fact]\n            public void code_id_token_token_missing_code()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"code id_token token\";\n                string y = \"id_token token\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeFalse();\n            }\n\n            [Fact]\n            public void code_id_token_token_missing_code_and_token()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"code id_token token\";\n                string y = \"id_token\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeFalse();\n            }\n\n            [Fact]\n            public void Totally_different_words()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"blerg smoo\";\n                string y = \"token code\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeFalse();\n            }\n\n            [Fact]\n            public void Same_length_different_count()\n            {\n                ResponseTypeEqualityComparer comparer = new ResponseTypeEqualityComparer();\n                string x = \"code id_token token\";\n                string y = \"tokenizer bleegerfi\";\n                var result = comparer.Equals(x, y);\n                result.Should().BeFalse();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/RevocationRequestValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class RevocationRequestValidation\n    {\n        private const string Category = \"Revocation Request Validation Tests\";\n\n        private ITokenRevocationRequestValidator _validator;\n        private Client _client;\n\n        public RevocationRequestValidation()\n        {\n            _validator = new TokenRevocationRequestValidator(TestLogger.Create<TokenRevocationRequestValidator>());\n            _client = new Client\n            {\n                ClientName = \"Code Client\",\n                Enabled = true,\n                ClientId = \"codeclient\",\n                ClientSecrets = new List<Secret>\n                {\n                    new Secret(\"secret\".Sha256())\n                },\n\n                AllowedGrantTypes = GrantTypes.Code,\n\n                RequireConsent = false,\n\n                RedirectUris = new List<string>\n                {\n                    \"https://server/cb\"\n                },\n\n                AuthorizationCodeLifetime = 60\n            };\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Empty_Parameters()\n        {\n            var parameters = new NameValueCollection();\n\n            var result = await _validator.ValidateRequestAsync(parameters, _client);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_Token_Valid_Hint()\n        {\n            var parameters = new NameValueCollection\n            {\n                { \"token_type_hint\", \"access_token\" }\n            };\n\n            var result = await _validator.ValidateRequestAsync(parameters, _client);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidRequest);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Token_And_AccessTokenHint()\n        {\n            var parameters = new NameValueCollection\n            {\n                { \"token\", \"foo\" },\n                { \"token_type_hint\", \"access_token\" }\n            };\n\n            var result = await _validator.ValidateRequestAsync(parameters, _client);\n\n            result.IsError.Should().BeFalse();\n            result.Token.Should().Be(\"foo\");\n            result.TokenTypeHint.Should().Be(\"access_token\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Token_and_RefreshTokenHint()\n        {\n            var parameters = new NameValueCollection\n            {\n                { \"token\", \"foo\" },\n                { \"token_type_hint\", \"refresh_token\" }\n            };\n\n            var result = await _validator.ValidateRequestAsync(parameters, _client);\n\n            result.IsError.Should().BeFalse();\n            result.Token.Should().Be(\"foo\");\n            result.TokenTypeHint.Should().Be(\"refresh_token\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Token_And_Missing_Hint()\n        {\n            var parameters = new NameValueCollection\n            {\n                { \"token\", \"foo\" }\n            };\n\n            var result = await _validator.ValidateRequestAsync(parameters, _client);\n\n            result.IsError.Should().BeFalse();\n            result.Token.Should().Be(\"foo\");\n            result.TokenTypeHint.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Token_And_Invalid_Hint()\n        {\n            var parameters = new NameValueCollection\n            {\n                { \"token\", \"foo\" },\n                { \"token_type_hint\", \"invalid\" }\n            };\n\n            var result = await _validator.ValidateRequestAsync(parameters, _client);\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(Constants.RevocationErrors.UnsupportedTokenType);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/BasicAuthenticationCredentialParsing.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Text;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Primitives;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class BasicAuthenticationSecretParsing\n    {\n        private const string Category = \"Secrets - Basic Authentication Secret Parsing\";\n\n        private IdentityServerOptions _options;\n        private BasicAuthenticationSecretParser _parser;\n\n        public BasicAuthenticationSecretParsing()\n        {\n            _options = new IdentityServerOptions();\n            _parser = new BasicAuthenticationSecretParser(_options, TestLogger.Create<BasicAuthenticationSecretParser>());\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void EmptyContext()\n        {\n            var context = new DefaultHttpContext();\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Valid_BasicAuthentication_Request()\n        {\n            var context = new DefaultHttpContext();\n\n            var headerValue = string.Format(\"Basic {0}\",\n                Convert.ToBase64String(Encoding.UTF8.GetBytes(\"client:secret\")));\n            context.Request.Headers.Append(\"Authorization\", new StringValues(headerValue));\n\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Type.Should().Be(IdentityServerConstants.ParsedSecretTypes.SharedSecret);\n            secret.Id.Should().Be(\"client\");\n            secret.Credential.Should().Be(\"secret\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Valid_BasicAuthentication_Request_With_UserName_Only_And_Colon_For_Optional_ClientSecret()\n        {\n            var context = new DefaultHttpContext();\n\n            var headerValue = string.Format(\"Basic {0}\",\n                Convert.ToBase64String(Encoding.UTF8.GetBytes(\"client:\")));\n            context.Request.Headers.Append(\"Authorization\", new StringValues(headerValue));\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Type.Should().Be(IdentityServerConstants.ParsedSecretTypes.NoSecret);\n            secret.Id.Should().Be(\"client\");\n            secret.Credential.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void BasicAuthentication_Request_With_Empty_Basic_Header()\n        {\n            var context = new DefaultHttpContext();\n\n            context.Request.Headers.Append(\"Authorization\", new StringValues(string.Empty));\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Valid_BasicAuthentication_Request_ClientId_Too_Long()\n        {\n            var context = new DefaultHttpContext();\n\n            var longClientId = \"x\".Repeat(_options.InputLengthRestrictions.ClientId + 1);\n            var credential = string.Format(\"{0}:secret\", longClientId);\n\n            var headerValue = string.Format(\"Basic {0}\",\n                Convert.ToBase64String(Encoding.UTF8.GetBytes(credential)));\n            context.Request.Headers.Append(\"Authorization\", new StringValues(headerValue));\n\n            var secret = await _parser.ParseAsync(context);\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Valid_BasicAuthentication_Request_ClientSecret_Too_Long()\n        {\n            var context = new DefaultHttpContext();\n\n            var longClientSecret = \"x\".Repeat(_options.InputLengthRestrictions.ClientSecret + 1);\n            var credential = string.Format(\"client:{0}\", longClientSecret);\n\n            var headerValue = string.Format(\"Basic {0}\",\n                Convert.ToBase64String(Encoding.UTF8.GetBytes(credential)));\n            context.Request.Headers.Append(\"Authorization\", new StringValues(headerValue));\n\n            var secret = await _parser.ParseAsync(context);\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void BasicAuthentication_Request_With_Empty_Basic_Header_Variation()\n        {\n            var context = new DefaultHttpContext();\n\n            context.Request.Headers.Append(\"Authorization\", new StringValues(\"Basic \"));\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void BasicAuthentication_Request_With_Unknown_Scheme()\n        {\n            var context = new DefaultHttpContext();\n\n            context.Request.Headers.Append(\"Authorization\", new StringValues(\"Unknown\"));\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void BasicAuthentication_Request_With_Malformed_Credentials_NoBase64_Encoding()\n        {\n            var context = new DefaultHttpContext();\n\n            context.Request.Headers.Append(\"Authorization\", new StringValues(\"Basic somerandomdata\"));\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void BasicAuthentication_Request_With_Malformed_Credentials_Base64_Encoding_UserName_Only()\n        {\n            var context = new DefaultHttpContext();\n\n            var headerValue = string.Format(\"Basic {0}\",\n                Convert.ToBase64String(Encoding.UTF8.GetBytes(\"client\")));\n            context.Request.Headers.Append(\"Authorization\", new StringValues(headerValue));\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/ClientAssertionSecretParsing.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IdentityModel.Tokens.Jwt;\nusing System.IO;\nusing System.Security.Claims;\nusing System.Text;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class ClientAssertionSecretParsing\n    {\n        private IdentityServerOptions _options;\n        private JwtBearerClientAssertionSecretParser _parser;\n\n        public ClientAssertionSecretParsing()\n        {\n            _options = new IdentityServerOptions();\n            _parser = new JwtBearerClientAssertionSecretParser(_options, new LoggerFactory().CreateLogger<JwtBearerClientAssertionSecretParser>());\n        }\n\n        [Fact]\n        public async void EmptyContext()\n        {\n            var context = new DefaultHttpContext();\n            context.Request.Body = new MemoryStream();\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        public async void Valid_ClientAssertion()\n        {\n            var context = new DefaultHttpContext();\n\n            var token = new JwtSecurityToken(issuer: \"issuer\", claims: new[] { new Claim(\"sub\", \"client\") });\n            var tokenString = new JwtSecurityTokenHandler().WriteToken(token);\n\n            var body = \"client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=\" + tokenString;\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().NotBeNull();\n            secret.Type.Should().Be(IdentityServerConstants.ParsedSecretTypes.JwtBearer);\n            secret.Id.Should().Be(\"client\");\n            secret.Credential.Should().Be(tokenString);\n        }\n\n        [Fact]\n        public async void Missing_ClientAssertionType()\n        {\n            var context = new DefaultHttpContext();\n\n            var body = \"client_id=client&client_assertion=token\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        public async void Missing_ClientAssertion()\n        {\n            var context = new DefaultHttpContext();\n\n            var body = \"client_id=client&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        public async void Malformed_PostBody()\n        {\n            var context = new DefaultHttpContext();\n            var body = \"malformed\";\n            \n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        public async void ClientId_TooLong()\n        {\n            var context = new DefaultHttpContext();\n\n            var longClientId = \"x\".Repeat(_options.InputLengthRestrictions.ClientId + 1);\n            var body = $\"client_id={longClientId}&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=token\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        public async void ClientAssertion_TooLong()\n        {\n            var context = new DefaultHttpContext();\n\n            var longToken = \"x\".Repeat(_options.InputLengthRestrictions.Jwt + 1);\n            var body = $\"client_id=client&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={longToken}\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/ClientSecretValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO;\nusing System.Text;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing Microsoft.AspNetCore.Http;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class ClientSecretValidation\n    {\n        private const string Category = \"Secrets - Client Secret Validator\";\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task confidential_client_with_correct_secret_should_be_able_to_request_token()\n        {\n            var validator = Factory.CreateClientSecretValidator();\n\n            var context = new DefaultHttpContext();\n            var body = \"client_id=roclient&client_secret=secret\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var result = await validator.ValidateAsync(context);\n\n            result.IsError.Should().BeFalse();\n            result.Client.ClientId.Should().Be(\"roclient\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task confidential_client_with_incorrect_secret_should_not_be_able_to_request_token()\n        {\n            var validator = Factory.CreateClientSecretValidator();\n\n            var context = new DefaultHttpContext();\n            var body = \"client_id=roclient&client_secret=invalid\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var result = await validator.ValidateAsync(context);\n\n            result.IsError.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task public_client_without_secret_should_be_able_to_request_token()\n        {\n            var validator = Factory.CreateClientSecretValidator();\n\n            var context = new DefaultHttpContext();\n            var body = \"client_id=roclient.public\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var result = await validator.ValidateAsync(context);\n\n            result.IsError.Should().BeFalse();\n            result.Client.ClientId.Should().Be(\"roclient.public\");\n            result.Client.RequireClientSecret.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task implicit_client_without_secret_should_be_able_to_authenticate()\n        {\n            var validator = Factory.CreateClientSecretValidator();\n\n            var context = new DefaultHttpContext();\n            var body = \"client_id=client.implicit\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var result = await validator.ValidateAsync(context);\n\n            result.IsError.Should().BeFalse();\n            result.Client.ClientId.Should().Be(\"client.implicit\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task implicit_client_and_client_creds_without_secret_should_not_be_able_to_authenticate()\n        {\n            var validator = Factory.CreateClientSecretValidator();\n\n            var context = new DefaultHttpContext();\n            var body = \"client_id=implicit_and_client_creds\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var result = await validator.ValidateAsync(context);\n\n            result.IsError.Should().BeTrue();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/FormPostCredentialParsing.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.IO;\nusing System.Text;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class FormPostCredentialExtraction\n    {\n        private const string Category = \"Secrets - Form Post Secret Parsing\";\n\n        private IdentityServerOptions _options;\n        private PostBodySecretParser _parser;\n\n        public FormPostCredentialExtraction()\n        {\n            _options = new IdentityServerOptions();\n            _parser = new PostBodySecretParser(_options, new LoggerFactory().CreateLogger<PostBodySecretParser>());\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void EmptyContext()\n        {\n            var context = new DefaultHttpContext();\n            context.Request.Body = new MemoryStream();\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Valid_PostBody()\n        {\n            var context = new DefaultHttpContext();\n\n            var body = \"client_id=client&client_secret=secret\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Type.Should().Be(IdentityServerConstants.ParsedSecretTypes.SharedSecret);\n            secret.Id.Should().Be(\"client\");\n            secret.Credential.Should().Be(\"secret\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void ClientId_Too_Long()\n        {\n            var context = new DefaultHttpContext();\n\n            var longClientId = \"x\".Repeat(_options.InputLengthRestrictions.ClientId + 1);\n            var body = string.Format(\"client_id={0}&client_secret=secret\", longClientId);\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void ClientSecret_Too_Long()\n        {\n            var context = new DefaultHttpContext();\n\n            var longClientSecret = \"x\".Repeat(_options.InputLengthRestrictions.ClientSecret + 1);\n            var body = string.Format(\"client_id=client&client_secret={0}\", longClientSecret);\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Missing_ClientId()\n        {\n            var context = new DefaultHttpContext();\n\n            var body = \"client_secret=secret\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Missing_ClientSecret()\n        {\n            var context = new DefaultHttpContext();\n\n            var body = \"client_id=client\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().NotBeNull();\n            secret.Type.Should().Be(IdentityServerConstants.ParsedSecretTypes.NoSecret);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async void Malformed_PostBody()\n        {\n            var context = new DefaultHttpContext();\n\n            var body = \"malformed\";\n\n            context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));\n            context.Request.ContentType = \"application/x-www-form-urlencoded\";\n\n            var secret = await _parser.ParseAsync(context);\n\n            secret.Should().BeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/HashedSharedSecretValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class HashedSharedSecretValidation\n    {\n        private const string Category = \"Secrets - Hashed Shared Secret Validation\";\n\n        private ISecretValidator _validator = new HashedSharedSecretValidator(new Logger<HashedSharedSecretValidator>(new LoggerFactory()));\n        private IClientStore _clients = new InMemoryClientStore(ClientValidationTestClients.Get());\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Single_Secret()\n        {\n            var clientId = \"single_secret_hashed_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Credential_Type()\n        {\n            var clientId = \"single_secret_hashed_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = \"invalid\"\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Multiple_Secrets()\n        {\n            var clientId = \"multiple_secrets_hashed\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"foobar\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"quux\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"notexpired\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Single_Secret()\n        {\n            var clientId = \"single_secret_hashed_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"invalid\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Multiple_Secrets()\n        {\n            var clientId = \"multiple_secrets_hashed\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"invalid\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_with_no_Secret_Should_Fail()\n        {\n            var clientId = \"no_secret_client\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_with_null_Secret_Should_Fail()\n        {\n            var clientId = \"null_secret_client\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret,\n                Credential = \"secret\"\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/MutualTlsSecretValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class MutualTlsSecretValidation\n    {\n        private const string Category = \"Secrets - MutualTls Secret Validation\";\n\n        private IClientStore _clients = new InMemoryClientStore(ClientValidationTestClients.Get());\n\n        ///////////////////\n        // thumbprints\n        ///////////////////\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Thumbprint_invalid_secret_type_should_not_match()\n        {\n            ISecretValidator validator = new X509ThumbprintSecretValidator(new Logger<X509ThumbprintSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Thumbprint_missing_cert_should_throw()\n        {\n            ISecretValidator validator = new X509ThumbprintSecretValidator(new Logger<X509ThumbprintSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.X509Certificate\n            };\n\n            Func<Task> act = async () => await validator.ValidateAsync(client.ClientSecrets, secret);\n            await act.Should().ThrowAsync<InvalidOperationException>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Thumbprint_invalid_secret_should_not_match()\n        {\n            ISecretValidator validator = new X509ThumbprintSecretValidator(new Logger<X509ThumbprintSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = TestCert.Load(),\n                Type = IdentityServerConstants.ParsedSecretTypes.X509Certificate\n            };\n\n            var result = await validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Thumbprint_valid_secret_should_match()\n        {\n            ISecretValidator validator = new X509ThumbprintSecretValidator(new Logger<X509ThumbprintSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = TestCert.Load(),\n                Type = IdentityServerConstants.ParsedSecretTypes.X509Certificate\n            };\n\n            var result = await validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeTrue();\n        }\n\n        ///////////////////\n        // names\n        ///////////////////\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Name_invalid_secret_type_should_not_match()\n        {\n            ISecretValidator validator = new X509NameSecretValidator(new Logger<X509NameSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Name_missing_cert_should_throw()\n        {\n            ISecretValidator validator = new X509NameSecretValidator(new Logger<X509NameSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.X509Certificate\n            };\n\n            Func<Task> act = async () => await validator.ValidateAsync(client.ClientSecrets, secret);\n            await act.Should().ThrowAsync<InvalidOperationException>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Name_invalid_secret_should_not_match()\n        {\n            ISecretValidator validator = new X509NameSecretValidator(new Logger<X509NameSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = TestCert.Load(),\n                Type = IdentityServerConstants.ParsedSecretTypes.X509Certificate\n            };\n\n            var result = await validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Name_valid_secret_should_match()\n        {\n            ISecretValidator validator = new X509NameSecretValidator(new Logger<X509NameSecretValidator>(new LoggerFactory()));\n\n            var clientId = \"mtls_client_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = TestCert.Load(),\n                Type = IdentityServerConstants.ParsedSecretTypes.X509Certificate\n            };\n\n            var result = await validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeTrue();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/PlainTextClientSecretValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class PlainTextClientSecretValidation\n    {\n        private const string Category = \"Secrets - PlainText Shared Secret Validation\";\n\n        private ISecretValidator _validator = new PlainTextSharedSecretValidator(new Logger<PlainTextSharedSecretValidator>(new LoggerFactory()));\n        private IClientStore _clients = new InMemoryClientStore(ClientValidationTestClients.Get());\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Single_Secret()\n        {\n            var clientId = \"single_secret_no_protection_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Credential_Type()\n        {\n            var clientId = \"single_secret_no_protection_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = \"invalid\"\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Multiple_Secrets_No_Protection()\n        {\n            var clientId = \"multiple_secrets_no_protection\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"foobar\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"quux\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"notexpired\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Single_Secret()\n        {\n            var clientId = \"single_secret_no_protection_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"invalid\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Multiple_Secrets()\n        {\n            var clientId = \"multiple_secrets_no_protection\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"invalid\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_with_no_Secret_Should_Fail()\n        {\n            var clientId = \"no_secret_client\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_with_null_Secret_Should_Fail()\n        {\n            var clientId = \"null_secret_client\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret,\n                Credential = \"secret\"\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/PrivateKeyJwtSecretValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Services.Default;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Microsoft.Extensions.Logging;\nusing Microsoft.IdentityModel.Tokens;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class PrivateKeyJwtSecretValidation\n    {\n        private readonly ISecretValidator _validator;\n        private readonly IClientStore _clients;\n\n        public PrivateKeyJwtSecretValidation()\n        {\n            _validator = new PrivateKeyJwtSecretValidator(\n                new MockHttpContextAccessor(\n                    new IdentityServerOptions()\n                        {\n                            IssuerUri = \"https://idsrv3.com\"\n                        }\n                    ),\n                    new DefaultReplayCache(new TestCache()), \n                    new LoggerFactory().CreateLogger<PrivateKeyJwtSecretValidator>()\n                );\n            _clients = new InMemoryClientStore(ClientValidationTestClients.Get());\n        }\n\n        private JwtSecurityToken CreateToken(string clientId, DateTime? nowOverride = null)\n        {\n            var certificate = TestCert.Load();\n            var now = nowOverride ?? DateTime.UtcNow;\n\n            var token = new JwtSecurityToken(\n                    clientId,\n                    \"https://idsrv3.com/connect/token\",\n                    new List<Claim>()\n                    {\n                        new Claim(\"jti\", Guid.NewGuid().ToString()),\n                        new Claim(JwtClaimTypes.Subject, clientId),\n                        new Claim(JwtClaimTypes.IssuedAt, new DateTimeOffset(now).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)\n                    },\n                    now,\n                    now.AddMinutes(1),\n                    new SigningCredentials(\n                        new X509SecurityKey(certificate),\n                        SecurityAlgorithms.RsaSha256\n                    )\n                );\n            return token;\n        }\n\n        [Fact]\n        public async Task Invalid_Certificate_X5t_Only_Requires_Full_Certificate()\n        {\n            var clientId = \"certificate_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var token = CreateToken(clientId);\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(token),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Invalid_Certificate_Thumbprint()\n        {\n            var clientId = \"certificate_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(CreateToken(clientId)),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Valid_Certificate_Base64()\n        {\n            var clientId = \"certificate_base64_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(CreateToken(clientId)),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeTrue();\n        }\n        \n        [Fact]\n        public async Task Invalid_Replay()\n        {\n            var clientId = \"certificate_base64_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n            var token = new JwtSecurityTokenHandler().WriteToken(CreateToken(clientId));\n            \n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = token,\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n            \n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Invalid_Certificate_Base64()\n        {\n            var clientId = \"certificate_base64_invalid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(CreateToken(clientId)),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Invalid_Issuer()\n        {\n            var clientId = \"certificate_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var token = CreateToken(clientId);\n            token.Payload.Remove(JwtClaimTypes.Issuer);\n            token.Payload.Add(JwtClaimTypes.Issuer, \"invalid\");\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(token),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Invalid_Subject()\n        {\n            var clientId = \"certificate_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var token = CreateToken(clientId);\n            token.Payload.Remove(JwtClaimTypes.Subject);\n            token.Payload.Add(JwtClaimTypes.Subject, \"invalid\");\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(token),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Invalid_Expired_Token()\n        {\n            var clientId = \"certificate_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var token = CreateToken(clientId, DateTime.UtcNow.AddHours(-1));\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(token),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        public async Task Invalid_Unsigned_Token()\n        {\n            var clientId = \"certificate_valid\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var token = CreateToken(clientId);\n            token.Header.Remove(\"alg\");\n            token.Header.Add(\"alg\", \"none\");\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = new JwtSecurityTokenHandler().WriteToken(token),\n                Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Secrets/SecretValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Microsoft.Extensions.Logging;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.Secrets\n{\n    public class SecretValidation\n    {\n        private const string Category = \"Secrets - Secret Validator\";\n\n        private ISecretValidator _hashedSecretValidator = new HashedSharedSecretValidator(new Logger<HashedSharedSecretValidator>(new LoggerFactory()));\n        private IClientStore _clients = new InMemoryClientStore(ClientValidationTestClients.Get());\n        private SecretValidator _validator;\n        private IdentityServerOptions _options = new IdentityServerOptions();\n\n        public SecretValidation()\n        {\n            _validator = new SecretValidator(\n                new StubClock(),\n                new[] { _hashedSecretValidator }, \n                new Logger<SecretValidator>(new LoggerFactory()));\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Single_Secret()\n        {\n            var clientId = \"single_secret_hashed_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Credential_Type()\n        {\n            var clientId = \"single_secret_hashed_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = \"invalid\"\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_Multiple_Secrets()\n        {\n            var clientId = \"multiple_secrets_hashed\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"secret\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"foobar\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"quux\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n\n            secret.Credential = \"notexpired\";\n            result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Single_Secret()\n        {\n            var clientId = \"single_secret_hashed_no_expiration\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"invalid\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Expired_Secret()\n        {\n            var clientId = \"multiple_secrets_hashed\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"expired\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Multiple_Secrets()\n        {\n            var clientId = \"multiple_secrets_hashed\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Credential = \"invalid\",\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n\n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_with_no_Secret_Should_Fail()\n        {\n            var clientId = \"no_secret_client\";\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n\n            var secret = new ParsedSecret\n            {\n                Id = clientId,\n                Type = IdentityServerConstants.ParsedSecretTypes.SharedSecret\n            };\n            \n            var result = await _validator.ValidateAsync(client.ClientSecrets, secret);\n            result.Success.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/ClientValidationTestClients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Security.Cryptography.X509Certificates;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing static IdentityServer8.IdentityServerConstants;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    internal static class ClientValidationTestClients\n    {\n        public static List<Client> Get()\n        {\n            return new List<Client>\n            {\n                new Client\n                {\n                    ClientName = \"Disabled client\",\n                    ClientId = \"disabled_client\",\n                    Enabled = false,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(\"secret\")\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with no secret set\",\n                    ClientId = \"no_secret_client\",\n                    Enabled = true\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with null secret set\",\n                    ClientId = \"null_secret_client\",\n                    Enabled = true,\n                    ClientSecrets = { new Secret(null) }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with single secret, no protection, no expiration\",\n                    ClientId = \"single_secret_no_protection_no_expiration\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(\"secret\")\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with X509 Certificate\",\n                    ClientId = \"certificate_valid\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret\n                        {\n                            Type = IdentityServerConstants.SecretTypes.X509CertificateThumbprint,\n                            Value = TestCert.Load().Thumbprint\n                        }\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with X509 Certificate\",\n                    ClientId = \"certificate_invalid\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret\n                        {\n                            Type = IdentityServerConstants.SecretTypes.X509CertificateThumbprint,\n                            Value = \"invalid\"\n                        }\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with Base64 encoded X509 Certificate\",\n                    ClientId = \"certificate_base64_valid\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret\n                        {\n                            Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                            Value = Convert.ToBase64String(TestCert.Load().Export(X509ContentType.Cert))\n                        }\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with Base64 encoded X509 Certificate\",\n                    ClientId = \"certificate_base64_invalid\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret\n                        {\n                            Type = IdentityServerConstants.SecretTypes.X509CertificateBase64,\n                            Value = \"invalid\"\n                        }\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with single secret, hashed, no expiration\",\n                    ClientId = \"single_secret_hashed_no_expiration\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        // secret\n                        new Secret(\"secret\".Sha256())\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with multiple secrets, no protection\",\n                    ClientId = \"multiple_secrets_no_protection\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(\"secret\"),\n                        new Secret(\"foobar\", \"some description\"),\n                        new Secret(\"quux\"),\n                        new Secret(\"notexpired\", DateTime.UtcNow.AddDays(1)),\n                        new Secret(\"expired\", DateTime.UtcNow.AddDays(-1))\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"Client with multiple secrets, hashed\",\n                    ClientId = \"multiple_secrets_hashed\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        // secret\n                        new Secret(\"secret\".Sha256()),\n                        // foobar\n                        new Secret(\"foobar\".Sha256(), \"some description\"),\n                        // quux\n                        new Secret(\"quux\".Sha512()),\n                        // notexpired\n                        new Secret(\"notexpired\".Sha256(), DateTime.UtcNow.AddDays(1)),\n                        // expired\n                        new Secret(\"expired\".Sha512(), DateTime.UtcNow.AddDays(-1))\n                    },\n                },\n\n                new Client\n                {\n                    ClientName = \"MTLS Client with invalid secrets\",\n                    ClientId = \"mtls_client_invalid\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(@\"CN=invalid\", \"mtls.test\")\n                        {\n                            Type = SecretTypes.X509CertificateName\n                        },\n                        new Secret(\"invalid\", \"mtls.test\")\n                        {\n                            Type = SecretTypes.X509CertificateThumbprint\n                        },\n                    }\n                },\n\n                new Client\n                {\n                    ClientName = \"MTLS Client with valid secrets\",\n                    ClientId = \"mtls_client_valid\",\n                    Enabled = true,\n\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(@\"CN=identityserver_testing\", \"mtls.test\")\n                        {\n                            Type = SecretTypes.X509CertificateName\n                        },\n                        new Secret(\"4B5FE072C7AD8A9B5DCFDD1A20608BB54DE0954F\", \"mtls.test\")\n                        {\n                            Type = SecretTypes.X509CertificateThumbprint\n                        },\n                    }\n                }\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/Factory.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Net.Http;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\nusing IdentityServer8.Services.Default;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Stores.Serialization;\nusing IdentityServer8.Validation;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.Extensions.Logging;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    internal static class Factory\n    {\n        public static IClientStore CreateClientStore()\n        {\n            return new InMemoryClientStore(TestClients.Get());\n        }\n\n        public static TokenRequestValidator CreateTokenRequestValidator(\n            IdentityServerOptions options = null,\n            IResourceStore resourceStore = null,\n            IAuthorizationCodeStore authorizationCodeStore = null,\n            IRefreshTokenStore refreshTokenStore = null,\n            IResourceOwnerPasswordValidator resourceOwnerValidator = null,\n            IProfileService profile = null,\n            IDeviceCodeValidator deviceCodeValidator = null,\n            IEnumerable<IExtensionGrantValidator> extensionGrantValidators = null,\n            ICustomTokenRequestValidator customRequestValidator = null,\n            ITokenValidator tokenValidator = null,\n            IRefreshTokenService refreshTokenService = null,\n            IResourceValidator resourceValidator = null)\n        {\n            if (options == null)\n            {\n                options = TestIdentityServerOptions.Create();\n            }\n\n            if (resourceStore == null)\n            {\n                resourceStore = new InMemoryResourcesStore(TestScopes.GetIdentity(), TestScopes.GetApis(), TestScopes.GetScopes());\n            }\n\n            if (resourceOwnerValidator == null)\n            {\n                resourceOwnerValidator = new TestResourceOwnerPasswordValidator();\n            }\n\n            if (profile == null)\n            {\n                profile = new TestProfileService();\n            }\n            \n            if (deviceCodeValidator == null)\n            {\n                deviceCodeValidator = new TestDeviceCodeValidator();\n            }\n\n            if (customRequestValidator == null)\n            {\n                customRequestValidator = new DefaultCustomTokenRequestValidator();\n            }\n\n            ExtensionGrantValidator aggregateExtensionGrantValidator;\n            if (extensionGrantValidators == null)\n            {\n                aggregateExtensionGrantValidator = new ExtensionGrantValidator(new[] { new TestGrantValidator() }, TestLogger.Create<ExtensionGrantValidator>());\n            }\n            else\n            {\n                aggregateExtensionGrantValidator = new ExtensionGrantValidator(extensionGrantValidators, TestLogger.Create<ExtensionGrantValidator>());\n            }\n\n            if (authorizationCodeStore == null)\n            {\n                authorizationCodeStore = CreateAuthorizationCodeStore();\n            }\n\n            if (refreshTokenStore == null)\n            {\n                refreshTokenStore = CreateRefreshTokenStore();\n            }\n\n            if (resourceValidator == null)\n            {\n                resourceValidator = CreateResourceValidator(resourceStore);\n            }\n            \n            if (tokenValidator == null)\n            {\n                tokenValidator = CreateTokenValidator(refreshTokenStore: refreshTokenStore, profile: profile);\n            }\n\n            if (refreshTokenService == null)\n            {\n                refreshTokenService = CreateRefreshTokenService(\n                    refreshTokenStore,\n                    profile);\n            }\n\n            return new TokenRequestValidator(\n                options,\n                authorizationCodeStore,\n                resourceOwnerValidator,\n                profile,\n                deviceCodeValidator,\n                aggregateExtensionGrantValidator,\n                customRequestValidator,\n                resourceValidator,\n                resourceStore,\n                tokenValidator,\n                refreshTokenService,\n                new TestEventService(), \n                new StubClock(), \n                TestLogger.Create<TokenRequestValidator>());\n        }\n\n        private static IRefreshTokenService CreateRefreshTokenService(IRefreshTokenStore store, IProfileService profile)\n        {\n            var service = new DefaultRefreshTokenService(\n                store,\n                profile,\n                new StubClock(),\n                TestLogger.Create<DefaultRefreshTokenService>());\n\n            return service;\n        }\n\n        internal static IResourceValidator CreateResourceValidator(IResourceStore store = null)\n        {\n            store = store ?? new InMemoryResourcesStore(TestScopes.GetIdentity(), TestScopes.GetApis(), TestScopes.GetScopes());\n            return new DefaultResourceValidator(store, new DefaultScopeParser(TestLogger.Create<DefaultScopeParser>()), TestLogger.Create<DefaultResourceValidator>());\n        }\n\n        internal static ITokenCreationService CreateDefaultTokenCreator(IdentityServerOptions options = null)\n        {\n            return new DefaultTokenCreationService(\n                new StubClock(),\n                new DefaultKeyMaterialService(new IValidationKeysStore[] { },\n                    new ISigningCredentialStore[] { new InMemorySigningCredentialsStore(TestCert.LoadSigningCredentials()) }),\n                options ?? TestIdentityServerOptions.Create(),\n                TestLogger.Create<DefaultTokenCreationService>());\n        }\n\n        public static DeviceAuthorizationRequestValidator CreateDeviceAuthorizationRequestValidator(\n            IdentityServerOptions options = null,\n            IResourceStore resourceStore = null,\n            IResourceValidator resourceValidator = null)\n        {\n            if (options == null)\n            {\n                options = TestIdentityServerOptions.Create();\n            }\n            \n            if (resourceStore == null)\n            {\n                resourceStore = new InMemoryResourcesStore(TestScopes.GetIdentity(), TestScopes.GetApis(), TestScopes.GetScopes());\n            }\n\n            if (resourceValidator == null)\n            {\n                resourceValidator = CreateResourceValidator(resourceStore);\n            }\n\n\n            return new DeviceAuthorizationRequestValidator(\n                options,\n                resourceValidator,\n                TestLogger.Create<DeviceAuthorizationRequestValidator>());\n        }\n\n        public static AuthorizeRequestValidator CreateAuthorizeRequestValidator(\n            IdentityServerOptions options = null,\n            IResourceStore resourceStore = null,\n            IClientStore clients = null,\n            IProfileService profile = null,\n            ICustomAuthorizeRequestValidator customValidator = null,\n            IRedirectUriValidator uriValidator = null,\n            IResourceValidator resourceValidator = null,\n            JwtRequestValidator jwtRequestValidator = null,\n            IJwtRequestUriHttpClient jwtRequestUriHttpClient = null)\n        {\n            if (options == null)\n            {\n                options = TestIdentityServerOptions.Create();\n            }\n\n            if (resourceStore == null)\n            {\n                resourceStore = new InMemoryResourcesStore(TestScopes.GetIdentity(), TestScopes.GetApis(), TestScopes.GetScopes());\n            }\n\n            if (clients == null)\n            {\n                clients = new InMemoryClientStore(TestClients.Get());\n            }\n\n            if (customValidator == null)\n            {\n                customValidator = new DefaultCustomAuthorizeRequestValidator();\n            }\n\n            if (uriValidator == null)\n            {\n                uriValidator = new StrictRedirectUriValidator();\n            }\n\n            if (resourceValidator == null)\n            {\n                resourceValidator = CreateResourceValidator(resourceStore);\n            }\n\n            if (jwtRequestValidator == null)\n            {\n                jwtRequestValidator = new JwtRequestValidator(\"https://identityserver\", new LoggerFactory().CreateLogger<JwtRequestValidator>());\n            }\n\n            if (jwtRequestUriHttpClient == null)\n            {\n                jwtRequestUriHttpClient = new DefaultJwtRequestUriHttpClient(new HttpClient(new NetworkHandler(new Exception(\"no jwt request uri response configured\"))), options, new LoggerFactory());\n            }\n\n\n            var userSession = new MockUserSession();\n\n            return new AuthorizeRequestValidator(\n                options,\n                clients,\n                customValidator,\n                uriValidator,\n                resourceValidator,\n                userSession,\n                jwtRequestValidator,\n                jwtRequestUriHttpClient,\n                TestLogger.Create<AuthorizeRequestValidator>());\n        }\n\n        public static TokenValidator CreateTokenValidator(\n            IReferenceTokenStore store = null, \n            IRefreshTokenStore refreshTokenStore = null,\n            IProfileService profile = null, \n            IdentityServerOptions options = null, ISystemClock clock = null)\n        {\n            if (options == null)\n            {\n                options = TestIdentityServerOptions.Create();\n            }\n\n            if (profile == null)\n            {\n                profile = new TestProfileService();\n            }\n\n            if (store == null)\n            {\n                store = CreateReferenceTokenStore();\n            }\n\n            clock = clock ?? new StubClock();\n\n            if (refreshTokenStore == null)\n            {\n                refreshTokenStore = CreateRefreshTokenStore();\n            }\n\n            var clients = CreateClientStore();\n            var context = new MockHttpContextAccessor(options);\n            var logger = TestLogger.Create<TokenValidator>();\n\n            var keyInfo = new SecurityKeyInfo\n            {\n                Key = TestCert.LoadSigningCredentials().Key,\n                SigningAlgorithm = \"RS256\"\n            };\n\n            var validator = new TokenValidator(\n                clients: clients,\n                clock: clock,\n                profile: profile,\n                referenceTokenStore: store,\n                refreshTokenStore: refreshTokenStore,\n                customValidator: new DefaultCustomTokenValidator(),\n                    keys: new DefaultKeyMaterialService(new[] { new InMemoryValidationKeysStore(new[] { keyInfo }) }, Enumerable.Empty<ISigningCredentialStore>()),\n                logger: logger,\n                options: options,\n                context: context);\n\n            return validator;\n        }\n\n        public static IDeviceCodeValidator CreateDeviceCodeValidator(\n            IDeviceFlowCodeService service,\n            IProfileService profile = null,\n            IDeviceFlowThrottlingService throttlingService = null,\n            ISystemClock clock = null)\n        {\n            profile = profile ?? new TestProfileService();\n            throttlingService = throttlingService ?? new TestDeviceFlowThrottlingService();\n            clock = clock ?? new StubClock();\n            \n            var validator = new DeviceCodeValidator(service, profile, throttlingService, clock, TestLogger.Create<DeviceCodeValidator>());\n\n            return validator;\n        }\n\n        public static IClientSecretValidator CreateClientSecretValidator(IClientStore clients = null, SecretParser parser = null, SecretValidator validator = null, IdentityServerOptions options = null)\n        {\n            options = options ?? TestIdentityServerOptions.Create();\n\n            if (clients == null) clients = new InMemoryClientStore(TestClients.Get());\n\n            if (parser == null)\n            {\n                var parsers = new List<ISecretParser>\n                {\n                    new BasicAuthenticationSecretParser(options, TestLogger.Create<BasicAuthenticationSecretParser>()),\n                    new PostBodySecretParser(options, TestLogger.Create<PostBodySecretParser>())\n                };\n\n                parser = new SecretParser(parsers, TestLogger.Create<SecretParser>());\n            }\n\n            if (validator == null)\n            {\n                var validators = new List<ISecretValidator>\n                {\n                    new HashedSharedSecretValidator(TestLogger.Create<HashedSharedSecretValidator>()),\n                    new PlainTextSharedSecretValidator(TestLogger.Create<PlainTextSharedSecretValidator>())\n                };\n\n                validator = new SecretValidator(new StubClock(), validators, TestLogger.Create<SecretValidator>());\n            }\n\n            return new ClientSecretValidator(clients, parser, validator, new TestEventService(), TestLogger.Create<ClientSecretValidator>());\n        }\n\n        public static IAuthorizationCodeStore CreateAuthorizationCodeStore()\n        {\n            return new DefaultAuthorizationCodeStore(new InMemoryPersistedGrantStore(),\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultAuthorizationCodeStore>());\n        }\n        \n        public static IRefreshTokenStore CreateRefreshTokenStore()\n        {\n            return new DefaultRefreshTokenStore(new InMemoryPersistedGrantStore(),\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultRefreshTokenStore>());\n        }\n        \n        public static IReferenceTokenStore CreateReferenceTokenStore()\n        {\n            return new DefaultReferenceTokenStore(new InMemoryPersistedGrantStore(),\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultReferenceTokenStore>());\n        }\n\n        public static IDeviceFlowCodeService CreateDeviceCodeService()\n        {\n            return new DefaultDeviceFlowCodeService(new InMemoryDeviceFlowStore(), new DefaultHandleGenerationService());\n        }\n        \n        public static IUserConsentStore CreateUserConsentStore()\n        {\n            return new DefaultUserConsentStore(new InMemoryPersistedGrantStore(),\n                new PersistentGrantSerializer(),\n                new DefaultHandleGenerationService(),\n                TestLogger.Create<DefaultUserConsentStore>());\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestClients.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    internal class TestClients\n    {\n        public static IEnumerable<Client> Get()\n        {\n            return new List<Client>\n            {\n                new Client\n                {\n                    ClientName = \"Code Client\",\n                    Enabled = true,\n                    ClientId = \"codeclient\",\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(\"secret\".Sha256())\n                    },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                    RequireConsent = false,\n                    RequirePkce = false,\n\n                    RedirectUris = new List<string>\n                    {\n                        \"https://server/cb\"\n                    },\n\n                    AuthorizationCodeLifetime = 60\n                },\n                new Client\n                {\n                    ClientName = \"Code Client (allows plain text PKCE)\",\n                    Enabled = true,\n                    ClientId = \"codeclient.plain\",\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(\"secret\".Sha256())\n                    },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                    AllowPlainTextPkce = true,\n\n                    RequireConsent = false,\n\n                    RedirectUris = new List<string>\n                    {\n                        \"https://server/cb\"\n                    },\n\n                    AuthorizationCodeLifetime = 60\n                },\n                new Client\n                {\n                    ClientName = \"Code Client with PKCE\",\n                    Enabled = true,\n                    ClientId = \"codeclient.pkce\",\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(\"secret\".Sha256())\n                    },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    RequirePkce = true,\n                    AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                    RequireConsent = false,\n\n                    RedirectUris = new List<string>\n                    {\n                        \"https://server/cb\"\n                    },\n\n                    AuthorizationCodeLifetime = 60\n                },\n                new Client\n                {\n                    ClientName = \"Code Client with PKCE and plain allowed\",\n                    Enabled = true,\n                    ClientId = \"codeclient.pkce.plain\",\n                    ClientSecrets = new List<Secret>\n                    {\n                        new Secret(\"secret\".Sha256())\n                    },\n\n                    AllowedGrantTypes = GrantTypes.Code,\n                    RequirePkce = true,\n                    AllowPlainTextPkce = true,\n                    AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                    RequireConsent = false,\n\n                    RedirectUris = new List<string>\n                    {\n                        \"https://server/cb\"\n                    },\n\n                    AuthorizationCodeLifetime = 60\n                },\n                new Client\n                {\n                        ClientName = \"Hybrid Client\",\n                        Enabled = true,\n                        ClientId = \"hybridclient\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.Hybrid,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        AllowAccessTokensViaBrowser = true,\n\n                        RequireConsent = false,\n                        RequirePkce = false,\n\n                        RedirectUris = new List<string>\n                        {\n                            \"https://server/cb\"\n                        },\n\n                        AuthorizationCodeLifetime = 60\n                    },\n                    new Client\n                    {\n                        ClientName = \"Hybrid Client with PKCE\",\n                        Enabled = true,\n                        ClientId = \"hybridclient.pkce\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.Hybrid,\n                        RequirePkce = true,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        AllowAccessTokensViaBrowser = true,\n\n                        RequireConsent = false,\n\n                        RedirectUris = new List<string>\n                        {\n                            \"https://server/cb\"\n                        },\n\n                        AuthorizationCodeLifetime = 60\n                    },\n                    new Client\n                    {\n                        ClientName = \"Hybrid Client\",\n                        Enabled = true,\n                        ClientId = \"hybridclient_no_aavb\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.Hybrid,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        AllowAccessTokensViaBrowser = false,\n\n                        RequireConsent = false,\n                        RequirePkce = false,\n\n                        RedirectUris = new List<string>\n                        {\n                            \"https://server/cb\"\n                        },\n\n                        AuthorizationCodeLifetime = 60\n                    },\n                    new Client\n                    {\n                        ClientName = \"Implicit Client\",\n                        ClientId = \"implicitclient\",\n\n                        AllowedGrantTypes = GrantTypes.Implicit,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        AllowAccessTokensViaBrowser = true,\n\n                        RequireConsent = false,\n\n                        RedirectUris = new List<string>\n                        {\n                            \"oob://implicit/cb\"\n                        }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Implicit Client\",\n                        ClientId = \"implicitclient_no_aavb\",\n\n                        AllowedGrantTypes = GrantTypes.Implicit,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        AllowAccessTokensViaBrowser = false,\n\n                        RequireConsent = false,\n\n                        RedirectUris = new List<string>\n                        {\n                            \"oob://implicit/cb\"\n                        }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Implicit and Client Credentials Client\",\n                        Enabled = true,\n                        ClientId = \"implicit_and_client_creds_client\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        RequireConsent = false,\n\n                        RedirectUris = new List<string>\n                        {\n                            \"oob://implicit/cb\"\n                        }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Code Client with Scope Restrictions\",\n                        Enabled = true,\n                        ClientId = \"codeclient_restricted\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.Code,\n                        RequireConsent = false,\n                        RequirePkce = false,\n\n                        AllowedScopes = new List<string>\n                        {\n                            \"openid\"\n                        },\n\n                        RedirectUris = new List<string>\n                        {\n                            \"https://server/cb\"\n                        }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Client Credentials Client\",\n                        Enabled = true,\n                        ClientId = \"client\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ClientCredentials,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                        AllowOfflineAccess = true,\n\n                        AccessTokenType = AccessTokenType.Jwt\n                    },\n                    new Client\n                    {\n                        ClientName = \"Client Credentials Client (restricted)\",\n                        Enabled = true,\n                        ClientId = \"client_restricted\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ClientCredentials,\n\n                        AllowedScopes = new List<string>\n                        {\n                            \"resource\"\n                        }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client\",\n                        Enabled = true,\n                        ClientId = \"roclient\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        AllowOfflineAccess = true\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client - Public\",\n                        Enabled = true,\n                        ClientId = \"roclient.public\",\n                        RequireClientSecret = false,\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client\",\n                        Enabled = true,\n                        ClientId = \"roclient_absolute_refresh_expiration_one_time_only\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                        RefreshTokenExpiration = TokenExpiration.Absolute,\n                        RefreshTokenUsage = TokenUsage.OneTimeOnly,\n                        AbsoluteRefreshTokenLifetime = 200\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client\",\n                        Enabled = true,\n                        ClientId = \"roclient_absolute_refresh_expiration_reuse\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                        RefreshTokenExpiration = TokenExpiration.Absolute,\n                        RefreshTokenUsage = TokenUsage.ReUse,\n                        AbsoluteRefreshTokenLifetime = 200\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client\",\n                        Enabled = true,\n                        ClientId = \"roclient_sliding_refresh_expiration_one_time_only\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                        RefreshTokenExpiration = TokenExpiration.Sliding,\n                        RefreshTokenUsage = TokenUsage.OneTimeOnly,\n                        AbsoluteRefreshTokenLifetime = 10,\n                        SlidingRefreshTokenLifetime = 4\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client\",\n                        Enabled = true,\n                        ClientId = \"roclient_sliding_refresh_expiration_reuse\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                        RefreshTokenExpiration = TokenExpiration.Sliding,\n                        RefreshTokenUsage = TokenUsage.ReUse,\n                        AbsoluteRefreshTokenLifetime = 200,\n                        SlidingRefreshTokenLifetime = 100\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client (restricted)\",\n                        Enabled = true,\n                        ClientId = \"roclient_restricted\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n\n                        AllowedScopes = new List<string>\n                        {\n                            \"resource\"\n                        }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Resource Owner Client (restricted with refresh)\",\n                        Enabled = true,\n                        ClientId = \"roclient_restricted_refresh\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,\n\n                        AllowOfflineAccess = true,\n                        AllowedScopes = new List<string>\n                        {\n                            \"resource\"\n                        }\n                    },\n\n                    new Client\n                    {\n                        ClientName = \"Custom Grant Client\",\n                        Enabled = true,\n                        ClientId = \"customgrantclient\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = { \"custom_grant\" },\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" }\n                    },\n\n                    new Client\n                    {\n                        ClientName = \"Disabled Client\",\n                        Enabled = false,\n                        ClientId = \"disabled\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"invalid\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.ClientCredentials,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" }\n                    },\n                    new Client\n                    {\n                        ClientName = \"Reference Token Client\",\n\n                        Enabled = true,\n                        ClientId = \"referencetokenclient\",\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n\n                        AllowedGrantTypes = GrantTypes.Implicit,\n                        RedirectUris = { \"https://notused\" },\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n\n                        AccessTokenType = AccessTokenType.Reference\n                    },\n                    new Client\n                    {\n                        ClientId = \"wsfed\",\n                        ClientName = \"WS-Fed Client\",\n                        ProtocolType = IdentityServerConstants.ProtocolTypes.WsFederation,\n                        AllowedGrantTypes = GrantTypes.Implicit,\n                        Enabled = true,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" },\n                        RedirectUris = { \"http://wsfed/callback\"  }\n                    },\n                    new Client\n                    {\n                        ClientId = \"client.cred.wsfed\",\n                        ClientName = \"WS-Fed Client\",\n                        ProtocolType = IdentityServerConstants.ProtocolTypes.WsFederation,\n                        AllowedGrantTypes = GrantTypes.ClientCredentials,\n                        ClientSecrets = { new Secret(\"secret\".Sha256()) },\n\n                        Enabled = true,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" }\n                    },\n                    new Client\n                    {\n                        ClientId = \"client.implicit\",\n                        ClientName = \"Implicit Client\",\n                        AllowedGrantTypes = GrantTypes.Implicit,\n                        RedirectUris = { \"https://notused\" },\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\", \"resource2\" }\n                    },\n                    new Client\n                    {\n                        ClientId = \"implicit_and_client_creds\",\n                        AllowedGrantTypes = GrantTypes.ImplicitAndClientCredentials,\n                        RedirectUris = { \"https://notused\" },\n                        AllowedScopes = {\"api1\"}\n                    },\n                    new Client\n                    {\n                        ClientId = \"device_flow\",\n                        ClientName = \"Device Flow Client\",\n                        AllowedGrantTypes = GrantTypes.DeviceFlow,\n                        AllowedScopes = { \"openid\", \"profile\", \"resource\" },\n                        AllowOfflineAccess = true,\n                        ClientSecrets = new List<Secret>\n                        {\n                            new Secret(\"secret\".Sha256())\n                        },\n                    }\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestDeviceCodeValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    public class TestDeviceCodeValidator : IDeviceCodeValidator\n    {\n        private readonly bool shouldError;\n\n        public TestDeviceCodeValidator(bool shouldError = false)\n        {\n            this.shouldError = shouldError;\n        }\n\n        public Task ValidateAsync(DeviceCodeValidationContext context)\n        {\n            if (shouldError) context.Result = new TokenRequestValidationResult(context.Request, \"error\");\n            else context.Result = new TokenRequestValidationResult(context.Request);\n\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestDeviceFlowThrottlingService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    public class TestDeviceFlowThrottlingService : IDeviceFlowThrottlingService\n    {\n        private readonly bool shouldSlownDown;\n\n        public TestDeviceFlowThrottlingService(bool shouldSlownDown = false)\n        {\n            this.shouldSlownDown = shouldSlownDown;\n        }\n\n        public Task<bool> ShouldSlowDown(string deviceCode, DeviceCode details) => Task.FromResult(shouldSlownDown);\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestGrantValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    internal class TestGrantValidator : IExtensionGrantValidator\n    {\n        private readonly bool _isInvalid;\n        private readonly string _errorDescription;\n\n        public TestGrantValidator(bool isInvalid = false, string errorDescription = null)\n        {\n            _isInvalid = isInvalid;\n            _errorDescription = errorDescription;\n        }\n\n        public Task<GrantValidationResult> ValidateAsync(ValidatedTokenRequest request)\n        {\n            if (_isInvalid)\n            {\n                return Task.FromResult(new GrantValidationResult(TokenRequestErrors.InvalidGrant, _errorDescription));\n            }\n\n            return Task.FromResult(new GrantValidationResult(\"bob\", \"CustomGrant\"));\n        }\n\n        public Task ValidateAsync(ExtensionGrantValidationContext context)\n        {\n            if (_isInvalid)\n            {\n                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, _errorDescription);\n            }\n            else\n            {\n                context.Result = new GrantValidationResult(\"bob\", \"CustomGrant\");\n            }\n\n            return Task.CompletedTask;\n        }\n\n        public string GrantType\n        {\n            get { return \"custom_grant\"; }\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestProfileService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Services;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    internal class TestProfileService : IProfileService\n    {\n        private bool _shouldBeActive;\n\n        public TestProfileService(bool shouldBeActive = true)\n        {\n            _shouldBeActive = shouldBeActive;\n        }\n\n        public Task GetProfileDataAsync(ProfileDataRequestContext context)\n        {\n            return Task.CompletedTask;\n        }\n\n        public Task IsActiveAsync(IsActiveContext context)\n        {\n            context.IsActive = _shouldBeActive;\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestResourceOwnerPasswordValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Threading.Tasks;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    public class TestResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator\n    {\n        private string _erroDescription;\n        private TokenRequestErrors _error;\n        private readonly bool _sendError;\n\n        public TestResourceOwnerPasswordValidator()\n        { }\n\n        public TestResourceOwnerPasswordValidator(TokenRequestErrors error, string errorDescription = null)\n        {\n            _sendError = true;\n            _error = error;\n            _erroDescription = errorDescription;\n        }\n\n        public Task ValidateAsync(ResourceOwnerPasswordValidationContext context)\n        {\n            if (_sendError)\n            {\n                context.Result = new GrantValidationResult(_error, _erroDescription);\n                return Task.CompletedTask;\n            }\n\n            if (context.UserName == context.Password)\n            {\n                context.Result = new GrantValidationResult(context.UserName, \"password\");\n            }\n            \n            if (context.UserName == \"bob_no_password\" && context.Password == \"\")\n            {\n                context.Result = new GrantValidationResult(context.UserName, \"password\");\n            }\n\n            return Task.CompletedTask;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestScopes.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Generic;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    internal class TestScopes\n    {\n        public static IEnumerable<IdentityResource> GetIdentity()\n        {\n            return new IdentityResource[]\n            {\n                new IdentityResources.OpenId(),\n                new IdentityResources.Profile()\n            };\n        }\n\n        public static IEnumerable<ApiResource> GetApis()\n        {\n            return new ApiResource[]\n            {\n                new ApiResource\n                {\n                    Name = \"api\",\n                    Scopes =  { \"resource\", \"resource2\" }\n                }\n            };\n        }\n\n        public static IEnumerable<ApiScope> GetScopes()\n        {\n            return new ApiScope[]\n            {\n                new ApiScope\n                {\n                    Name = \"resource\",\n                    Description = \"resource scope\"\n                },\n                new ApiScope\n                {\n                    Name = \"resource2\",\n                    Description = \"resource scope\"\n                }\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TestTokenValidator.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing System.Threading.Tasks;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    class TestTokenValidator : ITokenValidator\n    {\n        private readonly TokenValidationResult _result;\n\n        public TestTokenValidator(TokenValidationResult result)\n        {\n            _result = result;\n        }\n\n        public Task<TokenValidationResult> ValidateAccessTokenAsync(string token, string expectedScope = null)\n        {\n            return Task.FromResult(_result);\n        }\n\n        public Task<TokenValidationResult> ValidateIdentityTokenAsync(string token, string clientId = null, bool validateLifetime = true)\n        {\n            return Task.FromResult(_result);\n        }\n\n        public Task<TokenValidationResult> ValidateRefreshTokenAsync(string token, Client client = null)\n        {\n            return Task.FromResult(_result);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/TokenFactory.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Models;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{\n    internal static class TokenFactory\n    {\n        public static Token CreateAccessToken(Client client, string subjectId, int lifetime, params string[] scopes)\n        {\n            var claims = new List<Claim> \n            {\n                new Claim(\"client_id\", client.ClientId),\n                new Claim(\"sub\", subjectId)\n            };\n\n            scopes.ToList().ForEach(s => claims.Add(new Claim(\"scope\", s)));\n\n            var token = new Token(OidcConstants.TokenTypes.AccessToken)\n            {\n                CreationTime = DateTime.UtcNow,\n                Audiences = { \"https://idsvr.com/resources\" },\n                Issuer = \"https://idsvr.com\",\n                Lifetime = lifetime,\n                Claims = claims,\n                ClientId = client.ClientId,\n                AccessTokenType = client.AccessTokenType\n            };\n\n            return token;\n        }\n\n        public static Token CreateAccessTokenLong(Client client, string subjectId, int lifetime, int count, params string[] scopes)\n        {\n            var claims = new List<Claim>\n            {\n                new Claim(\"client_id\", client.ClientId),\n                new Claim(\"sub\", subjectId)\n            };\n\n            for (int i = 0; i < count; i++)\n            {\n                claims.Add(new Claim(\"junk\", \"x\".Repeat(100)));\n            }\n\n            scopes.ToList().ForEach(s => claims.Add(new Claim(\"scope\", s)));\n\n            var token = new Token(OidcConstants.TokenTypes.AccessToken)\n            {\n                CreationTime = DateTime.UtcNow,\n                Audiences = { \"https://idsvr.com/resources\" },\n                Issuer = \"https://idsvr.com\",\n                Lifetime = lifetime,\n                Claims = claims,\n                ClientId = client.ClientId,\n                AccessTokenType = client.AccessTokenType\n            };\n\n            return token;\n        }\n\n        public static Token CreateIdentityToken(string clientId, string subjectId)\n        {\n            var clients = Factory.CreateClientStore();\n\n            var claims = new List<Claim> \n            {\n                new Claim(\"sub\", subjectId)\n            };\n\n            var token = new Token(OidcConstants.TokenTypes.IdentityToken)\n            {\n                CreationTime = DateTime.UtcNow,\n                Audiences = { clientId },\n                ClientId = clientId,\n                Issuer = \"https://idsvr.com\",\n                Lifetime = 600,\n                Claims = claims\n            };\n\n            return token;\n        }\n\n        public static Token CreateIdentityTokenLong(string clientId, string subjectId, int count)\n        {\n            var clients = Factory.CreateClientStore();\n\n            var claims = new List<Claim>\n            {\n                new Claim(\"sub\", subjectId)\n            };\n\n            for (int i = 0; i < count; i++)\n            {\n                claims.Add(new Claim(\"junk\", \"x\".Repeat(100)));\n            }\n\n            var token = new Token(OidcConstants.TokenTypes.IdentityToken)\n            {\n                CreationTime = DateTime.UtcNow,\n                Audiences = { clientId },\n                ClientId = clientId,\n                Issuer = \"https://idsvr.com\",\n                Lifetime = 600,\n                Claims = claims\n            };\n\n            return token;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/Setup/ValidationExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\n\nnamespace IdentityServer.UnitTests.Validation.Setup\n{ \n    public static class ValidationExtensions\n    {\n        public static ClientSecretValidationResult ToValidationResult(this Client client, ParsedSecret secret = null)\n        {\n            return new ClientSecretValidationResult\n            {\n                Client = client,\n                Secret = secret\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/StrictRedirectUriValidatorAppAuthValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer8.Models;\nusing IdentityServer8.Validation;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class StrictRedirectUriValidatorAppAuthValidation\n    {\n        private const string Category = \"Strict Redirect Uri Validator AppAuth Validation Tests\";\n\n        private Client clientWithValidLoopbackRedirectUri = new Client\n        {\n            RequirePkce = true,\n            RedirectUris = new List<string>\n            {\n                \"http://127.0.0.1\"\n            }\n        };\n\n        private Client clientWithNoRedirectUris = new Client\n        {\n            RequirePkce = true\n        };\n\n        [Theory]\n        [Trait(\"Category\", Category)]\n        [InlineData(\"http://127.0.0.1\")] // This is in the clients redirect URIs\n        [InlineData(\"http://127.0.0.1:0\")]\n        [InlineData(\"http://127.0.0.1:80\")]\n        [InlineData(\"http://127.0.0.1:65535\")]\n        [InlineData(\"http://127.0.0.1:123/a/b\")]\n        [InlineData(\"http://127.0.0.1:123?q=123\")]\n        [InlineData(\"http://127.0.0.1:443/?q=123\")]\n        [InlineData(\"http://127.0.0.1:443/a/b?q=123\")]\n        [InlineData(\"http://127.0.0.1:443#abc\")]\n        [InlineData(\"http://127.0.0.1:443/a/b?q=123#abc\")]\n        public async Task Loopback_Redirect_URIs_Should_Be_AllowedAsync(string requestedUri)\n        {\n            var strictRedirectUriValidatorAppAuthValidator = new StrictRedirectUriValidatorAppAuth(TestLogger.Create<StrictRedirectUriValidatorAppAuth>());\n\n            var result = await strictRedirectUriValidatorAppAuthValidator.IsRedirectUriValidAsync(requestedUri, clientWithValidLoopbackRedirectUri);\n\n            result.Should().BeTrue();\n        }\n\n        [Theory]\n        [Trait(\"Category\", Category)]\n        [InlineData(null)]\n        [InlineData(\"\")]\n        [InlineData(\"http:\")]\n        [InlineData(\"127.0.0.1\")]\n        [InlineData(\"//127.0.0.1\")]\n        [InlineData(\"https://127.0.0.1:123\")]\n        [InlineData(\"http://127.0.0.1:\")]\n        [InlineData(\"http://127.0.0.1:-1\")]\n        [InlineData(\"http://127.0.0.2:65536\")]\n        [InlineData(\"http://127.0.0.1:443a\")]\n        [InlineData(\"http://127.0.0.1:a443\")]\n        [InlineData(\"http://127.0.0.1:443a/\")]\n        [InlineData(\"http://127.0.0.1:443a?\")]\n        [InlineData(\"http://127.0.0.2:443\")]\n        [InlineData(\"http://127.0.0.1#abc\")]\n        [InlineData(\"http://127.0.0.1:#abc\")]\n        public async Task Loopback_Redirect_URIs_Should_Not_Be_AllowedAsync(string requestedUri)\n        {\n            var strictRedirectUriValidatorAppAuthValidator = new StrictRedirectUriValidatorAppAuth(TestLogger.Create<StrictRedirectUriValidatorAppAuth>());\n\n            var result = await strictRedirectUriValidatorAppAuthValidator.IsRedirectUriValidAsync(requestedUri, clientWithValidLoopbackRedirectUri);\n\n            result.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_ClientCredentials_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_ClientCredentials_Invalid\n    {\n        private const string Category = \"TokenRequest Validation - ClientCredentials - Invalid\";\n\n        private IClientStore _clients = Factory.CreateClientStore();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_GrantType_For_Client()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Request_should_succeed_even_with_allowed_identity_scopes_because_they_are_filtered_out()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                { OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials }\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.Count.Should().Be(1);\n            result.ValidatedRequest.ValidatedResources.Resources.ApiResources.First().Name.Should().Be(\"api\");\n\n            result.ValidatedRequest.ValidatedResources.Resources.ApiScopes.Count.Should().Be(2);\n            result.ValidatedRequest.ValidatedResources.Resources.ApiScopes.Select(x=>x.Name).Should().BeEquivalentTo(new[] { \"resource\", \"resource2\" });\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_Scope()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n            var validator = Factory.CreateTokenRequestValidator();\n            \n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"unknown\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_Scope_Multiple()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource unknown\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Restricted_Scope()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client_restricted\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource2\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Restricted_Scope_Multiple()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client_restricted\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource resource2\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Identity_scope_is_not_allowed_for_client_credentials_when_specified_explicitly()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                { OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials },\n                { OidcConstants.TokenRequest.Scope, \"openid\" }\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Resource_and_Refresh_Token()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource offline_access\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_Code_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_Code_Invalid\n    {\n        private IClientStore _clients = Factory.CreateClientStore();\n        private const string Category = \"TokenRequest Validation - AuthorizationCode - Invalid\";\n\n        private ClaimsPrincipal _subject = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_AuthorizationCode()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_AuthorizationCode()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, \"invalid\");\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task AuthorizationCodeTooLong()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n            var options = new IdentityServerOptions();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n            var longCode = \"x\".Repeat(options.InputLengthRestrictions.AuthorizationCode + 1);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, longCode);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task No_Scopes_for_AuthorizationCode()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            OidcConstants.TokenErrors.InvalidRequest.Should().Be(result.Error);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_Not_Authorized_For_AuthorizationCode_Flow()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"implicitclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_Trying_To_Request_Token_Using_Another_Clients_Code()\n        {\n            var client1 = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var client2 = await _clients.FindEnabledClientByIdAsync(\"codeclient_restricted\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client1.ClientId,\n                Lifetime = client1.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client2.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_RedirectUri()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Different_RedirectUri_Between_Authorize_And_Token_Request()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server1/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server2/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Expired_AuthorizationCode()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                CreationTime = DateTime.UtcNow.AddSeconds(-100),\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Reused_AuthorizationCode()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            // request first time\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n\n            // request second time\n            validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n            \n            result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Code_Request_with_disabled_User()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                RedirectUri = \"https://server/cb\",\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store,\n                profile: new TestProfileService(shouldBeActive: false));\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_DeviceCode_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_DeviceCode_Invalid\n    {\n        private const string Category = \"TokenRequest Validation - DeviceCode - Invalid\";\n\n        private readonly IClientStore _clients = Factory.CreateClientStore();\n\n        private readonly DeviceCode deviceCode = new DeviceCode\n        {\n            ClientId = \"device_flow\",\n            IsAuthorized = true,\n            Subject = new IdentityServerUser(\"bob\").CreatePrincipal(),\n            IsOpenId = true,\n            Lifetime = 300,\n            CreationTime = DateTime.UtcNow,\n            AuthorizedScopes = new[] {\"openid\", \"profile\", \"resource\"}\n        };\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_DeviceCode()\n        {\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                {OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.DeviceCode}\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidRequest);\n        }\n        \n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task DeviceCode_Too_Long()\n        {\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n\n            var longCode = \"x\".Repeat(new IdentityServerOptions().InputLengthRestrictions.AuthorizationCode + 1);\n            \n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                {OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.DeviceCode},\n                {\"device_code\", longCode}\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Grant_For_Client()\n        {\n            var client = await _clients.FindClientByIdAsync(\"codeclient\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                {OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.DeviceCode},\n                {\"device_code\", Guid.NewGuid().ToString()}\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task DeviceCodeValidator_Failure()\n        {\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n\n            var validator = Factory.CreateTokenRequestValidator(deviceCodeValidator: new TestDeviceCodeValidator(true));\n\n            var parameters = new NameValueCollection\n            {\n                {OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.DeviceCode},\n                {\"device_code\", Guid.NewGuid().ToString()}\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n            result.IsError.Should().BeTrue();\n            result.Error.Should().NotBeNull();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_ExtensionGrants_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_ExtensionGrants_Invalid\n    {\n        private const string Category = \"TokenRequest Validation - Extension Grants - Invalid\";\n\n        private IClientStore _clients = Factory.CreateClientStore();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Extension_Grant_Type_For_Client_Credentials_Client()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                { OidcConstants.TokenRequest.GrantType, \"customGrant\" },\n                { OidcConstants.TokenRequest.Scope, \"resource\" }\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Restricted_Extension_Grant_Type()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"customgrantclient\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                { OidcConstants.TokenRequest.GrantType, \"unknown_grant_type\" },\n                { OidcConstants.TokenRequest.Scope, \"resource\" }\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Customer_Error_and_Description_Extension_Grant_Type()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"customgrantclient\");\n\n            var validator = Factory.CreateTokenRequestValidator(extensionGrantValidators: new[] { new TestGrantValidator(isInvalid: true, errorDescription: \"custom error description\") });\n\n            var parameters = new NameValueCollection\n            {\n                { OidcConstants.TokenRequest.GrantType, \"custom_grant\" },\n                { OidcConstants.TokenRequest.Scope, \"resource\" }\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n            result.ErrorDescription.Should().Be(\"custom error description\");\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task inactive_user_should_fail()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"customgrantclient\");\n\n            var validator = Factory.CreateTokenRequestValidator(\n                profile: new TestProfileService(shouldBeActive: false));\n\n            var parameters = new NameValueCollection\n            {\n                { OidcConstants.TokenRequest.GrantType, \"custom_grant\" },\n                { OidcConstants.TokenRequest.Scope, \"resource\" }\n            };\n\n            var result = await validator.ValidateRequestAsync(\n                parameters, \n                client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_General_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_General_Invalid\n    {\n        private const string Category = \"TokenRequest Validation - General - Invalid\";\n\n        private IClientStore _clients = new InMemoryClientStore(TestClients.Get());\n        private ClaimsPrincipal _subject = new IdentityServerUser(\"bob\").CreatePrincipal();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Parameters_Null()\n        {\n            var validator = Factory.CreateTokenRequestValidator();\n\n            Func<Task> act = () => validator.ValidateRequestAsync(null, null);\n\n            act.Should().ThrowAsync<ArgumentNullException>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public void Client_Null()\n        {\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, \"valid\");\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            Func<Task> act = () => validator.ValidateRequestAsync(parameters, null);\n\n            act.Should().ThrowAsync<ArgumentNullException>();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_Grant_Type()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"unknown\");\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_Protocol_Type()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client.cred.wsfed\");\n            var codeStore = Factory.CreateAuthorizationCodeStore();\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore:codeStore);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"client_credentials\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_Grant_Type()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var store = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                IsOpenId = true,\n                RedirectUri = \"https://server/cb\",\n                Subject = _subject\n            };\n\n            var handle = await store.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: store);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnsupportedGrantType);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_PKCE.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Text;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_PKCE\n    {\n        private const string Category = \"TokenRequest Validation - PKCE\";\n\n        private IClientStore _clients = Factory.CreateClientStore();\n        private InputLengthRestrictions lengths = new InputLengthRestrictions();\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task valid_pkce_token_request_with_plain_method_should_succeed(string clientId)\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n            var grants = Factory.CreateAuthorizationCodeStore();\n            var verifier = \"x\".Repeat(lengths.CodeVerifierMinLength);\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"bob\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n                CodeChallenge = verifier.Sha256(),\n                CodeChallengeMethod = OidcConstants.CodeChallengeMethods.Plain,\n\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, verifier);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task valid_pkce_token_request_with_plain_method_should_succeed_hybrid()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"hybridclient.pkce\");\n            var grants = Factory.CreateAuthorizationCodeStore();\n            var verifier = \"x\".Repeat(lengths.CodeVerifierMinLength);\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n                CodeChallenge = verifier.Sha256(),\n                CodeChallengeMethod = OidcConstants.CodeChallengeMethods.Plain,\n\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, verifier);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task valid_pkce_token_request_with_sha256_method_should_succeed(string clientId)\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n            var grants = Factory.CreateAuthorizationCodeStore();\n\n            var verifier = \"x\".Repeat(lengths.CodeVerifierMinLength);\n            var challenge = VerifierToSha256CodeChallenge(verifier);\n            \n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n                CodeChallenge = challenge.Sha256(),\n                CodeChallengeMethod = OidcConstants.CodeChallengeMethods.Sha256,\n\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, verifier);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [Trait(\"Category\", Category)]\n        public async Task token_request_with_missing_code_challenge_and_verifier_should_fail(string clientId)\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n            var grants = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task token_request_with_missing_code_challenge_should_fail(string clientId)\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n            var grants = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, \"x\".Repeat(lengths.CodeVerifierMinLength));\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task token_request_with_invalid_verifier_plain_method_should_fail(string clientId)\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n            var grants = Factory.CreateAuthorizationCodeStore();\n            var verifier = \"x\".Repeat(lengths.CodeVerifierMinLength);\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n                CodeChallenge = verifier.Sha256(),\n                CodeChallengeMethod = OidcConstants.CodeChallengeMethods.Plain,\n\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, verifier + \"invalid\");\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Theory]\n        [InlineData(\"codeclient.pkce\")]\n        [InlineData(\"codeclient\")]\n        [Trait(\"Category\", Category)]\n        public async Task token_request_with_invalid_verifier_sha256_method_should_fail(string clientId)\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(clientId);\n            var grants = Factory.CreateAuthorizationCodeStore();\n\n            var verifier = \"x\".Repeat(lengths.CodeVerifierMinLength);\n            var challenge = VerifierToSha256CodeChallenge(verifier);\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n                CodeChallenge = challenge.Sha256(),\n                CodeChallengeMethod = OidcConstants.CodeChallengeMethods.Sha256,\n\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.CodeVerifier, verifier + \"invalid\");\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        private static string VerifierToSha256CodeChallenge(string codeVerifier)\n        {\n            var codeVerifierBytes = Encoding.ASCII.GetBytes(codeVerifier);\n            var hashedBytes = codeVerifierBytes.Sha256();\n            var transformedCodeVerifier = Base64Url.Encode(hashedBytes);\n\n            return transformedCodeVerifier;\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_RefreshToken_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Configuration;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_RefreshToken_Invalid\n    {\n        private const string Category = \"TokenRequest Validation - RefreshToken - Invalid\";\n\n        private IClientStore _clients = Factory.CreateClientStore();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Non_existing_RefreshToken()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, \"nonexistent\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task RefreshTokenTooLong()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var options = new IdentityServerOptions();\n\n            var validator = Factory.CreateTokenRequestValidator();\n            var longRefreshToken = \"x\".Repeat(options.InputLengthRestrictions.RefreshToken + 1);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, longRefreshToken);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Expired_RefreshToken()\n        {\n            var refreshToken = new RefreshToken\n            {\n                AccessToken = new Token(\"access_token\") { ClientId = \"roclient\" },\n                Lifetime = 10,\n                CreationTime = DateTime.UtcNow.AddSeconds(-15)\n            };\n\n            var grants = Factory.CreateRefreshTokenStore();\n            var handle = await grants.StoreRefreshTokenAsync(refreshToken);\n\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n\n            var validator = Factory.CreateTokenRequestValidator(\n                refreshTokenStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, handle);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Wrong_Client_Binding_RefreshToken_Request()\n        {\n            var refreshToken = new RefreshToken\n            {\n                AccessToken = new Token(\"access_token\")\n                {\n                    ClientId = \"otherclient\",\n                    Lifetime = 600,\n                    CreationTime = DateTime.UtcNow\n                }\n            };\n\n            var grants = Factory.CreateRefreshTokenStore();\n            var handle = await grants.StoreRefreshTokenAsync(refreshToken);\n\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n\n            var validator = Factory.CreateTokenRequestValidator(\n                refreshTokenStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, handle);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Client_has_no_OfflineAccess_Scope_anymore_at_RefreshToken_Request()\n        {\n            var refreshToken = new RefreshToken\n            {\n                AccessToken = new Token(\"access_token\")\n                {\n                    ClientId = \"roclient_restricted\"\n                },\n                Lifetime = 600,\n                CreationTime = DateTime.UtcNow\n            };\n\n            var grants = Factory.CreateRefreshTokenStore();\n            var handle = await grants.StoreRefreshTokenAsync(refreshToken);\n\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient_restricted\");\n\n            var validator = Factory.CreateTokenRequestValidator(\n                refreshTokenStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, handle);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task RefreshToken_Request_with_disabled_User()\n        {\n            var subjectClaim = new Claim(JwtClaimTypes.Subject, \"foo\");\n\n            var refreshToken = new RefreshToken\n            {\n                AccessToken = new Token(\"access_token\")\n                {\n                    Claims = new List<Claim> { subjectClaim },\n                    ClientId = \"roclient\"\n                },\n                Lifetime = 600,\n                CreationTime = DateTime.UtcNow\n            };\n\n            var grants = Factory.CreateRefreshTokenStore();\n            var handle = await grants.StoreRefreshTokenAsync(refreshToken);\n\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n\n            var validator = Factory.CreateTokenRequestValidator(\n                refreshTokenStore: grants,\n                profile: new TestProfileService(shouldBeActive: false));\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, handle);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_ResourceOwner_Invalid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System.Collections.Specialized;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Common;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_ResourceOwner_Invalid\n    {\n        private const string Category = \"TokenRequest Validation - ResourceOwner - Invalid\";\n\n        private IClientStore _clients = Factory.CreateClientStore();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_GrantType_For_Client()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnauthorizedClient);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_Scope()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"unknown\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Unknown_Scope_Multiple()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource unknown\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Restricted_Scope()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient_restricted\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource2\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Restricted_Scope_Multiple()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient_restricted\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource resource2\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidScope);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task No_ResourceOwnerCredentials()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_ResourceOwner_UserName()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Invalid_ResourceOwner_Credentials()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"notbob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n            result.ErrorDescription.Should().Be(\"invalid_username_or_password\");\n        }\n        \n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_ResourceOwner_password_for_user_with_password_should_fail()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob_with_password\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Password_GrantType_Not_Supported()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator(resourceOwnerValidator: new NotSupportedResourceOwnerPasswordValidator(TestLogger.Create<NotSupportedResourceOwnerPasswordValidator>()));\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.UnsupportedGrantType);\n            result.ErrorDescription.Should().BeNull();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Inactive_ResourceOwner()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator(profile: new TestProfileService(shouldBeActive: false));\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Password_GrantType_With_Custom_ErrorDescription()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator(resourceOwnerValidator: new TestResourceOwnerPasswordValidator(TokenRequestErrors.InvalidGrant, \"custom error description\"));\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"notbob\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.TokenErrors.InvalidGrant);\n            result.ErrorDescription.Should().Be(\"custom error description\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/TokenRequest Validation/TokenRequestValidation_Valid.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8;\nusing IdentityServer8.Models;\nusing IdentityServer8.Stores;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation.TokenRequest_Validation\n{\n    public class TokenRequestValidation_Valid\n    {\n        private const string Category = \"TokenRequest Validation - General - Valid\";\n\n        private IClientStore _clients = Factory.CreateClientStore();\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Missing_ResourceOwner_password_for_user_with_no_password_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob_no_password\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n            result.ValidatedRequest.UserName.Should().Be(\"bob_no_password\");\n        }\n        \n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_code_request_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var grants = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                RedirectUri = \"https://server/cb\",\n                RequestedScopes = new List<string>\n                {\n                    \"openid\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_code_request_with_refresh_token_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"codeclient\");\n            var grants = Factory.CreateAuthorizationCodeStore();\n\n            var code = new AuthorizationCode\n            {\n                CreationTime = DateTime.UtcNow,\n                ClientId = client.ClientId,\n                Lifetime = client.AuthorizationCodeLifetime,\n                Subject = new IdentityServerUser(\"123\").CreatePrincipal(),\n                RedirectUri = \"https://server/cb\",\n                RequestedScopes = new List<string>\n                {\n                    \"openid\",\n                    \"offline_access\"\n                }\n            };\n\n            var handle = await grants.StoreAuthorizationCodeAsync(code);\n\n            var validator = Factory.CreateTokenRequestValidator(\n                authorizationCodeStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.AuthorizationCode);\n            parameters.Add(OidcConstants.TokenRequest.Code, handle);\n            parameters.Add(OidcConstants.TokenRequest.RedirectUri, \"https://server/cb\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_client_credentials_request_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_client_credentials_request_with_default_scopes_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client_restricted\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            \n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_client_credentials_request_for_implicit_and_client_credentials_client_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"implicit_and_client_creds_client\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_client_credentials_request_restricted_client_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"client_restricted\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.ClientCredentials);\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_resource_owner_request_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_resource_wwner_request_with_refresh_token_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource offline_access\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_resource_owner_request_restricted_client_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient_restricted\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.Password);\n            parameters.Add(OidcConstants.TokenRequest.UserName, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Password, \"bob\");\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task valid_extension_grant_request_should_succeed()\n        {\n            var client = await _clients.FindEnabledClientByIdAsync(\"customgrantclient\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"custom_grant\");\n            parameters.Add(OidcConstants.TokenRequest.Scope, \"resource\");\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_refresh_token_request_should_succeed()\n        {\n            var subjectClaim = new Claim(JwtClaimTypes.Subject, \"foo\");\n\n            var refreshToken = new RefreshToken\n            {\n                AccessToken = new Token(\"access_token\")\n                {\n                    Claims = new List<Claim> { subjectClaim },\n                    ClientId = \"roclient\"\n                },\n                Lifetime = 600,\n                CreationTime = DateTime.UtcNow\n            };\n\n            var grants = Factory.CreateRefreshTokenStore();\n            var handle = await grants.StoreRefreshTokenAsync(refreshToken);\n\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient\");\n\n            var validator = Factory.CreateTokenRequestValidator(\n                refreshTokenStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, handle);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_refresh_token_request_using_restricted_client_should_succeed()\n        {\n            var subjectClaim = new Claim(JwtClaimTypes.Subject, \"foo\");\n\n            var refreshToken = new RefreshToken\n            {\n                AccessToken = new Token(\"access_token\")\n                {\n                    Claims = new List<Claim> { subjectClaim },\n                    ClientId = \"roclient_restricted_refresh\"\n                },\n\n                Lifetime = 600,\n                CreationTime = DateTime.UtcNow\n            };\n\n            var grants = Factory.CreateRefreshTokenStore();\n            var handle = await grants.StoreRefreshTokenAsync(refreshToken);\n\n            var client = await _clients.FindEnabledClientByIdAsync(\"roclient_restricted_refresh\");\n\n            var validator = Factory.CreateTokenRequestValidator(\n                refreshTokenStore: grants);\n\n            var parameters = new NameValueCollection();\n            parameters.Add(OidcConstants.TokenRequest.GrantType, \"refresh_token\");\n            parameters.Add(OidcConstants.TokenRequest.RefreshToken, handle);\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n\n            result.IsError.Should().BeFalse();\n        }\n        \n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task Valid_device_code_request_should_succeed()\n        {\n            var deviceCode = new DeviceCode\n            {\n                ClientId = \"device_flow\",\n                IsAuthorized = true,\n                Subject = new IdentityServerUser(\"bob\").CreatePrincipal(),\n                IsOpenId = true,\n                Lifetime = 300,\n                CreationTime = DateTime.UtcNow,\n                AuthorizedScopes = new[] { \"openid\", \"profile\", \"resource\" }\n            };\n\n            var client = await _clients.FindClientByIdAsync(\"device_flow\");\n\n            var validator = Factory.CreateTokenRequestValidator();\n\n            var parameters = new NameValueCollection\n            {\n                {OidcConstants.TokenRequest.GrantType, OidcConstants.GrantTypes.DeviceCode},\n                {\"device_code\", Guid.NewGuid().ToString()}\n            };\n\n            var result = await validator.ValidateRequestAsync(parameters, client.ToValidationResult());\n            result.IsError.Should().BeFalse();\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/Validation/UserInfoRequestValidation.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing IdentityModel;\nusing IdentityServer.UnitTests.Validation.Setup;\nusing IdentityServer8.Stores;\nusing IdentityServer8.Validation;\nusing System.Collections.Generic;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\nusing IdentityServer.UnitTests.Common;\nusing Xunit;\n\nnamespace IdentityServer.UnitTests.Validation\n{\n    public class UserInfoRequestValidation\n    {\n        private const string Category = \"UserInfo Request Validation Tests\";\n        private IClientStore _clients = new InMemoryClientStore(TestClients.Get());\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task token_without_sub_should_fail()\n        {\n            var tokenResult = new TokenValidationResult\n            {\n                IsError = false,\n                Client = await _clients.FindEnabledClientByIdAsync(\"codeclient\"),\n                Claims = new List<Claim>()\n            };\n\n            var validator = new UserInfoRequestValidator(\n                new TestTokenValidator(tokenResult),\n                new TestProfileService(shouldBeActive: true),\n                TestLogger.Create<UserInfoRequestValidator>());\n\n            var result = await validator.ValidateRequestAsync(\"token\");\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task active_user_should_succeed()\n        {\n            var tokenResult = new TokenValidationResult\n            {\n                IsError = false,\n                Client = await _clients.FindEnabledClientByIdAsync(\"codeclient\"),\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\")\n                },\n            };\n\n            var validator = new UserInfoRequestValidator(\n                new TestTokenValidator(tokenResult),\n                new TestProfileService(shouldBeActive: true),\n                TestLogger.Create<UserInfoRequestValidator>());\n\n            var result = await validator.ValidateRequestAsync(\"token\");\n\n            result.IsError.Should().BeFalse();\n        }\n\n        [Fact]\n        [Trait(\"Category\", Category)]\n        public async Task inactive_user_should_fail()\n        {\n            var tokenResult = new TokenValidationResult\n            {\n                IsError = false,\n                Client = await _clients.FindEnabledClientByIdAsync(\"codeclient\"),\n                Claims = new List<Claim>\n                {\n                    new Claim(\"sub\", \"123\")\n                },\n            };\n\n            var validator = new UserInfoRequestValidator(\n                new TestTokenValidator(tokenResult),\n                new TestProfileService(shouldBeActive: false),\n                TestLogger.Create<UserInfoRequestValidator>());\n\n            var result = await validator.ValidateRequestAsync(\"token\");\n\n            result.IsError.Should().BeTrue();\n            result.Error.Should().Be(OidcConstants.ProtectedResourceErrors.InvalidToken);\n        }\n    }\n}\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/identityserver_testing.cer",
    "content": "-----BEGIN CERTIFICATE-----\nMIIDQTCCAimgAwIBAgIQO+9qzaJY9I5Ewq81kNEKWTANBgkqhkiG9w0BAQsFADAh\nMR8wHQYDVQQDDBZpZGVudGl0eXNlcnZlcl90ZXN0aW5nMCAXDTIwMDEyMjIzMTYz\nOFoYDzIxMDMwNTIyMjMyNjM5WjAhMR8wHQYDVQQDDBZpZGVudGl0eXNlcnZlcl90\nZXN0aW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuyZQvE+6gEoB\na+LV3dxjk/Xj4DRJ/tefQKR2AZoYAAfKN4ditFmEfRC1A6rckBpMVihTeb1kwwQT\n7H4HTS6O/ERHVjOdghoOjEsVakWhAkvh8gphC4IU0upXlYqMh2WzgXEXwYRFB9Tk\n7zoHb1/zjEEAhCf2Xbi6YslBoU71bFWyAaeOTl859wV6WaiBIK5L8nJUaIaq4zmC\nk8caPZq5E867mZiMdL4TcW9/YoAAO96Wa/W9o6OiuZrP414TlEjVuccpLXvjk0hB\nU5OZD2bTvD3MQZu1n1QMLwXfaOBrcv1/RqYJkK7vpP6Pp1YYlo7b2PBDVAIrRSVT\nlaViBP0owQIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB\nBQUHAwIGCCsGAQUFBwMBMCEGA1UdEQQaMBiCFmlkZW50aXR5c2VydmVyX3Rlc3Rp\nbmcwHQYDVR0OBBYEFCVXNpKp8QlHywXEBFfpXxWcOMcsMA0GCSqGSIb3DQEBCwUA\nA4IBAQBsEAzwyN6V6N5ggN9G1O0ZpviSjixGkWtySNCBjbGXAhOvfW4M3ysNkDwZ\nltk/Q17ihZzw135MrDCmnr5pRiN4CbEGbe1qsb+Z0uCCn8/WcIVYYooW66H/Jez+\ndg5RxUukA67ZDnjzRskIer7L2t1C4pDqpvPVcneUxkiYDSgcKpTuCVjkPNQKQTIw\nSm98NkQG8G8V8+ENIU837ytkiC5nqQa4zDRHexzWrYhiuayWWxJKcNRVF9YaE8ts\nvp5N1ewmWbSgF8caJuKraVOISj9R4iqf0XuhfSpW/7eIWYmXfqy/UloeqlALfP5C\n2d2FdDSfsQ4Jgc3ebrECAQaCC3Gq\n-----END CERTIFICATE-----\n"
  },
  {
    "path": "src/IdentityServer8/test/IdentityServer.UnitTests/xunit.runner.json",
    "content": "﻿{\n  \"methodDisplay\":\"classAndMethod\"\n}\n"
  },
  {
    "path": "src/IdentityServer8.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.8.34322.80\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{5461C61B-B06E-46BA-B206-925B660BE727}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"test\", \"test\", \"{45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8\", \"IdentityServer8\\src\\IdentityServer8.csproj\", \"{407C030E-60E6-41F7-AF43-0AC48EDCC17D}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Host\", \"IdentityServer8\\host\\Host.csproj\", \"{784B3C88-30FA-415D-B99E-584063064508}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer.UnitTests\", \"IdentityServer8\\test\\IdentityServer.UnitTests\\IdentityServer.UnitTests.csproj\", \"{4291820C-735F-4776-8BC4-6527433BC683}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer.IntegrationTests\", \"IdentityServer8\\test\\IdentityServer.IntegrationTests\\IdentityServer.IntegrationTests.csproj\", \"{94501373-478A-478D-8C17-6AC52E3438CF}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework.Storage\", \"EntityFramework.Storage\\src\\IdentityServer8.EntityFramework.Storage.csproj\", \"{5302DAB3-1662-4956-97AA-5EA5E85B10F6}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework.UnitTests\", \"EntityFramework.Storage\\test\\UnitTests\\IdentityServer8.EntityFramework.UnitTests.csproj\", \"{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework.IntegrationTests\", \"EntityFramework.Storage\\test\\IntegrationTests\\IdentityServer8.EntityFramework.IntegrationTests.csproj\", \"{E90F7470-C7F8-464B-9C28-87C474085812}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"migrations\", \"migrations\", \"{E3EF31E0-6658-4899-8BDA-FF84355E2FDD}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SqlServer\", \"EntityFramework.Storage\\migrations\\SqlServer\\SqlServer.csproj\", \"{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"host\", \"host\", \"{07C56E10-A807-4372-ACD9-ADED2D099BC8}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ConsoleHost\", \"EntityFramework.Storage\\host\\ConsoleHost\\ConsoleHost.csproj\", \"{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"IdentityServer\", \"IdentityServer\", \"{37FCD1F7-B8CB-4D7B-A2E8-0AE458652314}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"EntityFramework.Storage\", \"EntityFramework.Storage\", \"{28C914A4-BC3B-4D55-8799-C8A4A6AD724E}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"IdentityServer\", \"IdentityServer\", \"{E5F41733-E9B8-4EA8-A5A3-620827B68340}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"EntityFramework.Storage\", \"EntityFramework.Storage\", \"{6F2785D9-4208-4A9F-85B0-674185D393C5}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Storage\", \"Storage\", \"{19B12297-DCC0-4529-A04C-5B0E2C0F01B9}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Storage\", \"Storage\", \"{6CB8A0D7-77D4-411B-953C-A4AB50F56205}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.Storage\", \"Storage\\src\\IdentityServer8.Storage.csproj\", \"{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.AspNetIdentity\", \"AspNetIdentity\\src\\IdentityServer8.AspNetIdentity.csproj\", \"{A2CDBE15-5898-4A04-94DC-133EE03A78B3}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Host\", \"AspNetIdentity\\host\\Host.csproj\", \"{B7FBA07C-A462-4869-AF94-5E36DFC3742D}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SqlServer\", \"AspNetIdentity\\migrations\\SqlServer\\SqlServer.csproj\", \"{DD44B9E9-C32E-4F89-92C9-25444A709BBB}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework\", \"EntityFramework\\src\\IdentityServer8.EntityFramework.csproj\", \"{AB83F911-8B78-4973-A3A9-2A2D85581F25}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"SqlServer\", \"EntityFramework\\migrations\\SqlServer\\SqlServer.csproj\", \"{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.EntityFramework.Tests\", \"EntityFramework\\test\\IdentityServer8.EntityFramework.Tests\\IdentityServer8.EntityFramework.Tests.csproj\", \"{E3685B06-F135-4318-B841-889C35479D5C}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Files\", \"Solution Files\", \"{29DC1E06-3EC5-4F52-9EC1-0363BD571369}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\.gitignore = ..\\.gitignore\n\t\t..\\Directory.Build.props = ..\\Directory.Build.props\n\t\t..\\Directory.Build.targets = ..\\Directory.Build.targets\n\t\tDirectory.BuildOld.targets = Directory.BuildOld.targets\n\t\t..\\Directory.Packages.props = ..\\Directory.Packages.props\n\t\t..\\global.json = ..\\global.json\n\t\t..\\IdentityServer8.DotNet.ruleset = ..\\IdentityServer8.DotNet.ruleset\n\t\t..\\LICENSE = ..\\LICENSE\n\t\t..\\LicenseHeader.txt = ..\\LicenseHeader.txt\n\t\t..\\NuGet.config = ..\\NuGet.config\n\t\t..\\README.md = ..\\README.md\n\t\t..\\SECURITY.MD = ..\\SECURITY.MD\n\t\t..\\SPONSORS.md = ..\\SPONSORS.md\n\t\t..\\version.json = ..\\version.json\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"AspNetIdentity\", \"AspNetIdentity\", \"{7849D7DE-FD6A-4A5B-A793-5DCFFCDDC944}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"EntityFramework\", \"EntityFramework\", \"{06FC2C45-FCD6-469C-8F2D-3E1A750D1EF9}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"EntityFramework\", \"EntityFramework\", \"{39F7E2E8-1EAB-4163-8E4D-43CBB23AB871}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \".github\", \".github\", \"{A7171FEC-FEC1-4AF0-9625-E69D93F08A42}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\.github\\CONTRIBUTING.md = ..\\.github\\CONTRIBUTING.md\n\t\t..\\.github\\dependabot.yml = ..\\.github\\dependabot.yml\n\t\t..\\.github\\FUNDING.yml = ..\\.github\\FUNDING.yml\n\t\t..\\.github\\PULL_REQUEST_TEMPLATE.md = ..\\.github\\PULL_REQUEST_TEMPLATE.md\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"issuetemplate\", \"issuetemplate\", \"{0BC5E76A-A280-49C8-8E96-A43FEA357A4B}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"workflows\", \"workflows\", \"{C5474352-0715-41C0-92C2-BABA1A4103A0}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\.github\\workflows\\codeql.yml = ..\\.github\\workflows\\codeql.yml\n\t\t..\\.github\\workflows\\develop.yml = ..\\.github\\workflows\\develop.yml\n\t\t..\\.github\\workflows\\master.yml = ..\\.github\\workflows\\master.yml\n\t\t..\\.github\\workflows\\pre-release.yml = ..\\.github\\workflows\\pre-release.yml\n\t\t..\\.github\\workflows\\release.yml = ..\\.github\\workflows\\release.yml\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"docs\", \"docs\", \"{21B3EAAF-1A7D-4D46-AB3F-843296EDBDC2}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\docs\\CHANGELOG.md = ..\\docs\\CHANGELOG.md\n\tEndProjectSection\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Security\", \"Security\", \"{9B9C47C4-560E-4F2E-8F53-97F9FDE46008}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Security\", \"Security\", \"{19B652D0-0AA1-415C-AA62-065EE8C77182}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.Security\", \"Security\\IdentityServer8.Security\\IdentityServer8.Security.csproj\", \"{284DF9E0-8007-4E84-949D-5B610D76B1CF}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.Sanitizer.Tests\", \"Security\\test\\IdentityServer8.Santizer.Tests\\IdentityServer8.Sanitizer.Tests.csproj\", \"{00BDF864-B06A-4A48-B8B4-85C219B33CD1}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Host\", \"EntityFramework\\host\\Host.csproj\", \"{C7939ADD-36C9-444F-A773-28EC81587831}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{784B3C88-30FA-415D-B99E-584063064508}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{4291820C-735F-4776-8BC4-6527433BC683}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB}.Release|Any CPU.ActiveCfg = Release|Any CPU\t\t\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E3685B06-F135-4318-B841-889C35479D5C}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{284DF9E0-8007-4E84-949D-5B610D76B1CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{284DF9E0-8007-4E84-949D-5B610D76B1CF}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{284DF9E0-8007-4E84-949D-5B610D76B1CF}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{284DF9E0-8007-4E84-949D-5B610D76B1CF}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{00BDF864-B06A-4A48-B8B4-85C219B33CD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{00BDF864-B06A-4A48-B8B4-85C219B33CD1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{00BDF864-B06A-4A48-B8B4-85C219B33CD1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{00BDF864-B06A-4A48-B8B4-85C219B33CD1}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C7939ADD-36C9-444F-A773-28EC81587831}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C7939ADD-36C9-444F-A773-28EC81587831}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C7939ADD-36C9-444F-A773-28EC81587831}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C7939ADD-36C9-444F-A773-28EC81587831}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{407C030E-60E6-41F7-AF43-0AC48EDCC17D} = {E5F41733-E9B8-4EA8-A5A3-620827B68340}\n\t\t{784B3C88-30FA-415D-B99E-584063064508} = {E5F41733-E9B8-4EA8-A5A3-620827B68340}\n\t\t{4291820C-735F-4776-8BC4-6527433BC683} = {37FCD1F7-B8CB-4D7B-A2E8-0AE458652314}\n\t\t{94501373-478A-478D-8C17-6AC52E3438CF} = {37FCD1F7-B8CB-4D7B-A2E8-0AE458652314}\n\t\t{5302DAB3-1662-4956-97AA-5EA5E85B10F6} = {6F2785D9-4208-4A9F-85B0-674185D393C5}\n\t\t{8239FC82-46A3-4F21-8D05-1F0BE0B1B1FC} = {28C914A4-BC3B-4D55-8799-C8A4A6AD724E}\n\t\t{E90F7470-C7F8-464B-9C28-87C474085812} = {28C914A4-BC3B-4D55-8799-C8A4A6AD724E}\n\t\t{E3EF31E0-6658-4899-8BDA-FF84355E2FDD} = {6F2785D9-4208-4A9F-85B0-674185D393C5}\n\t\t{A93A59EC-D75D-44E1-9720-F75D9EF95BC3} = {E3EF31E0-6658-4899-8BDA-FF84355E2FDD}\n\t\t{07C56E10-A807-4372-ACD9-ADED2D099BC8} = {6F2785D9-4208-4A9F-85B0-674185D393C5}\n\t\t{2AA5AC6B-531B-426E-AD38-5B03F1949CF5} = {07C56E10-A807-4372-ACD9-ADED2D099BC8}\n\t\t{37FCD1F7-B8CB-4D7B-A2E8-0AE458652314} = {45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\n\t\t{28C914A4-BC3B-4D55-8799-C8A4A6AD724E} = {45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\n\t\t{E5F41733-E9B8-4EA8-A5A3-620827B68340} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{6F2785D9-4208-4A9F-85B0-674185D393C5} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{19B12297-DCC0-4529-A04C-5B0E2C0F01B9} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{6CB8A0D7-77D4-411B-953C-A4AB50F56205} = {45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7} = {19B12297-DCC0-4529-A04C-5B0E2C0F01B9}\n\t\t{A2CDBE15-5898-4A04-94DC-133EE03A78B3} = {7849D7DE-FD6A-4A5B-A793-5DCFFCDDC944}\n\t\t{B7FBA07C-A462-4869-AF94-5E36DFC3742D} = {7849D7DE-FD6A-4A5B-A793-5DCFFCDDC944}\n\t\t{DD44B9E9-C32E-4F89-92C9-25444A709BBB} = {7849D7DE-FD6A-4A5B-A793-5DCFFCDDC944}\n\t\t{AB83F911-8B78-4973-A3A9-2A2D85581F25} = {06FC2C45-FCD6-469C-8F2D-3E1A750D1EF9}\n\t\t{D9FABEC8-09DC-4B0D-80D7-86FA6C5D9C69} = {06FC2C45-FCD6-469C-8F2D-3E1A750D1EF9}\n\t\t{E3685B06-F135-4318-B841-889C35479D5C} = {39F7E2E8-1EAB-4163-8E4D-43CBB23AB871}\n\t\t{7849D7DE-FD6A-4A5B-A793-5DCFFCDDC944} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{06FC2C45-FCD6-469C-8F2D-3E1A750D1EF9} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{39F7E2E8-1EAB-4163-8E4D-43CBB23AB871} = {45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\n\t\t{A7171FEC-FEC1-4AF0-9625-E69D93F08A42} = {29DC1E06-3EC5-4F52-9EC1-0363BD571369}\n\t\t{0BC5E76A-A280-49C8-8E96-A43FEA357A4B} = {A7171FEC-FEC1-4AF0-9625-E69D93F08A42}\n\t\t{C5474352-0715-41C0-92C2-BABA1A4103A0} = {A7171FEC-FEC1-4AF0-9625-E69D93F08A42}\n\t\t{21B3EAAF-1A7D-4D46-AB3F-843296EDBDC2} = {29DC1E06-3EC5-4F52-9EC1-0363BD571369}\n\t\t{9B9C47C4-560E-4F2E-8F53-97F9FDE46008} = {5461C61B-B06E-46BA-B206-925B660BE727}\n\t\t{19B652D0-0AA1-415C-AA62-065EE8C77182} = {45C22EDD-91B1-4AEF-8620-77F4E3E7C544}\n\t\t{284DF9E0-8007-4E84-949D-5B610D76B1CF} = {9B9C47C4-560E-4F2E-8F53-97F9FDE46008}\n\t\t{00BDF864-B06A-4A48-B8B4-85C219B33CD1} = {19B652D0-0AA1-415C-AA62-065EE8C77182}\n\t\t{C7939ADD-36C9-444F-A773-28EC81587831} = {06FC2C45-FCD6-469C-8F2D-3E1A750D1EF9}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {176723F7-4A9B-4F05-A9F3-3BA715E4BDC3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/IdentityServer8.sln.licenseheader",
    "content": "extensions: designer.cs generated.cs\nextensions: .cs \n/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n"
  },
  {
    "path": "src/Security/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/Security/IdentityServer8.Security/Extensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\npublic class Ioc\n{\n    static Ioc()\n    {\n        var services = new ServiceCollection();\n        services.AddLogging();\n        services.AddSanitizers();\n        services.AddAllowAnyRedirectService();\n        services.AddSingleton<IRedirectService, AllowAnyRedirectService>();\n        ServiceProvider = services.BuildServiceProvider();\n        var sanitizer = ServiceProvider.GetRequiredService<ISanitizer>();\n        Sanitizer = sanitizer;\n        var redirectService = ServiceProvider.GetRequiredService<IRedirectService>();\n        RedirectService = redirectService;\n    }\n\n    public static ServiceProvider ServiceProvider { get; }\n    public static ISanitizer Sanitizer { get; }\n    public static IRedirectService RedirectService { get; }\n\n}\n"
  },
  {
    "path": "src/Security/IdentityServer8.Security/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityServer8.Security;\nglobal using Microsoft.AspNetCore.Http;\nglobal using Microsoft.Extensions.DependencyInjection;\nglobal using Microsoft.Extensions.Logging;\nglobal using System.Net;\nglobal using System.Web;\n"
  },
  {
    "path": "src/Security/IdentityServer8.Security/IdentityServer8.Security.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n        <Description>Security package for user input sanitzation IdentityServer8 services and packages.</Description>\n        <IsPackable>true</IsPackable>\n        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>\n        <ImplicitUsings>enable</ImplicitUsings>\n        <Nullable>enable</Nullable>\n    </PropertyGroup>\n\n    <ItemGroup>\n        <PackageReference Include=\"Microsoft.AspNetCore.Http.Abstractions\" />\n        <PackageReference Include=\"Microsoft.AspNetCore.Mvc.Abstractions\" />\n        <PackageReference Include=\"Microsoft.Extensions.DependencyInjection\" />\n        <PackageReference Include=\"Microsoft.Extensions.DependencyInjection.Abstractions\" />\n        <PackageReference Include=\"Microsoft.Extensions.Logging.Abstractions\" />\n        <PackageReference Include=\"Microsoft.Extensions.Logging\" />\n    </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Security/IdentityServer8.Security/RedirectService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Security;\n\npublic interface IRedirectService\n{\n    bool IsRedirectAllowed(string redirectUrl);\n}\n\n\npublic class RuleMatcher\n{\n    public bool IsMatch(string url, RedirectRule rule)\n    {\n        throw new NotImplementedException();\n    }\n}\npublic class RedirectRule\n{\n    public static RedirectRule AllowAny\n        => new RedirectRule();\n\n    public RedirectRule()\n    {\n        AllowedFragment = Fragment.Any;\n        AllowedPath = Path.Any;\n        AllowedPort = Port.Any;\n        AllowedQuery = Query.Any;\n        AllowedScheme = Scheme.Any;\n        AllowedHost = Host.Any;\n    }\n    public Scheme AllowedScheme { get; set; }\n    public Host AllowedHost { get; set; }\n    public Port AllowedPort { get; set; }\n    public Path AllowedPath { get; set; }\n    public Query AllowedQuery { get; set; }\n    public Fragment AllowedFragment { get; set; }\n}\n\npublic class Scheme\n{\n    public Scheme(string name) { Name = name; }\n    public string Name { get; }\n\n    public static readonly Scheme Http = new Scheme(\"http\");\n    public static readonly Scheme Https = new Scheme(\"https\");\n    public static readonly Scheme Any = new Scheme(\"*\");\n\n    public static Scheme Parse(string schemeName)\n    {\n        if (string.IsNullOrWhiteSpace(schemeName))\n        {\n            throw new ArgumentException(\"Scheme name cannot be null or empty\");\n        }\n        else if (schemeName.Equals(\"http\", StringComparison.OrdinalIgnoreCase))\n        {\n            return Http;\n        }\n        else if (schemeName.Equals(\"https\", StringComparison.OrdinalIgnoreCase))\n        {\n            return Https;\n        }\n        else if (schemeName.Equals(\"*\", StringComparison.OrdinalIgnoreCase))\n        {\n            return Any;\n        }\n        else\n        {\n            throw new ArgumentException(\"Invalid scheme name\");\n        }\n\n    }\n\n    public override string ToString()\n    {\n        return Name;\n    }\n}\n\npublic class Host\n{\n    public Host(string value)\n    {\n        Value = ((value ?? \"\").ToLower().Trim() ?? \"\");\n        var domainParts = Value.Split('.');\n        domainParts = domainParts.Where(x => !string.IsNullOrEmpty(x)).ToArray();\n        HostParts = new List<string>(domainParts);\n    }\n    public List<string> HostParts;\n\n    public string Value { get; }\n\n    public static readonly Host Any = new Host(\"*\");\n\n    public static Host Create(string hostname) => new Host(hostname);\n\n    public bool HasWildcard => Value.Contains(\"*.\");\n    public bool IsAny => Value == \"*\";\n    public bool IsLocalhost => Value.Equals(\"localhost\", StringComparison.OrdinalIgnoreCase) || Value.Equals(\"127.0.0.1\");\n    public bool IsIpAddress => Uri.CheckHostName(Value) == UriHostNameType.IPv4 || Uri.CheckHostName(Value) == UriHostNameType.IPv6;\n    public bool IsLocalNetwork => IsLocalhost || IsIpAddress;\n    public bool IsFullQualifiedDomainName => !IsLocalNetwork && !HasWildcard && !IsAny && Value.IndexOf('.') > -1;\n\n}\n\npublic class Port\n{\n    public Port(int value) { Value = value; }\n    public int Value { get; }\n\n    public static readonly Port Any = new Port(-1); // Assuming -1 signifies any port\n\n    public static Port Create(int portNumber) => new Port(portNumber);\n}\n\npublic class Path\n{\n    public Path(string value) { Value = value; }\n    public string Value { get; }\n\n    public static readonly Path Any = new Path(\"*\");\n\n    public static Path Create(string path) => new Path(path);\n}\n\npublic class Query\n{\n    public Query(string value) { Value = value; }\n    public string Value { get; }\n\n    public static readonly Query Any = new Query(\"*\");\n\n    public static Query Create(string query) => new Query(query);\n}\n\npublic class Fragment\n{\n    public Fragment(string value) { Value = value; }\n    public string Value { get; }\n\n    public static readonly Fragment Any = new Fragment(\"*\");\n\n    public static Fragment Create(string fragment) => new Fragment(fragment);\n}\n\n\npublic class RedirectValidition\n{\n    static RedirectValidition()\n    {\n        var provider = new ServiceCollection()\n            .AddLogging()\n            .AddSingleton<IRedirectService, RedirectService>()\n            .AddSanitizers()\n            .BuildServiceProvider();\n        ServiceProvider = provider;\n\n    }\n\n    public static ServiceProvider ServiceProvider { get; }\n}\n\npublic static class RedirectServiceExtensions\n{\n\n    public static IServiceCollection AddAllowAnyRedirectService(this IServiceCollection services)\n    {\n        services.AddSingleton<AllowAnyRedirectService>();\n        return services;\n    }\n}\n\npublic class AllowAnyRedirectService : RedirectService\n{\n    public AllowAnyRedirectService(ILogger<RedirectService> logger, ISanitizer sanitizer) : base(logger, sanitizer)\n    {\n        AddRedirectRule(RedirectRule.AllowAny);\n    }\n}\n\npublic class RedirectService : IRedirectService\n{\n    public RedirectService(ILogger<RedirectService> logger, ISanitizer sanitizer)\n    {\n        _logger = logger;\n        _sanitizer = sanitizer;\n    }\n    private readonly List<RedirectRule> _rules = new List<RedirectRule>();\n    private readonly ILogger<RedirectService> _logger;\n    private readonly ISanitizer _sanitizer;\n\n    public IRedirectService AddRedirectRule(RedirectRule rule)\n    {\n        _rules.Add(rule);\n        return this;\n    }\n    public IRedirectService ClearRules()\n    {\n        _rules.Clear();\n        return this;\n    }\n\n    public IRedirectService AddRule(RedirectRule rule)\n    {\n        _rules.Add(rule);\n        return this;\n    }\n\n    public IRedirectService RemoveRule(RedirectRule rule)\n    {\n        _rules.Remove(rule);\n        return this;\n    }\n    public IRedirectService AddRules(IEnumerable<RedirectRule> rules)\n    {\n        _rules.AddRange(rules);\n        return this;\n    }\n    public IRedirectService RemoveRules(IEnumerable<RedirectRule> rules)\n    {\n        foreach (var rule in rules)\n        {\n            RemoveRule(rule);\n        }\n        return this;\n    }\n\n    public virtual bool IsRedirectAllowed(string redirectUrl)\n    {\n        if (!Uri.TryCreate(redirectUrl, UriKind.RelativeOrAbsolute, out var uri))\n        {\n            _logger.LogWarning(\"Invalid URL: {redirectUrl}\", redirectUrl.SanitizeForLog());\n            return false;\n        }\n\n        // If the URL is relative, assume it's allowed, or handle according to your policy\n        if (!uri.IsAbsoluteUri)\n        {\n            // Handle relative URLs based on your specific requirements.\n            // For example, we might always allow them, check them against a specific set of rules,\n            // or reject them outright.\n            return HandleRelativeUrl(uri);\n        }\n\n        foreach (var rule in _rules)\n        {\n            if (IsRuleMatch(uri, rule))\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    public bool HandleRelativeUrl(Uri uri)\n    {\n        // Implement logic for handling relative URLs on local server.\n        // This is a placeholder as restricting redirect URLs on the local server is not a common scenario.\n        // For now: return true to allow all relative URLs\n        return true;\n    }\n\n\n    public bool IsRuleMatch(Uri uri, RedirectRule rule)\n    {\n        return IsSchemeMatch(uri, rule.AllowedScheme) &&\n               IsHostMatch(uri, rule.AllowedHost) &&\n               IsPortMatch(uri, rule.AllowedPort) &&\n               IsPathMatch(uri, rule.AllowedPath) &&\n               IsQueryMatch(uri, rule.AllowedQuery) &&\n               IsFragmentMatch(uri, rule.AllowedFragment);\n    }\n\n    public bool IsSchemeMatch(Uri uri, Scheme allowedScheme)\n    {\n        return allowedScheme == Scheme.Any || uri.Scheme.Equals(allowedScheme.Name, StringComparison.OrdinalIgnoreCase);\n    }\n\n    public bool IsHostMatch(string url, Host allowedHost)\n    {\n        if (string.IsNullOrWhiteSpace(url))\n        {\n            return false;\n        }\n\n        if (allowedHost == Host.Any)\n        {\n            return true;\n        }\n\n        // Check if URL already has a valid scheme; if not, prepend \"http://\" as a default\n        if (!url.StartsWith(\"http://\", StringComparison.OrdinalIgnoreCase) &&\n            !url.StartsWith(\"https://\", StringComparison.OrdinalIgnoreCase))\n        {\n            url = \"http://\" + url;\n        }\n\n        // Attempt to parse the URL into a Uri object\n        if (Uri.TryCreate(url, UriKind.Absolute, out var uri))\n        {\n            // Delegate to the existing IsHostMatch method that takes a Uri object\n            return IsHostMatch(uri, allowedHost);\n        }\n        else\n        {\n            // Log error or handle invalid URL format as needed\n            return false;\n        }\n    }\n\n\n    public bool IsHostMatch(Uri uri, Host allowedHost)\n    {\n        // Handle the case where any host is allowed\n        if (allowedHost == Host.Any)\n        {\n            return true;\n        }\n\n        string uriHost = uri.Host;\n        string allowedHostValue = allowedHost.Value;\n\n        // Direct match or wildcard match\n        if (uriHost.Equals(allowedHostValue, StringComparison.OrdinalIgnoreCase) ||\n            allowedHostValue == \"*\")\n        {\n            return true;\n        }\n\n        // Check for wildcard subdomain match\n        if (allowedHostValue.StartsWith(\"*.\"))\n        {\n            string allowedDomain = allowedHostValue.Substring(2);\n            if (uriHost.EndsWith(allowedDomain, StringComparison.OrdinalIgnoreCase) &&\n                // Additional check to ensure we're matching subdomains and not just any part of the host\n                (uriHost.Count(c => c == '.') == allowedDomain.Count(c => c == '.') + 1))\n            {\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    public bool IsPortMatch(Uri uri, Port allowedPort)\n    {\n        return allowedPort == Port.Any || uri.Port == allowedPort.Value;\n    }\n\n    public bool IsPathMatch(Uri uri, Path allowedPath)\n    {\n        return allowedPath == Path.Any || uri.AbsolutePath.Equals(allowedPath.Value, StringComparison.OrdinalIgnoreCase);\n    }\n\n    public bool IsQueryMatch(Uri uri, Query allowedQuery)\n    {\n        return allowedQuery == Query.Any || uri.Query.Equals(allowedQuery.Value, StringComparison.OrdinalIgnoreCase);\n    }\n\n    public bool IsFragmentMatch(Uri uri, Fragment allowedFragment)\n    {\n        return allowedFragment == Fragment.Any || uri.Fragment.Equals(allowedFragment.Value, StringComparison.OrdinalIgnoreCase);\n    }\n\n}\n\n\npublic class RedirectUrlValidator\n{\n    private readonly IRedirectService _redirectService;\n\n    public RedirectUrlValidator(IRedirectService redirectService)\n    {\n        _redirectService = redirectService;\n    }\n\n    public bool IsRedirectUrlValid(string redirectUrl)\n    {\n        return _redirectService.IsRedirectAllowed(redirectUrl);\n    }\n}\n"
  },
  {
    "path": "src/Security/IdentityServer8.Security/RedirectUrlParser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Security;\n\npublic readonly ref struct RedirectUrlS\n{\n    private readonly ReadOnlySpan<char> _input;\n\n    public RedirectUrlS(string input)\n    {\n        _input = input.AsSpan();\n    }\n\n    //public RedirectUrlS Parse()\n    //{\n    //    // Default values representing wildcards\n    //    var scheme = Scheme.Any;\n    //    var host = Host.Any;\n    //    var port = Port.Any;\n    //    var path = Path.Any;\n    //    var query = Query.Any;\n    //    var fragment = Fragment.Any;\n    //    int offset = 0;\n    //    int schemeEnd = _input.IndexOf(\"://\");\n    //    if (schemeEnd != -1)\n    //    {\n    //        scheme = new Scheme(_input.Slice(0, schemeEnd).ToString());\n    //        offset = schemeEnd + 3;\n    //    }\n\n    //    int pathStart = _input.IndexOf('/');\n    //    int portEnd = _input.Slice(0, pathStart != -1 ? pathStart : _input.Length).IndexOf(':');\n\n    //    if (portEnd != -1)\n    //    {\n    //        host = new Host(_input.Slice(0, portEnd).ToString());\n    //        port = new Port(int.Parse(_input.Slice(portEnd + 1, pathStart - portEnd - 1).ToString()));\n    //    }\n    //    else if (pathStart != -1)\n    //    {\n    //        host = new Host(_input.Slice(0, pathStart).ToString());\n    //    }\n    //    else\n    //    {\n    //        host = new Host(_input.ToString());\n    //    }\n\n    //    if (pathStart != -1)\n    //    {\n    //        offset = pathStart;\n    //        int queryStart = _input.IndexOf('?');\n    //        int fragmentStart = _input.IndexOf('#');\n\n    //        if (queryStart != -1)\n    //        {\n    //            path = new Path(_input.Slice(0, queryStart).ToString());\n    //            offset = queryStart + 1;\n\n\n    //            if (fragmentStart != -1)\n    //            {\n    //                query = new Query(_input.Slice(0, fragmentStart - queryStart - 1).ToString());\n    //                fragment = new Fragment(_input.Slice(fragmentStart + 1).ToString());\n    //            }\n    //            else\n    //            {\n    //                query = new Query(_input.ToString());\n    //            }\n    //        }\n    //        else if (fragmentStart != -1)\n    //        {\n    //            path = new Path(_input.Slice(0, fragmentStart).ToString());\n    //            fragment = new Fragment(_input.Slice(fragmentStart + 1).ToString());\n    //        }\n    //        else\n    //        {\n    //            path = new Path(_input.ToString());\n    //        }\n    //    }\n\n    //    return new RedirectUrl\n    //    {\n    //        Scheme = scheme,\n    //        Host = host,\n    //        Port = port,\n    //        Path = path,\n    //        Query = query,\n    //        Fragment = fragment\n    //    };\n    //}\n}\n\npublic class RedirectUrlParser\n{\n    public static UrlParts Parse(string redirectUrl)\n    {\n        // extract scheme, host, port, path, query, and fragment from the redirectUrl\n        // and return a RedirectUrl object\n        // expand: example.com to *://**.example.com:*/**?**#*\n        // expand: example.com/path to *://**.example.com:*/path?**#*\n        // expand: example.com/* to *://**.example.com:*/**?**#*\n        // expand: example.com/path/* to *://**.example.com:*/path/*?**#*\n        // expand: example.com/path/** to *://**.example.com:*/path/**?**#*\n        // expand: example.com/path/1/* to *://**.example.com:*/path/1/*?query#fragment\n        // expand: example.com/path/1/** to *://**.example.com:*/path/1/**?query#fragment\n        // expand: example.com/path/** to *://**.example.com:*/path/**?**#*\n        // expand: example.com/path/1/path/2?quru to *://**.example.com:*/path?query#fragment\n\n        var schemeParts = redirectUrl.Split(\"://\");\n        var originalScheme = schemeParts.Length == 1 ? \"\" : schemeParts[0];\n        var scheme = schemeParts.Length == 1 ? Scheme.Any : Scheme.Parse(schemeParts[0]);\n\n\n        var tail = redirectUrl.Substring(schemeParts.Length == 1 ? 0 : schemeParts[0].Length + 3);\n        var idx = tail.IndexOf(\"/\");\n        var hostAndPort = tail.Substring(0, idx);\n        var portDelimiter = hostAndPort.IndexOf(\":\");\n        var host = portDelimiter > 0 ? hostAndPort.Substring(0, portDelimiter) : hostAndPort;\n        var port = portDelimiter > 0 ? hostAndPort.Substring(portDelimiter + 1) : \"\";\n        int portNumber = 0;\n        if(int.TryParse(port, out var parsedPort))\n        {\n            portNumber = parsedPort;\n        }\n        else\n        {\n            //TODO: Modify port to accept wildcards, multiple ports, and ranges\n            //port = \"\";\n        }\n        var domainParts = host.Split(\".\");\n\n        var absolutePath = idx > -1 ? tail.Substring(idx) : \"\";\n        var pathParts = absolutePath.Split(\"?\");\n        var path = pathParts[0];\n        var query = pathParts.Length == 1 ? \"\" : pathParts[1];\n        var queryParts = query.Split(\"#\");\n        var queryString = queryParts[0];\n        var queryStringParts = queryString.Split(\"&\");\n\n        var fragment = queryParts.Length == 1 ? \"\" : queryParts[1];\n        var fragmentParts = fragment.Split(\"#\");\n\n        return new UrlParts\n        {\n\n            Scheme = scheme,\n            Host = Host.Create(host),\n            Port = Port.Create(portNumber),\n            Path = Path.Create(path),\n            Query = Query.Create(queryString),\n            Fragment = Fragment.Create(fragment)\n        };\n\n    }\n\n}\npublic class UrlParts\n{\n    public UrlParts()\n    {\n        Scheme= Scheme.Any;\n        Host = Host.Any;\n        Port = Port.Any;\n        Path = Path.Any;\n        Query = Query.Any;\n        Fragment = Fragment.Any;\n\n    }\n    public UrlParts(Scheme scheme, Host host, Port port, Path path, Query query, Fragment fragment)\n    {\n        Scheme = scheme;\n        Host = host;\n        Port = port;\n        Path = path;\n        Query = query;\n        Fragment = fragment;\n    }\n    public Scheme Scheme { get; set; }\n    public Host Host { get; set; }\n    public Port Port { get; set; }\n    public Path Path { get; set; }\n    public Query Query { get; set; }\n    public Fragment Fragment { get; set; }\n}\n"
  },
  {
    "path": "src/Security/IdentityServer8.Security/RedirectUrlServiceExtensions.cs",
    "content": "﻿/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\n\npublic static class RedirectUrlServiceExtensions\n{\n    public static bool IsAllowedRedirect(this string redirectUrl)\n    {\n        return Ioc.RedirectService.IsRedirectAllowed(redirectUrl);\n    }\n    public static bool IsAllowedRedirect(this Uri uri)\n    {\n        return Ioc.RedirectService.IsRedirectAllowed(uri.ToString());\n    }\n\n    public static void RedirectIfAllowed(this HttpResponse response, string url)\n    {\n        if (IsAllowedRedirect(url))\n            response.Redirect(url.SanitizeForRedirect());\n        else\n            SetRedirectNotAllowed(response);\n    }\n\n    public static void SetRedirectNotAllowed(this HttpResponse response)\n    {\n        response.StatusCode = (int) HttpStatusCode.Forbidden;\n    }\n\n    public static void SetRedirectNotAllowed(this HttpContext ctx)\n    {\n        ctx.Response.SetRedirectNotAllowed();\n    }\n\n}\n"
  },
  {
    "path": "src/Security/IdentityServer8.Security/Sanitizer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Security;\n\npublic enum SanitizerType\n{\n    Unknown = 0,\n    HtmlSanitizer,\n    XmlSanitizer,\n    JsonSanitizer,\n    UrlSanitizer,\n    CssSanitizer,\n    ScriptSanitizer,\n    StyleSanitizer,\n    SqlSanitizer,\n    LogSanitizer\n}\npublic enum SanitizerMode\n{\n    Debug,\n    Clean,\n    Mask,\n    Full\n}\npublic interface IInputSanitizer\n{\n    public string? Sanitize(string? input, SanitizerMode mode = SanitizerMode.Clean);\n}\npublic interface ISanitizerFactory\n{\n    TSanitizer Create<TSanitizer>()\n        where TSanitizer : IInputSanitizer;\n\n    IInputSanitizer Create(SanitizerType type);\n}\npublic interface IHtmlSanitizer : IInputSanitizer\n{\n}\npublic interface IXmlSanitizer : IInputSanitizer\n{\n}\npublic interface IJsonSanitizer : IInputSanitizer\n{\n}\npublic interface IUrlSanitizer : IInputSanitizer\n{\n}\npublic interface ICssSanitizer : IInputSanitizer\n{\n}\npublic interface IScriptSanitizer : IInputSanitizer\n{\n}\npublic interface IStyleSanitizer : IInputSanitizer\n{\n}\npublic interface ISqlSanitizer : IInputSanitizer\n{\n}\npublic interface ILogSanitizer : IInputSanitizer\n{\n}\n\npublic interface ISanitizerService\n{\n    string? Sanitize(string? input, SanitizerType type, SanitizerMode mode);\n}\n\npublic abstract class SanitizerServiceBase : ISanitizerService\n{\n    public abstract string? Sanitize(string? input, SanitizerType type, SanitizerMode mode);\n}\npublic class SanitizerService : SanitizerServiceBase\n{\n    private readonly ISanitizerFactory _sanitizerFactory;\n\n    public SanitizerService(ISanitizerFactory sanitizerFactory)\n    {\n        _sanitizerFactory = sanitizerFactory;\n    }\n    public override string? Sanitize(string? input, SanitizerType type, SanitizerMode mode)\n    {\n        var sanitizer = _sanitizerFactory.Create(type);\n        return sanitizer.Sanitize(input, mode);\n    }\n\n\n}\n\npublic class SanitizerBase : IInputSanitizer\n{\n    private Func<string?, string?> _sanitize;\n\n    public SanitizerBase() : this(HttpUtility.HtmlEncode)\n    {\n    }\n\n    public SanitizerBase(Func<string?, string?> sanitizer)\n    {\n        _sanitize = sanitizer;\n    }\n\n    public virtual string? Sanitize(string? input, SanitizerMode mode = SanitizerMode.Debug)\n    {\n        switch (mode)\n        {\n            case SanitizerMode.Debug:\n                return input;\n            case SanitizerMode.Clean:\n                return Clean(input);\n            case SanitizerMode.Mask:\n            case SanitizerMode.Full:\n                var result = _sanitize(input) ?? \"\";\n                switch (mode)\n                {\n                    case SanitizerMode.Mask:\n                        return Mask(result);\n                    case SanitizerMode.Full:\n                        return result;\n                    default:\n                        throw new NotImplementedException();\n                }\n            default:\n                throw new NotImplementedException();\n        }\n    }\n\n\n    public string? Mask(string? input, int unmaskedChars = 4, bool unmaskFirst = false)\n    {\n        if (string.IsNullOrEmpty(input))\n            return input;\n        if (unmaskedChars == 0)\n        {\n            return \"********\";\n        }\n\n        input = Clean(input);\n        if (input.Length <= unmaskedChars)\n        {\n            return new string('*', input.Length);\n        }\n        else if (unmaskFirst)\n        {\n            return input.Substring(0, unmaskedChars) + new string('*', input.Length - unmaskedChars);\n        }\n        else\n        {\n            return new string('*', input.Length - unmaskedChars) + input.Substring(input.Length - unmaskedChars);\n        }\n    }\n\n    public string Clean(string? input)\n    {\n        input = input ?? string.Empty;\n        input = input.Replace(\"\\r\", \" \").Replace(\"\\n\", \" \");\n        var idx = input.IndexOf(\"  \");\n        while (idx > -1)\n        {\n            input = input.Replace(\"  \", \" \");\n            idx = input.IndexOf(\"  \");\n        }\n        input = _sanitize(input) ?? \"\";\n\n        //unescape ' and \" and space\n        input = input.Replace(\"&#39;\", \"'\");\n        input = input.Replace(\"&#34;\", \"\\\"\");\n        input = input.Replace(\"&#20;\", \" \");\n        input = input.Replace(\"&apos;\", \"'\");\n        input = input.Replace(\"&quot;\", \"\\\"\");\n        input = input.Replace(\"&nbsp;\", \" \");\n\n\n\n        return input.Trim() ?? \"\";\n    }\n}\n\n\npublic class HtmlSanitizer : SanitizerBase, IHtmlSanitizer\n{\n    public HtmlSanitizer() : base()\n    {\n\n    }\n}\npublic class XmlSanitizer : SanitizerBase, IXmlSanitizer\n{\n    public XmlSanitizer() : base(HttpUtility.HtmlEncode)\n    {\n\n    }\n}\npublic class JsonSanitizer : SanitizerBase, IJsonSanitizer\n{\n    public JsonSanitizer() : base(HttpUtility.JavaScriptStringEncode)\n    {\n\n    }\n\n}\npublic class UrlSanitizer : SanitizerBase, IUrlSanitizer\n{\n    public UrlSanitizer() : base(x => Uri.EscapeUriString(x?.ToString() ?? \"\"))\n    {\n\n    }\n}\npublic class CssSanitizer : SanitizerBase, ICssSanitizer\n{\n    public CssSanitizer() : base()\n    {\n\n    }\n}\npublic class ScriptSanitizer : SanitizerBase, IScriptSanitizer\n{\n    public ScriptSanitizer() : base(x => Uri.EscapeDataString(x?.ToString() ?? \"\"))\n    {\n\n    }\n}\npublic class StyleSanitizer : SanitizerBase, IStyleSanitizer\n{\n    public StyleSanitizer() : base()\n    {\n\n    }\n}\npublic class SqlSanitizer : SanitizerBase, ISqlSanitizer\n{\n    public SqlSanitizer() : base()\n    {\n\n    }\n}\npublic class LogSanitizer : SanitizerBase, ILogSanitizer\n{\n    public LogSanitizer() : base(HttpUtility.HtmlEncode)\n    {\n\n    }\n    public override string? Sanitize(string? input, SanitizerMode mode)\n    {\n        if (input is null)\n            return input;\n\n        switch (mode)\n        {\n            case SanitizerMode.Debug:\n                return base.Mask(input, input.Length);\n            case SanitizerMode.Clean:\n                return base.Clean(input);\n            case SanitizerMode.Mask:\n                return base.Mask(input);\n            case SanitizerMode.Full:\n                return base.Mask(input, 0);\n            default:\n                throw new NotImplementedException();\n        }\n    }\n}\npublic class SanitizerFactory : ISanitizerFactory\n{\n    public TInputSanitizer Create<TInputSanitizer>() where TInputSanitizer : IInputSanitizer\n    {\n\n        var type = Enum.Parse<SanitizerType>(typeof(TInputSanitizer).Name.Substring(1));\n        return (TInputSanitizer) Create(type);\n    }\n\n    public IInputSanitizer Create(SanitizerType type)\n    {\n        switch (type)\n        {\n            case SanitizerType.HtmlSanitizer:\n                return new HtmlSanitizer();\n            case SanitizerType.XmlSanitizer:\n                return new XmlSanitizer();\n            case SanitizerType.JsonSanitizer:\n                return new JsonSanitizer();\n            case SanitizerType.UrlSanitizer:\n                return new UrlSanitizer();\n            case SanitizerType.CssSanitizer:\n                return new CssSanitizer();\n            case SanitizerType.ScriptSanitizer:\n                return new ScriptSanitizer();\n            case SanitizerType.StyleSanitizer:\n                return new StyleSanitizer();\n            case SanitizerType.SqlSanitizer:\n                return new SqlSanitizer();\n            case SanitizerType.LogSanitizer:\n                return new LogSanitizer();\n            default:\n                throw new NotImplementedException();\n        }\n    }\n}\n\npublic interface ISanitizer\n{\n    public IHtmlSanitizer Html { get; }\n    public IXmlSanitizer Xml { get; }\n    public IJsonSanitizer Json { get; }\n    public IUrlSanitizer Url { get; }\n    public ICssSanitizer Css { get; }\n    public IScriptSanitizer Script { get; }\n    public IStyleSanitizer Style { get; }\n    public ISqlSanitizer Sql { get; }\n    public ILogSanitizer Log { get; }\n\n}\npublic class Sanitizer : ISanitizer\n{\n    public Sanitizer(ISanitizerFactory sanitizerFactory)\n    {\n        Html = sanitizerFactory.Create<IHtmlSanitizer>();\n        Xml = sanitizerFactory.Create<IXmlSanitizer>();\n        Json = sanitizerFactory.Create<IJsonSanitizer>();\n        Url = sanitizerFactory.Create<IUrlSanitizer>();\n        Css = sanitizerFactory.Create<ICssSanitizer>();\n        Script = sanitizerFactory.Create<IScriptSanitizer>();\n        Style = sanitizerFactory.Create<IStyleSanitizer>();\n        Sql = sanitizerFactory.Create<ISqlSanitizer>();\n        Log = sanitizerFactory.Create<ILogSanitizer>();\n    }\n\n\n    public IHtmlSanitizer Html { get; }\n    public IXmlSanitizer Xml { get; }\n    public IJsonSanitizer Json { get; }\n    public IUrlSanitizer Url { get; }\n    public ICssSanitizer Css { get; }\n    public IScriptSanitizer Script { get; }\n    public IStyleSanitizer Style { get; }\n    public ISqlSanitizer Sql { get; }\n    public ILogSanitizer Log { get; }\n}\n\n"
  },
  {
    "path": "src/Security/IdentityServer8.Security/SanitizerServiceExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace Microsoft.Extensions.DependencyInjection;\npublic static class SanitizerServiceExtensions\n{\n    public static IServiceCollection AddSanitizers(this IServiceCollection services)\n    {\n        var factory = new SanitizerFactory();\n        services.AddSingleton(factory);\n        services.AddSingleton<ISanitizerFactory>(factory);\n        services.AddSingleton<ISanitizerService, SanitizerService>();\n        services.AddSingleton<ISanitizer, Sanitizer>();\n\n        var props = typeof(ISanitizer).GetProperties();\n        foreach (var prop in props)\n        {\n            var type = Enum.Parse<SanitizerType>(prop.PropertyType.Name.Substring(1));\n            var sanitizer = factory.Create(type);\n            services.AddSingleton(prop.PropertyType, sanitizer);\n            services.AddSingleton(sanitizer);\n        }\n\n        return services;\n    }\n\n    public static string? SanitizeForLog(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Log.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SanitizeForHtml(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Html.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SanitizeForXml(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Xml.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SanitizeForJson(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Json.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string SanitizeForRedirect(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        var rawUrl = input?.ToString() ?? \"\";\n        if (string.IsNullOrEmpty(rawUrl))\n            return rawUrl;\n        else\n        {\n            if (Uri.TryCreate(rawUrl, UriKind.RelativeOrAbsolute, out var uri))\n            {\n                var parsedUrl = uri.ToString();\n                if (parsedUrl == rawUrl.ToString())\n                    return parsedUrl;\n                else\n                {\n                    return uri.ToString().SanitizeForLog() ?? \"\";\n                }\n\n            }\n            else\n            {\n                throw new ArgumentException(\"Invalid URL\", nameof(input));\n            }\n        }\n\n    }\n\n    public static string? SanitizeForUrl(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Url.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SanitizeForCss(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Css.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SanitizeForScript(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Script.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SanitizeForStyle(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Style.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SanitizeForSql(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        return Ioc.Sanitizer.Sql.Sanitize(input?.ToString(), mode);\n    }\n\n    public static string? SantizeForRedirect(this object? input, SanitizerMode mode = SanitizerMode.Clean)\n    {\n        var decoded = Uri.UnescapeDataString(input?.ToString() ?? \"\");\n        decoded.SanitizeForHtml();\n        var escaped = Uri.EscapeDataString(decoded);\n        return escaped;\n    }\n\n}\n"
  },
  {
    "path": "src/Security/test/IdentityServer8.Santizer.Tests/IdentityServer8.Sanitizer.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" />\n    <PackageReference Include=\"xunit\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" />\n    <PackageReference Include=\"FluentAssertions\" />\n     <PackageReference Include=\"Microsoft.Extensions.Logging\" />\n    <PackageReference Include=\"coverlet.collector\" GeneratePathProperty=\"true\">\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n      <PrivateAssets>all</PrivateAssets>\n    </PackageReference>   \n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\IdentityServer8.Security\\IdentityServer8.Security.csproj\" />\n  </ItemGroup>\n  \n  \n\n</Project>\n"
  },
  {
    "path": "src/Security/test/IdentityServer8.Santizer.Tests/RedirectServiceTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing Microsoft.Extensions.DependencyInjection;\nusing Xunit;\n\n\nnamespace IdentityServer8.Security.Tests;\n\npublic class DependencyInjection\n{\n    static DependencyInjection()\n    {\n        var provider = new ServiceCollection()\n            .AddLogging()\n            .AddAllowAnyRedirectService()\n            .AddSingleton<IRedirectService, RedirectService>()\n            .AddSanitizers()\n            .BuildServiceProvider();\n        ServiceProvider = provider;\n\n    }\n\n    public static ServiceProvider ServiceProvider { get; }\n}\n\n\n\npublic class AllowAnyTests \n{\n    private readonly RedirectService _redirectService;\n\n    public AllowAnyTests()\n    {\n        var redirectService = DependencyInjection.ServiceProvider.GetRequiredService<AllowAnyRedirectService>();\n        _redirectService = redirectService;\n    }\n\n\n    [Theory]\n    [InlineData(\"http://example.com\",  true)]\n    [InlineData(\"http://a.example.com\", true)]\n    [InlineData(\"http://a.b.example.com\", true)]\n    [InlineData(\"https://example.com\", true)]\n    [InlineData(\"https://a.example.com\", true)]\n    [InlineData(\"https://a.b.example.com\", true)]\n    [InlineData(\"http://localhost\", true)]\n    [InlineData(\"https://localhost\", true)]\n\n\n\n\n    public void AllowAnyShouldReturnTrue(string uriString, bool expectedResult)\n    {\n        var result = _redirectService.IsRedirectAllowed(uriString);\n\n        Assert.Equal(expectedResult, result);\n    }\n}\npublic class RedirectServiceTests\n{\n    private readonly RedirectService _redirectService;\n\n    public RedirectServiceTests()\n    {\n        var redirectService = DependencyInjection.ServiceProvider.GetService<IRedirectService>();\n        _redirectService = redirectService as RedirectService;\n    }\n\n    [Theory]\n    [InlineData(\"http://example.com\", \"example.com\", true)]\n    [InlineData(\"http://example.com\", \"*\", true)]\n    [InlineData(\"http://example.com\", \"another.com\", false)]\n    [InlineData(\"example.com\", \"example.com\", true)]\n    [InlineData(\"example.com\", \"*\", true)]\n    [InlineData(\"example.com\", \"another.com\", false)]\n    [InlineData(\"*.example.com\", \"example.com\", false)]\n    [InlineData(\"*.example.com\", \"*\", true)]\n    [InlineData(\"*.example.com\", \"another.com\", false)]\n    public void IsHostMatch_ShouldCorrectlyMatchHost(string uriString, string allowedHostName, bool expectedResult)\n    {\n\n        var allowedHost = allowedHostName == \"*\" ? Host.Any : Host.Create(allowedHostName);\n\n        // Assuming IsHostMatch is made internal for testing and accessible here\n        var result = _redirectService.IsHostMatch(uriString, allowedHost);\n\n        Assert.Equal(expectedResult, result);\n    }\n\n    [Fact()]\n    public void RedirectServiceTest()\n    {\n\n    }\n\n    [Fact()]\n    public void AddARedirectRuleTest()\n    {\n\n    }\n\n    [Fact()]\n    public void IsRedirectAllowedTest()\n    {\n\n    }\n}\n"
  },
  {
    "path": "src/Security/test/IdentityServer8.Santizer.Tests/Services/SanitizerTests.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nusing FluentAssertions;\nusing Microsoft.Extensions.DependencyInjection;\nusing System.Diagnostics;\nusing System.Text.Json;\nusing Xunit;\n\nnamespace IdentityServer8.Security.Tests;\n\n\npublic class SanitizerTests\n{\n    public SanitizerTests()\n    {\n\n    }\n\n\n    [Fact]\n    public void SanitizerFactory()\n    {\n        var factory = Ioc.ServiceProvider.GetRequiredService<ISanitizerFactory>();\n        Assert.NotNull(factory);\n    }\n\n    [Fact]\n    public void SanitizerService()\n    {\n        var service = Ioc.ServiceProvider.GetRequiredService<ISanitizerService>();\n        Assert.NotNull(service);\n    }\n    [Fact]\n    public void Sanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<ISanitizer>();\n        Assert.NotNull(sanitizer);\n    }\n\n\n    [Fact]\n    public void HtmlSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<IHtmlSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = \"<div><script>alert('xss')</script></div>\";\n        var output = sanitizer.Sanitize(input);\n        var expected = \"&lt;div&gt;&lt;script&gt;alert('xss')&lt;/script&gt;&lt;/div&gt;\";\n\n        Validate(expected, output);\n    }\n    [Fact]\n    public void XmlSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<IXmlSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = \"<div><script>alert('xss')</script></div>\";\n        var output = sanitizer.Sanitize(input);\n        var expected = \"&lt;div&gt;&lt;script&gt;alert('xss')&lt;/script&gt;&lt;/div&gt;\";\n\n        Validate(expected, output);\n    }\n    [Fact]\n    public void JsonSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<IJsonSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = JsonSerializer.Serialize(new { test = \"test\", value = \"<div><script>alert('xss')</script></div>\" });\n        var output = sanitizer.Sanitize(input);\n        var expected = @\"{\\\"\"test\\\"\":\\\"\"test\\\"\",\\\"\"value\\\"\":\\\"\"\\\\u003Cdiv\\\\u003E\\\\u003Cscript\\\\u003Ealert(\\\\u0027xss\\\\u0027)\\\\u003C/script\\\\u003E\\\\u003C/div\\\\u003E\\\"\"}\";\n\n\n        Validate(expected, output);\n    }\n    [Fact]\n    public void UrlSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<IUrlSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = \"http://test.com?test=<div><script>alert('xss')</script></div>\";\n        var output = sanitizer.Sanitize(input);\n        var expected = \"http://test.com?test=%3Cdiv%3E%3Cscript%3Ealert('xss')%3C/script%3E%3C/div%3E\";\n\n        Validate(expected, output);\n    }\n    [Fact]\n    public void CssSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<ICssSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = \"div { background-url('<script>alert('xss')</script>') }\";\n        var output = sanitizer.Sanitize(input);\n        var expected = \"div { background-url('&lt;script&gt;alert('xss')&lt;/script&gt;') }\";\n        Validate(expected, output);\n    }\n    [Fact]\n    public void ScriptSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<IJsonSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = JsonSerializer.Serialize(new { test = \"test\", value = \"<div><script>alert('xss')</script></div>\" });\n        var output = sanitizer.Sanitize(input);\n        var expected = @\"{\\\"\"test\\\"\":\\\"\"test\\\"\",\\\"\"value\\\"\":\\\"\"\\\\u003Cdiv\\\\u003E\\\\u003Cscript\\\\u003Ealert(\\\\u0027xss\\\\u0027)\\\\u003C/script\\\\u003E\\\\u003C/div\\\\u003E\\\"\"}\";\n\n\n        Validate(expected, output);\n    }\n    [Fact]\n    public void StyleSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<IStyleSanitizer>();\n        Assert.NotNull(sanitizer);\n        var input = \"div { background-url('<script>alert('xss')</script>') }\";\n        var output = sanitizer.Sanitize(input);\n        var expected = \"div { background-url('&lt;script&gt;alert('xss')&lt;/script&gt;') }\";\n\n        Validate(expected, output);\n    }\n    [Fact]\n    public void SqlSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<ISqlSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = \"update table set value='<script>alert('xss')</script>' where 1=1;\";\n        var output = sanitizer.Sanitize(input);\n        var expected = \"update table set value='&lt;script&gt;alert('xss')&lt;/script&gt;' where 1=1;\";\n\n        Validate(expected, output);\n    }\n    [Fact]\n    public void LogSanitizer()\n    {\n        var sanitizer = Ioc.ServiceProvider.GetRequiredService<ILogSanitizer>();\n        Assert.NotNull(sanitizer);\n\n        var input = @\"log\npoisoning\ntest\n\n<script>alert('xss')</script>\n\";\n        var output = sanitizer.Sanitize(input);\n\n\n        var expected = \"log poisoning test &lt;script&gt;alert('xss')&lt;/script&gt;\";\n        Validate(expected, output);\n\n\n        output = sanitizer.Sanitize(\"mypassword\", SanitizerMode.Mask);\n        expected = \"******word\";\n        Validate(expected, output);\n\n\n        output = sanitizer.Sanitize(\"mypassword\", SanitizerMode.Full);\n        expected = \"********\";\n        Validate(expected, output);\n\n    }\n\n    void Validate(string expected, string output)\n    {\n        Console.WriteLine(\"Expected: \" + expected);\n        Console.WriteLine(\"Output: \" + output);\n        Debug.WriteLine(\"Expected: \" + expected);\n        Debug.WriteLine(\"Output: \" + output);\n        output.Should().Be(expected);\n    }\n\n    private void Log(string expected, string output)\n    {\n        Console.WriteLine(\"Expected: \" + expected);\n        Console.WriteLine(\"Output: \" + output);\n        Debug.WriteLine(\"Expected: \" + expected);\n        Debug.WriteLine(\"Output: \" + output);\n    }\n}\n"
  },
  {
    "path": "src/Storage/Directory.Build.props",
    "content": "<Project>\n  <ImportGroup>\n\t <Import Project=\"../Directory.Build.props\" />\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "src/Storage/IdentityServer8.Storage.sln",
    "content": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26124.0\nMinimumVisualStudioVersion = 15.0.26124.0\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{2EEC146C-3C96-4871-BBAF-8341719BD533}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"IdentityServer8.Storage\", \"src\\IdentityServer8.Storage.csproj\", \"{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|Any CPU = Release|Any CPU\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|x64.ActiveCfg = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|x64.Build.0 = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|x86.ActiveCfg = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Debug|x86.Build.0 = Debug|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|x64.ActiveCfg = Release|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|x64.Build.0 = Release|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|x86.ActiveCfg = Release|Any CPU\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7}.Release|x86.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{A5E2B0DD-9C88-42B5-BCEC-7ED701504FF7} = {2EEC146C-3C96-4871-BBAF-8341719BD533}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {AFF22F24-FEA5-4A1D-AFE6-942789486D59}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/Storage/README.md",
    "content": "# IdentityServer8.Storage\n\nIdentityServer8.Storage contains all the models and storage interfaces for IdentityServer 4 configuration data."
  },
  {
    "path": "src/Storage/build/Program.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace build\n{\n    partial class Program\n    {\n        private const string Prefix = \"Storage\";\n    }\n}\n"
  },
  {
    "path": "src/Storage/build/build.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Include=\"..\\..\\build\\Program.Partial.cs\" Link=\"Program.Partial.cs\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Bullseye\" />\n    <PackageReference Include=\"SimpleExec\" />\n  </ItemGroup>\n  \n</Project>\n"
  },
  {
    "path": "src/Storage/build.cmd",
    "content": "@echo off\ndotnet run --project build -- %*"
  },
  {
    "path": "src/Storage/build.ps1",
    "content": "$ErrorActionPreference = \"Stop\";\ndotnet run --project build -- $args"
  },
  {
    "path": "src/Storage/build.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\ndotnet run --project build -- \"$@\""
  },
  {
    "path": "src/Storage/src/Constants.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8;\n\ninternal static class Constants\n{\n    public const string IdentityServerName               = \"IdentityServer8\";\n    public const string IdentityServerAuthenticationType = IdentityServerName;\n}\n"
  },
  {
    "path": "src/Storage/src/Extensions/IEnumerableExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Extensions;\n\ninternal static class IEnumerableExtensions\n{\n    [DebuggerStepThrough]\n    public static bool IsNullOrEmpty<T>(this IEnumerable<T> list)\n    {\n        if (list == null)\n        {\n            return true;\n        }\n\n        if (!list.Any())\n        {\n            return true;\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Extensions/PersistedGrantFilterExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\n/// <summary>\n/// Extensions for PersistedGrantFilter.\n/// </summary>\npublic static class PersistedGrantFilterExtensions\n{\n    /// <summary>\n    /// Validates the PersistedGrantFilter and throws if invalid.\n    /// </summary>\n    /// <param name=\"filter\"></param>\n    public static void Validate(this PersistedGrantFilter filter)\n    {\n        if (filter == null) throw new ArgumentNullException(nameof(filter));\n\n        if (String.IsNullOrWhiteSpace(filter.ClientId) &&\n            String.IsNullOrWhiteSpace(filter.SessionId) &&\n            String.IsNullOrWhiteSpace(filter.SubjectId) &&\n            String.IsNullOrWhiteSpace(filter.Type))\n        {\n            throw new ArgumentException(\"No filter values set.\", nameof(filter));\n        }\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Extensions/StringsExtensions.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Extensions;\n\ninternal static class StringExtensions\n{\n    [DebuggerStepThrough]\n    public static bool IsMissing(this string value)\n    {\n        return string.IsNullOrWhiteSpace(value);\n    }\n\n    [DebuggerStepThrough]\n    public static bool IsPresent(this string value)\n    {\n        return !string.IsNullOrWhiteSpace(value);\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/GlobalUsings.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nglobal using IdentityModel;\nglobal using IdentityServer8.Extensions;\nglobal using IdentityServer8.Models;\nglobal using IdentityServer8.Stores;\nglobal using Newtonsoft.Json;\nglobal using Newtonsoft.Json.Serialization;\nglobal using System.Collections;\nglobal using System.Diagnostics;\nglobal using System.Security.Claims;\n"
  },
  {
    "path": "src/Storage/src/IdentityServer8.Storage.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n    <PropertyGroup>\n\n        <Description>Storage interfaces and models for IdentityServer8</Description>\n        <IsPackable>true</IsPackable>\n        <GeneratePackageOnBuild>True</GeneratePackageOnBuild>\n    </PropertyGroup>\n\n    <PropertyGroup>\n        <ContinuousIntegrationBuild Condition=\"'$(TF_BUILD)' == 'true'\">True</ContinuousIntegrationBuild>\n        <ContinuousIntegrationBuild Condition=\"'$(GITHUB_ACTIONS)' == 'true'\">True</ContinuousIntegrationBuild>\n\n    </PropertyGroup>\n\n    <ItemGroup>\n      <None Include=\"..\\..\\..\\icon.jpg\">\n        <Pack>True</Pack>\n        <PackagePath>\\</PackagePath>\n      </None>\n    </ItemGroup>\n\n\n    <ItemGroup>\n        <PackageReference Include=\"IdentityModel\" />\n        <PackageReference Include=\"Newtonsoft.Json\" />\n    </ItemGroup>\n\n</Project>"
  },
  {
    "path": "src/Storage/src/IdentityServerConstants.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8;\n\ninternal static class IdentityServerConstants\n{\n    public static class ProtocolTypes\n    {\n        public const string OpenIdConnect = \"oidc\";\n    }\n\n    public static class SecretTypes\n    {\n        public const string SharedSecret = \"SharedSecret\";\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/IdentityServerUser.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8;\n\n/// <summary>\n/// Model properties of an IdentityServer user\n/// </summary>\ninternal class IdentityServerUser\n{\n    /// <summary>\n    /// Subject ID (mandatory)\n    /// </summary>\n    public string SubjectId { get; }\n\n    /// <summary>\n    /// Display name (optional)\n    /// </summary>\n    public string DisplayName { get; set; }\n\n    /// <summary>\n    /// Identity provider (optional)\n    /// </summary>\n    public string IdentityProvider { get; set; }\n\n    /// <summary>\n    /// Authentication methods\n    /// </summary>\n    public ICollection<string> AuthenticationMethods { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Authentication time\n    /// </summary>\n    public DateTime? AuthenticationTime { get; set; }\n\n    /// <summary>\n    /// Additional claims\n    /// </summary>\n    public ICollection<Claim> AdditionalClaims { get; set; } = new HashSet<Claim>(new ClaimComparer());\n\n    /// <summary>\n    /// Initializes a user identity\n    /// </summary>\n    /// <param name=\"subjectId\">The subject ID</param>\n    public IdentityServerUser(string subjectId)\n    {\n        if (subjectId.IsMissing()) throw new ArgumentException(\"SubjectId is mandatory\", nameof(subjectId));\n\n        SubjectId = subjectId;\n    }\n\n    /// <summary>\n    /// Creates an IdentityServer claims principal\n    /// </summary>\n    /// <returns></returns>\n    /// <exception cref=\"ArgumentNullException\"></exception>\n    public ClaimsPrincipal CreatePrincipal()\n    {\n        if (SubjectId.IsMissing()) throw new ArgumentException(\"SubjectId is mandatory\", nameof(SubjectId));\n        var claims = new List<Claim> { new Claim(JwtClaimTypes.Subject, SubjectId) };\n\n        if (DisplayName.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.Name, DisplayName));\n        }\n\n        if (IdentityProvider.IsPresent())\n        {\n            claims.Add(new Claim(JwtClaimTypes.IdentityProvider, IdentityProvider));\n        }\n\n        if (AuthenticationTime.HasValue)\n        {\n            claims.Add(new Claim(JwtClaimTypes.AuthenticationTime, new DateTimeOffset(AuthenticationTime.Value).ToUnixTimeSeconds().ToString()));\n        }\n\n        if (AuthenticationMethods.Any())\n        {\n            foreach (var amr in AuthenticationMethods)\n            {\n                claims.Add(new Claim(JwtClaimTypes.AuthenticationMethod, amr));\n            }\n        }\n\n        claims.AddRange(AdditionalClaims);\n\n        var id = new ClaimsIdentity(claims.Distinct(new ClaimComparer()), Constants.IdentityServerAuthenticationType, JwtClaimTypes.Name, JwtClaimTypes.Role);\n        return new ClaimsPrincipal(id);\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Models/ApiResource.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models a web API resource.\n/// </summary>\n[DebuggerDisplay(\"{\" + nameof(DebuggerDisplay) + \",nq}\")]\npublic class ApiResource : Resource\n{\n    private string DebuggerDisplay => Name ?? $\"{{{typeof(ApiResource)}}}\";\n    \n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiResource\"/> class.\n    /// </summary>\n    public ApiResource()\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiResource\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    public ApiResource(string name)\n        : this(name, name, null)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiResource\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"displayName\">The display name.</param>\n    public ApiResource(string name, string displayName)\n        : this(name, displayName, null)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiResource\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"userClaims\">List of associated user claims that should be included when this resource is requested.</param>\n    public ApiResource(string name, IEnumerable<string> userClaims)\n        : this(name, name, userClaims)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiResource\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"displayName\">The display name.</param>\n    /// <param name=\"userClaims\">List of associated user claims that should be included when this resource is requested.</param>\n    /// <exception cref=\"System.ArgumentNullException\">name</exception>\n    public ApiResource(string name, string displayName, IEnumerable<string> userClaims)\n    {\n        if (name.IsMissing()) throw new ArgumentNullException(nameof(name));\n\n        Name = name;\n        DisplayName = displayName;\n\n        if (!userClaims.IsNullOrEmpty())\n        {\n            foreach (var type in userClaims)\n            {\n                UserClaims.Add(type);\n            }\n        }\n    }\n\n    /// <summary>\n    /// The API secret is used for the introspection endpoint. The API can authenticate with introspection using the API name and secret.\n    /// </summary>\n    public ICollection<Secret> ApiSecrets { get; set; } = new HashSet<Secret>();\n\n    /// <summary>\n    /// Models the scopes this API resource allows.\n    /// </summary>\n    public ICollection<string> Scopes { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Signing algorithm for access token. If empty, will use the server default signing algorithm.\n    /// </summary>\n    public ICollection<string> AllowedAccessTokenSigningAlgorithms { get; set; } = new HashSet<string>();\n}\n"
  },
  {
    "path": "src/Storage/src/Models/ApiScope.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models access to an API scope\n/// </summary>\n[DebuggerDisplay(\"{\" + nameof(DebuggerDisplay) + \",nq}\")]\npublic class ApiScope : Resource\n{\n    private string DebuggerDisplay => Name ?? $\"{{{typeof(ApiScope)}}}\";\n    \n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiScope\"/> class.\n    /// </summary>\n    public ApiScope()\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiScope\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    public ApiScope(string name)\n        : this(name, name, null)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiScope\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"displayName\">The display name.</param>\n    public ApiScope(string name, string displayName)\n        : this(name, displayName, null)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiScope\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"userClaims\">List of associated user claims that should be included when this resource is requested.</param>\n    public ApiScope(string name, IEnumerable<string> userClaims)\n        : this(name, name, userClaims)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"ApiScope\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"displayName\">The display name.</param>\n    /// <param name=\"userClaims\">List of associated user claims that should be included when this resource is requested.</param>\n    /// <exception cref=\"System.ArgumentNullException\">name</exception>\n    public ApiScope(string name, string displayName, IEnumerable<string> userClaims)\n    {\n        if (name.IsMissing()) throw new ArgumentNullException(nameof(name));\n\n        Name = name;\n        DisplayName = displayName;\n\n        if (!userClaims.IsNullOrEmpty())\n        {\n            foreach (var type in userClaims)\n            {\n                UserClaims.Add(type);\n            }\n        }\n    }\n\n    /// <summary>\n    /// Specifies whether the user can de-select the scope on the consent screen. Defaults to false.\n    /// </summary>\n    public bool Required { get; set; } = false;\n\n    /// <summary>\n    /// Specifies whether the consent screen will emphasize this scope. Use this setting for sensitive or important scopes. Defaults to false.\n    /// </summary>\n    public bool Emphasize { get; set; } = false;\n}\n"
  },
  {
    "path": "src/Storage/src/Models/AuthorizationCode.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models an authorization code.\n/// </summary>\npublic class AuthorizationCode\n{\n    /// <summary>\n    /// Gets or sets the creation time.\n    /// </summary>\n    /// <value>\n    /// The creation time.\n    /// </value>\n    public DateTime CreationTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the life time in seconds.\n    /// </summary>\n    /// <value>\n    /// The life time.\n    /// </value>\n    public int Lifetime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the ID of the client.\n    /// </summary>\n    /// <value>\n    /// The ID of the client.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether this code is an OpenID Connect code.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if this instance is open identifier; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsOpenId { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the requested scopes.\n    /// </summary>\n    /// <value>\n    /// The requested scopes.\n    /// </value>\n    // todo: brock, change to parsed scopes\n    public IEnumerable<string> RequestedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the redirect URI.\n    /// </summary>\n    /// <value>\n    /// The redirect URI.\n    /// </value>\n    public string RedirectUri { get; set; }\n\n    /// <summary>\n    /// Gets or sets the nonce.\n    /// </summary>\n    /// <value>\n    /// The nonce.\n    /// </value>\n    public string Nonce { get; set; }\n\n    /// <summary>\n    /// Gets or sets the hashed state (to output s_hash claim).\n    /// </summary>\n    /// <value>\n    /// The hashed state.\n    /// </value>\n    public string StateHash { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether consent was shown.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if consent was shown; otherwise, <c>false</c>.\n    /// </value>\n    public bool WasConsentShown { get; set; }\n\n    /// <summary>\n    /// Gets or sets the session identifier.\n    /// </summary>\n    /// <value>\n    /// The session identifier.\n    /// </value>\n    public string SessionId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the code challenge.\n    /// </summary>\n    /// <value>\n    /// The code challenge.\n    /// </value>\n    public string CodeChallenge { get; set; }\n\n    /// <summary>\n    /// Gets or sets the code challenge method.\n    /// </summary>\n    /// <value>\n    /// The code challenge method\n    /// </value>\n    public string CodeChallengeMethod { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Gets or sets properties\n    /// </summary>\n    /// <value>\n    /// The properties\n    /// </value>\n    public IDictionary<string, string> Properties { get; set; } = new Dictionary<string, string>();\n}\n"
  },
  {
    "path": "src/Storage/src/Models/Client.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models an OpenID Connect or OAuth2 client\n/// </summary>\n[DebuggerDisplay(\"{\" + nameof(DebuggerDisplay) + \",nq}\")]\npublic class Client\n{\n    // setting grant types should be atomic\n    private ICollection<string> _allowedGrantTypes = new GrantTypeValidatingHashSet();\n\n    private string DebuggerDisplay => ClientId ?? $\"{{{typeof(Client)}}}\";\n\n    /// <summary>\n    /// Specifies if client is enabled (defaults to <c>true</c>)\n    /// </summary>\n    public bool Enabled { get; set; } = true;\n\n    /// <summary>\n    /// Unique ID of the client\n    /// </summary>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the protocol type.\n    /// </summary>\n    /// <value>\n    /// The protocol type.\n    /// </value>\n    public string ProtocolType { get; set; } = IdentityServerConstants.ProtocolTypes.OpenIdConnect;\n\n    /// <summary>\n    /// Client secrets - only relevant for flows that require a secret\n    /// </summary>\n    public ICollection<Secret> ClientSecrets { get; set; } = new HashSet<Secret>();\n\n    /// <summary>\n    /// If set to false, no client secret is needed to request tokens at the token endpoint (defaults to <c>true</c>)\n    /// </summary>\n    public bool RequireClientSecret { get; set; } = true;\n\n    /// <summary>\n    /// Client display name (used for logging and consent screen)\n    /// </summary>\n    public string ClientName { get; set; }\n\n    /// <summary>\n    /// Description of the client.\n    /// </summary>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// URI to further information about client (used on consent screen)\n    /// </summary>\n    public string ClientUri { get; set; }\n\n    /// <summary>\n    /// URI to client logo (used on consent screen)\n    /// </summary>\n    public string LogoUri { get; set; }\n\n    /// <summary>\n    /// Specifies whether a consent screen is required (defaults to <c>false</c>)\n    /// </summary>\n    public bool RequireConsent { get; set; } = false;\n\n    /// <summary>\n    /// Specifies whether user can choose to store consent decisions (defaults to <c>true</c>)\n    /// </summary>\n    public bool AllowRememberConsent { get; set; } = true;\n\n    /// <summary>\n    /// Specifies the allowed grant types (legal combinations of AuthorizationCode, Implicit, Hybrid, ResourceOwner, ClientCredentials).\n    /// </summary>\n    public ICollection<string> AllowedGrantTypes\n    {\n        get { return _allowedGrantTypes; }\n        set\n        {\n            ValidateGrantTypes(value);\n            _allowedGrantTypes = new GrantTypeValidatingHashSet(value);\n        }\n    }\n\n    /// <summary>\n    /// Specifies whether a proof key is required for authorization code based token requests (defaults to <c>true</c>).\n    /// </summary>\n    public bool RequirePkce { get; set; } = true;\n\n    /// <summary>\n    /// Specifies whether a proof key can be sent using plain method (not recommended and defaults to <c>false</c>.)\n    /// </summary>\n    public bool AllowPlainTextPkce { get; set; } = false;\n\n    /// <summary>\n    /// Specifies whether the client must use a request object on authorize requests (defaults to <c>false</c>.)\n    /// </summary>\n    public bool RequireRequestObject { get; set; } = false;\n    \n    /// <summary>\n    /// Controls whether access tokens are transmitted via the browser for this client (defaults to <c>false</c>).\n    /// This can prevent accidental leakage of access tokens when multiple response types are allowed.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if access tokens can be transmitted via the browser; otherwise, <c>false</c>.\n    /// </value>\n    public bool AllowAccessTokensViaBrowser { get; set; } = false;\n\n    /// <summary>\n    /// Specifies allowed URIs to return tokens or authorization codes to\n    /// </summary>\n    public ICollection<string> RedirectUris { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Specifies allowed URIs to redirect to after logout\n    /// </summary>\n    public ICollection<string> PostLogoutRedirectUris { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Specifies logout URI at client for HTTP front-channel based logout.\n    /// </summary>\n    public string FrontChannelLogoutUri { get; set; }\n\n    /// <summary>\n    /// Specifies if the user's session id should be sent to the FrontChannelLogoutUri. Defaults to <c>true</c>.\n    /// </summary>\n    public bool FrontChannelLogoutSessionRequired { get; set; } = true;\n\n    /// <summary>\n    /// Specifies logout URI at client for HTTP back-channel based logout.\n    /// </summary>\n    public string BackChannelLogoutUri { get; set; }\n\n    /// <summary>\n    /// Specifies if the user's session id should be sent to the BackChannelLogoutUri. Defaults to <c>true</c>.\n    /// </summary>\n    public bool BackChannelLogoutSessionRequired { get; set; } = true;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether [allow offline access]. Defaults to <c>false</c>.\n    /// </summary>\n    public bool AllowOfflineAccess { get; set; } = false;\n\n    /// <summary>\n    /// Specifies the api scopes that the client is allowed to request. If empty, the client can't access any scope\n    /// </summary>\n    public ICollection<string> AllowedScopes { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// When requesting both an id token and access token, should the user claims always be added to the id token instead of requiring the client to use the userinfo endpoint.\n    /// Defaults to <c>false</c>.\n    /// </summary>\n    public bool AlwaysIncludeUserClaimsInIdToken { get; set; } = false;\n\n    /// <summary>\n    /// Lifetime of identity token in seconds (defaults to 300 seconds / 5 minutes)\n    /// </summary>\n    public int IdentityTokenLifetime { get; set; } = 300;\n\n    /// <summary>\n    /// Signing algorithm for identity token. If empty, will use the server default signing algorithm.\n    /// </summary>\n    public ICollection<string> AllowedIdentityTokenSigningAlgorithms { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Lifetime of access token in seconds (defaults to 3600 seconds / 1 hour)\n    /// </summary>\n    public int AccessTokenLifetime { get; set; } = 3600;\n\n    /// <summary>\n    /// Lifetime of authorization code in seconds (defaults to 300 seconds / 5 minutes)\n    /// </summary>\n    public int AuthorizationCodeLifetime { get; set; } = 300;\n\n    /// <summary>\n    /// Maximum lifetime of a refresh token in seconds. Defaults to 2592000 seconds / 30 days\n    /// </summary>\n    public int AbsoluteRefreshTokenLifetime { get; set; } = 2592000;\n\n    /// <summary>\n    /// Sliding lifetime of a refresh token in seconds. Defaults to 1296000 seconds / 15 days\n    /// </summary>\n    public int SlidingRefreshTokenLifetime { get; set; } = 1296000;\n\n    /// <summary>\n    /// Lifetime of a user consent in seconds. Defaults to null (no expiration)\n    /// </summary>\n    public int? ConsentLifetime { get; set; } = null;\n\n    /// <summary>\n    /// ReUse: the refresh token handle will stay the same when refreshing tokens\n    /// OneTime: the refresh token handle will be updated when refreshing tokens\n    /// </summary>\n    public TokenUsage RefreshTokenUsage { get; set; } = TokenUsage.OneTimeOnly;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the access token (and its claims) should be updated on a refresh token request.\n    /// Defaults to <c>false</c>.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if the token should be updated; otherwise, <c>false</c>.\n    /// </value>\n    public bool UpdateAccessTokenClaimsOnRefresh { get; set; } = false;\n\n    /// <summary>\n    /// Absolute: the refresh token will expire on a fixed point in time (specified by the AbsoluteRefreshTokenLifetime)\n    /// Sliding: when refreshing the token, the lifetime of the refresh token will be renewed (by the amount specified in SlidingRefreshTokenLifetime). The lifetime will not exceed AbsoluteRefreshTokenLifetime.\n    /// </summary>        \n    public TokenExpiration RefreshTokenExpiration { get; set; } = TokenExpiration.Absolute;\n\n    /// <summary>\n    /// Specifies whether the access token is a reference token or a self contained JWT token (defaults to Jwt).\n    /// </summary>\n    public AccessTokenType AccessTokenType { get; set; } = AccessTokenType.Jwt;\n\n    /// <summary>\n    /// Gets or sets a value indicating whether the local login is allowed for this client. Defaults to <c>true</c>.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if local logins are enabled; otherwise, <c>false</c>.\n    /// </value>\n    public bool EnableLocalLogin { get; set; } = true;\n\n    /// <summary>\n    /// Specifies which external IdPs can be used with this client (if list is empty all IdPs are allowed). Defaults to empty.\n    /// </summary>\n    public ICollection<string> IdentityProviderRestrictions { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Gets or sets a value indicating whether JWT access tokens should include an identifier. Defaults to <c>true</c>.\n    /// </summary>\n    /// <value>\n    /// <c>true</c> to add an id; otherwise, <c>false</c>.\n    /// </value>\n    public bool IncludeJwtId { get; set; } = true;\n\n    /// <summary>\n    /// Allows settings claims for the client (will be included in the access token).\n    /// </summary>\n    /// <value>\n    /// The claims.\n    /// </value>\n    public ICollection<ClientClaim> Claims { get; set; } = new HashSet<ClientClaim>();\n\n    /// <summary>\n    /// Gets or sets a value indicating whether client claims should be always included in the access tokens - or only for client credentials flow.\n    /// Defaults to <c>false</c>\n    /// </summary>\n    /// <value>\n    /// <c>true</c> if claims should always be sent; otherwise, <c>false</c>.\n    /// </value>\n    public bool AlwaysSendClientClaims { get; set; } = false;\n\n    /// <summary>\n    /// Gets or sets a value to prefix it on client claim types. Defaults to <c>client_</c>.\n    /// </summary>\n    /// <value>\n    /// Any non empty string if claims should be prefixed with the value; otherwise, <c>null</c>.\n    /// </value>\n    public string ClientClaimsPrefix { get; set; } = \"client_\";\n\n    /// <summary>\n    /// Gets or sets a salt value used in pair-wise subjectId generation for users of this client.\n    /// </summary>\n    public string PairWiseSubjectSalt { get; set; }\n\n    /// <summary>\n    /// The maximum duration (in seconds) since the last time the user authenticated.\n    /// </summary>\n    public int? UserSsoLifetime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the type of the device flow user code.\n    /// </summary>\n    /// <value>\n    /// The type of the device flow user code.\n    /// </value>\n    public string UserCodeType { get; set; }\n\n    /// <summary>\n    /// Gets or sets the device code lifetime.\n    /// </summary>\n    /// <value>\n    /// The device code lifetime.\n    /// </value>\n    public int DeviceCodeLifetime { get; set; } = 300;\n\n    /// <summary>\n    /// Gets or sets the allowed CORS origins for JavaScript clients.\n    /// </summary>\n    /// <value>\n    /// The allowed CORS origins.\n    /// </value>\n    public ICollection<string> AllowedCorsOrigins { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Gets or sets the custom properties for the client.\n    /// </summary>\n    /// <value>\n    /// The properties.\n    /// </value>\n    public IDictionary<string, string> Properties { get; set; } = new Dictionary<string, string>();\n\n    /// <summary>\n    /// Validates the grant types.\n    /// </summary>\n    /// <param name=\"grantTypes\">The grant types.</param>\n    /// <exception cref=\"System.InvalidOperationException\">\n    /// Grant types list is empty\n    /// or\n    /// Grant types cannot contain spaces\n    /// or\n    /// Grant types list contains duplicate values\n    /// </exception>\n    public static void ValidateGrantTypes(IEnumerable<string> grantTypes)\n    {\n        if (grantTypes == null)\n        {\n            throw new ArgumentNullException(nameof(grantTypes));\n        }\n\n        // spaces are not allowed in grant types\n        foreach (var type in grantTypes)\n        {\n            if (type.Contains(' '))\n            {\n                throw new InvalidOperationException(\"Grant types cannot contain spaces\");\n            }\n        }\n\n        // single grant type, seems to be fine\n        if (grantTypes.Count() == 1) return;\n\n        // don't allow duplicate grant types\n        if (grantTypes.Count() != grantTypes.Distinct().Count())\n        {\n            throw new InvalidOperationException(\"Grant types list contains duplicate values\");\n        }\n\n        // would allow response_type downgrade attack from code to token\n        DisallowGrantTypeCombination(GrantType.Implicit, GrantType.AuthorizationCode, grantTypes);\n        DisallowGrantTypeCombination(GrantType.Implicit, GrantType.Hybrid, grantTypes);\n\n        DisallowGrantTypeCombination(GrantType.AuthorizationCode, GrantType.Hybrid, grantTypes);\n    }\n\n    private static void DisallowGrantTypeCombination(string value1, string value2, IEnumerable<string> grantTypes)\n    {\n        if (grantTypes.Contains(value1, StringComparer.Ordinal) &&\n            grantTypes.Contains(value2, StringComparer.Ordinal))\n        {\n            throw new InvalidOperationException($\"Grant types list cannot contain both {value1} and {value2}\");\n        }\n    }\n\n    internal class GrantTypeValidatingHashSet : ICollection<string>\n    {\n        private readonly ICollection<string> _inner;\n\n        public GrantTypeValidatingHashSet()\n        {\n            _inner = new HashSet<string>();\n        }\n\n        public GrantTypeValidatingHashSet(IEnumerable<string> values)\n        {\n            _inner = new HashSet<string>(values);\n        }\n\n        private ICollection<string> Clone()\n        {\n            return new HashSet<string>(this);\n        }\n\n        private ICollection<string> CloneWith(params string[] values)\n        {\n            var clone = Clone();\n            foreach (var item in values) clone.Add(item);\n            return clone;\n        }\n\n        public int Count => _inner.Count;\n\n        public bool IsReadOnly => _inner.IsReadOnly;\n\n        public void Add(string item)\n        {\n            ValidateGrantTypes(CloneWith(item));\n            _inner.Add(item);\n        }\n\n        public void Clear()\n        {\n            _inner.Clear();\n        }\n\n        public bool Contains(string item)\n        {\n            return _inner.Contains(item);\n        }\n\n        public void CopyTo(string[] array, int arrayIndex)\n        {\n            _inner.CopyTo(array, arrayIndex);\n        }\n\n        public IEnumerator<string> GetEnumerator()\n        {\n            return _inner.GetEnumerator();\n        }\n\n        public bool Remove(string item)\n        {\n            return _inner.Remove(item);\n        }\n\n        IEnumerator IEnumerable.GetEnumerator()\n        {\n            return _inner.GetEnumerator();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Models/ClientClaim.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// A client claim\n/// </summary>\npublic class ClientClaim\n{\n    /// <summary>\n    /// The claim type\n    /// </summary>\n    public string Type { get; set; }\n    \n    /// <summary>\n    /// The claim value\n    /// </summary>\n    public string Value { get; set; }\n\n    /// <summary>\n    /// The claim value type\n    /// </summary>\n    public string ValueType { get; set; } = ClaimValueTypes.String;\n\n    /// <summary>\n    /// ctor\n    /// </summary>\n    public ClientClaim()\n    {\n    }\n\n    /// <summary>\n    /// ctor\n    /// </summary>\n    /// <param name=\"type\"></param>\n    /// <param name=\"value\"></param>\n    public ClientClaim(string type, string value)\n    {\n        Type = type;\n        Value = value;\n    }\n\n    /// <summary>\n    /// ctor\n    /// </summary>\n    /// <param name=\"type\"></param>\n    /// <param name=\"value\"></param>\n    /// <param name=\"valueType\"></param>\n    public ClientClaim(string type, string value, string valueType)\n    {\n        Type = type;\n        Value = value;\n        ValueType = valueType;\n    }\n\n    /// <inheritdoc/>\n    public override int GetHashCode()\n    {\n        unchecked \n        {\n            int hash = 17;\n\n            hash = hash * 23 + Value.GetHashCode();\n            hash = hash * 23 + Type.GetHashCode();\n            hash = hash * 23 + ValueType.GetHashCode();\n            return hash;\n        }\n    }\n\n    /// <inheritdoc/>\n    public override bool Equals(object obj)\n    {\n        if (obj is null) return false;\n        if (obj is ClientClaim c)\n        {\n            return (string.Equals(Type, c.Type, StringComparison.Ordinal) &&\n                    string.Equals(Value, c.Value, StringComparison.Ordinal) &&\n                    string.Equals(ValueType, c.ValueType, StringComparison.Ordinal));\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Models/Consent.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Represents the permissions (in terms of scopes) granted to a client by a subject\n/// </summary>\npublic class Consent\n{\n    /// <summary>\n    /// Gets or sets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public IEnumerable<string> Scopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the creation time.\n    /// </summary>\n    /// <value>\n    /// The creation time.\n    /// </value>\n    public DateTime CreationTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the expiration.\n    /// </summary>\n    /// <value>\n    /// The expiration.\n    /// </value>\n    public DateTime? Expiration { get; set; }\n}\n"
  },
  {
    "path": "src/Storage/src/Models/DeviceCode.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Represents data needed for device flow.\n/// </summary>\npublic class DeviceCode\n{\n    /// <summary>\n    /// Gets or sets the creation time.\n    /// </summary>\n    /// <value>\n    /// The creation time.\n    /// </value>\n    public DateTime CreationTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the lifetime.\n    /// </summary>\n    /// <value>\n    /// The lifetime.\n    /// </value>\n    public int Lifetime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether this instance is open identifier.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is open identifier; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsOpenId { get; set; }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether this instance is authorized.\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if this instance is authorized; otherwise, <c>false</c>.\n    /// </value>\n    public bool IsAuthorized { get; set; }\n\n    /// <summary>\n    /// Gets or sets the requested scopes.\n    /// </summary>\n    /// <value>\n    /// The authorized scopes.\n    /// </value>\n    public IEnumerable<string> RequestedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the authorized scopes.\n    /// </summary>\n    /// <value>\n    /// The authorized scopes.\n    /// </value>\n    public IEnumerable<string> AuthorizedScopes { get; set; }\n\n    /// <summary>\n    /// Gets or sets the subject.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject { get; set; }\n\n    /// <summary>\n    /// Gets or sets the session identifier.\n    /// </summary>\n    /// <value>\n    /// The session identifier.\n    /// </value>\n    public string SessionId { get; set; }\n}\n"
  },
  {
    "path": "src/Storage/src/Models/Enums.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// OpenID Connect subject types.\n/// </summary>\npublic enum SubjectTypes\n{\n    /// <summary>\n    /// global - use the native subject id\n    /// </summary>\n    Global = 0,\n\n    /// <summary>\n    /// ppid - scope the subject id to the client\n    /// </summary>\n    Ppid = 1\n}\n\n/// <summary>\n/// Access token types.\n/// </summary>\npublic enum AccessTokenType\n{\n    /// <summary>\n    /// Self-contained Json Web Token\n    /// </summary>\n    Jwt = 0,\n\n    /// <summary>\n    /// Reference token\n    /// </summary>\n    Reference = 1\n}\n\n/// <summary>\n/// Token usage types.\n/// </summary>\npublic enum TokenUsage\n{\n    /// <summary>\n    /// Re-use the refresh token handle\n    /// </summary>\n    ReUse = 0,\n\n    /// <summary>\n    /// Issue a new refresh token handle every time\n    /// </summary>\n    OneTimeOnly = 1\n}\n\n/// <summary>\n/// Token expiration types.\n/// </summary>\npublic enum TokenExpiration\n{\n    /// <summary>\n    /// Sliding token expiration\n    /// </summary>\n    Sliding = 0,\n\n    /// <summary>\n    /// Absolute token expiration\n    /// </summary>\n    Absolute = 1\n}\n\n/// <summary>\n/// Content Security Policy Level\n/// </summary>\npublic enum CspLevel\n{\n    /// <summary>\n    /// Level 1\n    /// </summary>\n    One = 0,\n\n    /// <summary>\n    /// Level 2\n    /// </summary>\n    Two = 1\n}\n"
  },
  {
    "path": "src/Storage/src/Models/GrantType.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Models;\n\npublic static class GrantType\n{\n    public const string Implicit = \"implicit\";\n    public const string Hybrid = \"hybrid\";\n    public const string AuthorizationCode = \"authorization_code\";\n    public const string ClientCredentials = \"client_credentials\";\n    public const string ResourceOwnerPassword = \"password\";\n    public const string DeviceFlow = \"urn:ietf:params:oauth:grant-type:device_code\";\n}\n"
  },
  {
    "path": "src/Storage/src/Models/IdentityResource.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models a user identity resource.\n/// </summary>\n[DebuggerDisplay(\"{\" + nameof(DebuggerDisplay) + \",nq}\")]\npublic class IdentityResource : Resource\n{\n    private string DebuggerDisplay => Name ?? $\"{{{typeof(IdentityResource)}}}\";\n    \n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IdentityResource\"/> class.\n    /// </summary>\n    public IdentityResource()\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IdentityResource\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"userClaims\">List of associated user claims that should be included when this resource is requested.</param>\n    public IdentityResource(string name, IEnumerable<string> userClaims)\n        : this(name, name, userClaims)\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"IdentityResource\"/> class.\n    /// </summary>\n    /// <param name=\"name\">The name.</param>\n    /// <param name=\"displayName\">The display name.</param>\n    /// <param name=\"userClaims\">List of associated user claims that should be included when this resource is requested.</param>\n    /// <exception cref=\"System.ArgumentNullException\">name</exception>\n    /// <exception cref=\"System.ArgumentException\">Must provide at least one claim type - claimTypes</exception>\n    public IdentityResource(string name, string displayName, IEnumerable<string> userClaims)\n    {\n        if (name.IsMissing()) throw new ArgumentNullException(nameof(name));\n        if (userClaims.IsNullOrEmpty()) throw new ArgumentException(\"Must provide at least one claim type\", nameof(userClaims));\n\n        Name = name;\n        DisplayName = displayName;\n\n        foreach(var type in userClaims)\n        {\n            UserClaims.Add(type);\n        }\n    }\n\n    /// <summary>\n    /// Specifies whether the user can de-select the scope on the consent screen (if the consent screen wants to implement such a feature). Defaults to false.\n    /// </summary>\n    public bool Required { get; set; } = false;\n\n    /// <summary>\n    /// Specifies whether the consent screen will emphasize this scope (if the consent screen wants to implement such a feature). \n    /// Use this setting for sensitive or important scopes. Defaults to false.\n    /// </summary>\n    public bool Emphasize { get; set; } = false;\n}\n"
  },
  {
    "path": "src/Storage/src/Models/PersistedGrant.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// A model for a persisted grant\n/// </summary>\npublic class PersistedGrant\n{\n    /// <summary>\n    /// Gets or sets the key.\n    /// </summary>\n    /// <value>\n    /// The key.\n    /// </value>\n    public string Key { get; set; }\n\n    /// <summary>\n    /// Gets the type.\n    /// </summary>\n    /// <value>\n    /// The type.\n    /// </value>\n    public string Type { get; set; }\n\n    /// <summary>\n    /// Gets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId { get; set; }\n\n    /// <summary>\n    /// Gets the session identifier.\n    /// </summary>\n    /// <value>\n    /// The session identifier.\n    /// </value>\n    public string SessionId { get; set; }\n    \n    /// <summary>\n    /// Gets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Gets or sets the creation time.\n    /// </summary>\n    /// <value>\n    /// The creation time.\n    /// </value>\n    public DateTime CreationTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the expiration.\n    /// </summary>\n    /// <value>\n    /// The expiration.\n    /// </value>\n    public DateTime? Expiration { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the consumed time.\n    /// </summary>\n    /// <value>\n    /// The consumed time.\n    /// </value>\n    public DateTime? ConsumedTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the data.\n    /// </summary>\n    /// <value>\n    /// The data.\n    /// </value>\n    public string Data { get; set; }\n}\n"
  },
  {
    "path": "src/Storage/src/Models/RefreshToken.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models a refresh token.\n/// </summary>\npublic class RefreshToken\n{\n    /// <summary>\n    /// Gets or sets the creation time.\n    /// </summary>\n    /// <value>\n    /// The creation time.\n    /// </value>\n    public DateTime CreationTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the life time.\n    /// </summary>\n    /// <value>\n    /// The life time.\n    /// </value>\n    public int Lifetime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the consumed time.\n    /// </summary>\n    /// <value>\n    /// The consumed time.\n    /// </value>\n    public DateTime? ConsumedTime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the access token.\n    /// </summary>\n    /// <value>\n    /// The access token.\n    /// </value>\n    public Token AccessToken { get; set; }\n\n    /// <summary>\n    /// Gets or sets the original subject that requiested the token.\n    /// </summary>\n    /// <value>\n    /// The subject.\n    /// </value>\n    public ClaimsPrincipal Subject\n    {\n        get\n        {\n            var user = new IdentityServerUser(SubjectId);\n            if (AccessToken.Claims != null)\n            {\n                foreach (var claim in AccessToken.Claims)\n                {\n                    user.AdditionalClaims.Add(claim);\n                }\n            }\n            return user.CreatePrincipal();\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets the version number.\n    /// </summary>\n    /// <value>\n    /// The version.\n    /// </value>\n    public int Version { get; set; } = 4;\n\n    /// <summary>\n    /// Gets the client identifier.\n    /// </summary>\n    /// <value>\n    /// The client identifier.\n    /// </value>\n    public string ClientId => AccessToken.ClientId;\n\n    /// <summary>\n    /// Gets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId => AccessToken.SubjectId;\n\n    /// <summary>\n    /// Gets the session identifier.\n    /// </summary>\n    /// <value>\n    /// The session identifier.\n    /// </value>\n    public string SessionId => AccessToken.SessionId;\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description => AccessToken.Description;\n\n    /// <summary>\n    /// Gets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public IEnumerable<string> Scopes => AccessToken.Scopes;\n}\n"
  },
  {
    "path": "src/Storage/src/Models/Resource.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models the common data of API and identity resources.\n/// </summary>\n[DebuggerDisplay(\"{DebuggerDisplay,nq}\")]\npublic abstract class Resource\n{\n    private string DebuggerDisplay => Name ?? $\"{{{typeof(Resource)}}}\";\n\n    /// <summary>\n    /// Indicates if this resource is enabled. Defaults to true.\n    /// </summary>\n    public bool Enabled { get; set; } = true;\n\n    /// <summary>\n    /// The unique name of the resource.\n    /// </summary>\n    public string Name { get; set; }\n\n    /// <summary>\n    /// Display name of the resource.\n    /// </summary>\n    public string DisplayName { get; set; }\n    \n    /// <summary>\n    /// Description of the resource.\n    /// </summary>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Specifies whether this scope is shown in the discovery document. Defaults to true.\n    /// </summary>\n    public bool ShowInDiscoveryDocument { get; set; } = true;\n\n    /// <summary>\n    /// List of associated user claims that should be included when this resource is requested.\n    /// </summary>\n    public ICollection<string> UserClaims { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Gets or sets the custom properties for the resource.\n    /// </summary>\n    /// <value>\n    /// The properties.\n    /// </value>\n    public IDictionary<string, string> Properties { get; set; } = new Dictionary<string, string>();\n}\n"
  },
  {
    "path": "src/Storage/src/Models/Resources.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models a collection of identity and API resources.\n/// </summary>\npublic class Resources\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Resources\"/> class.\n    /// </summary>\n    public Resources()\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Resources\"/> class.\n    /// </summary>\n    /// <param name=\"other\">The other.</param>\n    public Resources(Resources other)\n        : this(other.IdentityResources, other.ApiResources, other.ApiScopes)\n    {\n        OfflineAccess = other.OfflineAccess;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Resources\"/> class.\n    /// </summary>\n    /// <param name=\"identityResources\">The identity resources.</param>\n    /// <param name=\"apiResources\">The API resources.</param>\n    /// <param name=\"apiScopes\">The API scopes.</param>\n    public Resources(IEnumerable<IdentityResource> identityResources, IEnumerable<ApiResource> apiResources, IEnumerable<ApiScope> apiScopes)\n    {\n        if (identityResources?.Any() == true)\n        {\n            IdentityResources = new HashSet<IdentityResource>(identityResources.ToArray());\n        }\n        if (apiResources?.Any() == true)\n        {\n            ApiResources = new HashSet<ApiResource>(apiResources.ToArray());\n        }\n        if (apiScopes?.Any() == true)\n        {\n            ApiScopes = new HashSet<ApiScope>(apiScopes.ToArray());\n        }\n    }\n\n    /// <summary>\n    /// Gets or sets a value indicating whether [offline access].\n    /// </summary>\n    /// <value>\n    ///   <c>true</c> if [offline access]; otherwise, <c>false</c>.\n    /// </value>\n    public bool OfflineAccess { get; set; }\n\n    /// <summary>\n    /// Gets or sets the identity resources.\n    /// </summary>\n    public ICollection<IdentityResource> IdentityResources { get; set; } = new HashSet<IdentityResource>();\n\n    /// <summary>\n    /// Gets or sets the API resources.\n    /// </summary>\n    public ICollection<ApiResource> ApiResources { get; set; } = new HashSet<ApiResource>();\n    \n    /// <summary>\n    /// Gets or sets the API scopes.\n    /// </summary>\n    public ICollection<ApiScope> ApiScopes { get; set; } = new HashSet<ApiScope>();\n}\n"
  },
  {
    "path": "src/Storage/src/Models/Secret.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models a client secret with identifier and expiration\n/// </summary>\npublic class Secret\n{\n    /// <summary>\n    /// Gets or sets the description.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n\n    /// <summary>\n    /// Gets or sets the value.\n    /// </summary>\n    /// <value>\n    /// The value.\n    /// </value>\n    public string Value { get; set; }\n\n    /// <summary>\n    /// Gets or sets the expiration.\n    /// </summary>\n    /// <value>\n    /// The expiration.\n    /// </value>\n    public DateTime? Expiration { get; set; }\n\n    /// <summary>\n    /// Gets or sets the type of the client secret.\n    /// </summary>\n    /// <value>\n    /// The type of the client secret.\n    /// </value>\n    public string Type { get; set; }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Secret\"/> class.\n    /// </summary>\n    public Secret()\n    {\n        Type = IdentityServerConstants.SecretTypes.SharedSecret;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Secret\"/> class.\n    /// </summary>\n    /// <param name=\"value\">The value.</param>\n    /// <param name=\"expiration\">The expiration.</param>\n    public Secret(string value, DateTime? expiration = null)\n        : this()\n    {\n        Value = value;\n        Expiration = expiration;\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Secret\" /> class.\n    /// </summary>\n    /// <param name=\"value\">The value.</param>\n    /// <param name=\"description\">The description.</param>\n    /// <param name=\"expiration\">The expiration.</param>\n    public Secret(string value, string description, DateTime? expiration = null)\n        : this()\n    {\n        Description = description;\n        Value = value;\n        Expiration = expiration;\n    }\n\n    /// <summary>\n    /// Returns a hash code for this instance.\n    /// </summary>\n    /// <returns>\n    /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. \n    /// </returns>\n    public override int GetHashCode()\n    {\n        unchecked\n        {\n            var hash = 17;\n            hash = hash * 23 + (Value?.GetHashCode() ?? 0);\n            hash = hash * 23 + (Type?.GetHashCode() ?? 0);\n\n            return hash;\n        }\n    }\n\n    /// <summary>\n    /// Determines whether the specified <see cref=\"System.Object\" />, is equal to this instance.\n    /// </summary>\n    /// <param name=\"obj\">The <see cref=\"System.Object\" /> to compare with this instance.</param>\n    /// <returns>\n    ///   <c>true</c> if the specified <see cref=\"System.Object\" /> is equal to this instance; otherwise, <c>false</c>.\n    /// </returns>\n    public override bool Equals(object obj)\n    {\n        if (obj == null) return false;\n        var other = obj as Secret;\n        if (other == null) return false;\n        if (ReferenceEquals(other, this)) return true;\n\n        return String.Equals(other.Type, Type, StringComparison.Ordinal) && \n            String.Equals(other.Value, Value, StringComparison.Ordinal);\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Models/Token.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Models;\n\n/// <summary>\n/// Models a token.\n/// </summary>\npublic class Token\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Token\"/> class.\n    /// </summary>\n    public Token()\n    {\n    }\n\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"Token\"/> class.\n    /// </summary>\n    /// <param name=\"tokenType\">Type of the token.</param>\n    public Token(string tokenType)\n    {\n        Type = tokenType;\n    }\n\n    /// <summary>\n    /// A list of allowed algorithm for signing the token. If null or empty, will use the default algorithm.\n    /// </summary>\n    public ICollection<string> AllowedSigningAlgorithms { get; set; } = new HashSet<string>();\n\n    /// <summary>\n    /// Specifies the confirmation method of the token. This value, if set, will become the cnf claim.\n    /// </summary>\n    public string Confirmation { get; set; }\n\n    /// <summary>\n    /// Gets or sets the audiences.\n    /// </summary>\n    /// <value>\n    /// The audiences.\n    /// </value>\n    public ICollection<string> Audiences { get; set; } = new HashSet<string>();\n    \n    /// <summary>\n    /// Gets or sets the issuer.\n    /// </summary>\n    /// <value>\n    /// The issuer.\n    /// </value>\n    public string Issuer { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the creation time.\n    /// </summary>\n    /// <value>\n    /// The creation time.\n    /// </value>\n    public DateTime CreationTime { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the lifetime.\n    /// </summary>\n    /// <value>\n    /// The lifetime.\n    /// </value>\n    public int Lifetime { get; set; }\n\n    /// <summary>\n    /// Gets or sets the type.\n    /// </summary>\n    /// <value>\n    /// The type.\n    /// </value>\n    public string Type { get; set; } = OidcConstants.TokenTypes.AccessToken;\n\n    /// <summary>\n    /// Gets or sets the ID of the client.\n    /// </summary>\n    /// <value>\n    /// The ID of the client.\n    /// </value>\n    public string ClientId { get; set; }\n\n    /// <summary>\n    /// Gets or sets the type of access token of the client\n    /// </summary>\n    /// <value>\n    /// The access token type specified by the client.\n    /// </value>\n    public AccessTokenType AccessTokenType { get; set; }\n\n    /// <summary>\n    /// Gets the description the user assigned to the device being authorized.\n    /// </summary>\n    /// <value>\n    /// The description.\n    /// </value>\n    public string Description { get; set; }\n    \n    /// <summary>\n    /// Gets or sets the claims.\n    /// </summary>\n    /// <value>\n    /// The claims.\n    /// </value>\n    public ICollection<Claim> Claims { get; set; } = new HashSet<Claim>(new ClaimComparer());\n\n    /// <summary>\n    /// Gets or sets the version.\n    /// </summary>\n    /// <value>\n    /// The version.\n    /// </value>\n    public int Version { get; set; } = 4;\n\n    /// <summary>\n    /// Gets the subject identifier.\n    /// </summary>\n    /// <value>\n    /// The subject identifier.\n    /// </value>\n    public string SubjectId => Claims.Where(x => x.Type == JwtClaimTypes.Subject).Select(x => x.Value).SingleOrDefault();\n\n    /// <summary>\n    /// Gets the session identifier.\n    /// </summary>\n    /// <value>\n    /// The session identifier.\n    /// </value>\n    public string SessionId => Claims.Where(x => x.Type == JwtClaimTypes.SessionId).Select(x => x.Value).SingleOrDefault();\n\n    /// <summary>\n    /// Gets the scopes.\n    /// </summary>\n    /// <value>\n    /// The scopes.\n    /// </value>\n    public IEnumerable<string> Scopes => Claims.Where(x => x.Type == JwtClaimTypes.Scope).Select(x => x.Value);\n}\n"
  },
  {
    "path": "src/Storage/src/Services/ICorsPolicyService.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Services;\n\n/// <summary>\n/// Service that determines if CORS is allowed.\n/// </summary>\npublic interface ICorsPolicyService\n{\n    /// <summary>\n    /// Determines whether origin is allowed.\n    /// </summary>\n    /// <param name=\"origin\">The origin.</param>\n    /// <returns></returns>\n    Task<bool> IsOriginAllowedAsync(string origin);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IAuthorizationCodeStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for the authorization code store\n/// </summary>\npublic interface IAuthorizationCodeStore\n{\n    /// <summary>\n    /// Stores the authorization code.\n    /// </summary>\n    /// <param name=\"code\">The code.</param>\n    /// <returns></returns>\n    Task<string> StoreAuthorizationCodeAsync(AuthorizationCode code);\n\n    /// <summary>\n    /// Gets the authorization code.\n    /// </summary>\n    /// <param name=\"code\">The code.</param>\n    /// <returns></returns>\n    Task<AuthorizationCode> GetAuthorizationCodeAsync(string code);\n\n    /// <summary>\n    /// Removes the authorization code.\n    /// </summary>\n    /// <param name=\"code\">The code.</param>\n    /// <returns></returns>\n    Task RemoveAuthorizationCodeAsync(string code);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IClientStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Retrieval of client configuration\n/// </summary>\npublic interface IClientStore\n{\n    /// <summary>\n    /// Finds a client by id\n    /// </summary>\n    /// <param name=\"clientId\">The client id</param>\n    /// <returns>The client</returns>\n    Task<Client> FindClientByIdAsync(string clientId);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IDeviceFlowStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for the device flow store\n/// </summary>\npublic interface IDeviceFlowStore\n{\n    /// <summary>\n    /// Stores the device authorization request.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    /// <returns></returns>\n    Task StoreDeviceAuthorizationAsync(string deviceCode, string userCode, DeviceCode data);\n\n    /// <summary>\n    /// Finds device authorization by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <returns></returns>\n    Task<DeviceCode> FindByUserCodeAsync(string userCode);\n\n    /// <summary>\n    /// Finds device authorization by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    Task<DeviceCode> FindByDeviceCodeAsync(string deviceCode);\n\n    /// <summary>\n    /// Updates device authorization, searching by user code.\n    /// </summary>\n    /// <param name=\"userCode\">The user code.</param>\n    /// <param name=\"data\">The data.</param>\n    Task UpdateByUserCodeAsync(string userCode, DeviceCode data);\n\n    /// <summary>\n    /// Removes the device authorization, searching by device code.\n    /// </summary>\n    /// <param name=\"deviceCode\">The device code.</param>\n    Task RemoveByDeviceCodeAsync(string deviceCode);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IPersistedGrantStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for persisting any type of grant.\n/// </summary>\npublic interface IPersistedGrantStore\n{\n    /// <summary>\n    /// Stores the grant.\n    /// </summary>\n    /// <param name=\"grant\">The grant.</param>\n    /// <returns></returns>\n    Task StoreAsync(PersistedGrant grant);\n\n    /// <summary>\n    /// Gets the grant.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <returns></returns>\n    Task<PersistedGrant> GetAsync(string key);\n\n    /// <summary>\n    /// Gets all grants based on the filter.\n    /// </summary>\n    /// <param name=\"filter\">The filter.</param>\n    /// <returns></returns>\n    Task<IEnumerable<PersistedGrant>> GetAllAsync(PersistedGrantFilter filter);\n\n    /// <summary>\n    /// Removes the grant by key.\n    /// </summary>\n    /// <param name=\"key\">The key.</param>\n    /// <returns></returns>\n    Task RemoveAsync(string key);\n\n    /// <summary>\n    /// Removes all grants based on the filter.\n    /// </summary>\n    /// <param name=\"filter\">The filter.</param>\n    /// <returns></returns>\n    Task RemoveAllAsync(PersistedGrantFilter filter);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IReferenceTokenStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for reference token storage\n/// </summary>\npublic interface IReferenceTokenStore\n{\n    /// <summary>\n    /// Stores the reference token.\n    /// </summary>\n    /// <param name=\"token\">The token.</param>\n    /// <returns></returns>\n    Task<string> StoreReferenceTokenAsync(Token token);\n\n    /// <summary>\n    /// Gets the reference token.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <returns></returns>\n    Task<Token> GetReferenceTokenAsync(string handle);\n\n    /// <summary>\n    /// Removes the reference token.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <returns></returns>\n    Task RemoveReferenceTokenAsync(string handle);\n\n    /// <summary>\n    /// Removes the reference tokens.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    Task RemoveReferenceTokensAsync(string subjectId, string clientId);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IRefreshTokenStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for refresh token storage\n/// </summary>\npublic interface IRefreshTokenStore\n{\n    /// <summary>\n    /// Stores the refresh token.\n    /// </summary>\n    /// <param name=\"refreshToken\">The refresh token.</param>\n    /// <returns></returns>\n    Task<string> StoreRefreshTokenAsync(RefreshToken refreshToken);\n\n    /// <summary>\n    /// Updates the refresh token.\n    /// </summary>\n    /// <param name=\"handle\">The handle.</param>\n    /// <param name=\"refreshToken\">The refresh token.</param>\n    /// <returns></returns>\n    Task UpdateRefreshTokenAsync(string handle, RefreshToken refreshToken);\n\n    /// <summary>\n    /// Gets the refresh token.\n    /// </summary>\n    /// <param name=\"refreshTokenHandle\">The refresh token handle.</param>\n    /// <returns></returns>\n    Task<RefreshToken> GetRefreshTokenAsync(string refreshTokenHandle);\n\n    /// <summary>\n    /// Removes the refresh token.\n    /// </summary>\n    /// <param name=\"refreshTokenHandle\">The refresh token handle.</param>\n    /// <returns></returns>\n    Task RemoveRefreshTokenAsync(string refreshTokenHandle);\n\n    /// <summary>\n    /// Removes the refresh tokens.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    Task RemoveRefreshTokensAsync(string subjectId, string clientId);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IResourceStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Resource retrieval\n/// </summary>\npublic interface IResourceStore\n{\n    /// <summary>\n    /// Gets identity resources by scope name.\n    /// </summary>\n    Task<IEnumerable<IdentityResource>> FindIdentityResourcesByScopeNameAsync(IEnumerable<string> scopeNames);\n\n    /// <summary>\n    /// Gets API scopes by scope name.\n    /// </summary>\n    Task<IEnumerable<ApiScope>> FindApiScopesByNameAsync(IEnumerable<string> scopeNames);\n    \n    /// <summary>\n    /// Gets API resources by scope name.\n    /// </summary>\n    Task<IEnumerable<ApiResource>> FindApiResourcesByScopeNameAsync(IEnumerable<string> scopeNames);\n\n    /// <summary>\n    /// Gets API resources by API resource name.\n    /// </summary>\n    Task<IEnumerable<ApiResource>> FindApiResourcesByNameAsync(IEnumerable<string> apiResourceNames);\n\n    /// <summary>\n    /// Gets all resources.\n    /// </summary>\n    Task<Resources> GetAllResourcesAsync();\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/IUserConsentStore.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Interface for user consent storage\n/// </summary>\npublic interface IUserConsentStore\n{\n    /// <summary>\n    /// Stores the user consent.\n    /// </summary>\n    /// <param name=\"consent\">The consent.</param>\n    /// <returns></returns>\n    Task StoreUserConsentAsync(Consent consent);\n\n    /// <summary>\n    /// Gets the user consent.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    Task<Consent> GetUserConsentAsync(string subjectId, string clientId);\n\n    /// <summary>\n    /// Removes the user consent.\n    /// </summary>\n    /// <param name=\"subjectId\">The subject identifier.</param>\n    /// <param name=\"clientId\">The client identifier.</param>\n    /// <returns></returns>\n    Task RemoveUserConsentAsync(string subjectId, string clientId);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/PersistedGrantFilter.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores;\n\n/// <summary>\n/// Represents a filter used when accessing the persisted grants store. \n/// Setting multiple properties is interpreted as a logical 'AND' to further filter the query.\n/// At least one value must be supplied.\n/// </summary>\npublic class PersistedGrantFilter\n{\n    /// <summary>\n    /// Subject id of the user.\n    /// </summary>\n    public string SubjectId { get; set; }\n    \n    /// <summary>\n    /// Session id used for the grant.\n    /// </summary>\n    public string SessionId { get; set; }\n    \n    /// <summary>\n    /// Client id the grant was issued to.\n    /// </summary>\n    public string ClientId { get; set; }\n    \n    /// <summary>\n    /// The type of grant.\n    /// </summary>\n    public string Type { get; set; }\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/Serialization/ClaimConverter.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Stores.Serialization;\n\npublic class ClaimConverter : JsonConverter\n{\n    public override bool CanConvert(Type objectType)\n    {\n        return typeof(Claim) == objectType;\n    }\n\n    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)\n    {\n        var source = serializer.Deserialize<ClaimLite>(reader);\n        var target = new Claim(source.Type, source.Value, source.ValueType);\n        return target;\n    }\n\n    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)\n    {\n        var source = (Claim)value;\n\n        var target = new ClaimLite\n        {\n            Type = source.Type,\n            Value = source.Value,\n            ValueType = source.ValueType\n        };\n\n        serializer.Serialize(writer, target);\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/Serialization/ClaimLite.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Stores.Serialization;\n\npublic class ClaimLite\n{\n    public string Type { get; set; }\n    public string Value { get; set; }\n    public string ValueType { get; set; }\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/Serialization/ClaimsPrincipalConverter.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Stores.Serialization;\n\npublic class ClaimsPrincipalConverter : JsonConverter\n{\n    public override bool CanConvert(Type objectType)\n    {\n        return typeof(ClaimsPrincipal) == objectType;\n    }\n\n    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)\n    {\n        var source = serializer.Deserialize<ClaimsPrincipalLite>(reader);\n        if (source == null) return null;\n\n        var claims = source.Claims.Select(x => new Claim(x.Type, x.Value, x.ValueType));\n        var id = new ClaimsIdentity(claims, source.AuthenticationType, JwtClaimTypes.Name, JwtClaimTypes.Role);\n        var target = new ClaimsPrincipal(id);\n        return target;\n    }\n\n    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)\n    {\n        var source = (ClaimsPrincipal)value;\n\n        var target = new ClaimsPrincipalLite\n        {\n            AuthenticationType = source.Identity.AuthenticationType,\n            Claims = source.Claims.Select(x => new ClaimLite { Type = x.Type, Value = x.Value, ValueType = x.ValueType }).ToArray()\n        };\n        serializer.Serialize(writer, target);\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/Serialization/ClaimsPrincipalLite.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Stores.Serialization;\n\npublic class ClaimsPrincipalLite\n{\n    public string AuthenticationType { get; set; }\n    public ClaimLite[] Claims { get; set; }\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/Serialization/CustomContractResolver.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\n#pragma warning disable 1591\n\nnamespace IdentityServer8.Stores.Serialization;\n\npublic class CustomContractResolver: DefaultContractResolver\n{\n    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)\n    {\n        var props = base.CreateProperties(type, memberSerialization);\n        return props.Where(p => p.Writable).ToList();\n    }\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/Serialization/IPersistentGrantSerializer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores.Serialization;\n\n/// <summary>\n/// Interface for persisted grant serialization\n/// </summary>\npublic interface IPersistentGrantSerializer\n{\n    /// <summary>\n    /// Serializes the specified value.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"value\">The value.</param>\n    /// <returns></returns>\n    string Serialize<T>(T value);\n\n    /// <summary>\n    /// Deserializes the specified string.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"json\">The json.</param>\n    /// <returns></returns>\n    T Deserialize<T>(string json);\n}\n"
  },
  {
    "path": "src/Storage/src/Stores/Serialization/PersistentGrantSerializer.cs",
    "content": "/*\n Copyright (c) 2024 HigginsSoft, Alexander Higgins - https://github.com/alexhiggins732/ \n\n Copyright (c) 2018, Brock Allen & Dominick Baier. All rights reserved.\n\n Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. \n Source code and license this software can be found \n\n The above copyright notice and this permission notice shall be included in all\n copies or substantial portions of the Software.\n*/\n\nnamespace IdentityServer8.Stores.Serialization;\n\n/// <summary>\n/// JSON-based persisted grant serializer\n/// </summary>\n/// <seealso cref=\"IdentityServer8.Stores.Serialization.IPersistentGrantSerializer\" />\npublic class PersistentGrantSerializer : IPersistentGrantSerializer\n{\n    private static readonly JsonSerializerSettings _settings;\n\n    static PersistentGrantSerializer()\n    {\n        _settings = new JsonSerializerSettings\n        {\n            ContractResolver = new CustomContractResolver()\n        };\n        _settings.Converters.Add(new ClaimConverter());\n        _settings.Converters.Add(new ClaimsPrincipalConverter());\n    }\n\n    /// <summary>\n    /// Serializes the specified value.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"value\">The value.</param>\n    /// <returns></returns>\n    public string Serialize<T>(T value)\n    {\n        return JsonConvert.SerializeObject(value, _settings);\n    }\n\n    /// <summary>\n    /// Deserializes the specified string.\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    /// <param name=\"json\">The json.</param>\n    /// <returns></returns>\n    public T Deserialize<T>(string json)\n    {\n        return JsonConvert.DeserializeObject<T>(json, _settings);\n    }\n}\n"
  },
  {
    "path": "version.json",
    "content": "{\n  \"$schema\": \"https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json\",\n  \"version\": \"8.0.4-beta.4\",\n  \"nugetPackageVersion\": {\n    \"semVer\": 2, // optional. Set to either 1 or 2 to control how the NuGet package version string is generated. Default is 1.\n    \"precision\": \"revision\"\n  },\n  \"semVer1NumericIdentifierPadding\": 4,\n  \"pathFilters\": [\n    // optional list of paths to consider when calculating version height.\n    \"!docs\",\n    \"!.git\",\n    \"!.vs\",\n    \"!.config\",\n    \"!.github\",\n    \"!.config\",\n    \"!Directory.Build.props\",\n    \"!Directory.Build.targets\",\n    \"!Directory.Packages.props\",\n    \"docker-compose.yml\",\n    \"docker-compose.override.yml\",\n    \"docker-compose.vs.debug.yml\",\n    \"docker-compose.vs.release.yml\",\n    \"docker-compose.dcrpoj\",\n    \"src/IdentityServer8.sln\",\n    \"!global.json\",\n    \"!IdentityServer8.DotNet.ruleset\",\n    \"!LICENSCE\",\n    \"!Nuget.config\",\n    \"!SECURITY.md\",\n    \"!SPONSORS.md\",\n    \"!README.md\",\n    \"!samples\",\n    \"!nuget\"\n  ],\n  \"publicReleaseRefSpec\": [\n    \"^refs/heads/master$\", // we release out of master\n    \"^refs/tags/v\\\\d+\\\\.\\\\d+\", // we also release tags starting with vN.N\n    \"^refs/heads/develop$\", // we release alpha out of develop\n    \"^refs/heads/release/*\" // we release beta out of release\n  ],\n  \"cloudBuild\": {\n    \"setVersionVariables\": true,\n    \"buildNumber\": {\n      \"enabled\": true,\n      \"includeCommitId\": {\n        \"when\": \"always\",\n        \"where\": \"buildMetadata\"\n      }\n    }\n  },\n  \"release\": {\n    \"tagName\": \"v{version}\",\n    \"branchName\": \"v{version}\",\n    \"versionIncrement\": \"minor\",\n    \"firstUnstableTag\": \"alpha\"\n  }\n}\n"
  }
]